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");
2452 op->nrof += spot->nrof;
2460 && (
op->speed_left+
op->speed) < 0.0) {
2491 if (originator->
map !=
op->map
2492 || originator->
x !=
op->x
2493 || originator->
y !=
op->y) {
2494 LOG(
llevError,
"object_insert_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
2497 op->above = originator;
2498 op->below = originator->
below;
2500 op->below->above =
op;
2513 op->above->below =
op;
2517 op->above =
top->above;
2519 op->above->below =
op;
2523 if (
op->above == NULL)
2529 op->contr->do_los = 1;
2537 tmp->contr->socket->update_look = 1;
2552 if (
op->contr && !
op->contr->hidden)
2599 if (!strcmp(
tmp->arch->name, arch_string)) {
2633 object *
object_split(
object *orig_ob, uint32_t nr,
char *err,
size_t size) {
2636 if (
MAX(1, orig_ob->
nrof) < nr) {
2639 snprintf(err, size,
"There are only %u %ss.",
NROF(orig_ob), orig_ob->
name);
2645 if (orig_ob->
nrof == 0) {
2683 }
else if (
op->env != NULL) {
2698 if (
pl->ob->container ==
op->env)
2731 pl->contr->socket->update_look = 1;
2767 }
else if (
op->env != NULL) {
2781 if (
pl->ob->container ==
op->env)
2808 pl->contr->socket->update_look = 1;
2830 while (
op != NULL) {
2832 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
2834 op->carrying += weight;
2863 LOG(
llevError,
"Trying to insert (ob) inserted object.\n%s\n", diff);
2868 if (
where == NULL) {
2875 LOG(
llevError,
"Trying to put object in NULL.\n%s\n", diff);
2880 LOG(
llevDebug,
"Warning: Tried to insert object wrong part of multipart object.\n");
2884 LOG(
llevError,
"Tried to insert multipart object %s (%u)\n",
op->name,
op->count);
2895 tmp->stats.exp +=
op->stats.exp;
2896 tmp->total_exp +=
op->total_exp;
2927 if (
where->inv == NULL)
2931 op->below->above =
op;
2941 if (
where->contr != NULL)
2946 if (
op->env->env &&
op->env->env->contr)
2949 else if (
op->env->map) {
2963 if (otmp && otmp->
contr != NULL) {
2972 if (
op->glow_radius != 0 &&
where->map) {
2974 LOG(
llevDebug,
" object_insert_in_ob(): got %s to insert in map/op\n",
op->name);
3012 int x =
op->x,
y =
op->y;
3013 MoveType move_on, move_slow, move_block;
3030 && !(
op->move_type&move_on)
3031 && !(
op->move_type&move_slow))
3039 if ((
op->move_type&~move_on&~move_block) != 0
3040 && (
op->move_type&~move_slow&~move_block) != 0)
3049 if (
tmp->above == NULL)
3070 || ((
op->move_type&
tmp->move_slow) && (
op->move_type&~
tmp->move_slow&~
tmp->move_block) == 0)) {
3073 diff =
tmp->move_slow_penalty*
FABS(
op->speed);
3080 op->speed_left -= diff;
3086 || ((
op->move_type&
tmp->move_on) && (
op->move_type&~
tmp->move_on&~
tmp->move_block) == 0)) {
3095 if (
op->map !=
m ||
op->x !=
x ||
op->y !=
y)
3121 if (
tmp->arch == at)
3222 if (
tmp->arch == at)
3293 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3316 ix = gen->
x-sx-genx2;
3317 iy = gen->
y-sy-geny2;
3329 for (i = 0; i < (sx+sx+sy+sy); i++) {
3333 }
else if (i <= sx+sy) {
3336 }
else if (i <= sx+sy+sx) {
3337 nx = ix+sx-(i-(sx+sy));
3341 ny = iy+sy-(i-(sx+sy+sx));
3354 freecount =
RANDOM()%freecount;
3355 for (i = 0; i < sx+sx+sy+sy; i++) {
3359 }
else if (i <= sx+sy) {
3362 }
else if (i <= sx+sy+sx) {
3363 nx = ix+sx-(i-(sx+sy));
3367 ny = iy+sy-(i-(sx+sy+sx));
3379 if (freecount <= 0) {
3409 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3410 int8_t
x,
y, radius;
3411 int freecount = 0, freecountstop = 0;
3419 radius = (int8_t)strtol(
value, NULL, 10);
3451 ix = gen->
x-sx-genx2-radius+1;
3452 iy = gen->
y-sy-geny2-radius+1;
3453 sx += genx+sx2+radius*2-1;
3454 sy += geny+sy2+radius*2-1;
3464 x_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3465 y_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3470 for (
x = 0;
x < sx;
x++) {
3471 for (
y = 0;
y < sy;
y++) {
3484 x_array[freecount] = nx;
3485 y_array[freecount] = ny;
3498 freecountstop =
RANDOM()%freecount;
3499 for (i = 0; i < freecount; i++) {
3507 if (freecountstop <= 0) {
3556 int i,
index = 0, flag;
3559 for (i = start; i <
stop; i++) {
3562 altern[
index++] = i;
3614 static void permute(
int *arr,
int begin,
int end) {
3618 for (i = begin; i < end; i++) {
3870 if (
item->weight <= 0)
3876 if (
item->invisible)
3906 object *dst = NULL, *
tmp, *src, *part, *prev;
3913 for (part = src; part; part = part->more) {
3920 tmp->carrying =
tmp->arch->clone.carrying;
3957 if (
tmp->name == name_shared)
4005 for (
int i = 0; i < num_flags; ++i) {
4037 if (
tmp->type == type1 ||
tmp->type == type2)
4133 if (
tmp->type ==
type && strcmp(
tmp->race, race) == 0)
4158 if (
tmp->type ==
type &&
tmp->slaying != NULL && strcmp(
tmp->slaying, slaying) == 0)
4183 if (
tmp->type ==
type &&
tmp->skill != NULL && strcmp(
tmp->skill, skill) == 0)
4252 if (strcmp(
tmp->arch->name,
name) == 0)
4301 if (
tmp->type ==
type &&
tmp->subtype == subtype)
4320 for (link =
ob->key_values; link != NULL; link = link->
next) {
4344 const char *canonical_key;
4348 if (canonical_key == NULL) {
4360 for (link =
op->key_values; link != NULL; link = link->
next) {
4361 if (link->
key == canonical_key) {
4374 if (ret == NULL || (strcmp(ret,
"") == 0) || (strcmp(ret,
"0") == 0)) {
4387 for (
key_value *link =
op->key_values; link != NULL; link = link->next) {
4388 if (link->key ==
key) {
4389 if ((strcmp(link->value,
"") == 0) || (strcmp(link->value,
"0") == 0)) {
4415 for (field =
op->key_values; field != NULL; field = field->
next) {
4416 if (field->
key != canonical_key) {
4432 field->
value = NULL;
4440 last->next = field->
next;
4442 op->key_values = field->
next;
4469 field->
next =
op->key_values;
4470 op->key_values = field;
4496 const char *canonical_key = NULL;
4497 int floating_ref =
FALSE;
4505 if (canonical_key == NULL) {
4507 floating_ref =
TRUE;
4572 int count, retval = 0;
4577 for (cp = strtok(local_name,
","); cp; cp = strtok(NULL,
",")) {
4578 while (cp[0] ==
' ')
4583 if (!strcmp(cp,
"all"))
4589 if (!strcmp(cp,
"cursed")
4599 if (*cp ==
'+' || *cp ==
'-')
4602 cp = strchr(cp,
' ');
4603 while (cp && cp[0] ==
' ')
4612 if (!cp || cp[0] ==
'\0' ||
count < 0)
4634 else if (custom_name && !
strcasecmp(cp, custom_name))
4636 else if (!strncasecmp(cp, bname_s, strlen(cp)))
4638 else if (!strncasecmp(cp, bname_p, strlen(cp)))
4645 else if (strstr(bname_p, cp))
4647 else if (strstr(bname_s, cp))
4649 else if (strstr(name_short, cp))
4661 else if (custom_name && strstr(custom_name, cp))
4686 LOG(
llevError,
"object_fix_multipart: not on a map!\n");
4691 if (
tmp->head ||
tmp->more)
4697 for (at =
tmp->arch->more, last =
tmp; at != NULL; at = at->
more, last =
op) {
4706 if (
tmp->name !=
op->name) {
4711 if (
tmp->title !=
op->title) {
4742 int maxx = 0, maxy = 0, minx = 0, miny = 0;
4747 if (
ob->arch->more) {
4748 for (part =
ob->arch; part; part = part->
more) {
4749 if (part->
clone.
x > maxx)
4751 if (part->
clone.
y > maxy)
4753 if (part->
clone.
x < minx)
4755 if (part->
clone.
y < miny)
4808 if (
op->msg != NULL) {
4814 if (*
msg !=
'\0' && strchr(
msg,
'\0')[-1] !=
'\n') {
4848 "alive",
"wiz", NULL, NULL,
"was_wiz",
"applied",
"unpaid",
4849 "can_use_shield",
"no_pick",
"client_anim_sync",
"client_anim_random",
4850 "is_animated", NULL ,
4851 NULL ,
"monster",
"friendly",
"generator",
4852 "is_thrown",
"auto_apply",
"treasure",
"player sold",
4853 "see_invisible",
"can_roll",
"overlay_floor",
4854 "is_turnable", NULL , NULL ,
4855 NULL ,
"is_used_up",
"identified",
"reflecting",
4856 "changing",
"splitting",
"hitback",
"startequip",
4857 "blocksview",
"undead",
"scared",
"unaggressive",
4858 "reflect_missile",
"reflect_spell",
4859 "no_magic",
"no_fix_player",
"is_lightable",
"tear_down",
4860 "run_away", NULL , NULL ,
4861 NULL ,
"unique",
"no_drop",
4862 NULL ,
"can_cast_spell",
"can_use_scroll",
"can_use_range",
4863 "can_use_bow",
"can_use_armour",
"can_use_weapon",
4864 "can_use_ring",
"has_ready_range",
"has_ready_bow",
4865 "xrays", NULL,
"is_floor",
"lifesave",
"no_strength",
"sleep",
4866 "stand_still",
"random_movement",
"only_attack",
"confused",
4867 "stealth", NULL, NULL,
"cursed",
"damned",
4868 "see_anywhere",
"known_magical",
"known_cursed",
4869 "can_use_skill",
"been_applied",
4870 "has_ready_scroll", NULL, NULL,
4871 NULL,
"make_invisible",
"inv_locked",
"is_wooded",
4872 "is_hilly",
"has_ready_skill",
"has_ready_weapon",
4873 "no_skill_ident",
"is_blind",
"can_see_in_dark",
"is_cauldron",
4874 NULL,
"no_steal",
"one_hit", NULL,
"berserk",
"neutral",
4875 "no_attack",
"no_damage", NULL, NULL,
"activate_on_push",
4876 "activate_on_release",
"is_water",
"use_content_on_gen", NULL,
"is_buildable",
4877 NULL,
"blessed",
"known_blessed"
4891 int i, all_count = 0,
count;
4894 strcpy(retbuf_all,
" all");
4911 if (mt&(1<<
count)) {
4912 strcat(retbuf,
" ");
4915 strcat(retbuf_all,
" -");
4957 for (
int i = 0; i < 4; i++) {
4958 int idx = ffs((*diff)[i]);
4962 (*diff)[i] &= ~(1 << bit);
4983 static char buf2[64];
4992 for (my_field =
op->key_values; my_field != NULL; my_field = my_field->
next) {
4997 if (arch_field == NULL || my_field->
value != arch_field->
value) {
5003 if (my_field->
value)
5012 if (
op->name &&
op->name != op2->
name) {
5021 if (
op->title &&
op->title != op2->
title) {
5024 if (
op->race &&
op->race != op2->
race) {
5030 if (
op->skill &&
op->skill != op2->
skill) {
5033 if (
op->msg &&
op->msg != op2->
msg) {
5038 if (
op->lore &&
op->lore != op2->
lore) {
5043 if (
op->other_arch != op2->
other_arch &&
op->other_arch != NULL &&
op->other_arch->name) {
5046 if (
op->face != op2->
face) {
5051 if (
op->animation) {
5088 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->stats.exp);
5093 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->total_exp);
5109 if (
op->x != op2->
x)
5111 if (
op->y != op2->
y)
5113 if (
op->speed != op2->
speed) {
5129 if (
op->nrof != op2->
nrof)
5135 if (
op->type != op2->
type)
5332 LOG(
llevError,
"could not find original archetype %s for custom monster!\n", at->
name);
5346 }
else if (
op->artifact != NULL) {
5353 LOG(
llevError,
"could not find artifact %s [%d] to save data\n",
op->artifact,
op->type);
5390 if (fputs(cp, fp) == EOF) {
5402 if (death_animation != NULL) {
5405 if (death != NULL) {
5422 if (
force == NULL) {
5428 if (duration != 0) {
5429 force->speed = 0.01;
5430 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)