Status change packet cleanup

* fixed a couple typos
 * replaced duplicate function clif_status_load with a macro
 * normalized and documented status change table related getter abstraction
 * put some checks that were previously in multiple places into clif_status_change
 * packets are now used as they are on official servers:
  - ZC_MSG_STATE_CHANGE for ending statuses and starting them on non-pcs
  - ZC_MSG_STATE_CHANGE2 for starting *all* statuses on players
  - tick = 9999 for statuses of indeterminate duration
  - for non-pc units, a packet is only sent if it has a visual impact on the client; if you notice any missing visual effects, please report them!
 * fixed hidden GM characters leaking certain status packets
 * fixed hidden GM characters not displaying timers for newly gained statuses
 * fixed status end packet never being sent for non-pc, non-mercenary units
 * fixed SC_CLOAKING displaying a time bar on the client
 * fixed tick being an unsigned int, yet used as a signed int
 * removed hard-coded status length exceptions in clif_status_change

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15688 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
lordttseven 2012-03-15 10:30:42 +00:00
parent 2a9d39e36f
commit a58fc65984
6 changed files with 92 additions and 72 deletions

View File

@ -1592,7 +1592,7 @@ void clif_move(struct unit_data *ud)
return; //This performance check is needed to keep GM-hidden objects from being notified to bots. return; //This performance check is needed to keep GM-hidden objects from being notified to bots.
/** /**
* Hide NPC from maya puprle card. * Hide NPC from maya purple card.
**/ **/
if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE)) if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
return; return;
@ -4019,7 +4019,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
return; return;
/** /**
* Hide NPC from maya puprle card. * Hide NPC from maya purple card.
**/ **/
if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE)) if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
return; return;
@ -5230,69 +5230,42 @@ void clif_cooking_list(struct map_session_data *sd, int trigger)
} }
} }
/*==========================================
* Sends a status change packet to the object only, used for loading status changes. [Skotlex]
*------------------------------------------*/
int clif_status_load(struct block_list *bl,int type, int flag)
{
int fd;
if (type == SI_BLANK) //It shows nothing on the client...
return 0;
if (bl->type != BL_PC)
return 0;
fd = ((struct map_session_data*)bl)->fd;
WFIFOHEAD(fd,packet_len(0x196));
WFIFOW(fd,0)=0x0196;
WFIFOW(fd,2)=type;
WFIFOL(fd,4)=bl->id;
WFIFOB(fd,8)=flag; //Status start
WFIFOSET(fd, packet_len(0x196));
return 0;
}
/// Notifies clients of a status change. /// Notifies clients of a status change.
/// 0196 <index>.W <id>.L <state>.B (ZC_MSG_STATE_CHANGE) /// 0196 <index>.W <id>.L <state>.B (ZC_MSG_STATE_CHANGE) [used for ending status changes and starting them on non-pc units (when needed)]
/// 043f <index>.W <id>.L <state>.B <remain msec>.L { <val>.L }*3 (ZC_MSG_STATE_CHANGE2) /// 043f <index>.W <id>.L <state>.B <remain msec>.L { <val>.L }*3 (ZC_MSG_STATE_CHANGE2) [used exclusively for starting statuses on pcs]
void clif_status_change(struct block_list *bl,int type,int flag,unsigned int tick,int val1, int val2, int val3) void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3)
{ {
unsigned char buf[32]; unsigned char buf[32];
struct map_session_data *sd;
if (type == SI_BLANK) //It shows nothing on the client... if (type == SI_BLANK) //It shows nothing on the client...
return; return;
nullpo_retv(bl); nullpo_retv(bl);
if (type == SI_BLANK || type == SI_MAXIMIZEPOWER || type == SI_RIDING || sd = BL_CAST(BL_PC, bl);
type == SI_FALCON || type == SI_TRICKDEAD || type == SI_BROKENARMOR ||
type == SI_BROKENWEAPON || type == SI_WEIGHT50 || type == SI_WEIGHT90 ||
type == SI_TENSIONRELAX || type == SI_LANDENDOW || type == SI_AUTOBERSERK ||
type == SI_BUMP || type == SI_READYSTORM || type == SI_READYDOWN ||
type == SI_READYTURN || type == SI_READYCOUNTER || type == SI_DODGE ||
type == SI_DEVIL || type == SI_NIGHT || type == SI_INTRAVISION ||
type == SI_BANDING)
tick=0;
// TODO: 0x43f PACKETVER? if (!(status_type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client
if( battle_config.display_status_timers && tick>0 ) return;
if(flag && battle_config.display_status_timers && sd)
WBUFW(buf,0)=0x43f; WBUFW(buf,0)=0x43f;
else else
WBUFW(buf,0)=0x196; WBUFW(buf,0)=0x196;
WBUFW(buf,2)=type; WBUFW(buf,2)=type;
WBUFL(buf,4)=bl->id; WBUFL(buf,4)=bl->id;
WBUFB(buf,8)=flag; WBUFB(buf,8)=flag;
if( battle_config.display_status_timers && tick>0 ) if(flag && battle_config.display_status_timers && sd)
{ {
WBUFL(buf,9)=tick; if (tick <= 0)
tick = 9999; // this is indeed what official servers do
WBUFL(buf,9) = tick;
WBUFL(buf,13) = val1; WBUFL(buf,13) = val1;
WBUFL(buf,17) = val2; WBUFL(buf,17) = val2;
WBUFL(buf,21) = val3; WBUFL(buf,21) = val3;
} }
clif_send(buf,packet_len(WBUFW(buf,0)),bl,AREA); clif_send(buf,packet_len(WBUFW(buf,0)),bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA);
} }

