Added clan emblems to the NPCs (#2221)

* Added clan emblems to the NPCs
* Partial merge of/based on idathena/trunk@1f84c5d
Thanks to @exneval
This commit is contained in:
Lemongrass3110 2017-06-30 18:31:06 +02:00 committed by Aleos
parent a8e4c83ef1
commit 45e91e2a3a
7 changed files with 255 additions and 139 deletions

View File

@ -7,8 +7,24 @@
//= 1.0 Initial release. [Lemongrass]
//= 1.1 iRO translation. [RagnarokNova]
//= 1.2 Dialogue cleanup. [Aleos]
//= 1.3 Added clan helper. [exneval]
//============================================================
prontera,138,183,7 script Clan Helper 703,{
mes "[Clan Helper]";
mes "Do you want to build connections without being in a guild?";
next;
mes "[Clan Helper]";
mes "Can't find the perfect guild for yourself?";
next;
mes "[Clan Helper]";
mes "You can join or leave clans freely! Just join!";
next;
mes "[Clan Helper]";
mes "Now, come on in and meet the masters of the Kingdom's best clans!";
close;
}
prt_in,33,114,5 script Raffam Oranpere 10058,{
cutin "laperm01.bmp", 2;
mes "[Raffam Oranpere]";
@ -145,6 +161,10 @@ prt_in,33,114,5 script Raffam Oranpere 10058,{
close2;
cutin "", 255;
end;
OnInit:
sc_start2 SC_SWORDCLAN, -1, 0, SWORDCLAN, 10000, SCSTART_NOAVOID, getnpcid(0);
end;
}
prt_in,35,114,5 script Devon Aire 10059,{
@ -308,6 +328,10 @@ prt_in,35,114,5 script Devon Aire 10059,{
close2;
cutin "", 255;
end;
OnInit:
sc_start2 SC_ARCWANDCLAN, -1, 0, ARCWANDCLAN, 10000, SCSTART_NOAVOID, getnpcid(0);
end;
}
prt_in,37,114,5 script Berman Aire 10060,{
@ -448,6 +472,10 @@ prt_in,37,114,5 script Berman Aire 10060,{
close2;
cutin "", 255;
end;
OnInit:
sc_start2 SC_GOLDENMACECLAN, -1, 0, GOLDENMACECLAN, 10000, SCSTART_NOAVOID, getnpcid(0);
end;
}
prt_in,39,114,5 script Shaam Rumi 10027,{
@ -597,4 +625,8 @@ prt_in,39,114,5 script Shaam Rumi 10027,{
close2;
cutin "", 255;
end;
OnInit:
sc_start2 SC_CROSSBOWCLAN, -1, 0, CROSSBOWCLAN, 10000, SCSTART_NOAVOID, getnpcid(0);
end;
}

View File

@ -1484,7 +1484,7 @@ int clif_spawn(struct block_list *bl)
clif_spiritcharm(sd);
if (sd->status.robe)
clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
clif_efst_status_change_sub(sd, bl, AREA);
clif_efst_status_change_sub(bl, bl, AREA);
clif_hat_effects(sd,bl,AREA);
}
break;
@ -1504,6 +1504,7 @@ int clif_spawn(struct block_list *bl)
clif_specialeffect(&nd->bl,423,AREA);
else if( nd->size == SZ_MEDIUM )
clif_specialeffect(&nd->bl,421,AREA);
clif_efst_status_change_sub(bl, bl, AREA);
}
break;
case BL_PET:
@ -4660,7 +4661,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
clif_sendbgemblem_single(sd->fd,tsd);
if ( tsd->status.robe )
clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF);
clif_efst_status_change_sub(sd, bl, SELF);
clif_efst_status_change_sub(&sd->bl, bl, SELF);
clif_hat_effects(sd,bl,SELF);
}
break;
@ -4677,6 +4678,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
clif_specialeffect_single(bl,423,sd->fd);
else if( nd->size == SZ_MEDIUM )
clif_specialeffect_single(bl,421,sd->fd);
clif_efst_status_change_sub(&sd->bl, bl, SELF);
}
break;
case BL_MOB:
@ -6050,24 +6052,38 @@ void clif_status_change(struct block_list *bl, int type, int flag, int tick, int
/**
* Send any active EFST to those around.
* @param sd: Player to send the packet to
* @param tbl: Unit to send the packet to
* @param bl: Objects walking into view
* @param target: Client send type
*/
void clif_efst_status_change_sub(struct map_session_data *sd, struct block_list *bl, enum send_target target) {
struct map_session_data *tsd = NULL;
void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target) {
unsigned char i;
struct sc_display_entry **sc_display;
unsigned char sc_display_count;
nullpo_retv(sd);
nullpo_retv(bl);
if (target == SELF)
tsd = (TBL_PC *)bl;
else
tsd = sd;
switch( bl->type ){
case BL_PC: {
struct map_session_data* sd = (struct map_session_data*)bl;
for (i = 0; i < tsd->sc_display_count; i++) {
enum sc_type type = tsd->sc_display[i]->type;
sc_display = sd->sc_display;
sc_display_count = sd->sc_display_count;
}
break;
case BL_NPC: {
struct npc_data* nd = (struct npc_data*)bl;
sc_display = nd->sc_display;
sc_display_count = nd->sc_display_count;
}
break;
default:
return;
}
for (i = 0; i < sc_display_count; i++) {
enum sc_type type = sc_display[i]->type;
struct status_change *sc = status_get_sc(bl);
const struct TimerData *td = (sc && sc->data[type] ? get_timer(sc->data[type]->timer) : NULL);
int tick = 0;
@ -6075,9 +6091,9 @@ void clif_efst_status_change_sub(struct map_session_data *sd, struct block_list
if (td)
tick = DIFF_TICK(td->tick, gettick());
#if PACKETVER > 20120418
clif_efst_status_change((target == SELF) ? &sd->bl : bl, bl->id, target, StatusIconChangeTable[type], tick, tsd->sc_display[i]->val1, tsd->sc_display[i]->val2, tsd->sc_display[i]->val3);
clif_efst_status_change(tbl, bl->id, target, StatusIconChangeTable[type], tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3);
#else
clif_status_change_sub(&sd->bl, bl->id, StatusIconChangeTable[type], 1, tick, tsd->sc_display[i]->val1, tsd->sc_display[i]->val2, tsd->sc_display[i]->val3, target);
clif_status_change_sub(tbl, bl->id, StatusIconChangeTable[type], 1, tick, sc_display[i]->val1, sc_display[i]->val2, sc_display[i]->val3, target);
#endif
}
}
@ -9393,7 +9409,7 @@ void clif_refresh(struct map_session_data *sd)
clif_clearunit_single(sd->bl.id,CLR_DEAD,sd->fd);
else
clif_changed_dir(&sd->bl, SELF);
clif_efst_status_change_sub(sd,&sd->bl,SELF);
clif_efst_status_change_sub(&sd->bl,&sd->bl,SELF);
//Issue #2143
//Cancel Trading State

View File

@ -676,7 +676,7 @@ void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_targe
#define clif_status_load(bl, type, flag) clif_status_change((bl), (type), (flag), 0, 0, 0, 0)
void clif_status_change(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3);
void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, int tick, int val1, int val2, int val3);
void clif_efst_status_change_sub(struct map_session_data *sd, struct block_list *bl, enum send_target target);
void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target);
void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len);
void clif_wis_end(int fd, int result);

