Initial release of nocostume map flag (#1137)

* Initial release of `nocostume` map flag to follow official `DISABLE_COSTUMEITEM` map property.
* Added map flag `nocostume`, current confirmed maps are TE Castles and Guild Dungeons.
* Fixed #815.
* Stores `setlook` values so it won't be removed on `nocostume` mapflag

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
This commit is contained in:
Atemo 2016-09-06 11:34:36 +02:00 committed by Lemongrass3110
parent cf80d72359
commit 23b271c958
11 changed files with 141 additions and 94 deletions

View File

@ -396,3 +396,13 @@ in '/conf/channels.conf'.
Disables MVP tombs from appearing on a map.
---------------------------------------
*nocostume
Disables costume sprites on a map.
This only disables the sprites and not the effect of the items.
If a player logs out on a nocostume map the costume sprites will also not be shown in the
character server.
---------------------------------------

28
npc/mapflag/nocostume.txt Normal file
View File

@ -0,0 +1,28 @@
//===== rAthena Script =======================================
//= Mapflag: nocostume
//===== Description: =========================================
//= A mapflag to disable costume's sprite on map.
//= Usage:
//= [mapname] mapflag nocostume
//===== Changelogs: ==========================================
//= 1.0 Initial release. [Cydh]
//= 1.0.1 Added arug_dun01 and schg_dun01 to the list. [Cydh]
//============================================================
// WOE:TE Castles =========
te_prtcas01 mapflag nocostume
te_prtcas02 mapflag nocostume
te_prtcas03 mapflag nocostume
te_prtcas04 mapflag nocostume
te_prtcas05 mapflag nocostume
te_aldecas1 mapflag nocostume
te_aldecas2 mapflag nocostume
te_aldecas3 mapflag nocostume
te_aldecas4 mapflag nocostume
te_aldecas5 mapflag nocostume
// Guild Dungeons =========
teg_dun01 mapflag nocostume
teg_dun02 mapflag nocostume
arug_dun01 mapflag nocostume
schg_dun01 mapflag nocostume

View File

@ -25,3 +25,4 @@ npc: npc/mapflag/restricted.txt
npc: npc/mapflag/battleground.txt
npc: npc/mapflag/skill_damage.txt
npc: npc/mapflag/town.txt
npc: npc/mapflag/nocostume.txt

View File

@ -4163,6 +4163,8 @@ ACMD_FUNC(mapinfo) {
strcat(atcmd_output, " NoLockOn |");
if (map[m_id].flag.notomb)
strcat(atcmd_output, " NoTomb |");
if (map[m_id].flag.nocostume)
strcat(atcmd_output, " NoCostume |");
clif_displaymessage(fd, atcmd_output);
switch (list) {
@ -8034,7 +8036,7 @@ ACMD_FUNC(mapflag) {
checkflag(nodrop); checkflag(novending); checkflag(loadevent); checkflag(nochat);
checkflag(partylock); checkflag(guildlock); checkflag(reset); checkflag(chmautojoin);
checkflag(nousecart); checkflag(noitemconsumption); checkflag(nosumstarmiracle); checkflag(nomineeffect);
checkflag(nolockon); checkflag(notomb);
checkflag(nolockon); checkflag(notomb); checkflag(nocostume);
#ifdef ADJUST_SKILL_DAMAGE
checkflag(skill_damage);
#endif
@ -8058,7 +8060,7 @@ ACMD_FUNC(mapflag) {
setflag(nodrop); setflag(novending); setflag(loadevent); setflag(nochat);
setflag(partylock); setflag(guildlock); setflag(reset); setflag(chmautojoin);
setflag(nousecart); setflag(noitemconsumption); setflag(nosumstarmiracle); setflag(nomineeffect);
setflag(nolockon); setflag(notomb);
setflag(nolockon); setflag(notomb); setflag(nocostume);
#ifdef ADJUST_SKILL_DAMAGE
setflag(skill_damage);
#endif
@ -8073,7 +8075,8 @@ ACMD_FUNC(mapflag) {
clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot, nomvploot,");
clif_displaymessage(sd->fd,"nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock, guildlock,");
clif_displaymessage(sd->fd,"reset, chmautojoin, nousecart, noitemconsumption, nosumstarmiracle, nolockon, notomb");
clif_displaymessage(sd->fd,"reset, chmautojoin, nousecart, noitemconsumption, nosumstarmiracle, nolockon, notomb,");
clif_displaymessage(sd->fd,"nocostume");
#ifdef ADJUST_SKILL_DAMAGE
clif_displaymessage(sd->fd,"skill_damage");
#endif

View File

@ -6167,7 +6167,7 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
((map[bl->m].flag.pvp?1:0)<<5)| // COUNT_PK - Show the PvP counter
((map[bl->m].flag.partylock?1:0)<<6)| // NO_PARTY_FORMATION - Prevents party creation/modification (Might be used for instance dungeons)
((map[bl->m].flag.battleground?1:0)<<7)| // BATTLEFIELD - Unknown (Does something for battlegrounds areas)
((map[bl->m].flag.noitemconsumption?1:0)<<8)| // DISABLE_COSTUMEITEM - Unknown - (Prevents wearing of costume items?)
((map[bl->m].flag.nocostume?1:0)<<8)| // DISABLE_COSTUMEITEM - Disable costume sprites
((map[bl->m].flag.nousecart?0:1)<<9)| // USECART - Allow opening cart inventory (Well force it to always allow it)
((map[bl->m].flag.nosumstarmiracle?0:1)<<10); // SUNMOONSTAR_MIRACLE - Unknown - (Guessing it blocks Star Gladiator's Miracle from activating)
//(1<<11); // Unused bits. 1 - 10 is 0x1 length and 11 is 0x15 length. May be used for future settings.
@ -10079,6 +10079,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
#else
clif_changelook(&sd->bl,LOOK_WEAPON,0);
#endif
pc_set_costume_view(sd);
if(sd->vd.cloth_color)
clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);

View File

@ -662,6 +662,7 @@ struct map_data {
unsigned nomineeffect : 1; //allow /mineeffect
unsigned nolockon : 1;
unsigned notomb : 1;
unsigned nocostume : 1; // Disable costume sprites [Cydh]
#ifdef ADJUST_SKILL_DAMAGE
unsigned skill_damage : 1;
#endif

View File

@ -4089,6 +4089,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
map[m].flag.nolockon = state;
else if (!strcmpi(w3,"notomb"))
map[m].flag.notomb = state;
else if (!strcmpi(w3,"nocostume"))
map[m].flag.nocostume = state;
else if (!strcmpi(w3,"skill_damage")) {
#ifdef ADJUST_SKILL_DAMAGE
char skill[SKILL_NAME_LENGTH];

View File

@ -8616,12 +8616,15 @@ void pc_changelook(struct map_session_data *sd,int type,int val) {
break;
case LOOK_HEAD_BOTTOM:
sd->status.head_bottom = val;
sd->setlook_head_bottom = val;
break;
case LOOK_HEAD_TOP:
sd->status.head_top = val;
sd->setlook_head_top = val;
break;
case LOOK_HEAD_MID:
sd->status.head_mid = val;
sd->setlook_head_mid = val;
break;
case LOOK_HAIR_COLOR: //Use the battle_config limits! [Skotlex]
val = cap_value(val, MIN_HAIR_COLOR, MAX_HAIR_COLOR);
@ -8645,6 +8648,7 @@ void pc_changelook(struct map_session_data *sd,int type,int val) {
break;
case LOOK_ROBE:
sd->status.robe = val;
sd->setlook_robe = val;
break;
case LOOK_BODY2:
val = cap_value(val, MIN_BODY_STYLE, MAX_BODY_STYLE);
@ -9691,60 +9695,10 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
pc_calcweapontype(sd);
clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
}
//Added check to prevent sending the same look on multiple slots ->
//causes client to redraw item on top of itself. (suggested by Lupus)
if(pos & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
sd->status.head_bottom = id->look;
else
sd->status.head_bottom = 0;
clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
}
if(pos & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
if(id)
sd->status.head_top = id->look;
else
sd->status.head_top = 0;
clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
}
if(pos & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
if(id && !(pos&EQP_HEAD_TOP))
sd->status.head_mid = id->look;
else
sd->status.head_mid = 0;
clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
}
if(pos & EQP_COSTUME_HEAD_TOP) {
if(id){
sd->status.head_top = id->look;
} else
sd->status.head_top = 0;
clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
}
if(pos & EQP_COSTUME_HEAD_MID) {
if(id && !(pos&EQP_HEAD_TOP)){
sd->status.head_mid = id->look;
} else
sd->status.head_mid = 0;
clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
}
if(pos & EQP_COSTUME_HEAD_LOW) {
if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){
sd->status.head_bottom = id->look;
} else
sd->status.head_bottom = 0;
clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
}
if(pos & EQP_SHOES)
clif_changelook(&sd->bl,LOOK_SHOES,0);
if(pos&EQP_GARMENT && pc_checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
sd->status.robe = id ? id->look : 0;
clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
}
if(pos & EQP_COSTUME_GARMENT) {
sd->status.robe = id ? id->look : 0;
clif_changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
}
pc_set_costume_view(sd);
pc_checkallowskill(sd); //Check if status changes should be halted.
iflag = sd->npc_item_flag;
@ -9850,48 +9804,12 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
pc_calcweapontype(sd);
clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
}
if(sd->status.inventory[n].equip & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1 ) {
sd->status.head_bottom = 0;
clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
}
if(sd->status.inventory[n].equip & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1 ) {
sd->status.head_top = 0;
clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
}
if(sd->status.inventory[n].equip & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1 ) {
sd->status.head_mid = 0;
clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
}
if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_TOP) {
sd->status.head_top = ( pc_checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_TOP)]->look : 0;
clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
}
if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_MID) {
sd->status.head_mid = ( pc_checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_MID)]->look : 0;
clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
}
if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_LOW) {
sd->status.head_bottom = ( pc_checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_LOW)]->look : 0;
clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
}
if(sd->status.inventory[n].equip & EQP_SHOES)
clif_changelook(&sd->bl,LOOK_SHOES,0);
if(sd->status.inventory[n].equip&EQP_GARMENT && pc_checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
sd->status.robe = 0;
clif_changelook(&sd->bl, LOOK_ROBE, 0);
}
if(sd->status.inventory[n].equip & EQP_COSTUME_GARMENT) {
sd->status.robe = ( pc_checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_GARMENT)]->look : 0;
clif_changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
}
clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
pc_set_costume_view(sd);
status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
// On weapon change (right and left hand)
@ -12266,6 +12184,82 @@ bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) {
return true;
}
/**
* Tells client about player's costume view on mapchange for checking 'nocostume' mapflag.
* @param sd
**/
void pc_set_costume_view(struct map_session_data *sd) {
int i = -1, head_low = 0, head_mid = 0, head_top = 0, robe = 0;
struct item_data *id = NULL;
nullpo_retv(sd);
head_low = sd->status.head_bottom;
head_mid = sd->status.head_mid;
head_top = sd->status.head_top;
robe = sd->status.robe;
sd->status.head_bottom = sd->status.head_mid = sd->status.head_top = sd->status.robe = 0;
//Added check to prevent sending the same look on multiple slots ->
//causes client to redraw item on top of itself. (suggested by Lupus)
// Normal headgear checks
if ((i = sd->equip_index[EQI_HEAD_LOW]) != -1 && (id = sd->inventory_data[i])) {
if (!(id->equip&(EQP_HEAD_MID|EQP_HEAD_TOP)))
sd->status.head_bottom = id->look;
else
sd->status.head_bottom = 0;
}
if ((i = sd->equip_index[EQI_HEAD_MID]) != -1 && (id = sd->inventory_data[i])) {
if (!(id->equip&(EQP_HEAD_TOP)))
sd->status.head_mid = id->look;
else
sd->status.head_mid = 0;
}
if ((i = sd->equip_index[EQI_HEAD_TOP]) != -1 && (id = sd->inventory_data[i]))
sd->status.head_top = id->look;
if ((i = sd->equip_index[EQI_GARMENT]) != -1 && (id = sd->inventory_data[i]))
sd->status.robe = id->look;
// Costumes check
if (!map[sd->bl.m].flag.nocostume) {
if ((i = sd->equip_index[EQI_COSTUME_HEAD_LOW]) != -1 && (id = sd->inventory_data[i])) {
if (!(id->equip&(EQP_COSTUME_HEAD_MID|EQP_COSTUME_HEAD_TOP)))
sd->status.head_bottom = id->look;
else
sd->status.head_bottom = 0;
}
if ((i = sd->equip_index[EQI_COSTUME_HEAD_MID]) != -1 && (id = sd->inventory_data[i])) {
if (!(id->equip&EQP_COSTUME_HEAD_TOP))
sd->status.head_mid = id->look;
else
sd->status.head_mid = 0;
}
if ((i = sd->equip_index[EQI_COSTUME_HEAD_TOP]) != -1 && (id = sd->inventory_data[i]))
sd->status.head_top = id->look;
if ((i = sd->equip_index[EQI_COSTUME_GARMENT]) != -1 && (id = sd->inventory_data[i]))
sd->status.robe = id->look;
}
if (sd->setlook_head_bottom)
sd->status.head_bottom = sd->setlook_head_bottom;
if (sd->setlook_head_mid)
sd->status.head_mid = sd->setlook_head_mid;
if (sd->setlook_head_top)
sd->status.head_top = sd->setlook_head_top;
if (sd->setlook_robe)
sd->status.robe = sd->setlook_robe;
if (head_low != sd->status.head_bottom)
clif_changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.head_bottom);
if (head_mid != sd->status.head_mid)
clif_changelook(&sd->bl, LOOK_HEAD_MID, sd->status.head_mid);
if (head_top != sd->status.head_top)
clif_changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.head_top);
if (robe != sd->status.robe)
clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
}
/*==========================================
* pc Init/Terminate
*------------------------------------------*/