View File

@ -445,8 +445,8 @@ void clif_combo_delay(struct block_list *bl,int wait);
void clif_bladestop(struct block_list *src, int dst_id, int active); void clif_bladestop(struct block_list *src, int dst_id, int active);
void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target target); void clif_changemapcell(int fd, int m, int x, int y, int type, enum send_target target);
int clif_status_load(struct block_list *bl,int type, int flag); #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,unsigned int tick,int val1, int val2, int val3); void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3);
void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len); void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len);
void clif_wis_end(int fd, int flag); void clif_wis_end(int fd, int flag);

View File

@ -282,7 +282,7 @@ int pc_banding(struct map_session_data *sd, short skill_lv) {
if( (sc = status_get_sc(&sd->bl)) != NULL && sc->data[SC_BANDING] ) if( (sc = status_get_sc(&sd->bl)) != NULL && sc->data[SC_BANDING] )
{ {
sc->data[SC_BANDING]->val2 = 0; // Reset the counter sc->data[SC_BANDING]->val2 = 0; // Reset the counter
status_calc_bl(&sd->bl,StatusChangeFlagTable[SC_BANDING]); status_calc_bl(&sd->bl, status_sc2scb_flag(SC_BANDING));
} }
return 0; return 0;
} }
@ -325,7 +325,7 @@ int pc_banding(struct map_session_data *sd, short skill_lv) {
if( (sc = status_get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] ) if( (sc = status_get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] )
{ {
sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self. sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
status_calc_bl(&bsd->bl,StatusChangeFlagTable[SC_BANDING]); // Set atk and def. status_calc_bl(&bsd->bl, status_sc2scb_flag(SC_BANDING)); // Set atk and def.
} }
} }
} }

View File

@ -2737,7 +2737,7 @@ int skill_guildaura_sub (struct map_session_data* sd, int id, int strvit, int ag
if( sce->val3 != strvit || sce->val4 != agidex ) { if( sce->val3 != strvit || sce->val4 != agidex ) {
sce->val3 = strvit; sce->val3 = strvit;
sce->val4 = agidex; sce->val4 = agidex;
status_calc_bl(&sd->bl, StatusChangeFlagTable[SC_GUILDAURA]); status_calc_bl(&sd->bl, status_sc2scb_flag(SC_GUILDAURA));
} }
return 0; return 0;
} }

View File

