version 1.8 | | version 1.9 |
---|
| | |
/* | | /* |
* static char *rcsid_object_c = | | * static char *rcsid_object_c = |
* "$Id: object.c,v 1.8 2000/06/27 03:34:34 cvs Exp $"; | | * "$Id: object.c,v 1.9 2000/11/06 23:06:47 jec Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
else | | else |
set_map_ob(op->map,op->x,op->y,op); /* Tell the map that we're here */ | | set_map_ob(op->map,op->x,op->y,op); /* Tell the map that we're here */ |
| | |
/* Only check this if we are the head of the object */ | | |
if (!op->head) { | | |
mapstruct *map=op->map; | | |
if (check_walk_on(op, originator)) | | |
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_walk_on (op, originator)) | | |
return NULL; | | |
| | |
} | | |
if(op->type==PLAYER) | | if(op->type==PLAYER) |
op->contr->do_los=1; | | op->contr->do_los=1; |
for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) | | for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) |
| | |
#endif | | #endif |
/* Don't know if moving this to the end will break anything. However, | | /* Don't know if moving this to the end will break anything. However, |
* we want to have update_look set above before calling this. | | * we want to have update_look set above before calling this. |
| | * |
| | * check_walk_on() must be after this because code called from |
| | * check_walk_on() depends on correct map flags (so functions like |
| | * blocked() and wall() work properly), and these flags are updated by |
| | * update_object(). |
*/ | | */ |
update_object(op); | | update_object(op); |
| | |
| | /* Only check this if we are the head of the object */ |
| | if ( ! op->head) { |
| | mapstruct *map=op->map; |
| | if (check_walk_on(op, originator)) |
| | 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_walk_on (op, originator)) |
| | return NULL; |
| | } |
| | |
return op; | | return op; |
} | | } |
| | |
| | |
| | |
object *get_split_ob(object *orig_ob,int nr) { | | object *get_split_ob(object *orig_ob,int nr) { |
object *newob; | | object *newob; |
| | int is_removed = (QUERY_FLAG (orig_ob, FLAG_REMOVED) != 0); |
| | |
if(orig_ob->nrof<nr) { | | if(orig_ob->nrof<nr) { |
sprintf(errmsg,"There are only %d %ss.", | | sprintf(errmsg,"There are only %d %ss.", |
| | |
newob=get_object(); | | newob=get_object(); |
copy_object(orig_ob,newob); | | copy_object(orig_ob,newob); |
if((orig_ob->nrof-=nr)<1) { | | if((orig_ob->nrof-=nr)<1) { |
| | if ( ! is_removed) |
remove_ob(orig_ob); | | remove_ob(orig_ob); |
free_object(orig_ob); | | free_object(orig_ob); |
} | | } |
else if(!QUERY_FLAG(orig_ob,FLAG_REMOVED)){ | | else if ( ! is_removed) { |
if(orig_ob->env!=NULL) | | if(orig_ob->env!=NULL) |
sub_weight (orig_ob->env,orig_ob->weight*nr); | | sub_weight (orig_ob->env,orig_ob->weight*nr); |
if (orig_ob->env == NULL && orig_ob->map->in_memory!=MAP_IN_MEMORY) { | | if (orig_ob->env == NULL && orig_ob->map->in_memory!=MAP_IN_MEMORY) { |
| | |
{ | | { |
object *tmp; | | object *tmp; |
| | |
/* nrof is split out into a long so it is handled ok on 64 bit machines. | | if (i == 0) /* objects with op->nrof require this check */ |
* I think it might work to just do op->nrof-=i and cast that to an sint32 | | return op; |
* to see if it is negative. But if so, we might as well just nrof in | | |
* the object structure an sint32, since that would still set a maximum | | if (i > op->nrof) |
* value. | | i = op->nrof; |
*/ | | |
long nrof=op->nrof; | | if (QUERY_FLAG (op, FLAG_REMOVED)) |
| | { |
nrof -= i; | | op->nrof -= i; |
if (nrof<0) nrof=0; | | } |
op->nrof = nrof; | | else if (op->env != NULL) |
| | { |
if(!op->nrof) { | | |
op->nrof=0; /* just to be sure that remove_ob handles weight properly */ | | |
/* We don't have remove object send delete to the new client, because | | |
* in many areas, more intelligent strategies are employed. However, if | | |
* we are decreasing the number, we can be sure that the object is gone | | |
* for good, so send a delete down the line. Need to check for | | |
* environment before we call remove_ob, since that deletes the | | |
* environment. | | |
*/ | | |
if(op->env!=NULL) { | | |
tmp=is_player_inv (op->env); | | tmp=is_player_inv (op->env); |
if(tmp!=NULL) { | | if (i < op->nrof) { |
(*esrv_del_item_func)(tmp->contr, op->count); | | sub_weight (op->env, op->weight * i); |
| | op->nrof -= i; |
| | if (tmp) { |
| | (*esrv_send_item_func) (tmp, op); |
(*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); | | (*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); |
} | | } |
} else { | | } else { |
for(tmp=op->above;tmp!=NULL;tmp=tmp->above) | | remove_ob (op); |
if(tmp->type==PLAYER) { | | op->nrof = 0; |
| | if (tmp) { |
(*esrv_del_item_func)(tmp->contr, op->count); | | (*esrv_del_item_func)(tmp->contr, op->count); |
(*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); | | (*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); |
} | | } |
} | | } |
remove_ob(op); | | |
free_object(op); | | |
return NULL; | | |
} | | } |
else | | else |
if(op->env!=NULL) { | | { |
sub_weight(op->env,op->weight*i); | | if (i < op->nrof) { |
tmp=is_player_inv (op->env); | | op->nrof -= i; |
if(tmp!=NULL) { | | |
(*esrv_send_item_func)(tmp, op); | | |
(*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); | | |
} | | |
} else { | | } else { |
| | remove_ob (op); |
| | op->nrof = 0; |
| | } |
for(tmp=op->above;tmp!=NULL;tmp=tmp->above) | | for(tmp=op->above;tmp!=NULL;tmp=tmp->above) |
if(tmp->type==PLAYER) { | | if(tmp->type==PLAYER) { |
| | if (op->nrof) |
(*esrv_send_item_func)(tmp, op); | | (*esrv_send_item_func)(tmp, op); |
(*esrv_update_item_func)(UPD_WEIGHT, tmp, tmp); | | else |
| | (*esrv_del_item_func) (tmp->contr, op->count); |
} | | } |
} | | } |
| | |
| | if (op->nrof) { |
return op; | | return op; |
| | } else { |
| | free_object (op); |
| | return NULL; |
| | } |
} | | } |
| | |
/* | | /* |