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
1242 add[i].
next = &add[i+1],
1243 add[i].
prev = &add[i-1],
1276 op =
static_cast<object *
>(calloc(1,
sizeof(
object)));
1304 op->materialname = NULL;
1307 op->active_next = NULL;
1308 op->active_prev = NULL;
1309 op->spell_tags = NULL;
1367 if (
op->active_next != NULL)
1368 op->active_next->active_prev =
op;
1392 if (
op->active_prev == NULL) {
1394 if (
op->active_next != NULL)
1395 op->active_next->active_prev = NULL;
1397 op->active_prev->active_next =
op->active_next;
1398 if (
op->active_next)
1399 op->active_next->active_prev =
op->active_prev;
1401 op->active_next = NULL;
1402 op->active_prev = NULL;
1430 int update_now = 0,
flags;
1431 MoveType move_on, move_off, move_block, move_slow;
1436 LOG(
llevDebug,
"object_update() called for NULL object.\n");
1440 if (
op->env != NULL) {
1456 LOG(
llevError,
"object_update() called for object out of map!\n");
1483 if ((move_on|
op->move_on) != move_on)
1485 if ((move_off|
op->move_off) != move_off)
1490 if (((move_block|
op->move_block)&~
op->move_allow) != move_block)
1492 if ((move_slow|
op->move_slow) != move_slow)
1526 if (!
pl->contr->socket->update_look) {
1539 if (
op->more != NULL)
1565 object *
inv =
ob->inv;
1592 LOG(
llevError,
"Free object called with non removed object\n");
1613 LOG(
llevError,
"Trying to free freed object.\n%s\n", diff);
1654 for (part =
ob; part; part = part->
more) {
1658 partcount =
RANDOM()%partcount;
1659 for (part =
ob; partcount > 0; partcount--) {
1679 if (
ob->more != NULL) {
1692 if (
ob->prev == NULL) {
1697 ob->prev->next =
ob->next;
1698 if (
ob->next != NULL)
1699 ob->next->prev =
ob->prev;
1721 if (
ob->arch &&
ob->arch->reference_count > 0) {
1722 if (--
ob->arch->reference_count == 0) {
1803 while (
op != NULL) {
1829 object *last = NULL;
1843 LOG(
llevError,
"Trying to remove removed object.\n%s\n", diff);
1847 if (
op->more != NULL)
1857 if (
op->env != NULL) {
1866 if (
op->env->contr != NULL &&
op->head == NULL) {
1867 pl =
op->env->contr;
1870 if (
op->env->env &&
op->env->env->contr)
1872 pl =
op->env->env->contr;
1873 else if (
op->env->map) {
1875 object *
above =
op->env->above;
1894 if (
op->above != NULL)
1895 op->above->below =
op->below;
1897 op->env->inv =
op->below;
1899 if (
op->below != NULL)
1900 op->below->above =
op->above;
1903 op->env->event_bitmask = 0;
1914 op->map =
op->env->map;
1926 if (
op->map == NULL)
1929 if (
op->contr != NULL && !
op->contr->hidden)
1937 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);
1941 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);
1946 op->above->below =
op->below;
1952 op->below->above =
op->above;
1966 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);
1995 if (
tmp->container ==
op) {
1997 tmp->container = NULL;
2001 tmp->contr->socket->update_look = 1;
2005 && ((
op->move_type&
tmp->move_off) && (
op->move_type&~
tmp->move_off&~
tmp->move_block) == 0)) {
2008 LOG(
llevError,
"BUG: object_remove(): name %s, archname %s destroyed leaving object\n",
tmp->name,
tmp->arch->name);
2100 tmp->x =
x+
tmp->arch->clone.x;
2101 tmp->y =
y+
tmp->arch->clone.y;
2142 if (
op->type ==
tmp->type
2143 &&
op->subtype ==
tmp->subtype
2144 &&
op->direction ==
tmp->direction
2145 &&
op->owner ==
tmp->owner &&
op->ownercount ==
tmp->ownercount
2146 &&
op->range ==
tmp->range
2147 &&
op->stats.wc ==
tmp->stats.wc
2148 &&
op->level ==
tmp->level
2149 &&
op->attacktype ==
tmp->attacktype
2150 &&
op->speed ==
tmp->speed
2152 && (
tmp->speed_left+
tmp->speed) < 0.0
2184 if (
tmp->spell_tags &&
op->spell_tags) {
2192 if (
op->spell_tags[i] &&
tmp->spell_tags[i]
2193 &&
op->spell_tags[i] !=
tmp->spell_tags[i]) {
2201 if ((!
op->spell_tags[i] &&
tmp->spell_tags[i])
2202 || (
op->spell_tags[i] && !
tmp->spell_tags[i])) {
2221 if (!
op->spell_tags[i]
2222 &&
tmp->spell_tags[i]
2223 &&
tmp->spell_tags[i] != (
tag_t)
op->stats.maxhp)
2224 op->spell_tags[i] =
tmp->spell_tags[i];
2230 if (
tmp->spell_tags && !
op->spell_tags) {
2231 op->spell_tags =
tmp->spell_tags;
2232 tmp->spell_tags = NULL;
2246 if (
op->stats.maxhp !=
tmp->stats.maxhp) {
2260 if (!
op->spell_tags)
2267 op->speed_left =
MAX(
op->speed_left,
tmp->speed_left);
2269 if (
tmp->duration !=
op->duration) {
2273 int tmp_dam =
tmp->stats.dam*(
tmp->duration+1)+
2274 op->stats.dam*(
op->duration+1);
2276 op->duration =
MAX(
op->duration,
tmp->duration);
2277 tmp_dam /=
op->duration+1;
2278 op->stats.dam = tmp_dam+1;
2283 op->stats.dam +=
tmp->stats.dam;
2293 object *
floor = NULL;
2309 object *last = NULL;
2371 LOG(
llevError,
"Trying to insert in null-map!\n%s\n", diff);
2382 LOG(
llevError,
"Trying to insert object outside the map.\n%s\n", diff);
2400 LOG(
llevError,
"Trying to insert (map) inserted object.\n%s\n", diff);
2404 if (
op->more != NULL) {
2407 object *more =
op->more;
2419 }
else if (!more->
map) {
2428 LOG(
llevError,
"BUG: object_insert_in_map(): inserting op->more killed op\n");
2447 op->nrof += spot->nrof;
2455 && (
op->speed_left+
op->speed) < 0.0) {
2486 if (originator->
map !=
op->map
2487 || originator->
x !=
op->x
2488 || originator->
y !=
op->y) {
2489 LOG(
llevError,
"object_insert_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
2492 op->above = originator;
2493 op->below = originator->
below;
2495 op->below->above =
op;
2508 op->above->below =
op;
2512 op->above =
top->above;
2514 op->above->below =
op;
2518 if (
op->above == NULL)
2524 op->contr->do_los = 1;
2532 tmp->contr->socket->update_look = 1;
2547 if (
op->contr && !
op->contr->hidden)
2594 if (!strcmp(
tmp->arch->name, arch_string)) {
2628 object *
object_split(
object *orig_ob, uint32_t nr,
char *err,
size_t size) {
2631 if (
MAX(1, orig_ob->
nrof) < nr) {
2634 snprintf(err, size,
"There are only %u %ss.",
NROF(orig_ob), orig_ob->
name);
2640 if (orig_ob->
nrof == 0) {
2678 }
else if (
op->env != NULL) {
2693 if (
pl->ob->container ==
op->env)
2726 pl->contr->socket->update_look = 1;
2762 }
else if (
op->env != NULL) {
2776 if (
pl->ob->container ==
op->env)
2803 pl->contr->socket->update_look = 1;
2825 while (
op != NULL) {
2858 LOG(
llevError,
"Trying to insert (ob) inserted object.\n%s\n", diff);
2863 if (
where == NULL) {
2870 LOG(
llevError,
"Trying to put object in NULL.\n%s\n", diff);
2875 LOG(
llevDebug,
"Warning: Tried to insert object wrong part of multipart object.\n");
2879 LOG(
llevError,
"Tried to insert multipart object %s (%u)\n",
op->name,
op->count);
2890 tmp->stats.exp +=
op->stats.exp;
2891 tmp->total_exp +=
op->total_exp;
2922 if (
where->inv == NULL)
2926 op->below->above =
op;
2936 if (
where->contr != NULL)
2941 if (
op->env->env &&
op->env->env->contr)
2944 else if (
op->env->map) {
2958 if (otmp && otmp->
contr != NULL) {
2967 if (
op->glow_radius != 0 &&
where->map) {
2969 LOG(
llevDebug,
" object_insert_in_ob(): got %s to insert in map/op\n",
op->name);
3007 int x =
op->x,
y =
op->y;
3008 MoveType move_on, move_slow, move_block;
3025 && !(
op->move_type&move_on)
3026 && !(
op->move_type&move_slow))
3034 if ((
op->move_type&~move_on&~move_block) != 0
3035 && (
op->move_type&~move_slow&~move_block) != 0)
3044 if (
tmp->above == NULL)
3065 || ((
op->move_type&
tmp->move_slow) && (
op->move_type&~
tmp->move_slow&~
tmp->move_block) == 0)) {
3068 diff =
tmp->move_slow_penalty*
FABS(
op->speed);
3075 op->speed_left -= diff;
3081 || ((
op->move_type&
tmp->move_on) && (
op->move_type&~
tmp->move_on&~
tmp->move_block) == 0)) {
3090 if (
op->map !=
m ||
op->x !=
x ||
op->y !=
y)
3116 if (
tmp->arch == at)
3217 if (
tmp->arch == at)
3288 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3311 ix = gen->
x-sx-genx2;
3312 iy = gen->
y-sy-geny2;
3324 for (i = 0; i < (sx+sx+sy+sy); i++) {
3328 }
else if (i <= sx+sy) {
3331 }
else if (i <= sx+sy+sx) {
3332 nx = ix+sx-(i-(sx+sy));
3336 ny = iy+sy-(i-(sx+sy+sx));
3349 freecount =
RANDOM()%freecount;
3350 for (i = 0; i < sx+sx+sy+sy; i++) {
3354 }
else if (i <= sx+sy) {
3357 }
else if (i <= sx+sy+sx) {
3358 nx = ix+sx-(i-(sx+sy));
3362 ny = iy+sy-(i-(sx+sy+sx));
3374 if (freecount <= 0) {
3404 int genx, geny, genx2, geny2, sx, sy, sx2, sy2, ix, iy, nx, ny, i, flag;
3405 int8_t
x,
y, radius;
3406 int freecount = 0, freecountstop = 0;
3414 radius = (int8_t)strtol(
value, NULL, 10);
3446 ix = gen->
x-sx-genx2-radius+1;
3447 iy = gen->
y-sy-geny2-radius+1;
3448 sx += genx+sx2+radius*2-1;
3449 sy += geny+sy2+radius*2-1;
3459 x_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3460 y_array =
static_cast<int8_t *
>(malloc(sx*sy*
sizeof(int8_t)));
3465 for (
x = 0;
x < sx;
x++) {
3466 for (
y = 0;
y < sy;
y++) {
3479 x_array[freecount] = nx;
3480 y_array[freecount] = ny;
3493 freecountstop =
RANDOM()%freecount;
3494 for (i = 0; i < freecount; i++) {
3502 if (freecountstop <= 0) {
3551 int i,
index = 0, flag;
3554 for (i = start; i <
stop; i++) {
3557 altern[
index++] = i;
3609 static void permute(
int *arr,
int begin,
int end) {
3613 for (i = begin; i < end; i++) {
3865 if (
item->weight <= 0)
3871 if (
item->invisible)
3901 object *dst = NULL, *
tmp, *src, *part, *prev;
3908 for (part = src; part; part = part->more) {
3915 tmp->carrying =
tmp->arch->clone.carrying;
3952 if (
tmp->name == name_shared)
4000 for (
int i = 0; i < num_flags; ++i) {
4032 if (
tmp->type == type1 ||
tmp->type == type2)
4128 if (
tmp->type ==
type && strcmp(
tmp->race, race) == 0)
4153 if (
tmp->type ==
type &&
tmp->slaying != NULL && strcmp(
tmp->slaying, slaying) == 0)
4247 if (strcmp(
tmp->arch->name,
name) == 0)
4296 if (
tmp->type ==
type &&
tmp->subtype == subtype)
4315 for (link =
ob->key_values; link != NULL; link = link->
next) {
4339 const char *canonical_key;
4343 if (canonical_key == NULL) {
4355 for (link =
op->key_values; link != NULL; link = link->
next) {
4356 if (link->
key == canonical_key) {
4369 if (ret == NULL || (strcmp(ret,
"") == 0) || (strcmp(ret,
"0") == 0)) {
4382 for (
key_value *link =
op->key_values; link != NULL; link = link->next) {
4383 if (link->key ==
key) {
4384 if ((strcmp(link->value,
"") == 0) || (strcmp(link->value,
"0") == 0)) {
4410 for (field =
op->key_values; field != NULL; field = field->
next) {
4411 if (field->
key != canonical_key) {
4427 field->
value = NULL;
4435 last->next = field->
next;
4437 op->key_values = field->
next;
4464 field->
next =
op->key_values;
4465 op->key_values = field;
4491 const char *canonical_key = NULL;
4492 int floating_ref =
FALSE;
4500 if (canonical_key == NULL) {
4502 floating_ref =
TRUE;
4567 int count, retval = 0;
4572 for (cp = strtok(local_name,
","); cp; cp = strtok(NULL,
",")) {
4573 while (cp[0] ==
' ')
4578 if (!strcmp(cp,
"all"))
4584 if (!strcmp(cp,
"cursed")
4594 if (*cp ==
'+' || *cp ==
'-')
4597 cp = strchr(cp,
' ');
4598 while (cp && cp[0] ==
' ')
4607 if (!cp || cp[0] ==
'\0' ||
count < 0)
4629 else if (custom_name && !
strcasecmp(cp, custom_name))
4631 else if (!strncasecmp(cp, bname_s, strlen(cp)))
4633 else if (!strncasecmp(cp, bname_p, strlen(cp)))
4640 else if (strstr(bname_p, cp))
4642 else if (strstr(bname_s, cp))
4644 else if (strstr(name_short, cp))
4656 else if (custom_name && strstr(custom_name, cp))
4681 LOG(
llevError,
"object_fix_multipart: not on a map!\n");
4686 if (
tmp->head ||
tmp->more)
4692 for (at =
tmp->arch->more, last =
tmp; at != NULL; at = at->
more, last =
op) {
4701 if (
tmp->name !=
op->name) {
4706 if (
tmp->title !=
op->title) {
4737 int maxx = 0, maxy = 0, minx = 0, miny = 0;
4742 if (
ob->arch->more) {
4743 for (part =
ob->arch; part; part = part->
more) {
4744 if (part->
clone.
x > maxx)
4746 if (part->
clone.
y > maxy)
4748 if (part->
clone.
x < minx)
4750 if (part->
clone.
y < miny)
4803 if (
op->msg != NULL) {
4809 if (*
msg !=
'\0' && strchr(
msg,
'\0')[-1] !=
'\n') {
4843 "alive",
"wiz", NULL, NULL,
"was_wiz",
"applied",
"unpaid",
4844 "can_use_shield",
"no_pick",
"client_anim_sync",
"client_anim_random",
4845 "is_animated", NULL ,
4846 NULL ,
"monster",
"friendly",
"generator",
4847 "is_thrown",
"auto_apply",
"treasure",
"player sold",
4848 "see_invisible",
"can_roll",
"overlay_floor",
4849 "is_turnable", NULL , NULL ,
4850 NULL ,
"is_used_up",
"identified",
"reflecting",
4851 "changing",
"splitting",
"hitback",
"startequip",
4852 "blocksview",
"undead",
"scared",
"unaggressive",
4853 "reflect_missile",
"reflect_spell",
4854 "no_magic",
"no_fix_player",
"is_lightable",
"tear_down",
4855 "run_away", NULL , NULL ,
4856 NULL ,
"unique",
"no_drop",
4857 NULL ,
"can_cast_spell",
"can_use_scroll",
"can_use_range",
4858 "can_use_bow",
"can_use_armour",
"can_use_weapon",
4859 "can_use_ring",
"has_ready_range",
"has_ready_bow",
4860 "xrays", NULL,
"is_floor",
"lifesave",
"no_strength",
"sleep",
4861 "stand_still",
"random_movement",
"only_attack",
"confused",
4862 "stealth", NULL, NULL,
"cursed",
"damned",
4863 "see_anywhere",
"known_magical",
"known_cursed",
4864 "can_use_skill",
"been_applied",
4865 "has_ready_scroll", NULL, NULL,
4866 NULL,
"make_invisible",
"inv_locked",
"is_wooded",
4867 "is_hilly",
"has_ready_skill",
"has_ready_weapon",
4868 "no_skill_ident",
"is_blind",
"can_see_in_dark",
"is_cauldron",
4869 NULL,
"no_steal",
"one_hit", NULL,
"berserk",
"neutral",
4870 "no_attack",
"no_damage", NULL, NULL,
"activate_on_push",
4871 "activate_on_release",
"is_water",
"use_content_on_gen", NULL,
"is_buildable",
4872 NULL,
"blessed",
"known_blessed"
4886 int i, all_count = 0,
count;
4889 strcpy(retbuf_all,
" all");
4906 if (mt&(1<<
count)) {
4907 strcat(retbuf,
" ");
4910 strcat(retbuf_all,
" -");
4952 for (
int i = 0; i < 4; i++) {
4953 int idx = ffs((*diff)[i]);
4957 (*diff)[i] &= ~(1 << bit);
4978 static char buf2[64];
4987 for (my_field =
op->key_values; my_field != NULL; my_field = my_field->
next) {
4992 if (arch_field == NULL || my_field->
value != arch_field->
value) {
4998 if (my_field->
value)
5007 if (
op->name &&
op->name != op2->
name) {
5016 if (
op->title &&
op->title != op2->
title) {
5019 if (
op->race &&
op->race != op2->
race) {
5025 if (
op->skill &&
op->skill != op2->
skill) {
5028 if (
op->msg &&
op->msg != op2->
msg) {
5033 if (
op->lore &&
op->lore != op2->
lore) {
5038 if (
op->other_arch != op2->
other_arch &&
op->other_arch != NULL &&
op->other_arch->name) {
5041 if (
op->face != op2->
face) {
5046 if (
op->animation) {
5083 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->stats.exp);
5088 snprintf(buf2,
sizeof(buf2),
"%" FMT64,
op->total_exp);
5104 if (
op->x != op2->
x)
5106 if (
op->y != op2->
y)
5108 if (
op->speed != op2->
speed) {
5124 if (
op->nrof != op2->
nrof)
5130 if (
op->type != op2->
type)
5327 LOG(
llevError,
"could not find original archetype %s for custom monster!\n", at->
name);
5341 }
else if (
op->artifact != NULL) {
5348 LOG(
llevError,
"could not find artifact %s [%d] to save data\n",
op->artifact,
op->type);
5385 if (fputs(cp, fp) == EOF) {
5397 if (death_animation != NULL) {
5400 if (death != NULL) {
5417 if (
force == NULL) {
5423 if (duration != 0) {
5424 force->speed = 0.01;
5425 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]
Plugin animator file specs[Config] name
#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)
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various what they and how they effect the player s actions Also in this section are the stat modifiers that specific classes professions bring Player and sps the current and maximum the Current and Maximum The Current Sp can go somewhat negative When Sp is negative not all spells can be and a more negative Sp makes spell casting less likey to succeed can affect Damage and how the characters speed
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)
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in of these the most important may be the signs all a player must do is apply the handle In the case of the player must move items over the button to hold it down Some of the larger buttons may need very large items to be moved onto before they can be activated Gates and locked but be for you could fall down into a pit full of ghosts or dragons and not be able to get back out Break away sometimes it may be worth a player s time to test the walls of a map for secret doors Fire such as missile weapons and spells you will notice them going up in smoke ! So be careful not to destroy valuable items Spellbooks sometimes a player can learn the other times they cannot There are many different types of books and scrolls out there Improve item have lower weight
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
How to Install a Crossfire Server on you must install a python script engine on your computer Python is the default script engine of Crossfire You can find the python engine you have only to install them The VisualC Crossfire settings are for d
object * object_create_clone(object *asrc)
void object_copy_no_speed(const object *src_ob, object *dest_ob)
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)
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have so the higher your the better hidden the runes you make are Examples of whichever way you re facing invoke magic rune transfer as above
object * object_decrease_nrof(object *op, uint32_t i)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
void fatal(enum fatal_error err)
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
Magical Runes Runes are magical inscriptions on the dungeon floor
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)