@ -72,11 +72,17 @@ int current_equip_card_id; //To prevent card-stacking (from jA) [Skotlex]
//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only //we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
//to avoid cards exploits //to avoid cards exploits
static sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status static sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status
static int StatusIconChangeTable[SC_MAX]; // status -> icon static int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
unsigned long StatusChangeFlagTable[SC_MAX]; // status -> flags static unsigned int StatusChangeFlagTable[SC_MAX]; // status -> flags
static int StatusSkillChangeTable[SC_MAX]; // status -> skill static int StatusSkillChangeTable[SC_MAX]; // status -> skill
static int StatusRelevantBLTypes[SI_MAX]; // "icon" -> enum bl_type (for clif_status_change to identify for which bl types to send packets)
/**
* Returns the status change associated with a skill.
* @param skill The skill to look up
* @return The status registered for this skill
**/
sc_type status_skill2sc(int skill) sc_type status_skill2sc(int skill)
{ {
int sk = skill_get_index(skill); int sk = skill_get_index(skill);
@ -87,17 +93,55 @@ sc_type status_skill2sc(int skill)
return SkillStatusChangeTable[sk]; return SkillStatusChangeTable[sk];
} }
/**
* Returns the FIRST skill (in order of definition in initChangeTables) to use a given status change.
* Utilized for various duration lookups. Use with caution!
* @param sc The status to look up
* @return A skill associated with the status
**/
int status_sc2skill(sc_type sc) int status_sc2skill(sc_type sc)
{ {
if( sc < 0 || sc >= SC_MAX ) { if( sc < 0 || sc >= SC_MAX ) {
ShowError("status_skill2sc: Unsupported status change id %d\n", sc); ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
return 0; return 0;
} }
return StatusSkillChangeTable[sc]; return StatusSkillChangeTable[sc];
} }
/**
* Returns the status calculation flag associated with a given status change.
* @param sc The status to look up
* @return The scb_flag registered for this status (see enum scb_flag)
**/
unsigned int status_sc2scb_flag(sc_type sc)
{
if( sc < 0 || sc >= SC_MAX ) {
ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
return SCB_NONE;
}
return StatusChangeFlagTable[sc];
}
/**
* Returns the bl types which require a status change packet to be sent for a given client status identifier.
* @param type The client-side status identifier to look up (see enum si_type)
* @return The bl types relevant to the type (see enum bl_type)
**/
int status_type2relevant_bl_types(int type)
{
if( type < 0 || type >= SI_MAX ) {
ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
return SI_BLANK;
}
return StatusRelevantBLTypes[type];
}
#define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE) #define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE)
// indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units
#define set_sc_with_vfx(skill, sc, icon, flag) set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) StatusRelevantBLTypes[(icon)] |= BL_SCEFFECT
static void set_sc(int skill, sc_type sc, int icon, unsigned int flag) static void set_sc(int skill, sc_type sc, int icon, unsigned int flag)
{ {
@ -128,6 +172,8 @@ void initChangeTables(void)
StatusIconChangeTable[i] = SI_BLANK; StatusIconChangeTable[i] = SI_BLANK;
for (i = 0; i < MAX_SKILL; i++) for (i = 0; i < MAX_SKILL; i++)
SkillStatusChangeTable[i] = SC_NONE; SkillStatusChangeTable[i] = SC_NONE;
for (i = 0; i < SI_MAX; i++)
StatusRelevantBLTypes[i] = BL_PC;
memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable)); memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable)); memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
@ -471,7 +517,7 @@ void initChangeTables(void)
/** /**
* GC Guillotine Cross * GC Guillotine Cross
**/ **/
set_sc( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE ); set_sc_with_vfx( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE );
set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE ); set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE );
set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE ); set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED ); set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
@ -485,7 +531,7 @@ void initChangeTables(void)
add_sc( AB_CANTO , SC_INCREASEAGI ); add_sc( AB_CANTO , SC_INCREASEAGI );
set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP ); set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
add_sc( AB_PRAEFATIO , SC_KYRIE ); add_sc( AB_PRAEFATIO , SC_KYRIE );
set_sc( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE ); set_sc_with_vfx( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE );
set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT ); set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT );
set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK ); set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK );
set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN ); set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN );
@ -496,7 +542,7 @@ void initChangeTables(void)
* Warlock * Warlock
**/ **/
add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON ); add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
set_sc( WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 ); set_sc_with_vfx( WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF ); set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF );
set_sc( WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_NONE ); set_sc( WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_NONE );
set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE ); set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
@ -512,7 +558,7 @@ void initChangeTables(void)
add_sc( RA_MAIZETRAP , SC_ELEMENTALCHANGE ); add_sc( RA_MAIZETRAP , SC_ELEMENTALCHANGE );
add_sc( RA_VERDURETRAP , SC_ELEMENTALCHANGE ); add_sc( RA_VERDURETRAP , SC_ELEMENTALCHANGE );
add_sc( RA_FIRINGTRAP , SC_BURNING ); add_sc( RA_FIRINGTRAP , SC_BURNING );
set_sc( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE ); set_sc_with_vfx( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE );
/** /**
* Mechanic * Mechanic
**/ **/
@ -552,7 +598,7 @@ void initChangeTables(void)
set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 ); set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 );
set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP ); set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP );
set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK ); set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
set_sc( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE ); set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
add_sc( SC_CHAOSPANIC , SC_CHAOS ); add_sc( SC_CHAOSPANIC , SC_CHAOS );
set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK ); set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
/** /**
@ -6344,7 +6390,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
clif_emotion(bl,E_SWT); clif_emotion(bl,E_SWT);
break; break;
case SC_MAXIMIZEPOWER: case SC_MAXIMIZEPOWER:
val2 = tick>0?tick:60000; tick_time = val2 = tick>0?tick:60000;
tick = -1; // duration sent to the client should be infinite
break; break;
case SC_EDP: // [Celest] case SC_EDP: // [Celest]
val2 = val1 + 2; //Chance to Poison enemies. val2 = val1 + 2; //Chance to Poison enemies.
@ -6620,7 +6667,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CLOAKING: case SC_CLOAKING:
if (!sd) //Monsters should be able to walk with no penalties. [Skotlex] if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
val1 = 10; val1 = 10;
val2 = tick>0?tick:60000; //SP consumption rate. tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
tick = -1; // duration sent to the client should be infinite
val3 = 0; // unused, previously walk speed adjustment val3 = 0; // unused, previously walk speed adjustment
//val4&1 signals the presence of a wall. //val4&1 signals the presence of a wall.
//val4&2 makes cloak not end on normal attacks [Skotlex] //val4&2 makes cloak not end on normal attacks [Skotlex]
@ -6708,6 +6756,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 12; //SP cost val2 = 12; //SP cost
val4 = 10000; //Decrease at 10secs intervals. val4 = 10000; //Decrease at 10secs intervals.
val3 = tick/val4; val3 = tick/val4;
tick = -1; // duration sent to the client should be infinite
tick_time = val4; // [GodLesZ] tick time tick_time = val4; // [GodLesZ] tick time
break; break;
case SC_PARRYING: case SC_PARRYING:
@ -7857,10 +7906,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag&=~SCB_DYE; calc_flag&=~SCB_DYE;
} }
if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER || bl->type == BL_MOB ) ) clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
else if( sd ) //Send packet to self otherwise (disguised player?)
clif_status_load(bl,StatusIconChangeTable[type],1);
/** /**
* used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first. * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
**/ **/
@ -8660,10 +8707,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
} }
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet. //On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) ) clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
else if (sd)
clif_status_load(bl,StatusIconChangeTable[type],0);
if( opt_flag&8 ) //bugreport:681 if( opt_flag&8 ) //bugreport:681
clif_changeoption2(bl); clif_changeoption2(bl);

