From cd40a623549f42d77c54515360813131e6c9c33d Mon Sep 17 00:00:00 2001 From: zephyrus Date: Tue, 12 May 2009 16:47:12 +0000 Subject: - Rental items now can be stackable items too. - Added @font command to test kRO fonts. (Client side requires : Langtype 0 / Hex + Fonts Files on the data folder). - Rental now announces with a maximum time to fix a problem with 1 month or more rentals. - Reduced amount of calculations of Flee on map change (only if required). - More security on Rental items. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13761 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 80 ++++++++++++++++++++++++++++++++++++++--------------- src/map/clif.c | 36 ++++++++++++++++++++++-- src/map/clif.h | 4 +++ src/map/pc.c | 77 ++++++++++++++++++++++++++++----------------------- src/map/pc.h | 2 ++ src/map/script.c | 36 ++++++++++++++++-------- src/map/skill.c | 7 ++--- src/map/vending.c | 1 + 8 files changed, 169 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 61557fd51..9019fd86a 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8586,6 +8586,42 @@ int atcommand_delitem(const int fd, struct map_session_data* sd, const char* com return 0; } +/*========================================== + * Custom Fonts + *------------------------------------------*/ +int atcommand_font(const int fd, struct map_session_data *sd, const char *command, const char *message) +{ + int font_id; + nullpo_retr(-1,sd); + + font_id = atoi(message); + if( font_id == 0 ) + { + if( sd->state.user_font ) + { + sd->state.user_font = 0; + clif_displaymessage(fd, "Returning to normal font."); + clif_font_area(sd); + } + else + { + clif_displaymessage(fd, "Use @font <1..9> to change your messages font."); + clif_displaymessage(fd, "Use 0 or no parameter to back to normal font."); + } + } + else if( font_id < 0 || font_id > 9 ) + clif_displaymessage(fd, "Invalid font. Use a Value from 0 to 9."); + else if( font_id != sd->state.user_font ) + { + sd->state.user_font = font_id; + clif_font_area(sd); + clif_displaymessage(fd, "Font changed."); + } + else + clif_displaymessage(fd, "Already using this font."); + + return 0; +} /*========================================== @@ -8890,6 +8926,7 @@ AtCommandInfo atcommand_info[] = { { "stats", 40,40, atcommand_stats }, { "delitem", 60,60, atcommand_delitem }, { "charcommands", 1,1, atcommand_commands }, + { "font", 1,1, atcommand_font }, }; @@ -9147,36 +9184,35 @@ int atcommand_commands(const int fd, struct map_session_data* sd, const char* co clif_displaymessage(fd, msg_txt(273)); // "Commands available:" - for( i = 0; i < ARRAYLENGTH(atcommand_info); i++ ) - { - unsigned int slen; + for( i = 0; i < ARRAYLENGTH(atcommand_info); i++ ) + { + unsigned int slen; - if( gm_lvl < atcommand_info[i].level && stristr(command,"commands") ) - continue; - if( gm_lvl < atcommand_info[i].level2 && stristr(command,"charcommands") ) - continue; + if( gm_lvl < atcommand_info[i].level && stristr(command,"commands") ) + continue; + if( gm_lvl < atcommand_info[i].level2 && stristr(command,"charcommands") ) + continue; - slen = (unsigned int)strlen(atcommand_info[i].command); + slen = (unsigned int)strlen(atcommand_info[i].command); - // flush the text buffer if this command won't fit into it - if( slen + cur - line_buff >= CHATBOX_SIZE ) - { - clif_displaymessage(fd,line_buff); - cur = line_buff; - memset(line_buff,' ',CHATBOX_SIZE); - line_buff[CHATBOX_SIZE-1] = 0; - } + // flush the text buffer if this command won't fit into it + if( slen + cur - line_buff >= CHATBOX_SIZE ) + { + clif_displaymessage(fd,line_buff); + cur = line_buff; + memset(line_buff,' ',CHATBOX_SIZE); + line_buff[CHATBOX_SIZE-1] = 0; + } - memcpy(cur,atcommand_info[i].command,slen); - cur += slen+(10-slen%10); + memcpy(cur,atcommand_info[i].command,slen); + cur += slen+(10-slen%10); - count++; - } - + count++; + } clif_displaymessage(fd,line_buff); sprintf(atcmd_output, msg_txt(274), count); // "%d commands found." clif_displaymessage(fd, atcmd_output); - + return 0; } diff --git a/src/map/clif.c b/src/map/clif.c index 1446755db..95eddb1f4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1062,6 +1062,8 @@ int clif_spawn(struct block_list *bl) clif_specialeffect(bl,423,AREA); else if(sd->state.size==1) clif_specialeffect(bl,421,AREA); + if( sd->state.user_font ) + clif_font_area(sd); if( sd->state.bg_id && map[sd->bl.m].flag.battleground ) clif_sendbgemblem_area(sd); } @@ -3486,6 +3488,8 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) clif_specialeffect_single(bl,423,sd->fd); else if(tsd->state.size==1) clif_specialeffect_single(bl,421,sd->fd); + if( tsd->state.user_font ) + clif_font_single(sd->fd,tsd); if( tsd->state.bg_id && map[tsd->bl.m].flag.battleground ) clif_sendbgemblem_single(sd->fd,tsd); } @@ -8125,8 +8129,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if( sd->state.changemap ) {// restore information that gets lost on map-change - if( battle_config.gvg_flee_penalty != 100 || battle_config.bg_flee_penalty != 100 ) + if( (map_flag_gvg(sd->state.pmap) && battle_config.gvg_flee_penalty != 100) || (map[sd->state.pmap].flag.battleground && battle_config.bg_flee_penalty != 100) ) status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty + else if( (map_flag_gvg(sd->bl.m) && battle_config.gvg_flee_penalty != 100) || (map[sd->bl.m].flag.battleground && battle_config.bg_flee_penalty != 100) ) + status_calc_bl(&sd->bl, SCB_FLEE); if( night_flag && map[sd->bl.m].flag.nightenabled ) { //Display night. @@ -13012,6 +13018,32 @@ int clif_sendbgemblem_single(int fd, struct map_session_data *sd) return 0; } +/*========================================== + * Custom Fonts + * S 0x2ef .l .w + *------------------------------------------*/ +int clif_font_area(struct map_session_data *sd) +{ + unsigned char buf[8]; + nullpo_retr(0,sd); + WBUFW(buf,0) = 0x2ef; + WBUFL(buf,2) = sd->bl.id; + WBUFW(buf,6) = sd->state.user_font; + clif_send(buf, packet_len(0x2ef), &sd->bl, AREA); + return 1; +} + +int clif_font_single(int fd, struct map_session_data *sd) +{ + nullpo_retr(0,sd); + WFIFOHEAD(fd,packet_len(0x2ef)); + WFIFOW(fd,0) = 0x2ef; + WFIFOL(fd,2) = sd->bl.id; + WFIFOW(fd,6) = sd->state.user_font; + WFIFOSET(fd,packet_len(0x2ef)); + return 1; +} + /*========================================== * パケットデバッグ *------------------------------------------*/ @@ -13286,7 +13318,7 @@ static int packetdb_readdb(void) //#0x02C0 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, -1, 10, 10, 0, 0, -1, 32, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //#0x0300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/map/clif.h b/src/map/clif.h index f529b8779..f78bbb666 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -350,6 +350,10 @@ int clif_bg_updatescore_single(struct map_session_data *sd); int clif_sendbgemblem_area(struct map_session_data *sd); int clif_sendbgemblem_single(int fd, struct map_session_data *sd); +// Custom Fonts +int clif_font_area(struct map_session_data *sd); +int clif_font_single(int fd, struct map_session_data *sd); + // atcommand int clif_displaymessage(const int fd,const char* mes); int clif_disp_onlyself(struct map_session_data *sd,const char *mes,int len); diff --git a/src/map/pc.c b/src/map/pc.c index 97ed1b5cb..757d3ccca 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -349,10 +349,10 @@ void pc_inventory_rentals(struct map_session_data *sd) } } - if( c > 0 ) - sd->rental_timer = add_timer(gettick() + next_tick, pc_inventory_rental_end, sd->bl.id, 0); + if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days + sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0); else - sd->rental_timer = -1; + sd->rental_timer = INVALID_TIMER; } void pc_inventory_rental_add(struct map_session_data *sd, int seconds) @@ -848,7 +848,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim for( i = 0; i < MAX_EVENTTIMER; i++ ) sd->eventtimer[i] = -1; // Rental Timer - sd->rental_timer = -1; + sd->rental_timer = INVALID_TIMER; for( i = 0; i < 3; i++ ) sd->hate_mob[i] = -1; @@ -3119,9 +3119,9 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) nullpo_retr(1, sd); nullpo_retr(1, item_data); - if(item_data->nameid <= 0 || amount <= 0) + if( item_data->nameid <= 0 || amount <= 0 ) return 1; - if(amount > MAX_AMOUNT) + if( amount > MAX_AMOUNT ) return 5; data = itemdb_search(item_data->nameid); @@ -3131,15 +3131,13 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) i = MAX_INVENTORY; - if (itemdb_isstackable2(data)) - { //Stackable - for (i = 0; i < MAX_INVENTORY; i++) + if( itemdb_isstackable2(data) && item_data->serial == 0 && item_data->expire_time == 0 ) + { // Stackable | Non Serialized (non unique) | Non Rental + for( i = 0; i < MAX_INVENTORY; i++ ) { - if(sd->status.inventory[i].nameid == item_data->nameid && - memcmp(&sd->status.inventory[i].card,&item_data->card, - sizeof(item_data->card))==0) + if( sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) { - if (amount > MAX_AMOUNT - sd->status.inventory[i].amount) + if( amount > MAX_AMOUNT - sd->status.inventory[i].amount ) return 5; sd->status.inventory[i].amount += amount; clif_additem(sd,i,amount,0); @@ -3147,12 +3145,16 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) } } } - if (i >= MAX_INVENTORY){ + + if( i >= MAX_INVENTORY ) + { i = pc_search_inventory(sd,0); - if(i<0) return 4; + if( i < 0 ) + return 4; + memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0])); // clear equips field first, just in case - if (item_data->equip) + if( item_data->equip ) sd->status.inventory[i].equip = 0; sd->status.inventory[i].amount = amount; @@ -3447,18 +3449,17 @@ int pc_useitem(struct map_session_data *sd,int n) nullpo_retr(0, sd); - if(sd->status.inventory[n].nameid <= 0 || - sd->status.inventory[n].amount <= 0) + if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 ) return 0; - if(!pc_isUseitem(sd,n)) + if( !pc_isUseitem(sd,n) ) return 0; //Prevent mass item usage. [Skotlex] - if(DIFF_TICK(sd->canuseitem_tick, tick) > 0) + if( DIFF_TICK(sd->canuseitem_tick, tick) > 0 ) return 0; - if (sd->sc.count && ( + if( sd->sc.count && ( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) || sd->sc.data[SC_TRICKDEAD] || @@ -3484,15 +3485,22 @@ int pc_useitem(struct map_session_data *sd,int n) amount = sd->status.inventory[n].amount; script = sd->inventory_data[n]->script; //Check if the item is to be consumed immediately [Skotlex] - if (sd->inventory_data[n]->flag.delay_consume) + if( sd->inventory_data[n]->flag.delay_consume ) clif_useitemack(sd,n,amount,1); - else { - clif_useitemack(sd,n,amount-1,1); - //Logs (C)onsumable items [Lupus] - if(log_config.enable_logs&0x100) - log_pick_pc(sd, "C", sd->status.inventory[n].nameid, -1, &sd->status.inventory[n]); - //Logs - pc_delitem(sd,n,1,1); + else + { + if( sd->status.inventory[n].expire_time == 0 ) + { + clif_useitemack(sd,n,amount-1,1); + + //Logs (C)onsumable items [Lupus] + if( log_config.enable_logs&0x100 ) + log_pick_pc(sd, "C", sd->status.inventory[n].nameid, -1, &sd->status.inventory[n], sd->status.inventory[n].serial ); + + pc_delitem(sd,n,1,1); // Rental Usable Items are not deleted until expiration + } + else + clif_useitemack(sd,n,0,0); } if(sd->status.inventory[n].card[0]==CARD0_CREATE && pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST)) @@ -3533,7 +3541,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun return 1; i = MAX_CART; - if( itemdb_isstackable2(data) ) + if( itemdb_isstackable2(data) && !item_data->expire_time ) { ARR_FIND( 0, MAX_CART, i, sd->status.cart[i].nameid == item_data->nameid && @@ -3606,10 +3614,10 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) item_data = &sd->status.inventory[idx]; - if (item_data->nameid==0 || amount < 1 || item_data->amountvender_id) + if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->vender_id || item_data->expire_time ) return 1; - if (pc_cart_additem(sd,item_data,amount) == 0) + if( pc_cart_additem(sd,item_data,amount) == 0 ) return pc_delitem(sd,idx,amount,0); return 1; @@ -3814,9 +3822,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y sd->state.changemap = (sd->mapindex != mapindex); if( sd->state.changemap ) - { //Misc map-changing settings + { // Misc map-changing settings + sd->state.pmap = sd->bl.m; if (sd->sc.count) - { //Cancel some map related stuff. + { // Cancel some map related stuff. if (sd->sc.data[SC_JAILED]) return 1; //You may not get out! if (sd->sc.data[SC_BOSSMAPINFO]) diff --git a/src/map/pc.h b/src/map/pc.h index 8a3f912b0..b846b4e66 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -120,9 +120,11 @@ struct map_session_data { unsigned short autolootid; // [Zephyrus] unsigned noks : 3; // [Zeph Kill Steal Protection] bool changemap; + short pmap; // Previous map on Map Change struct guild *gmaster_flag; unsigned int bg_id; unsigned skillonskill : 1; + unsigned short user_font; } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; diff --git a/src/map/script.c b/src/map/script.c index 85cd4d095..f0fab4ce6 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -5356,12 +5356,6 @@ BUILDIN_FUNC(rentitem) return 1; } - if( itemdb_isstackable(nameid) ) - { - ShowError("buildin_rentitem: invalid rental item %d requested.\n", nameid); - return 1; - } - seconds = script_getnum(st,3); memset(&it, 0, sizeof(it)); it.nameid = nameid; @@ -6268,14 +6262,12 @@ BUILDIN_FUNC(getequipisenableref) if( sd == NULL ) return 0; - if (num > 0 && num <= ARRAYLENGTH(equip)) - i=pc_checkequip(sd,equip[num-1]); - if(i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine) - { + if( num > 0 && num <= ARRAYLENGTH(equip) ) + i = pc_checkequip(sd,equip[num-1]); + if( i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->status.inventory[i].expire_time ) script_pushint(st,1); - } else { + else script_pushint(st,0); - } return 0; } @@ -13640,6 +13632,25 @@ BUILDIN_FUNC(bg_get_data) return 0; } +/*========================================== + * Custom Fonts + *------------------------------------------*/ +BUILDIN_FUNC(setfont) +{ + struct map_session_data *sd = script_rid2sd(st); + int font = script_getnum(st,2); + if( sd == NULL ) + return 0; + + if( sd->state.user_font != font ) + sd->state.user_font = font; + else + sd->state.user_font = 0; + + clif_font_area(sd); + return 0; +} + // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT BUILDIN_FUNC(defpattern); @@ -13998,6 +14009,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(mercenary_set_calls,"ii"), BUILDIN_DEF(mercenary_set_faith,"ii"), BUILDIN_DEF(readbook,"ii"), + BUILDIN_DEF(setfont,"i"), // WoE SE BUILDIN_DEF(agitstart2,""), BUILDIN_DEF(agitend2,""), diff --git a/src/map/skill.c b/src/map/skill.c index 767bb7833..e84562496 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -7995,11 +7995,10 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in } //Consume sd->itemid = sd->itemindex = -1; - if(skill == WZ_EARTHSPIKE && sc && - sc->data[SC_EARTHSCROLL] && rand()%100 > sc->data[SC_EARTHSCROLL]->val2) // [marquis007] + if( skill == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rand()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007] ; //Do not consume item. - else - pc_delitem(sd,i,1,0); + else if( sd->status.inventory[i].expire_time == 0 ) + pc_delitem(sd,i,1,0); // Rental usable items are not consumed until expiration } if (type&1) //Casting finished sd->skillitem = sd->skillitemlv = 0; diff --git a/src/map/vending.c b/src/map/vending.c index c77b1ac78..a6ea1d84b 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -266,6 +266,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool //NOTE: official server does not do any of the following checks! || !sd->status.cart[index].identify // unidentified item || sd->status.cart[index].attribute == 1 // broken item + || sd->status.cart[index].expire_time // It should not be in the cart but just in case || !itemdb_cantrade(&sd->status.cart[index], pc_isGM(sd), pc_isGM(sd)) ) // untradeable item continue; -- cgit v1.2.3-60-g2f50