Mark Wedel wrote: > It might actually make more sense to treat the weight like any > of the other stats (at least player weight), store the last > value we sent, and send again if different instead of having > these explicit calls. Here is a diff that should do this. I declared the function pay_from_container() as "static" since it is called from nowhere else. In addition I removed the parameter "object *op" since it is unused. The use of the magic value "last_weight==(uint32)-1" was necessary to delay sending "upditem" commands until the player object has been sent ("player" and "item" commands). To check (and document) implicit assumptions, I use assert() statements. Since these statements are basically not used elsewhere, I'm not sure if I should remove these statements. -------------- next part -------------- Index: common/item.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/common/item.c,v retrieving revision 1.44 diff -w -c -5 -r1.44 item.c *** common/item.c 4 May 2004 07:14:53 -0000 1.44 --- common/item.c 5 Jun 2004 16:01:56 -0000 *************** *** 235,252 **** return buf; } /* * query_weight(object) returns a character pointer to a static buffer * containing the text-representation of the weight of the given object. * The buffer will be overwritten by the next call to query_weight(). */ char *query_weight(object *op) { static char buf[10]; ! int i=op->nrof?op->nrof*op->weight:op->weight+op->carrying; if(op->weight<0) return " "; if(i%1000) sprintf(buf,"%6.1f",i/1000.0); --- 235,260 ---- return buf; } /* + * get_weight(object) returns the weight of the given object. + */ + sint32 get_weight(const object *op) { + return op->nrof ? op->weight : op->weight+op->carrying; + } + + + /* * query_weight(object) returns a character pointer to a static buffer * containing the text-representation of the weight of the given object. * The buffer will be overwritten by the next call to query_weight(). */ char *query_weight(object *op) { static char buf[10]; ! sint32 i=op->nrof?op->nrof*op->weight:op->weight+op->carrying; if(op->weight<0) return " "; if(i%1000) sprintf(buf,"%6.1f",i/1000.0); Index: common/object.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/common/object.c,v retrieving revision 1.87 diff -w -c -5 -r1.87 object.c *** common/object.c 18 May 2004 16:11:52 -0000 1.87 --- common/object.c 5 Jun 2004 16:01:56 -0000 *************** *** 1641,1658 **** if (i < op->nrof) { 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); } } else { remove_ob (op); op->nrof = 0; if (tmp) { (*esrv_del_item_func) (tmp->contr, op->count); - (*esrv_update_item_func) (UPD_WEIGHT, tmp, tmp); } } } else { --- 1641,1656 ---- Index: include/libproto.h =================================================================== RCS file: /cvsroot/crossfire/crossfire/include/libproto.h,v retrieving revision 1.56 diff -w -c -5 -r1.56 libproto.h *** include/libproto.h 28 Apr 2004 22:04:09 -0000 1.56 --- include/libproto.h 5 Jun 2004 16:01:56 -0000 *************** *** 135,144 **** --- 135,145 ---- extern void init_attackmess(void); /* item.c */ extern int get_power_from_ench(int ench); extern int calc_item_power(object *op, int flag); extern char *describe_resistance(object *op, int newline); + extern sint32 get_weight(const object *op); extern char *query_weight(object *op); extern char *get_levelnumber(int i); extern char *get_number(int i); extern char *ring_desc(object *op); extern char *query_short_name(object *op); Index: include/player.h =================================================================== RCS file: /cvsroot/crossfire/crossfire/include/player.h,v retrieving revision 1.35 diff -w -c -5 -r1.35 player.h *** include/player.h 16 Feb 2004 18:05:32 -0000 1.35 --- include/player.h 5 Jun 2004 16:01:56 -0000 *************** *** 135,144 **** --- 135,145 ---- sint64 last_skill_exp[NUM_SKILLS]; /* shadow register. if != exp. obj update client */ float weapon_sp; /* Penalties to speed when fighting w speed >ws/10*/ float last_weapon_sp; /* if diff than weapon_sp, update client */ uint16 last_flags; /* fire/run on flags for last tick */ + uint32 last_weight; /* Last weight as sent to client; (uint32)-1 means do not send weight */ uint32 last_weight_limit; /* Last weight limit transmitted to client */ living orig_stats; /* Permanent real stats of player */ living last_stats; /* Last stats as sent to client */ float last_speed; /* Last speed as sent to client */ sint16 last_resist[NROFATTACKS]; /* last resist values sent to client */ Index: include/sproto.h =================================================================== RCS file: /cvsroot/crossfire/crossfire/include/sproto.h,v retrieving revision 1.106 diff -w -c -5 -r1.106 sproto.h *** include/sproto.h 24 May 2004 21:00:16 -0000 1.106 --- include/sproto.h 5 Jun 2004 16:01:56 -0000 *************** *** 626,636 **** char *cost_string_from_value(uint64 cost); char *query_cost_string(object *tmp, object *who, int flag); uint64 query_money(object *op); int pay_for_amount(int to_pay, object *pl); int pay_for_item(object *op, object *pl); - uint64 pay_from_container(object *op, object *pouch, int to_pay); int get_payment(object *pl, object *op); void sell_item(object *op, object *pl); void shop_listing(object *op); /* skills.c */ int steal(object *op, int dir, object *skill); --- 626,635 ---- Index: server/attack.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/server/attack.c,v retrieving revision 1.98 diff -w -c -5 -r1.98 attack.c *** server/attack.c 4 May 2004 07:14:53 -0000 1.98 --- server/attack.c 5 Jun 2004 16:01:56 -0000 *************** *** 190,200 **** if (op->env) { object *tmp= is_player_inv(op->env); if (tmp) { esrv_del_item(tmp->contr, op->count); - esrv_update_item(UPD_WEIGHT, tmp, tmp); } } if ( ! QUERY_FLAG (op, FLAG_REMOVED)) remove_ob(op); free_object(op); --- 190,199 ---- Index: server/c_object.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/server/c_object.c,v retrieving revision 1.57 diff -w -c -5 -r1.57 c_object.c *** server/c_object.c 26 Apr 2004 05:07:52 -0000 1.57 --- server/c_object.c 5 Jun 2004 16:01:57 -0000 *************** *** 629,642 **** */ if(pl->type!=PLAYER) return; esrv_send_item (pl, tmp); /* These are needed to update the weight for the container we ! * are putting the object in, and the players weight, if different. */ esrv_update_item (UPD_WEIGHT, pl, op); ! if (op!=pl) esrv_send_item (pl, pl); /* Update the container the object was in */ if (env && env!=pl && env!=op) esrv_update_item (UPD_WEIGHT, pl, env); } --- 629,644 ---- */ if(pl->type!=PLAYER) return; esrv_send_item (pl, tmp); /* These are needed to update the weight for the container we ! * are putting the object in. */ + if (op!=pl) { esrv_update_item (UPD_WEIGHT, pl, op); ! esrv_send_item (pl, pl); ! } /* Update the container the object was in */ if (env && env!=pl && env!=op) esrv_update_item (UPD_WEIGHT, pl, env); } *************** *** 891,903 **** */ if (tmp2 != tmp) esrv_del_item (op->contr, tmp_tag); esrv_send_item (op, tmp2); ! /* update the sacks and players weight */ esrv_update_item (UPD_WEIGHT, op, sack); - esrv_update_item (UPD_WEIGHT, op, op); } /* * This function was part of drop, now is own function. * Player 'op' tries to drop object 'tmp', if tmp is non zero, then --- 893,904 ---- */ if (tmp2 != tmp) esrv_del_item (op->contr, tmp_tag); esrv_send_item (op, tmp2); ! /* update the sacks weight */ esrv_update_item (UPD_WEIGHT, op, sack); } /* * This function was part of drop, now is own function. * Player 'op' tries to drop object 'tmp', if tmp is non zero, then Index: server/login.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/server/login.c,v retrieving revision 1.46 diff -w -c -5 -r1.46 login.c *** server/login.c 12 Mar 2004 19:04:15 -0000 1.46 --- server/login.c 5 Jun 2004 16:01:57 -0000 *************** *** 700,709 **** --- 700,712 ---- * the data isn't needed. */ esrv_new_player(op->contr,op->weight+op->carrying); esrv_send_inventory(op, op); + op->contr->last_weight = 0; /* set to incorrect weight, so esrv_update_item will send correct value */ + esrv_update_item(UPD_WEIGHT, op, op); + CLEAR_FLAG(op, FLAG_FRIENDLY); /* can_use_shield is a new flag. However, the can_use.. seems to largely come * from the class, and not race. I don't see any way to get the class information * to then update this. I don't think this will actually break anything - anyone Index: server/player.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/server/player.c,v retrieving revision 1.150 diff -w -c -5 -r1.150 player.c *** server/player.c 16 Apr 2004 06:23:44 -0000 1.150 --- server/player.c 5 Jun 2004 16:01:57 -0000 *************** *** 204,213 **** --- 204,214 ---- } for (i=0; i < NROFATTACKS; i++) { p->last_resist[i] = -1; } p->last_stats.exp = -1; + p->last_weight = (uint32)-1; p->socket.update_look=0; p->socket.look_position=0; return p; } *************** *** 2828,2838 **** for (pl = first_player; pl != NULL; pl = pl->next) { int old = pl->ob->carrying, sum = sum_weight(pl->ob); if(old == sum) continue; fix_player(pl->ob); - esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob); LOG(llevDebug,"Fixed inventory in %s (%d -> %d)\n", pl->ob->name, old, sum); } } --- 2829,2838 ---- Index: server/shop.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/server/shop.c,v retrieving revision 1.30 diff -w -c -5 -r1.30 shop.c *** server/shop.c 6 May 2004 07:04:23 -0000 1.30 --- server/shop.c 5 Jun 2004 16:01:57 -0000 *************** *** 24,43 **** --- 24,47 ---- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The authors can be reached via e-mail at crossfire-devel at real-time.com */ + #include <assert.h> #include <global.h> #include <spells.h> #include <skills.h> #include <living.h> #include <newclient.h> #ifndef __CEXTRACT__ #include <sproto.h> #endif + static uint64 pay_from_container(object *pouch, uint64 to_pay); + + #define NUM_COINS 3 /* number of coin types */ static char *coins[] = {"platinacoin", "goldcoin", "silvercoin", NULL}; /* Added F_TRUE flag to define.h to mean that the price should not * be adjusted by players charisma. With F_TRUE, it returns the amount *************** *** 333,349 **** object *pouch; if (to_pay==0) return 1; if (to_pay > query_money(pl)) return 0; ! to_pay = pay_from_container(NULL, pl, to_pay); for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) { if (pouch->type == CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr(pouch->race, "gold"))) { ! to_pay = pay_from_container(NULL, pouch, to_pay); } } fix_player(pl); return 1; } --- 337,353 ---- object *pouch; if (to_pay==0) return 1; if (to_pay > query_money(pl)) return 0; ! to_pay = pay_from_container(pl, to_pay); for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) { if (pouch->type == CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr(pouch->race, "gold"))) { ! to_pay = pay_from_container(pouch, to_pay); } } fix_player(pl); return 1; } *************** *** 368,384 **** saved_money = query_cost(op,pl,F_BUY | F_NO_BARGAIN) - to_pay; if (saved_money > 0) change_exp(pl,saved_money,"bargaining",SK_EXP_NONE); ! to_pay = pay_from_container(op, pl, to_pay); for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) { if (pouch->type == CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr(pouch->race, "gold"))) { ! to_pay = pay_from_container(op, pouch, to_pay); } } if (settings.real_wiz == FALSE && QUERY_FLAG(pl, FLAG_WAS_WIZ)) SET_FLAG(op, FLAG_WAS_WIZ); fix_player(pl); --- 372,388 ---- saved_money = query_cost(op,pl,F_BUY | F_NO_BARGAIN) - to_pay; if (saved_money > 0) change_exp(pl,saved_money,"bargaining",SK_EXP_NONE); ! to_pay = pay_from_container(pl, to_pay); for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) { if (pouch->type == CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr(pouch->race, "gold"))) { ! to_pay = pay_from_container(pouch, to_pay); } } if (settings.real_wiz == FALSE && QUERY_FLAG(pl, FLAG_WAS_WIZ)) SET_FLAG(op, FLAG_WAS_WIZ); fix_player(pl); *************** *** 391,403 **** * with weight not be subtracted properly. We now remove and * insert the coin objects - this should update the weight * appropriately * * DAMN: This function is used for the player, then for any active ! * containers that can hold money, until the op is paid for. */ ! uint64 pay_from_container(object *op, object *pouch, int to_pay) { int count, i; sint64 remain; object *tmp, *coin_objs[NUM_COINS], *next; archetype *at; object *who; --- 395,411 ---- * with weight not be subtracted properly. We now remove and * insert the coin objects - this should update the weight * appropriately * * DAMN: This function is used for the player, then for any active ! * containers that can hold money. ! * ! * pouch is the container (pouch or player) to remove the coins from. ! * to_pay is the required amount. ! * returns the amount still missing after using "pouch". */ ! static uint64 pay_from_container(object *pouch, uint64 to_pay) { int count, i; sint64 remain; object *tmp, *coin_objs[NUM_COINS], *next; archetype *at; object *who; *************** *** 475,490 **** } for (i=0; i<NUM_COINS; i++) { if (coin_objs[i]->nrof) { object *tmp = insert_ob_in_ob(coin_objs[i], pouch); for (who = pouch; who && who->type!=PLAYER && who->env!=NULL; who=who->env) ; esrv_send_item(who, tmp); esrv_send_item (who, pouch); ! esrv_update_item (UPD_WEIGHT, who, pouch); if (pouch->type != PLAYER) { esrv_send_item (who, who); - esrv_update_item (UPD_WEIGHT, who, who); } } else { free_object(coin_objs[i]); } } --- 483,498 ---- } for (i=0; i<NUM_COINS; i++) { if (coin_objs[i]->nrof) { object *tmp = insert_ob_in_ob(coin_objs[i], pouch); for (who = pouch; who && who->type!=PLAYER && who->env!=NULL; who=who->env) ; + assert(who != NULL && who->type == PLAYER); esrv_send_item(who, tmp); esrv_send_item (who, pouch); ! if(who != pouch) esrv_update_item (UPD_WEIGHT, who, pouch); if (pouch->type != PLAYER) { esrv_send_item (who, who); } } else { free_object(coin_objs[i]); } } *************** *** 611,621 **** tmp = insert_ob_in_ob(tmp, pouch); esrv_send_item (pl, tmp); esrv_send_item (pl, pouch); esrv_update_item (UPD_WEIGHT, pl, pouch); esrv_send_item (pl, pl); - esrv_update_item (UPD_WEIGHT, pl, pl); } } } if (i/at->clone.value > 0) { tmp = get_object(); --- 619,628 ---- *************** *** 623,633 **** tmp->nrof = i/tmp->value; i -= (uint64)tmp->nrof * (uint64)tmp->value; tmp = insert_ob_in_ob(tmp, pl); esrv_send_item (pl, tmp); esrv_send_item (pl, pl); - esrv_update_item (UPD_WEIGHT, pl, pl); } } } if (i!=0) --- 630,639 ---- Index: socket/item.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/socket/item.c,v retrieving revision 1.28 diff -w -c -5 -r1.28 item.c *** socket/item.c 11 Feb 2004 08:09:29 -0000 1.28 --- socket/item.c 5 Jun 2004 16:01:57 -0000 *************** *** 52,64 **** * * Functions related to sending object data to the client. * ******************************************************************************/ - /** This is more or less stolen from the query_weight function. */ - #define WEIGHT(op) (op->nrof?op->weight:op->weight+op->carrying) - /** * Adds string to socklist. * * This is a simple function that we use a lot here. It basically * adds the specified buffer into the socklist, but prepends a --- 52,61 ---- *************** *** 225,235 **** !pl->contr->socket.anims_sent[tmp->animation_id]) esrv_send_animation(&pl->contr->socket, tmp->animation_id); SockList_AddInt(&sl, tmp->count); SockList_AddInt(&sl, flags); ! SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : WEIGHT(tmp)); SockList_AddInt(&sl, tmp->face->number); if (!tmp->custom_name) { strncpy(item_n,query_base_name(tmp, 0),127); item_n[127]=0; --- 222,232 ---- !pl->contr->socket.anims_sent[tmp->animation_id]) esrv_send_animation(&pl->contr->socket, tmp->animation_id); SockList_AddInt(&sl, tmp->count); SockList_AddInt(&sl, flags); ! SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : get_weight(tmp)); SockList_AddInt(&sl, tmp->face->number); if (!tmp->custom_name) { strncpy(item_n,query_base_name(tmp, 0),127); item_n[127]=0; *************** *** 315,325 **** if (QUERY_FLAG(tmp,FLAG_ANIMATE) && !pl->contr->socket.anims_sent[tmp->animation_id]) esrv_send_animation(&pl->contr->socket, tmp->animation_id); SockList_AddInt(&sl, tmp->count); SockList_AddInt(&sl, flags); ! SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : WEIGHT(tmp)); SockList_AddInt(&sl, tmp->face->number); if (!tmp->custom_name) { strncpy(item_n,query_base_name(tmp, 0),127); item_n[127]=0; --- 312,322 ---- if (QUERY_FLAG(tmp,FLAG_ANIMATE) && !pl->contr->socket.anims_sent[tmp->animation_id]) esrv_send_animation(&pl->contr->socket, tmp->animation_id); SockList_AddInt(&sl, tmp->count); SockList_AddInt(&sl, flags); ! SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : get_weight(tmp)); SockList_AddInt(&sl, tmp->face->number); if (!tmp->custom_name) { strncpy(item_n,query_base_name(tmp, 0),127); item_n[127]=0; *************** *** 415,426 **** SockList_AddInt(&sl, op->env? op->env->count:0); if (flags & UPD_FLAGS) SockList_AddInt(&sl, query_flags(op)); ! if (flags & UPD_WEIGHT) ! SockList_AddInt(&sl, WEIGHT(op)); if (flags & UPD_FACE) { if (!pl->contr->socket.faces_sent[op->face->number]) esrv_send_face(&pl->contr->socket, op->face->number,0); SockList_AddInt(&sl, op->face->number); --- 412,428 ---- SockList_AddInt(&sl, op->env? op->env->count:0); if (flags & UPD_FLAGS) SockList_AddInt(&sl, query_flags(op)); ! if (flags & UPD_WEIGHT) { ! sint32 weight = get_weight(op); ! SockList_AddInt(&sl, weight); ! if (pl == op) { ! op->contr->last_weight = weight; ! } ! } if (flags & UPD_FACE) { if (!pl->contr->socket.faces_sent[op->face->number]) esrv_send_face(&pl->contr->socket, op->face->number,0); SockList_AddInt(&sl, op->face->number); *************** *** 508,518 **** !pl->contr->socket.anims_sent[op->animation_id]) esrv_send_animation(&pl->contr->socket, op->animation_id); SockList_AddInt(&sl, op->count); SockList_AddInt(&sl, query_flags(op)); ! SockList_AddInt(&sl, WEIGHT(op)); SockList_AddInt(&sl, op->face->number); if(!op->custom_name) { strncpy(item_n,query_base_name(op, 0),127); item_n[127]=0; --- 510,520 ---- !pl->contr->socket.anims_sent[op->animation_id]) esrv_send_animation(&pl->contr->socket, op->animation_id); SockList_AddInt(&sl, op->count); SockList_AddInt(&sl, query_flags(op)); ! SockList_AddInt(&sl, get_weight(op)); SockList_AddInt(&sl, op->face->number); if(!op->custom_name) { strncpy(item_n,query_base_name(op, 0),127); item_n[127]=0; Index: socket/loop.c =================================================================== RCS file: /cvsroot/crossfire/crossfire/socket/loop.c,v retrieving revision 1.26 diff -w -c -5 -r1.26 loop.c *** socket/loop.c 2 Dec 2003 18:51:44 -0000 1.26 --- socket/loop.c 5 Jun 2004 16:01:57 -0000 *************** *** 37,46 **** --- 37,47 ---- * maintenance (checking for lost connections and if data has arrived.) * The reading of data is handled in ericserver.c */ + #include <assert.h> #include <global.h> #ifndef __CEXTRACT__ #include <sproto.h> #include <sockproto.h> #endif *************** *** 656,665 **** --- 657,670 ---- /* Update the players stats once per tick. More efficient than * sending them whenever they change, and probably just as useful */ esrv_update_stats(pl); + if (pl->last_weight != (uint32)-1 && pl->last_weight != get_weight(pl->ob)) { + esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob); + assert(pl->last_weight == get_weight(pl->ob)); + } if (pl->ob->map && pl->ob->map->in_memory==MAP_IN_MEMORY) draw_client_map(pl->ob); if (pl->socket.update_look) esrv_draw_look(pl->ob); } } -------------- next part -------------- _______________________________________________ crossfire-devel mailing list crossfire-devel at lists.real-time.com https://mailman.real-time.com/mailman/listinfo/crossfire-devel