--- deliantra/server/common/object.C 2006/08/29 05:03:54 1.7 +++ deliantra/server/common/object.C 2006/08/29 08:01:35 1.8 @@ -1,6 +1,6 @@ /* * static char *rcsid_object_c = - * "$Id: object.C,v 1.7 2006/08/29 05:03:54 root Exp $"; + * "$Id: object.C,v 1.8 2006/08/29 08:01:35 root Exp $"; */ /* @@ -134,28 +134,28 @@ * check? */ if (!QUERY_FLAG(ob1,FLAG_ANIMATE) && FABS((ob1)->speed) > MIN_ACTIVE_SPEED) - return 0; + return 0; /* Do not merge objects if nrof would overflow. We use 1UL<<31 since that * value could not be stored in a sint32 (which unfortunately sometimes is * used to store nrof). */ if (ob1->nrof+ob2->nrof >= 1UL<<31) - return 0; + return 0; /* This is really a spellbook check - really, we should * check all objects in the inventory. */ if (ob1->inv || ob2->inv) { - /* if one object has inventory but the other doesn't, not equiv */ - if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) return 0; + /* if one object has inventory but the other doesn't, not equiv */ + if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) return 0; - /* Now check to see if the two inventory objects could merge */ - if (!CAN_MERGE(ob1->inv, ob2->inv)) return 0; + /* Now check to see if the two inventory objects could merge */ + if (!CAN_MERGE(ob1->inv, ob2->inv)) return 0; - /* inventory ok - still need to check rest of this object to see - * if it is valid. - */ + /* inventory ok - still need to check rest of this object to see + * if it is valid. + */ } /* If the objects have been identified, set the BEEN_APPLIED flag. @@ -165,10 +165,10 @@ * flags lose any meaning. */ if (QUERY_FLAG(ob1, FLAG_IDENTIFIED)) - SET_FLAG(ob1, FLAG_BEEN_APPLIED); + SET_FLAG(ob1, FLAG_BEEN_APPLIED); if (QUERY_FLAG(ob2, FLAG_IDENTIFIED)) - SET_FLAG(ob2, FLAG_BEEN_APPLIED); + SET_FLAG(ob2, FLAG_BEEN_APPLIED); /* the 0x400000 on flags2 is FLAG_INV_LOCK. I don't think something @@ -176,47 +176,47 @@ * 0x4 in flags3 is CLIENT_SENT */ if ((ob1->arch != ob2->arch) || - (ob1->flags[0] != ob2->flags[0]) || - (ob1->flags[1] != ob2->flags[1]) || - ((ob1->flags[2] & ~0x400000) != (ob2->flags[2] & ~ 0x400000)) || - ((ob1->flags[3] & ~0x4) != (ob2->flags[3] & ~0x4)) || - (ob1->name != ob2->name) || - (ob1->title != ob2->title) || - (ob1->msg != ob2->msg) || - (ob1->weight != ob2->weight) || - (memcmp(&ob1->resist, &ob2->resist, sizeof(ob1->resist))!=0) || - (memcmp(&ob1->stats, &ob2->stats, sizeof(ob1->stats))!=0) || - (ob1->attacktype != ob2->attacktype) || - (ob1->magic != ob2->magic) || - (ob1->slaying != ob2->slaying) || - (ob1->skill != ob2->skill) || - (ob1->value != ob2->value) || - (ob1->animation_id != ob2->animation_id) || - (ob1->client_type != ob2->client_type) || - (ob1->materialname != ob2->materialname) || - (ob1->lore != ob2->lore) || - (ob1->subtype != ob2->subtype) || - (ob1->move_type != ob2->move_type) || - (ob1->move_block != ob2->move_block) || - (ob1->move_allow != ob2->move_allow) || - (ob1->move_on != ob2->move_on) || - (ob1->move_off != ob2->move_off) || - (ob1->move_slow != ob2->move_slow) || - (ob1->move_slow_penalty != ob2->move_slow_penalty) - ) - return 0; + (ob1->flags[0] != ob2->flags[0]) || + (ob1->flags[1] != ob2->flags[1]) || + ((ob1->flags[2] & ~0x400000) != (ob2->flags[2] & ~ 0x400000)) || + ((ob1->flags[3] & ~0x4) != (ob2->flags[3] & ~0x4)) || + (ob1->name != ob2->name) || + (ob1->title != ob2->title) || + (ob1->msg != ob2->msg) || + (ob1->weight != ob2->weight) || + (memcmp(&ob1->resist, &ob2->resist, sizeof(ob1->resist))!=0) || + (memcmp(&ob1->stats, &ob2->stats, sizeof(ob1->stats))!=0) || + (ob1->attacktype != ob2->attacktype) || + (ob1->magic != ob2->magic) || + (ob1->slaying != ob2->slaying) || + (ob1->skill != ob2->skill) || + (ob1->value != ob2->value) || + (ob1->animation_id != ob2->animation_id) || + (ob1->client_type != ob2->client_type) || + (ob1->materialname != ob2->materialname) || + (ob1->lore != ob2->lore) || + (ob1->subtype != ob2->subtype) || + (ob1->move_type != ob2->move_type) || + (ob1->move_block != ob2->move_block) || + (ob1->move_allow != ob2->move_allow) || + (ob1->move_on != ob2->move_on) || + (ob1->move_off != ob2->move_off) || + (ob1->move_slow != ob2->move_slow) || + (ob1->move_slow_penalty != ob2->move_slow_penalty) + ) + return 0; /* Don't merge objects that are applied. With the new 'body' code, * it is possible for most any character to have more than one of * some items equipped, and we don't want those to merge. */ if (QUERY_FLAG(ob1, FLAG_APPLIED) || QUERY_FLAG(ob2, FLAG_APPLIED)) - return 0; + return 0; switch (ob1->type) { - case SCROLL: - if (ob1->level != ob2->level) return 0; - break; + case SCROLL: + if (ob1->level != ob2->level) return 0; + break; } if (ob1->key_values != NULL || ob2->key_values != NULL) { @@ -243,7 +243,7 @@ object *inv; for(sum = 0, inv = op->inv; inv != NULL; inv = inv->below) { if (inv->inv) - sum_weight(inv); + sum_weight(inv); sum += inv->carrying + inv->weight * (inv->nrof ? inv->nrof : 1); } if (op->type == CONTAINER && op->stats.Str) @@ -272,7 +272,7 @@ object *is_player_inv (object *op) { for (;op!=NULL&&op->type!=PLAYER; op=op->env) if (op->env==op) - op->env = NULL; + op->env = NULL; return op; } @@ -291,7 +291,7 @@ strcat(errmsg,op->arch->name?op->arch->name:"(null)"); strcat(errmsg,"\n"); if((cp=get_ob_diff(op,&empty_archetype->clone))!=NULL) - strcat(errmsg,cp); + strcat(errmsg,cp); #if 0 /* Don't dump player diffs - they are too long, mostly meaningless, and * will overflow the buffer. @@ -430,15 +430,15 @@ object *op, *next; for (op=free_objects; op!=NULL; ) { - next=op->next; - free(op); - nrofallocobjects--; - nroffreeobjects--; - op=next; + next=op->next; + free(op); + nrofallocobjects--; + nroffreeobjects--; + op=next; } #endif LOG(llevDebug,"%d allocated objects, %d free objects, STARMAX=%d\n", - nrofallocobjects, nroffreeobjects,STARTMAX); + nrofallocobjects, nroffreeobjects,STARTMAX); } /* @@ -454,11 +454,11 @@ object *get_owner(object *op) { if(op->owner==NULL) - return NULL; + return NULL; if (!QUERY_FLAG(op->owner,FLAG_FREED) && !QUERY_FLAG(op->owner, FLAG_REMOVED) && - op->owner->count==op->ownercount) - return op->owner; + op->owner->count==op->ownercount) + return op->owner; op->owner=NULL; op->ownercount=0; @@ -470,7 +470,7 @@ if (!op) return; if (op->owner && op->ownercount == op->owner->count) - op->owner->refcount--; + op->owner->refcount--; op->owner = NULL; op->ownercount = 0; @@ -485,7 +485,7 @@ void set_owner (object *op, object *owner) { if(owner==NULL||op==NULL) - return; + return; /* next line added to allow objects which own objects */ /* Add a check for ownercounts in here, as I got into an endless loop @@ -495,7 +495,7 @@ * didn't match, this check is valid and I believe that cause is valid. */ while (owner->owner && owner!=owner->owner && - owner->ownercount==owner->owner->count) owner=owner->owner; + owner->ownercount==owner->owner->count) owner=owner->owner; /* IF the owner still has an owner, we did not resolve to a final owner. * so lets not add to that. @@ -523,11 +523,11 @@ { object *owner = get_owner (clone); if (owner == NULL) { - /* players don't have owners - they own themselves. Update - * as appropriate. - */ - if (clone->type == PLAYER) owner=clone; - else return; + /* players don't have owners - they own themselves. Update + * as appropriate. + */ + if (clone->type == PLAYER) owner=clone; + else return; } set_owner(op, owner); @@ -564,8 +564,8 @@ /* Store next *first*. */ next = i->next; - if (i->key) FREE_AND_CLEAR_STR(i->key); - if (i->value) FREE_AND_CLEAR_STR(i->value); + if (i->key) FREE_AND_CLEAR_STR(i->key); + if (i->value) FREE_AND_CLEAR_STR(i->value); i->next = NULL; free(i); } @@ -591,7 +591,7 @@ * as much info available as possible (eg, object name). */ for (evt = op->events; evt; evt=evt2) { - evt2 = evt->next; + evt2 = evt->next; if (evt->hook != NULL) FREE_AND_CLEAR_STR(evt->hook); if (evt->plugin != NULL) FREE_AND_CLEAR_STR(evt->plugin); @@ -644,7 +644,7 @@ op->face = blank_face; op->attacked_by_count = (tag_t) -1; if (settings.casting_time) - op->casting_time = -1; + op->casting_time = -1; } @@ -678,13 +678,13 @@ /* Basically, same code as from clear_object() */ for (evt = op->events; evt; evt=evt2) { - evt2 = evt->next; + evt2 = evt->next; - if (evt->hook != NULL) FREE_AND_CLEAR_STR(evt->hook); - if (evt->plugin != NULL) FREE_AND_CLEAR_STR(evt->plugin); - if (evt->options != NULL) FREE_AND_CLEAR_STR(evt->options); + if (evt->hook != NULL) FREE_AND_CLEAR_STR(evt->hook); + if (evt->plugin != NULL) FREE_AND_CLEAR_STR(evt->plugin); + if (evt->options != NULL) FREE_AND_CLEAR_STR(evt->options); - free(evt); + free(evt); } op->events = NULL; @@ -707,55 +707,55 @@ if (op->materialname != NULL) add_refcount(op->materialname); if((op2->speed<0) && !editor) - op->speed_left=op2->speed_left-RANDOM()%200/100.0; + op->speed_left=op2->speed_left-RANDOM()%200/100.0; /* Copy over event information */ evt2 = NULL; for (evt = op2->events; evt; evt=evt->next) { - evt_new = (event *) malloc(sizeof(event)); - memcpy(evt_new, evt, sizeof(event)); - if (evt_new->hook) add_refcount(evt_new->hook); - if (evt_new->plugin) add_refcount(evt_new->plugin); - if (evt_new->options) add_refcount(evt_new->options); - evt_new->next = NULL; - - /* Try to be a little clever here, and store away the - * last event we copied, so that its simpler to update the - * pointer. - */ - if (evt2) - evt2->next = evt_new; - else - op->events = evt_new; + evt_new = (event *) malloc(sizeof(event)); + memcpy(evt_new, evt, sizeof(event)); + if (evt_new->hook) add_refcount(evt_new->hook); + if (evt_new->plugin) add_refcount(evt_new->plugin); + if (evt_new->options) add_refcount(evt_new->options); + evt_new->next = NULL; + + /* Try to be a little clever here, and store away the + * last event we copied, so that its simpler to update the + * pointer. + */ + if (evt2) + evt2->next = evt_new; + else + op->events = evt_new; - evt2 = evt_new; + evt2 = evt_new; } /* Copy over key_values, if any. */ if (op2->key_values != NULL) { - key_value * tail = NULL; - key_value * i; + key_value * tail = NULL; + key_value * i; - op->key_values = NULL; + op->key_values = NULL; - for (i = op2->key_values; i != NULL; i = i->next) { - key_value * new_link = (key_value *) malloc(sizeof(key_value)); + for (i = op2->key_values; i != NULL; i = i->next) { + key_value * new_link = (key_value *) malloc(sizeof(key_value)); - new_link->next = NULL; - new_link->key = add_refcount(i->key); - if (i->value) - new_link->value = add_refcount(i->value); - else - new_link->value = NULL; - - /* Try and be clever here, too. */ - if (op->key_values == NULL) { - op->key_values = new_link; - tail = new_link; - } else { - tail->next = new_link; - tail = new_link; - } - } + new_link->next = NULL; + new_link->key = add_refcount(i->key); + if (i->value) + new_link->value = add_refcount(i->value); + else + new_link->value = NULL; + + /* Try and be clever here, too. */ + if (op->key_values == NULL) { + op->key_values = new_link; + tail = new_link; + } else { + tail->next = new_link; + tail = new_link; + } + } } update_ob_speed(op); @@ -854,7 +854,7 @@ void update_turn_face(object *op) { if(!QUERY_FLAG(op,FLAG_IS_TURNABLE)||op->arch==NULL) - return; + return; SET_ANIMATION(op, op->direction); update_object(op,UP_OBJ_FACE); } @@ -873,45 +873,45 @@ */ if (QUERY_FLAG(op, FLAG_FREED) && op->speed) { - LOG(llevError,"Object %s is freed but has speed.\n", op->name); + LOG(llevError,"Object %s is freed but has speed.\n", op->name); #ifdef MANY_CORES - abort(); + abort(); #else - op->speed = 0; + op->speed = 0; #endif } if (arch_init) { - return; + return; } if (FABS(op->speed)>MIN_ACTIVE_SPEED) { - /* If already on active list, don't do anything */ - if (op->active_next || op->active_prev || op==active_objects) - return; + /* If already on active list, don't do anything */ + if (op->active_next || op->active_prev || op==active_objects) + return; /* process_events() expects us to insert the object at the beginning * of the list. */ - op->active_next = active_objects; - if (op->active_next!=NULL) - op->active_next->active_prev = op; - active_objects = op; + op->active_next = active_objects; + if (op->active_next!=NULL) + op->active_next->active_prev = op; + active_objects = op; } else { - /* If not on the active list, nothing needs to be done */ - if (!op->active_next && !op->active_prev && op!=active_objects) - return; - - if (op->active_prev==NULL) { - active_objects = op->active_next; - if (op->active_next!=NULL) - op->active_next->active_prev = NULL; - } - else { - op->active_prev->active_next = op->active_next; - if (op->active_next) - op->active_next->active_prev = op->active_prev; - } - op->active_next = NULL; - op->active_prev = NULL; + /* If not on the active list, nothing needs to be done */ + if (!op->active_next && !op->active_prev && op!=active_objects) + return; + + if (op->active_prev==NULL) { + active_objects = op->active_next; + if (op->active_next!=NULL) + op->active_next->active_prev = NULL; + } + else { + op->active_prev->active_next = op->active_next; + if (op->active_next) + op->active_next->active_prev = op->active_prev; + } + op->active_next = NULL; + op->active_prev = NULL; } } @@ -927,17 +927,17 @@ { /* If not on the active list, nothing needs to be done */ if (!op->active_next && !op->active_prev && op!=active_objects) - return; + return; if (op->active_prev==NULL) { - active_objects = op->active_next; - if (op->active_next!=NULL) - op->active_next->active_prev = NULL; + active_objects = op->active_next; + if (op->active_next!=NULL) + op->active_next->active_prev = NULL; } else { - op->active_prev->active_next = op->active_next; - if (op->active_next) - op->active_next->active_prev = op->active_prev; + op->active_prev->active_next = op->active_next; + if (op->active_next) + op->active_next->active_prev = op->active_prev; } op->active_next = NULL; op->active_prev = NULL; @@ -972,14 +972,14 @@ if (op == NULL) { /* this should never happen */ LOG(llevDebug,"update_object() called for NULL object.\n"); - return; + return; } if(op->env!=NULL) { - /* Animation is currently handled by client, so nothing - * to do in this case. - */ - return; + /* Animation is currently handled by client, so nothing + * to do in this case. + */ + return; } /* If the map is saving, don't do anything as everything is @@ -989,12 +989,12 @@ /* make sure the object is within map boundaries */ if (op->x < 0 || op->x >= MAP_WIDTH(op->map) || - op->y < 0 || op->y >= MAP_HEIGHT(op->map)) { + op->y < 0 || op->y >= MAP_HEIGHT(op->map)) { LOG(llevError,"update_object() called for object out of map!\n"); #ifdef MANY_CORES - abort(); + abort(); #endif - return; + return; } flags = GET_MAP_FLAGS(op->map, op->x, op->y); @@ -1017,26 +1017,26 @@ if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE)) update_now=1; - if ((move_on | op->move_on) != move_on) update_now=1; - if ((move_off | op->move_off) != move_off) update_now=1; - /* This isn't perfect, but I don't expect a lot of objects to - * to have move_allow right now. - */ - if (((move_block | op->move_block) & ~op->move_allow) != move_block) - update_now=1; - if ((move_slow | op->move_slow) != move_slow) update_now=1; + if ((move_on | op->move_on) != move_on) update_now=1; + if ((move_off | op->move_off) != move_off) update_now=1; + /* This isn't perfect, but I don't expect a lot of objects to + * to have move_allow right now. + */ + if (((move_block | op->move_block) & ~op->move_allow) != move_block) + update_now=1; + if ((move_slow | op->move_slow) != move_slow) update_now=1; } /* if the object is being removed, we can't make intelligent * decisions, because remove_ob can't really pass the object * that is being removed. */ else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE) { - update_now=1; + update_now=1; } else if (action == UP_OBJ_FACE) { - /* Nothing to do for that case */ + /* Nothing to do for that case */ } else { - LOG(llevError,"update_object called with invalid action: %d\n", action); + LOG(llevError,"update_object called with invalid action: %d\n", action); } if (update_now) { @@ -1045,7 +1045,7 @@ } if(op->more!=NULL) - update_object(op->more, action); + update_object(op->more, action); } @@ -1069,57 +1069,57 @@ ob->clear (); if (!QUERY_FLAG(ob,FLAG_REMOVED)) { - LOG(llevDebug,"Free object called with non removed object\n"); - dump_object(ob); + LOG(llevDebug,"Free object called with non removed object\n"); + dump_object(ob); #ifdef MANY_CORES - abort(); + abort(); #endif } if(QUERY_FLAG(ob,FLAG_FRIENDLY)) { - LOG(llevMonster,"Warning: tried to free friendly object.\n"); - remove_friendly_object(ob); + LOG(llevMonster,"Warning: tried to free friendly object.\n"); + remove_friendly_object(ob); } if(QUERY_FLAG(ob,FLAG_FREED)) { - dump_object(ob); - LOG(llevError,"Trying to free freed object.\n%s\n",errmsg); - return; + dump_object(ob); + LOG(llevError,"Trying to free freed object.\n%s\n",errmsg); + return; } if(ob->more!=NULL) { - free_object2(ob->more, free_inventory); - ob->more=NULL; + free_object2(ob->more, free_inventory); + ob->more=NULL; } if (ob->inv) { - /* Only if the space blocks everything do we not process - - * if some form of movemnt is allowed, let objects - * drop on that space. - */ - if (free_inventory || ob->map==NULL || ob->map->in_memory!=MAP_IN_MEMORY || - (GET_MAP_MOVE_BLOCK(ob->map, ob->x, ob->y) == MOVE_ALL)) - { - op=ob->inv; - while(op!=NULL) { - tmp=op->below; - remove_ob(op); - free_object2(op, free_inventory); - op=tmp; - } - } - else { /* Put objects in inventory onto this space */ - op=ob->inv; - while(op!=NULL) { - tmp=op->below; - remove_ob(op); - if(QUERY_FLAG(op,FLAG_STARTEQUIP)||QUERY_FLAG(op,FLAG_NO_DROP) || - op->type==RUNE || op->type==TRAP || QUERY_FLAG(op,FLAG_IS_A_TEMPLATE)) - free_object(op); - else { - op->x=ob->x; - op->y=ob->y; - insert_ob_in_map(op,ob->map,NULL,0); /* Insert in same map as the envir */ - } - op=tmp; - } - } + /* Only if the space blocks everything do we not process - + * if some form of movemnt is allowed, let objects + * drop on that space. + */ + if (free_inventory || ob->map==NULL || ob->map->in_memory!=MAP_IN_MEMORY || + (GET_MAP_MOVE_BLOCK(ob->map, ob->x, ob->y) == MOVE_ALL)) + { + op=ob->inv; + while(op!=NULL) { + tmp=op->below; + remove_ob(op); + free_object2(op, free_inventory); + op=tmp; + } + } + else { /* Put objects in inventory onto this space */ + op=ob->inv; + while(op!=NULL) { + tmp=op->below; + remove_ob(op); + if(QUERY_FLAG(op,FLAG_STARTEQUIP)||QUERY_FLAG(op,FLAG_NO_DROP) || + op->type==RUNE || op->type==TRAP || QUERY_FLAG(op,FLAG_IS_A_TEMPLATE)) + free_object(op); + else { + op->x=ob->x; + op->y=ob->y; + insert_ob_in_map(op,ob->map,NULL,0); /* Insert in same map as the envir */ + } + op=tmp; + } + } } /* Remove object from the active list */ ob->speed = 0; @@ -1130,14 +1130,14 @@ /* Remove this object from the list of used objects */ if(ob->prev==NULL) { - objects=ob->next; - if(objects!=NULL) - objects->prev=NULL; + objects=ob->next; + if(objects!=NULL) + objects->prev=NULL; } else { - ob->prev->next=ob->next; - if(ob->next!=NULL) - ob->next->prev=ob->prev; + ob->prev->next=ob->next; + if(ob->next!=NULL) + ob->next->prev=ob->prev; } if(ob->name!=NULL) FREE_AND_CLEAR_STR(ob->name); @@ -1172,7 +1172,7 @@ ob->prev=NULL; ob->next=free_objects; if(free_objects!=NULL) - free_objects->prev=ob; + free_objects->prev=ob; free_objects=ob; nroffreeobjects++; #endif @@ -1248,23 +1248,23 @@ if(QUERY_FLAG(op,FLAG_REMOVED)) { - dump_object(op); - LOG(llevError,"Trying to remove removed object.\n%s\n",errmsg); + dump_object(op); + LOG(llevError,"Trying to remove removed object.\n%s\n",errmsg); - /* Changed it to always dump core in this case. As has been learned - * in the past, trying to recover from errors almost always - * make things worse, and this is a real error here - something - * that should not happen. - * Yes, if this was a mission critical app, trying to do something - * to recover may make sense, but that is because failure of the app - * may have other disastrous problems. Cf runs out of a script - * so is easily enough restarted without any real problems. - * MSW 2001-07-01 - */ - abort(); + /* Changed it to always dump core in this case. As has been learned + * in the past, trying to recover from errors almost always + * make things worse, and this is a real error here - something + * that should not happen. + * Yes, if this was a mission critical app, trying to do something + * to recover may make sense, but that is because failure of the app + * may have other disastrous problems. Cf runs out of a script + * so is easily enough restarted without any real problems. + * MSW 2001-07-01 + */ + abort(); } if(op->more!=NULL) - remove_ob(op->more); + remove_ob(op->more); SET_FLAG(op, FLAG_REMOVED); @@ -1273,37 +1273,37 @@ * inventory. */ if(op->env!=NULL) { - if(op->nrof) - sub_weight(op->env, op->weight*op->nrof); - else - sub_weight(op->env, op->weight+op->carrying); - - /* NO_FIX_PLAYER is set when a great many changes are being - * made to players inventory. If set, avoiding the call - * to save cpu time. - */ - if ((otmp=is_player_inv(op->env))!=NULL && otmp->contr && - !QUERY_FLAG(otmp,FLAG_NO_FIX_PLAYER)) - fix_player(otmp); - - if(op->above!=NULL) - op->above->below=op->below; - else - op->env->inv=op->below; - - if(op->below!=NULL) - op->below->above=op->above; - - /* we set up values so that it could be inserted into - * the map, but we don't actually do that - it is up - * to the caller to decide what we want to do. - */ - op->x=op->env->x,op->y=op->env->y; - op->ox=op->x,op->oy=op->y; - op->map=op->env->map; - op->above=NULL,op->below=NULL; - op->env=NULL; - return; + if(op->nrof) + sub_weight(op->env, op->weight*op->nrof); + else + sub_weight(op->env, op->weight+op->carrying); + + /* NO_FIX_PLAYER is set when a great many changes are being + * made to players inventory. If set, avoiding the call + * to save cpu time. + */ + if ((otmp=is_player_inv(op->env))!=NULL && otmp->contr && + !QUERY_FLAG(otmp,FLAG_NO_FIX_PLAYER)) + fix_player(otmp); + + if(op->above!=NULL) + op->above->below=op->below; + else + op->env->inv=op->below; + + if(op->below!=NULL) + op->below->above=op->above; + + /* we set up values so that it could be inserted into + * the map, but we don't actually do that - it is up + * to the caller to decide what we want to do. + */ + op->x=op->env->x,op->y=op->env->y; + op->ox=op->x,op->oy=op->y; + op->map=op->env->map; + op->above=NULL,op->below=NULL; + op->env=NULL; + return; } /* If we get here, we are removing it from a map */ @@ -1314,17 +1314,17 @@ m = get_map_from_coord(op->map, &x, &y); if (!m) { - LOG(llevError,"remove_ob 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); - /* in old days, we used to set x and y to 0 and continue. - * it seems if we get into this case, something is probablye - * screwed up and should be fixed. - */ - abort(); + LOG(llevError,"remove_ob 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); + /* in old days, we used to set x and y to 0 and continue. + * it seems if we get into this case, something is probablye + * screwed up and should be fixed. + */ + abort(); } if (op->map != m) { - LOG(llevDebug,"remove_ob: 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); + LOG(llevDebug,"remove_ob: 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); } /* Re did the following section of code - it looks like it had @@ -1333,82 +1333,82 @@ /* link the object above us */ if (op->above) - op->above->below=op->below; + op->above->below=op->below; else - SET_MAP_TOP(m,x,y,op->below); /* we were top, set new top */ + SET_MAP_TOP(m,x,y,op->below); /* we were top, set new top */ /* Relink the object below us, if there is one */ if(op->below) { - op->below->above=op->above; + op->below->above=op->above; } else { - /* Nothing below, which means we need to relink map object for this space - * use translated coordinates in case some oddness with map tiling is - * evident - */ - if(GET_MAP_OB(m,x,y)!=op) { - dump_object(op); - LOG(llevError,"remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", errmsg); - dump_object(GET_MAP_OB(m,x,y)); - LOG(llevError,"%s\n",errmsg); - } - SET_MAP_OB(m,x,y,op->above); /* goes on above it. */ + /* Nothing below, which means we need to relink map object for this space + * use translated coordinates in case some oddness with map tiling is + * evident + */ + if(GET_MAP_OB(m,x,y)!=op) { + dump_object(op); + LOG(llevError,"remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", errmsg); + dump_object(GET_MAP_OB(m,x,y)); + LOG(llevError,"%s\n",errmsg); + } + SET_MAP_OB(m,x,y,op->above); /* goes on above it. */ } op->above=NULL; op->below=NULL; if (op->map->in_memory == MAP_SAVING) - return; + return; tag = op->count; check_walk_off = ! QUERY_FLAG (op, FLAG_NO_APPLY); for(tmp=GET_MAP_OB(m,x,y);tmp!=NULL;tmp=tmp->above) { - /* No point updating the players look faces if he is the object - * being removed. - */ - - if(tmp->type==PLAYER && tmp!=op) { - /* If a container that the player is currently using somehow gets - * removed (most likely destroyed), update the player view - * appropriately. - */ - if (tmp->container==op) { - CLEAR_FLAG(op, FLAG_APPLIED); - tmp->container=NULL; - } - tmp->contr->socket.update_look=1; - } - /* See if player moving off should effect something */ - if (check_walk_off && ((op->move_type & tmp->move_off) && - (op->move_type & ~tmp->move_off & ~tmp->move_block)==0)) { - - move_apply(tmp, op, NULL); - if (was_destroyed (op, tag)) { - LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " - "leaving object\n", tmp->name, tmp->arch->name); - } - } - - /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ - - if(tmp->above == tmp) - tmp->above = NULL; - last=tmp; + /* No point updating the players look faces if he is the object + * being removed. + */ + + if(tmp->type==PLAYER && tmp!=op) { + /* If a container that the player is currently using somehow gets + * removed (most likely destroyed), update the player view + * appropriately. + */ + if (tmp->container==op) { + CLEAR_FLAG(op, FLAG_APPLIED); + tmp->container=NULL; + } + tmp->contr->socket.update_look=1; + } + /* See if player moving off should effect something */ + if (check_walk_off && ((op->move_type & tmp->move_off) && + (op->move_type & ~tmp->move_off & ~tmp->move_block)==0)) { + + move_apply(tmp, op, NULL); + if (was_destroyed (op, tag)) { + LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " + "leaving object\n", tmp->name, tmp->arch->name); + } + } + + /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ + + if(tmp->above == tmp) + tmp->above = NULL; + last=tmp; } /* last == NULL of there are no objects on this space */ if (last==NULL) { - /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, - * we could preserve the flags (GET_MAP_FLAGS), but update_position figures - * those out anyways, and if there are any flags set right now, they won't - * be correct anyways. - */ - SET_MAP_FLAGS(op->map, op->x, op->y, P_NEED_UPDATE); - update_position(op->map, op->x, op->y); + /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, + * we could preserve the flags (GET_MAP_FLAGS), but update_position figures + * those out anyways, and if there are any flags set right now, they won't + * be correct anyways. + */ + SET_MAP_FLAGS(op->map, op->x, op->y, P_NEED_UPDATE); + update_position(op->map, op->x, op->y); } else - update_object(last, UP_OBJ_REMOVE); + update_object(last, UP_OBJ_REMOVE); if(QUERY_FLAG(op,FLAG_BLOCKSVIEW)|| (op->glow_radius != 0)) - update_all_los(op->map, op->x, op->y); + update_all_los(op->map, op->x, op->y); } @@ -1484,58 +1484,58 @@ sint16 x,y; if (QUERY_FLAG (op, FLAG_FREED)) { - LOG (llevError, "Trying to insert freed object!\n"); - return NULL; + LOG (llevError, "Trying to insert freed object!\n"); + return NULL; } if(m==NULL) { - dump_object(op); - LOG(llevError,"Trying to insert in null-map!\n%s\n",errmsg); - return op; + dump_object(op); + LOG(llevError,"Trying to insert in null-map!\n%s\n",errmsg); + return op; } if(out_of_map(m,op->x,op->y)) { - dump_object(op); - LOG(llevError,"Trying to insert object outside the map.\n%s\n", errmsg); + dump_object(op); + LOG(llevError,"Trying to insert object outside the map.\n%s\n", errmsg); #ifdef MANY_CORES - /* Better to catch this here, as otherwise the next use of this object - * is likely to cause a crash. Better to find out where it is getting - * improperly inserted. - */ - abort(); + /* Better to catch this here, as otherwise the next use of this object + * is likely to cause a crash. Better to find out where it is getting + * improperly inserted. + */ + abort(); #endif - return op; + return op; } if(!QUERY_FLAG(op,FLAG_REMOVED)) { - dump_object(op); - LOG(llevError,"Trying to insert (map) inserted object.\n%s\n", errmsg); - return op; + dump_object(op); + LOG(llevError,"Trying to insert (map) inserted object.\n%s\n", errmsg); + return op; } if(op->more!=NULL) { - /* The part may be on a different map. */ + /* The part may be on a different map. */ - object *more = op->more; + object *more = op->more; - /* We really need the caller to normalize coordinates - if - * we set the map, that doesn't work if the location is within - * a map and this is straddling an edge. So only if coordinate - * is clear wrong do we normalize it. - */ - if (OUT_OF_REAL_MAP(more->map, more->x, more->y)) { - /* Debugging information so you can see the last coordinates this object had */ - more->ox = more->x; - more->oy = more->y; - more->map = get_map_from_coord(m, &more->x, &more->y); - } else if (!more->map) { - /* For backwards compatibility - when not dealing with tiled maps, - * more->map should always point to the parent. - */ - more->map = m; - } - - if (insert_ob_in_map(more, more->map, originator, flag) == NULL) { - if ( ! op->head) - LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); - return NULL; - } + /* We really need the caller to normalize coordinates - if + * we set the map, that doesn't work if the location is within + * a map and this is straddling an edge. So only if coordinate + * is clear wrong do we normalize it. + */ + if (OUT_OF_REAL_MAP(more->map, more->x, more->y)) { + /* Debugging information so you can see the last coordinates this object had */ + more->ox = more->x; + more->oy = more->y; + more->map = get_map_from_coord(m, &more->x, &more->y); + } else if (!more->map) { + /* For backwards compatibility - when not dealing with tiled maps, + * more->map should always point to the parent. + */ + more->map = m; + } + + if (insert_ob_in_map(more, more->map, originator, flag) == NULL) { + if ( ! op->head) + LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); + return NULL; + } } CLEAR_FLAG(op,FLAG_REMOVED); @@ -1554,52 +1554,52 @@ /* this has to be done after we translate the coordinates. */ if(op->nrof && !(flag & INS_NO_MERGE)) { - for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) - if (CAN_MERGE(op,tmp)) { - op->nrof+=tmp->nrof; - remove_ob(tmp); - free_object(tmp); - } + for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) + if (CAN_MERGE(op,tmp)) { + op->nrof+=tmp->nrof; + remove_ob(tmp); + free_object(tmp); + } } CLEAR_FLAG(op,FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ CLEAR_FLAG(op, FLAG_INV_LOCKED); if (!QUERY_FLAG(op, FLAG_ALIVE)) - CLEAR_FLAG(op, FLAG_NO_STEAL); + CLEAR_FLAG(op, FLAG_NO_STEAL); if (flag & INS_BELOW_ORIGINATOR) { - if (originator->map != op->map || originator->x != op->x || - originator->y != op->y) { - LOG(llevError,"insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n"); - abort(); - } - op->above = originator; - op->below = originator->below; - if (op->below) op->below->above = op; - else SET_MAP_OB(op->map, op->x, op->y, op); - /* since *below* originator, no need to update top */ - originator->below = op; + if (originator->map != op->map || originator->x != op->x || + originator->y != op->y) { + LOG(llevError,"insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n"); + abort(); + } + op->above = originator; + op->below = originator->below; + if (op->below) op->below->above = op; + else SET_MAP_OB(op->map, op->x, op->y, op); + /* since *below* originator, no need to update top */ + originator->below = op; } else { - /* If there are other objects, then */ - if((! (flag & INS_MAP_LOAD)) && ((top=GET_MAP_OB(op->map,op->x,op->y))!=NULL)) { - object *last=NULL; - /* - * If there are multiple objects on this space, we do some trickier handling. - * We've already dealt with merging if appropriate. - * Generally, we want to put the new object on top. But if - * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last - * floor, we want to insert above that and no further. - * Also, if there are spell objects on this space, we stop processing - * once we get to them. This reduces the need to traverse over all of - * them when adding another one - this saves quite a bit of cpu time - * when lots of spells are cast in one area. Currently, it is presumed - * that flying non pickable objects are spell objects. - */ - - while (top != NULL) { - if (QUERY_FLAG(top, FLAG_IS_FLOOR) || - QUERY_FLAG(top, FLAG_OVERLAY_FLOOR)) floor = top; - if (QUERY_FLAG(top, FLAG_NO_PICK) + /* If there are other objects, then */ + if((! (flag & INS_MAP_LOAD)) && ((top=GET_MAP_OB(op->map,op->x,op->y))!=NULL)) { + object *last=NULL; + /* + * If there are multiple objects on this space, we do some trickier handling. + * We've already dealt with merging if appropriate. + * Generally, we want to put the new object on top. But if + * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last + * floor, we want to insert above that and no further. + * Also, if there are spell objects on this space, we stop processing + * once we get to them. This reduces the need to traverse over all of + * them when adding another one - this saves quite a bit of cpu time + * when lots of spells are cast in one area. Currently, it is presumed + * that flying non pickable objects are spell objects. + */ + + while (top != NULL) { + if (QUERY_FLAG(top, FLAG_IS_FLOOR) || + QUERY_FLAG(top, FLAG_OVERLAY_FLOOR)) floor = top; + if (QUERY_FLAG(top, FLAG_NO_PICK) && (top->move_type & (MOVE_FLY_LOW |MOVE_FLY_HIGH)) && !QUERY_FLAG(top, FLAG_IS_FLOOR)) { @@ -1607,69 +1607,69 @@ top=top->below; break; } - last = top; - top = top->above; - } - /* Don't want top to be NULL, so set it to the last valid object */ - top = last; - - /* We let update_position deal with figuring out what the space - * looks like instead of lots of conditions here. - * makes things faster, and effectively the same result. - */ + last = top; + top = top->above; + } + /* Don't want top to be NULL, so set it to the last valid object */ + top = last; + + /* We let update_position deal with figuring out what the space + * looks like instead of lots of conditions here. + * makes things faster, and effectively the same result. + */ - /* Have object 'fall below' other objects that block view. + /* Have object 'fall below' other objects that block view. * Unless those objects are exits, type 66 - * If INS_ON_TOP is used, don't do this processing - * Need to find the object that in fact blocks view, otherwise - * stacking is a bit odd. - */ - if (!(flag & INS_ON_TOP) && - (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_BLOCKSVIEW) && - (op->face && !op->face->visibility)) { - for (last=top; last != floor; last=last->below) + * If INS_ON_TOP is used, don't do this processing + * Need to find the object that in fact blocks view, otherwise + * stacking is a bit odd. + */ + if (!(flag & INS_ON_TOP) && + (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_BLOCKSVIEW) && + (op->face && !op->face->visibility)) { + for (last=top; last != floor; last=last->below) if (QUERY_FLAG(last, FLAG_BLOCKSVIEW)&&(last->type != EXIT)) break; - /* Check to see if we found the object that blocks view, - * and make sure we have a below pointer for it so that - * we can get inserted below this one, which requires we - * set top to the object below us. - */ - if (last && last->below && last != floor) top=last->below; - } - } /* If objects on this space */ - if (flag & INS_MAP_LOAD) - top = GET_MAP_TOP(op->map,op->x,op->y); - if (flag & INS_ABOVE_FLOOR_ONLY) top = floor; - - /* Top is the object that our object (op) is going to get inserted above. - */ - - /* First object on this space */ - if (!top) { - op->above = GET_MAP_OB(op->map, op->x, op->y); - if (op->above) op->above->below = op; - op->below = NULL; - SET_MAP_OB(op->map, op->x, op->y, op); - } else { /* get inserted into the stack above top */ - op->above = top->above; - if (op->above) op->above->below = op; - op->below = top; - top->above = op; - } - if (op->above==NULL) - SET_MAP_TOP(op->map,op->x, op->y, op); + /* Check to see if we found the object that blocks view, + * and make sure we have a below pointer for it so that + * we can get inserted below this one, which requires we + * set top to the object below us. + */ + if (last && last->below && last != floor) top=last->below; + } + } /* If objects on this space */ + if (flag & INS_MAP_LOAD) + top = GET_MAP_TOP(op->map,op->x,op->y); + if (flag & INS_ABOVE_FLOOR_ONLY) top = floor; + + /* Top is the object that our object (op) is going to get inserted above. + */ + + /* First object on this space */ + if (!top) { + op->above = GET_MAP_OB(op->map, op->x, op->y); + if (op->above) op->above->below = op; + op->below = NULL; + SET_MAP_OB(op->map, op->x, op->y, op); + } else { /* get inserted into the stack above top */ + op->above = top->above; + if (op->above) op->above->below = op; + op->below = top; + top->above = op; + } + if (op->above==NULL) + SET_MAP_TOP(op->map,op->x, op->y, op); } /* else not INS_BELOW_ORIGINATOR */ if(op->type==PLAYER) - op->contr->do_los=1; + op->contr->do_los=1; /* If we have a floor, we know the player, if any, will be above * it, so save a few ticks and start from there. */ if (!(flag & INS_MAP_LOAD)) for(tmp=floor?floor:GET_MAP_OB(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) { - if (tmp->type == PLAYER) - tmp->contr->socket.update_look=1; + if (tmp->type == PLAYER) + tmp->contr->socket.update_look=1; } /* If this object glows, it may affect lighting conditions that are @@ -1682,7 +1682,7 @@ * of effect may be sufficient. */ if(MAP_DARKNESS(op->map) && (op->glow_radius != 0)) - update_all_los(op->map, op->x, op->y); + update_all_los(op->map, op->x, op->y); /* updates flags (blocked, alive, no magic, etc) for this map space */ @@ -1702,14 +1702,14 @@ if (!(flag & INS_NO_WALK_ON) && !op->head) { if (check_move_on(op, originator)) - return NULL; + return NULL; /* If we are a multi part object, lets work our way through the check * walk on's. */ for (tmp=op->more; tmp!=NULL; tmp=tmp->more) if (check_move_on (tmp, originator)) - return NULL; + return NULL; } return op; } @@ -1725,10 +1725,10 @@ /* first search for itself and remove any old instances */ for(tmp=GET_MAP_OB(op->map,op->x,op->y); tmp!=NULL; tmp=tmp->above) { - if(!strcmp(tmp->arch->name,arch_string)) /* same archetype */ { - remove_ob(tmp); - free_object(tmp); - } + if(!strcmp(tmp->arch->name,arch_string)) /* same archetype */ { + remove_ob(tmp); + free_object(tmp); + } } tmp1=arch_to_object(find_archetype(arch_string)); @@ -1751,25 +1751,25 @@ int is_removed = (QUERY_FLAG (orig_ob, FLAG_REMOVED) != 0); if(orig_ob->nrofnrof?orig_ob->nrof:1, orig_ob->name); - return NULL; + return NULL; } newob = object_create_clone(orig_ob); if((orig_ob->nrof-=nr)<1) { - if ( ! is_removed) + if ( ! is_removed) remove_ob(orig_ob); - free_object2(orig_ob, 1); + free_object2(orig_ob, 1); } else if ( ! is_removed) { - if(orig_ob->env!=NULL) - sub_weight (orig_ob->env,orig_ob->weight*nr); - if (orig_ob->env == NULL && orig_ob->map->in_memory!=MAP_IN_MEMORY) { - strcpy(errmsg, "Tried to split object whose map is not in memory."); - LOG(llevDebug, - "Error, Tried to split object whose map is not in memory.\n"); - return NULL; - } + if(orig_ob->env!=NULL) + sub_weight (orig_ob->env,orig_ob->weight*nr); + if (orig_ob->env == NULL && orig_ob->map->in_memory!=MAP_IN_MEMORY) { + strcpy(errmsg, "Tried to split object whose map is not in memory."); + LOG(llevDebug, + "Error, Tried to split object whose map is not in memory.\n"); + return NULL; + } } newob->nrof=nr; @@ -1801,22 +1801,22 @@ } else if (op->env != NULL) { - /* is this object in the players inventory, or sub container - * therein? - */ + /* is this object in the players inventory, or sub container + * therein? + */ tmp = is_player_inv (op->env); - /* nope. Is this a container the player has opened? - * If so, set tmp to that player. - * IMO, searching through all the players will mostly - * likely be quicker than following op->env to the map, - * and then searching the map for a player. - */ - if (!tmp) { - for (pl=first_player; pl; pl=pl->next) - if (pl->ob->container == op->env) break; - if (pl) tmp=pl->ob; - else tmp=NULL; - } + /* nope. Is this a container the player has opened? + * If so, set tmp to that player. + * IMO, searching through all the players will mostly + * likely be quicker than following op->env to the map, + * and then searching the map for a player. + */ + if (!tmp) { + for (pl=first_player; pl; pl=pl->next) + if (pl->ob->container == op->env) break; + if (pl) tmp=pl->ob; + else tmp=NULL; + } if (i < op->nrof) { sub_weight (op->env, op->weight * i); @@ -1834,7 +1834,7 @@ } else { - object *above = op->above; + object *above = op->above; if (i < op->nrof) { op->nrof -= i; @@ -1842,7 +1842,7 @@ remove_ob (op); op->nrof = 0; } - /* Since we just removed op, op->above is null */ + /* Since we just removed op, op->above is null */ for (tmp = above; tmp != NULL; tmp = tmp->above) if (tmp->type == PLAYER) { if (op->nrof) @@ -1904,7 +1904,7 @@ } if (where->head) { LOG(llevDebug, - "Warning: Tried to insert object wrong part of multipart object.\n"); + "Warning: Tried to insert object wrong part of multipart object.\n"); where = where->head; } if (op->more) { @@ -1917,19 +1917,19 @@ if(op->nrof) { for(tmp=where->inv;tmp!=NULL;tmp=tmp->below) if ( CAN_MERGE(tmp,op) ) { - /* return the original object and remove inserted object + /* return the original object and remove inserted object (client needs the original object) */ tmp->nrof += op->nrof; - /* Weight handling gets pretty funky. Since we are adding to - * tmp->nrof, we need to increase the weight. - */ - add_weight (where, op->weight*op->nrof); + /* Weight handling gets pretty funky. Since we are adding to + * tmp->nrof, we need to increase the weight. + */ + add_weight (where, op->weight*op->nrof); SET_FLAG(op, FLAG_REMOVED); free_object(op); /* free the inserted object */ op = tmp; remove_ob (op); /* and fix old object's links */ CLEAR_FLAG(op, FLAG_REMOVED); - break; + break; } /* I assume combined objects have no inventory @@ -1960,7 +1960,7 @@ { #ifdef DEBUG_LIGHTS LOG(llevDebug, " insert_ob_in_ob(): got %s to insert in map/op\n", - op->name); + op->name); #endif /* DEBUG_LIGHTS */ if (MAP_DARKNESS(where->map)) update_all_los(where->map, where->x, where->y); } @@ -2008,7 +2008,7 @@ MoveType move_on, move_slow, move_block; if(QUERY_FLAG(op,FLAG_NO_APPLY)) - return 0; + return 0; tag = op->count; @@ -2022,7 +2022,7 @@ * as walking. */ if (op->move_type && !(op->move_type & move_on) && !(op->move_type & move_slow)) - return 0; + return 0; /* This is basically inverse logic of that below - basically, * if the object can avoid the move on or slow move, they do so, @@ -2030,62 +2030,62 @@ * blocked. Logic on this seems confusing, but does seem correct. */ if ((op->move_type & ~move_on & ~move_block) != 0 && - (op->move_type & ~move_slow & ~move_block) != 0) return 0; + (op->move_type & ~move_slow & ~move_block) != 0) return 0; /* The objects have to be checked from top to bottom. * Hence, we first go to the top: */ for (tmp=GET_MAP_OB(op->map, op->x, op->y); tmp!=NULL && - tmp->above!=NULL; tmp=tmp->above) { - /* Trim the search when we find the first other spell effect - * this helps performance so that if a space has 50 spell objects, - * we don't need to check all of them. - */ - if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG(tmp, FLAG_NO_PICK)) break; + tmp->above!=NULL; tmp=tmp->above) { + /* Trim the search when we find the first other spell effect + * this helps performance so that if a space has 50 spell objects, + * we don't need to check all of them. + */ + if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG(tmp, FLAG_NO_PICK)) break; } for(;tmp!=NULL; tmp=tmp->below) { - if (tmp == op) continue; /* Can't apply yourself */ + if (tmp == op) continue; /* Can't apply yourself */ - /* Check to see if one of the movement types should be slowed down. - * Second check makes sure that the movement types not being slowed - * (~slow_move) is not blocked on this space - just because the - * space doesn't slow down swimming (for example), if you can't actually - * swim on that space, can't use it to avoid the penalty. - */ - if (!QUERY_FLAG(op, FLAG_WIZPASS)) { - if ((!op->move_type && tmp->move_slow & MOVE_WALK) || - ((op->move_type & tmp->move_slow) && - (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0)) { - - float diff; - - diff = tmp->move_slow_penalty*FABS(op->speed); - if (op->type == PLAYER) { - if ((QUERY_FLAG(tmp, FLAG_IS_HILLY) && find_skill_by_number(op, SK_CLIMBING)) || - (QUERY_FLAG(tmp, FLAG_IS_WOODED) && find_skill_by_number(op, SK_WOODSMAN))) { - diff /= 4.0; - } - } - op->speed_left -= diff; - } - } - - /* Basically same logic as above, except now for actual apply. */ - if ((!op->move_type && tmp->move_on & MOVE_WALK) || - ((op->move_type & tmp->move_on) && - (op->move_type & ~tmp->move_on & ~tmp->move_block)==0)) { + /* Check to see if one of the movement types should be slowed down. + * Second check makes sure that the movement types not being slowed + * (~slow_move) is not blocked on this space - just because the + * space doesn't slow down swimming (for example), if you can't actually + * swim on that space, can't use it to avoid the penalty. + */ + if (!QUERY_FLAG(op, FLAG_WIZPASS)) { + if ((!op->move_type && tmp->move_slow & MOVE_WALK) || + ((op->move_type & tmp->move_slow) && + (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0)) { + + float diff; + + diff = tmp->move_slow_penalty*FABS(op->speed); + if (op->type == PLAYER) { + if ((QUERY_FLAG(tmp, FLAG_IS_HILLY) && find_skill_by_number(op, SK_CLIMBING)) || + (QUERY_FLAG(tmp, FLAG_IS_WOODED) && find_skill_by_number(op, SK_WOODSMAN))) { + diff /= 4.0; + } + } + op->speed_left -= diff; + } + } - move_apply(tmp, op, originator); + /* Basically same logic as above, except now for actual apply. */ + if ((!op->move_type && tmp->move_on & MOVE_WALK) || + ((op->move_type & tmp->move_on) && + (op->move_type & ~tmp->move_on & ~tmp->move_block)==0)) { + + move_apply(tmp, op, originator); if (was_destroyed (op, tag)) - return 1; + return 1; - /* what the person/creature stepped onto has moved the object - * someplace new. Don't process any further - if we did, - * have a feeling strange problems would result. - */ - if (op->map != m || op->x != x || op->y != y) return 0; - } + /* what the person/creature stepped onto has moved the object + * someplace new. Don't process any further - if we did, + * have a feeling strange problems would result. + */ + if (op->map != m || op->x != x || op->y != y) return 0; + } } return 0; } @@ -2159,8 +2159,8 @@ object *tmp; for(tmp=op->inv; tmp!=NULL; tmp=tmp->below) { - if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name))) - return tmp; + if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name))) + return tmp; } return NULL; } @@ -2240,20 +2240,20 @@ static int altern[SIZEOFFREE]; for(i=start;ihead) { - exclude = exclude->head; - move_type = exclude->move_type; + exclude = exclude->head; + move_type = exclude->move_type; } else { - /* If we don't have anything, presume it can use all movement types. */ - move_type=MOVE_ALL; + /* If we don't have anything, presume it can use all movement types. */ + move_type=MOVE_ALL; } for(i=1;iabove) { - if ((QUERY_FLAG(tmp,FLAG_MONSTER) || tmp->type==PLAYER) && - (tmp != exclude ||(tmp->head && tmp->head != exclude))) { - break; - } - } - if(tmp) { - return freedir[i]; - } - } - } + mp = m; + nx = x + freearr_x[i]; + ny = y + freearr_y[i]; + + mflags = get_map_flags(m, &mp, nx, ny, &nx, &ny); + if (mflags & P_OUT_OF_MAP) { + max = maxfree[i]; + } else { + blocked = GET_MAP_MOVE_BLOCK(mp, nx, ny); + + if ((move_type & blocked) == move_type) { + max=maxfree[i]; + } else if (mflags & P_IS_ALIVE) { + for (tmp=GET_MAP_OB(mp,nx,ny); tmp!= NULL; tmp=tmp->above) { + if ((QUERY_FLAG(tmp,FLAG_MONSTER) || tmp->type==PLAYER) && + (tmp != exclude ||(tmp->head && tmp->head != exclude))) { + break; + } + } + if(tmp) { + return freedir[i]; + } + } + } } return 0; } @@ -2541,12 +2541,12 @@ /* yes, can see. */ if(dir < 9) return 1; return can_see_monsterP(m, x, y, reduction_dir[dir][0]) | - can_see_monsterP(m,x,y, reduction_dir[dir][1]) | - can_see_monsterP(m,x,y, reduction_dir[dir][2]); + can_see_monsterP(m,x,y, reduction_dir[dir][1]) | + can_see_monsterP(m,x,y, reduction_dir[dir][2]); } - + /* * can_pick(picker, item): finds out if an object is possible to be * picked up by the picker. Returnes 1 if it can be @@ -2561,7 +2561,7 @@ int can_pick(const object *who, const object *item) { return /*QUERY_FLAG(who,FLAG_WIZ)||*/ (item->weight>0&&!QUERY_FLAG(item,FLAG_NO_PICK)&& - !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible && + !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible && (who->type==PLAYER||item->weightweight/3)); } @@ -2596,7 +2596,7 @@ } /*** copy inventory ***/ for(item = src->inv; item; item = item->below) { - (void) insert_ob_in_ob(object_create_clone(item),dst); + (void) insert_ob_in_ob(object_create_clone(item),dst); } return dst; @@ -2657,7 +2657,7 @@ object *tmp; for (tmp=who->inv; tmp; tmp=tmp->below) - if (tmp->type == type && tmp->subtype == subtype) return tmp; + if (tmp->type == type && tmp->subtype == subtype) return tmp; return NULL; } @@ -2728,31 +2728,31 @@ key_value * field = NULL, *last=NULL; for (field=op->key_values; field != NULL; field=field->next) { - if (field->key != canonical_key) { - last = field; - continue; - } + if (field->key != canonical_key) { + last = field; + continue; + } - if (field->value) FREE_AND_CLEAR_STR(field->value); - if (value) - field->value = add_string(value); - else { - /* Basically, if the archetype has this key set, - * we need to store the null value so when we save - * it, we save the empty value so that when we load, - * we get this value back again. - */ - if (get_ob_key_link(&op->arch->clone, canonical_key)) - field->value = NULL; - else { - /* Delete this link */ - if (field->key) FREE_AND_CLEAR_STR(field->key); - if (field->value) FREE_AND_CLEAR_STR(field->value); - if (last) last->next = field->next; - else op->key_values = field->next; - free(field); - } - } + if (field->value) FREE_AND_CLEAR_STR(field->value); + if (value) + field->value = add_string(value); + else { + /* Basically, if the archetype has this key set, + * we need to store the null value so when we save + * it, we save the empty value so that when we load, + * we get this value back again. + */ + if (get_ob_key_link(&op->arch->clone, canonical_key)) + field->value = NULL; + else { + /* Delete this link */ + if (field->key) FREE_AND_CLEAR_STR(field->key); + if (field->value) FREE_AND_CLEAR_STR(field->value); + if (last) last->next = field->next; + else op->key_values = field->next; + free(field); + } + } return TRUE; } /* IF we get here, key doesn't exist */