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;
2006 tmp->contr->socket->update_look = 1;
2010 && ((
op->move_type&
tmp->move_off) && (
op->move_type&~
tmp->move_off&~
tmp->move_block) == 0)) {
2013 LOG(
llevError,
"BUG: object_remove(): name %s, archname %s destroyed leaving object\n",
tmp->name,
tmp->arch->name);
2105 tmp->x =
x+
tmp->arch->clone.x;
2106 tmp->y =
y+
tmp->arch->clone.y;
2147 if (
op->type ==
tmp->type
2148 &&
op->subtype ==
tmp->subtype
2149 &&
op->direction ==
tmp->direction
2150 &&
op->owner ==
tmp->owner &&
op->ownercount ==
tmp->ownercount
2151 &&
op->range ==
tmp->range
2152 &&
op->stats.wc ==
tmp->stats.wc
2153 &&
op->level ==
tmp->level
2154 &&
op->attacktype ==
tmp->attacktype
2155 &&
op->speed ==
tmp->speed
2157 && (
tmp->speed_left+
tmp->speed) < 0.0
2189 if (
tmp->spell_tags &&
op->spell_tags) {
2197 if (
op->spell_tags[i] &&
tmp->spell_tags[i]
2198 &&
op->spell_tags[i] !=
tmp->spell_tags[i]) {
2206 if ((!
op->spell_tags[i] &&
tmp->spell_tags[i])
2207 || (
op->spell_tags[i] && !
tmp->spell_tags[i])) {
2226 if (!
op->spell_tags[i]
2227 &&
tmp->spell_tags[i]
2228 &&
tmp->spell_tags[i] != (
tag_t)
op->stats.maxhp)
2229 op->spell_tags[i] =
tmp->spell_tags[i];
2235 if (
tmp->spell_tags && !
op->spell_tags) {
2236 op->spell_tags =
tmp->spell_tags;
2237 tmp->spell_tags = NULL;
2251 if (
op->stats.maxhp !=
tmp->stats.maxhp) {
2265 if (!
op->spell_tags)
2272 op->speed_left =
MAX(
op->speed_left,
tmp->speed_left);
2274 if (
tmp->duration !=
op->duration) {
2278 int tmp_dam =
tmp->stats.dam*(
tmp->duration+1)+
2279 op->stats.dam*(
op->duration+1);
2281 op->duration =
MAX(
op->duration,
tmp->duration);
2282 tmp_dam /=
op->duration+1;
2283 op->stats.dam = tmp_dam+1;
2288 op->stats.dam +=
tmp->stats.dam;
2298 object *floor = NULL;
2314 object *last = NULL;
2362 object *
tmp, *
top, *floor = NULL;
2376 LOG(
llevError,
"Trying to insert in null-map!\n%s\n", diff);
2387 LOG(
llevError,
"Trying to insert object outside the map.\n%s\n", diff);
2405 LOG(
llevError,
"Trying to insert (map) inserted object.\n%s\n", diff);
2409 if (
op->more != NULL) {
2412 object *more =
op->more;
2424 }
else if (!more->
map) {
2433 LOG(
llevError,
"BUG: object_insert_in_map(): inserting op->more killed op\n");
2445 if (
op->map == NULL) {
2456 op->nrof += spot->nrof;
2464 && (
op->speed_left+
op->speed) < 0.0) {
2495 if (originator->
map !=
op->map
2496 || originator->
x !=
op->x
2497 || originator->
y !=
op->y) {
2498 LOG(
llevError,
"object_insert_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
2501 op->above = originator;
2502 op->below = originator->
below;
2504 op->below->above =
op;
2517 op->above->below =
op;
2521 op->above =
top->above;
2523 op->above->below =
op;
2527 if (
op->above == NULL)
2533 op->contr->do_los = 1;
2541 tmp->contr->socket->update_look = 1;
2556 if (
op->contr && !
op->contr->hidden)
2603 if (!strcmp(
tmp->arch->name, arch_string)) {
2637 object *
object_split(
object *orig_ob, uint32_t nr,
char *err,
size_t size) {
2640 if (
MAX(1, orig_ob->
nrof) < nr) {
2643 snprintf(err, size,
"There are only %u %ss.",
NROF(orig_ob), orig_ob->
name);
2649 if (orig_ob->
nrof == 0) {
2687 }
else if (
op->env != NULL) {
2702 if (
pl->ob->container ==
op->env)
2735 pl->contr->socket->update_look = 1;
2771 }
else if (
op->env != NULL) {
2785 if (
pl->ob->container ==
op->env)
2812 pl->contr->socket->update_look = 1;
2834 while (
op != NULL) {
2836 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
2838 op->carrying += weight;
2867 LOG(
llevError,
"Trying to insert (ob) inserted object.\n%s\n", diff);
2872 if (
where == NULL) {
2879 LOG(
llevError,
"Trying to put object in NULL.\n%s\n", diff);
2884 LOG(
llevDebug,
"Warning: Tried to insert object wrong part of multipart object.\n");
2888 LOG(
llevError,
"Tried to insert multipart object %s (%u)\n",
op->name,
op->count);
2899 tmp->stats.exp +=
op->stats.exp;
2900 tmp->total_exp +=
op->total_exp;
2931 if (
where->inv == NULL)
2935 op->below->above =
op;
2945 if (
where->contr != NULL)
2950 if (
op->env->env &&
op->env->env->contr)
2953 else if (
op->env->map) {
2967 if (otmp && otmp->
contr != NULL) {
2976 if (
op->glow_radius != 0 &&
where->map) {
2978 LOG(
llevDebug,
" object_insert_in_ob(): got %s to insert in map/op\n",
op->name);
3016 int x =
op->x,
y =
op->y;
3017 MoveType move_on, move_slow, move_block;
3034 && !(
op->move_type&move_on)
3035 && !(
op->move_type&move_slow))
3043 if ((
op->move_type&~move_on&~move_block) != 0
3044 && (
op->move_type&~move_slow&~move_block) != 0)
3053 if (
tmp->above == NULL)
3074 || ((
op->move_type&
tmp->move_slow) && (
op->move_type&~
tmp->move_slow&~
tmp->move_block) == 0)) {
3077 diff =
tmp->move_slow_penalty*
FABS(
op->speed);
3084 op->speed_left -= diff;
3090 || ((
op->move_type&
tmp->move_on) && (
op->move_type&~
tmp->move_on&~
tmp->move_block) == 0)) {
3099 if (
op->map !=
m ||
op->x !=
x ||
op->y !=
y)
3125 if (
tmp->arch == at)
3226 if (
tmp->arch == at)
3297 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3320 ix = gen->
x-sx-genx2;
3321 iy = gen->
y-sy-geny2;
3333 for (i = 0; i < (sx+sx+sy+sy); i++) {
3337 }
else if (i <= sx+sy) {
3340 }
else if (i <= sx+sy+sx) {
3341 nx = ix+sx-(i-(sx+sy));
3345 ny = iy+sy-(i-(sx+sy+sx));
3358 freecount =
RANDOM()%freecount;
3359 for (i = 0; i < sx+sx+sy+sy; i++) {
3363 }
else if (i <= sx+sy) {
3366 }
else if (i <= sx+sy+sx) {
3367 nx = ix+sx-(i-(sx+sy));
3371 ny = iy+sy-(i-(sx+sy+sx));
3383 if (freecount <= 0) {
3413 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3414 int8_t
x,
y, radius;
3415 int freecount = 0, freecountstop = 0;
3423 radius = (int8_t)strtol(
value, NULL, 10);
3455 ix = gen->
x-sx-genx2-radius+1;
3456 iy = gen->
y-sy-geny2-radius+1;
3457 sx += genx+sx2+radius*2-1;
3458 sy += geny+sy2+radius*2-1;
3468 x_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3469 y_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3474 for (
x = 0;
x < sx;
x++) {
3475 for (
y = 0;
y < sy;
y++) {
3488 x_array[freecount] = nx;
3489 y_array[freecount] = ny;
3502 freecountstop =
RANDOM()%freecount;
3503 for (i = 0; i < freecount; i++) {
3511 if (freecountstop <= 0) {
3560 int i,
index = 0, flag;
3563 for (i = start; i <
stop; i++) {
3566 altern[
index++] = i;
3618 static void permute(
int *arr,
int begin,
int end) {
3622 for (i = begin; i < end; i++) {
3874 if (
item->weight <= 0)
3880 if (
item->invisible)
3910 object *dst = NULL, *
tmp, *src, *part, *prev;
3917 for (part = src; part; part = part->more) {
3924 tmp->carrying =
tmp->arch->clone.carrying;
3961 if (
tmp->name == name_shared)
4009 for (
int i = 0; i < num_flags; ++i) {
4041 if (
tmp->type == type1 ||
tmp->type == type2)
4137 if (
tmp->type ==
type && strcmp(
tmp->race, race) == 0)
4162 if (
tmp->type ==
type &&
tmp->slaying != NULL && strcmp(
tmp->slaying, slaying) == 0)
4187 if (
tmp->type ==
type &&
tmp->skill != NULL && strcmp(
tmp->skill, skill) == 0)
4256 if (strcmp(
tmp->arch->name,
name) == 0)
4305 if (
tmp->type ==
type &&
tmp->subtype == subtype)
4324 for (link =
ob->key_values; link != NULL; link = link->
next) {
4348 const char *canonical_key;
4352 if (canonical_key == NULL) {
4364 for (link =
op->key_values; link != NULL; link = link->
next) {
4365 if (link->
key == canonical_key) {
4378 if (ret == NULL || (strcmp(ret,
"") == 0) || (strcmp(ret,
"0") == 0)) {
4391 for (
key_value *link =
op->key_values; link != NULL; link = link->next) {
4392 if (link->key ==
key) {
4393 if ((strcmp(link->value,
"") == 0) || (strcmp(link->value,
"0") == 0)) {
4419 for (field =
op->key_values; field != NULL; field = field->
next) {
4420 if (field->
key != canonical_key) {
4436 field->
value = NULL;
4444 last->next = field->
next;
4446 op->key_values = field->
next;
4473 field->
next =
op->key_values;
4474 op->key_values = field;
4500 const char *canonical_key = NULL;
4501 int floating_ref =
FALSE;
4509 if (canonical_key == NULL) {
4511 floating_ref =
TRUE;
4576 int count, retval = 0;
4581 for (cp = strtok(local_name,
","); cp; cp = strtok(NULL,
",")) {
4582 while (cp[0] ==
' ')
4587 if (!strcmp(cp,
"all"))
4593 if (!strcmp(cp,
"cursed")
4603 if (*cp ==
'+' || *cp ==
'-')
4606 cp = strchr(cp,
' ');
4607 while (cp && cp[0] ==
' ')
4616 if (!cp || cp[0] ==
'\0' ||
count < 0)
4638 else if (custom_name && !
strcasecmp(cp, custom_name))
4640 else if (!strncasecmp(cp, bname_s, strlen(cp)))
4642 else if (!strncasecmp(cp, bname_p, strlen(cp)))
4649 else if (strstr(bname_p, cp))
4651 else if (strstr(bname_s, cp))
4653 else if (strstr(name_short, cp))
4665 else if (custom_name && strstr(custom_name, cp))
4690 LOG(
llevError,
"object_fix_multipart: not on a map!\n");
4695 if (
tmp->head ||
tmp->more)
4701 for (at =
tmp->arch->more, last =
tmp; at != NULL; at = at->
more, last =
op) {
4710 if (
tmp->name !=
op->name) {
4715 if (
tmp->title !=
op->title) {
4746 int maxx = 0, maxy = 0, minx = 0, miny = 0;
4751 if (
ob->arch->more) {
4752 for (part =
ob->arch; part; part = part->
more) {
4753 if (part->
clone.
x > maxx)
4755 if (part->
clone.
y > maxy)
4757 if (part->
clone.
x < minx)
4759 if (part->
clone.
y < miny)
4812 if (
op->msg != NULL) {
4818 if (*
msg !=
'\0' && strchr(
msg,
'\0')[-1] !=
'\n') {
4852 "alive",
"wiz", NULL, NULL,
"was_wiz",
"applied",
"unpaid",
4853 "can_use_shield",
"no_pick",
"client_anim_sync",
"client_anim_random",
4854 "is_animated", NULL ,
4855 NULL ,
"monster",
"friendly",
"generator",
4856 "is_thrown",
"auto_apply",
"treasure",
"player sold",
4857 "see_invisible",
"can_roll",
"overlay_floor",
4858 "is_turnable", NULL , NULL ,
4859 NULL ,
"is_used_up",
"identified",
"reflecting",
4860 "changing",
"splitting",
"hitback",
"startequip",
4861 "blocksview",
"undead",
"scared",
"unaggressive",
4862 "reflect_missile",
"reflect_spell",
4863 "no_magic",
"no_fix_player",
"is_lightable",
"tear_down",
4864 "run_away", NULL , NULL ,
4865 NULL ,
"unique",
"no_drop",
4866 NULL ,
"can_cast_spell",
"can_use_scroll",
"can_use_range",
4867 "can_use_bow",
"can_use_armour",
"can_use_weapon",
4868 "can_use_ring",
"has_ready_range",
"has_ready_bow",
4869 "xrays", NULL,
"is_floor",
"lifesave",
"no_strength",
"sleep",
4870 "stand_still",
"random_movement",
"only_attack",
"confused",
4871 "stealth", NULL, NULL,
"cursed",
"damned",
4872 "see_anywhere",
"known_magical",
"known_cursed",
4873 "can_use_skill",
"been_applied",
4874 "has_ready_scroll", NULL, NULL,
4875 NULL,
"make_invisible",
"inv_locked",
"is_wooded",
4876 "is_hilly",
"has_ready_skill",
"has_ready_weapon",
4877 "no_skill_ident",
"is_blind",
"can_see_in_dark",
"is_cauldron",
4878 NULL,
"no_steal",
"one_hit", NULL,
"berserk",
"neutral",
4879 "no_attack",
"no_damage", NULL, NULL,
"activate_on_push",
4880 "activate_on_release",
"is_water",
"use_content_on_gen", NULL,
"is_buildable",
4881 NULL,
"blessed",
"known_blessed"
4895 int i, all_count = 0,
count;
4898 strcpy(retbuf_all,
" all");
4915 if (mt&(1<<
count)) {
4916 strcat(retbuf,
" ");
4919 strcat(retbuf_all,
" -");
4961 for (
int i = 0; i < 4; i++) {
4962 int idx = ffs((*diff)[i]);
4966 (*diff)[i] &= ~(1 << bit);
4987 static char buf2[64];
4996 for (my_field =
op->key_values; my_field != NULL; my_field = my_field->
next) {
5001 if (arch_field == NULL || my_field->
value != arch_field->
value) {
5007 if (my_field->
value)
5016 if (
op->name &&
op->name != op2->
name) {
5025 if (
op->title &&
op->title != op2->
title) {
5028 if (
op->race &&
op->race != op2->
race) {
5034 if (
op->skill &&
op->skill != op2->
skill) {
5037 if (
op->msg &&
op->msg != op2->
msg) {
5042 if (
op->lore &&
op->lore != op2->
lore) {
5047 if (
op->other_arch != op2->
other_arch &&
op->other_arch != NULL &&
op->other_arch->name) {
5050 if (
op->face != op2->
face) {
5055 if (
op->animation) {
5092 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->stats.exp);
5097 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->total_exp);
5113 if (
op->x != op2->
x)
5115 if (
op->y != op2->
y)
5119 if (
op->speed != op2->
speed) {
5135 if (
op->nrof != op2->
nrof)
5141 if (
op->type != op2->
type)
5343 LOG(
llevError,
"could not find original archetype %s for custom monster!\n", at->
name);
5357 }
else if (
op->artifact != NULL) {
5364 LOG(
llevError,
"could not find artifact %s [%d] to save data\n",
op->artifact,
op->type);
5401 if (fputs(cp, fp) == EOF) {
5413 if (death_animation != NULL) {
5416 if (death != NULL) {
5433 if (
force == NULL) {
5439 if (duration != 0) {
5440 force->speed = 0.01;
5441 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]
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)
const typedef char * sstring
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)
int strcasecmp(const char *s1, const char *s2)
int object_distance(const object *ob1, const object *ob2)
object * find_force(object *op, const char *name)
int8_t body_info[NUM_BODY_LOCATIONS]
void object_fix_multipart(object *tmp)
struct treasurelist * randomitems
#define GET_MAP_MOVE_OFF(M, X, Y)
void object_remove(object *op)
static int compare_ob_value_lists_one(const object *, const object *)
#define GET_MAP_FLAGS(M, X, Y)
signed long object_sum_weight(object *op)
archetype * empty_archetype
int object_check_move_on(object *op, object *originator)
#define FREE_OBJ_FREE_INVENTORY
void update_all_los(const mapstruct *map, int x, int y)
void object_copy_owner(object *op, object *clone)
static void object_increase_nrof(object *op, uint32_t i)
void query_base_name(const object *op, int plural, char *buf, size_t size)
int object_set_value(object *op, const char *key, const char *value, int add_key)
short freearr_x[SIZEOFFREE]
void object_sub_weight(object *op, signed long weight)
#define SAVE_FLAG_SAVE_UNPAID
int save_object(FILE *fp, object *op, int flag)
object * object_get_player_container(object *op)
int dirdiff(int dir1, int dir2)
#define OB_SPELL_TAG_HASH(op, count)
const char *const map_layer_name[MAP_LAYERS]
#define CUSTOM_NAME_FIELD
void object_free_inventory(object *ob)
void free_dialog_information(object *op)
#define FOR_INV_PREPARE(op_, it_)
void object_replace_insert_in_map(const char *arch_string, object *op)
int object_can_merge(object *ob1, object *ob2)
static void FAST_SAVE_LONG(StringBuffer *sb, const char *name, const long value)