summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-05-12 16:47:12 +0000
committerzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-05-12 16:47:12 +0000
commitcd40a623549f42d77c54515360813131e6c9c33d (patch)
tree09afde7308a84efae2982546f73d7231d2e355b0
parent0c5e8296319a3f1396e0208fba16135ac2c7b4b0 (diff)
downloadhercules-cd40a623549f42d77c54515360813131e6c9c33d.tar.gz
hercules-cd40a623549f42d77c54515360813131e6c9c33d.tar.bz2
hercules-cd40a623549f42d77c54515360813131e6c9c33d.tar.xz
hercules-cd40a623549f42d77c54515360813131e6c9c33d.zip
- 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
-rw-r--r--src/map/atcommand.c80
-rw-r--r--src/map/clif.c36
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/pc.c77
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c36
-rw-r--r--src/map/skill.c7
-rw-r--r--src/map/vending.c1
8 files changed, 169 insertions, 74 deletions
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.
@@ -13013,6 +13019,32 @@ int clif_sendbgemblem_single(int fd, struct map_session_data *sd)
}
/*==========================================
+ * Custom Fonts
+ * S 0x2ef <account_id>.l <font id>.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;
+}
+
+/*==========================================
* パケットデバッグ
*------------------------------------------*/
void clif_parse_debug(int fd,struct map_session_data *sd)
@@ -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->amount<amount || sd->vender_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;