Atrinik Server  4.0
ring.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <object_methods.h>
34 #include <arch.h>
35 #include <artifact.h>
36 
38 
42 #define RING_CHANCE_CURSED 5
43 
47 #define RING_CHANCE_DAMNED 10
48 
51 #define RING_CHANCE_TABLE 3
52 
55 #define RING_CHANCE_EXTRA 4
56 
58 static bool
60  int difficulty,
61  treasure_affinity_t *affinity,
62  double *item_power,
63  int bonus)
64 {
65  HARD_ASSERT(op != NULL);
66  HARD_ASSERT(item_power != NULL);
67 
68  op->stats.exp += bonus;
69  op->value *= 1.0 + (0.15 * FABS(bonus));
70 
71  return true;
72 }
73 
75 static bool
77  int difficulty,
78  treasure_affinity_t *affinity,
79  double *item_power,
80  int bonus)
81 {
82  HARD_ASSERT(op != NULL);
83  HARD_ASSERT(item_power != NULL);
84 
85  int tmp = bonus;
86 
87  if (bonus > 0 && rndm_chance(5)) {
88  tmp++;
89  op->value *= 1.3;
90  }
91 
92  op->stats.hp += tmp;
93  op->value *= 1.0 + (0.2 * FABS(bonus));
94 
95  if (tmp > 0) {
96  *item_power += tmp;
97  }
98 
99  return true;
100 }
101 
103 static bool
105  int difficulty,
106  treasure_affinity_t *affinity,
107  double *item_power,
108  int bonus)
109 {
110  HARD_ASSERT(op != NULL);
111  HARD_ASSERT(item_power != NULL);
112 
113  int tmp = bonus;
114 
115  if (bonus > 0 && rndm_chance(5)) {
116  tmp++;
117  op->value *= 1.3;
118  }
119 
120  op->stats.sp += tmp;
121  op->value *= 1.0 + (0.2 * FABS(bonus));
122 
123  if (tmp > 0) {
124  *item_power += tmp;
125  }
126 
127  return true;
128 }
129 
131 static bool
133  int difficulty,
134  treasure_affinity_t *affinity,
135  double *item_power,
136  int bonus)
137 {
138  HARD_ASSERT(op != NULL);
139  HARD_ASSERT(item_power != NULL);
140 
141  int tmp = bonus;
142 
143  if (bonus > 0 && rndm_chance(5)) {
144  tmp++;
145  op->value *= 1.5;
146  }
147 
148  op->stats.dam += tmp;
149  op->value *= 1.0 + (0.4 * FABS(bonus));
150 
151  if (tmp > 0) {
152  *item_power += tmp;
153  }
154 
155  return true;
156 }
157 
159 static bool
161  int difficulty,
162  treasure_affinity_t *affinity,
163  double *item_power,
164  int bonus)
165 {
166  HARD_ASSERT(op != NULL);
167  HARD_ASSERT(item_power != NULL);
168 
169  int tmp = bonus;
170 
171  if (bonus > 0 && rndm_chance(5)) {
172  tmp++;
173  op->value *= 1.1;
174  }
175 
176  op->stats.food += tmp;
177  op->value *= 1.0 + (0.1 * FABS(bonus));
178 
179  return true;
180 }
181 
200 static bool
202  int difficulty,
203  treasure_affinity_t *affinity,
204  double *item_power,
205  int bonus,
206  int stat)
207 {
208  HARD_ASSERT(op != NULL);
209  HARD_ASSERT(item_power != NULL);
210 
211  int value = get_attr_value(&op->stats, stat) + bonus;
212  if (value > MAX_STAT || value < -MAX_STAT) {
213  /* Extremely unlikely to happen (if it's even possible), but guard
214  * against it anyway. Returning false will make the main processing
215  * function roll something else (hopefully). */
216  LOG(DEVEL,
217  "Stat value reached minimum/maximum %d: %s",
218  value,
219  object_get_str(op));
220  return false;
221  }
222 
223  set_attr_value(&op->stats, stat, value);
224  op->value *= 1.0 + (0.25 * FABS(bonus));
225 
226  if (bonus > 0) {
227  *item_power += bonus;
228  }
229 
230  return true;
231 }
232 
234 static bool
236  int difficulty,
237  treasure_affinity_t *affinity,
238  double *item_power,
239  int bonus)
240 {
241  return ring_set_bonus_stat(op,
242  difficulty,
243  affinity,
244  item_power,
245  bonus,
246  STR);
247 }
248 
250 static bool
252  int difficulty,
253  treasure_affinity_t *affinity,
254  double *item_power,
255  int bonus)
256 {
257  return ring_set_bonus_stat(op,
258  difficulty,
259  affinity,
260  item_power,
261  bonus,
262  DEX);
263 }
264 
266 static bool
268  int difficulty,
269  treasure_affinity_t *affinity,
270  double *item_power,
271  int bonus)
272 {
273  return ring_set_bonus_stat(op,
274  difficulty,
275  affinity,
276  item_power,
277  bonus,
278  CON);
279 }
280 
282 static bool
284  int difficulty,
285  treasure_affinity_t *affinity,
286  double *item_power,
287  int bonus)
288 {
289  return ring_set_bonus_stat(op,
290  difficulty,
291  affinity,
292  item_power,
293  bonus,
294  INT);
295 }
296 
298 static bool
300  int difficulty,
301  treasure_affinity_t *affinity,
302  double *item_power,
303  int bonus)
304 {
305  return ring_set_bonus_stat(op,
306  difficulty,
307  affinity,
308  item_power,
309  bonus,
310  POW);
311 }
312 
317  {40, ring_set_bonus_speed},
320  {25, ring_set_bonus_damage},
327 };
328 
330 static int
332  object **ret,
333  int difficulty,
334  treasure_affinity_t *affinity,
335  int flags)
336 {
337  HARD_ASSERT(op != NULL);
338  HARD_ASSERT(difficulty > 0);
339 
340  /* Avoid processing if the item is already special. */
341  if (process_treasure_is_special(op)) {
343  }
344 
345  /* We only process ring_generic objects. */
346  if (op->arch != arches[ARCH_RING_GENERIC]) {
348  }
349 
350  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
351  object_remove(op, 0);
352  }
353 
354  /* Destroy the original and create a ring_normal archetype,
355  * which will be turned into an artifact. */
356  object_destroy(op);
357  *ret = op = arch_to_object(arches[ARCH_RING_NORMAL]);
358 
359  if (!artifact_generate(op, difficulty, affinity)) {
360  log_error("Failed to generate artifact: %s", object_get_str(op));
361  object_destroy(op);
362  return OBJECT_METHOD_ERROR;
363  }
364 
365  if (!(flags & GT_ONLY_GOOD)) {
366  if (rndm_chance(RING_CHANCE_CURSED)) {
367  if (rndm_chance(RING_CHANCE_DAMNED)) {
368  SET_FLAG(op, FLAG_DAMNED);
369  } else {
370  SET_FLAG(op, FLAG_CURSED);
371  }
372  }
373  }
374 
375  double item_power = 0.0;
376 
377  for (int i = 0; i < 5; i++) {
378  /* If it's not the first bonus, roll for a chance of another bonus.
379  *
380  * The first unsuccessful roll is a combo-breaker. */
381  if (i != 0 && !rndm_chance(RING_CHANCE_EXTRA)) {
382  break;
383  }
384 
385  /* Decide which table to roll from. */
386  if (rndm_chance(RING_CHANCE_TABLE)) {
387  static uint32_t total_chance = 0;
388  if (total_chance == 0) {
389  total_chance =
390  PROCESS_TREASURE_TABLE_TOTAL_CHANCE(ring_treasure_table);
391  }
392 
393  if (!process_treasure_table(ring_treasure_table,
394  arraysize(ring_treasure_table),
395  total_chance,
396  op,
397  difficulty,
398  affinity,
399  &item_power)) {
400  object_destroy(op);
401  return OBJECT_METHOD_ERROR;
402  }
403  } else {
405  difficulty,
406  affinity,
407  &item_power)) {
408  object_destroy(op);
409  return OBJECT_METHOD_ERROR;
410  }
411  }
412  }
413 
414  process_treasure_set_item_power(op, item_power);
415 
416  return OBJECT_METHOD_OK;
417 }
418 
423 {
424  OBJECT_METHODS(RING)->apply_func = object_apply_item;
425  OBJECT_METHODS(RING)->process_treasure_func = process_treasure_func;
426 }
#define GT_ONLY_GOOD
Definition: treasure.h:63
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:239
void object_destroy(object *ob)
Definition: object.c:1441
#define RING_CHANCE_DAMNED
Definition: ring.c:47
static bool ring_set_bonus_damage(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:132
#define FLAG_CURSED
Definition: define.h:1154
static bool ring_set_bonus_regen_hp(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:76
bool process_treasure_table_jewelry(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power)
static bool ring_set_bonus_regen_sp(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:104
static bool ring_set_bonus_stat_con(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:267
#define OBJECT_METHOD_ERROR
The 'ring_normal' archetype.
Definition: arch.h:59
int64_t exp
Definition: living.h:69
void process_treasure_set_item_power(object *op, double item_power)
#define RING_CHANCE_EXTRA
Definition: ring.c:55
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:305
int16_t sp
Definition: living.h:78
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
struct archetype * arch
Definition: object.h:225
The 'ring_generic' archetype.
Definition: arch.h:60
void object_remove(object *op, int flags)
Definition: object.c:1623
int32_t hp
Definition: living.h:72
#define CON
Definition: living.h:43
#define FLAG_DAMNED
Definition: define.h:1158
archetype_t * arches[ARCH_MAX]
Definition: arch.c:45
const char * object_get_str(const object *op)
Definition: object.c:3151
static bool ring_set_bonus_stat_dex(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:251
#define RING_CHANCE_CURSED
Definition: ring.c:42
static bool ring_set_bonus_stat_int(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:283
int16_t dam
Definition: living.h:87
bool process_treasure_table(const process_treasure_table_t *table, size_t table_size, uint32_t total_chance, object *op, int difficulty, treasure_affinity_t *affinity, double *item_power)
#define SET_FLAG(xyz, p)
Definition: define.h:741
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
#define POW
Definition: living.h:47
#define DEX
Definition: living.h:41
#define PROCESS_TREASURE_TABLE_TOTAL_CHANCE(table)
static bool ring_set_bonus_stat_str(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:235
#define OBJECT_METHOD_UNHANDLED
#define FLAG_REMOVED
Definition: define.h:930
OBJECT_TYPE_INIT_DEFINE(ring)
Definition: ring.c:422
bool process_treasure_is_special(object *op)
int object_apply_item(object *op, object *applier, int aflags)
Definition: apply.c:110
#define RING
Definition: define.h:320
living stats
Definition: object.h:481
#define OBJECT_METHODS(type)
static bool ring_set_bonus_sustenance(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:160
bool artifact_generate(object *op, int difficulty, treasure_affinity_t *affinity)
Definition: artifact.c:541
#define RING_CHANCE_TABLE
Definition: ring.c:51
static bool ring_set_bonus_stat_pow(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:299
#define OBJECT_METHOD_OK
static bool ring_set_bonus_speed(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus)
Definition: ring.c:59
#define INT
Definition: living.h:45
static const process_treasure_table_t ring_treasure_table[]
Definition: ring.c:316
static int process_treasure_func(object *op, object **ret, int difficulty, treasure_affinity_t *affinity, int flags)
Definition: ring.c:331
static bool ring_set_bonus_stat(object *op, int difficulty, treasure_affinity_t *affinity, double *item_power, int bonus, int stat)
Definition: ring.c:201
#define STR
Definition: living.h:39
int64_t value
Definition: object.h:240
#define MAX_STAT
Definition: define.h:47
int16_t food
Definition: living.h:84