diff --git a/doc/mapflags.txt b/doc/mapflags.txt index 719ce79cab..18482c9bdb 100644 --- a/doc/mapflags.txt +++ b/doc/mapflags.txt @@ -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. + +--------------------------------------- diff --git a/npc/mapflag/nocostume.txt b/npc/mapflag/nocostume.txt new file mode 100644 index 0000000000..e493ae9424 --- /dev/null +++ b/npc/mapflag/nocostume.txt @@ -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 diff --git a/npc/scripts_mapflags.conf b/npc/scripts_mapflags.conf index 88d4c6d835..68618c22a3 100644 --- a/npc/scripts_mapflags.conf +++ b/npc/scripts_mapflags.conf @@ -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 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 6a51ee5f94..65363f5275 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -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 diff --git a/src/map/clif.c b/src/map/clif.c index d228d79b2c..59a9acd8f4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -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); diff --git a/src/map/map.h b/src/map/map.h index ab69142579..989a2bf3a0 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -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 diff --git a/src/map/npc.c b/src/map/npc.c index 88053ceb87..90b3967741 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -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]; diff --git a/src/map/pc.c b/src/map/pc.c index daa42222b6..95ef035758 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -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 *------------------------------------------*/ diff --git a/src/map/pc.h b/src/map/pc.h index a415fc69bc..5554acb496 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -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); diff --git a/src/map/script.c b/src/map/script.c index bb94701851..b180a635b2 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -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: { diff --git a/src/map/script_constants.h b/src/map/script_constants.h index f15c804f60..a87e07865b 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -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);