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)
549 if (
ob1->custom_name !=
ob2->custom_name)
582 sum = (sum*(100-
op->stats.Str))/100;
595 while (
op->env != NULL)
629 if (
op->owner == NULL)
634 &&
op->owner->count ==
op->ownercount)
657 if (
op->arch != NULL) {
664 if (
op->artifact != NULL) {
686 if (
op->attacked_by) {
809 if (
op->owner == NULL)
814 &&
op->owner->count ==
op->ownercount)
874 if (
op->owner != NULL)
920 if (
op->enemy == enemy) {
926 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);
946 op->materialname = NULL;
962 if (
op->key_values == NULL)
965 for (i =
op->key_values; i != NULL; i =
next) {
977 op->key_values = NULL;
1000 if (
op->name != NULL)
1002 if (
op->name_pl != NULL)
1004 if (
op->title != NULL)
1006 if (
op->race != NULL)
1008 if (
op->slaying != NULL)
1010 if (
op->skill != NULL)
1012 if (
op->msg != NULL)
1014 if (
op->lore != NULL)
1016 if (
op->materialname != NULL)
1035 op->container = NULL;
1040 op->active_next = NULL;
1041 op->active_prev = NULL;
1046 op->attacked_by_count = -1;
1048 op->casting_time = -1;
1071 if (dest_ob->
name != NULL)
1077 if (dest_ob->
title != NULL)
1079 if (dest_ob->
race != NULL)
1083 if (dest_ob->
skill != NULL)
1085 if (dest_ob->
msg != NULL)
1087 if (dest_ob->
lore != NULL)
1112 if (dest_ob->
name != NULL)
1118 if (dest_ob->
title != NULL)
1120 if (dest_ob->
race != NULL)
1124 if (dest_ob->
skill != NULL)
1126 if (dest_ob->
lore != NULL)
1128 if (dest_ob->
msg != NULL)
1143 if (dest_ob->
arch != NULL) {
1148 if (src_ob->
speed < 0)
1161 new_link->
next = NULL;
1166 new_link->
value = NULL;
1173 tail->
next = new_link;
1205 #ifndef MEMORY_DEBUG
1223 new[0].
next = &
new[1],
1228 new[i].next = &
new[i+1],
1229 new[i].prev = &
new[i-1],
1263 op = calloc(1,
sizeof(
object));
1291 op->materialname = NULL;
1294 op->active_next = NULL;
1295 op->active_prev = NULL;
1296 op->spell_tags = NULL;
1358 if (
op->active_next != NULL)
1359 op->active_next->active_prev =
op;
1383 if (
op->active_prev == NULL) {
1385 if (
op->active_next != NULL)
1386 op->active_next->active_prev = NULL;
1388 op->active_prev->active_next =
op->active_next;
1389 if (
op->active_next)
1390 op->active_next->active_prev =
op->active_prev;
1392 op->active_next = NULL;
1393 op->active_prev = NULL;
1421 int update_now = 0,
flags;
1422 MoveType move_on, move_off, move_block, move_slow;
1427 LOG(
llevDebug,
"object_update() called for NULL object.\n");
1431 if (
op->env != NULL) {
1447 LOG(
llevError,
"object_update() called for object out of map!\n");
1474 if ((move_on|
op->move_on) != move_on)
1476 if ((move_off|
op->move_off) != move_off)
1481 if (((move_block|
op->move_block)&~
op->move_allow) != move_block)
1483 if ((move_slow|
op->move_slow) != move_slow)
1530 if (
op->more != NULL)
1556 object *
inv =
ob->inv;
1583 LOG(
llevError,
"Free object called with non removed object\n");
1604 LOG(
llevError,
"Trying to free freed object.\n%s\n", diff);
1645 for (part =
ob; part; part = part->
more) {
1649 partcount =
RANDOM()%partcount;
1650 for (part =
ob; partcount > 0; partcount--) {
1670 if (
ob->more != NULL) {
1683 if (
ob->prev == NULL) {
1688 ob->prev->next =
ob->next;
1689 if (
ob->next != NULL)
1690 ob->next->prev =
ob->prev;
1712 if (
ob->arch &&
ob->arch->reference_count > 0) {
1713 if (--
ob->arch->reference_count == 0) {
1794 while (
op != NULL) {
1796 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
1798 op->carrying -= weight;
1820 object *last = NULL;
1834 LOG(
llevError,
"Trying to remove removed object.\n%s\n", diff);
1838 if (
op->more != NULL)
1848 if (
op->env != NULL) {
1857 if (
op->env->contr != NULL &&
op->head == NULL) {
1858 pl =
op->env->contr;
1861 if (
op->env->env &&
op->env->env->contr)
1863 pl =
op->env->env->contr;
1864 else if (
op->env->map) {
1866 object *above =
op->env->above;
1868 while (above && !above->
contr)
1869 above = above->
above;
1885 if (
op->above != NULL)
1886 op->above->below =
op->below;
1888 op->env->inv =
op->below;
1890 if (
op->below != NULL)
1891 op->below->above =
op->above;
1901 op->map =
op->env->map;
1913 if (
op->map == NULL)
1916 if (
op->contr != NULL && !
op->contr->hidden)
1924 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);
1928 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);
1933 op->above->below =
op->below;
1939 op->below->above =
op->above;
1953 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);
1982 if (
tmp->container ==
op) {
1984 tmp->container = NULL;
1986 tmp->contr->socket.update_look = 1;
1990 && ((
op->move_type&
tmp->move_off) && (
op->move_type&~
tmp->move_off&~
tmp->move_block) == 0)) {
1993 LOG(
llevError,
"BUG: object_remove(): name %s, archname %s destroyed leaving object\n",
tmp->name,
tmp->arch->name);
2085 tmp->x =
x+
tmp->arch->clone.x;
2086 tmp->y =
y+
tmp->arch->clone.y;
2127 if (
op->type ==
tmp->type
2128 &&
op->subtype ==
tmp->subtype
2129 &&
op->direction ==
tmp->direction
2130 &&
op->owner ==
tmp->owner &&
op->ownercount ==
tmp->ownercount
2131 &&
op->range ==
tmp->range
2132 &&
op->stats.wc ==
tmp->stats.wc
2133 &&
op->level ==
tmp->level
2134 &&
op->attacktype ==
tmp->attacktype
2135 &&
op->speed ==
tmp->speed
2137 && (
tmp->speed_left+
tmp->speed) < 0.0
2169 if (
tmp->spell_tags &&
op->spell_tags) {
2177 if (
op->spell_tags[i] &&
tmp->spell_tags[i]
2178 &&
op->spell_tags[i] !=
tmp->spell_tags[i]) {
2186 if ((!
op->spell_tags[i] &&
tmp->spell_tags[i])
2187 || (
op->spell_tags[i] && !
tmp->spell_tags[i])) {
2206 if (!
op->spell_tags[i]
2207 &&
tmp->spell_tags[i]
2208 &&
tmp->spell_tags[i] != (
tag_t)
op->stats.maxhp)
2209 op->spell_tags[i] =
tmp->spell_tags[i];
2215 if (
tmp->spell_tags && !
op->spell_tags) {
2216 op->spell_tags =
tmp->spell_tags;
2217 tmp->spell_tags = NULL;
2231 if (
op->stats.maxhp !=
tmp->stats.maxhp) {
2245 if (!
op->spell_tags)
2252 op->speed_left =
MAX(
op->speed_left,
tmp->speed_left);
2254 if (
tmp->duration !=
op->duration) {
2258 int tmp_dam =
tmp->stats.dam*(
tmp->duration+1)+
2259 op->stats.dam*(
op->duration+1);
2261 op->duration =
MAX(
op->duration,
tmp->duration);
2262 tmp_dam /=
op->duration+1;
2263 op->stats.dam = tmp_dam+1;
2268 op->stats.dam +=
tmp->stats.dam;
2278 object *floor = NULL;
2294 object *last = NULL;
2342 object *
tmp, *
top, *floor = NULL;
2356 LOG(
llevError,
"Trying to insert in null-map!\n%s\n", diff);
2367 LOG(
llevError,
"Trying to insert object outside the map.\n%s\n", diff);
2385 LOG(
llevError,
"Trying to insert (map) inserted object.\n%s\n", diff);
2389 if (
op->more != NULL) {
2392 object *more =
op->more;
2404 }
else if (!more->
map) {
2413 LOG(
llevError,
"BUG: object_insert_in_map(): inserting op->more killed op\n");
2432 op->nrof += spot->nrof;
2440 && (
op->speed_left+
op->speed) < 0.0) {
2471 if (originator->
map !=
op->map
2472 || originator->
x !=
op->x
2473 || originator->
y !=
op->y) {
2474 LOG(
llevError,
"object_insert_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
2477 op->above = originator;
2478 op->below = originator->
below;
2480 op->below->above =
op;
2493 op->above->below =
op;
2497 op->above =
top->above;
2499 op->above->below =
op;
2503 if (
op->above == NULL)
2509 op->contr->do_los = 1;
2517 tmp->contr->socket.update_look = 1;
2532 if (
op->contr && !
op->contr->hidden)
2579 if (!strcmp(
tmp->arch->name, arch_string)) {
2613 object *
object_split(
object *orig_ob, uint32_t nr,
char *err,
size_t size) {
2616 if (
MAX(1, orig_ob->
nrof) < nr) {
2619 snprintf(err, size,
"There are only %u %ss.",
NROF(orig_ob), orig_ob->
name);
2625 if (orig_ob->
nrof == 0) {
2663 }
else if (
op->env != NULL) {
2747 }
else if (
op->env != NULL) {
2810 while (
op != NULL) {
2812 weight = (
signed long)(weight*(100-
op->stats.Str)/100);
2814 op->carrying += weight;
2843 LOG(
llevError,
"Trying to insert (ob) inserted object.\n%s\n", diff);
2848 if (
where == NULL) {
2855 LOG(
llevError,
"Trying to put object in NULL.\n%s\n", diff);
2860 LOG(
llevDebug,
"Warning: Tried to insert object wrong part of multipart object.\n");
2864 LOG(
llevError,
"Tried to insert multipart object %s (%u)\n",
op->name,
op->count);
2874 tmp->stats.exp +=
op->stats.exp;
2875 tmp->total_exp +=
op->total_exp;
2906 if (
where->inv == NULL)
2910 op->below->above =
op;
2916 if (
where->contr != NULL)
2921 if (
op->env->env &&
op->env->env->contr)
2924 else if (
op->env->map) {
2938 if (otmp && otmp->
contr != NULL) {
2947 if (
op->glow_radius != 0 &&
where->map) {
2949 LOG(
llevDebug,
" object_insert_in_ob(): got %s to insert in map/op\n",
op->name);
2987 int x =
op->x,
y =
op->y;
2988 MoveType move_on, move_slow, move_block;
3005 && !(
op->move_type&move_on)
3006 && !(
op->move_type&move_slow))
3014 if ((
op->move_type&~move_on&~move_block) != 0
3015 && (
op->move_type&~move_slow&~move_block) != 0)
3024 if (
tmp->above == NULL)
3045 || ((
op->move_type&
tmp->move_slow) && (
op->move_type&~
tmp->move_slow&~
tmp->move_block) == 0)) {
3048 diff =
tmp->move_slow_penalty*
FABS(
op->speed);
3055 op->speed_left -= diff;
3061 || ((
op->move_type&
tmp->move_on) && (
op->move_type&~
tmp->move_on&~
tmp->move_block) == 0)) {
3070 if (
op->map !=
m ||
op->x !=
x ||
op->y !=
y)
3096 if (
tmp->arch == at)
3197 if (
tmp->arch == at)
3268 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3291 ix = gen->
x-sx-genx2;
3292 iy = gen->
y-sy-geny2;
3304 for (i = 0; i < (sx+sx+sy+sy); i++) {
3308 }
else if (i <= sx+sy) {
3311 }
else if (i <= sx+sy+sx) {
3312 nx = ix+sx-(i-(sx+sy));
3316 ny = iy+sy-(i-(sx+sy+sx));
3329 freecount =
RANDOM()%freecount;
3330 for (i = 0; i < sx+sx+sy+sy; i++) {
3334 }
else if (i <= sx+sy) {
3337 }
else if (i <= sx+sy+sx) {
3338 nx = ix+sx-(i-(sx+sy));
3342 ny = iy+sy-(i-(sx+sy+sx));
3354 if (freecount <= 0) {
3384 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3385 int8_t
x,
y, radius;
3386 int freecount = 0, freecountstop = 0;
3394 radius = (int8_t)strtol(
value, NULL, 10);
3426 ix = gen->
x-sx-genx2-radius+1;
3427 iy = gen->
y-sy-geny2-radius+1;
3428 sx += genx+sx2+radius*2-1;
3429 sy += geny+sy2+radius*2-1;
3439 x_array = malloc(sx*sy*
sizeof(int8_t));
3440 y_array = malloc(sx*sy*
sizeof(int8_t));
3445 for (
x = 0;
x < sx;
x++) {
3446 for (
y = 0;
y < sy;
y++) {
3459 x_array[freecount] = nx;
3460 y_array[freecount] = ny;
3473 freecountstop =
RANDOM()%freecount;
3474 for (i = 0; i < freecount; i++) {
3482 if (freecountstop <= 0) {
3531 int i,
index = 0, flag;
3534 for (i = start; i <
stop; i++) {
3537 altern[
index++] = i;
3589 static void permute(
int *arr,
int begin,
int end) {
3593 for (i = begin; i < end; i++) {
3845 if (
item->weight <= 0)
3851 if (
item->invisible)
3881 object *dst = NULL, *
tmp, *src, *part, *prev;
3888 for (part = src; part; part = part->more) {
3895 tmp->carrying =
tmp->arch->clone.carrying;
3932 if (
tmp->name == name_shared)
3980 for (
int i = 0; i < num_flags; ++i) {
4012 if (
tmp->type == type1 ||
tmp->type == type2)
4108 if (
tmp->type ==
type && strcmp(
tmp->race, race) == 0)
4133 if (
tmp->type ==
type &&
tmp->slaying != NULL && strcmp(
tmp->slaying, slaying) == 0)
4158 if (
tmp->type ==
type &&
tmp->skill != NULL && strcmp(
tmp->skill, skill) == 0)
4227 if (strcmp(
tmp->arch->name,
name) == 0)
4276 if (
tmp->type ==
type &&
tmp->subtype == subtype)
4295 for (link =
ob->key_values; link != NULL; link = link->
next) {
4319 const char *canonical_key;
4323 if (canonical_key == NULL) {
4335 for (link =
op->key_values; link != NULL; link = link->
next) {
4336 if (link->
key == canonical_key) {
4349 if (ret == NULL || (strcmp(ret,
"") == 0) || (strcmp(ret,
"0") == 0)) {
4362 for (
key_value *link =
op->key_values; link != NULL; link = link->next) {
4363 if (link->key ==
key) {
4364 if ((strcmp(link->value,
"") == 0) || (strcmp(link->value,
"0") == 0)) {
4390 for (field =
op->key_values; field != NULL; field = field->
next) {
4391 if (field->
key != canonical_key) {
4407 field->
value = NULL;
4415 last->next = field->
next;
4417 op->key_values = field->
next;
4444 field->
next =
op->key_values;
4445 op->key_values = field;
4471 const char *canonical_key = NULL;
4472 int floating_ref =
FALSE;
4480 if (canonical_key == NULL) {
4482 floating_ref =
TRUE;
4547 int count, retval = 0;
4551 for (cp = strtok(local_name,
","); cp; cp = strtok(NULL,
",")) {
4552 while (cp[0] ==
' ')
4557 if (!strcmp(cp,
"all"))
4563 if (!strcmp(cp,
"cursed")
4573 if (*cp ==
'+' || *cp ==
'-')
4576 cp = strchr(cp,
' ');
4577 while (cp && cp[0] ==
' ')
4586 if (!cp || cp[0] ==
'\0' ||
count < 0)
4610 else if (!strncasecmp(cp, bname_s, strlen(cp)))
4612 else if (!strncasecmp(cp, bname_p, strlen(cp)))
4619 else if (strstr(bname_p, cp))
4621 else if (strstr(bname_s, cp))
4623 else if (strstr(name_short, cp))
4635 else if (
op->custom_name && strstr(
op->custom_name, cp))
4660 LOG(
llevError,
"object_fix_multipart: not on a map!\n");
4665 if (
tmp->head ||
tmp->more)
4671 for (at =
tmp->arch->more, last =
tmp; at != NULL; at = at->
more, last =
op) {
4680 if (
tmp->name !=
op->name) {
4685 if (
tmp->title !=
op->title) {
4716 int maxx = 0, maxy = 0, minx = 0, miny = 0;
4721 if (
ob->arch->more) {
4722 for (part =
ob->arch; part; part = part->
more) {
4723 if (part->
clone.
x > maxx)
4725 if (part->
clone.
y > maxy)
4727 if (part->
clone.
x < minx)
4729 if (part->
clone.
y < miny)
4782 if (
op->msg != NULL) {
4788 if (*
msg !=
'\0' && strchr(
msg,
'\0')[-1] !=
'\n') {
4822 "alive",
"wiz", NULL, NULL,
"was_wiz",
"applied",
"unpaid",
4823 "can_use_shield",
"no_pick",
"client_anim_sync",
"client_anim_random",
4824 "is_animated", NULL ,
4825 NULL ,
"monster",
"friendly",
"generator",
4826 "is_thrown",
"auto_apply",
"treasure",
"player sold",
4827 "see_invisible",
"can_roll",
"overlay_floor",
4828 "is_turnable", NULL , NULL ,
4829 NULL ,
"is_used_up",
"identified",
"reflecting",
4830 "changing",
"splitting",
"hitback",
"startequip",
4831 "blocksview",
"undead",
"scared",
"unaggressive",
4832 "reflect_missile",
"reflect_spell",
4833 "no_magic",
"no_fix_player",
"is_lightable",
"tear_down",
4834 "run_away", NULL , NULL ,
4835 NULL ,
"unique",
"no_drop",
4836 NULL ,
"can_cast_spell",
"can_use_scroll",
"can_use_range",
4837 "can_use_bow",
"can_use_armour",
"can_use_weapon",
4838 "can_use_ring",
"has_ready_range",
"has_ready_bow",
4839 "xrays", NULL,
"is_floor",
"lifesave",
"no_strength",
"sleep",
4840 "stand_still",
"random_movement",
"only_attack",
"confused",
4841 "stealth", NULL, NULL,
"cursed",
"damned",
4842 "see_anywhere",
"known_magical",
"known_cursed",
4843 "can_use_skill",
"been_applied",
4844 "has_ready_scroll", NULL, NULL,
4845 NULL,
"make_invisible",
"inv_locked",
"is_wooded",
4846 "is_hilly",
"has_ready_skill",
"has_ready_weapon",
4847 "no_skill_ident",
"is_blind",
"can_see_in_dark",
"is_cauldron",
4848 NULL,
"no_steal",
"one_hit", NULL,
"berserk",
"neutral",
4849 "no_attack",
"no_damage", NULL, NULL,
"activate_on_push",
4850 "activate_on_release",
"is_water",
"use_content_on_gen", NULL,
"is_buildable",
4851 NULL,
"blessed",
"known_blessed"
4865 int i, all_count = 0,
count;
4868 strcpy(retbuf_all,
" all");
4885 if (mt&(1<<
count)) {
4886 strcat(retbuf,
" ");
4889 strcat(retbuf_all,
" -");
4931 for (
int i = 0; i < 4; i++) {
4932 int idx = ffs((*diff)[i]);
4936 (*diff)[i] &= ~(1 << bit);
4957 static char buf2[64];
4966 for (my_field =
op->key_values; my_field != NULL; my_field = my_field->
next) {
4971 if (arch_field == NULL || my_field->
value != arch_field->
value) {
4977 if (my_field->
value)
4986 if (
op->name &&
op->name != op2->
name) {
4998 if (
op->title &&
op->title != op2->
title) {
5001 if (
op->race &&
op->race != op2->
race) {
5007 if (
op->skill &&
op->skill != op2->
skill) {
5010 if (
op->msg &&
op->msg != op2->
msg) {
5015 if (
op->lore &&
op->lore != op2->
lore) {
5020 if (
op->other_arch != op2->
other_arch &&
op->other_arch != NULL &&
op->other_arch->name) {
5023 if (
op->face != op2->
face) {
5028 if (
op->animation) {
5065 snprintf(buf2,
sizeof(buf2),
"%"FMT64,
op->stats.exp);
5070 snprintf(buf2,
sizeof(buf2),
"%"FMT64,
op->total_exp);
5086 if (
op->x != op2->
x)
5088 if (
op->y != op2->
y)
5090 if (
op->speed != op2->
speed) {
5106 if (
op->nrof != op2->
nrof)
5112 if (
op->type != op2->
type)
5301 if (
op->arch->reference_count > 0) {
5309 LOG(
llevError,
"could not find original archetype %s for custom monster!\n",
op->arch->name);
5313 if (
op->stats.hp !=
op->arch->clone.stats.hp)
5315 if (
op->stats.sp !=
op->arch->clone.stats.sp)
5317 if (
op->stats.grace !=
op->arch->clone.stats.grace)
5319 if (
op->x !=
op->arch->clone.x)
5321 if (
op->y !=
op->arch->clone.y)
5323 }
else if (
op->artifact != NULL) {
5330 LOG(
llevError,
"could not find artifact %s [%d] to save data\n",
op->artifact,
op->type);
5367 if (fputs(cp, fp) == EOF) {
5379 if (death_animation != NULL) {
5382 if (death != NULL) {
5399 if (
force == NULL) {
5405 if (duration != 0) {
5406 force->speed = 0.01;
5407 force->speed_left = -duration;
#define object_was_destroyed(op, old_tag)
#define GET_MAP_OB(M, X, Y)
uint32_t get_weight_limit(int stat)
int object_find_first_free_spot(const object *ob, mapstruct *m, int x, int y)
EXTERN archetype * empty_archetype
struct artifactstruct artifact
#define FREE_AND_CLEAR_STR_IF(xyz)
#define FREE_OBJ_NO_DESTROY_CALLBACK
sstring add_refcount(sstring str)
void object_free(object *ob, int flags)
sstring add_string(const char *str)
object * object_find_by_flag_applied(const object *who, int flag)
void object_remove(object *op)
static void permute(int *, int, int)
void remove_friendly_object(object *op)
StringBuffer * stringbuffer_new(void)
signed long object_sum_weight(object *op)
void object_set_enemy(object *op, object *enemy)
#define NUM_BODY_LOCATIONS
static object objarray[STARTMAX]
object * object_find_by_type2(const object *who, int type1, int type2)
void object_free_key_values(object *op)
#define GET_MAP_TOP(M, X, Y)
object * object_find_by_type_and_skill(const object *who, int type, const char *skill)
void give_artifact_abilities(object *op, const object *artifact)
#define FLAG_CLIENT_ANIM_RANDOM
object * find_skill_by_number(object *who, int skillno)
void object_reset(object *op)
void object_copy_owner(object *op, object *clone)
object * object_create_clone(object *asrc)
#define FLAG_OVERLAY_FLOOR
void stringbuffer_append_char(StringBuffer *sb, const char c)
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
void object_add_weight(object *op, signed long weight)
void object_update(object *op, int action)
#define QUERY_FLAG(xyz, p)
int out_of_map(mapstruct *m, int x, int y)
#define SET_MAP_TOP(M, X, Y, tmp)
object * object_new(void)
object * object_find_by_arch_name(const object *who, const char *name)
static const char *const flag_names[NUM_FLAGS+1]
#define FLAG_OBJ_ORIGINAL
int object_distance(const object *ob1, const object *ob2)
#define OB_SPELL_TAG_MATCH(op, count)
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
void object_merge_spell(object *op, int16_t x, int16_t y)
object * arch_present_in_ob(const archetype *at, const object *op)
void object_set_flag_inv(object *op, int flag)
int object_matches_string(object *pl, object *op, const char *name)
#define GET_MAP_MOVE_SLOW(M, X, Y)
static int compare_ob_value_lists_one(const object *, const object *)
object * object_find_by_type_applied(const object *who, int type)
int object_can_merge(object *ob1, object *ob2)
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
int flags_differ(ob_flags *diff)
#define GET_MAP_PLAYER(M, X, Y)
static int object_set_value_s(object *, const char *, const char *, int)
#define FOR_ABOVE_PREPARE(op_, it_)
static const flag_definition flags[]
int8_t body_info[NUM_BODY_LOCATIONS]
void object_free_all_data(void)
void free_arch(archetype *at)
#define FOR_OB_AND_ABOVE_FINISH()
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
const EXTERN char *const resist_save[NROFATTACKS]
struct treasureliststruct * randomitems
short freearr_x[SIZEOFFREE]
const char *const map_layer_name[MAP_LAYERS]
short freearr_y[SIZEOFFREE]
uint8_t duration_modifier
const artifact * find_artifact(const object *op, const char *name)
#define FLAG_DIALOG_PARSED
void animate_object(object *op, int dir)
void esrv_send_item(object *pl, object *op)
#define INS_ABOVE_FLOOR_ONLY
object * object_merge(object *op, object *top)
#define FOR_OB_AND_ABOVE_PREPARE(op_)
static void FAST_SAVE_LONG(StringBuffer *sb, const char *name, const long value)
const char * object_get_value(const object *op, const char *const key)
#define FLAG_IS_A_TEMPLATE
void free_string(sstring str)
static event_registration m
void object_free_inventory(object *ob)
object * find_force(object *op, const char *name)
key_value * object_get_key_value(const object *ob, const char *key)
object * object_find_by_type_subtype(const object *who, int type, int subtype)
void object_unset_flag_inv(object *op, int flag)
object * object_find_by_type_without_flags(const object *who, int type, int *flags, int num_flags)
static uint32_t NROF(const object *const ob)
static void expand_objects(void)
void object_sub_weight(object *op, signed long weight)
object * object_find_by_flag(const object *who, int flag)
void object_dump_all(void)
void object_copy_with_inv(const object *src_ob, object *dest_ob)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
void object_copy(const object *src_ob, object *dest_ob)
void query_name(const object *op, char *buf, size_t size)
sstring stringbuffer_finish_shared(StringBuffer *sb)
void object_update_turn_face(object *op)
#define FLAG_KNOWN_CURSED
#define FOR_ABOVE_FINISH()
void object_dump(const object *op, StringBuffer *sb)
#define FOR_OB_AND_BELOW_FINISH()
void fatal(enum fatal_error err)
void object_fix_multipart(object *tmp)
void stringbuffer_append_string(StringBuffer *sb, const char *str)
int object_can_pick(const object *who, const object *item)
void object_clear(object *op)
static void ADD_STRINGLINE_ENTRY(StringBuffer *sb, const char *name, const char *value)
sstring find_string(const char *str)
void query_short_name(const object *op, char *buf, size_t size)
object * object_present_in_ob(uint8_t type, const object *op)
static void FAST_SAVE_DOUBLE(StringBuffer *sb, const char *name, const double value)
EXTERN player * first_player
#define SET_MAP_FLAGS(M, X, Y, C)
void fix_object(object *op)
char * stringbuffer_finish(StringBuffer *sb)
static void object_increase_nrof(object *op, uint32_t i)
#define GET_MAP_MOVE_BLOCK(M, X, Y)
struct archt * other_arch
static void get_string_move_type(StringBuffer *sb, MoveType mt)
#define INS_BELOW_ORIGINATOR
int object_set_value(object *op, const char *key, const char *value, int add_key)
const typedef char * sstring
void free_dialog_information(object *op)
#define FOR_OB_AND_BELOW_PREPARE(op_)
static void compare_flags(ob_flags *ret, const object *p, const object *q)
#define GET_MAP_MOVE_ON(M, X, Y)
static object * free_objects
const Animations * animation
#define FREE_OBJ_DROP_ABOVE_FLOOR
int object_check_move_on(object *op, object *originator)
int object_find_multi_free_spot_around(const object *ob, const object *gen, int16_t *hx, int16_t *hy)
method_ret ob_move_on(object *op, object *victim, object *originator)
void object_set_owner(object *op, object *owner)
static const int reduction_dir[SIZEOFFREE][3]
void stringbuffer_append_int64(StringBuffer *sb, int64_t x)
const char *const move_name[]
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
static object * find_insert_pos(object *op, const int flag)
void esrv_del_item(player *pl, object *ob)
object * create_archetype(const char *name)
void object_insert_to_free_spot_or_free(object *op, mapstruct *map, int x, int y, int start, int stop, object *originator)
#define offsetof(type, member)
struct Statistics statistics
#define FREE_AND_CLEAR_STR(xyz)
#define FLAG_CLIENT_ANIM_SYNC
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
int object_count_used(void)
#define OUT_OF_REAL_MAP(M, X, Y)
int dirdiff(int dir1, int dir2)
void object_set_msg(object *op, const char *msg)
int object_count_active(void)
int object_count_free(void)
object * object_find_by_tag_global(tag_t i)
object * object_find_by_tag(const object *who, tag_t tag)
#define FREE_AND_CLEAR(xyz)
#define SCRIPT_FIX_NOTHING
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
void object_remove_from_active_list(object *op)
void LOG(LogLevel logLevel, const char *format,...)
void object_set_cheat(object *op)
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
object * object_insert_in_map(object *op, mapstruct *m, object *originator, int flag)
bool object_value_set(const object *op, const char *const key)
archetype * find_archetype(const char *name)
bool object_value_set_shared(const object *op, sstring key)
void esrv_update_item(int flags, object *pl, object *op)
void query_base_name(const object *op, int plural, char *buf, size_t size)
object * map_find_by_type(mapstruct *m, int x, int y, uint8_t type)
#define FLAG_NO_FIX_PLAYER
#define FLAG_BEEN_APPLIED
#define CLEAR_FLAG(xyz, p)
object * object_find_by_type(const object *who, int type)
#define SET_MAP_OB(M, X, Y, tmp)
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
object * object_insert_in_ob(object *op, object *where)
void update_all_los(const mapstruct *map, int x, int y)
void object_update_speed(object *op)
void object_handle_death_animation(object *op)
static const object * object_get_owner_const(const object *op)
object * object_get_env_recursive(object *op)
object * object_find_by_name_global(const char *str)
object * arch_to_object(archetype *at)
int strcasecmp(const char *s1, const char *s2)
int find_dir_2(int x, int y)
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
void object_free_drop_inventory(object *ob)
#define GET_MAP_MOVE_OFF(M, X, Y)
void update_position(mapstruct *m, int x, int y)
int object_find_multi_free_spot_within_radius(const object *ob, const object *gen, int *hx, int *hy)
void object_replace_insert_in_map(const char *arch_string, object *op)
#define GET_MAP_FLAGS(M, X, Y)
object * object_find_by_type_and_race(const object *who, int type, const char *race)
object * object_decrease_nrof(object *op, uint32_t i)
object * object_find_by_name(const object *who, const char *name)
#define FREE_OBJ_FREE_INVENTORY
object * add_force(object *op, const char *name, int duration)
object * object_find_by_type_and_name(const object *who, int type, const char *name)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
object * object_get_player_container(object *op)
void get_search_arr(int *search_arr)
#define SAVE_FLAG_SAVE_UNPAID
body_locations_struct body_locations[NUM_BODY_LOCATIONS]
#define OB_SPELL_TAG_HASH(op, count)
const char *const spell_mapping[SPELL_MAPPINGS]
int16_t resist[NROFATTACKS]
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
#define FOR_INV_PREPARE(op_, it_)
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
void save_object_in_sb(StringBuffer *sb, object *op, const int flag)
static int compare_ob_value_lists(const object *, const object *)
int save_object(FILE *fp, object *op, int flag)
void object_clear_owner(object *op)
object * object_get_owner(object *op)