View File

@ -2079,6 +2079,7 @@ void npc_unload_duplicates(struct npc_data* nd)
int npc_unload(struct npc_data* nd, bool single) {
nullpo_ret(nd);
status_change_clear(&nd->bl, 1);
npc_remove_map(nd);
map_deliddb(&nd->bl);
if( single )
@ -2160,6 +2161,15 @@ int npc_unload(struct npc_data* nd, bool single) {
}
if( nd->u.scr.guild_id )
guild_flag_remove(nd);
if( nd->sc_display_count ){
unsigned char i;
for( i = 0; i < nd->sc_display_count; i++ )
ers_free(npc_sc_display_ers, nd->sc_display[i]);
nd->sc_display_count = 0;
aFree(nd->sc_display);
nd->sc_display = NULL;
}
}
script_stop_sleeptimers(nd->bl.id);
@ -2390,6 +2400,28 @@ bool npc_viewisid(const char * viewid)
return true;
}
/**
* Create a bare NPC object.
* @param m: Map ID
* @param x: X location
* @param y: Y location
* @return npc_data
*/
struct npc_data *npc_create_npc(int16 m, int16 x, int16 y){
struct npc_data *nd;
CREATE(nd, struct npc_data, 1);
nd->bl.id = npc_get_new_npc_id();
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
nd->sc_display = NULL;
nd->sc_display_count = 0;
return nd;
}
/**
* Add then display an npc warp on map
* @param name : warp unique name
@ -2408,13 +2440,8 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
int i, flag = 0;
struct npc_data *nd;
CREATE(nd, struct npc_data, 1);
nd->bl.id = npc_get_new_npc_id();
nd = npc_create_npc(from_mapid, from_x, from_y);
map_addnpc(from_mapid, nd);
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = from_mapid;
nd->bl.x = from_x;
nd->bl.y = from_y;
safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname));
if (npc_name2id(nd->exname) != NULL)
@ -2495,14 +2522,8 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
ShowWarning("npc_parse_warp: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
}
CREATE(nd, struct npc_data, 1);
nd->bl.id = npc_get_new_npc_id();
nd = npc_create_npc(m, x, y);
map_addnpc(m, nd);
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
npc_parsename(nd, w3, start, buffer, filepath);
if (!battle_config.warp_point_debug)
@ -2645,8 +2666,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
break;
}
CREATE(nd, struct npc_data, 1);
nd = npc_create_npc(m, x, y);
nd->u.shop.count = 0;
while ( p ) {
unsigned short nameid2, qty = 0;
@ -2740,11 +2760,6 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
nd->u.shop.discount = is_discount;
}
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
nd->bl.id = npc_get_new_npc_id();
npc_parsename(nd, w3, start, buffer, filepath);
nd->class_ = m == -1 ? -1 : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
@ -2967,7 +2982,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
db_clear(label_db); // not needed anymore, so clear the db
}
CREATE(nd, struct npc_data, 1);
nd = npc_create_npc(m, x, y);
if( sscanf(w4, "%*[^,],%6hd,%6hd", &xs, &ys) == 2 )
{// OnTouch area defined
@ -2980,12 +2995,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
nd->u.scr.ys = -1;
}
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
npc_parsename(nd, w3, start, buffer, filepath);
nd->bl.id = npc_get_new_npc_id();
nd->class_ = m == -1 ? -1 : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->u.scr.script = script;
@ -3112,14 +3122,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
return end;// next line, try to continue
}
CREATE(nd, struct npc_data, 1);
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
nd = npc_create_npc(m, x, y);
npc_parsename(nd, w3, start, buffer, filepath);
nd->bl.id = npc_get_new_npc_id();
nd->class_ = m == -1 ? -1 : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->src_id = src_id;
@ -3233,13 +3237,8 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
return 1;
}
CREATE(wnd, struct npc_data, 1);
wnd->bl.id = npc_get_new_npc_id();
wnd = npc_create_npc(m, snd->bl.x, snd->bl.y);
map_addnpc(m, wnd);
wnd->bl.prev = wnd->bl.next = NULL;
wnd->bl.m = m;
wnd->bl.x = snd->bl.x;
wnd->bl.y = snd->bl.y;
safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
wnd->class_ = WARP_CLASS;
@ -4656,6 +4655,7 @@ void do_final_npc(void) {
NPCMarketDB->destroy(NPCMarketDB, npc_market_free);
#endif
ers_destroy(timer_event_ers);
ers_destroy(npc_sc_display_ers);
npc_clearsrcfile();
}
@ -4716,7 +4716,8 @@ void do_init_npc(void){
npc_market_fromsql();
#endif
timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
timer_event_ers = ers_new(sizeof(struct timer_event_data),"npc.c::timer_event_ers",ERS_OPT_NONE);
npc_sc_display_ers = ers_new(sizeof(struct sc_display_entry), "npc.c:npc_sc_display_ers", ERS_OPT_NONE);
// process all npc files
ShowStatus("Loading NPCs...\r");

View File

@ -96,8 +96,13 @@ struct npc_data {
int spawn_timer;
} tomb;
} u;
struct sc_display_entry **sc_display;
unsigned char sc_display_count;
};
struct eri *npc_sc_display_ers;
#define START_NPC_NUM 110000000
enum actor_classes

View File

@ -1278,61 +1278,61 @@ void initChangeTables(void)
#endif
/* StatusDisplayType Table [Ind] */
StatusDisplayType[SC_ALL_RIDING] = true;
StatusDisplayType[SC_PUSH_CART] = true;
StatusDisplayType[SC_SPHERE_1] = true;
StatusDisplayType[SC_SPHERE_2] = true;
StatusDisplayType[SC_SPHERE_3] = true;
StatusDisplayType[SC_SPHERE_4] = true;
StatusDisplayType[SC_SPHERE_5] = true;
StatusDisplayType[SC_CAMOUFLAGE] = true;
StatusDisplayType[SC_STEALTHFIELD] = true;
StatusDisplayType[SC_DUPLELIGHT] = true;
StatusDisplayType[SC_ORATIO] = true;
StatusDisplayType[SC_FREEZING] = true;
StatusDisplayType[SC_VENOMIMPRESS] = true;
StatusDisplayType[SC_HALLUCINATIONWALK] = true;
StatusDisplayType[SC_ROLLINGCUTTER] = true;
StatusDisplayType[SC_BANDING] = true;
StatusDisplayType[SC_CRYSTALIZE] = true;
StatusDisplayType[SC_DEEPSLEEP] = true;
StatusDisplayType[SC_CURSEDCIRCLE_ATKER] = true;
StatusDisplayType[SC_CURSEDCIRCLE_TARGET] = true;
StatusDisplayType[SC_NETHERWORLD] = true;
StatusDisplayType[SC_VOICEOFSIREN] = true;
StatusDisplayType[SC_BLOODSUCKER] = true;
StatusDisplayType[SC__SHADOWFORM] = true;
StatusDisplayType[SC__MANHOLE] = true;
StatusDisplayType[SC_JYUMONJIKIRI] = true;
StatusDisplayType[SC_AKAITSUKI] = true;
StatusDisplayType[SC_MONSTER_TRANSFORM] = true;
StatusDisplayType[SC_ACTIVE_MONSTER_TRANSFORM] = true;
StatusDisplayType[SC_DARKCROW] = true;
StatusDisplayType[SC_OFFERTORIUM] = true;
StatusDisplayType[SC_TELEKINESIS_INTENSE] = true;
StatusDisplayType[SC_UNLIMIT] = true;
StatusDisplayType[SC_ILLUSIONDOPING] = true;
StatusDisplayType[SC_C_MARKER] = true;
StatusDisplayType[SC_ANTI_M_BLAST] = true;
StatusDisplayType[SC_SPRITEMABLE] = true;
StatusDisplayType[SC_ALL_RIDING] = BL_PC;
StatusDisplayType[SC_PUSH_CART] = BL_PC;
StatusDisplayType[SC_SPHERE_1] = BL_PC;
StatusDisplayType[SC_SPHERE_2] = BL_PC;
StatusDisplayType[SC_SPHERE_3] = BL_PC;
StatusDisplayType[SC_SPHERE_4] = BL_PC;
StatusDisplayType[SC_SPHERE_5] = BL_PC;
StatusDisplayType[SC_CAMOUFLAGE] = BL_PC;
StatusDisplayType[SC_STEALTHFIELD] = BL_PC;
StatusDisplayType[SC_DUPLELIGHT] = BL_PC;
StatusDisplayType[SC_ORATIO] = BL_PC;
StatusDisplayType[SC_FREEZING] = BL_PC;
StatusDisplayType[SC_VENOMIMPRESS] = BL_PC;
StatusDisplayType[SC_HALLUCINATIONWALK] = BL_PC;
StatusDisplayType[SC_ROLLINGCUTTER] = BL_PC;
StatusDisplayType[SC_BANDING] = BL_PC;
StatusDisplayType[SC_CRYSTALIZE] = BL_PC;
StatusDisplayType[SC_DEEPSLEEP] = BL_PC;
StatusDisplayType[SC_CURSEDCIRCLE_ATKER] = BL_PC;
StatusDisplayType[SC_CURSEDCIRCLE_TARGET] = BL_PC;
StatusDisplayType[SC_NETHERWORLD] = BL_PC;
StatusDisplayType[SC_VOICEOFSIREN] = BL_PC;
StatusDisplayType[SC_BLOODSUCKER] = BL_PC;
StatusDisplayType[SC__SHADOWFORM] = BL_PC;
StatusDisplayType[SC__MANHOLE] = BL_PC;
StatusDisplayType[SC_JYUMONJIKIRI] = BL_PC;
StatusDisplayType[SC_AKAITSUKI] = BL_PC;
StatusDisplayType[SC_MONSTER_TRANSFORM] = BL_PC;
StatusDisplayType[SC_ACTIVE_MONSTER_TRANSFORM] = BL_PC;
StatusDisplayType[SC_DARKCROW] = BL_PC;
StatusDisplayType[SC_OFFERTORIUM] = BL_PC;
StatusDisplayType[SC_TELEKINESIS_INTENSE] = BL_PC;
StatusDisplayType[SC_UNLIMIT] = BL_PC;
StatusDisplayType[SC_ILLUSIONDOPING] = BL_PC;
StatusDisplayType[SC_C_MARKER] = BL_PC;
StatusDisplayType[SC_ANTI_M_BLAST] = BL_PC;
StatusDisplayType[SC_SPRITEMABLE] = BL_PC;
// Costumes
StatusDisplayType[SC_MOONSTAR] = true;
StatusDisplayType[SC_SUPER_STAR] = true;
StatusDisplayType[SC_STRANGELIGHTS] = true;
StatusDisplayType[SC_DECORATION_OF_MUSIC] = true;
StatusDisplayType[SC_LJOSALFAR] = true;
StatusDisplayType[SC_MERMAID_LONGING] = true;
StatusDisplayType[SC_HAT_EFFECT] = true;
StatusDisplayType[SC_FLOWERSMOKE] = true;
StatusDisplayType[SC_FSTONE] = true;
StatusDisplayType[SC_HAPPINESS_STAR] = true;
StatusDisplayType[SC_MAPLE_FALLS] = true;
StatusDisplayType[SC_TIME_ACCESSORY] = true;
StatusDisplayType[SC_MAGICAL_FEATHER] = true;
StatusDisplayType[SC_MOONSTAR] = BL_PC;
StatusDisplayType[SC_SUPER_STAR] = BL_PC;
StatusDisplayType[SC_STRANGELIGHTS] = BL_PC;
StatusDisplayType[SC_DECORATION_OF_MUSIC] = BL_PC;
StatusDisplayType[SC_LJOSALFAR] = BL_PC;
StatusDisplayType[SC_MERMAID_LONGING] = BL_PC;
StatusDisplayType[SC_HAT_EFFECT] = BL_PC;
StatusDisplayType[SC_FLOWERSMOKE] = BL_PC;
StatusDisplayType[SC_FSTONE] = BL_PC;
StatusDisplayType[SC_HAPPINESS_STAR] = BL_PC;
StatusDisplayType[SC_MAPLE_FALLS] = BL_PC;
StatusDisplayType[SC_TIME_ACCESSORY] = BL_PC;
StatusDisplayType[SC_MAGICAL_FEATHER] = BL_PC;
// Clans
StatusDisplayType[SC_CLAN_INFO] = true;
StatusDisplayType[SC_CLAN_INFO] = BL_PC|BL_NPC;
/* StatusChangeState (SCS_) NOMOVE */
StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
@ -8077,74 +8077,135 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
}
/**
* Applies SC effect to the player
* @param sd: Source to apply effect [PC]
* Applies SC effect
* @param bl: Source to apply effect
* @param type: Status change (SC_*)
* @param dval1~3: Depends on type of status change
* Author: Ind
*/
void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
void status_display_add(struct block_list *bl, enum sc_type type, int dval1, int dval2, int dval3) {
struct eri *eri;
struct sc_display_entry **sc_display;
struct sc_display_entry ***sc_display_ptr;
struct sc_display_entry *entry;
int i;
unsigned char sc_display_count;
unsigned char *sc_display_count_ptr;
for( i = 0; i < sd->sc_display_count; i++ ) {
if( sd->sc_display[i]->type == type )
nullpo_retv(bl);
switch( bl->type ){
case BL_PC: {
struct map_session_data* sd = (struct map_session_data*)bl;
sc_display_ptr = &sd->sc_display;
sc_display_count_ptr = &sd->sc_display_count;
eri = pc_sc_display_ers;
}
break;
case BL_NPC: {
struct npc_data* nd = (struct npc_data*)bl;
sc_display_ptr = &nd->sc_display;
sc_display_count_ptr = &nd->sc_display_count;
eri = npc_sc_display_ers;
}
break;
default:
return;
}
if( i != sd->sc_display_count ) {
sd->sc_display[i]->val1 = dval1;
sd->sc_display[i]->val2 = dval2;
sd->sc_display[i]->val3 = dval3;
sc_display = *sc_display_ptr;
sc_display_count = *sc_display_count_ptr;
ARR_FIND(0, sc_display_count, i, sc_display[i]->type == type);
if( i != sc_display_count ) {
sc_display[i]->val1 = dval1;
sc_display[i]->val2 = dval2;
sc_display[i]->val3 = dval3;
return;
}
entry = ers_alloc(pc_sc_display_ers, struct sc_display_entry);
entry = ers_alloc(eri, struct sc_display_entry);
entry->type = type;
entry->val1 = dval1;
entry->val2 = dval2;
entry->val3 = dval3;
RECREATE(sd->sc_display, struct sc_display_entry *, ++sd->sc_display_count);
sd->sc_display[sd->sc_display_count - 1] = entry;
RECREATE(sc_display, struct sc_display_entry *, ++sc_display_count);
sc_display[sc_display_count - 1] = entry;
*sc_display_ptr = sc_display;
*sc_display_count_ptr = sc_display_count;
}
/**
* Removes SC effect of the player
* @param sd: Source to remove effect [PC]
* Removes SC effect
* @param bl: Source to remove effect
* @param type: Status change (SC_*)
* Author: Ind
*/
void status_display_remove(struct map_session_data *sd, enum sc_type type) {
void status_display_remove(struct block_list *bl, enum sc_type type) {
struct eri *eri;
struct sc_display_entry **sc_display;
struct sc_display_entry ***sc_display_ptr;
int i;
unsigned char sc_display_count;
unsigned char *sc_display_count_ptr;
for( i = 0; i < sd->sc_display_count; i++ ) {
if( sd->sc_display[i]->type == type )
nullpo_retv(bl);
switch( bl->type ){
case BL_PC: {
struct map_session_data* sd = (struct map_session_data*)bl;
sc_display_ptr = &sd->sc_display;
sc_display_count_ptr = &sd->sc_display_count;
eri = pc_sc_display_ers;
}
break;
case BL_NPC: {
struct npc_data* nd = (struct npc_data*)bl;
sc_display_ptr = &nd->sc_display;
sc_display_count_ptr = &nd->sc_display_count;
eri = npc_sc_display_ers;
}
break;
default:
return;
}
if( i != sd->sc_display_count ) {
sc_display = *sc_display_ptr;
sc_display_count = *sc_display_count_ptr;
ARR_FIND(0, sc_display_count, i, sc_display[i]->type == type);
if( i != sc_display_count ) {
int cursor;
ers_free(pc_sc_display_ers, sd->sc_display[i]);
sd->sc_display[i] = NULL;
ers_free(eri, sc_display[i]);
sc_display[i] = NULL;
/* The all-mighty compact-o-matic */
for( i = 0, cursor = 0; i < sd->sc_display_count; i++ ) {
if( sd->sc_display[i] == NULL )
for( i = 0, cursor = 0; i < sc_display_count; i++ ) {
if( sc_display[i] == NULL )
continue;
if( i != cursor )
sd->sc_display[cursor] = sd->sc_display[i];
sc_display[cursor] = sc_display[i];
cursor++;
}
if( !(sd->sc_display_count = cursor) ) {
aFree(sd->sc_display);
sd->sc_display = NULL;
if( !(sc_display_count = cursor) ) {
aFree(sc_display);
sc_display = NULL;
}
*sc_display_ptr = sc_display;
*sc_display_count_ptr = sc_display_count;
}
}
@ -8181,7 +8242,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
if( !sc )
return 0; // Unable to receive status changes
if( status_isdead(bl) && ( type != SC_NOCHAT && type != SC_JAILED ) ) // SC_NOCHAT and SC_JAILED should work even on dead characters
if( bl->type != BL_NPC && status_isdead(bl) && ( type != SC_NOCHAT && type != SC_JAILED ) ) // SC_NOCHAT and SC_JAILED should work even on dead characters
return 0;
if (status_change_isDisabledOnMap(type, bl->m))
@ -10946,7 +11007,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
}
/* [Ind] */
if (sd && StatusDisplayType[type]) {
if (StatusDisplayType[type]&bl->type) {
int dval1 = 0, dval2 = 0, dval3 = 0;
switch (type) {
@ -10962,7 +11023,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
dval1 = val1;
break;
}
status_display_add(sd,type,dval1,dval2,dval3);
status_display_add(bl,type,dval1,dval2,dval3);
clif_efst_status_change_sub(bl, bl, AREA);
}
// Those that make you stop attacking/walking....
@ -11696,8 +11758,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->data[type] = NULL;
if (sd && StatusDisplayType[type])
status_display_remove(sd,type);
if (StatusDisplayType[type]&bl->type)
status_display_remove(bl,type);
vd = status_get_viewdata(bl);
calc_flag = StatusChangeFlagTable[type];

View File

@ -2075,7 +2075,7 @@ unsigned int StatusChangeFlagTable[SC_MAX]; /// status -> flags
int StatusSkillChangeTable[SC_MAX]; /// status -> skill
int StatusRelevantBLTypes[SI_MAX]; /// "icon" -> enum bl_type (for clif->status_change to identify for which bl types to send packets)
unsigned int StatusChangeStateTable[SC_MAX]; /// status -> flags
bool StatusDisplayType[SC_MAX];
unsigned int StatusDisplayType[SC_MAX];
///For holding basic status (which can be modified by status changes)
struct status_data {