View File

@ -687,6 +687,7 @@ struct map_session_data {
} roulette;
unsigned short instance_id;
short setlook_head_top, setlook_head_mid, setlook_head_bottom, setlook_robe; ///< Stores 'setlook' script command values.
#if PACKETVER >= 20150513
uint32* hatEffectIDs;
@ -1098,6 +1099,7 @@ void pc_setriding(struct map_session_data* sd, int flag);
void pc_setmadogear(struct map_session_data* sd, int flag);
void pc_changelook(struct map_session_data *,int,int);
void pc_equiplookall(struct map_session_data *sd);
void pc_set_costume_view(struct map_session_data *sd);
int pc_readparam(struct map_session_data *sd, int type);
bool pc_setparam(struct map_session_data *sd, int type, int val);

View File

@ -361,7 +361,8 @@ enum {
MF_NOMINEEFFECT,
MF_NOLOCKON,
MF_NOTOMB,
MF_SKILL_DAMAGE //60
MF_SKILL_DAMAGE, //60
MF_NOCOSTUME,
};
const char* script_op2name(int op)
@ -11845,6 +11846,7 @@ BUILDIN_FUNC(getmapflag)
case MF_NOMINEEFFECT: script_pushint(st,map[m].flag.nomineeffect); break;
case MF_NOLOCKON: script_pushint(st,map[m].flag.nolockon); break;
case MF_NOTOMB: script_pushint(st,map[m].flag.notomb); break;
case MF_NOCOSTUME: script_pushint(st,map[m].flag.nocostume); break;
#ifdef ADJUST_SKILL_DAMAGE
case MF_SKILL_DAMAGE:
{
@ -11968,6 +11970,7 @@ BUILDIN_FUNC(setmapflag)
case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 1 ; break;
case MF_NOLOCKON: map[m].flag.nolockon = 1 ; break;
case MF_NOTOMB: map[m].flag.notomb = 1; break;
case MF_NOCOSTUME: map[m].flag.nocostume = 1; break;
#ifdef ADJUST_SKILL_DAMAGE
case MF_SKILL_DAMAGE:
{
@ -12079,6 +12082,7 @@ BUILDIN_FUNC(removemapflag)
case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 0 ; break;
case MF_NOLOCKON: map[m].flag.nolockon = 0 ; break;
case MF_NOTOMB: map[m].flag.notomb = 0; break;
case MF_NOCOSTUME: map[m].flag.nocostume = 0; break;
#ifdef ADJUST_SKILL_DAMAGE
case MF_SKILL_DAMAGE:
{

View File

@ -396,6 +396,7 @@
export_constant(MF_NOLOCKON);
export_constant(MF_NOTOMB);
export_constant(MF_SKILL_DAMAGE);
export_constant(MF_NOCOSTUME);
/* setcell types */
export_constant(CELL_WALKABLE);