- 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://svn.code.sf.net/p/rathena/svn/trunk@13761 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
7828b01c09
commit
15a8174e29
@ -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++ )
|
||||
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;
|
||||
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
memcpy(cur,atcommand_info[i].command,slen);
|
||||
cur += slen+(10-slen%10);
|
||||
|
||||
count++;
|
||||
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);
|
||||
|
||||
count++;
|
||||
}
|
||||
clif_displaymessage(fd,line_buff);
|
||||
|
||||
sprintf(atcmd_output, msg_txt(274), count); // "%d commands found."
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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 <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;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* ƒpƒPƒbƒgƒfƒoƒbƒO
|
||||
*------------------------------------------*/
|
||||
@ -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,
|
||||
|
@ -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);
|
||||
|
77
src/map/pc.c
77
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])
|
||||
|
@ -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;
|
||||
|
@ -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,""),
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user