Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
CF: Misc. crash fixes
- To: crossfire (at) ifi.uio.no
- Subject: CF: Misc. crash fixes
- From: Jan Echternach <>
- Date: Thu, 8 Jun 2000 18:21:32 +0200
- Mail-Followup-To:
- Reply-To: Jan Echternach <>
- Sender:
These patches are already in the CVS tree. They fix some more crashes
I've seen on the MwizardG map. From the CHANGES file:
common/button.c: do_mood_floor(): Bugfixes: Only players can have pets.
Call add_friendly_object() for friendly monsters.
server/spell_effect.c and server/spell_util.c: Several functions: Only
add a pet if there really is a pet's owner, and it's a player.
server/spell_effect.c: cast_charm() and cast_charm_undead(): Bugfixes:
Only players can cast these spells. This fixes server crash if
a monster casted a charm spell, and the charmed pet was killed.
Call add_friendly_object for friendly monsters.
common/friend.c: remove_friendly_object(): Use llevError for error
messages.
common/living.c: fix_player(); server/gods.c: tailor_god_spell();
server/spell_effect.c: summon_avatar() and animate_weapon(): Bugfix: Set
a string to NULL after calling free_string(). This fixes a nasty bug
that caused the string's reference count drop below 0, which resulted
in corruption of malloc()'s internal data structures (and possibly
server crashes).
server/time.c: move_creator(): Bugfix: Call free_string() to free old
values of op->name and op->title before overwriting them with new values.
common/object.c: insert_ob_in_map_simple() and insert_ob_in_map():
Check that we don't insert freed objects.
server/attack.c: hit_player_attacktype() and hit_player(): Bugfix: Check
that find_god() really found a god, and that 'god->slaying' is not NULL.
Fixes crash if a monster casted turn undead and actually hit something.
server/attack.c: hit_player(): Check that a pet's owner is a player.
Prevents server crashes if a monster has a pet monster due to a bug
somewhere. Use llevError for error message.
server/time.c: move_arrow(): Use llevDebug level for "Arrow had no
map" message.
server/c_object.c, server/spell_effect.c, server/spell_util.c: Bugfixes:
Added some missing checks for destroyed objects. Use was_destroyed()
or return value of insert_ob_in_map() to check for destroyed objects,
not FLAG_FREED or FLAG_REMOVED. Don't use op->count of destroyed objects.
server/shop.c: get_payment2(): Type of tag is 'tag_t', not 'long'.
server/spell_effect.c: animate_bomb(): Fix environment checks.
server/spell_util.c: fire_bolt(): Bugfix: Set level of bolt.
server/spell_util.c: explosion(): Bugfix: Set FLAG_NO_APPLY before
moving the exploding object to the top.
server/spell_util.c: put_a_monster(): First create the monster
completely, then just insert its head.
server/time.c: generate_monster(): Bugfix: Don't free generators that
are used up in this function. process_object() already does this.
This fixes steambolt (which is a generator but must not used up here -
generate_monster() wasn't looking at FLAG_IS_USED_UP) and all generators
which should really be used up (because process_object() didn't expect
generate_monster() to destroy the object).
--
Jan
diff -ru orig/crossfire-0.95.5-cvs3-patch20/server/c_object.c crossfire-0.95.5-cvs3/server/c_object.c
--- orig/crossfire-0.95.5-cvs3-patch20/server/c_object.c Fri May 26 11:50:49 2000
+++ crossfire-0.95.5-cvs3/server/c_object.c Thu Jun 8 03:15:48 2000
@@ -322,6 +322,7 @@
if(nrof != tmp->nrof && !(nrof == 1 && tmp->nrof == 0)) {
object *tmp2 = tmp;
+ tag_t tmp2_tag = tmp2->count;
tmp = get_split_ob (tmp, nrof);
if(!tmp) {
new_draw_info(NDI_UNIQUE, 0,pl, errmsg);
@@ -329,8 +330,8 @@
}
/* Tell a client what happened rest of objects */
if (pl->type == PLAYER) {
- if (QUERY_FLAG(tmp2, FLAG_REMOVED))
- esrv_del_item (pl->contr, tmp2->count);
+ if (was_destroyed (tmp2, tmp2_tag))
+ esrv_del_item (pl->contr, tmp2_tag);
else
esrv_send_item (pl, tmp2);
}
@@ -483,6 +484,7 @@
*/
void put_object_in_sack (object *op, object *sack, object *tmp, long nrof)
{
+ tag_t tmp_tag, tmp2_tag;
object *tmp2, *sack2;
char buf[MAX_BUF];
@@ -536,6 +538,7 @@
/* we want to put some portion of the item into the container */
if (nrof && tmp->nrof != nrof) {
object *tmp2 = tmp;
+ tmp2_tag = tmp2->count;
tmp = get_split_ob (tmp, nrof);
if(!tmp) {
@@ -543,8 +546,8 @@
return;
}
/* Tell a client what happened other objects */
- if (QUERY_FLAG(tmp2, FLAG_FREED))
- esrv_del_item (op->contr, tmp2->count);
+ if (was_destroyed (tmp2, tmp2_tag))
+ esrv_del_item (op->contr, tmp2_tag);
else /* this can proably be replaced with an update */
esrv_send_item (op, tmp2);
} else
@@ -553,6 +556,7 @@
sprintf(buf, "You put %s in ", query_name(tmp));
strcat (buf, query_name(sack));
strcat (buf, ".");
+ tmp_tag = tmp->count;
tmp2 = insert_ob_in_ob(tmp, sack);
new_draw_info(NDI_UNIQUE, 0,op,buf);
fix_player(op); /* This is overkill, fix_player() is called somewhere */
@@ -562,7 +566,7 @@
* delete the original.
*/
if (tmp2 != tmp)
- esrv_del_item (op->contr, tmp->count);
+ esrv_del_item (op->contr, tmp_tag);
esrv_send_item (op, tmp2);
/* update the sacks and players weight */
@@ -604,6 +608,7 @@
*/
if(nrof && tmp->nrof != nrof) {
object *tmp2 = tmp;
+ tag_t tmp2_tag = tmp2->count;
tmp = get_split_ob (tmp, nrof);
if(!tmp) {
new_draw_info(NDI_UNIQUE, 0,op, errmsg);
@@ -612,8 +617,8 @@
/* Tell a client what happened rest of objects. tmp2 is now the
* original object
*/
- if (QUERY_FLAG(tmp2, FLAG_FREED))
- esrv_del_item (op->contr, tmp2->count);
+ if (was_destroyed (tmp2, tmp2_tag))
+ esrv_del_item (op->contr, tmp2_tag);
else
esrv_send_item (op, tmp2);
} else
diff -ru orig/crossfire-0.95.5-cvs3-patch20/server/shop.c crossfire-0.95.5-cvs3/server/shop.c
--- orig/crossfire-0.95.5-cvs3-patch20/server/shop.c Fri Sep 17 21:11:24 1999
+++ crossfire-0.95.5-cvs3/server/shop.c Thu Jun 8 03:17:23 2000
@@ -467,7 +467,7 @@
return 0;
} else {
object *tmp;
- long c = op->count;
+ tag_t c = op->count;
CLEAR_FLAG(op, FLAG_UNPAID);
new_draw_info_format(NDI_UNIQUE, 0, op,
diff -ru orig/crossfire-0.95.5-cvs3-patch20/server/spell_effect.c crossfire-0.95.5-cvs3/server/spell_effect.c
--- orig/crossfire-0.95.5-cvs3-patch20/server/spell_effect.c Tue Jun 6 17:03:07 2000
+++ crossfire-0.95.5-cvs3/server/spell_effect.c Thu Jun 8 11:52:41 2000
@@ -294,14 +294,8 @@
/* Put the new creature on the map */
op->x = x; op->y = y;
- insert_ob_in_map(op,map,owner);
-
- /* It is possible that there is something on the map that kills
- * the object when inserted. Unlikely, but worth checking. */
- if (QUERY_FLAG(op, FLAG_FREED)) return;
-
- /*update_object(op);*/ /*I believe insert_ob_in_map already does this */
-
+ if ((op = insert_ob_in_map (op, map, owner)) == NULL)
+ return;
if(op->randomitems != NULL)
create_treasure(op->randomitems,op,GT_INVISIBLE,map->difficulty,0);
@@ -872,9 +866,7 @@
return 0;
}
tmp->x=op->x+freearr_x[dir],tmp->y=op->y+freearr_y[dir];
- insert_ob_in_map(tmp,op->map,op);
-
- if (QUERY_FLAG(tmp, FLAG_REMOVED)) {
+ if ((tmp = insert_ob_in_map (tmp, op->map, op)) == NULL) {
new_draw_info(NDI_UNIQUE, 0,op,"Something destroys your wall");
return 0;
}
@@ -1003,8 +995,8 @@
remove_ob(op);
op->x=x,op->y=y;
- insert_ob_in_map(op,op->map,op);
- draw(op);
+ if ((op = insert_ob_in_map(op,op->map,op)) != NULL)
+ draw(op);
return 1;
}
} else { /* Player didn't specify a distance, so lets see how far
@@ -1031,7 +1023,8 @@
/* Actually move the player now */
remove_ob(op);
op->x+=freearr_x[dir]*dist,op->y+=freearr_y[dir]*dist;
- insert_ob_in_map(op,op->map,op);
+ if ((op = insert_ob_in_map(op,op->map,op)) == NULL)
+ return 1;
draw(op);
op->speed_left= -FABS(op->speed)*5; /* Freeze them for a short while */
return 1;
@@ -1482,8 +1475,8 @@
prev = tmp;
}
head->direction = dir;
- insert_ob_in_map(head, op->map, op);
- if (!QUERY_FLAG(head, FLAG_FREED) && head->randomitems != NULL) {
+ head = insert_ob_in_map (head, op->map, op);
+ if (head != NULL && head->randomitems != NULL) {
object *tmp;
create_treasure(head->randomitems,head,GT_INVENTORY,6,0);
for(tmp = head->inv; tmp != NULL; tmp = tmp->below)
@@ -1542,10 +1535,12 @@
at = find_archetype("splint");
for(env=op;env->env!=NULL;env=env->env);
if (op->env) {
- if (op->type==PLAYER) drop(env,op);
+ if (env->type==PLAYER) drop(env,op);
else {
+ SET_FLAG (op, FLAG_NO_APPLY);
remove_ob(op);
insert_ob_in_map(op, env->map, op);
+ CLEAR_FLAG (op, FLAG_NO_APPLY);
}
}
if (env->map == NULL)
@@ -1647,6 +1642,7 @@
int missile_plus=0;
char *missile_name;
object *tmp, *missile;
+ tag_t tag;
missile_name = "arrow";
@@ -1685,7 +1681,10 @@
arrows +4 and selling them, even with value = 1 */
SET_FLAG(missile, FLAG_IDENTIFIED);
- if (!cast_create_obj(op,caster,missile,dir) && op->type==PLAYER) {
+ tag = missile->count;
+ if ( ! cast_create_obj (op, caster, missile, dir) && op->type == PLAYER
+ && ! was_destroyed (missile, tag))
+ {
tmp= get_owner(op);
if (!tmp)
pick_up(op, missile);
@@ -2265,7 +2264,8 @@
free_object(tmp);
return 0;
}
- insert_ob_in_map(tmp,op->map,op);
+ if ((tmp = insert_ob_in_map (tmp, op->map, op)) == NULL)
+ return 1;
if(QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
update_all_los(op->map);
if(op->type==PLAYER)
@@ -2706,8 +2706,8 @@
}
} /* if monster level is much less than character level */
- insert_ob_in_map(head, op->map, op);
- if (!QUERY_FLAG(head, FLAG_FREED) && head->randomitems != NULL) {
+ head = insert_ob_in_map (head, op->map, op);
+ if (head != NULL && head->randomitems != NULL) {
object *tmp;
create_treasure(head->randomitems,head,GT_INVENTORY,6,0);
for(tmp = head->inv; tmp != NULL; tmp = tmp->below)
diff -ru orig/crossfire-0.95.5-cvs3-patch20/server/spell_util.c crossfire-0.95.5-cvs3/server/spell_util.c
--- orig/crossfire-0.95.5-cvs3-patch20/server/spell_util.c Mon May 29 18:31:26 2000
+++ crossfire-0.95.5-cvs3/server/spell_util.c Thu Jun 8 02:31:55 2000
@@ -954,6 +954,7 @@
if(QUERY_FLAG(tmp, FLAG_IS_TURNABLE))
SET_ANIMATION(tmp, dir);
set_owner(tmp,op);
+ tmp->level = SK_level (caster);
#if 0
if(op->type==PLAYER)
tmp->stats.wc=5+(op->contr->shootstrength-5)/5,
@@ -969,8 +970,8 @@
tmp->x=op->x,tmp->y=op->y;
tmp->direction=absdir(tmp->direction+4);
}
- insert_ob_in_map(tmp,op->map,op);
- move_bolt(tmp);
+ if ((tmp = insert_ob_in_map(tmp,op->map,op)) != NULL)
+ move_bolt (tmp);
return 1;
}
@@ -1026,11 +1027,8 @@
if(op->type==PLAYER)
tmp->stats.hp=(op->contr->shootstrength-10)/10+10;
#endif
- insert_ob_in_map(tmp,op->map,op);
- /* object was used when it was inserted into the map - don't do anything
- * more
- */
- if (QUERY_FLAG(tmp, FLAG_FREED)) return 1;
+ if ((tmp = insert_ob_in_map (tmp, op->map, op)) == NULL)
+ return 1;
switch(type) {
case SP_M_MISSILE:
move_missile(tmp);
@@ -1210,8 +1208,10 @@
return;
}
if(op->above!=NULL&&op->above->type!=PLAYER) {
+ SET_FLAG (op, FLAG_NO_APPLY);
remove_ob(op);
insert_ob_in_map(op,op->map,op);
+ CLEAR_FLAG (op, FLAG_NO_APPLY);
}
hit_map(op,0,op->attacktype);
if(op->stats.hp>2&&!op->value) {
@@ -1303,12 +1303,15 @@
tmp->value=0;
tmp->stats.hp++;
tmp->x+=DIRX(tmp),tmp->y+=DIRY(tmp);
- insert_ob_in_map(tmp,op->map,op);
- if (!tmp->stats.food) {
- tmp->stats.food = 1;
- move_bolt(tmp);
- } else
- tmp->stats.food = 0;
+ tmp = insert_ob_in_map(tmp,op->map,op);
+ if (tmp) {
+ if ( ! tmp->stats.food) {
+ tmp->stats.food = 1;
+ move_bolt (tmp);
+ } else {
+ tmp->stats.food = 0;
+ }
+ }
}
}
}
@@ -1320,6 +1323,7 @@
void move_golem(object *op) {
int made_attack=0;
object *tmp;
+ tag_t tag;
if(QUERY_FLAG(op, FLAG_MONSTER))
return; /* Has already been moved */
@@ -1358,7 +1362,10 @@
* move_ob (makes recursive calls to other parts)
* move_ob returns 0 if the creature was not able to move.
*/
+ tag = op->count;
if(move_ob(op,op->direction,op)) return;
+ if (was_destroyed (op, tag))
+ return;
for(tmp=op;tmp;tmp=tmp->more) {
int x=tmp->x+freearr_x[op->direction],y=tmp->y+freearr_y[op->direction];
@@ -1560,8 +1567,8 @@
if(reflwall(op->map,op->x,op->y)) {
op->direction=absdir(op->direction+4);
- insert_ob_in_map(op,op->map,op);
- update_turn_face(op);
+ if ((op = insert_ob_in_map(op,op->map,op)) != NULL)
+ update_turn_face(op);
return;
}
if(blocked(op->map,op->x,op->y)) {
@@ -1942,13 +1949,12 @@
tmp->head=head;
prev->more=tmp;
}
- insert_ob_in_map(tmp,op->map,op);
- /* If something happens on the insert, don't insert anymore parts */
- if (QUERY_FLAG(tmp,FLAG_FREED)) break;
if (!head) head=tmp;
prev=tmp;
at=at->more;
}
+
+ insert_ob_in_map(head,op->map,op);
/* thought it'd be cool to insert a burnout, too.*/
tmp=get_archetype("burnout");
diff -ru orig/crossfire-0.95.5-cvs3-patch20/server/time.c crossfire-0.95.5-cvs3/server/time.c
--- orig/crossfire-0.95.5-cvs3-patch20/server/time.c Tue Jun 6 17:03:07 2000
+++ crossfire-0.95.5-cvs3/server/time.c Thu Jun 8 11:38:02 2000
@@ -100,10 +100,6 @@
prev=op;
at=at->more;
}
- if(gen->stats.food&&!--(gen->stats.food)) {
- remove_ob(gen);
- free_object(gen);
- }
}
void regenerate_rod(object *rod) {
diff -ru orig/crossfire-0.95.5-cvs3-patch21/common/button.c crossfire-0.95.5-cvs3/common/button.c
--- orig/crossfire-0.95.5-cvs3-patch21/common/button.c Fri May 26 11:50:45 2000
+++ crossfire-0.95.5-cvs3/common/button.c Thu Jun 8 12:18:03 2000
@@ -552,11 +552,14 @@
for(tmp2=get_map_ob(op2->map,op2->x,op2->y); /* finding an owner */
tmp2->type!=PLAYER;tmp2=tmp2->above)
if(tmp2->above==NULL) break;
-
+
+ if (tmp2->type != PLAYER)
+ break;
set_owner(tmp,tmp2);
SET_FLAG(tmp,FLAG_MONSTER);
tmp->stats.exp = 0;
SET_FLAG(tmp, FLAG_FRIENDLY);
+ add_friendly_object (tmp);
tmp->move_type = PETMOVE;
break;
diff -ru orig/crossfire-0.95.5-cvs3-patch21/common/friend.c crossfire-0.95.5-cvs3/common/friend.c
--- orig/crossfire-0.95.5-cvs3-patch21/common/friend.c Tue Jul 13 08:02:41 1999
+++ crossfire-0.95.5-cvs3/common/friend.c Thu Jun 8 12:13:12 2000
@@ -54,7 +54,7 @@
prev=prev->next;
if(prev==NULL||prev->next==NULL||
prev->next->ob!=op||prev->next->id!=op->count) {
- LOG(llevDebug,"Remove_friendly_object: Can't find object %s (%d).\n",
+ LOG(llevError,"Remove_friendly_object: Can't find object %s (%d).\n",
op->name,op->count);
return;
}
diff -ru orig/crossfire-0.95.5-cvs3-patch21/common/living.c crossfire-0.95.5-cvs3/common/living.c
--- orig/crossfire-0.95.5-cvs3-patch21/common/living.c Sun May 28 20:27:00 2000
+++ crossfire-0.95.5-cvs3/common/living.c Thu Jun 8 15:29:03 2000
@@ -1052,8 +1052,11 @@
if(tmp->armour)
op->armour+=((100-op->armour)*tmp->armour)/100;
- if(tmp->slaying!=NULL)
+ if(tmp->slaying!=NULL) {
+ if (op->slaying != NULL)
+ free_string (op->slaying);
add_refcount(op->slaying = tmp->slaying);
+ }
if(tmp->stats.ac)
op->stats.ac-=(tmp->stats.ac+tmp->magic);
@@ -1094,8 +1097,11 @@
weapon_weight=tmp->weight;
weapon_speed=((int)WEAPON_SPEED(tmp)*2-tmp->magic)/2;
if(weapon_speed<0) weapon_speed=0;
- if(tmp->slaying!=NULL)
+ if(tmp->slaying!=NULL) {
+ if (op->slaying != NULL)
+ free_string (op->slaying);
add_refcount(op->slaying = tmp->slaying);
+ }
#ifdef SPELL_ENCUMBRANCE
if(op->type==PLAYER) op->contr->encumbrance+=(int)3*tmp->weight/1000;
#endif
diff -ru orig/crossfire-0.95.5-cvs3-patch21/common/object.c crossfire-0.95.5-cvs3/common/object.c
--- orig/crossfire-0.95.5-cvs3-patch21/common/object.c Sun May 28 20:27:00 2000
+++ crossfire-0.95.5-cvs3/common/object.c Thu Jun 8 13:26:04 2000
@@ -1227,6 +1227,10 @@
{
object *tmp, *top;
+ if (QUERY_FLAG (op, FLAG_FREED)) {
+ LOG (llevError, "Trying to insert freed object!\n");
+ return;
+ }
if(m==NULL) {
dump_object(op);
LOG(llevError,"Trying to insert in null-map!\n%s\n",errmsg);
@@ -1343,6 +1347,10 @@
{
object *tmp, *top;
+ if (QUERY_FLAG (op, FLAG_FREED)) {
+ LOG (llevError, "Trying to insert freed object!\n");
+ return;
+ }
if(m==NULL) {
dump_object(op);
LOG(llevError,"Trying to insert in null-map!\n%s\n",errmsg);
diff -ru orig/crossfire-0.95.5-cvs3-patch21/server/attack.c crossfire-0.95.5-cvs3/server/attack.c
--- orig/crossfire-0.95.5-cvs3-patch21/server/attack.c Thu Jun 8 01:21:56 2000
+++ crossfire-0.95.5-cvs3/server/attack.c Thu Jun 8 14:15:41 2000
@@ -670,10 +670,15 @@
} else if (attacktype & AT_TURN_UNDEAD) {
if (QUERY_FLAG(op,FLAG_UNDEAD)) {
object *owner=get_owner(hitter)==NULL?hitter:get_owner(hitter);
- /* if undead are not an enemy of your god, you turn them at half strength */
- if(op->level<((turn_bonus[owner->stats.Wis]+owner->level) /
- (strstr(find_god(determine_god(owner))->slaying,undead_name)?1:2)))
- SET_FLAG(op, FLAG_SCARED);
+ object *god = find_god (determine_god (owner));
+ int div = 1;
+ /* if undead are not an enemy of your god, you turn them at half
+ * strength */
+ if ( ! god || ! god->slaying
+ || strstr (god->slaying, undead_name) == NULL)
+ div = 2;
+ if (op->level < (turn_bonus[owner->stats.Wis]+owner->level) / div)
+ SET_FLAG(op, FLAG_SCARED);
}
else dam=0; /*don't damage non undead - should we damage undead? */
/* fear, cancelleation, deplete handled above */
@@ -800,12 +805,15 @@
* a proper match, otherwise no damage.
*/
if (type & AT_HOLYWORD) {
+ object *god;
if ((!hitter->slaying ||
(!(op->race && strstr(hitter->slaying,op->race)) &&
!(op->name && strstr(hitter->slaying,op->name)))) &&
(!QUERY_FLAG(op,FLAG_UNDEAD) ||
- (hitter->title != NULL &&
- (strstr(find_god(determine_god(hitter))->race,undead_name)!=NULL))))
+ (hitter->title != NULL
+ && (god = find_god(determine_god(hitter))) != NULL
+ && god->race != NULL
+ && strstr(god->race,undead_name) != NULL)))
return 0;
}
@@ -885,10 +893,11 @@
}
if(QUERY_FLAG (op, FLAG_FRIENDLY)) {
remove_friendly_object(op);
- if(get_owner(op)!=NULL)
+ if (get_owner (op) != NULL && op->owner->type == PLAYER)
op->owner->contr->golem=NULL;
else
- LOG(llevDebug,"Encountered golem without owner.\n");
+ LOG (llevError, "BUG: hit_player(): Encountered golem "
+ "without owner.\n");
remove_ob(op);
free_object(op);
return maxdam;
diff -ru orig/crossfire-0.95.5-cvs3-patch21/server/gods.c crossfire-0.95.5-cvs3/server/gods.c
--- orig/crossfire-0.95.5-cvs3-patch21/server/gods.c Fri May 26 11:50:49 2000
+++ crossfire-0.95.5-cvs3/server/gods.c Thu Jun 8 16:50:52 2000
@@ -658,7 +658,10 @@
/* either holy word or godpower attacks will set the slaying field */
if(spellop->attacktype&AT_HOLYWORD||spellop->attacktype&AT_GODPOWER) {
- if(spellop->slaying) free_string(spellop->slaying);
+ if (spellop->slaying) {
+ free_string(spellop->slaying);
+ spellop->slaying = NULL;
+ }
if(!caster_is_spell)
spellop->slaying = add_string(god->slaying);
else if(caster->slaying)
diff -ru orig/crossfire-0.95.5-cvs3-patch21/server/spell_effect.c crossfire-0.95.5-cvs3/server/spell_effect.c
--- orig/crossfire-0.95.5-cvs3-patch21/server/spell_effect.c Thu Jun 8 13:01:20 2000
+++ crossfire-0.95.5-cvs3/server/spell_effect.c Thu Jun 8 15:37:40 2000
@@ -771,16 +771,6 @@
10* SP_level_strength_adjust(op,caster,spell_type);
/* More solid, since they can be torn down */
tmp->stats.maxhp = tmp->stats.hp;
-#if 0
- /* Don't make them friendly - ends up making them too hard hard for other
- * players to kill
- */
- /*
- * Now, make agressive monsters tear down the walls:
- */
- SET_FLAG(tmp, FLAG_FRIENDLY);
- add_friendly_object(tmp);
-#endif
break;
case SP_FIRE_WALL:
tmp=get_archetype("firebreath");
@@ -1455,12 +1445,15 @@
add_friendly_object(tmp);
SET_FLAG(tmp, FLAG_FRIENDLY);
tmp->move_type = PETMOVE;
- } else
- if(QUERY_FLAG(op, FLAG_FRIENDLY)) {
- add_friendly_object(tmp);
- SET_FLAG(tmp, FLAG_FRIENDLY);
- tmp->move_type = PETMOVE;
- } else
+ } else if (QUERY_FLAG (op, FLAG_FRIENDLY)) {
+ object *owner = get_owner(op);
+ if (owner != NULL) {
+ set_owner (tmp, owner);
+ tmp->move_type = PETMOVE;
+ add_friendly_object (tmp);
+ SET_FLAG (tmp, FLAG_FRIENDLY);
+ }
+ }
tmp->speed_left = -1;
tmp->enemy = op->enemy;
tmp->type = 0;
@@ -2457,6 +2450,8 @@
int i;
object *tmp,*effect;
+ if (op->type != PLAYER)
+ return 0;
for(i=1;i<MIN(9+SP_level_strength_adjust(op,caster,spellnum),SIZEOFFREE);i++) {
if (out_of_map(op->map,op->x+freearr_x[i],op->y+freearr_y[i]))
continue;
@@ -2477,9 +2472,9 @@
}
set_owner(tmp,op);
SET_FLAG(tmp,FLAG_MONSTER);
- if(op->type==PLAYER)
- tmp->stats.exp = 0;
SET_FLAG(tmp,FLAG_FRIENDLY);
+ add_friendly_object (tmp);
+ tmp->stats.exp = 0;
tmp->move_type = PETMOVE;
}
return 1;
@@ -2488,7 +2483,9 @@
int cast_charm_undead(object *op, object *caster,archetype *arch,int spellnum) {
int i,bonus;
object *tmp,*effect;
-
+
+ if (op->type != PLAYER)
+ return 0;
if (QUERY_FLAG(caster,FLAG_UNDEAD) || strstr(find_god(determine_god(op))->race,undead_name)!=NULL) {
bonus = 5;
} else if (strstr(find_god(determine_god(op))->slaying,undead_name)!=NULL) {
@@ -2515,9 +2512,9 @@
}
set_owner(tmp,op);
SET_FLAG(tmp,FLAG_MONSTER);
- if(op->type==PLAYER)
- tmp->stats.exp = 0;
SET_FLAG(tmp,FLAG_FRIENDLY);
+ add_friendly_object (tmp);
+ tmp->stats.exp = 0;
tmp->move_type = PETMOVE;
}
return 1;
@@ -2798,8 +2795,14 @@
tmp->vulnerable|=god->vulnerable;
tmp->immune|=god->immune;
tmp->protected|=god->protected;
- if(tmp->race) free_string(tmp->race);
- if(tmp->slaying) free_string(tmp->slaying);
+ if (tmp->race) {
+ free_string (tmp->race);
+ tmp->race = NULL;
+ }
+ if (tmp->slaying) {
+ free_string (tmp->slaying);
+ tmp->slaying = NULL;
+ }
if(god->race) tmp->race = add_string(god->race);
if(god->slaying) tmp->slaying = add_string(god->slaying);
/* safety, we must allow a god's servants some reasonable attack */
@@ -2839,11 +2842,12 @@
} else {
if(QUERY_FLAG(op, FLAG_FRIENDLY)) {
object *owner = get_owner(op);
- if(owner != NULL) /* For now, we transfer ownership */
+ if(owner != NULL) {/* For now, we transfer ownership */
set_owner(tmp,owner);
- tmp->move_type = PETMOVE;
- add_friendly_object(tmp);
- SET_FLAG(tmp, FLAG_FRIENDLY);
+ tmp->move_type = PETMOVE;
+ add_friendly_object(tmp);
+ SET_FLAG(tmp, FLAG_FRIENDLY);
+ }
}
}
if(op->type!=PLAYER||type!=GOLEM) {
@@ -3058,11 +3062,12 @@
&& !QUERY_FLAG(weapon,FLAG_CURSED)
&& !QUERY_FLAG(weapon,FLAG_DAMNED)){
object *owner = get_owner(op);
- if(owner != NULL)
+ if(owner != NULL) {
set_owner(tmp,owner);
- tmp->move_type = PETMOVE;
- add_friendly_object(tmp);
- SET_FLAG(tmp, FLAG_FRIENDLY);
+ tmp->move_type = PETMOVE;
+ add_friendly_object(tmp);
+ SET_FLAG(tmp, FLAG_FRIENDLY);
+ }
}
/* otherwise, make the golem an enemy */
SET_FLAG(tmp, FLAG_MONSTER);
@@ -3135,7 +3140,10 @@
}
tmp->armour = 100 - (int)((100.0-(float)tmp->armour)/(30.0-2.0*(a>14?14.0:(float)a)));
/* If the weapon has a Slaying list, so does the golem */
- if(tmp->slaying) free_string(tmp->slaying);
+ if (tmp->slaying) {
+ free_string (tmp->slaying);
+ tmp->slaying = NULL;
+ }
if(weapon->slaying) tmp->slaying = add_string(weapon->slaying);
/* Determine golem's speed */
diff -ru orig/crossfire-0.95.5-cvs3-patch21/server/spell_util.c crossfire-0.95.5-cvs3/server/spell_util.c
--- orig/crossfire-0.95.5-cvs3-patch21/server/spell_util.c Thu Jun 8 13:01:20 2000
+++ crossfire-0.95.5-cvs3/server/spell_util.c Thu Jun 8 12:49:22 2000
@@ -834,11 +834,12 @@
} else {
if(QUERY_FLAG(op, FLAG_FRIENDLY)) {
object *owner = get_owner(op);
- if(owner != NULL) /* For now, we transfer ownership */
- set_owner(tmp,owner);
- tmp->move_type = PETMOVE;
- add_friendly_object(tmp);
- SET_FLAG(tmp, FLAG_FRIENDLY);
+ if (owner != NULL) { /* For now, we transfer ownership */
+ set_owner (tmp, owner);
+ tmp->move_type = PETMOVE;
+ add_friendly_object (tmp);
+ SET_FLAG (tmp, FLAG_FRIENDLY);
+ }
}
SET_FLAG(tmp, FLAG_MONSTER);
}
diff -ru orig/crossfire-0.95.5-cvs3-patch21/server/time.c crossfire-0.95.5-cvs3/server/time.c
--- orig/crossfire-0.95.5-cvs3-patch21/server/time.c Thu Jun 8 13:01:20 2000
+++ crossfire-0.95.5-cvs3/server/time.c Thu Jun 8 15:39:48 2000
@@ -511,7 +511,7 @@
object *tmp;
if(op->map==NULL) {
- LOG(llevError,"Arrow had no map.\n");
+ LOG(llevDebug,"Arrow had no map.\n");
remove_ob(op);
free_object(op);
return;
@@ -773,6 +773,8 @@
{ op->stats.hp=-1;return;}
tmp=arch_to_object(op->other_arch);
if(op->slaying) {
+ if (tmp->name) free_string (tmp->name);
+ if (tmp->title) free_string (tmp->title);
tmp->name = add_string(op->slaying);
tmp->title = add_string(op->slaying);
}
diff -ru orig/crossfire-0.95.5-cvs3-patch22/server/spell_effect.c crossfire-0.95.5-cvs3/server/spell_effect.c
--- orig/crossfire-0.95.5-cvs3-patch22/server/spell_effect.c Thu Jun 8 17:23:54 2000
+++ crossfire-0.95.5-cvs3/server/spell_effect.c Thu Jun 8 17:23:13 2000
@@ -1528,16 +1528,15 @@
at = find_archetype("splint");
for(env=op;env->env!=NULL;env=env->env);
if (op->env) {
+ if (env->map == NULL)
+ return;
if (env->type==PLAYER) drop(env,op);
else {
- SET_FLAG (op, FLAG_NO_APPLY);
remove_ob(op);
- insert_ob_in_map(op, env->map, op);
- CLEAR_FLAG (op, FLAG_NO_APPLY);
+ if ((op = insert_ob_in_map (op, env->map, op)) == NULL)
+ return;
}
}
- if (env->map == NULL)
- return;
if (at)
for(i=1;i<9;i++)
fire_arch(op,op,i,at,0,0);