View File

@ -13,8 +13,6 @@ struct status_change;
#define MAX_REFINE_BONUS 5 #define MAX_REFINE_BONUS 5
extern unsigned long StatusChangeFlagTable[];
// Status changes listing. These code are for use by the server. // Status changes listing. These code are for use by the server.
typedef enum sc_type { typedef enum sc_type {
@ -1152,6 +1150,8 @@ enum si_type {
SI_EARTH_INSIGNIA = 570, SI_EARTH_INSIGNIA = 570,
SI_EQUIPED_FLOOR = 571, SI_EQUIPED_FLOOR = 571,
SI_ALL_RIDING = 613,//awesome 571-613 gap, we're missing quite a few stuff here. SI_ALL_RIDING = 613,//awesome 571-613 gap, we're missing quite a few stuff here.
SI_MAX,
}; };
// JOINTBEAT stackable ailments // JOINTBEAT stackable ailments
@ -1333,7 +1333,8 @@ enum scb_flag
#define BL_CONSUME (BL_PC|BL_HOM|BL_MER) #define BL_CONSUME (BL_PC|BL_HOM|BL_MER)
//Define to determine who has regen //Define to determine who has regen
#define BL_REGEN (BL_PC|BL_HOM|BL_MER) #define BL_REGEN (BL_PC|BL_HOM|BL_MER)
//Define to determine who will receive a clif_status_change packet for effects that require one to display correctly
#define BL_SCEFFECT (BL_PC|BL_HOM|BL_MER|BL_MOB)
//Basic damage info of a weapon //Basic damage info of a weapon
//Required because players have two of these, one in status_data //Required because players have two of these, one in status_data
@ -1458,6 +1459,8 @@ struct status_change {
// for looking up associated data // for looking up associated data
sc_type status_skill2sc(int skill); sc_type status_skill2sc(int skill);
int status_sc2skill(sc_type sc); int status_sc2skill(sc_type sc);
unsigned int status_sc2scb_flag(sc_type sc);
int status_type2relevant_bl_types(int type);
int status_damage(struct block_list *src,struct block_list *target,int hp,int sp, int walkdelay, int flag); int status_damage(struct block_list *src,struct block_list *target,int hp,int sp, int walkdelay, int flag);
//Define for standard HP damage attacks. //Define for standard HP damage attacks.