Go to the documentation of this file.
32 #include <sys/types.h>
42 #ifdef CF_MXE_CROSS_COMPILE
43 # define ffs(word) (__builtin_constant_p (word) \
44 ? __builtin_ffs (word) \
45 : ({ int __cnt, __tmp; \
46 __asm__ __volatile__ \
49 : "=&r" (__cnt), "=r" (__tmp) \
50 : "rm" (word), "1" (-1)); \
56 static void permute(
int *,
int,
int);
76 "spell_small_fireball",
77 "spell_medium_fireball",
78 "spell_large_fireball",
79 "spell_burning_hands",
81 "spell_large_lightning",
82 "spell_magic_missile",
85 "spell_summon_fire_elemental",
86 "spell_summon_earth_elemental",
87 "spell_summon_water_elemental",
88 "spell_summon_air_elemental",
89 "spell_dimension_door",
90 "spell_create_earth_wall",
93 "spell_magic_mapping",
99 "spell_perceive_self",
100 "spell_word_of_recall",
102 "spell_invisible_to_undead",
104 "spell_lg_magic_bullet",
105 "spell_improved_invisibility",
107 "spell_minor_healing",
108 "spell_medium_healing",
109 "spell_major_healing",
112 "spell_earth_to_dust",
116 "spell_constitution",
118 "spell_create_fire_wall",
119 "spell_create_frost_wall",
120 "spell_protection_from_cold",
121 "spell_protection_from_electricity",
122 "spell_protection_from_fire",
123 "spell_protection_from_poison",
124 "spell_protection_from_slow",
125 "spell_protection_from_paralysis",
126 "spell_protection_from_draining",
127 "spell_protection_from_magic",
128 "spell_protection_from_attack",
130 "spell_small_speedball",
131 "spell_large_speedball",
133 "spell_dragonbreath",
134 "spell_large_icestorm",
137 "spell_cancellation",
139 "spell_mass_confusion",
140 "spell_summon_pet_monster",
142 "spell_regenerate_spellpoints",
144 "spell_protection_from_confusion",
145 "spell_protection_from_cancellation",
146 "spell_protection_from_depletion",
148 "spell_remove_curse",
149 "spell_remove_damnation",
151 "spell_detect_magic",
152 "spell_detect_monster",
154 "spell_detect_curse",
162 "spell_face_of_death",
163 "spell_ball_lightning",
164 "spell_meteor_swarm",
168 "spell_resurrection",
169 "spell_reincarnation",
179 "spell_invulnerability",
181 "spell_rune_of_fire",
182 "spell_rune_of_frost",
183 "spell_rune_of_shocking",
184 "spell_rune_of_blasting",
185 "spell_rune_of_death",
186 "spell_marking_rune",
187 "spell_build_director",
188 "spell_create_pool_of_chaos",
189 "spell_build_bullet_wall",
190 "spell_build_lightning_wall",
191 "spell_build_fireball_wall",
193 "spell_rune_of_magic_drain",
194 "spell_antimagic_rune",
195 "spell_rune_of_transference",
196 "spell_transference",
198 "spell_counterspell",
200 "spell_cure_confusion",
204 "spell_cause_light_wounds",
205 "spell_cause_medium_wounds",
206 "spell_cause_heavy_wounds",
207 "spell_charm_monsters",
209 "spell_create_missile",
210 "spell_show_invisible",
215 "spell_command_undead",
217 "spell_summon_avatar",
218 "spell_holy_possession",
221 "spell_regeneration",
223 "spell_summon_cult_monsters",
224 "spell_cause_critical_wounds",
226 "spell_retributive_strike",
227 "spell_finger_of_death",
228 "spell_insect_plague",
229 "spell_call_holy_servant",
230 "spell_wall_of_thorns",
231 "spell_staff_to_snake",
238 "spell_cure_blindness",
240 "spell_bullet_swarm",
241 "spell_bullet_storm",
242 "spell_cause_many_wounds",
243 "spell_small_snowstorm",
244 "spell_medium_snowstorm",
245 "spell_large_snowstorm",
246 "spell_cure_disease",
247 "spell_cause_red_death",
249 "spell_cause_black_death",
250 "spell_cause_leprosy",
251 "spell_cause_smallpox",
252 "spell_cause_white_death",
253 "spell_cause_anthrax",
254 "spell_cause_typhoid",
256 "spell_small_manaball",
257 "spell_medium_manaball",
258 "spell_large_manaball",
260 "spell_dancing_sword",
261 "spell_animate_weapon",
263 "spell_divine_shock",
270 "spell_forked_lightning",
272 "spell_flaming_aura",
274 "spell_vitriol_splash",
276 "spell_wrathful_eye",
278 "spell_missile_swarm",
279 "spell_cause_rabies",
300 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1,
301 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1
306 0, -1, -1, 0, 1, 1, 1, 0, -1, -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2,
307 -3, -3, -3, -3, -2, -1, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3
312 0, 9, 10, 13, 14, 17, 18, 21, 22, 25, 26, 27, 30, 31, 32, 33, 36, 37, 39, 39, 42, 43, 44, 45,
313 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49
318 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8,
319 1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8
340 for (
int i = 1; i <
STARTMAX-1; i++) {
372 for (wants_field = wants->
key_values; wants_field != NULL; wants_field = wants_field->
next) {
378 if (has_field == NULL) {
438 if (
ob1->speed !=
ob2->speed)
452 if (
ob1->nrof+
ob2->nrof >= 1UL<<31)
459 if (
ob1->inv ||
ob2->inv) {
489 if ((
ob1->arch !=
ob2->arch)
490 || (
ob1->flags[0] !=
ob2->flags[0])
491 || (
ob1->flags[1] !=
ob2->flags[1])
492 || (
ob1->flags[2] !=
ob2->flags[2])
493 || ((
ob1->flags[3]&~0x84) != (
ob2->flags[3]&~0x84))
494 || (
ob1->name !=
ob2->name)
495 || (
ob1->title !=
ob2->title)
497 || (
ob1->weight !=
ob2->weight)
498 || (
ob1->item_power !=
ob2->item_power)
499 || (memcmp(&
ob1->resist, &
ob2->resist,
sizeof(
ob1->resist)) != 0)
500 || (memcmp(&
ob1->stats, &
ob2->stats,
sizeof(
ob1->stats)) != 0)
501 || (
ob1->attacktype !=
ob2->attacktype)
502 || (
ob1->magic !=
ob2->magic)
503 || (
ob1->slaying !=
ob2->slaying)
504 || (
ob1->skill !=
ob2->skill)
505 || (
ob1->value !=
ob2->value)
506 || (
ob1->animation !=
ob2->animation)
507 || (
ob1->client_type !=
ob2->client_type)
508 || (
ob1->materialname !=
ob2->materialname)
509 || (
ob1->lore !=
ob2->lore)
510 || (
ob1->subtype !=
ob2->subtype)
511 || (
ob1->move_type !=
ob2->move_type)
512 || (
ob1->move_block !=
ob2->move_block)
513 || (
ob1->move_allow !=
ob2->move_allow)
514 || (
ob1->move_on !=
ob2->move_on)
515 || (
ob1->move_off !=
ob2->move_off)
516 || (
ob1->move_slow !=
ob2->move_slow)
517 || (
ob1->move_slow_penalty !=
ob2->move_slow_penalty)
518 || (
ob1->map_layer !=
ob2->map_layer))
528 if (
ob1->key_values != NULL ||
ob2->key_values != NULL) {
530 if ((
ob1->key_values == NULL) != (
ob2->key_values == NULL)) {
543 if (
ob1->level !=
ob2->level)
578 sum = (sum*(100-
op->stats.Str))/100;
591 while (
op->env != NULL)
625 if (
op->owner == NULL)
630 &&
op->owner->count ==
op->ownercount)
653 if (
op->arch != NULL) {
660 if (
op->artifact != NULL) {
682 if (
op->attacked_by) {
805 if (
op->owner == NULL)
810 &&
op->owner->count ==
op->ownercount)
870 if (
op->owner != NULL)
916 if (
op->enemy == enemy) {
922 LOG(
llevDebug,
"object_set_enemy: %s(%lu)->enemy=%s(%lu)\n",
op->name,
op->count, enemy == NULL ?
"NONE" : enemy->
name, enemy == NULL ? 0 : enemy->
count);
942 op->materialname = NULL;
958 if (
op->key_values == NULL)
961 for (i =
op->key_values; i != NULL; i =
next) {
973 op->key_values = NULL;
996 if (
op->name != NULL)
998 if (
op->name_pl != NULL)
1000 if (
op->title != NULL)
1002 if (
op->race != NULL)
1004 if (
op->slaying != NULL)
1006 if (
op->skill != NULL)
1008 if (
op->msg != NULL)
1010 if (
op->lore != NULL)
1012 if (
op->materialname != NULL)
1031 op->container = NULL;
1036 op->active_next = NULL;
1037 op->active_prev = NULL;
1042 op->attacked_by_count = -1;
1044 op->casting_time = -1;
1068 if (dest_ob->
name != NULL)
1074 if (dest_ob->
title != NULL)
1076 if (dest_ob->
race != NULL)
1080 if (dest_ob->
skill != NULL)
1082 if (dest_ob->
msg != NULL)
1084 if (dest_ob->
lore != NULL)
1107 if (dest_ob->
name != NULL)
1113 if (dest_ob->
title != NULL)
1115 if (dest_ob->
race != NULL)
1119 if (dest_ob->
skill != NULL)
1121 if (dest_ob->
lore != NULL)
1123 if (dest_ob->
msg != NULL)
1136 if (dest_ob->
arch != NULL) {
1141 if (src_ob->
speed < 0)
1154 new_link->
next = NULL;
1159 new_link->
value = NULL;
1166 tail->
next = new_link;
1223 #ifndef MEMORY_DEBUG
1241 add[0].
next = &add[1],
1246 add[i].
next = &add[i+1],
1247 add[i].
prev = &add[i-1],
1281 op =
static_cast<object *
>(calloc(1,
sizeof(
object)));
1309 op->materialname = NULL;
1312 op->active_next = NULL;
1313 op->active_prev = NULL;
1314 op->spell_tags = NULL;
1372 if (
op->active_next != NULL)
1373 op->active_next->active_prev =
op;
1397 if (
op->active_prev == NULL) {
1399 if (
op->active_next != NULL)
1400 op->active_next->active_prev = NULL;
1402 op->active_prev->active_next =
op->active_next;
1403 if (
op->active_next)
1404 op->active_next->active_prev =
op->active_prev;
1406 op->active_next = NULL;
1407 op->active_prev = NULL;
1435 int update_now = 0,
flags;
1436 MoveType move_on, move_off, move_block, move_slow;
1441 LOG(
llevDebug,
"object_update() called for NULL object.\n");
1445 if (
op->env != NULL) {
1461 LOG(
llevError,
"object_update() called for object out of map!\n");
1488 if ((move_on|
op->move_on) != move_on)
1490 if ((move_off|
op->move_off) != move_off)
1495 if (((move_block|
op->move_block)&~
op->move_allow) != move_block)
1497 if ((move_slow|
op->move_slow) != move_slow)
1531 if (!
pl->contr->socket->update_look) {
1544 if (
op->more != NULL)
1570 object *
inv =
ob->inv;
1597 LOG(
llevError,
"Free object called with non removed object\n");
1618 LOG(
llevError,
"Trying to free freed object.\n%s\n", diff);
1659 for (part =
ob; part; part = part->
more) {
1663 partcount =
RANDOM()%partcount;
1664 for (part =
ob; partcount > 0; partcount--) {
1684 if (
ob->more != NULL) {
1697 if (
ob->prev == NULL) {
1702 ob->prev->next =
ob->next;
1703 if (
ob->next != NULL)
1704 ob->next->prev =
ob->prev;
1726 if (
ob->arch &&
ob->arch->reference_count > 0) {
1727 if (--
ob->arch->reference_count == 0) {
1808 while (
op != NULL) {
1810 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
1812 op->carrying -= weight;
1834 object *last = NULL;
1848 LOG(
llevError,
"Trying to remove removed object.\n%s\n", diff);
1852 if (
op->more != NULL)
1862 if (
op->env != NULL) {
1871 if (
op->env->contr != NULL &&
op->head == NULL) {
1872 pl =
op->env->contr;
1875 if (
op->env->env &&
op->env->env->contr)
1877 pl =
op->env->env->contr;
1878 else if (
op->env->map) {
1880 object *above =
op->env->above;
1882 while (above && !above->
contr)
1883 above = above->
above;
1899 if (
op->above != NULL)
1900 op->above->below =
op->below;
1902 op->env->inv =
op->below;
1904 if (
op->below != NULL)
1905 op->below->above =
op->above;
1908 op->env->event_bitmask = 0;
1919 op->map =
op->env->map;
1931 if (
op->map == NULL)
1934 if (
op->contr != NULL && !
op->contr->hidden)
1942 LOG(
llevError,
"object_remove called when object was on map but appears to not be within valid coordinates? %s (%d,%d)\n",
op->map->path,
op->x,
op->y);
1946 LOG(
llevError,
"object_remove: Object not really on map it claimed to be on? %s != %s, %d,%d != %d,%d\n",
op->map->path,
m->path,
op->x,
op->y,
x,
y);
1951 op->above->below =
op->below;
1957 op->below->above =
op->above;
1971 LOG(
llevError,
"object_remove: GET_MAP_OB on %s does not return object to be removed even though it appears to be on the bottom?\n%s\n",
m->path, diff);
2000 if (
tmp->container ==
op) {
2002 tmp->container = NULL;
2004 tmp->contr->socket->update_look = 1;
2008 && ((
op->move_type&
tmp->move_off) && (
op->move_type&~
tmp->move_off&~
tmp->move_block) == 0)) {
2011 LOG(
llevError,
"BUG: object_remove(): name %s, archname %s destroyed leaving object\n",
tmp->name,
tmp->arch->name);
2103 tmp->x =
x+
tmp->arch->clone.x;
2104 tmp->y =
y+
tmp->arch->clone.y;
2145 if (
op->type ==
tmp->type
2146 &&
op->subtype ==
tmp->subtype
2147 &&
op->direction ==
tmp->direction
2148 &&
op->owner ==
tmp->owner &&
op->ownercount ==
tmp->ownercount
2149 &&
op->range ==
tmp->range
2150 &&
op->stats.wc ==
tmp->stats.wc
2151 &&
op->level ==
tmp->level
2152 &&
op->attacktype ==
tmp->attacktype
2153 &&
op->speed ==
tmp->speed
2155 && (
tmp->speed_left+
tmp->speed) < 0.0
2187 if (
tmp->spell_tags &&
op->spell_tags) {
2195 if (
op->spell_tags[i] &&
tmp->spell_tags[i]
2196 &&
op->spell_tags[i] !=
tmp->spell_tags[i]) {
2204 if ((!
op->spell_tags[i] &&
tmp->spell_tags[i])
2205 || (
op->spell_tags[i] && !
tmp->spell_tags[i])) {
2224 if (!
op->spell_tags[i]
2225 &&
tmp->spell_tags[i]
2226 &&
tmp->spell_tags[i] != (
tag_t)
op->stats.maxhp)
2227 op->spell_tags[i] =
tmp->spell_tags[i];
2233 if (
tmp->spell_tags && !
op->spell_tags) {
2234 op->spell_tags =
tmp->spell_tags;
2235 tmp->spell_tags = NULL;
2249 if (
op->stats.maxhp !=
tmp->stats.maxhp) {
2263 if (!
op->spell_tags)
2270 op->speed_left =
MAX(
op->speed_left,
tmp->speed_left);
2272 if (
tmp->duration !=
op->duration) {
2276 int tmp_dam =
tmp->stats.dam*(
tmp->duration+1)+
2277 op->stats.dam*(
op->duration+1);
2279 op->duration =
MAX(
op->duration,
tmp->duration);
2280 tmp_dam /=
op->duration+1;
2281 op->stats.dam = tmp_dam+1;
2286 op->stats.dam +=
tmp->stats.dam;
2296 object *floor = NULL;
2312 object *last = NULL;
2360 object *
tmp, *
top, *floor = NULL;
2374 LOG(
llevError,
"Trying to insert in null-map!\n%s\n", diff);
2385 LOG(
llevError,
"Trying to insert object outside the map.\n%s\n", diff);
2403 LOG(
llevError,
"Trying to insert (map) inserted object.\n%s\n", diff);
2407 if (
op->more != NULL) {
2410 object *more =
op->more;
2422 }
else if (!more->
map) {
2431 LOG(
llevError,
"BUG: object_insert_in_map(): inserting op->more killed op\n");
2450 op->nrof += spot->nrof;
2458 && (
op->speed_left+
op->speed) < 0.0) {
2489 if (originator->
map !=
op->map
2490 || originator->
x !=
op->x
2491 || originator->
y !=
op->y) {
2492 LOG(
llevError,
"object_insert_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
2495 op->above = originator;
2496 op->below = originator->
below;
2498 op->below->above =
op;
2511 op->above->below =
op;
2515 op->above =
top->above;
2517 op->above->below =
op;
2521 if (
op->above == NULL)
2527 op->contr->do_los = 1;
2535 tmp->contr->socket->update_look = 1;
2550 if (
op->contr && !
op->contr->hidden)
2597 if (!strcmp(
tmp->arch->name, arch_string)) {
2631 object *
object_split(
object *orig_ob, uint32_t nr,
char *err,
size_t size) {
2634 if (
MAX(1, orig_ob->
nrof) < nr) {
2637 snprintf(err, size,
"There are only %u %ss.",
NROF(orig_ob), orig_ob->
name);
2643 if (orig_ob->
nrof == 0) {
2681 }
else if (
op->env != NULL) {
2696 if (
pl->ob->container ==
op->env)
2729 pl->contr->socket->update_look = 1;
2765 }
else if (
op->env != NULL) {
2779 if (
pl->ob->container ==
op->env)
2806 pl->contr->socket->update_look = 1;
2828 while (
op != NULL) {
2830 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
2832 op->carrying += weight;
2861 LOG(
llevError,
"Trying to insert (ob) inserted object.\n%s\n", diff);
2866 if (
where == NULL) {
2873 LOG(
llevError,
"Trying to put object in NULL.\n%s\n", diff);
2878 LOG(
llevDebug,
"Warning: Tried to insert object wrong part of multipart object.\n");
2882 LOG(
llevError,
"Tried to insert multipart object %s (%u)\n",
op->name,
op->count);
2892 tmp->stats.exp +=
op->stats.exp;
2893 tmp->total_exp +=
op->total_exp;
2924 if (
where->inv == NULL)
2928 op->below->above =
op;
2938 if (
where->contr != NULL)
2943 if (
op->env->env &&
op->env->env->contr)
2946 else if (
op->env->map) {
2960 if (otmp && otmp->
contr != NULL) {
2969 if (
op->glow_radius != 0 &&
where->map) {
2971 LOG(
llevDebug,
" object_insert_in_ob(): got %s to insert in map/op\n",
op->name);
3009 int x =
op->x,
y =
op->y;
3010 MoveType move_on, move_slow, move_block;
3027 && !(
op->move_type&move_on)
3028 && !(
op->move_type&move_slow))
3036 if ((
op->move_type&~move_on&~move_block) != 0
3037 && (
op->move_type&~move_slow&~move_block) != 0)
3046 if (
tmp->above == NULL)
3067 || ((
op->move_type&
tmp->move_slow) && (
op->move_type&~
tmp->move_slow&~
tmp->move_block) == 0)) {
3070 diff =
tmp->move_slow_penalty*
FABS(
op->speed);
3077 op->speed_left -= diff;
3083 || ((
op->move_type&
tmp->move_on) && (
op->move_type&~
tmp->move_on&~
tmp->move_block) == 0)) {
3092 if (
op->map !=
m ||
op->x !=
x ||
op->y !=
y)
3118 if (
tmp->arch == at)
3219 if (
tmp->arch == at)
3290 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3313 ix = gen->
x-sx-genx2;
3314 iy = gen->
y-sy-geny2;
3326 for (i = 0; i < (sx+sx+sy+sy); i++) {
3330 }
else if (i <= sx+sy) {
3333 }
else if (i <= sx+sy+sx) {
3334 nx = ix+sx-(i-(sx+sy));
3338 ny = iy+sy-(i-(sx+sy+sx));
3351 freecount =
RANDOM()%freecount;
3352 for (i = 0; i < sx+sx+sy+sy; i++) {
3356 }
else if (i <= sx+sy) {
3359 }
else if (i <= sx+sy+sx) {
3360 nx = ix+sx-(i-(sx+sy));
3364 ny = iy+sy-(i-(sx+sy+sx));
3376 if (freecount <= 0) {
3406 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3407 int8_t
x,
y, radius;
3408 int freecount = 0, freecountstop = 0;
3416 radius = (int8_t)strtol(
value, NULL, 10);
3448 ix = gen->
x-sx-genx2-radius+1;
3449 iy = gen->
y-sy-geny2-radius+1;
3450 sx += genx+sx2+radius*2-1;
3451 sy += geny+sy2+radius*2-1;
3461 x_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3462 y_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3467 for (
x = 0;
x < sx;
x++) {
3468 for (
y = 0;
y < sy;
y++) {
3481 x_array[freecount] = nx;
3482 y_array[freecount] = ny;
3495 freecountstop =
RANDOM()%freecount;
3496 for (i = 0; i < freecount; i++) {
3504 if (freecountstop <= 0) {
3553 int i,
index = 0, flag;
3556 for (i = start; i <
stop; i++) {
3559 altern[
index++] = i;
3611 static void permute(
int *arr,
int begin,
int end) {
3615 for (i = begin; i < end; i++) {
3867 if (
item->weight <= 0)
3873 if (
item->invisible)
3903 object *dst = NULL, *
tmp, *src, *part, *prev;
3910 for (part = src; part; part = part->more) {
3917 tmp->carrying =
tmp->arch->clone.carrying;
3954 if (
tmp->name == name_shared)
4002 for (
int i = 0; i < num_flags; ++i) {
4034 if (
tmp->type == type1 ||
tmp->type == type2)
4130 if (
tmp->type ==
type && strcmp(
tmp->race, race) == 0)
4155 if (
tmp->type ==
type &&
tmp->slaying != NULL && strcmp(
tmp->slaying, slaying) == 0)
4180 if (
tmp->type ==
type &&
tmp->skill != NULL && strcmp(
tmp->skill, skill) == 0)
4249 if (strcmp(
tmp->arch->name,
name) == 0)
4298 if (
tmp->type ==
type &&
tmp->subtype == subtype)
4317 for (link =
ob->key_values; link != NULL; link = link->
next) {
4341 const char *canonical_key;
4345 if (canonical_key == NULL) {
4357 for (link =
op->key_values; link != NULL; link = link->
next) {
4358 if (link->
key == canonical_key) {
4371 if (ret == NULL || (strcmp(ret,
"") == 0) || (strcmp(ret,
"0") == 0)) {
4384 for (
key_value *link =
op->key_values; link != NULL; link = link->next) {
4385 if (link->key ==
key) {
4386 if ((strcmp(link->value,
"") == 0) || (strcmp(link->value,
"0") == 0)) {
4412 for (field =
op->key_values; field != NULL; field = field->
next) {
4413 if (field->
key != canonical_key) {
4429 field->
value = NULL;
4437 last->next = field->
next;
4439 op->key_values = field->
next;
4466 field->
next =
op->key_values;
4467 op->key_values = field;
4493 const char *canonical_key = NULL;
4494 int floating_ref =
FALSE;
4502 if (canonical_key == NULL) {
4504 floating_ref =
TRUE;
4569 int count, retval = 0;
4574 for (cp = strtok(local_name,
","); cp; cp = strtok(NULL,
",")) {
4575 while (cp[0] ==
' ')
4580 if (!strcmp(cp,
"all"))
4586 if (!strcmp(cp,
"cursed")
4596 if (*cp ==
'+' || *cp ==
'-')
4599 cp = strchr(cp,
' ');
4600 while (cp && cp[0] ==
' ')
4609 if (!cp || cp[0] ==
'\0' ||
count < 0)
4631 else if (custom_name && !
strcasecmp(cp, custom_name))
4633 else if (!strncasecmp(cp, bname_s, strlen(cp)))
4635 else if (!strncasecmp(cp, bname_p, strlen(cp)))
4642 else if (strstr(bname_p, cp))
4644 else if (strstr(bname_s, cp))
4646 else if (strstr(name_short, cp))
4658 else if (custom_name && strstr(custom_name, cp))
4683 LOG(
llevError,
"object_fix_multipart: not on a map!\n");
4688 if (
tmp->head ||
tmp->more)
4694 for (at =
tmp->arch->more, last =
tmp; at != NULL; at = at->
more, last =
op) {
4703 if (
tmp->name !=
op->name) {
4708 if (
tmp->title !=
op->title) {
4739 int maxx = 0, maxy = 0, minx = 0, miny = 0;
4744 if (
ob->arch->more) {
4745 for (part =
ob->arch; part; part = part->
more) {
4746 if (part->
clone.
x > maxx)
4748 if (part->
clone.
y > maxy)
4750 if (part->
clone.
x < minx)
4752 if (part->
clone.
y < miny)
4805 if (
op->msg != NULL) {
4811 if (*
msg !=
'\0' && strchr(
msg,
'\0')[-1] !=
'\n') {
4845 "alive",
"wiz", NULL, NULL,
"was_wiz",
"applied",
"unpaid",
4846 "can_use_shield",
"no_pick",
"client_anim_sync",
"client_anim_random",
4847 "is_animated", NULL ,
4848 NULL ,
"monster",
"friendly",
"generator",
4849 "is_thrown",
"auto_apply",
"treasure",
"player sold",
4850 "see_invisible",
"can_roll",
"overlay_floor",
4851 "is_turnable", NULL , NULL ,
4852 NULL ,
"is_used_up",
"identified",
"reflecting",
4853 "changing",
"splitting",
"hitback",
"startequip",
4854 "blocksview",
"undead",
"scared",
"unaggressive",
4855 "reflect_missile",
"reflect_spell",
4856 "no_magic",
"no_fix_player",
"is_lightable",
"tear_down",
4857 "run_away", NULL , NULL ,
4858 NULL ,
"unique",
"no_drop",
4859 NULL ,
"can_cast_spell",
"can_use_scroll",
"can_use_range",
4860 "can_use_bow",
"can_use_armour",
"can_use_weapon",
4861 "can_use_ring",
"has_ready_range",
"has_ready_bow",
4862 "xrays", NULL,
"is_floor",
"lifesave",
"no_strength",
"sleep",
4863 "stand_still",
"random_movement",
"only_attack",
"confused",
4864 "stealth", NULL, NULL,
"cursed",
"damned",
4865 "see_anywhere",
"known_magical",
"known_cursed",
4866 "can_use_skill",
"been_applied",
4867 "has_ready_scroll", NULL, NULL,
4868 NULL,
"make_invisible",
"inv_locked",
"is_wooded",
4869 "is_hilly",
"has_ready_skill",
"has_ready_weapon",
4870 "no_skill_ident",
"is_blind",
"can_see_in_dark",
"is_cauldron",
4871 NULL,
"no_steal",
"one_hit", NULL,
"berserk",
"neutral",
4872 "no_attack",
"no_damage", NULL, NULL,
"activate_on_push",
4873 "activate_on_release",
"is_water",
"use_content_on_gen", NULL,
"is_buildable",
4874 NULL,
"blessed",
"known_blessed"
4888 int i, all_count = 0,
count;
4891 strcpy(retbuf_all,
" all");
4908 if (mt&(1<<
count)) {
4909 strcat(retbuf,
" ");
4912 strcat(retbuf_all,
" -");
4954 for (
int i = 0; i < 4; i++) {
4955 int idx = ffs((*diff)[i]);
4959 (*diff)[i] &= ~(1 << bit);
4980 static char buf2[64];
4989 for (my_field =
op->key_values; my_field != NULL; my_field = my_field->
next) {
4994 if (arch_field == NULL || my_field->
value != arch_field->
value) {
5000 if (my_field->
value)
5009 if (
op->name &&
op->name != op2->
name) {
5018 if (
op->title &&
op->title != op2->
title) {
5021 if (
op->race &&
op->race != op2->
race) {
5027 if (
op->skill &&
op->skill != op2->
skill) {
5030 if (
op->msg &&
op->msg != op2->
msg) {
5035 if (
op->lore &&
op->lore != op2->
lore) {
5040 if (
op->other_arch != op2->
other_arch &&
op->other_arch != NULL &&
op->other_arch->name) {
5043 if (
op->face != op2->
face) {
5048 if (
op->animation) {
5085 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->stats.exp);
5090 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->total_exp);
5106 if (
op->x != op2->
x)
5108 if (
op->y != op2->
y)
5110 if (
op->speed != op2->
speed) {
5126 if (
op->nrof != op2->
nrof)
5132 if (
op->type != op2->
type)
5329 LOG(
llevError,
"could not find original archetype %s for custom monster!\n", at->
name);
5343 }
else if (
op->artifact != NULL) {
5350 LOG(
llevError,
"could not find artifact %s [%d] to save data\n",
op->artifact,
op->type);
5387 if (fputs(cp, fp) == EOF) {
5399 if (death_animation != NULL) {
5402 if (death != NULL) {
5419 if (
force == NULL) {
5425 if (duration != 0) {
5426 force->speed = 0.01;
5427 force->speed_left = -duration;
#define object_was_destroyed(op, old_tag)
bool object_value_set(const object *op, const char *const key)
static object * free_objects
#define GET_MAP_OB(M, X, Y)
static const object * object_get_owner_const(const object *op)
object * object_get_owner(object *op)
#define FREE_AND_CLEAR_STR_IF(xyz)
#define FREE_OBJ_NO_DESTROY_CALLBACK
object * object_find_by_type_subtype(const object *who, int type, int subtype)
void object_clear_owner(object *op)
static void permute(int *, int, int)
object * object_get_env_recursive(object *op)
void object_update_turn_face(object *op)
void remove_friendly_object(object *op)
int object_count_active(void)
object * object_find_by_type_applied(const object *who, int type)
#define NUM_BODY_LOCATIONS
const artifact * find_artifact(const object *op, const char *name)
#define GET_MAP_TOP(M, X, Y)
struct Statistics statistics
void object_set_flag_inv(object *op, int flag)
#define FLAG_CLIENT_ANIM_RANDOM
object * find_skill_by_number(object *who, int skillno)
void LOG(LogLevel logLevel, const char *format,...)
static void ADD_STRINGLINE_ENTRY(StringBuffer *sb, const char *name, const char *value)
#define FLAG_OVERLAY_FLOOR
void object_free_all_data(void)
#define QUERY_FLAG(xyz, p)
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
object * object_merge(object *op, object *top)
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
void update_position(mapstruct *m, int x, int y)
#define BITMASK_EVENT(evt)
#define SET_MAP_TOP(M, X, Y, tmp)
StringBuffer * stringbuffer_new(void)
static const char *const flag_names[NUM_FLAGS+1]
void object_set_enemy(object *op, object *enemy)
void object_insert_to_free_spot_or_free(object *op, mapstruct *map, int x, int y, int start, int stop, object *originator)
#define FLAG_OBJ_ORIGINAL
#define OB_SPELL_TAG_MATCH(op, count)
void object_dump_all(void)
void give_artifact_abilities(object *op, const object *artifact)
int object_find_first_free_spot(const object *ob, mapstruct *m, int x, int y)
object * arch_present_in_ob(const archetype *at, const object *op)
void object_set_owner(object *op, object *owner)
static int object_set_value_s(object *, const char *, const char *, int)
void object_handle_death_animation(object *op)
#define GET_MAP_MOVE_SLOW(M, X, Y)
void object_reset(object *op)
static const flag_definition flags[]
void object_copy(const object *src_ob, object *dest_ob)
void fix_object(object *op)
object * object_find_by_flag_applied(const object *who, int flag)
int object_find_multi_free_spot_within_radius(const object *ob, const object *gen, int *hx, int *hy)
object * object_find_by_type_and_skill(const object *who, int type, const char *skill)
#define GET_MAP_PLAYER(M, X, Y)
int flags_differ(ob_flags *diff)
#define FOR_ABOVE_PREPARE(op_, it_)
void object_copy_with_inv(const object *src_ob, object *dest_ob, bool update_speed)
void stringbuffer_append_char(StringBuffer *sb, const char c)
static int compare_ob_value_lists(const object *, const object *)
void free_arch(archetype *at)
#define FOR_OB_AND_ABOVE_FINISH()
object * object_find_by_tag_global(tag_t i)
const char * object_get_value(const object *op, const char *const key)
static void expand_objects(void)
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
void object_merge_spell(object *op, int16_t x, int16_t y)
object * object_insert_in_ob(object *op, object *where)
static void FAST_SAVE_DOUBLE(StringBuffer *sb, const char *name, const double value)
void stringbuffer_append_int64(StringBuffer *sb, int64_t x)
method_ret ob_move_on(object *op, object *victim, object *originator)
int16_t resist[NROFATTACKS]
#define FLAG_DIALOG_PARSED
void object_clear(object *op)
void esrv_send_item(object *pl, object *op)
#define INS_ABOVE_FLOOR_ONLY
#define FOR_OB_AND_ABOVE_PREPARE(op_)
#define FLAG_IS_A_TEMPLATE
object * object_find_by_type_and_race(const object *who, int type, const char *race)
static event_registration m
char * stringbuffer_finish(StringBuffer *sb)
void object_free_drop_inventory(object *ob)
void object_update(object *op, int action)
static uint32_t NROF(const object *const ob)
object * object_find_by_name(const object *who, const char *name)
key_value * object_get_key_value(const object *ob, const char *key)
object * object_find_by_type2(const object *who, int type1, int type2)
sstring add_refcount(sstring str)
bool object_value_set_shared(const object *op, sstring key)
short freearr_y[SIZEOFFREE]
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
void query_name(const object *op, char *buf, size_t size)
object * map_find_by_type(mapstruct *m, int x, int y, uint8_t type)
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
#define FLAG_KNOWN_CURSED
sstring stringbuffer_finish_shared(StringBuffer *sb)
#define FOR_ABOVE_FINISH()
void object_dump(const object *op, StringBuffer *sb)
sstring add_string(const char *str)
int object_count_free(void)
#define FOR_OB_AND_BELOW_FINISH()
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
object * object_find_by_type_and_name(const object *who, int type, const char *name)
void query_short_name(const object *op, char *buf, size_t size)
int out_of_map(mapstruct *m, int x, int y)
sstring find_string(const char *str)
void object_update_speed(object *op)
#define SET_MAP_FLAGS(M, X, Y, C)
object * object_find_by_tag(const object *who, tag_t tag)
object * object_find_by_flag(const object *who, int flag)
void object_free(object *ob, int flags)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
#define INS_BELOW_ORIGINATOR
const char *const resist_save[NROFATTACKS]
const typedef char * sstring
body_locations_struct body_locations[NUM_BODY_LOCATIONS]
int object_matches_string(object *pl, object *op, const char *name)
int object_find_multi_free_spot_around(const object *ob, const object *gen, int16_t *hx, int16_t *hy)
void stringbuffer_append_string(StringBuffer *sb, const char *str)
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
#define FOR_OB_AND_BELOW_PREPARE(op_)
static void compare_flags(ob_flags *ret, const object *p, const object *q)
const Animations * animation
#define GET_MAP_MOVE_ON(M, X, Y)
#define FREE_OBJ_DROP_ABOVE_FLOOR
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
object * object_find_by_type_without_flags(const object *who, int type, int *flags, int num_flags)
static const int reduction_dir[SIZEOFFREE][3]
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
struct archetype * other_arch
object * object_create_clone(object *asrc)
void object_copy_no_speed(const object *src_ob, object *dest_ob)
void fatal(enum fatal_error err)
const char *const move_name[]
void object_set_cheat(object *op)
object * object_new(void)
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
void esrv_del_item(player *pl, object *ob)
object * create_archetype(const char *name)
object * object_present_in_ob(uint8_t type, const object *op)
uint32_t get_weight_limit(int stat)
void free_string(sstring str)
#define offsetof(type, member)
#define FREE_AND_CLEAR_STR(xyz)
#define FLAG_CLIENT_ANIM_SYNC
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
#define OUT_OF_REAL_MAP(M, X, Y)
void get_search_arr(int *search_arr)
int find_dir_2(int x, int y)
void object_add_weight(object *op, signed long weight)
object * object_decrease_nrof(object *op, uint32_t i)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
uint8_t duration_modifier
int object_count_used(void)
#define FREE_AND_CLEAR(xyz)
object * object_find_by_arch_name(const object *who, const char *name)
int object_can_pick(const object *who, const object *item)
#define SCRIPT_FIX_NOTHING
static object objarray[STARTMAX]
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
object * object_find_by_type(const object *who, int type)
object * object_find_by_name_global(const char *str)
static void get_string_move_type(StringBuffer *sb, MoveType mt)
void animate_object(object *op, int dir)
archetype * find_archetype(const char *name)
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
void object_set_msg(object *op, const char *msg)
void esrv_update_item(int flags, object *pl, object *op)
const char *const spell_mapping[SPELL_MAPPINGS]
#define FLAG_NO_FIX_PLAYER
void object_unset_flag_inv(object *op, int flag)
void object_free_key_values(object *op)
object * add_force(object *op, const char *name, int duration)
#define FLAG_BEEN_APPLIED
#define CLEAR_FLAG(xyz, p)
#define SET_MAP_OB(M, X, Y, tmp)
void save_object_in_sb(StringBuffer *sb, object *op, const int flag)
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
void object_remove_from_active_list(object *op)
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
object * arch_to_object(archetype *at)
static object * find_insert_pos(object *op, const int flag)