summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c4551
1 files changed, 2451 insertions, 2100 deletions
diff --git a/src/map/status.c b/src/map/status.c
index a8771c0a5..9a274c080 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2,8 +2,8 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
- * Copyright (C) Athena Dev Teams
+ * Copyright (C) 2012-2020 Hercules Dev Team
+ * Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include "map/battle.h"
#include "map/chrif.h"
+#include "map/clan.h"
#include "map/clif.h"
#include "map/elemental.h"
#include "map/guild.h"
@@ -37,6 +38,7 @@
#include "map/path.h"
#include "map/pc.h"
#include "map/pet.h"
+#include "map/refine.h"
#include "map/script.h"
#include "map/skill.h"
#include "map/skill.h"
@@ -60,17 +62,18 @@
#include <string.h>
#include <time.h>
-struct status_interface status_s;
-struct s_status_dbs statusdbs;
+static struct status_interface status_s;
+static struct s_status_dbs statusdbs;
struct status_interface *status;
/**
-* 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_id) {
+ * Returns the status change associated with a skill.
+ * @param skill The skill to look up
+ * @return The status registered for this skill
+ */
+static sc_type status_skill2sc(int skill_id)
+{
int idx;
if( (idx = skill->get_index(skill_id)) == 0 ) {
ShowError("status_skill2sc: Unsupported skill id %d\n", skill_id);
@@ -80,12 +83,12 @@ sc_type status_skill2sc(int skill_id) {
}
/**
-* 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)
+ * 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
+ */
+static int status_sc2skill(sc_type sc)
{
if( sc < 0 || sc >= SC_MAX ) {
ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
@@ -96,11 +99,11 @@ int status_sc2skill(sc_type 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)
+ * 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)
+ */
+static 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);
@@ -111,21 +114,29 @@ unsigned int status_sc2scb_flag(sc_type 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);
+ * Returns the bl types which require a status change packet to be sent for a given client status identifier.
+ * @param type status identifier to look up (see enum sc_type)
+ * @return The bl types relevant to the type (see enum bl_type)
+ */
+static int status_get_sc_relevant_bl_types(enum sc_type type)
+{
+ if (type < 0 || type >= SC_MAX) {
+ ShowError("status_get_sc_relevant_bl_types: Unsupported type %d\n", type);
return BL_NUL;
}
- return status->dbs->RelevantBLTypes[type];
+ return status->dbs->IconChangeTable[type].relevant_bl_types;
}
-static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) {
+static int status_get_sc_icon(enum sc_type type)
+{
+ Assert_retr(SI_BLANK, type >= SC_NONE && type < SC_MAX);
+
+ return status->dbs->IconChangeTable[type].id;
+}
+
+static void status_set_sc(uint16 skill_id, sc_type sc, unsigned int flag)
+{
uint16 idx;
if( (idx = skill->get_index(skill_id)) == 0 ) {
ShowError("set_sc: Unsupported skill id %d\n", skill_id);
@@ -138,112 +149,110 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) {
if( status->dbs->SkillChangeTable[sc] == 0 )
status->dbs->SkillChangeTable[sc] = skill_id;
- if( status->dbs->IconChangeTable[sc] == SI_BLANK )
- status->dbs->IconChangeTable[sc] = icon;
status->dbs->ChangeFlagTable[sc] |= flag;
if( status->dbs->Skill2SCTable[idx] == SC_NONE )
status->dbs->Skill2SCTable[idx] = sc;
}
-void initChangeTables(void) {
-#define add_sc(skill,sc) set_sc((skill),(sc),SI_BLANK,SCB_NONE)
+static void initChangeTables(void)
+{
+#define add_sc(skill,sc) status->set_sc((skill),(sc),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) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->dbs->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0)
+#define set_sc_with_vfx(skill, sc, flag) do { status->set_sc((skill), (sc), (flag)); status->dbs->IconChangeTable[sc].relevant_bl_types |= BL_SCEFFECT; } while(0)
int i;
- for (i = 0; i < SC_MAX; i++)
- status->dbs->IconChangeTable[i] = SI_BLANK;
-
- for (i = 0; i < MAX_SKILL; i++)
+ for (i = 0; i < MAX_SKILL_DB; i++)
status->dbs->Skill2SCTable[i] = SC_NONE;
- for (i = 0; i < SI_MAX; i++)
- status->dbs->RelevantBLTypes[i] = BL_PC;
+ for (i = 0; i < SC_MAX; i++) {
+ status->dbs->IconChangeTable[i].id = SI_BLANK;
+ status->dbs->IconChangeTable[i].relevant_bl_types = BL_PC;
+ }
memset(status->dbs->SkillChangeTable, 0, sizeof(status->dbs->SkillChangeTable));
memset(status->dbs->ChangeFlagTable, 0, sizeof(status->dbs->ChangeFlagTable));
memset(status->dbs->DisplayType, 0, sizeof(status->dbs->DisplayType));
//First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
- set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
- set_sc( NPC_WIDEFREEZE , SC_FREEZE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
- set_sc( NPC_STUNATTACK , SC_STUN , SI_BLANK , SCB_NONE );
- set_sc( NPC_SLEEPATTACK , SC_SLEEP , SI_BLANK , SCB_NONE );
- set_sc( NPC_POISON , SC_POISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
- set_sc( NPC_CURSEATTACK , SC_CURSE , SI_BLANK , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
- set_sc( NPC_SILENCEATTACK , SC_SILENCE , SI_BLANK , SCB_NONE );
- set_sc( NPC_WIDECONFUSE , SC_CONFUSION , SI_BLANK , SCB_NONE );
- set_sc( NPC_BLINDATTACK , SC_BLIND , SI_BLANK , SCB_HIT|SCB_FLEE );
- set_sc( NPC_BLEEDING , SC_BLOODING , SI_BLOODING , SCB_REGEN );
- set_sc( NPC_POISON , SC_DPOISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
+ status->set_sc( NPC_PETRIFYATTACK , SC_STONE , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
+ status->set_sc( NPC_WIDEFREEZE , SC_FREEZE , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
+ status->set_sc( NPC_STUNATTACK , SC_STUN , SCB_NONE );
+ status->set_sc( NPC_SLEEPATTACK , SC_SLEEP , SCB_NONE );
+ status->set_sc( NPC_POISON , SC_POISON , SCB_DEF2|SCB_REGEN );
+ status->set_sc( NPC_CURSEATTACK , SC_CURSE , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
+ status->set_sc( NPC_SILENCEATTACK , SC_SILENCE , SCB_NONE );
+ status->set_sc( NPC_WIDECONFUSE , SC_CONFUSION , SCB_NONE );
+ status->set_sc( NPC_BLINDATTACK , SC_BLIND , SCB_HIT|SCB_FLEE );
+ status->set_sc( NPC_BLEEDING , SC_BLOODING , SCB_REGEN );
+ status->set_sc( NPC_POISON , SC_DPOISON , SCB_DEF2|SCB_REGEN );
//The main status definitions
add_sc( SM_BASH , SC_STUN );
- set_sc( SM_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ status->set_sc( SM_PROVOKE , SC_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
add_sc( SM_MAGNUM , SC_SUB_WEAPONPROPERTY );
- set_sc( SM_ENDURE , SC_ENDURE , SI_ENDURE , SCB_MDEF|SCB_DSPD );
+ status->set_sc( SM_ENDURE , SC_ENDURE , SCB_MDEF|SCB_DSPD );
add_sc( MG_SIGHT , SC_SIGHT );
add_sc( MG_SAFETYWALL , SC_SAFETYWALL );
add_sc( MG_FROSTDIVER , SC_FREEZE );
add_sc( MG_STONECURSE , SC_STONE );
add_sc( AL_RUWACH , SC_RUWACH );
add_sc( AL_PNEUMA , SC_PNEUMA );
- set_sc( AL_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
- set_sc( AL_DECAGI , SC_DEC_AGI , SI_DEC_AGI , SCB_AGI|SCB_SPEED );
- set_sc( AL_CRUCIS , SC_CRUCIS , SI_CRUCIS , SCB_DEF );
- set_sc( AL_ANGELUS , SC_ANGELUS , SI_ANGELUS , SCB_DEF2 );
- set_sc( AL_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( AC_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_AGI|SCB_DEX );
- set_sc( TF_HIDING , SC_HIDING , SI_HIDING , SCB_SPEED );
+ status->set_sc( AL_INCAGI , SC_INC_AGI , SCB_AGI|SCB_SPEED );
+ status->set_sc( AL_DECAGI , SC_DEC_AGI , SCB_AGI|SCB_SPEED );
+ status->set_sc( AL_CRUCIS , SC_CRUCIS , SCB_DEF );
+ status->set_sc( AL_ANGELUS , SC_ANGELUS , SCB_DEF2 );
+ status->set_sc( AL_BLESSING , SC_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ status->set_sc( AC_CONCENTRATION , SC_CONCENTRATION , SCB_AGI|SCB_DEX );
+ status->set_sc( TF_HIDING , SC_HIDING , SCB_SPEED );
add_sc( TF_POISON , SC_POISON );
- set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
+ status->set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SCB_ASPD );
add_sc( KN_AUTOCOUNTER , SC_AUTOCOUNTER );
- set_sc( PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO ,
+ status->set_sc( PR_IMPOSITIO , SC_IMPOSITIO ,
#ifdef RENEWAL
SCB_NONE );
#else
SCB_WATK );
#endif
- set_sc( PR_SUFFRAGIUM , SC_SUFFRAGIUM , SI_SUFFRAGIUM , SCB_NONE );
- set_sc( PR_ASPERSIO , SC_ASPERSIO , SI_ASPERSIO , SCB_ATK_ELE );
- set_sc( PR_BENEDICTIO , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
- set_sc( PR_SLOWPOISON , SC_SLOWPOISON , SI_SLOWPOISON , SCB_REGEN );
- set_sc( PR_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
- set_sc( PR_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
- set_sc( PR_GLORIA , SC_GLORIA , SI_GLORIA , SCB_LUK );
+ status->set_sc( PR_SUFFRAGIUM , SC_SUFFRAGIUM , SCB_NONE );
+ status->set_sc( PR_ASPERSIO , SC_ASPERSIO , SCB_ATK_ELE );
+ status->set_sc( PR_BENEDICTIO , SC_BENEDICTIO , SCB_DEF_ELE );
+ status->set_sc( PR_SLOWPOISON , SC_SLOWPOISON , SCB_REGEN );
+ status->set_sc( PR_KYRIE , SC_KYRIE , SCB_NONE );
+ status->set_sc( PR_MAGNIFICAT , SC_MAGNIFICAT , SCB_REGEN );
+ status->set_sc( PR_GLORIA , SC_GLORIA , SCB_LUK );
add_sc( PR_LEXDIVINA , SC_SILENCE );
- set_sc( PR_LEXAETERNA , SC_LEXAETERNA , SI_LEXAETERNA , SCB_NONE );
+ status->set_sc( PR_LEXAETERNA , SC_LEXAETERNA , SCB_NONE );
add_sc( WZ_METEOR , SC_STUN );
add_sc( WZ_VERMILION , SC_BLIND );
add_sc( WZ_FROSTNOVA , SC_FREEZE );
add_sc( WZ_STORMGUST , SC_FREEZE );
- set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
- set_sc( BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD );
- set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECT , SI_WEAPONPERFECT, SCB_NONE );
- set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE );
- set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZE , SCB_REGEN );
+ status->set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
+ status->set_sc( BS_ADRENALINE , SC_ADRENALINE , SCB_ASPD );
+ status->set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECT , SCB_NONE );
+ status->set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SCB_NONE );
+ status->set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SCB_REGEN );
add_sc( HT_LANDMINE , SC_STUN );
- set_sc( HT_ANKLESNARE , SC_ANKLESNARE , SI_ANKLESNARE , SCB_NONE );
+ status->set_sc( HT_ANKLESNARE , SC_ANKLESNARE , SCB_NONE );
add_sc( HT_SANDMAN , SC_SLEEP );
add_sc( HT_FLASHER , SC_BLIND );
add_sc( HT_FREEZINGTRAP , SC_FREEZE );
- set_sc( AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED );
+ status->set_sc( AS_CLOAKING , SC_CLOAKING , SCB_CRI|SCB_SPEED );
add_sc( AS_SONICBLOW , SC_STUN );
- set_sc( AS_ENCHANTPOISON , SC_ENCHANTPOISON , SI_ENCHANTPOISON, SCB_ATK_ELE );
- set_sc( AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE );
+ status->set_sc( AS_ENCHANTPOISON , SC_ENCHANTPOISON , SCB_ATK_ELE );
+ status->set_sc( AS_POISONREACT , SC_POISONREACT , SCB_NONE );
add_sc( AS_VENOMDUST , SC_POISON );
add_sc( AS_SPLASHER , SC_SPLASHER );
- set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN );
- set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
+ status->set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SCB_REGEN );
+ status->set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SCB_NONE );
add_sc( TF_SPRINKLESAND , SC_BLIND );
add_sc( TF_THROWSTONE , SC_STUN );
- set_sc( MC_LOUD , SC_SHOUT , SI_SHOUT , SCB_STR );
- set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE );
- set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE );
+ status->set_sc( MC_LOUD , SC_SHOUT , SCB_STR );
+ status->set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SCB_NONE );
+ status->set_sc( NPC_EMOTION , SC_MODECHANGE , SCB_MODE );
add_sc( NPC_EMOTION_ON , SC_MODECHANGE );
- set_sc( NPC_ATTRICHANGE , SC_ARMOR_PROPERTY , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
+ status->set_sc( NPC_ATTRICHANGE , SC_ARMOR_PROPERTY , SCB_DEF_ELE );
add_sc( NPC_CHANGEWATER , SC_ARMOR_PROPERTY );
add_sc( NPC_CHANGEGROUND , SC_ARMOR_PROPERTY );
add_sc( NPC_CHANGEFIRE , SC_ARMOR_PROPERTY );
@@ -260,184 +269,184 @@ void initChangeTables(void) {
add_sc( NPC_CURSEATTACK , SC_CURSE );
add_sc( NPC_SLEEPATTACK , SC_SLEEP );
add_sc( NPC_MAGICALATTACK , SC_MAGICALATTACK );
- set_sc( NPC_KEEPING , SC_KEEPING , SI_BLANK , SCB_DEF );
+ status->set_sc( NPC_KEEPING , SC_KEEPING , SCB_DEF );
add_sc( NPC_DARKBLESSING , SC_COMA );
- set_sc( NPC_BARRIER , SC_BARRIER , SI_BLANK , SCB_MDEF|SCB_DEF );
+ status->set_sc( NPC_BARRIER , SC_BARRIER , SCB_MDEF|SCB_DEF );
add_sc( NPC_DEFENDER , SC_ARMOR );
add_sc( NPC_LICK , SC_STUN );
- set_sc( NPC_HALLUCINATION , SC_ILLUSION , SI_ILLUSION , SCB_NONE );
+ status->set_sc( NPC_HALLUCINATION , SC_ILLUSION , SCB_NONE );
add_sc( NPC_REBIRTH , SC_REBIRTH );
add_sc( RG_RAID , SC_STUN );
#ifdef RENEWAL
add_sc( RG_RAID , SC_RAID );
add_sc( RG_BACKSTAP , SC_STUN );
#endif
- set_sc( RG_STRIPWEAPON , SC_NOEQUIPWEAPON , SI_NOEQUIPWEAPON , SCB_WATK );
- set_sc( RG_STRIPSHIELD , SC_NOEQUIPSHIELD , SI_NOEQUIPSHIELD , SCB_DEF );
- set_sc( RG_STRIPARMOR , SC_NOEQUIPARMOR , SI_NOEQUIPARMOR , SCB_VIT );
- set_sc( RG_STRIPHELM , SC_NOEQUIPHELM , SI_NOEQUIPHELM , SCB_INT );
+ status->set_sc( RG_STRIPWEAPON , SC_NOEQUIPWEAPON , SCB_WATK );
+ status->set_sc( RG_STRIPSHIELD , SC_NOEQUIPSHIELD , SCB_DEF );
+ status->set_sc( RG_STRIPARMOR , SC_NOEQUIPARMOR , SCB_VIT );
+ status->set_sc( RG_STRIPHELM , SC_NOEQUIPHELM , SCB_INT );
add_sc( AM_ACIDTERROR , SC_BLOODING );
- set_sc( AM_CP_WEAPON , SC_PROTECTWEAPON , SI_PROTECTWEAPON , SCB_NONE );
- set_sc( AM_CP_SHIELD , SC_PROTECTSHIELD , SI_PROTECTSHIELD , SCB_NONE );
- set_sc( AM_CP_ARMOR , SC_PROTECTARMOR , SI_PROTECTARMOR , SCB_NONE );
- set_sc( AM_CP_HELM , SC_PROTECTHELM , SI_PROTECTHELM , SCB_NONE );
- set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
+ status->set_sc( AM_CP_WEAPON , SC_PROTECTWEAPON , SCB_NONE );
+ status->set_sc( AM_CP_SHIELD , SC_PROTECTSHIELD , SCB_NONE );
+ status->set_sc( AM_CP_ARMOR , SC_PROTECTARMOR , SCB_NONE );
+ status->set_sc( AM_CP_HELM , SC_PROTECTHELM , SCB_NONE );
+ status->set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SCB_NONE );
add_sc( CR_SHIELDCHARGE , SC_STUN );
- set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
+ status->set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SCB_NONE );
add_sc( CR_HOLYCROSS , SC_BLIND );
add_sc( CR_GRANDCROSS , SC_BLIND );
add_sc( CR_DEVOTION , SC_DEVOTION );
- set_sc( CR_PROVIDENCE , SC_PROVIDENCE , SI_PROVIDENCE , SCB_ALL );
- set_sc( CR_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
- set_sc( CR_SPEARQUICKEN , SC_SPEARQUICKEN , SI_SPEARQUICKEN , SCB_ASPD|SCB_CRI|SCB_FLEE );
- set_sc( MO_STEELBODY , SC_STEELBODY , SI_STEELBODY , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED );
+ status->set_sc( CR_PROVIDENCE , SC_PROVIDENCE , SCB_ALL );
+ status->set_sc( CR_DEFENDER , SC_DEFENDER , SCB_SPEED|SCB_ASPD );
+ status->set_sc( CR_SPEARQUICKEN , SC_SPEARQUICKEN , SCB_ASPD|SCB_CRI|SCB_FLEE );
+ status->set_sc( MO_STEELBODY , SC_STEELBODY , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED );
add_sc( MO_BLADESTOP , SC_BLADESTOP_WAIT );
add_sc( MO_BLADESTOP , SC_BLADESTOP );
- set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
- set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN );
+ status->set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
+ status->set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SCB_REGEN );
#ifdef RENEWAL
- set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE );
+ status->set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SCB_NONE );
#endif
add_sc( SA_MAGICROD , SC_MAGICROD );
- set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE );
- set_sc( SA_FLAMELAUNCHER , SC_PROPERTYFIRE , SI_PROPERTYFIRE , SCB_ATK_ELE );
- set_sc( SA_FROSTWEAPON , SC_PROPERTYWATER , SI_PROPERTYWATER , SCB_ATK_ELE );
- set_sc( SA_LIGHTNINGLOADER , SC_PROPERTYWIND , SI_PROPERTYWIND , SCB_ATK_ELE );
- set_sc( SA_SEISMICWEAPON , SC_PROPERTYGROUND , SI_PROPERTYGROUND , SCB_ATK_ELE );
- set_sc( SA_VOLCANO , SC_VOLCANO , SI_GROUNDMAGIC , SCB_WATK );
- set_sc( SA_DELUGE , SC_DELUGE , SI_GROUNDMAGIC , SCB_MAXHP );
- set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SI_GROUNDMAGIC , SCB_FLEE );
+ status->set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SCB_NONE );
+ status->set_sc( SA_FLAMELAUNCHER , SC_PROPERTYFIRE , SCB_ATK_ELE );
+ status->set_sc( SA_FROSTWEAPON , SC_PROPERTYWATER , SCB_ATK_ELE );
+ status->set_sc( SA_LIGHTNINGLOADER , SC_PROPERTYWIND , SCB_ATK_ELE );
+ status->set_sc( SA_SEISMICWEAPON , SC_PROPERTYGROUND , SCB_ATK_ELE );
+ status->set_sc( SA_VOLCANO , SC_VOLCANO , SCB_WATK );
+ status->set_sc( SA_DELUGE , SC_DELUGE , SCB_MAXHP );
+ status->set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SCB_FLEE );
add_sc( SA_REVERSEORCISH , SC_ORCISH );
add_sc( SA_COMA , SC_COMA );
- set_sc( BD_ENCORE , SC_DANCING , SI_BLANK , SCB_SPEED|SCB_REGEN );
+ status->set_sc( BD_ENCORE , SC_DANCING , SCB_SPEED|SCB_REGEN );
add_sc( BD_RICHMANKIM , SC_RICHMANKIM );
- set_sc( BD_ETERNALCHAOS , SC_ETERNALCHAOS , SI_BLANK , SCB_DEF2 );
- set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_BLANK , SCB_WATK|SCB_DEF );
- set_sc( BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SI_BLANK , SCB_WATK );
+ status->set_sc( BD_ETERNALCHAOS , SC_ETERNALCHAOS , SCB_DEF2 );
+ status->set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SCB_WATK|SCB_DEF );
+ status->set_sc( BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SCB_WATK );
add_sc( BD_ROKISWEIL , SC_ROKISWEIL );
add_sc( BD_INTOABYSS , SC_INTOABYSS );
- set_sc( BD_SIEGFRIED , SC_SIEGFRIED , SI_BLANK , SCB_ALL );
+ status->set_sc( BD_SIEGFRIED , SC_SIEGFRIED , SCB_ALL );
add_sc( BA_FROSTJOKER , SC_FREEZE );
- set_sc( BA_WHISTLE , SC_WHISTLE , SI_BLANK , SCB_FLEE|SCB_FLEE2 );
- set_sc( BA_ASSASSINCROSS , SC_ASSNCROS , SI_BLANK , SCB_ASPD );
+ status->set_sc( BA_WHISTLE , SC_WHISTLE , SCB_FLEE|SCB_FLEE2 );
+ status->set_sc( BA_ASSASSINCROSS , SC_ASSNCROS , SCB_ASPD );
add_sc( BA_POEMBRAGI , SC_POEMBRAGI );
- set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SI_BLANK , SCB_MAXHP );
+ status->set_sc( BA_APPLEIDUN , SC_APPLEIDUN , SCB_MAXHP );
add_sc( DC_SCREAM , SC_STUN );
- set_sc( DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT );
- set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD );
- set_sc( DC_FORTUNEKISS , SC_FORTUNE , SI_BLANK , SCB_CRI );
- set_sc( DC_SERVICEFORYOU , SC_SERVICEFORYOU , SI_BLANK , SCB_ALL );
+ status->set_sc( DC_HUMMING , SC_HUMMING , SCB_HIT );
+ status->set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SCB_SPEED|SCB_ASPD );
+ status->set_sc( DC_FORTUNEKISS , SC_FORTUNE , SCB_CRI );
+ status->set_sc( DC_SERVICEFORYOU , SC_SERVICEFORYOU , SCB_ALL );
add_sc( NPC_DARKCROSS , SC_BLIND );
add_sc( NPC_GRANDDARKNESS , SC_BLIND );
- set_sc( NPC_STOP , SC_STOP , SI_STOP , SCB_NONE );
- set_sc( NPC_WEAPONBRAKER , SC_BROKENWEAPON , SI_BROKENWEAPON , SCB_NONE );
- set_sc( NPC_ARMORBRAKE , SC_BROKENARMOR , SI_BROKENARMOR , SCB_NONE );
- set_sc( NPC_CHANGEUNDEAD , SC_PROPERTYUNDEAD , SI_PROPERTYUNDEAD , SCB_DEF_ELE );
- set_sc( NPC_POWERUP , SC_INCHITRATE , SI_BLANK , SCB_HIT );
- set_sc( NPC_AGIUP , SC_INCFLEERATE , SI_BLANK , SCB_FLEE );
+ status->set_sc( NPC_STOP , SC_STOP , SCB_NONE );
+ status->set_sc( NPC_WEAPONBRAKER , SC_BROKENWEAPON , SCB_NONE );
+ status->set_sc( NPC_ARMORBRAKE , SC_BROKENARMOR , SCB_NONE );
+ status->set_sc( NPC_CHANGEUNDEAD , SC_PROPERTYUNDEAD , SCB_DEF_ELE );
+ status->set_sc( NPC_POWERUP , SC_INCHITRATE , SCB_HIT );
+ status->set_sc( NPC_AGIUP , SC_INCFLEERATE , SCB_FLEE );
add_sc( NPC_INVISIBLE , SC_CLOAKING );
- set_sc( LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE );
- set_sc( LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
+ status->set_sc( LK_AURABLADE , SC_AURABLADE , SCB_NONE );
+ status->set_sc( LK_PARRYING , SC_PARRYING , SCB_NONE );
#ifndef RENEWAL
- set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_LKCONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2);
+ status->set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2);
#else
- set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_LKCONCENTRATION , SCB_HIT|SCB_DEF);
+ status->set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SCB_HIT|SCB_DEF);
#endif
- set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN );
- set_sc( LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
- set_sc( HP_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
+ status->set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SCB_REGEN );
+ status->set_sc( LK_BERSERK , SC_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
+ status->set_sc( HP_ASSUMPTIO , SC_ASSUMPTIO , SCB_NONE );
add_sc( HP_BASILICA , SC_BASILICA );
- set_sc( HW_MAGICPOWER , SC_MAGICPOWER , SI_MAGICPOWER , SCB_MATK );
+ status->set_sc( HW_MAGICPOWER , SC_MAGICPOWER , SCB_MATK );
add_sc( PA_SACRIFICE , SC_SACRIFICE );
- set_sc( PA_GOSPEL , SC_GOSPEL , SI_BLANK , SCB_SPEED|SCB_ASPD );
+ status->set_sc( PA_GOSPEL , SC_GOSPEL , SCB_SPEED|SCB_ASPD );
add_sc( PA_GOSPEL , SC_SCRESIST );
add_sc( CH_TIGERFIST , SC_STOP );
- set_sc( ASC_EDP , SC_EDP , SI_EDP , SCB_NONE );
- set_sc( SN_SIGHT , SC_TRUESIGHT , SI_TRUESIGHT , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT );
- set_sc( SN_WINDWALK , SC_WINDWALK , SI_WINDWALK , SCB_FLEE|SCB_SPEED );
- set_sc( WS_MELTDOWN , SC_MELTDOWN , SI_MELTDOWN , SCB_NONE );
- set_sc( WS_CARTBOOST , SC_CARTBOOST , SI_CARTBOOST , SCB_SPEED );
- set_sc( ST_CHASEWALK , SC_CHASEWALK , SI_BLANK , SCB_SPEED );
- set_sc( ST_REJECTSWORD , SC_SWORDREJECT , SI_SWORDREJECT , SCB_NONE );
+ status->set_sc( ASC_EDP , SC_EDP , SCB_NONE );
+ status->set_sc( SN_SIGHT , SC_TRUESIGHT , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT );
+ status->set_sc( SN_WINDWALK , SC_WINDWALK , SCB_FLEE|SCB_SPEED );
+ status->set_sc( WS_MELTDOWN , SC_MELTDOWN , SCB_NONE );
+ status->set_sc( WS_CARTBOOST , SC_CARTBOOST , SCB_SPEED );
+ status->set_sc( ST_CHASEWALK , SC_CHASEWALK , SCB_SPEED );
+ status->set_sc( ST_REJECTSWORD , SC_SWORDREJECT , SCB_NONE );
add_sc( ST_REJECTSWORD , SC_AUTOCOUNTER );
- set_sc( CG_MARIONETTE , SC_MARIONETTE_MASTER , SI_MARIONETTE_MASTER , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
- set_sc( CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ status->set_sc( CG_MARIONETTE , SC_MARIONETTE_MASTER , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ status->set_sc( CG_MARIONETTE , SC_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
add_sc( LK_SPIRALPIERCE , SC_STOP );
add_sc( LK_HEADCRUSH , SC_BLOODING );
- set_sc( LK_JOINTBEAT , SC_JOINTBEAT , SI_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
+ status->set_sc( LK_JOINTBEAT , SC_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
add_sc( HW_NAPALMVULCAN , SC_CURSE );
- set_sc( PF_MINDBREAKER , SC_MINDBREAKER , SI_BLANK , SCB_MATK|SCB_MDEF2 );
+ status->set_sc( PF_MINDBREAKER , SC_MINDBREAKER , SCB_MATK|SCB_MDEF2 );
add_sc( PF_MEMORIZE , SC_MEMORIZE );
add_sc( PF_FOGWALL , SC_FOGWALL );
- set_sc( PF_SPIDERWEB , SC_SPIDERWEB , SI_BLANK , SCB_FLEE );
- set_sc( WE_BABY , SC_BABY , SI_PROTECTEXP , SCB_NONE );
- set_sc( TK_RUN , SC_RUN , SI_RUN , SCB_SPEED|SCB_DSPD );
- set_sc( TK_RUN , SC_STRUP , SI_STRUP , SCB_STR );
- set_sc( TK_READYSTORM , SC_STORMKICK_READY , SI_STORMKICK_ON , SCB_NONE );
- set_sc( TK_READYDOWN , SC_DOWNKICK_READY , SI_DOWNKICK_ON , SCB_NONE );
+ status->set_sc( PF_SPIDERWEB , SC_SPIDERWEB , SCB_FLEE );
+ status->set_sc( WE_BABY , SC_BABY , SCB_NONE );
+ status->set_sc( TK_RUN , SC_RUN , SCB_SPEED|SCB_DSPD );
+ status->set_sc( TK_RUN , SC_STRUP , SCB_STR );
+ status->set_sc( TK_READYSTORM , SC_STORMKICK_READY , SCB_NONE );
+ status->set_sc( TK_READYDOWN , SC_DOWNKICK_READY , SCB_NONE );
add_sc( TK_DOWNKICK , SC_STUN );
- set_sc( TK_READYTURN , SC_TURNKICK_READY , SI_TURNKICK_ON , SCB_NONE );
- set_sc( TK_READYCOUNTER , SC_COUNTERKICK_READY , SI_COUNTER_ON , SCB_NONE );
- set_sc( TK_DODGE , SC_DODGE_READY , SI_DODGE_ON , SCB_NONE );
- set_sc( TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE );
+ status->set_sc( TK_READYTURN , SC_TURNKICK_READY , SCB_NONE );
+ status->set_sc( TK_READYCOUNTER , SC_COUNTERKICK_READY , SCB_NONE );
+ status->set_sc( TK_DODGE , SC_DODGE_READY , SCB_NONE );
+ status->set_sc( TK_SPTIME , SC_EARTHSCROLL , SCB_NONE );
add_sc( TK_SEVENWIND , SC_TK_SEVENWIND );
- set_sc( TK_SEVENWIND , SC_PROPERTYTELEKINESIS , SI_PROPERTYTELEKINESIS , SCB_ATK_ELE );
- set_sc( TK_SEVENWIND , SC_PROPERTYDARK , SI_PROPERTYDARK , SCB_ATK_ELE );
- set_sc( SG_SUN_WARM , SC_WARM , SI_SG_SUN_WARM , SCB_NONE );
+ status->set_sc( TK_SEVENWIND , SC_PROPERTYTELEKINESIS , SCB_ATK_ELE );
+ status->set_sc( TK_SEVENWIND , SC_PROPERTYDARK , SCB_ATK_ELE );
+ status->set_sc( SG_SUN_WARM , SC_WARM , SCB_NONE );
add_sc( SG_MOON_WARM , SC_WARM );
add_sc( SG_STAR_WARM , SC_WARM );
- set_sc( SG_SUN_COMFORT , SC_SUN_COMFORT , SI_SUN_COMFORT , SCB_DEF2 );
- set_sc( SG_MOON_COMFORT , SC_MOON_COMFORT , SI_MOON_COMFORT , SCB_FLEE );
- set_sc( SG_STAR_COMFORT , SC_STAR_COMFORT , SI_STAR_COMFORT , SCB_ASPD );
+ status->set_sc( SG_SUN_COMFORT , SC_SUN_COMFORT , SCB_DEF2 );
+ status->set_sc( SG_MOON_COMFORT , SC_MOON_COMFORT , SCB_FLEE );
+ status->set_sc( SG_STAR_COMFORT , SC_STAR_COMFORT , SCB_ASPD );
add_sc( SG_FRIEND , SC_SKILLRATE_UP );
- set_sc( SG_KNOWLEDGE , SC_KNOWLEDGE , SI_BLANK , SCB_ALL );
- set_sc( SG_FUSION , SC_FUSION , SI_BLANK , SCB_SPEED );
- set_sc( BS_ADRENALINE2 , SC_ADRENALINE2 , SI_ADRENALINE2 , SCB_ASPD );
- set_sc( SL_KAIZEL , SC_KAIZEL , SI_KAIZEL , SCB_NONE );
- set_sc( SL_KAAHI , SC_KAAHI , SI_KAAHI , SCB_NONE );
- set_sc( SL_KAUPE , SC_KAUPE , SI_KAUPE , SCB_NONE );
- set_sc( SL_KAITE , SC_KAITE , SI_KAITE , SCB_NONE );
+ status->set_sc( SG_KNOWLEDGE , SC_KNOWLEDGE , SCB_ALL );
+ status->set_sc( SG_FUSION , SC_FUSION , SCB_SPEED );
+ status->set_sc( BS_ADRENALINE2 , SC_ADRENALINE2 , SCB_ASPD );
+ status->set_sc( SL_KAIZEL , SC_KAIZEL , SCB_NONE );
+ status->set_sc( SL_KAAHI , SC_KAAHI , SCB_NONE );
+ status->set_sc( SL_KAUPE , SC_KAUPE , SCB_NONE );
+ status->set_sc( SL_KAITE , SC_KAITE , SCB_NONE );
add_sc( SL_STUN , SC_STUN );
- set_sc( SL_SWOO , SC_SWOO , SI_BLANK , SCB_SPEED );
- set_sc( SL_SKE , SC_SKE , SI_BLANK , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
- set_sc( SL_SKA , SC_SKA , SI_BLANK , SCB_DEF|SCB_MDEF|SCB_ASPD );
- set_sc( SL_SMA , SC_SMA_READY , SI_SMA_READY , SCB_NONE );
- set_sc( SM_SELFPROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
- set_sc( ST_PRESERVE , SC_PRESERVE , SI_PRESERVE , SCB_NONE );
- set_sc( PF_DOUBLECASTING , SC_DOUBLECASTING , SI_DOUBLECASTING , SCB_NONE );
- set_sc( HW_GRAVITATION , SC_GRAVITATION , SI_BLANK , SCB_ASPD );
+ status->set_sc( SL_SWOO , SC_SWOO , SCB_SPEED );
+ status->set_sc( SL_SKE , SC_SKE , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
+ status->set_sc( SL_SKA , SC_SKA , SCB_DEF|SCB_MDEF|SCB_ASPD );
+ status->set_sc( SL_SMA , SC_SMA_READY , SCB_NONE );
+ status->set_sc( SM_SELFPROVOKE , SC_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ status->set_sc( ST_PRESERVE , SC_PRESERVE , SCB_NONE );
+ status->set_sc( PF_DOUBLECASTING , SC_DOUBLECASTING , SCB_NONE );
+ status->set_sc( HW_GRAVITATION , SC_GRAVITATION , SCB_ASPD );
add_sc( WS_CARTTERMINATION , SC_STUN );
- set_sc( WS_OVERTHRUSTMAX , SC_OVERTHRUSTMAX , SI_OVERTHRUSTMAX , SCB_NONE );
- set_sc( CG_LONGINGFREEDOM , SC_LONGING , SI_BLANK , SCB_SPEED|SCB_ASPD );
+ status->set_sc( WS_OVERTHRUSTMAX , SC_OVERTHRUSTMAX , SCB_NONE );
+ status->set_sc( CG_LONGINGFREEDOM , SC_LONGING , SCB_SPEED|SCB_ASPD );
add_sc( CG_HERMODE , SC_HERMODE );
- set_sc( CG_TAROTCARD , SC_TAROTCARD , SI_TAROTCARD , SCB_NONE );
- set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE );
- set_sc( SL_HIGH , SC_SOULLINK , SI_SOULLINK , SCB_ALL );
- set_sc( KN_ONEHAND , SC_ONEHANDQUICKEN , SI_ONEHANDQUICKEN , SCB_ASPD );
- set_sc( GS_FLING , SC_FLING , SI_BLANK , SCB_DEF|SCB_DEF2 );
+ status->set_sc( CG_TAROTCARD , SC_TAROTCARD , SCB_NONE );
+ status->set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SCB_ATK_ELE );
+ status->set_sc( SL_HIGH , SC_SOULLINK , SCB_ALL );
+ status->set_sc( KN_ONEHAND , SC_ONEHANDQUICKEN , SCB_ASPD );
+ status->set_sc( GS_FLING , SC_FLING , SCB_DEF|SCB_DEF2 );
add_sc( GS_CRACKER , SC_STUN );
add_sc( GS_DISARM , SC_NOEQUIPWEAPON );
add_sc( GS_PIERCINGSHOT , SC_BLOODING );
- set_sc( GS_MADNESSCANCEL , SC_GS_MADNESSCANCEL , SI_GS_MADNESSCANCEL , SCB_ASPD
+ status->set_sc( GS_MADNESSCANCEL , SC_GS_MADNESSCANCEL , SCB_ASPD
#ifndef RENEWAL
|SCB_BATK );
#else
);
#endif
- set_sc( GS_ADJUSTMENT , SC_GS_ADJUSTMENT , SI_GS_ADJUSTMENT , SCB_HIT|SCB_FLEE );
- set_sc( GS_INCREASING , SC_GS_ACCURACY , SI_GS_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
- set_sc( GS_GATLINGFEVER , SC_GS_GATLINGFEVER , SI_GS_GATLINGFEVER , SCB_FLEE|SCB_SPEED|SCB_ASPD
+ status->set_sc( GS_ADJUSTMENT , SC_GS_ADJUSTMENT , SCB_HIT|SCB_FLEE );
+ status->set_sc( GS_INCREASING , SC_GS_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
+ status->set_sc( GS_GATLINGFEVER , SC_GS_GATLINGFEVER , SCB_FLEE|SCB_SPEED|SCB_ASPD
#ifndef RENEWAL
|SCB_BATK );
#else
);
#endif
- set_sc( NJ_TATAMIGAESHI , SC_NJ_TATAMIGAESHI , SI_BLANK , SCB_NONE );
- set_sc( NJ_SUITON , SC_NJ_SUITON , SI_NJ_SUITON , SCB_AGI|SCB_SPEED );
+ status->set_sc( NJ_TATAMIGAESHI , SC_NJ_TATAMIGAESHI , SCB_NONE );
+ status->set_sc( NJ_SUITON , SC_NJ_SUITON , SCB_AGI|SCB_SPEED );
add_sc( NJ_HYOUSYOURAKU , SC_FREEZE );
- set_sc( NJ_NEN , SC_NJ_NEN , SI_NJ_NEN , SCB_STR|SCB_INT );
- set_sc( NJ_UTSUSEMI , SC_NJ_UTSUSEMI , SI_NJ_UTSUSEMI , SCB_NONE );
- set_sc( NJ_BUNSINJYUTSU , SC_NJ_BUNSINJYUTSU , SI_NJ_BUNSINJYUTSU , SCB_DYE );
+ status->set_sc( NJ_NEN , SC_NJ_NEN , SCB_STR|SCB_INT );
+ status->set_sc( NJ_UTSUSEMI , SC_NJ_UTSUSEMI , SCB_NONE );
+ status->set_sc( NJ_BUNSINJYUTSU , SC_NJ_BUNSINJYUTSU , SCB_DYE );
add_sc( NPC_ICEBREATH , SC_FREEZE );
add_sc( NPC_ACIDBREATH , SC_POISON );
@@ -451,202 +460,202 @@ void initChangeTables(void) {
add_sc( NPC_WIDESIGHT , SC_SIGHT );
add_sc( NPC_EVILLAND , SC_BLIND );
add_sc( NPC_MAGICMIRROR , SC_MAGICMIRROR );
- set_sc( NPC_SLOWCAST , SC_SLOWCAST , SI_SLOWCAST , SCB_NONE );
- set_sc( NPC_CRITICALWOUND , SC_CRITICALWOUND , SI_CRITICALWOUND , SCB_NONE );
- set_sc( NPC_STONESKIN , SC_STONESKIN , SI_BLANK , SCB_DEF|SCB_MDEF );
+ status->set_sc( NPC_SLOWCAST , SC_SLOWCAST , SCB_NONE );
+ status->set_sc( NPC_CRITICALWOUND , SC_CRITICALWOUND , SCB_NONE );
+ status->set_sc( NPC_STONESKIN , SC_STONESKIN , SCB_DEF|SCB_MDEF );
add_sc( NPC_ANTIMAGIC , SC_STONESKIN );
add_sc( NPC_WIDECURSE , SC_CURSE );
add_sc( NPC_WIDESTUN , SC_STUN );
- set_sc( NPC_HELLPOWER , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
- set_sc( NPC_WIDEHELLDIGNITY , SC_HELLPOWER , SI_HELLPOWER , SCB_NONE );
- set_sc( NPC_INVINCIBLE , SC_INVINCIBLE , SI_INVINCIBLE , SCB_SPEED );
- set_sc( NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SI_BLANK , SCB_SPEED );
+ status->set_sc( NPC_HELLPOWER , SC_HELLPOWER , SCB_NONE );
+ status->set_sc( NPC_WIDEHELLDIGNITY , SC_HELLPOWER , SCB_NONE );
+ status->set_sc( NPC_INVINCIBLE , SC_INVINCIBLE , SCB_SPEED );
+ status->set_sc( NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SCB_SPEED );
- set_sc( CASH_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( CASH_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
- set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
+ status->set_sc( CASH_BLESSING , SC_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ status->set_sc( CASH_INCAGI , SC_INC_AGI , SCB_AGI|SCB_SPEED );
+ status->set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SCB_NONE );
- set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_NONE );
- set_sc( ALL_ODINS_POWER , SC_ODINS_POWER , SI_ODINS_POWER , SCB_WATK | SCB_MATK | SCB_MDEF | SCB_DEF);
+ status->set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SCB_NONE );
+ status->set_sc( ALL_ODINS_POWER , SC_ODINS_POWER , SCB_WATK | SCB_MATK | SCB_MDEF | SCB_DEF);
- set_sc( CR_SHRINK , SC_CR_SHRINK , SI_CR_SHRINK , SCB_NONE );
- set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_S , SI_RG_CCONFINE_S , SCB_NONE );
- set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_M , SI_RG_CCONFINE_M , SCB_FLEE );
- set_sc( WZ_SIGHTBLASTER , SC_WZ_SIGHTBLASTER , SI_WZ_SIGHTBLASTER , SCB_NONE );
- set_sc( DC_WINKCHARM , SC_DC_WINKCHARM , SI_DC_WINKCHARM , SCB_NONE );
+ status->set_sc( CR_SHRINK , SC_CR_SHRINK , SCB_NONE );
+ status->set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_S , SCB_NONE );
+ status->set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_M , SCB_FLEE );
+ status->set_sc( WZ_SIGHTBLASTER , SC_WZ_SIGHTBLASTER , SCB_NONE );
+ status->set_sc( DC_WINKCHARM , SC_DC_WINKCHARM , SCB_NONE );
add_sc( MO_BALKYOUNG , SC_STUN );
add_sc( SA_ELEMENTWATER , SC_ARMOR_PROPERTY );
add_sc( SA_ELEMENTFIRE , SC_ARMOR_PROPERTY );
add_sc( SA_ELEMENTGROUND , SC_ARMOR_PROPERTY );
add_sc( SA_ELEMENTWIND , SC_ARMOR_PROPERTY );
- set_sc( HLIF_AVOID , SC_HLIF_AVOID , SI_BLANK , SCB_SPEED );
- set_sc( HLIF_CHANGE , SC_HLIF_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
- set_sc( HFLI_FLEET , SC_HLIF_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
- set_sc( HFLI_SPEED , SC_HLIF_SPEED , SI_BLANK , SCB_FLEE );
- set_sc( HAMI_DEFENCE , SC_HAMI_DEFENCE , SI_BLANK , SCB_DEF );
- set_sc( HAMI_BLOODLUST , SC_HAMI_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
+ status->set_sc( HLIF_AVOID , SC_HLIF_AVOID , SCB_SPEED );
+ status->set_sc( HLIF_CHANGE , SC_HLIF_CHANGE , SCB_VIT|SCB_INT );
+ status->set_sc( HFLI_FLEET , SC_HLIF_FLEET , SCB_ASPD|SCB_BATK|SCB_WATK );
+ status->set_sc( HFLI_SPEED , SC_HLIF_SPEED , SCB_FLEE );
+ status->set_sc( HAMI_DEFENCE , SC_HAMI_DEFENCE , SCB_DEF );
+ status->set_sc( HAMI_BLOODLUST , SC_HAMI_BLOODLUST , SCB_BATK|SCB_WATK );
// Homunculus S
- set_sc( MH_LIGHT_OF_REGENE , SC_LIGHT_OF_REGENE , SI_LIGHT_OF_REGENE , SCB_NONE );
- set_sc( MH_OVERED_BOOST , SC_OVERED_BOOST , SI_OVERED_BOOST , SCB_FLEE|SCB_ASPD|SCB_DEF );
+ status->set_sc( MH_LIGHT_OF_REGENE , SC_LIGHT_OF_REGENE , SCB_NONE );
+ status->set_sc( MH_OVERED_BOOST , SC_OVERED_BOOST , SCB_FLEE|SCB_ASPD|SCB_DEF );
add_sc(MH_STAHL_HORN, SC_STUN);
- set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SI_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
- set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SI_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
+ status->set_sc(MH_ANGRIFFS_MODUS, SC_ANGRIFFS_MODUS, SCB_BATK | SCB_DEF | SCB_FLEE | SCB_MAXHP);
+ status->set_sc(MH_GOLDENE_FERSE, SC_GOLDENE_FERSE, SCB_ASPD|SCB_MAXHP);
add_sc( MH_STEINWAND, SC_SAFETYWALL );
- set_sc(MH_VOLCANIC_ASH, SC_VOLCANIC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
- set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
- set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
- set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
+ status->set_sc(MH_VOLCANIC_ASH, SC_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
+ status->set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SCB_NONE);
+ status->set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SCB_NONE);
+ status->set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
add_sc(MH_LAVA_SLIDE, SC_BURNING);
- set_sc(MH_NEEDLE_OF_PARALYZE, SC_NEEDLE_OF_PARALYZE, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
+ status->set_sc(MH_NEEDLE_OF_PARALYZE, SC_NEEDLE_OF_PARALYZE, SCB_DEF2);
add_sc(MH_POISON_MIST, SC_BLIND);
- set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
+ status->set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SCB_ASPD);
- set_sc( MH_SILENT_BREEZE , SC_SILENCE , SI_SILENT_BREEZE , SCB_NONE );
+ status->set_sc( MH_SILENT_BREEZE , SC_SILENCE , SCB_NONE );
add_sc( MH_STYLE_CHANGE , SC_STYLE_CHANGE);
- set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_S , SI_RG_CCONFINE_S , SCB_NONE );
- set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_M , SI_RG_CCONFINE_M , SCB_FLEE );
+ status->set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_S , SCB_NONE );
+ status->set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_M , SCB_FLEE );
add_sc( MER_CRASH , SC_STUN );
- set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ status->set_sc( MER_PROVOKE , SC_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
add_sc( MS_MAGNUM , SC_SUB_WEAPONPROPERTY );
add_sc( MER_SIGHT , SC_SIGHT );
- set_sc( MER_DECAGI , SC_DEC_AGI , SI_DEC_AGI , SCB_AGI|SCB_SPEED );
- set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
+ status->set_sc( MER_DECAGI , SC_DEC_AGI , SCB_AGI|SCB_SPEED );
+ status->set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SCB_REGEN );
add_sc( MER_LEXDIVINA , SC_SILENCE );
add_sc( MA_LANDMINE , SC_STUN );
add_sc( MA_SANDMAN , SC_SLEEP );
add_sc( MA_FREEZINGTRAP , SC_FREEZE );
- set_sc( MER_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
- set_sc( ML_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
- set_sc( MS_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
- set_sc( ML_DEFENDER , SC_DEFENDER , SI_DEFENDER , SCB_SPEED|SCB_ASPD );
- set_sc( MS_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
- set_sc( MS_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
+ status->set_sc( MER_AUTOBERSERK , SC_AUTOBERSERK , SCB_NONE );
+ status->set_sc( ML_AUTOGUARD , SC_AUTOGUARD , SCB_NONE );
+ status->set_sc( MS_REFLECTSHIELD , SC_REFLECTSHIELD , SCB_NONE );
+ status->set_sc( ML_DEFENDER , SC_DEFENDER , SCB_SPEED|SCB_ASPD );
+ status->set_sc( MS_PARRYING , SC_PARRYING , SCB_NONE );
+ status->set_sc( MS_BERSERK , SC_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
add_sc( ML_SPIRALPIERCE , SC_STOP );
- set_sc( MER_QUICKEN , SC_MER_QUICKEN , SI_BLANK , SCB_ASPD );
+ status->set_sc( MER_QUICKEN , SC_MER_QUICKEN , SCB_ASPD );
add_sc( ML_DEVOTION , SC_DEVOTION );
- set_sc( MER_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
- set_sc( MER_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( MER_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
+ status->set_sc( MER_KYRIE , SC_KYRIE , SCB_NONE );
+ status->set_sc( MER_BLESSING , SC_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
+ status->set_sc( MER_INCAGI , SC_INC_AGI , SCB_AGI|SCB_SPEED );
- set_sc( GD_LEADERSHIP , SC_LEADERSHIP , SI_BLANK , SCB_STR );
- set_sc( GD_GLORYWOUNDS , SC_GLORYWOUNDS , SI_BLANK , SCB_VIT );
- set_sc( GD_SOULCOLD , SC_SOULCOLD , SI_BLANK , SCB_AGI );
- set_sc( GD_HAWKEYES , SC_HAWKEYES , SI_BLANK , SCB_DEX );
+ status->set_sc( GD_LEADERSHIP , SC_LEADERSHIP , SCB_STR );
+ status->set_sc( GD_GLORYWOUNDS , SC_GLORYWOUNDS , SCB_VIT );
+ status->set_sc( GD_SOULCOLD , SC_SOULCOLD , SCB_AGI );
+ status->set_sc( GD_HAWKEYES , SC_HAWKEYES , SCB_DEX );
- set_sc( GD_BATTLEORDER , SC_GDSKILL_BATTLEORDER , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( GD_REGENERATION , SC_GDSKILL_REGENERATION , SI_BLANK , SCB_REGEN );
+ status->set_sc( GD_BATTLEORDER , SC_GDSKILL_BATTLEORDER , SCB_STR|SCB_INT|SCB_DEX );
+ status->set_sc( GD_REGENERATION , SC_GDSKILL_REGENERATION , SCB_REGEN );
/**
* Rune Knight
**/
- set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE );
- set_sc( RK_DRAGONHOWLING , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
- set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE );
- set_sc( RK_WINDCUTTER , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
+ status->set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SCB_NONE );
+ status->set_sc( RK_DRAGONHOWLING , SC_FEAR , SCB_FLEE|SCB_HIT );
+ status->set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SCB_NONE );
+ status->set_sc( RK_WINDCUTTER , SC_FEAR , SCB_FLEE|SCB_HIT );
add_sc( RK_DRAGONBREATH , SC_BURNING );
- set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_BLANK , SCB_NONE );
- set_sc( RK_REFRESH , SC_REFRESH , SI_REFRESH , SCB_NONE );
- set_sc( RK_GIANTGROWTH , SC_GIANTGROWTH , SI_GIANTGROWTH , SCB_STR );
- set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_NONE );
- set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SI_VITALITYACTIVATION, SCB_REGEN );
- set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD );
- set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE );
- set_sc( RK_CRUSHSTRIKE , SC_CRUSHSTRIKE , SI_CRUSHSTRIKE , SCB_NONE );
+ status->set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SCB_NONE );
+ status->set_sc( RK_REFRESH , SC_REFRESH , SCB_NONE );
+ status->set_sc( RK_GIANTGROWTH , SC_GIANTGROWTH , SCB_STR );
+ status->set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SCB_NONE );
+ status->set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SCB_REGEN );
+ status->set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD );
+ status->set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SCB_NONE );
+ status->set_sc( RK_CRUSHSTRIKE , SC_CRUSHSTRIKE , SCB_NONE );
add_sc( RK_DRAGONBREATH_WATER, SC_FROSTMISTY );
/**
* GC Guillotine Cross
**/
- 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_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
- set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
- set_sc( GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SI_HALLUCINATIONWALK, SCB_FLEE );
- set_sc( GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SI_ROLLINGCUTTER , SCB_NONE );
- set_sc_with_vfx( GC_DARKCROW , SC_DARKCROW , SI_DARKCROW , SCB_NONE );
+ set_sc_with_vfx( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SCB_NONE );
+ status->set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SCB_NONE );
+ status->set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SCB_NONE );
+ status->set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SCB_SPEED );
+ status->set_sc( GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SCB_FLEE );
+ status->set_sc( GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SCB_NONE );
+ set_sc_with_vfx( GC_DARKCROW , SC_DARKCROW , SCB_NONE );
/**
* Arch Bishop
**/
- set_sc( AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED );
+ status->set_sc( AB_ADORAMUS , SC_ADORAMUS , SCB_AGI|SCB_SPEED );
add_sc( AB_CLEMENTIA , SC_BLESSING );
add_sc( AB_CANTO , SC_INC_AGI );
- set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
+ status->set_sc( AB_EPICLESIS , SC_EPICLESIS , SCB_MAXHP );
add_sc( AB_PRAEFATIO , SC_KYRIE );
- 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_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK );
- set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN );
- set_sc( AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_ATK_ELE );
- set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE );
- set_sc( AB_SECRAMENT , SC_SECRAMENT , SI_SECRAMENT , SCB_NONE );
- set_sc( AB_OFFERTORIUM , SC_OFFERTORIUM , SI_OFFERTORIUM , SCB_NONE );
+ set_sc_with_vfx( AB_ORATIO , SC_ORATIO , SCB_NONE );
+ status->set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SCB_VIT );
+ status->set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SCB_LUK );
+ status->set_sc( AB_RENOVATIO , SC_RENOVATIO , SCB_REGEN );
+ status->set_sc( AB_EXPIATIO , SC_EXPIATIO , SCB_ATK_ELE );
+ status->set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SCB_NONE );
+ status->set_sc( AB_SECRAMENT , SC_SECRAMENT , SCB_NONE );
+ status->set_sc( AB_OFFERTORIUM , SC_OFFERTORIUM , SCB_NONE );
/**
* Warlock
**/
add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
- set_sc_with_vfx( WL_FROSTMISTY , SC_FROSTMISTY , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF );
- set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_AGI|SCB_DEX );
- set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_MATK);
- set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
- set_sc( WL_TELEKINESIS_INTENSE, SC_TELEKINESIS_INTENSE , SI_TELEKINESIS_INTENSE , SCB_MATK );
+ set_sc_with_vfx( WL_FROSTMISTY , SC_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF );
+ status->set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_AGI|SCB_DEX );
+ status->set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SCB_MATK);
+ status->set_sc( WL_STASIS , SC_STASIS , SCB_NONE );
+ status->set_sc( WL_TELEKINESIS_INTENSE, SC_TELEKINESIS_INTENSE , SCB_MATK );
/**
* Ranger
**/
- set_sc( RA_FEARBREEZE , SC_FEARBREEZE , SI_FEARBREEZE , SCB_NONE );
- set_sc( RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SI_ELECTRICSHOCKER , SCB_NONE );
- set_sc( RA_WUGDASH , SC_WUGDASH , SI_WUGDASH , SCB_SPEED );
- set_sc( RA_CAMOUFLAGE , SC_CAMOUFLAGE , SI_CAMOUFLAGE , SCB_SPEED );
+ status->set_sc( RA_FEARBREEZE , SC_FEARBREEZE , SCB_NONE );
+ status->set_sc( RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SCB_NONE );
+ status->set_sc( RA_WUGDASH , SC_WUGDASH , SCB_SPEED );
+ status->set_sc( RA_CAMOUFLAGE , SC_CAMOUFLAGE , SCB_SPEED );
add_sc( RA_MAGENTATRAP , SC_ARMOR_PROPERTY );
add_sc( RA_COBALTTRAP , SC_ARMOR_PROPERTY );
add_sc( RA_MAIZETRAP , SC_ARMOR_PROPERTY );
add_sc( RA_VERDURETRAP , SC_ARMOR_PROPERTY );
add_sc( RA_FIRINGTRAP , SC_BURNING );
add_sc( RA_ICEBOUNDTRAP , SC_FROSTMISTY );
- set_sc( RA_UNLIMIT , SC_UNLIMIT , SI_UNLIMIT , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+ status->set_sc( RA_UNLIMIT , SC_UNLIMIT , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
/**
* Mechanic
**/
- set_sc( NC_ACCELERATION , SC_ACCELERATION , SI_ACCELERATION , SCB_SPEED );
- set_sc( NC_HOVERING , SC_HOVERING , SI_HOVERING , SCB_SPEED );
- set_sc( NC_SHAPESHIFT , SC_SHAPESHIFT , SI_SHAPESHIFT , SCB_DEF_ELE );
- set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE );
- set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
- set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE );
- set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_DEF|SCB_MDEF );
- set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE );
+ status->set_sc( NC_ACCELERATION , SC_ACCELERATION , SCB_SPEED );
+ status->set_sc( NC_HOVERING , SC_HOVERING , SCB_SPEED );
+ status->set_sc( NC_SHAPESHIFT , SC_SHAPESHIFT , SCB_DEF_ELE );
+ status->set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SCB_FLEE );
+ status->set_sc( NC_ANALYZE , SC_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+ status->set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SCB_NONE );
+ status->set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SCB_DEF|SCB_MDEF );
+ status->set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SCB_NONE );
/**
* Royal Guard
**/
- set_sc( LG_REFLECTDAMAGE , SC_LG_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE );
- set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP );
- set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE );
- set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF );
- set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
- set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
- set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD );
- set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
- set_sc( LG_KINGS_GRACE , SC_KINGS_GRACE , SI_KINGS_GRACE , SCB_NONE );
+ status->set_sc( LG_REFLECTDAMAGE , SC_LG_REFLECTDAMAGE , SCB_NONE );
+ status->set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SCB_MAXHP );
+ status->set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SCB_NONE );
+ status->set_sc( LG_PRESTIGE , SC_PRESTIGE , SCB_DEF );
+ status->set_sc( LG_BANDING , SC_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
+ status->set_sc( LG_PIETY , SC_BENEDICTIO , SCB_DEF_ELE );
+ status->set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SCB_DEF|SCB_ASPD );
+ status->set_sc( LG_INSPIRATION , SC_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
+ status->set_sc( LG_KINGS_GRACE , SC_KINGS_GRACE , SCB_NONE );
/**
* Shadow Chaser
**/
- set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE );
- set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE );
- set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE );
- set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINT , SCB_ASPD );
- set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
- set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE );
- set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK );
- set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED );
- set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE );
- set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE );
- 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_STRIPACCESSARY , SC__STRIPACCESSARY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
- set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
+ status->set_sc( SC_REPRODUCE , SC__REPRODUCE , SCB_NONE );
+ status->set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SCB_NONE );
+ status->set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SCB_NONE );
+ status->set_sc( SC_BODYPAINT , SC__BODYPAINT , SCB_ASPD );
+ status->set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
+ status->set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SCB_NONE );
+ status->set_sc( SC_ENERVATION , SC__ENERVATION , SCB_BATK );
+ status->set_sc( SC_GROOMY , SC__GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED );
+ status->set_sc( SC_IGNORANCE , SC__IGNORANCE , SCB_NONE );
+ status->set_sc( SC_LAZINESS , SC__LAZINESS , SCB_FLEE );
+ status->set_sc( SC_UNLUCKY , SC__UNLUCKY , SCB_CRI|SCB_FLEE2 );
+ status->set_sc( SC_WEAKNESS , SC__WEAKNESS , SCB_FLEE2|SCB_MAXHP );
+ status->set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
+ set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SCB_NONE );
add_sc( SC_CHAOSPANIC , SC__CHAOS );
add_sc( SC_MAELSTROM , SC__MAELSTROM );
add_sc( SC_BLOODYLUST , SC_BERSERK );
@@ -656,113 +665,132 @@ void initChangeTables(void) {
**/
add_sc( SR_DRAGONCOMBO , SC_STUN );
add_sc( SR_EARTHSHAKER , SC_STUN );
- set_sc( SR_FALLENEMPIRE , SC_FALLENEMPIRE , SI_FALLENEMPIRE , SCB_NONE );
- set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE );
- set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE );
- set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE );
- set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
- set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GENTLETOUCH_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
- set_sc( SR_GENTLETOUCH_CHANGE , SC_GENTLETOUCH_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
- set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GENTLETOUCH_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_DEF2|SCB_REGEN );
- set_sc( SR_FLASHCOMBO , SC_FLASHCOMBO , SI_FLASHCOMBO , SCB_WATK );
+ status->set_sc( SR_FALLENEMPIRE , SC_FALLENEMPIRE , SCB_NONE );
+ status->set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SCB_NONE );
+ set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SCB_NONE );
+ status->set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SCB_NONE );
+ status->set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
+ status->set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GENTLETOUCH_ENERGYGAIN , SCB_NONE );
+ status->set_sc( SR_GENTLETOUCH_CHANGE , SC_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
+ status->set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GENTLETOUCH_REVITALIZE , SCB_MAXHP|SCB_DEF2|SCB_REGEN );
+ status->set_sc( SR_FLASHCOMBO , SC_FLASHCOMBO , SCB_WATK );
/**
* Wanderer / Minstrel
**/
- set_sc( WA_SWING_DANCE , SC_SWING , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD );
- set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONY_LOVE , SI_SYMPHONYOFLOVERS , SCB_MDEF );
- set_sc( WA_MOONLIT_SERENADE , SC_MOONLIT_SERENADE , SI_MOONLITSERENADE , SCB_MATK );
- set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_WATK );
- set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 );
- set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
- set_sc_with_vfx(WM_POEMOFNETHERWORLD, SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE);
- set_sc_with_vfx( WM_VOICEOFSIREN , SC_SIREN , SI_SIREN , SCB_NONE );
- set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE );
- set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
- set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
- set_sc( WM_SONG_OF_MANA , SC_SONG_OF_MANA , SI_SONG_OF_MANA , SCB_NONE );
- set_sc( WM_DANCE_WITH_WUG , SC_DANCE_WITH_WUG , SI_DANCEWITHWUG , SCB_ASPD );
- set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAY_NIGHT_FEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
- set_sc( WM_LERADS_DEW , SC_LERADS_DEW , SI_LERADSDEW , SCB_MAXHP );
- set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_INT );
- set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SI_WARCRYOFBEYOND , SCB_STR|SCB_CRI|SCB_MAXHP );
- set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
- set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SI_FRIGG_SONG , SCB_MAXHP );
+ status->set_sc( WA_SWING_DANCE , SC_SWING , SCB_SPEED|SCB_ASPD );
+ status->set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONY_LOVE , SCB_MDEF );
+ status->set_sc( WA_MOONLIT_SERENADE , SC_MOONLIT_SERENADE , SCB_MATK );
+ status->set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SCB_WATK );
+ status->set_sc( MI_ECHOSONG , SC_ECHOSONG , SCB_DEF2 );
+ status->set_sc( MI_HARMONIZE , SC_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ set_sc_with_vfx(WM_POEMOFNETHERWORLD, SC_NETHERWORLD , SCB_NONE);
+ set_sc_with_vfx( WM_VOICEOFSIREN , SC_SIREN , SCB_NONE );
+ set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEP_SLEEP , SCB_NONE );
+ status->set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SCB_NONE );
+ status->set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
+ status->set_sc( WM_SONG_OF_MANA , SC_SONG_OF_MANA , SCB_NONE );
+ status->set_sc( WM_DANCE_WITH_WUG , SC_DANCE_WITH_WUG , SCB_ASPD );
+ status->set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAY_NIGHT_FEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
+ status->set_sc( WM_LERADS_DEW , SC_LERADS_DEW , SCB_MAXHP );
+ status->set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SCB_INT );
+ status->set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SCB_STR|SCB_CRI|SCB_MAXHP );
+ status->set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SCB_NONE );
+ status->set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SCB_MAXHP );
+ status->set_sc( WM_SEVERE_RAINSTORM , SC_NO_SWITCH_EQUIP , SCB_NONE );
/**
* Sorcerer
**/
- set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
- set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
- set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
- set_sc_with_vfx( SO_DIAMONDDUST , SC_COLD , SI_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it.
- set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE );
- set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
+ status->set_sc( SO_FIREWALK , SC_PROPERTYWALK , SCB_NONE );
+ status->set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SCB_NONE );
+ status->set_sc( SO_SPELLFIST , SC_SPELLFIST , SCB_NONE );
+ set_sc_with_vfx( SO_DIAMONDDUST , SC_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it.
+ status->set_sc( SO_CLOUD_KILL , SC_POISON , SCB_NONE );
+ status->set_sc( SO_STRIKING , SC_STRIKING , SCB_WATK|SCB_CRI );
add_sc( SO_WARMER , SC_WARMER ); // At the moment, no icon on officials
- set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
- set_sc( SO_ARRULLO , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE );
- set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
- set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
- set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
- set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ status->set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SCB_NONE );
+ status->set_sc( SO_ARRULLO , SC_DEEP_SLEEP , SCB_NONE );
+ status->set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ status->set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ status->set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ status->set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
add_sc( SO_ELEMENTAL_SHIELD , SC_SAFETYWALL );
/**
* Genetic
**/
- set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
- set_sc( GN_THORNS_TRAP , SC_THORNS_TRAP , SI_THORNTRAP , SCB_NONE );
- set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOOD_SUCKER , SI_BLOODSUCKER , SCB_NONE );
- set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
- set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_FIRE_EXPANSION_SMOKE_POWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
- set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_FIRE_EXPANSION_TEAR_GAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
- set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
+ status->set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SCB_SPEED );
+ status->set_sc( GN_THORNS_TRAP , SC_THORNS_TRAP , SCB_NONE );
+ set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOOD_SUCKER , SCB_NONE );
+ status->set_sc( GN_WALLOFTHORN , SC_STOP , SCB_NONE );
+ status->set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_FIRE_EXPANSION_SMOKE_POWDER , SCB_NONE );
+ status->set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
+ status->set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SCB_INT );
+
+ /**
+ * Summoner
+ */
+ status->set_sc(SU_HIDE, SC_SUHIDE, SCB_SPEED);
+ add_sc(SU_SCRATCH, SC_BLOODING);
+ status->set_sc(SU_STOOP, SC_SU_STOOP, SCB_NONE);
+ status->set_sc(SU_FRESHSHRIMP, SC_FRESHSHRIMP, SCB_NONE);
+ add_sc(SU_SV_STEMSPEAR, SC_BLOODING);
+ status->set_sc(SU_CN_POWDERING, SC_CATNIPPOWDER, SCB_WATK | SCB_SPEED | SCB_REGEN);
+ add_sc(SU_CN_METEOR, SC_CURSE);
+ set_sc_with_vfx(SU_SV_ROOTTWIST, SC_SV_ROOTTWIST, SCB_NONE);
+ add_sc(SU_SCAROFTAROU, SC_STUN );
+ status->set_sc(SU_SCAROFTAROU, SC_BITESCAR, SCB_NONE);
+ status->set_sc(SU_ARCLOUSEDASH, SC_ARCLOUSEDASH, SCB_AGI | SCB_SPEED);
+ add_sc(SU_LUNATICCARROTBEAT, SC_STUN);
+ status->set_sc(SU_TUNAPARTY, SC_TUNAPARTY, SCB_NONE);
+ status->set_sc(SU_BUNCHOFSHRIMP, SC_SHRIMP, SCB_BATK | SCB_MATK);
// Elemental Spirit summoner's 'side' status changes.
- set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
- set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL );
- set_sc( EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SI_WATER_SCREEN_OPTION , SCB_NONE );
- set_sc( EL_WATER_DROP , SC_WATER_DROP_OPTION , SI_WATER_DROP_OPTION , SCB_ALL );
- set_sc( EL_WATER_BARRIER , SC_WATER_BARRIER , SI_WATER_BARRIER , SCB_WATK|SCB_FLEE );
- set_sc( EL_WIND_STEP , SC_WIND_STEP_OPTION , SI_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE );
- set_sc( EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SI_WIND_CURTAIN_OPTION , SCB_ALL );
- set_sc( EL_ZEPHYR , SC_ZEPHYR , SI_ZEPHYR , SCB_FLEE );
- set_sc( EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SI_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP );
- set_sc( EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SI_STONE_SHIELD_OPTION , SCB_ALL );
- set_sc( EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SI_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED );
- set_sc( EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SI_PYROTECHNIC_OPTION , SCB_WATK );
- set_sc( EL_HEATER , SC_HEATER_OPTION , SI_HEATER_OPTION , SCB_WATK );
- set_sc( EL_TROPIC , SC_TROPIC_OPTION , SI_TROPIC_OPTION , SCB_WATK );
- set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK );
- set_sc( EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK );
- set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK );
- set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_ASPD );
- set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_ASPD );
- set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_ASPD );
- set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_MAXHP );
- set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_MAXHP );
- set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_MAXHP );
- set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
- set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
- set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
+ status->set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
+ status->set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SCB_ALL );
+ status->set_sc( EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SCB_NONE );
+ status->set_sc( EL_WATER_DROP , SC_WATER_DROP_OPTION , SCB_ALL );
+ status->set_sc( EL_WATER_BARRIER , SC_WATER_BARRIER , SCB_WATK|SCB_FLEE );
+ status->set_sc( EL_WIND_STEP , SC_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE );
+ status->set_sc( EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SCB_ALL );
+ status->set_sc( EL_ZEPHYR , SC_ZEPHYR , SCB_FLEE );
+ status->set_sc( EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP );
+ status->set_sc( EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SCB_ALL );
+ status->set_sc( EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED );
+ status->set_sc( EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SCB_WATK );
+ status->set_sc( EL_HEATER , SC_HEATER_OPTION , SCB_WATK );
+ status->set_sc( EL_TROPIC , SC_TROPIC_OPTION , SCB_WATK );
+ status->set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SCB_MATK );
+ status->set_sc( EL_COOLER , SC_COOLER_OPTION , SCB_MATK );
+ status->set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SCB_MATK );
+ status->set_sc( EL_GUST , SC_GUST_OPTION , SCB_ASPD );
+ status->set_sc( EL_BLAST , SC_BLAST_OPTION , SCB_ASPD );
+ status->set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SCB_ASPD );
+ status->set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SCB_MAXHP );
+ status->set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SCB_MAXHP );
+ status->set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SCB_MAXHP );
+ status->set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SCB_ALL );
+ status->set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SCB_DEF );
+ status->set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SCB_SPEED );
add_sc( KO_YAMIKUMO , SC_HIDING );
- set_sc_with_vfx( KO_JYUMONJIKIRI , SC_KO_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE );
+ set_sc_with_vfx( KO_JYUMONJIKIRI , SC_KO_JYUMONJIKIRI , SCB_NONE );
add_sc( KO_MAKIBISHI , SC_STUN );
- set_sc( KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SI_MEIKYOUSISUI , SCB_NONE );
- set_sc( KO_KYOUGAKU , SC_KYOUGAKU , SI_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ status->set_sc( KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SCB_NONE );
+ status->set_sc( KO_KYOUGAKU , SC_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
add_sc( KO_JYUSATSU , SC_CURSE );
- set_sc( KO_ZENKAI , SC_ZENKAI , SI_ZENKAI , SCB_NONE );
- set_sc( KO_IZAYOI , SC_IZAYOI , SI_IZAYOI , SCB_MATK );
- set_sc( KG_KYOMU , SC_KYOMU , SI_KYOMU , SCB_NONE );
- set_sc( KG_KAGEMUSYA , SC_KAGEMUSYA , SI_KAGEMUSYA , SCB_NONE );
- set_sc( KG_KAGEHUMI , SC_KG_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE );
- set_sc( OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK );
- set_sc_with_vfx( OB_AKAITSUKI, SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
- set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
+ status->set_sc( KO_ZENKAI , SC_ZENKAI , SCB_NONE );
+ status->set_sc( KO_IZAYOI , SC_IZAYOI , SCB_MATK );
+ status->set_sc( KG_KYOMU , SC_KYOMU , SCB_NONE );
+ status->set_sc( KG_KAGEMUSYA , SC_KAGEMUSYA , SCB_NONE );
+ status->set_sc( KG_KAGEHUMI , SC_KG_KAGEHUMI , SCB_NONE );
+ status->set_sc( OB_ZANGETSU , SC_ZANGETSU , SCB_MATK|SCB_BATK );
+ set_sc_with_vfx( OB_AKAITSUKI, SC_AKAITSUKI , SCB_NONE );
+ status->set_sc( OB_OBOROGENSOU , SC_GENSOU , SCB_NONE );
- set_sc( ALL_FULL_THROTTLE , SC_FULL_THROTTLE , SI_FULL_THROTTLE , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ status->set_sc( ALL_FULL_THROTTLE , SC_FULL_THROTTLE , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
add_sc( ALL_REVERSEORCISH , SC_ORCISH );
- set_sc( ALL_ANGEL_PROTECT , SC_ANGEL_PROTECT , SI_ANGEL_PROTECT , SCB_REGEN );
+ status->set_sc( ALL_ANGEL_PROTECT , SC_ANGEL_PROTECT , SCB_REGEN );
add_sc( NPC_WIDEHEALTHFEAR , SC_FEAR );
add_sc( NPC_WIDEBODYBURNNING , SC_BURNING );
@@ -771,228 +799,24 @@ void initChangeTables(void) {
add_sc( NPC_WIDE_DEEP_SLEEP , SC_DEEP_SLEEP );
add_sc( NPC_WIDESIREN , SC_SIREN );
- set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SI_ILLUSIONDOPING , SCB_HIT );
+ set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SCB_HIT );
// Storing the target job rather than simply SC_SOULLINK simplifies code later on.
- status->dbs->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
- status->dbs->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK,
- status->dbs->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
- status->dbs->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE,
- status->dbs->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER,
- status->dbs->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE,
- status->dbs->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT,
- status->dbs->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD,
- status->dbs->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST,
- status->dbs->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER,
- status->dbs->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE,
- status->dbs->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN,
- status->dbs->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH,
- status->dbs->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER,
- status->dbs->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
-
- // Status that don't have a skill associated.
- status->dbs->IconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50;
- status->dbs->IconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90;
- status->dbs->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1;
- status->dbs->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2;
- status->dbs->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3;
- status->dbs->IconChangeTable[SC_MOVHASTE_POTION] = SI_MOVHASTE_POTION;
- status->dbs->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY;
- status->dbs->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE;
- status->dbs->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY;
- status->dbs->IconChangeTable[SC_MOVESLOW_POTION] = SI_MOVESLOW_POTION;
- status->dbs->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR;
- status->dbs->IconChangeTable[SC_MIRACLE] = SI_SOULLINK;
- status->dbs->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE;
- status->dbs->IconChangeTable[SC_FOOD_STR] = SI_FOOD_STR;
- status->dbs->IconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI;
- status->dbs->IconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT;
- status->dbs->IconChangeTable[SC_FOOD_INT] = SI_FOOD_INT;
- status->dbs->IconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX;
- status->dbs->IconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK;
- status->dbs->IconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE;
- status->dbs->IconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT;
- status->dbs->IconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
- status->dbs->IconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
- status->dbs->IconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
- status->dbs->IconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
- status->dbs->IconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
- status->dbs->IconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
- status->dbs->IconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER;
- status->dbs->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER;
- status->dbs->IconChangeTable[SC_FOOD_CRITICALSUCCESSVALUE] = SI_FOOD_CRITICALSUCCESSVALUE;
- status->dbs->IconChangeTable[SC_MORA_BUFF] = SI_MORA_BUFF;
- status->dbs->IconChangeTable[SC_BUCHEDENOEL] = SI_BUCHEDENOEL;
- status->dbs->IconChangeTable[SC_PHI_DEMON] = SI_PHI_DEMON;
-
- // Cash Items
- status->dbs->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
- status->dbs->IconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
- status->dbs->IconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
- status->dbs->IconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
- status->dbs->IconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
- status->dbs->IconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
- status->dbs->IconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP;
- status->dbs->IconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM;
- status->dbs->IconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP;
- status->dbs->IconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY;
- status->dbs->IconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM;
- status->dbs->IconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF;
- status->dbs->IconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF;
- status->dbs->IconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT;
- status->dbs->IconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE;
- status->dbs->IconChangeTable[SC_HEALPLUS] = SI_HEALPLUS;
- status->dbs->IconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
- status->dbs->IconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
- status->dbs->IconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD;
- status->dbs->IconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD;
- status->dbs->IconChangeTable[SC_ACARAJE] = SI_ACARAJE;
- status->dbs->IconChangeTable[SC_TARGET_ASPD] = SI_TARGET_ASPD;
- status->dbs->IconChangeTable[SC_ATKER_ASPD] = SI_ATKER_ASPD;
- status->dbs->IconChangeTable[SC_ATKER_MOVESPEED] = SI_ATKER_MOVESPEED;
- status->dbs->IconChangeTable[SC_CUP_OF_BOZA] = SI_CUP_OF_BOZA;
- status->dbs->IconChangeTable[SC_OVERLAPEXPUP] = SI_OVERLAPEXPUP;
- status->dbs->IconChangeTable[SC_GM_BATTLE] = SI_GM_BATTLE;
- status->dbs->IconChangeTable[SC_GM_BATTLE2] = SI_GM_BATTLE2;
- status->dbs->IconChangeTable[SC_2011RWC] = SI_2011RWC;
- status->dbs->IconChangeTable[SC_STR_SCROLL] = SI_STR_SCROLL;
- status->dbs->IconChangeTable[SC_INT_SCROLL] = SI_INT_SCROLL;
- status->dbs->IconChangeTable[SC_STEAMPACK] = SI_STEAMPACK;
- status->dbs->IconChangeTable[SC_MAGIC_CANDY] = SI_MAGIC_CANDY;
- status->dbs->IconChangeTable[SC_M_LIFEPOTION] = SI_M_LIFEPOTION;
- status->dbs->IconChangeTable[SC_G_LIFEPOTION] = SI_G_LIFEPOTION;
- status->dbs->IconChangeTable[SC_MYSTICPOWDER] = SI_MYSTICPOWDER;
-
- // Eden Crystal Synthesis
- status->dbs->IconChangeTable[SC_QUEST_BUFF1] = SI_QUEST_BUFF1;
- status->dbs->IconChangeTable[SC_QUEST_BUFF2] = SI_QUEST_BUFF2;
- status->dbs->IconChangeTable[SC_QUEST_BUFF3] = SI_QUEST_BUFF3;
-
- // Geffen Magic Tournament
- status->dbs->IconChangeTable[SC_GEFFEN_MAGIC1] = SI_GEFFEN_MAGIC1;
- status->dbs->IconChangeTable[SC_GEFFEN_MAGIC2] = SI_GEFFEN_MAGIC2;
- status->dbs->IconChangeTable[SC_GEFFEN_MAGIC3] = SI_GEFFEN_MAGIC3;
- status->dbs->IconChangeTable[SC_FENRIR_CARD] = SI_FENRIR_CARD;
-
- // MVP Scrolls
- status->dbs->IconChangeTable[SC_MVPCARD_TAOGUNKA] = SI_MVPCARD_TAOGUNKA;
- status->dbs->IconChangeTable[SC_MVPCARD_MISTRESS] = SI_MVPCARD_MISTRESS;
- status->dbs->IconChangeTable[SC_MVPCARD_ORCHERO] = SI_MVPCARD_ORCHERO;
- status->dbs->IconChangeTable[SC_MVPCARD_ORCLORD] = SI_MVPCARD_ORCLORD;
-
- // Mercenary Bonus Effects
- status->dbs->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE;
- status->dbs->IconChangeTable[SC_MER_ATK] = SI_MER_ATK;
- status->dbs->IconChangeTable[SC_MER_HP] = SI_MER_HP;
- status->dbs->IconChangeTable[SC_MER_SP] = SI_MER_SP;
- status->dbs->IconChangeTable[SC_MER_HIT] = SI_MER_HIT;
-
- // Warlock Spheres
- status->dbs->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1;
- status->dbs->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2;
- status->dbs->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3;
- status->dbs->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4;
- status->dbs->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5;
-
- // Warlock Preserved spells
- status->dbs->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
- status->dbs->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
- status->dbs->IconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
- status->dbs->IconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
- status->dbs->IconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
- status->dbs->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
- status->dbs->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7;
-
- // Mechanic status icon
- status->dbs->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
- status->dbs->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
- status->dbs->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
- status->dbs->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
-
- // Guillotine Cross status icons
- status->dbs->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
- status->dbs->IconChangeTable[SC_TOXIN] = SI_TOXIN;
- status->dbs->IconChangeTable[SC_PARALYSE] = SI_PARALYSE;
- status->dbs->IconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
- status->dbs->IconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
- status->dbs->IconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
- status->dbs->IconChangeTable[SC_PYREXIA] = SI_PYREXIA;
- status->dbs->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
- status->dbs->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
-
- // Royal Guard status icons
- status->dbs->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
- status->dbs->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
- status->dbs->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
- status->dbs->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
-
- // Sura status icon
- status->dbs->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
-
- // Genetics Food items / Throwable items status icons
- status->dbs->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
- status->dbs->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
- status->dbs->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
- status->dbs->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
- status->dbs->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
- status->dbs->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
- status->dbs->IconChangeTable[SC_BOOST500] |= SI_BOOST500;
- status->dbs->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
- status->dbs->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
- status->dbs->IconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
- status->dbs->IconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
- status->dbs->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
- status->dbs->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
- status->dbs->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
- status->dbs->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
- status->dbs->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
- status->dbs->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
- status->dbs->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
- status->dbs->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
- status->dbs->IconChangeTable[SC_PROMOTE_HEALTH_RESERCH] = SI_PROMOTE_HEALTH_RESERCH;
- status->dbs->IconChangeTable[SC_ENERGY_DRINK_RESERCH] = SI_ENERGY_DRINK_RESERCH;
-
- // Elemental Spirit's 'side' status change icons.
- status->dbs->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
- status->dbs->IconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
- status->dbs->IconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
- status->dbs->IconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
- status->dbs->IconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
- status->dbs->IconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
- status->dbs->IconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
- status->dbs->IconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
- status->dbs->IconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
- status->dbs->IconChangeTable[SC_HEATER] = SI_HEATER;
- status->dbs->IconChangeTable[SC_TROPIC] = SI_TROPIC;
- status->dbs->IconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
- status->dbs->IconChangeTable[SC_COOLER] = SI_COOLER;
- status->dbs->IconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
- status->dbs->IconChangeTable[SC_GUST] = SI_GUST;
- status->dbs->IconChangeTable[SC_BLAST] = SI_BLAST;
- status->dbs->IconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
- status->dbs->IconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
- status->dbs->IconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
- status->dbs->IconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
- status->dbs->IconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
- status->dbs->IconChangeTable[SC_REBOUND] = SI_REBOUND;
- status->dbs->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
- status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
-
- // Costumes
- status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
- status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
- status->dbs->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
- status->dbs->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC;
- status->dbs->IconChangeTable[SC_LJOSALFAR] = SI_LJOSALFAR;
- status->dbs->IconChangeTable[SC_MERMAID_LONGING] = SI_MERMAID_LONGING;
- status->dbs->IconChangeTable[SC_HAT_EFFECT] = SI_HAT_EFFECT;
- status->dbs->IconChangeTable[SC_FLOWERSMOKE] = SI_FLOWERSMOKE;
- status->dbs->IconChangeTable[SC_FSTONE] = SI_FSTONE;
- status->dbs->IconChangeTable[SC_HAPPINESS_STAR] = SI_HAPPINESS_STAR;
- status->dbs->IconChangeTable[SC_MAPLE_FALLS] = SI_MAPLE_FALLS;
- status->dbs->IconChangeTable[SC_TIME_ACCESSORY] = SI_TIME_ACCESSORY;
- status->dbs->IconChangeTable[SC_MAGICAL_FEATHER] = SI_MAGICAL_FEATHER;
- status->dbs->IconChangeTable[SC_BLOSSOM_FLUTTERING] = SI_BLOSSOM_FLUTTERING;
+ status->dbs->Skill2SCTable[skill->get_index(SL_ALCHEMIST)] = (sc_type)MAPID_ALCHEMIST,
+ status->dbs->Skill2SCTable[skill->get_index(SL_MONK)] = (sc_type)MAPID_MONK,
+ status->dbs->Skill2SCTable[skill->get_index(SL_STAR)] = (sc_type)MAPID_STAR_GLADIATOR,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SAGE)] = (sc_type)MAPID_SAGE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_CRUSADER)] = (sc_type)MAPID_CRUSADER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SUPERNOVICE)] = (sc_type)MAPID_SUPER_NOVICE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_KNIGHT)] = (sc_type)MAPID_KNIGHT,
+ status->dbs->Skill2SCTable[skill->get_index(SL_WIZARD)] = (sc_type)MAPID_WIZARD,
+ status->dbs->Skill2SCTable[skill->get_index(SL_PRIEST)] = (sc_type)MAPID_PRIEST,
+ status->dbs->Skill2SCTable[skill->get_index(SL_BARDDANCER)] = (sc_type)MAPID_BARDDANCER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_ROGUE)] = (sc_type)MAPID_ROGUE,
+ status->dbs->Skill2SCTable[skill->get_index(SL_ASSASIN)] = (sc_type)MAPID_ASSASSIN,
+ status->dbs->Skill2SCTable[skill->get_index(SL_BLACKSMITH)] = (sc_type)MAPID_BLACKSMITH,
+ status->dbs->Skill2SCTable[skill->get_index(SL_HUNTER)] = (sc_type)MAPID_HUNTER,
+ status->dbs->Skill2SCTable[skill->get_index(SL_SOULLINKER)] = (sc_type)MAPID_SOUL_LINKER,
// Other SC which are not necessarily associated to skills.
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD;
@@ -1061,6 +885,13 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_PHI_DEMON] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MAGIC_CANDY] |= SCB_MATK | SCB_ALL;
status->dbs->ChangeFlagTable[SC_MYSTICPOWDER] |= SCB_FLEE | SCB_LUK;
+ status->dbs->ChangeFlagTable[SC_POPECOOKIE] |= SCB_BASE | SCB_BATK | SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_VITALIZE_POTION] |= SCB_BATK | SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_SKF_MATK] |= SCB_MATK;
+ status->dbs->ChangeFlagTable[SC_SKF_ATK] |= SCB_BATK;
+ status->dbs->ChangeFlagTable[SC_SKF_ASPD] |= SCB_ASPD;
+ status->dbs->ChangeFlagTable[SC_SKF_CAST] |= SCB_NONE;
+ status->dbs->ChangeFlagTable[SC_ALMIGHTY] |= SCB_BATK | SCB_MATK;
// Cash Items
status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR;
@@ -1153,7 +984,11 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCHERO] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCLORD] |= SCB_ALL;
+ // Clan System
+ status->dbs->ChangeFlagTable[SC_CLAN_INFO] |= SCB_NONE;
+
// Costumes
+ status->dbs->ChangeFlagTable[SC_DRESS_UP] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE;
@@ -1169,53 +1004,11 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_MAGICAL_FEATHER] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_BLOSSOM_FLUTTERING] |= SCB_NONE;
- /* status->dbs->DisplayType Table [Ind/Hercules] */
- status->dbs->DisplayType[SC_ALL_RIDING] = true;
- status->dbs->DisplayType[SC_PUSH_CART] = true;
- status->dbs->DisplayType[SC_SUMMON1] = true;
- status->dbs->DisplayType[SC_SUMMON2] = true;
- status->dbs->DisplayType[SC_SUMMON3] = true;
- status->dbs->DisplayType[SC_SUMMON4] = true;
- status->dbs->DisplayType[SC_SUMMON5] = true;
- status->dbs->DisplayType[SC_CAMOUFLAGE] = true;
- status->dbs->DisplayType[SC_DUPLELIGHT] = true;
- status->dbs->DisplayType[SC_ORATIO] = true;
- status->dbs->DisplayType[SC_FROSTMISTY] = true;
- status->dbs->DisplayType[SC_VENOMIMPRESS] = true;
- status->dbs->DisplayType[SC_HALLUCINATIONWALK] = true;
- status->dbs->DisplayType[SC_ROLLINGCUTTER] = true;
- status->dbs->DisplayType[SC_BANDING] = true;
- status->dbs->DisplayType[SC_COLD] = true;
- status->dbs->DisplayType[SC_DEEP_SLEEP] = true;
- status->dbs->DisplayType[SC_CURSEDCIRCLE_ATKER] = true;
- status->dbs->DisplayType[SC_CURSEDCIRCLE_TARGET] = true;
- status->dbs->DisplayType[SC_BLOOD_SUCKER] = true;
- status->dbs->DisplayType[SC__SHADOWFORM] = true;
- status->dbs->DisplayType[SC_MONSTER_TRANSFORM] = true;
-
- // Costumes
- status->dbs->DisplayType[SC_MOONSTAR] = true;
- status->dbs->DisplayType[SC_SUPER_STAR] = true;
- status->dbs->DisplayType[SC_STRANGELIGHTS] = true;
- status->dbs->DisplayType[SC_DECORATION_OF_MUSIC] = true;
- status->dbs->DisplayType[SC_LJOSALFAR] = true;
- status->dbs->DisplayType[SC_MERMAID_LONGING] = true;
- status->dbs->DisplayType[SC_HAT_EFFECT] = true;
- status->dbs->DisplayType[SC_FLOWERSMOKE] = true;
- status->dbs->DisplayType[SC_FSTONE] = true;
- status->dbs->DisplayType[SC_HAPPINESS_STAR] = true;
- status->dbs->DisplayType[SC_MAPLE_FALLS] = true;
- status->dbs->DisplayType[SC_TIME_ACCESSORY] = true;
- status->dbs->DisplayType[SC_MAGICAL_FEATHER] = true;
- status->dbs->DisplayType[SC_BLOSSOM_FLUTTERING] = true;
-
- if( !battle_config.display_hallucination ) //Disable Hallucination.
- status->dbs->IconChangeTable[SC_ILLUSION] = SI_BLANK;
#undef add_sc
#undef set_sc_with_vfx
}
-void initDummyData(void)
+static void initDummyData(void)
{
memset(&status->dummy, 0, sizeof(status->dummy));
status->dummy.hp =
@@ -1237,15 +1030,23 @@ void initDummyData(void)
}
//For copying a status_data structure from b to a, without overwriting current Hp and Sp
-static inline void status_cpy(struct status_data* a, const struct status_data* b)
+static void status_copy(struct status_data *a, const struct status_data *b)
{
+ nullpo_retv(a);
+ nullpo_retv(b);
memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
}
-//Sets HP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players) It will always succeed (overrides Berserk block), but it can't kill.
-int status_set_hp(struct block_list *bl, unsigned int hp, int flag) {
+/**
+ * Sets HP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired HP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of HP gained.
+ */
+static int status_set_hp(struct block_list *bl, unsigned int hp, enum status_heal_flag flag)
+{
struct status_data *st;
if (hp < 1) return 0;
st = status->get_status_data(bl);
@@ -1255,14 +1056,20 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag) {
if (hp > st->max_hp) hp = st->max_hp;
if (hp == st->hp) return 0;
if (hp > st->hp)
- return status->heal(bl, hp - st->hp, 0, 1|flag);
+ return status->heal(bl, hp - st->hp, 0, STATUS_HEAL_FORCED | flag);
return status_zap(bl, st->hp - hp, 0);
}
-//Sets SP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players)
-int status_set_sp(struct block_list *bl, unsigned int sp, int flag) {
+/**
+ * Sets SP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired SP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of SP gained.
+ */
+static int status_set_sp(struct block_list *bl, unsigned int sp, enum status_heal_flag flag)
+{
struct status_data *st;
st = status->get_status_data(bl);
@@ -1272,11 +1079,13 @@ int status_set_sp(struct block_list *bl, unsigned int sp, int flag) {
if (sp > st->max_sp) sp = st->max_sp;
if (sp == st->sp) return 0;
if (sp > st->sp)
- return status->heal(bl, 0, sp - st->sp, 1|flag);
+ return status->heal(bl, 0, sp - st->sp, STATUS_HEAL_FORCED | flag);
return status_zap(bl, 0, st->sp - sp);
}
-int status_charge(struct block_list* bl, int64 hp, int64 sp) {
+static int status_charge(struct block_list *bl, int64 hp, int64 sp)
+{
+ nullpo_retr((int)(hp + sp), bl);
if(!(bl->type&BL_CONSUME))
return (int)(hp+sp); //Assume all was charged so there are no 'not enough' fails.
return status->damage(NULL, bl, hp, sp, 0, 3);
@@ -1287,11 +1096,13 @@ int status_charge(struct block_list* bl, int64 hp, int64 sp) {
//If flag&2, fail if target does not has enough to subtract.
//If flag&4, if killed, mob must not give exp/loot.
//flag will be set to &8 when damaging sp of a dead character
-int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, int64 in_sp, int walkdelay, int flag) {
+static int status_damage(struct block_list *src, struct block_list *target, int64 in_hp, int64 in_sp, int walkdelay, int flag)
+{
struct status_data *st;
struct status_change *sc;
int hp,sp;
+ nullpo_ret(target);
/* From here onwards, we consider it a 32-type as the client does not support higher and the value doesn't get through percentage modifiers */
hp = (int)cap_value(in_hp,INT_MIN,INT_MAX);
sp = (int)cap_value(in_sp,INT_MIN,INT_MAX);
@@ -1300,12 +1111,12 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
sp = 0; //Not a valid SP target.
if (hp < 0) { //Assume absorbed damage.
- status->heal(target, -hp, 0, 1);
+ status->heal(target, -hp, 0, STATUS_HEAL_FORCED);
hp = 0;
}
if (sp < 0) {
- status->heal(target, 0, -sp, 1);
+ status->heal(target, 0, -sp, STATUS_HEAL_FORCED);
sp = 0;
}
@@ -1376,6 +1187,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
status_change_end(target, SC_CLOAKING, INVALID_TIMER);
status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(target, SC_SUHIDE, INVALID_TIMER);
if ((sce=sc->data[SC_ENDURE]) && !sce->val4 && !sc->data[SC_LKCONCENTRATION]) {
//Endure count is only reduced by non-players on non-gvg maps.
//val4 signals infinite endure. [Skotlex]
@@ -1522,16 +1334,27 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
return (int)(hp+sp);
}
-//Heals a character. If flag&1, this is forced healing (otherwise stuff like Berserk can block it)
-//If flag&2, when the player is healed, show the HP/SP heal effect.
-int status_heal(struct block_list *bl,int64 in_hp,int64 in_sp, int flag) {
+/**
+ * Heals a character.
+ *
+ * @param bl The target unit.
+ * @param in_hp Amount of HP to recover.
+ * @param in_sp Amount of SP to recover.
+ * @param flag Additional options, @see enum status_heal_flag.
+ * @return The amount of HP + SP healed.
+ */
+static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, enum status_heal_flag flag)
+{
struct status_data *st;
struct status_change *sc;
int hp,sp;
+ nullpo_ret(bl);
st = status->get_status_data(bl);
- if (st == &status->dummy || !st->hp)
+ if (st == &status->dummy)
+ return 0;
+ if (st->hp == 0 && (flag & STATUS_HEAL_ALLOWREVIVE) == 0)
return 0;
/* From here onwards, we consider it a 32-type as the client does not support higher and the value doesn't get through percentage modifiers */
@@ -1548,10 +1371,10 @@ int status_heal(struct block_list *bl,int64 in_hp,int64 in_sp, int flag) {
hp = 0;
}
- if(hp) {
- if( sc && sc->data[SC_BERSERK] ) {
- if( flag&1 )
- flag &= ~2;
+ if (hp != 0) {
+ if (sc && sc->data[SC_BERSERK] != NULL) {
+ if ((flag & STATUS_HEAL_FORCED) != 0)
+ flag &= ~STATUS_HEAL_SHOWEFFECT;
else
hp = 0;
}
@@ -1586,7 +1409,7 @@ int status_heal(struct block_list *bl,int64 in_hp,int64 in_sp, int flag) {
// send hp update to client
switch(bl->type) {
- case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag&2) ? 1 : 0); break;
+ case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag & STATUS_HEAL_SHOWEFFECT) != 0 ? 1 : 0); break;
case BL_MOB: mob->heal(BL_UCAST(BL_MOB, bl), hp); break;
case BL_HOM: homun->healed(BL_UCAST(BL_HOM, bl)); break;
case BL_MER: mercenary->heal(BL_UCAST(BL_MER, bl), hp, sp); break;
@@ -1602,7 +1425,8 @@ int status_heal(struct block_list *bl,int64 in_hp,int64 in_sp, int flag) {
//If rates are < 0, percent is of max HP/SP
//If !flag, this is heal, otherwise it is damage.
//Furthermore, if flag==2, then the target must not die from the subtraction.
-int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag) {
+static int status_percent_change(struct block_list *src, struct block_list *target, signed char hp_rate, signed char sp_rate, int flag)
+{
struct status_data *st;
unsigned int hp = 0, sp = 0;
@@ -1640,23 +1464,26 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe
if (flag)
status->damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
else
- status->heal(target, INT_MAX, 0, 0);
+ status->heal(target, INT_MAX, 0, STATUS_HEAL_DEFAULT);
}
if (sp > INT_MAX) {
sp -= INT_MAX;
if (flag)
status->damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
else
- status->heal(target, 0, INT_MAX, 0);
+ status->heal(target, 0, INT_MAX, STATUS_HEAL_DEFAULT);
}
if (flag)
return status->damage(src, target, hp, sp, 0, (!src||src==target?5:1));
- return status->heal(target, hp, sp, 0);
+ return status->heal(target, hp, sp, STATUS_HEAL_DEFAULT);
}
-int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp) {
+static int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
+{
struct status_data *st;
unsigned int hp, sp;
+
+ nullpo_ret(bl);
if (!status->isdead(bl)) return 0;
st = status->get_status_data(bl);
@@ -1690,11 +1517,13 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
return 1;
}
-int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp) {
+static int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp)
+{
struct status_data *st;
unsigned int hp, sp;
if (!status->isdead(bl)) return 0;
+ nullpo_ret(bl);
st = status->get_status_data(bl);
if (st == &status->dummy)
return 0; //Invalid target.
@@ -1726,17 +1555,18 @@ int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int
}
/*==========================================
-* Checks whether the src can use the skill on the target,
-* taking into account status/option of both source/target. [Skotlex]
-* flag:
-* 0 - Trying to use skill on target.
-* 1 - Cast bar is done.
-* 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
-* src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
-* target MAY Be null, in which case the checks are only to see
-* whether the source can cast or not the skill on the ground.
-*------------------------------------------*/
-int status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag) {
+ * Checks whether the src can use the skill on the target,
+ * taking into account status/option of both source/target. [Skotlex]
+ * flag:
+ * 0 - Trying to use skill on target.
+ * 1 - Cast bar is done.
+ * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
+ * src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
+ * target MAY Be null, in which case the checks are only to see
+ * whether the source can cast or not the skill on the ground.
+ *------------------------------------------*/
+static int status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag)
+{
struct status_data *st;
struct status_change *sc=NULL, *tsc;
int hide_flag;
@@ -1747,6 +1577,9 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
if (src != NULL && src->type != BL_PC && status->isdead(src))
return 0;
+ if (sd != NULL && sd->block_action.skill && skill_id) // *pcblock script command
+ return 0;
+
if (!skill_id) { //Normal attack checks.
if (!(st->mode&MD_CANATTACK))
return 0; //This mode is only needed for melee attacking.
@@ -1759,14 +1592,18 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
}
if( skill_id ) {
- if (src != NULL && (sd == NULL || sd->skillitem == 0)) {
+ if (src != NULL && (sd == NULL || sd->autocast.type != AUTOCAST_ITEM)) {
// Items that cast skills using 'itemskill' will not be handled by map_zone_db.
int i;
for(i = 0; i < map->list[src->m].zone->disabled_skills_count; i++) {
if( skill_id == map->list[src->m].zone->disabled_skills[i]->nameid && (map->list[src->m].zone->disabled_skills[i]->type&src->type) ) {
if (src->type == BL_PC) {
- clif->msgtable(sd, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 2);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 50));
+#endif
} else if (src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE) {
if( st->mode&MD_BOSS ) { /* is boss */
if( !( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) )
@@ -1799,7 +1636,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
if (src != NULL
&& map->getcell(src->m, src, src->x, src->y, CELL_CHKLANDPROTECTOR)
&& !(st->mode&MD_BOSS)
- && (src->type != BL_PC || sd->skillitem != skill_id))
+ && (src->type != BL_PC || sd->autocast.type != AUTOCAST_ITEM))
return 0;
break;
default:
@@ -1822,6 +1659,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
(sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD)
|| (sc->data[SC_AUTOCOUNTER] && !flag && skill_id)
|| (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL)
+ || (sc->data[SC_SUHIDE] && skill_id != SU_HIDE)
)
return 0;
@@ -1841,9 +1679,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
switch (sc->data[SC_BLADESTOP]->val1)
{
case 5: if (skill_id == MO_EXTREMITYFIST) break;
+ FALLTHROUGH
case 4: if (skill_id == MO_CHAINCOMBO) break;
+ FALLTHROUGH
case 3: if (skill_id == MO_INVESTIGATE) break;
+ FALLTHROUGH
case 2: if (skill_id == MO_FINGEROFFENSIVE) break;
+ FALLTHROUGH
default: return 0;
}
}
@@ -1873,7 +1715,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
}
- if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->skillitem != skill_id)) {
+ if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->autocast.type != AUTOCAST_ITEM)) {
//Skills blocked through status changes...
if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
sc->data[SC_SILENCE] ||
@@ -1985,7 +1827,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
|| (tsc->data[SC_CLOAKINGEXCEED] != NULL && is_detect)
))
return 0;
- if (tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && (!skill_id || (flag == 0 && src && src->type != BL_PC)))
+ if (tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && flag == 0)
return 0;
if (tsc->data[SC_STEALTHFIELD] && !is_boss)
return 0;
@@ -2007,6 +1849,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
return 0; // Can't use Weapon endow skills on Mercenary (only Master)
if( skill_id == AM_POTIONPITCHER && ( target->type == BL_MER || target->type == BL_ELEM) )
return 0; // Can't use Potion Pitcher on Mercenaries
+ FALLTHROUGH
default:
//Check for chase-walk/hiding/cloaking opponents.
if( tsc ) {
@@ -2022,12 +1865,14 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
//Skotlex: Calculates the initial status for the given mob
//first will only be false when the mob leveled up or got a GuardUp level.
-int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
+static int status_calc_mob_(struct mob_data *md, enum e_status_calc_opt opt)
+{
struct status_data *mstatus;
struct block_list *mbl = NULL;
int flag=0;
int guardup_lv = 0;
+ nullpo_retr(1, md);
if(opt&SCO_FIRST) { //Set basic level on respawn.
if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
;
@@ -2191,7 +2036,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
}
//Skotlex: Calculates the stats of the given pet.
-int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
+static int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
{
nullpo_ret(pd);
@@ -2208,9 +2053,7 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
if (battle_config.pet_lv_rate && pd->msd) {
struct map_session_data *sd = pd->msd;
- int lv;
-
- lv =sd->status.base_level*battle_config.pet_lv_rate/100;
+ int lv = sd->status.base_level * battle_config.pet_lv_rate / 100;
if (lv < 0)
lv = 1;
if (lv != pd->pet.level || opt&SCO_FIRST) {
@@ -2255,17 +2098,20 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
return 1;
}
-unsigned int status_get_base_maxsp(const struct map_session_data *sd, const struct status_data *st)
+static unsigned int status_get_base_maxsp(const struct map_session_data *sd, const struct status_data *st)
{
- uint64 val = pc->class2idx(sd->status.class_);
+ uint64 val;
+ nullpo_ret(sd);
+ nullpo_ret(st);
+ val = pc->class2idx(sd->status.class);
val = status->dbs->SP_table[val][sd->status.base_level];
- if ( sd->class_&JOBL_UPPER )
+ if ((sd->job & JOBL_UPPER) != 0)
val += val * 25 / 100;
- else if ( sd->class_&JOBL_BABY )
+ else if ((sd->job & JOBL_BABY) != 0)
val = val * 70 / 100;
- if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->fame_rank(sd->status.char_id, RANKTYPE_TAEKWON) > 0)
val *= 3; //Triple max SP for top ranking Taekwons over level 90.
val += val * st->int_ / 100;
@@ -2273,23 +2119,26 @@ unsigned int status_get_base_maxsp(const struct map_session_data *sd, const stru
return (unsigned int)cap_value(val, 0, UINT_MAX);
}
-unsigned int status_get_base_maxhp(const struct map_session_data *sd, const struct status_data *st)
+static unsigned int status_get_base_maxhp(const struct map_session_data *sd, const struct status_data *st)
{
- uint64 val = pc->class2idx(sd->status.class_);
+ uint64 val;
+ nullpo_ret(sd);
+ nullpo_ret(st);
+ val = pc->class2idx(sd->status.class);
val = status->dbs->HP_table[val][sd->status.base_level];
- if ( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99 )
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
val += 2000; //Supernovice lvl99 hp bonus.
- if ( (sd->class_&MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E && sd->status.base_level >= 150 )
+ if ((sd->job & MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E && sd->status.base_level >= 150)
val += 2000; //Extented Supernovice lvl150 hp bonus.
- if ( sd->class_&JOBL_UPPER )
+ if ((sd->job & JOBL_UPPER) != 0)
val += val * 25 / 100; //Trans classes get a 25% hp bonus
- else if ( sd->class_&JOBL_BABY )
+ else if ((sd->job & JOBL_BABY) != 0)
val = val * 70 / 100; //Baby classes get a 30% hp penalty
- if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->fame_rank(sd->status.char_id, RANKTYPE_TAEKWON))
val *= 3; //Triple max HP for top ranking Taekwons over level 90.
val += val * st->vit / 100; // +1% per each point of VIT
@@ -2297,22 +2146,83 @@ unsigned int status_get_base_maxhp(const struct map_session_data *sd, const stru
return (unsigned int)cap_value(val,0,UINT_MAX);
}
-void status_calc_pc_additional(struct map_session_data* sd, enum e_status_calc_opt opt) {
+/**
+ * Calculates the HP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_hp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int hp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_hp;
+
+ if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0 && battle_config.restart_hp_rate < 50)
+ hp = st->max_hp / 2;
+ else
+ hp = APPLY_RATE(st->max_hp, battle_config.restart_hp_rate);
+
+ if (hp > 0)
+ return hp;
+
+ return 1;
+}
+
+/**
+ * Calculates the SP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_sp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int sp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_sp;
+
+ sp = APPLY_RATE(st->max_sp, battle_config.restart_sp_rate);
+
+ if (sp > 0)
+ return sp;
+
+ return 1; // the minimum for the respawn setting is SP:1
+}
+
+static void status_calc_pc_additional(struct map_session_data *sd, enum e_status_calc_opt opt)
+{
/* Just used for Plugin to give bonuses. */
return;
}
+static void status_calc_pc_recover_hp(struct map_session_data *sd, struct status_data *bstatus)
+{
+ nullpo_retv(sd);
+ nullpo_retv(bstatus);
+
+ if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0
+ && battle_config.restart_hp_rate < 50)
+ bstatus->hp = bstatus->max_hp>>1;
+ else
+ bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate);
+}
+
//Calculates player data from scratch without counting SC adjustments.
//Should be invoked whenever players raise stats, learn passive skills or change equipment.
-int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
+static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt opt)
+{
static int calculating = 0; //Check for recursive call preemption. [Skotlex]
struct status_data *bstatus; // pointer to the player's base status
- const struct status_change *sc = &sd->sc;
- struct s_skill b_skill[MAX_SKILL]; // previous skill tree
+ const struct status_change *sc;
+ struct s_skill b_skill[MAX_SKILL_DB]; // previous skill tree
int b_weight, b_max_weight, b_cart_weight_max, // previous weight
i, k, index, skill_lv,refinedef=0;
int64 i64;
+ nullpo_retr(-1, sd);
+ sc = &sd->sc;
if (++calculating > 10) //Too many recursive calls!
return -1;
@@ -2324,7 +2234,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
pc->calc_skilltree(sd); // SkillTree calculation
- sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300;
+ sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class)]+sd->status.str*300;
if(opt&SCO_FIRST) {
//Load Hp/SP from char-received data.
@@ -2333,7 +2243,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->regen.sregen = &sd->sregen;
sd->regen.ssregen = &sd->ssregen;
sd->weight=0;
- for(i=0;i<MAX_INVENTORY;i++){
+ for (i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
continue;
sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
@@ -2369,7 +2279,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
memset(ZEROED_BLOCK_POS(&(sd->left_weapon)), 0, ZEROED_BLOCK_SIZE(&(sd->left_weapon)));
if (sd->special_state.intravision && !sd->sc.data[SC_CLAIRVOYANCE]) //Clear intravision as long as nothing else is using it
- clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE);
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, status->get_sc_icon(SC_CLAIRVOYANCE));
memset(&sd->special_state,0,sizeof(sd->special_state));
@@ -2382,13 +2292,13 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->speed = pSpeed;
}
- //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
- //Give them all modes except these (useful for clones)
+ // FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
+ // Give them all modes except these (useful for clones)
bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
- bstatus->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
+ bstatus->size = ((sd->job & JOBL_BABY) != 0 || (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?SZ_SMALL:SZ_MEDIUM;
if (battle_config.character_size && (pc_isridingpeco(sd) || pc_isridingdragon(sd))) { //[Lupus]
- if (sd->class_&JOBL_BABY) {
+ if ((sd->job & JOBL_BABY) != 0) {
if (battle_config.character_size&SZ_BIG)
bstatus->size++;
} else {
@@ -2398,7 +2308,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
bstatus->aspd_rate = 1000;
bstatus->ele_lv = 1;
- bstatus->race = RC_PLAYER;
+ bstatus->race = ((sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?RC_BRUTE:RC_PLAYER;
// Autobonus
pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
@@ -2464,18 +2374,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
r = 0;
if (r)
- wa->atk2 = status->dbs->refine_info[wlv].bonus[r-1] / 100;
+ wa->atk2 = refine->get_bonus(wlv, r) / 100;
#ifdef RENEWAL
wa->matk += sd->inventory_data[index]->matk;
wa->wlv = wlv;
if( r && sd->weapontype1 != W_BOW ) // renewal magic attack refine bonus
- wa->matk += status->dbs->refine_info[wlv].bonus[r-1] / 100;
+ wa->matk += refine->get_bonus(wlv, r) / 100;
#endif
//Overrefined bonus.
if (r)
- wd->overrefine = status->dbs->refine_info[wlv].randombonus_max[r-1] / 100;
+ wd->overrefine = refine->get_randombonus_max(wlv, r) / 100;
wa->range += sd->inventory_data[index]->range;
if(sd->inventory_data[index]->script) {
@@ -2492,8 +2402,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
if (sd->status.inventory[index].card[0]==CARD0_FORGE) {
// Forged weapon
wd->star += (sd->status.inventory[index].card[1]>>8);
- if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
- if(pc->famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
+ if (wd->star >= 15)
+ wd->star = 40; // 3 Star Crumbs now give +40 dmg
+ if (pc->fame_rank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]), RANKTYPE_BLACKSMITH) > 0)
wd->star += 10;
if (!wa->ele) //Do not overwrite element from previous bonuses.
@@ -2509,7 +2420,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
r = 0;
if (r)
- refinedef += status->dbs->refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
+ refinedef += refine->get_bonus(REFINE_TYPE_ARMOR, r);
if(sd->inventory_data[index]->script) {
if( i == EQI_HAND_L ) //Shield
@@ -2628,14 +2539,57 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
}
+ /* parse item options [Smokexyz] */
+ for (i = 0; i < EQI_MAX; i++) {
+ status->current_equip_item_index = index = sd->equip_index[i];
+ status->current_equip_option_index = -1;
+
+ if (i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
+ continue;
+ else if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
+ continue;
+ else if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
+ continue;
+
+ if (index >= 0 && sd->inventory_data[index]) {
+ int j = 0;
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
+ int16 option_index = sd->status.inventory[index].option[j].index;
+ struct itemdb_option *ito = NULL;
+
+ if (option_index == 0 || (ito = itemdb->option_exists(option_index)) == NULL || ito->script == NULL)
+ continue;
+
+ status->current_equip_option_index = j;
+ script->run(ito->script, 0, sd->bl.id, 0);
+
+ if (calculating == 0) //Abort, script->run his function. [Skotlex]
+ return 1;
+ }
+ }
+ }
+
+ status->current_equip_option_index = -1;
+ status->current_equip_item_index = -1;
+
+ // Clan Buffs
+ if (sd->status.clan_id > 0) {
+ struct clan *c = clan->search(sd->status.clan_id);
+ clan->buff_start(sd, c);
+ }
+
status->calc_pc_additional(sd, opt);
- if( sd->pd ) { // Pet Bonus
+ if (sd->pd != NULL) { // Pet bonus.
struct pet_data *pd = sd->pd;
- if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
- script->run(pd->petDB->equip_script,0,sd->bl.id,0);
- if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
- pc->bonus(sd,pd->bonus->type, pd->bonus->val);
+
+ if (pd->petDB != NULL && pd->petDB->equip_script != NULL)
+ script->run(pd->petDB->equip_script, 0, sd->bl.id, 0);
+
+ if (pd->pet.intimate > PET_INTIMACY_NONE && pd->state.skillbonus == 1 && pd->bonus != NULL
+ && (battle_config.pet_equip_required == 0 || pd->pet.equip > 0)) {
+ pc->bonus(sd, pd->bonus->type, pd->bonus->val);
+ }
}
//param_bonus now holds card bonuses.
@@ -2656,9 +2610,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->left_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype2];
sd->left_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype2];
- if ((pc_isridingpeco(sd) || pc_isridingdragon(sd))
- && (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR)
- ) {
+ if ((pc_isridingpeco(sd) || pc_isridingdragon(sd)) && (sd->weapontype == W_1HSPEAR || sd->weapontype == W_2HSPEAR)) {
//When Riding with spear, damage modifier to mid-class becomes
//same as versus large size.
sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
@@ -2668,8 +2620,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// ----- STATS CALCULATION -----
// Job bonuses
- index = pc->class2idx(sd->status.class_);
- for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){
+ index = pc->class2idx(sd->status.class);
+ for (i = 0; i < sd->status.job_level && i < MAX_LEVEL; i++) {
if(!status->dbs->job_bonus[index][i])
continue;
switch(status->dbs->job_bonus[index][i]) {
@@ -2683,7 +2635,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
// If a Super Novice has never died and is at least joblv 70, he gets all stats +10
- if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70) {
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70) {
bstatus->str += 10;
bstatus->agi += 10;
bstatus->vit += 10;
@@ -2701,6 +2653,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->dex += skill_lv;
if((skill_lv = pc->checkskill(sd,RA_RESEARCHTRAP))>0)
bstatus->int_ += skill_lv;
+ if ((pc->checkskill(sd,SU_POWEROFLAND)) > 0)
+ bstatus->int_ += 20;
// Bonuses from cards and equipment as well as base stat, remember to avoid overflows.
i = bstatus->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0];
@@ -2720,8 +2674,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// Base batk value is set on status->calc_misc
// weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
- if (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
- bstatus->batk += sd->weapon_atk[sd->status.weapon];
+ if (sd->weapontype < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->weapontype])
+ bstatus->batk += sd->weapon_atk[sd->weapontype];
// Absolute modifiers from passive skills
#ifndef RENEWAL
if((skill_lv=pc->checkskill(sd,BS_HILTBINDING))>0) // it doesn't work in RE.
@@ -2738,9 +2692,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->max_hp = (unsigned int)cap_value(i64, 0, INT_MAX);
// Absolute modifiers from passive skills
- if((skill_lv=pc->checkskill(sd,CR_TRUST))>0)
+ if ((skill_lv=pc->checkskill(sd,CR_TRUST)) > 0)
bstatus->max_hp += skill_lv*200;
+ if ((pc->checkskill(sd,SU_SPRITEMABLE)) > 0)
+ bstatus->max_hp += 1000;
+
// Apply relative modifiers from equipment
if(sd->hprate < 0)
sd->hprate = 0;
@@ -2773,6 +2730,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->max_sp += 200 + 20 * skill_lv;
if( (skill_lv = pc->checkskill(sd,WM_LESSON)) > 0 )
bstatus->max_sp += 30 * skill_lv;
+ if ((pc->checkskill(sd,SU_SPRITEMABLE)) > 0)
+ bstatus->max_sp += 100;
// Apply relative modifiers from equipment
if(sd->sprate < 0)
@@ -2790,24 +2749,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// ----- RESPAWN HP/SP -----
//
//Calc respawn hp and store it on base_status
- if (sd->special_state.restart_full_recover)
- {
- bstatus->hp = bstatus->max_hp;
- bstatus->sp = bstatus->max_sp;
- } else {
- if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
- && battle_config.restart_hp_rate < 50)
- bstatus->hp = bstatus->max_hp>>1;
- else
- bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate);
- if(!bstatus->hp)
- bstatus->hp = 1;
-
- bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate);
-
- if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */
- bstatus->sp = 1;
- }
+ bstatus->hp = status->get_restart_hp(sd, bstatus);
+ bstatus->sp = status->get_restart_sp(sd, bstatus);
// ----- MISC CALCULATION -----
status->calc_misc(&sd->bl, bstatus, sd->status.base_level);
@@ -2845,6 +2788,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->critical_rate = 0;
if(sd->critical_rate != 100)
bstatus->cri = bstatus->cri * sd->critical_rate/100;
+ if (pc->checkskill(sd, SU_POWEROFLIFE) > 0)
+ bstatus->cri += 20;
if(sd->flee2_rate < 0)
sd->flee2_rate = 0;
@@ -2862,10 +2807,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
#ifndef RENEWAL
bstatus->hit += skill_lv;
#endif
- if(sd->status.weapon == W_BOW)
+ if (sd->weapontype == W_BOW)
bstatus->rhw.range += skill_lv;
}
- if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE) {
+ if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE) {
if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0)
bstatus->hit += 2*skill_lv;
if((skill_lv=pc->checkskill(sd,GS_SNAKEEYE))>0) {
@@ -2873,18 +2818,22 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->rhw.range += skill_lv;
}
}
- if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 )
+ if ((sd->weapontype == W_1HAXE || sd->weapontype == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
bstatus->hit += 3*skill_lv;
- if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
+ if ((sd->weapontype == W_MACE || sd->weapontype == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
bstatus->hit += 2*skill_lv;
+ if (pc->checkskill(sd, SU_POWEROFLIFE) > 0)
+ bstatus->hit += 20;
// ----- FLEE CALCULATION -----
// Absolute modifiers from passive skills
if((skill_lv=pc->checkskill(sd,TF_MISS))>0)
- bstatus->flee += skill_lv*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
+ bstatus->flee += skill_lv*((sd->job & JOBL_2) != 0 && (sd->job & MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
if((skill_lv=pc->checkskill(sd,MO_DODGE))>0)
bstatus->flee += (skill_lv*3)>>1;
+ if (pc->checkskill(sd, SU_POWEROFLIFE) > 0)
+ bstatus->flee += 20;
// ----- EQUIPMENT-DEF CALCULATION -----
// Apply relative modifiers from equipment
@@ -2927,16 +2876,15 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
// Basic ASPD value
i = status->base_amotion_pc(sd,bstatus);
- bstatus->amotion = cap_value(i,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
+ bstatus->amotion = cap_value(i,((sd->job & JOBL_THIRD) != 0 ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
// Relative modifiers from passive skills
#ifndef RENEWAL_ASPD
- if((skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
+ if (sd->weapontype == W_BOOK && (skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK)) > 0)
bstatus->aspd_rate -= 5*skill_lv;
if((skill_lv = pc->checkskill(sd,SG_DEVIL)) > 0 && !pc->nextjobexp(sd))
bstatus->aspd_rate -= 30*skill_lv;
- if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0 &&
- (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
+ if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE && (skill_lv=pc->checkskill(sd,GS_SINGLEACTION)) > 0)
bstatus->aspd_rate -= ((skill_lv+1)/2) * 10;
if (pc_isridingpeco(sd))
bstatus->aspd_rate += 500-100*pc->checkskill(sd,KN_CAVALIERMASTERY);
@@ -3102,6 +3050,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->subele[ELE_EARTH] += i;
sd->subele[ELE_FIRE] -= i;
}
+ if (sc->data[SC_POPECOOKIE] != NULL) {
+ i = sc->data[SC_POPECOOKIE]->val3;
+ sd->subele[ELE_WATER] += i;
+ sd->subele[ELE_EARTH] += i;
+ sd->subele[ELE_FIRE] += i;
+ sd->subele[ELE_WIND] += i;
+ sd->subele[ELE_POISON] += i;
+ sd->subele[ELE_HOLY] += i;
+ sd->subele[ELE_DARK] += i;
+ sd->subele[ELE_GHOST] += i;
+ sd->subele[ELE_UNDEAD] += i;
+ }
if (sc->data[SC_MTF_MLEATKED])
sd->subele[ELE_NEUTRAL] += sc->data[SC_MTF_MLEATKED]->val1;
if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
@@ -3160,7 +3120,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->left_weapon.addrace[RC_DEMON] += sc->data[SC_PHI_DEMON]->val1;
}
}
- status_cpy(&sd->battle_status, bstatus);
+ status->copy(&sd->battle_status, bstatus);
// ----- CLIENT-SIDE REFRESH -----
if(!sd->bl.prev) {
@@ -3180,15 +3140,25 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
clif->updatestatus(sd,SP_CARTINFO);
}
+ // Spirit Marble status activates automatically for a infinite
+ // amount of time when the skill is learned. Felt this was the
+ // best place to put this. [Rytech]
+ if (pc->checkskill(sd, SU_SPRITEMABLE))
+ sc_start(&sd->bl, &sd->bl, SC_SPRITEMABLE, 100, 1, INFINITE_DURATION);
+
calculating = 0;
return 0;
}
-int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt) {
- struct status_data *mstatus = &md->base_status;
- struct s_mercenary *merc = &md->mercenary;
+static int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
+{
+ struct status_data *mstatus;
+ struct s_mercenary *merc;
+ nullpo_ret(md);
+ mstatus = &md->base_status;
+ merc = &md->mercenary;
if( opt&SCO_FIRST ) {
memcpy(mstatus, &md->db->status, sizeof(struct status_data));
mstatus->mode = MD_CANMOVE|MD_CANATTACK;
@@ -3199,17 +3169,22 @@ int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt
}
status->calc_misc(&md->bl, mstatus, md->db->lv);
- status_cpy(&md->battle_status, mstatus);
+ status->copy(&md->battle_status, mstatus);
return 0;
}
-int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) {
- struct status_data *estatus = &ed->base_status;
- struct s_elemental *ele = &ed->elemental;
- struct map_session_data *sd = ed->master;
+static int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt)
+{
+ struct status_data *estatus;
+ struct s_elemental *ele;
+ struct map_session_data *sd;
- if ( !sd )
+ nullpo_ret(ed);
+ estatus = &ed->base_status;
+ ele = &ed->elemental;
+ sd = ed->master;
+ if (sd == NULL)
return 0;
if ( opt&SCO_FIRST ) {
@@ -3237,13 +3212,14 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt
memcpy(&ed->battle_status, estatus, sizeof(struct status_data));
} else {
status->calc_misc(&ed->bl, estatus, 0);
- status_cpy(&ed->battle_status, estatus);
+ status->copy(&ed->battle_status, estatus);
}
return 0;
}
-int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
+static int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
+{
struct status_data *nstatus;
if (!nd)
@@ -3274,17 +3250,21 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
nstatus->luk = nd->stat_point;
status->calc_misc(&nd->bl, nstatus, nd->level);
- status_cpy(&nd->status, nstatus);
+ status->copy(&nd->status, nstatus);
return 0;
}
-int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
- struct status_data *hstatus = &hd->base_status;
- struct s_homunculus *hom = &hd->homunculus;
+static int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
+{
+ struct status_data *hstatus;
+ struct s_homunculus *hom;
int skill_lv;
int amotion;
+ nullpo_retr(1, hd);
+ hstatus = &hd->base_status;
+ hom = &hd->homunculus;
hstatus->str = hom->str / 10;
hstatus->agi = hom->agi / 10;
hstatus->vit = hom->vit / 10;
@@ -3360,12 +3340,13 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
status->calc_misc(&hd->bl, hstatus, hom->level);
- status_cpy(&hd->battle_status, hstatus);
+ status->copy(&hd->battle_status, hstatus);
return 1;
}
//Calculates base regen values.
-void status_calc_regen(struct block_list *bl, struct status_data *st, struct regen_data *regen) {
+static void status_calc_regen(struct block_list *bl, struct status_data *st, struct regen_data *regen)
+{
struct map_session_data *sd;
int val, skill_lv, reg_flag;
nullpo_retv(bl);
@@ -3465,8 +3446,9 @@ void status_calc_regen(struct block_list *bl, struct status_data *st, struct reg
}
//Calculates SC related regen rates.
-void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
+static void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
{
+ nullpo_retv(bl);
if (!(bl->type&BL_REGEN) || !regen)
return;
@@ -3509,7 +3491,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|| sc->data[SC_OBLIVIONCURSE] != NULL
|| sc->data[SC_MAXIMIZEPOWER] != NULL
|| sc->data[SC_REBOUND] != NULL
- || (bl->type == BL_PC && (BL_UCAST(BL_PC, bl)->class_&MAPID_UPPERMASK) == MAPID_MONK
+ || (bl->type == BL_PC && (BL_UCAST(BL_PC, bl)->job & MAPID_UPPERMASK) == MAPID_MONK
&& (sc->data[SC_EXTREMITYFIST] != NULL
|| (sc->data[SC_EXPLOSIONSPIRITS] != NULL
&& (sc->data[SC_SOULLINK] == NULL || sc->data[SC_SOULLINK]->val2 != SL_MONK)
@@ -3540,7 +3522,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
#endif
regen->rate.sp += 1;
}
-
+
if (sc->data[SC_GDSKILL_REGENERATION]) {
const struct status_change_entry *sce = sc->data[SC_GDSKILL_REGENERATION];
if (!sce->val4) {
@@ -3573,6 +3555,10 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
regen->rate.hp += regen->rate.hp * sc->data[SC_BUCHEDENOEL]->val1 / 100;
regen->rate.sp += regen->rate.sp * sc->data[SC_BUCHEDENOEL]->val2 / 100;
}
+ if (sc->data[SC_CATNIPPOWDER]) {
+ regen->rate.hp *= 2;
+ regen->rate.sp *= 2;
+ }
}
#define status_get_homstr(st, hd) ((st)->str + (hd)->homunculus.str_value)
@@ -3584,13 +3570,16 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
/// Recalculates parts of an object's battle status according to the specified flags.
/// @param flag bitfield of values from enum scb_flag
-void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
+static void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
+{
const struct status_data *bst = status->get_base_status(bl);
struct status_data *st = status->get_status_data(bl);
struct status_change *sc = status->get_sc(bl);
struct map_session_data *sd = BL_CAST(BL_PC,bl);
int temp;
+ nullpo_retv(bl);
+
if (!bst || !st)
return;
@@ -3610,7 +3599,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
}
if((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { //No difference.
- status_cpy(st, bst);
+ status->copy(st, bst);
return;
}
@@ -3677,7 +3666,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
temp = bst->batk - status->base_atk(bl,bst);
if (temp) {
temp += st->batk;
- st->batk = cap_value(temp, 0, USHRT_MAX);
+ st->batk = cap_value(temp, battle_config.batk_min, battle_config.batk_max);
}
st->batk = status->calc_batk(bl, sc, st->batk, true);
}
@@ -3792,13 +3781,15 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
}
if(flag&SCB_CRI && bst->cri) {
- if (st->luk == bst->luk)
+ if (st->luk == bst->luk) {
st->cri = status->calc_critical(bl, sc, bst->cri, true);
- else
+ } else {
st->cri = status->calc_critical(bl, sc, bst->cri + 3*(st->luk - bst->luk), true);
+ }
+ if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->weapontype == W_KATAR) {
+ st->cri *= 2;
+ }
}
- if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->status.weapon == W_KATAR)
- st->cri <<= 1;
if(flag&SCB_FLEE2 && bst->flee2) {
if (st->luk == bst->luk)
@@ -3857,10 +3848,10 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_MAXSP) {
if( bl->type&BL_PC ) {
st->max_sp = status->get_base_maxsp(sd,st);
- if (sd)
+ if (sd != NULL) {
st->max_sp += bst->max_sp - sd->status.max_sp;
-
- st->max_sp = status->calc_maxsp(&sd->bl, &sd->sc, st->max_sp);
+ st->max_sp = status->calc_maxsp(&sd->bl, &sd->sc, st->max_sp);
+ }
if( st->max_sp > (unsigned int)battle_config.max_sp )
st->max_sp = (unsigned int)battle_config.max_sp;
@@ -3927,14 +3918,29 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
#endif
if ( st->aspd_rate != 1000 ) // absolute percentage modifier
amotion = amotion * st->aspd_rate / 1000;
- if ( sd && sd->ud.skilltimer != INVALID_TIMER && pc->checkskill(sd, SA_FREECAST) > 0 )
- amotion = amotion * 5 * (pc->checkskill(sd, SA_FREECAST) + 10) / 100;
+ if (sd && sd->ud.skilltimer != INVALID_TIMER) {
+ if (pc->checkskill(sd, SA_FREECAST) > 0) {
+ amotion = amotion * 5 * (pc->checkskill(sd, SA_FREECAST) + 10) / 100;
+ } else {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if (ud && (skill->get_inf2(ud->skill_id) & INF2_FREE_CAST_REDUCED) != 0) {
+ amotion = amotion * 5 * (ud->skill_lv + 10) / 100;
+ }
+ }
+ }
#ifdef RENEWAL_ASPD
amotion += (max(0xc3 - amotion, 2) * (st->aspd_rate2 + status->calc_aspd(bl, sc, 2))) / 100;
- amotion = 10 * (200 - amotion) + sd->bonus.aspd_add;
+ amotion = 10 * (200 - amotion);
+ if (sd != NULL) {
+ amotion += sd->bonus.aspd_add;
+ }
#endif
amotion = status->calc_fix_aspd(bl, sc, amotion);
- st->amotion = cap_value(amotion, ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd), 2000);
+ if (sd != NULL) {
+ st->amotion = cap_value(amotion, ((sd->job & JOBL_THIRD) != 0 ? battle_config.max_third_aspd : battle_config.max_aspd), 2000);
+ } else {
+ st->amotion = cap_value(amotion, battle_config.max_aspd, 2000);
+ }
st->adelay = 2 * st->amotion;
} else { // mercenary and mobs
@@ -3958,15 +3964,17 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_REGEN && bl->type&BL_REGEN)
status->calc_regen_rate(bl, status->get_regen_data(bl), sc);
}
+
/// Recalculates parts of an object's base status and battle status according to the specified flags.
/// Also sends updates to the client wherever applicable.
/// @param flag bitfield of values from enum scb_flag
/// @param first if true, will cause status_calc_* functions to run their base status initialization code
-void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt)
+static void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt)
{
struct status_data bst; // previous battle status
struct status_data *st; // pointer to current battle status
+ nullpo_retv(bl);
if (bl->type == BL_PC) {
struct map_session_data *sd = BL_UCAST(BL_PC, bl);
if (sd->delayed_damage != 0) {
@@ -4144,11 +4152,16 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_ca
clif->mercenary_updatestatus(ed->master, SP_SP);
}
}
+
//Checks whether the source can see and chase target.
-int status_check_visibility(struct block_list *src, struct block_list *target) {
+static int status_check_visibility(struct block_list *src, struct block_list *target)
+{
int view_range;
struct status_change *tsc = NULL;
+ nullpo_ret(src);
+ nullpo_ret(target);
+
switch ( src->type ) {
case BL_MOB:
view_range = BL_UCCAST(BL_MOB, src)->min_chase;
@@ -4193,17 +4206,22 @@ int status_check_visibility(struct block_list *src, struct block_list *target) {
}
// Basic ASPD value
-int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) {
+static int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
+{
int amotion;
#ifdef RENEWAL_ASPD /* [malufett/Hercules] */
float temp;
int skill_lv, val = 0;
- amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1];
- if ( sd->status.weapon > MAX_SINGLE_WEAPON_TYPE)
- amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4;
- if ( sd->status.shield )
- amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][MAX_SINGLE_WEAPON_TYPE];
- switch ( sd->status.weapon ) {
+
+ nullpo_ret(sd);
+ nullpo_ret(st);
+
+ amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1];
+ if (sd->weapontype > MAX_SINGLE_WEAPON_TYPE)
+ amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2] / 4;
+ if (sd->has_shield)
+ amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][MAX_SINGLE_WEAPON_TYPE];
+ switch (sd->weapontype) {
case W_BOW:
case W_MUSICAL:
case W_WHIP:
@@ -4218,16 +4236,16 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
temp = st->dex * st->dex / 5.0f + st->agi * st->agi * 0.5f;
}
temp = (float)(sqrt(temp) * 0.25f) + 0xc4;
- if ( (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK )
+ if (sd->weapontype == W_BOOK && (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0)
val += (skill_lv - 1) / 2 + 1;
if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 )
val += ((skill_lv + 1) / 2);
amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200));
#else
// base weapon delay
- amotion = (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE)
- ? (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
- : (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield
+ amotion = (sd->weapontype < MAX_SINGLE_WEAPON_TYPE)
+ ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype]) // single weapon
+ : (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2]) * 7 / 10; // dual-wield
// percentual delay reduction from stats
amotion -= amotion * (4 * st->agi + st->dex) / 1000;
@@ -4243,14 +4261,17 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
return amotion;
}
-unsigned short status_base_atk(const struct block_list *bl, const struct status_data *st) {
+static int status_base_atk(const struct block_list *bl, const struct status_data *st)
+{
int flag = 0, str, dex, dstr;
+ nullpo_ret(bl);
+ nullpo_ret(st);
if ( !(bl->type&battle_config.enable_baseatk) )
return 0;
if (bl->type == BL_PC) {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_MUSICAL:
case W_WHIP:
@@ -4297,34 +4318,61 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
if (bl->type == BL_PC)
str += dex / 5 + st->luk / 5;
#endif // RENEWAL
- return cap_value(str, 0, USHRT_MAX);
+ return cap_value(str, battle_config.batk_min, battle_config.batk_max);
}
-#ifndef RENEWAL
-static inline unsigned short status_base_matk_min(const struct status_data *st) { return st->int_ + (st->int_ / 7)*(st->int_ / 7); }
-#endif // not RENEWAL
-static inline unsigned short status_base_matk_max(const struct status_data *st) { return st->int_ + (st->int_ / 5)*(st->int_ / 5); }
+static int status_base_matk_min(const struct status_data *st)
+{
+ nullpo_ret(st);
+#ifdef RENEWAL
+ Assert_ret(0);
+ return 0;
+#else // not RENEWAL
+ int matk = st->int_ + (st->int_ / 7) * (st->int_ / 7);
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
+#endif // RENEWAL
+}
+
+static int status_base_matk_max(const struct status_data *st)
+{
+ nullpo_ret(st);
+ int matk = st->int_ + (st->int_ / 5) * (st->int_ / 5);
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
+}
-unsigned short status_base_matk(struct block_list *bl, const struct status_data *st, int level) {
+static int status_base_matk(struct block_list *bl, const struct status_data *st, int level)
+{
#ifdef RENEWAL
- switch ( bl->type ) {
+ nullpo_ret(bl);
+ nullpo_ret(st);
+ int matk = 0;
+ switch (bl->type) {
case BL_MOB:
- return st->int_ + level;
+ matk = st->int_ + level;
+ break;
case BL_HOM:
- return status_get_homint(st, BL_UCCAST(BL_HOM, bl)) + level;
+ matk = status_get_homint(st, BL_UCCAST(BL_HOM, bl)) + level;
+ break;
case BL_MER:
- return st->int_ + st->int_ / 5 * st->int_ / 5;
+ matk = st->int_ + st->int_ / 5 * st->int_ / 5;
+ break;
case BL_PC:
default: // temporary until all are formulated
- return st->int_ + (st->int_ / 2) + (st->dex / 5) + (st->luk / 3) + (level / 4);
+ matk = st->int_ + (st->int_ / 2) + (st->dex / 5) + (st->luk / 3) + (level / 4);
+ break;
}
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
#else
+ Assert_ret(0);
return 0;
#endif
}
//Fills in the misc data that can be calculated from the other status info (except for level)
-void status_calc_misc(struct block_list *bl, struct status_data *st, int level) {
+static void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
+{
+ nullpo_retv(bl);
+ nullpo_retv(st);
//Non players get the value set, players need to stack with previous bonuses.
if ( bl->type != BL_PC )
st->batk =
@@ -4350,8 +4398,8 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
st->mdef2 += (int)(bl->type == BL_PC ? (st->int_ + ((float)level / 4) + ((float)(st->dex + st->vit) / 5)) : ((float)(st->int_ + level) / 4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
}
#else // not RENEWAL
- st->matk_min = status_base_matk_min(st);
- st->matk_max = status_base_matk_max(st);
+ st->matk_min = status->base_matk_min(st);
+ st->matk_max = status->base_matk_max(st);
st->hit += level + st->dex;
st->flee += level + st->agi;
st->def2 += st->vit;
@@ -4370,7 +4418,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
if ( st->batk ) {
int temp = st->batk + status->base_atk(bl, st);
- st->batk = cap_value(temp, 0, USHRT_MAX);
+ st->batk = cap_value(temp, battle_config.batk_min, battle_config.batk_max);
} else
st->batk = status->base_atk(bl, st);
if ( st->cri ) {
@@ -4386,7 +4434,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
break;
case BL_MER:
#ifdef RENEWAL
- st->matk_min = st->matk_max = status_base_matk_max(st);
+ st->matk_min = st->matk_max = status->base_matk_max(st);
st->def2 = st->vit + level / 10 + st->vit / 5;
st->mdef2 = level / 10 + st->int_ / 5;
#endif
@@ -4403,9 +4451,9 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
}
/*==========================================
-* Apply shared stat mods from status changes [DracoRPG]
-*------------------------------------------*/
-unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
+ * Apply shared stat mods from status changes [DracoRPG]
+ *------------------------------------------*/
+static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
{
if(!sc || !sc->count)
return cap_value(str,0,USHRT_MAX);
@@ -4468,7 +4516,7 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
-unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
+static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
{
if(!sc || !sc->count)
return cap_value(agi,0,USHRT_MAX);
@@ -4522,13 +4570,16 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc,
if (sc->data[SC_2011RWC])
agi += sc->data[SC_2011RWC]->val1;
- if(sc->data[SC_MARSHOFABYSS])
+ if (sc->data[SC_MARSHOFABYSS])
agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100;
+ if (sc->data[SC_ARCLOUSEDASH])
+ agi += sc->data[SC_ARCLOUSEDASH]->val2;
+
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
-unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
+static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
{
if(!sc || !sc->count)
return cap_value(vit,0,USHRT_MAX);
@@ -4579,8 +4630,9 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
-unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
+static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
{
+ nullpo_ret(bl);
if(!sc || !sc->count)
return cap_value(int_,0,USHRT_MAX);
@@ -4645,8 +4697,9 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
-unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
+static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
{
+ nullpo_ret(bl);
if(!sc || !sc->count)
return cap_value(dex,0,USHRT_MAX);
@@ -4707,7 +4760,9 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
-unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk) {
+static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
+{
+ nullpo_ret(bl);
if (!sc || !sc->count)
return cap_value(luk, 0, USHRT_MAX);
@@ -4759,16 +4814,22 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(luk, 0, USHRT_MAX);
}
-unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
+
+static int status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
{
+ nullpo_ret(bl);
if(!sc || !sc->count)
- return cap_value(batk,0,USHRT_MAX);
+ return cap_value(batk, battle_config.batk_min, battle_config.batk_max);
if( !viewable ){
/* some statuses that are hidden in the status window */
if(sc->data[SC_PLUSATTACKPOWER])
batk += sc->data[SC_PLUSATTACKPOWER]->val1;
- return (unsigned short)cap_value(batk,0,USHRT_MAX);
+ if (sc->data[SC_POPECOOKIE] != NULL)
+ batk += batk * sc->data[SC_POPECOOKIE]->val1 / 100;
+ if (sc->data[SC_VITALIZE_POTION] != NULL)
+ batk += batk * sc->data[SC_VITALIZE_POTION]->val1 / 100;
+ return cap_value(batk, battle_config.batk_min, battle_config.batk_max);
}
#ifndef RENEWAL
if(sc->data[SC_PLUSATTACKPOWER])
@@ -4807,9 +4868,6 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
#ifndef RENEWAL
if(sc->data[SC_LKCONCENTRATION])
batk += batk * sc->data[SC_LKCONCENTRATION]->val2/100;
-#else
- if ( sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC )
- batk -= batk * sc->data[SC_NOEQUIPWEAPON]->val2 / 100;
#endif
if(sc->data[SC_SKE])
batk += batk * 3;
@@ -4850,14 +4908,22 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
batk += batk * sc->data[SC_2011RWC]->val2 / 100;
if (sc->data[SC_STEAMPACK])
batk += sc->data[SC_STEAMPACK]->val1;
+ if (sc->data[SC_SKF_ATK] != NULL)
+ batk += sc->data[SC_SKF_ATK]->val1;
+ if (sc->data[SC_ALMIGHTY] != NULL)
+ batk += sc->data[SC_ALMIGHTY]->val1;
+
+ if (sc->data[SC_SHRIMP])
+ batk += batk * sc->data[SC_SHRIMP]->val2 / 100;
- return (unsigned short)cap_value(batk,0,USHRT_MAX);
+ return cap_value(batk, battle_config.batk_min, battle_config.batk_max);
}
-unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable)
+static int status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable)
{
+ nullpo_ret(bl);
if(!sc || !sc->count)
- return cap_value(watk,0,USHRT_MAX);
+ return cap_value(watk, battle_config.watk_min, battle_config.watk_max);
if( !viewable ){
/* some statuses that are hidden in the status window */
@@ -4865,7 +4931,7 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk -= sc->data[SC_WATER_BARRIER]->val3;
if(sc->data[SC_GENTLETOUCH_CHANGE] && sc->data[SC_GENTLETOUCH_CHANGE]->val2)
watk += sc->data[SC_GENTLETOUCH_CHANGE]->val2;
- return (unsigned short)cap_value(watk,0,USHRT_MAX);
+ return cap_value(watk, battle_config.watk_min, battle_config.watk_max);
}
#ifndef RENEWAL
if(sc->data[SC_IMPOSITIO])
@@ -4908,7 +4974,7 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_LKCONCENTRATION])
watk += watk * sc->data[SC_LKCONCENTRATION]->val2/100;
#endif
- if(sc->data[SC_INCATKRATE] && bl->type != BL_MOB)
+ if(sc->data[SC_INCATKRATE])
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
@@ -4918,10 +4984,8 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk += watk * sc->data[SC_HLIF_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
-#ifndef RENEWAL
if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC)
watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100;
-#endif
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_RUSH_WINDMILL])
@@ -4942,14 +5006,17 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
if( sc->data[SC_FLASHCOMBO] )
watk += sc->data[SC_FLASHCOMBO]->val2;
+ if (sc->data[SC_CATNIPPOWDER])
+ watk -= watk * sc->data[SC_CATNIPPOWDER]->val2 / 100;
- return (unsigned short)cap_value(watk,0,USHRT_MAX);
+ return cap_value(watk, battle_config.watk_min, battle_config.watk_max);
}
-unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk) {
-#ifdef RENEWAL
+static int status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
+{
+#ifdef RENEWAL
if (!sc || !sc->count)
- return cap_value(matk,0,USHRT_MAX);
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
if (sc->data[SC_PLUSMAGICPOWER])
matk += sc->data[SC_PLUSMAGICPOWER]->val1;
if (sc->data[SC_MATKFOOD])
@@ -4968,21 +5035,28 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc
matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
if(sc->data[SC_IZAYOI])
matk += 25 * sc->data[SC_IZAYOI]->val1;
- return (unsigned short)cap_value(matk,0,USHRT_MAX);
+ if (sc->data[SC_SHRIMP])
+ matk += matk * sc->data[SC_SHRIMP]->val2 / 100;
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
#else
return 0;
#endif
}
-unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable) {
+static int status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable)
+{
if (!sc || !sc->count)
- return cap_value(matk,0,USHRT_MAX);
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
if (!viewable) {
/* some statuses that are hidden in the status window */
if (sc->data[SC_MINDBREAKER])
matk += matk * sc->data[SC_MINDBREAKER]->val2 / 100;
- return (unsigned short)cap_value(matk, 0, USHRT_MAX);
+ if (sc->data[SC_POPECOOKIE] != NULL)
+ matk += matk * sc->data[SC_POPECOOKIE]->val2 / 100;
+ if (sc->data[SC_VITALIZE_POTION] != NULL)
+ matk += matk * sc->data[SC_VITALIZE_POTION]->val2 / 100;
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
}
#ifndef RENEWAL
@@ -5039,18 +5113,22 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
matk += matk * sc->data[SC_2011RWC]->val2 / 100;
if (sc->data[SC_MAGIC_CANDY])
matk += sc->data[SC_MAGIC_CANDY]->val1;
+ if (sc->data[SC_SKF_MATK] != NULL)
+ matk += sc->data[SC_SKF_MATK]->val1;
+ if (sc->data[SC_ALMIGHTY] != NULL)
+ matk += sc->data[SC_ALMIGHTY]->val2;
- return (unsigned short)cap_value(matk, 0, USHRT_MAX);
+ return cap_value(matk, battle_config.matk_min, battle_config.matk_max);
}
-signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable) {
-
+static int status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable)
+{
if (!sc || !sc->count)
- return cap_value(critical, 10, SHRT_MAX);
+ return cap_value(critical, battle_config.critical_min, battle_config.critical_max);
if (!viewable) {
/* some statuses that are hidden in the status window */
- return (short)cap_value(critical, 10, SHRT_MAX);
+ return cap_value(critical, battle_config.critical_min, battle_config.critical_max);
}
if (sc->data[SC_CRITICALPERCENT])
@@ -5081,20 +5159,20 @@ signed short status_calc_critical(struct block_list *bl, struct status_change *s
if (sc->data[SC_BUCHEDENOEL])
critical += sc->data[SC_BUCHEDENOEL]->val4 * 10;
- return (short)cap_value(critical, 10, SHRT_MAX);
+ return cap_value(critical, battle_config.critical_min, battle_config.critical_max);
}
-signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable)
+static int status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable)
{
if (!sc || !sc->count)
- return cap_value(hit, 1, SHRT_MAX);
+ return cap_value(hit, battle_config.hit_min, battle_config.hit_max);
if (!viewable) {
/* some statuses that are hidden in the status window */
if (sc->data[SC_MTF_ASPD])
hit += sc->data[SC_MTF_ASPD]->val2;
- return (short)cap_value(hit, 1, SHRT_MAX);
+ return cap_value(hit, battle_config.hit_min, battle_config.hit_max);
}
if (sc->data[SC_INCHIT])
@@ -5136,24 +5214,26 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in
if (sc->data[SC_BUCHEDENOEL])
hit += sc->data[SC_BUCHEDENOEL]->val3;
- return (short)cap_value(hit, 1, SHRT_MAX);
+ return cap_value(hit, battle_config.hit_min, battle_config.hit_max);
}
-signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable) {
+static int status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable)
+{
+ nullpo_retr(1, bl);
if (bl->type == BL_PC) {
if (map_flag_gvg2(bl->m))
flee -= flee * battle_config.gvg_flee_penalty / 100;
- else if( map->list[bl->m].flag.battleground )
+ else if (map->list[bl->m].flag.battleground)
flee -= flee * battle_config.bg_flee_penalty / 100;
}
if (!sc || !sc->count)
- return cap_value(flee, 1, SHRT_MAX);
+ return cap_value(flee, battle_config.flee_min, battle_config.flee_max);
if (!viewable) {
/* some statuses that are hidden in the status window */
- return (short)cap_value(flee, 1, SHRT_MAX);
+ return cap_value(flee, battle_config.flee_min, battle_config.flee_max);
}
if (sc->data[SC_INCFLEE])
@@ -5231,17 +5311,17 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i
if (sc->data[SC_MYSTICPOWDER])
flee += sc->data[SC_MYSTICPOWDER]->val2;
- return (short)cap_value(flee, 1, SHRT_MAX);
+ return cap_value(flee, battle_config.flee_min, battle_config.flee_max);
}
-signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable)
+static int status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable)
{
if(!sc || !sc->count)
- return cap_value(flee2,10,SHRT_MAX);
+ return cap_value(flee2, battle_config.flee2_min, battle_config.flee2_max);
if( !viewable ){
/* some statuses that are hidden in the status window */
- return (short)cap_value(flee2,10,SHRT_MAX);
+ return cap_value(flee2, battle_config.flee2_min, battle_config.flee2_max);
}
if(sc->data[SC_PLUSAVOIDVALUE])
@@ -5253,10 +5333,12 @@ signed short status_calc_flee2(struct block_list *bl, struct status_change *sc,
if (sc->data[SC_FREYJASCROLL])
flee2 += sc->data[SC_FREYJASCROLL]->val2;
- return (short)cap_value(flee2,10,SHRT_MAX);
+ return cap_value(flee2, battle_config.flee2_min, battle_config.flee2_max);
}
-defType status_calc_def(struct block_list *bl, struct status_change *sc, int def, bool viewable)
+
+static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def, bool viewable)
{
+ nullpo_retr(DEFTYPE_MIN, bl);
if (!sc || !sc->count)
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
@@ -5359,8 +5441,9 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
}
-signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2, bool viewable)
+static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2, bool viewable)
{
+ nullpo_retr(1, bl);
if(!sc || !sc->count)
#ifdef RENEWAL
return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
@@ -5435,7 +5518,8 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i
#endif
}
-defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef, bool viewable) {
+static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef, bool viewable)
+{
if(!sc || !sc->count)
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
@@ -5491,7 +5575,7 @@ defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int md
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
}
-signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2, bool viewable)
+static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2, bool viewable)
{
if(!sc || !sc->count)
#ifdef RENEWAL
@@ -5530,22 +5614,25 @@ signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc,
#endif
}
-unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
+static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
{
struct map_session_data *sd = BL_CAST(BL_PC, bl);
- int speed_rate;
+ int speed_rate = -1;
if( sc == NULL || ( sd && sd->state.permanent_speed ) )
return (unsigned short)cap_value(speed,MIN_WALK_SPEED,MAX_WALK_SPEED);
- if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) )
+ if (sd && sd->ud.skilltimer != INVALID_TIMER)
{
- if( sd->ud.skill_id == LG_EXEEDBREAK )
+ if (sd->ud.skill_id == LG_EXEEDBREAK) {
speed_rate = 160 - 10 * sd->ud.skill_lv;
- else
+ } else if ((skill->get_inf2(sd->ud.skill_id) & INF2_FREE_CAST_REDUCED) != 0) {
+ speed_rate = 175 - 5 * sd->ud.skill_lv;
+ } else if (pc->checkskill(sd, SA_FREECAST) > 0) {
speed_rate = 175 - 5 * pc->checkskill(sd,SA_FREECAST);
+ }
}
- else
+ if (speed_rate == -1)
{
speed_rate = 100;
@@ -5576,9 +5663,9 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
{
int val = 0;
- if( sd && sc->data[SC_HIDING] && pc->checkskill(sd,RG_TUNNELDRIVE) > 0 )
+ if ( sd && sc->data[SC_HIDING] && pc->checkskill(sd,RG_TUNNELDRIVE) > 0 ) {
val = 120 - 6 * pc->checkskill(sd,RG_TUNNELDRIVE);
- else
+ } else {
if( sd && sc->data[SC_CHASEWALK] && sc->data[SC_CHASEWALK]->val3 < 0 )
val = sc->data[SC_CHASEWALK]->val3;
else
@@ -5644,12 +5731,14 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if (sc->data[SC_DEC_AGI] || sc->data[SC_QUAGMIRE] || sc->data[SC_DONTFORGETME])
return 0;
}
+ if (sc->data[SC_CATNIPPOWDER])
+ val = max(val, sc->data[SC_CATNIPPOWDER]->val3);
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup
val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
}
-
- speed_rate += val;
+ }
+ speed_rate += val;
}
//GetMoveHasteValue1()
@@ -5666,7 +5755,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
val = max( val, 2 * sc->data[SC_WINDWALK]->val1 );
if( sc->data[SC_CARTBOOST] )
val = max( val, 20 );
- if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc->checkskill(sd,TF_MISS) > 0 )
+ if (sd != NULL && (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN && pc->checkskill(sd,TF_MISS) > 0)
val = max( val, 1 * pc->checkskill(sd,TF_MISS) );
if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 )
val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 );
@@ -5694,6 +5783,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
val = max(val, sc->data[SC_MOVHASTE_HORSE]->val1);
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup
val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
+ if (sc->data[SC_ARCLOUSEDASH])
+ val = max(val, sc->data[SC_ARCLOUSEDASH]->val3);
speed_rate -= val;
}
@@ -5726,10 +5817,12 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
// flag&1 - fixed value [malufett]
// flag&2 - percentage value
-short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag) {
+static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
+{
#ifdef RENEWAL_ASPD
int pots = 0, bonus = 0;
+ nullpo_ret(bl);
if (!sc || !sc->count)
return 0;
@@ -5764,7 +5857,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
if (bl->type != BL_PC) {
bonus = sc->data[SC_ASSNCROS]->val2;
} else {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -5848,6 +5941,8 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
bonus += sc->data[SC_BATTLESCROLL]->val1;
if (sc->data[SC_STEAMPACK])
bonus += sc->data[SC_STEAMPACK]->val2;
+ if (sc->data[SC_SKF_ASPD] != NULL)
+ bonus += sc->data[SC_SKF_ASPD]->val1;
}
return (bonus + pots);
@@ -5856,7 +5951,9 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
#endif
}
-short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) {
+static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
+{
+ nullpo_ret(bl);
if (!sc || !sc->count)
return cap_value(aspd, 0, 2000);
@@ -5874,10 +5971,11 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int
/// Calculates an object's ASPD modifier (alters the base amotion value).
/// Note that the scale of aspd_rate is 1000 = 100%.
-short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
+static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
{
int i;
+ nullpo_ret(bl);
if(!sc || !sc->count)
return cap_value(aspd_rate,0,SHRT_MAX);
@@ -5922,7 +6020,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
if (bl->type != BL_PC) {
max = sc->data[SC_ASSNCROS]->val2;
} else {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -6012,12 +6110,15 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
aspd_rate += sc->data[SC_BATTLESCROLL]->val1 * 10;
if (sc->data[SC_STEAMPACK])
aspd_rate += sc->data[SC_STEAMPACK]->val2 * 10;
+ if (sc->data[SC_SKF_ASPD] != NULL)
+ aspd_rate -= sc->data[SC_SKF_ASPD]->val1 * 10;
return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
-unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
+static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
{
+ nullpo_ret(bl);
// It has been confirmed on official servers that MvP mobs have no dmotion even without endure
if (bl->type == BL_MOB && (BL_UCCAST(BL_MOB, bl)->status.mode&MD_BOSS))
return 0;
@@ -6033,7 +6134,8 @@ unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *
return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
}
-unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp) {
+static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp)
+{
if (!sc || !sc->count)
return (unsigned int)cap_value(maxhp, 1, UINT_MAX);
@@ -6112,8 +6214,8 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc,
return (unsigned int)cap_value(maxhp, 1, UINT_MAX);
}
-unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) {
-
+static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp)
+{
if (!sc || !sc->count)
return cap_value(maxsp, 1, UINT_MAX);
@@ -6151,7 +6253,7 @@ unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc,
return cap_value(maxsp, 1, UINT_MAX);
}
-unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
+static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
{
if(!sc || !sc->count)
return element;
@@ -6172,7 +6274,7 @@ unsigned char status_calc_element(struct block_list *bl, struct status_change *s
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
-unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
+static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
{
if(!sc || !sc->count)
return lv;
@@ -6195,7 +6297,7 @@ unsigned char status_calc_element_lv(struct block_list *bl, struct status_change
return (unsigned char)cap_value(lv,1,4);
}
-unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
+static unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
{
if(!sc || !sc->count)
return element;
@@ -6236,7 +6338,7 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
* @param mode The starting mode.
* @return The calculated mode.
*/
-uint32 status_calc_mode(const struct block_list *bl, const struct status_change *sc, uint32 mode)
+static uint32 status_calc_mode(const struct block_list *bl, const struct status_change *sc, uint32 mode)
{
if (sc == NULL || sc->count == 0)
return mode & MD_MASK;
@@ -6257,7 +6359,7 @@ uint32 status_calc_mode(const struct block_list *bl, const struct status_change
* @param bl The requested bl.
* @return The bl's name or NULL if not available.
*/
-const char *status_get_name(const struct block_list *bl)
+static const char *status_get_name(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6277,17 +6379,17 @@ const char *status_get_name(const struct block_list *bl)
}
/*==========================================
-* Get the class of the current bl
-* return
-* 0 = fail
-* class_id = success
-*------------------------------------------*/
-int status_get_class(const struct block_list *bl)
+ * Get the class of the current bl
+ * return
+ * 0 = fail
+ * class_id = success
+ *------------------------------------------*/
+static int status_get_class(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
- case BL_PC: return BL_UCCAST(BL_PC, bl)->status.class_;
- case BL_MOB: return BL_UCCAST(BL_MOB, bl)->vd->class_; //Class used on all code should be the view class of the mob.
+ case BL_PC: return BL_UCCAST(BL_PC, bl)->status.class;
+ case BL_MOB: return BL_UCCAST(BL_MOB, bl)->vd->class; //Class used on all code should be the view class of the mob.
case BL_PET: return BL_UCCAST(BL_PET, bl)->pet.class_;
case BL_HOM: return BL_UCCAST(BL_HOM, bl)->homunculus.class_;
case BL_MER: return BL_UCCAST(BL_MER, bl)->mercenary.class_;
@@ -6297,12 +6399,12 @@ int status_get_class(const struct block_list *bl)
return 0;
}
/*==========================================
-* Get the base level of the current bl
-* return
-* 1 = fail
-* level = success
-*------------------------------------------*/
-int status_get_lv(const struct block_list *bl)
+ * Get the base level of the current bl
+ * return
+ * 1 = fail
+ * level = success
+ *------------------------------------------*/
+static int status_get_lv(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6317,7 +6419,7 @@ int status_get_lv(const struct block_list *bl)
return 1;
}
-struct regen_data *status_get_regen_data(struct block_list *bl)
+static struct regen_data *status_get_regen_data(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
@@ -6330,7 +6432,7 @@ struct regen_data *status_get_regen_data(struct block_list *bl)
}
}
-struct status_data *status_get_status_data(struct block_list *bl)
+static struct status_data *status_get_status_data(struct block_list *bl)
{
nullpo_retr(&status->dummy, bl);
@@ -6351,7 +6453,7 @@ struct status_data *status_get_status_data(struct block_list *bl)
}
}
-struct status_data *status_get_base_status(struct block_list *bl)
+static struct status_data *status_get_base_status(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
@@ -6374,7 +6476,9 @@ struct status_data *status_get_base_status(struct block_list *bl)
return NULL;
}
}
-defType status_get_def(struct block_list *bl) {
+
+static defType status_get_def(struct block_list *bl)
+{
struct unit_data *ud;
struct status_data *st = status->get_status_data(bl);
int def = st ? st->def : 0;
@@ -6385,14 +6489,15 @@ defType status_get_def(struct block_list *bl) {
return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
}
-unsigned short status_get_speed(struct block_list *bl)
+static unsigned short status_get_speed(struct block_list *bl)
{
+ nullpo_ret(bl);
if (bl->type == BL_NPC) //Only BL with speed data but no status_data [Skotlex]
return BL_UCCAST(BL_NPC, bl)->speed;
return status->get_status_data(bl)->speed;
}
-int status_get_party_id(const struct block_list *bl)
+static int status_get_party_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6448,7 +6553,7 @@ int status_get_party_id(const struct block_list *bl)
return 0;
}
-int status_get_guild_id(const struct block_list *bl)
+static int status_get_guild_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6514,7 +6619,7 @@ int status_get_guild_id(const struct block_list *bl)
return 0;
}
-int status_get_emblem_id(const struct block_list *bl)
+static int status_get_emblem_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6576,7 +6681,7 @@ int status_get_emblem_id(const struct block_list *bl)
return 0;
}
-int status_get_mexp(const struct block_list *bl)
+static int status_get_mexp(const struct block_list *bl)
{
nullpo_ret(bl);
if (bl->type == BL_MOB)
@@ -6586,7 +6691,7 @@ int status_get_mexp(const struct block_list *bl)
return 0;
}
-int status_get_race2(const struct block_list *bl)
+static int status_get_race2(const struct block_list *bl)
{
nullpo_ret(bl);
if (bl->type == BL_MOB)
@@ -6596,12 +6701,13 @@ int status_get_race2(const struct block_list *bl)
return 0;
}
-int status_isdead(struct block_list *bl) {
+static int status_isdead(struct block_list *bl)
+{
nullpo_ret(bl);
return status->get_status_data(bl)->hp == 0;
}
-int status_isimmune(struct block_list *bl)
+static int status_isimmune(struct block_list *bl)
{
struct status_change *sc = NULL;
nullpo_ret(bl);
@@ -6618,14 +6724,14 @@ int status_isimmune(struct block_list *bl)
return 0;
}
-struct view_data *status_get_viewdata(struct block_list *bl)
+static struct view_data *status_get_viewdata(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
case BL_PC: return &BL_UCAST(BL_PC, bl)->vd;
case BL_MOB: return BL_UCAST(BL_MOB, bl)->vd;
case BL_PET: return &BL_UCAST(BL_PET, bl)->vd;
- case BL_NPC: return BL_UCAST(BL_NPC, bl)->vd;
+ case BL_NPC: return &BL_UCAST(BL_NPC, bl)->vd;
case BL_HOM: return BL_UCAST(BL_HOM, bl)->vd;
case BL_MER: return BL_UCAST(BL_MER, bl)->vd;
case BL_ELEM: return BL_UCAST(BL_ELEM, bl)->vd;
@@ -6633,7 +6739,7 @@ struct view_data *status_get_viewdata(struct block_list *bl)
return NULL;
}
-void status_set_viewdata(struct block_list *bl, int class_)
+static void status_set_viewdata(struct block_list *bl, int class_)
{
struct view_data* vd;
nullpo_retv(bl);
@@ -6678,36 +6784,33 @@ void status_set_viewdata(struct block_list *bl, int class_)
break;
}
}
- sd->vd.class_ = class_;
+ sd->vd.class = class_;
clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
- sd->vd.head_top = sd->status.head_top;
- sd->vd.head_mid = sd->status.head_mid;
- sd->vd.head_bottom = sd->status.head_bottom;
+ sd->vd.head_top = sd->status.look.head_top;
+ sd->vd.head_mid = sd->status.look.head_mid;
+ sd->vd.head_bottom = sd->status.look.head_bottom;
sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
- sd->vd.robe = sd->status.robe;
+ sd->vd.robe = sd->status.look.robe;
sd->vd.body_style = sd->status.body;
sd->vd.sex = sd->status.sex;
if (sd->vd.cloth_color) {
- if (sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_XMAS && battle_config.xmas_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_SUMMER && battle_config.summer_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */)
+ if ((sd->sc.option & OPTION_WEDDING) != 0 && battle_config.wedding_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_XMAS) != 0 && battle_config.xmas_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_SUMMER) != 0 && battle_config.summer_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_HANBOK) != 0 && battle_config.hanbok_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_OKTOBERFEST) != 0 && battle_config.oktoberfest_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_SUMMER2) != 0 && battle_config.summer2_ignorepalette == true)
sd->vd.cloth_color = 0;
}
- if (sd->vd.body_style
- && (sd->sc.option&OPTION_WEDDING
- || sd->sc.option&OPTION_XMAS
- || sd->sc.option&OPTION_SUMMER
- || sd->sc.option&OPTION_HANBOK
- || sd->sc.option&OPTION_OKTOBERFEST))
+ if (sd->vd.body_style != 0 && (sd->sc.option & OPTION_COSTUME) != 0)
sd->vd.body_style = 0;
} else if (vd != NULL) {
memcpy(&sd->vd, vd, sizeof(struct view_data));
@@ -6730,7 +6833,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
struct pet_data *pd = BL_UCAST(BL_PET, bl);
if (vd != NULL) {
memcpy(&pd->vd, vd, sizeof(struct view_data));
- if (!pc->db_checkid(vd->class_)) {
+ if (!pc->db_checkid(vd->class)) {
pd->vd.hair_style = battle_config.pet_hair_style;
if(pd->pet.equip) {
pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
@@ -6746,10 +6849,14 @@ void status_set_viewdata(struct block_list *bl, int class_)
case BL_NPC:
{
struct npc_data *nd = BL_UCAST(BL_NPC, bl);
- if (vd != NULL)
- nd->vd = vd;
- else
+ if (vd != NULL) {
+ memcpy(&nd->vd, vd, sizeof(struct view_data));
+ } else if (pc->db_checkid(class_)) {
+ memset(&nd->vd, 0, sizeof(struct view_data));
+ nd->vd.class = class_;
+ } else {
ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name);
+ }
}
break;
case BL_HOM: //[blackhole89]
@@ -6783,7 +6890,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
}
/// Returns the status_change data of bl or NULL if it doesn't exist.
-struct status_change *status_get_sc(struct block_list *bl)
+static struct status_change *status_get_sc(struct block_list *bl)
{
if (bl != NULL) {
switch (bl->type) {
@@ -6798,7 +6905,8 @@ struct status_change *status_get_sc(struct block_list *bl)
return NULL;
}
-void status_change_init(struct block_list *bl) {
+static void status_change_init(struct block_list *bl)
+{
struct status_change *sc = status->get_sc(bl);
nullpo_retv(sc);
memset(sc, 0, sizeof (struct status_change));
@@ -6810,7 +6918,8 @@ void status_change_init(struct block_list *bl) {
* @see status_change_start for the expected parameters.
* @return the adjusted duration based on flag values.
*/
-int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag) {
+static int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
+{
//Percentual resistance: 10000 = 100% Resist
//Example: 50% -> sc_def=5000 -> 25%; 5000ms -> tick_def=5000 -> 2500ms
int sc_def = 0, tick_def = -1; //-1 = use sc_def
@@ -6864,6 +6973,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
sd = BL_CAST(BL_PC,bl);
st = status->get_status_data(bl);
bst = status->get_base_status(bl);
+ nullpo_ret(bst);
sc = status->get_sc(bl);
if( sc && !sc->count )
sc = NULL;
@@ -7157,6 +7267,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
case SC_NETHERWORLD:
tick = max(tick, 4000);
break;
+ case SC_SIREN:
+ tick = max(tick, 10000); // Minimum duration 10s
+ break;
default:
//Skills need to trigger even if the duration is reduced below 1ms
tick = max(tick, 1);
@@ -7167,11 +7280,14 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
#undef SCDEF_LVL_CAP
#undef SCDEF_LVL_DIFF
}
+
/* [Ind/Hercules] fast-checkin sc-display array */
-void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
+static void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3)
+{
struct sc_display_entry *entry;
int i;
+ nullpo_retv(sd);
for( i = 0; i < sd->sc_display_count; i++ ) {
if( sd->sc_display[i]->type == type )
break;
@@ -7194,9 +7310,12 @@ void status_display_add(struct map_session_data *sd, enum sc_type type, int dval
RECREATE(sd->sc_display, struct sc_display_entry *, ++sd->sc_display_count);
sd->sc_display[ sd->sc_display_count - 1 ] = entry;
}
-void status_display_remove(struct map_session_data *sd, enum sc_type type) {
+
+static void status_display_remove(struct map_session_data *sd, enum sc_type type)
+{
int i;
+ nullpo_retv(sd);
for( i = 0; i < sd->sc_display_count; i++ ) {
if( sd->sc_display[i]->type == type )
break;
@@ -7226,8 +7345,9 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
}
}
}
+
/**
- * Starts a status change.
+ * Starts a status change with a set remaining time.
*
* @param src Status change source bl.
* @param bl Status change target bl.
@@ -7237,13 +7357,15 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
* @param val2 Additional value (meaning depends on type).
* @param val3 Additional value (meaning depends on type).
* @param val4 Additional value (meaning depends on type).
- * @param tick Base duration (milliseconds).
+ * @param tick Remaining duration (miliseconds). (if flag doesn't contain SCFLAG_LOADED, it will become the final total_tick)
+ * @param total_tick Base duration (milliseconds).
* @param flag Special flags (@see enum scstart_flag).
*
* @retval 0 if no status change happened.
* @retval 1 if the status change was successfully applied.
*/
-int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) {
+static int status_change_start_sub(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag)
+{
struct map_session_data *sd = NULL;
struct status_change* sc;
struct status_change_entry* sce;
@@ -7256,7 +7378,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
st = status->get_status_data(bl);
if (type <= SC_NONE || type >= SC_MAX) {
- ShowError("status_change_start: invalid status change (%d)!\n", type);
+ ShowError("status_change_start_sub: invalid status change (%d)!\n", type);
return 0;
}
@@ -7276,84 +7398,19 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
#endif // 0
}
- if( sc->data[SC_REFRESH] ) {
- if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
- return 0; // Immune to status ailements
- switch( type ) {
- case SC_DEEP_SLEEP:
- case SC__CHAOS:
- case SC_BURNING:
- case SC_STUN:
- case SC_SLEEP:
- case SC_CURSE:
- case SC_STONE:
- case SC_POISON:
- case SC_BLIND:
- case SC_SILENCE:
- case SC_BLOODING:
- case SC_FREEZE:
- case SC_FROSTMISTY:
- case SC_COLD:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_MARSHOFABYSS:
- case SC_MANDRAGORA:
- return 0;
- }
- } else if( sc->data[SC_INSPIRATION] ) {
- if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
- return 0; // Immune to status ailements
- switch( type ) {
- case SC_POISON:
- case SC_BLIND:
- case SC_STUN:
- case SC_SILENCE:
- case SC__CHAOS:
- case SC_STONE:
- case SC_SLEEP:
- case SC_BLOODING:
- case SC_CURSE:
- case SC_BURNING:
- case SC_FROSTMISTY:
- case SC_FREEZE:
- case SC_COLD:
- case SC_FEAR:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_DEEP_SLEEP:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC__BODYPAINT:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- return 0;
- }
- }
+ if (status->is_immune_to_status(sc, type))
+ return 0;
sd = BL_CAST(BL_PC, bl);
- //Adjust tick according to status resistances
+ //Adjust total_tick according to status resistances
if( !(flag&(SCFLAG_NOAVOID|SCFLAG_LOADED)) ) {
- tick = status->get_sc_def(src, bl, type, rate, tick, flag);
- if( !tick ) return 0;
+ total_tick = status->get_sc_def(src, bl, type, rate, total_tick, flag);
+ if( !total_tick ) return 0;
}
- undead_flag = battle->check_undead(st->race,st->def_ele);
- //Check for inmunities / sc fails
+ undead_flag = battle->check_undead(st->race, st->def_ele);
+ // Check for inmunities / sc fails
switch (type) {
case SC_DRUMBATTLE:
case SC_NIBELUNGEN:
@@ -7366,8 +7423,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_GOLDENE_FERSE:
if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
|| (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
- )
+ ) {
return 0;
+ }
+ FALLTHROUGH
case SC_VACUUM_EXTREME:
if(sc->data[SC_HALLUCINATIONWALK])
return 0;
@@ -7375,10 +7434,15 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_STONE:
if(sc->data[SC_POWER_OF_GAIA])
return 0;
+ FALLTHROUGH
case SC_FREEZE:
//Undead are immune to Freeze/Stone
if (undead_flag && !(flag&SCFLAG_NOAVOID))
return 0;
+ // SC_LEXAETERNA should be removed when applying SC_STONE or SC_FREEZE
+ if (sc->data[SC_LEXAETERNA] != NULL)
+ status_change_end(bl, SC_LEXAETERNA, INVALID_TIMER);
+ FALLTHROUGH
case SC_SLEEP:
case SC_STUN:
case SC_FROSTMISTY:
@@ -7405,12 +7469,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
break;
case SC_KYRIE:
+ case SC_TUNAPARTY:
if (bl->type == BL_MOB)
return 0;
break;
case SC_OVERTHRUST:
if (sc->data[SC_OVERTHRUSTMAX])
return 0; // Overthrust can't take effect if under Max Overthrust. [Skotlex]
+ FALLTHROUGH
case SC_OVERTHRUSTMAX:
if (sc->option&OPTION_MADOGEAR)
return 0; // Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
@@ -7428,7 +7494,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
break;
case SC_MAGNIFICAT:
- if (sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR) // Mado is immune to magnificat
+ if (sc->option&OPTION_MADOGEAR) // Mado is immune to magnificat
return 0;
break;
case SC_ONEHANDQUICKEN:
@@ -7436,6 +7502,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_TWOHANDQUICKEN:
if (sc->data[SC_DEC_AGI])
return 0;
+ FALLTHROUGH
case SC_CONCENTRATION:
case SC_SPEARQUICKEN:
case SC_TRUESIGHT:
@@ -7444,6 +7511,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_ASSNCROS:
if (sc->option&OPTION_MADOGEAR)
return 0; // Mado is immune to wind walk, cart boost, etc (others above) [Ind]
+ FALLTHROUGH
case SC_INC_AGI:
if (sc->data[SC_QUAGMIRE])
return 0;
@@ -7492,11 +7560,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
if (!opt_flag) return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPSHIELD:
- if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
- else
+ if (val2 == 1) {
+ val2 = 0; //GX effect. Do not take shield off..
+ } else {
if (sd && !(flag&SCFLAG_LOADED)) {
int i;
if(sd->bonus.unstripable_equip&EQP_SHIELD)
@@ -7506,8 +7575,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
+ }
+ if (total_tick == 1)
+ return 1; //Minimal duration: Only strip without causing the SC
+ break;
case SC_NOEQUIPARMOR:
if (sd && !(flag&SCFLAG_LOADED)) {
int i;
@@ -7518,7 +7589,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPHELM:
if (sd && !(flag&SCFLAG_LOADED)) {
@@ -7530,7 +7601,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_MER_FLEE:
case SC_MER_ATK:
@@ -7564,30 +7635,6 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
return 0;
break;
- case SC_FOOD_STR_CASH:
- if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI_CASH:
- if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT_CASH:
- if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT_CASH:
- if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX_CASH:
- if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK_CASH:
- if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
- return 0;
- break;
case SC_CAMOUFLAGE:
if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
return 0;
@@ -7608,7 +7655,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( i < 0 )
return 0;
}
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_TOXIN:
case SC_PARALYSE:
@@ -7628,305 +7675,17 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if(sc->data[SC_HOVERING])
return 0;
break;
- case SC_OFFERTORIUM:
- if (sc->data[SC_MAGNIFICAT])
- return 0;
- break;
}
//Check for BOSS resistances
- if(st->mode&MD_BOSS && !(flag&SCFLAG_NOAVOID)) {
- if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ if (st->mode & MD_BOSS && !(flag & SCFLAG_NOAVOID)) {
+ if (status->is_boss_resist_sc(type))
return 0;
- switch (type) {
- case SC_BLESSING:
- case SC_DEC_AGI:
- case SC_PROVOKE:
- case SC_COMA:
- case SC_GRAVITATION:
- case SC_NJ_SUITON:
- case SC_RICHMANKIM:
- case SC_ROKISWEIL:
- case SC_FOGWALL:
- case SC_FROSTMISTY:
- case SC_BURNING:
- case SC_MARSHOFABYSS:
- case SC_ADORAMUS:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEEP_SLEEP:
- case SC_COLD:
-
- // Exploit prevention - kRO Fix
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
-
- // Ranger Effects
- case SC_WUGBITE:
- case SC_ELECTRICSHOCKER:
- case SC_MAGNETICFIELD:
-
- // Masquerades
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__IGNORANCE:
-
- // Other Effects
- case SC_VACUUM_EXTREME:
- case SC_NETHERWORLD:
-
- return 0;
- }
}
//Before overlapping fail, one must check for status cured.
- switch (type) {
- case SC_BLESSING:
- //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
- //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
- if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) {
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- }
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_INC_AGI:
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DEC_AGI:
- case SC_ADORAMUS:
- status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DONTFORGETME:
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
- break;
- case SC_ONEHANDQUICKEN:
- //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_OVERTHRUSTMAX:
- //Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
- break;
- case SC_KYRIE:
- //Cancels Assumptio
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_DELUGE:
- if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC_SILENCE:
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- break;
- case SC_HIDING:
- status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
- status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
- break;
- case SC_BERSERK:
- if( val3 == SC__BLOODYLUST )
- break;
- if(battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_PARRYING, INVALID_TIMER);
- status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- }
- #ifdef RENEWAL
- else {
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- }
- #endif
- break;
- case SC_ASSUMPTIO:
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- break;
- case SC_KAITE:
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_CARTBOOST:
- if (sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS]) {
- //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
- return 0;
- }
- break;
- case SC_FUSION:
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_GS_ADJUSTMENT:
- status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
- break;
- case SC_GS_MADNESSCANCEL:
- status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
- break;
- //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_PROPERTYUNDEAD:
- status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_STR:
- status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_AGI:
- status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_VIT:
- status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_INT:
- status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_DEX:
- status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_LUK:
- status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
- break;
- case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
- break;
- case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
- break;
- case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
- break;
- case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
- break;
- case SC_GM_BATTLE:
- status_change_end(bl, SC_GM_BATTLE2, INVALID_TIMER);
- break;
- case SC_GM_BATTLE2:
- status_change_end(bl, SC_GM_BATTLE, INVALID_TIMER);
- break;
- case SC_ENDURE:
- if( val4 == 1 )
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- break;
- case SC_FIGHTINGSPIRIT:
- case SC_OVERED_BOOST:
- status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
- break;
- case SC_MARSHOFABYSS:
- status_change_end(bl, SC_INCAGI, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- //Group A Status (doesn't overlap)
- case SC_SWING:
- case SC_SYMPHONY_LOVE:
- case SC_MOONLIT_SERENADE:
- case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- case SC_HARMONIZE:
- case SC_FRIGG_SONG:
- if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
- if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
- if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
- if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
- if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
- break;
- //Group B Status
- case SC_SIREN:
- case SC_DEEP_SLEEP:
- case SC_SIRCLEOFNATURE:
- case SC_LERADS_DEW:
- case SC_MELODYOFSINK:
- case SC_BEYOND_OF_WARCRY:
- case SC_UNLIMITED_HUMMING_VOICE:
- case SC_GLOOMYDAY:
- case SC_SONG_OF_MANA:
- case SC_DANCE_WITH_WUG:
- if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
- if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
- if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
- if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
- if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
- if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
- if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
- if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- break;
- case SC_REFLECTSHIELD:
- status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
- break;
- case SC_LG_REFLECTDAMAGE:
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
- break;
- case SC_GENTLETOUCH_ENERGYGAIN:
- case SC_GENTLETOUCH_CHANGE:
- case SC_GENTLETOUCH_REVITALIZE:
- if( type != SC_GENTLETOUCH_REVITALIZE )
- status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_ENERGYGAIN )
- status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_CHANGE )
- status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
- break;
- case SC_INVINCIBLE:
- status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
- break;
- case SC_INVINCIBLEOFF:
- status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
- break;
- case SC_MAGICPOWER:
- status_change_end(bl, type, INVALID_TIMER);
- break;
- }
+ if (status->end_sc_before_start(bl, st, sc, type, undead_flag, val1, val2, val3, val4))
+ return 0;
//Check for overlapping fails
if( (sce = sc->data[type]) ) {
@@ -8026,6 +7785,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_LERADS_DEW:
if (sc && sc->data[SC_BERSERK])
return 0;
+ FALLTHROUGH
case SC_SHAPESHIFT:
case SC_PROPERTYWALK:
break;
@@ -8038,6 +7798,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_JOINTBEAT:
val2 |= sce->val2; // stackable ailments
+ FALLTHROUGH
default:
if(sce->val1 > val1)
return 1; //Return true to not mess up skill animations. [Skotlex]
@@ -8048,9 +7809,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
calc_flag = status->dbs->ChangeFlagTable[type];
if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
+ case SC_AUTOTRADE:
+ case SC_KSPROTECTED:
+ break; // Prevent calling status_change_start_unknown_sc().
case SC_ADORAMUS:
sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
// Fall through to SC_INC_AGI
+ FALLTHROUGH
case SC_DEC_AGI:
case SC_INC_AGI:
val2 = 2 + val1; //Agi change
@@ -8063,33 +7828,33 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
if (val4)
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOBERSERK:
if (st->hp < st->max_hp>>2 &&
(!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000);
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CRUCIS:
val2 = 10 + 4*val1; //Def reduction
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
clif->emotion(bl,E_SWT);
break;
case SC_MAXIMIZEPOWER:
- tick_time = val2 = tick>0?tick:60000;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
break;
case SC_EDP: // [Celest]
//Chance to Poison enemies.
@@ -8100,7 +7865,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
#endif
val3 = 50 * (val1 + 1); //Damage increase (+50 +50*lv%)
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
- tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ total_tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
break;
case SC_POISONREACT:
val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
@@ -8130,10 +7895,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_SACRIFICE:
val2 = 5; //Lasts 5 hits
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_ENCHANTPOISON:
val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
+ FALLTHROUGH
case SC_ASPERSIO:
case SC_PROPERTYFIRE:
case SC_PROPERTYWATER:
@@ -8166,12 +7932,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
int i;
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8220,7 +7986,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
#endif
break;
case SC_NJ_SUITON:
- if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
+ if (val2 == 0 || (sd != NULL && (sd->job & MAPID_BASEMASK) == MAPID_NINJA)) {
//No penalties.
val2 = 0; //Agi penalty
val3 = 0; //Walk speed penalty
@@ -8250,9 +8016,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
//val3 : Brings the skill_lv (merged into val1 here)
//val4 : Partner
if (val1 == CG_MOONLIT)
- clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
+ clif->status_change(bl, status->get_sc_icon(SC_MOON), status->get_sc_relevant_bl_types(SC_MOON), 1, total_tick, 0, 0, 0);
val1|= (val3<<16);
- val3 = tick/1000; //Tick duration
+ val3 = total_tick/1000; //Tick duration
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_LONGING:
@@ -8278,8 +8044,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_SUMMER:
case SC_HANBOK:
case SC_OKTOBERFEST:
- if (!vd) return 0;
- //Store previous values as they could be removed.
+ case SC_DRESS_UP:
+ if (vd == NULL)
+ return 0;
+ // Store previous values as they could be removed.
unit->stop_attack(bl);
break;
case SC_NOCHAT:
@@ -8287,8 +8055,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
// mmocharstatus.manner, each negative point results in 1 minute with this status activated
// This is done this way because the message that the client displays is hardcoded, and only
// shows how many minutes are remaining. [Panikon]
- tick = 60000;
- val1 = battle_config.manner_system; //Mute filters.
+ total_tick = 60000;
if (sd)
{
clif->changestatus(sd,SP_MANNER,sd->status.manner);
@@ -8297,11 +8064,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_STONE:
- val3 = tick/1000; //Petrified HP-damage iterations.
+ val3 = total_tick/1000; //Petrified HP-damage iterations.
if(val3 < 1) val3 = 1;
- tick = val4; //Petrifying time.
+ total_tick = val4; //Petrifying time.
if(val4 > 500) // not with WL_SIENNAEXECRATE
- tick = max(tick, 1000); //Min time
+ total_tick = max(total_tick, 1000); //Min time
calc_flag = 0; //Actual status changes take effect on petrified state.
break;
@@ -8320,7 +8087,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
// fall through
case SC_POISON:
- val3 = tick/1000; //Damage iterations
+ val3 = total_tick/1000; //Damage iterations
if(val3 < 1) val3 = 1;
tick_time = 1000; // [GodLesZ] tick time
//val4: HP damage
@@ -8334,7 +8101,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
clif->emotion(bl,E_WHAT);
break;
case SC_BLOODING:
- val4 = tick/10000;
+ val4 = total_tick/10000;
if (!val4) val4 = 1;
tick_time = 10000; // [GodLesZ] tick time
break;
@@ -8347,7 +8114,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
// val2 = seconds between heals
// val4 = total of heals
if (val2 < 1) val2 = 1;
- if ((val4 = tick / (val2 * 1000)) < 1)
+ if ((val4 = total_tick / (val2 * 1000)) < 1)
val4 = 1;
tick_time = val2 * 1000; // [GodLesZ] tick time
break;
@@ -8360,19 +8127,19 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0; // No need to start SC
}
val1 = boss_md->bl.id;
- if( (val4 = tick/1000) < 1 )
+ if( (val4 = total_tick/1000) < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
}
break;
case SC_HIDING:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
val3 = 0; // unused, previously speed adjustment
val4 = val1+3; //Seconds before SP substraction happen.
break;
case SC_CHASEWALK:
- val2 = tick>0?tick:10000; //Interval at which SP is drained.
+ val2 = total_tick>0?total_tick:10000; //Interval at which SP is drained.
val3 = 35 - 5 * val1; //Speed adjustment.
if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
val3 -= 40;
@@ -8382,8 +8149,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_CLOAKING:
if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
val1 = 10;
- tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ tick_time = val2 = total_tick>0?total_tick:60000; //SP consumption rate.
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
val3 = 0; // unused, previously walk speed adjustment
//val4&1 signals the presence of a wall.
//val4&2 makes cloak not end on normal attacks [Skotlex]
@@ -8397,7 +8164,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_RUWACH:
case SC_WZ_SIGHTBLASTER:
val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
- val2 = tick/20;
+ val2 = total_tick/20;
tick_time = 20; // [GodLesZ] tick time
break;
@@ -8414,7 +8181,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_TURNKICK_READY:
case SC_DODGE_READY:
case SC_PUSH_CART:
- tick = INFINITE_DURATION;
+ case SC_DAILYSENDMAILCNT:
+ total_tick = INFINITE_DURATION;
break;
case SC_AUTOGUARD:
@@ -8430,12 +8198,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( sd ) {
for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
if (mc->devotion_flag && (tsd = mc->master) != NULL) {
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON);
}
}
}
@@ -8454,7 +8222,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
for (i = 0; i < MAX_PC_DEVOTION; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL)
- status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID);
+ status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,total_tick,SCFLAG_NOAVOID);
}
}
}
@@ -8467,8 +8235,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
val2 = 12; //SP cost
val4 = 10000; //Decrease at 10secs intervals.
- val3 = tick/val4;
- tick = INFINITE_DURATION; // duration sent to the client should be infinite
+ val3 = total_tick/val4;
+ total_tick = INFINITE_DURATION; // duration sent to the client should be infinite
tick_time = val4; // [GodLesZ] tick time
break;
case SC_PARRYING:
@@ -8486,21 +8254,21 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_BERSERK:
if( val3 == SC__BLOODYLUST )
- sc_start(src,bl,(sc_type)val3,100,val1,tick);
+ sc_start(src,bl,(sc_type)val3,100,val1,total_tick);
if (!val3 && (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4))
- sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick);
+ sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, total_tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
if (!val4) val4 = 10000; //Val4 holds damage interval
- val3 = tick/val4; //val3 holds skill duration
+ val3 = total_tick/val4; //val3 holds skill duration
tick_time = val4; // [GodLesZ] tick time
break;
case SC_GOSPEL:
if(val4 == BCT_SELF) {
// self effect
- val2 = tick/10000;
+ val2 = total_tick/10000;
tick_time = 10000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
}
@@ -8553,23 +8321,23 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = 0;
val4 = 0;
max_stat = (status->get_lv(bl)-10<50)?status->get_lv(bl)-10:50;
- stat = max(0, max_stat - status2->str ); val3 |= cap_value(stat,0,0xFF)<<16;
- stat = max(0, max_stat - status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
- stat = max(0, max_stat - status2->vit ); val3 |= cap_value(stat,0,0xFF);
- stat = max(0, max_stat - status2->int_); val4 |= cap_value(stat,0,0xFF)<<16;
- stat = max(0, max_stat - status2->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
- stat = max(0, max_stat - status2->luk ); val4 |= cap_value(stat,0,0xFF);
+ stat = max(0, max_stat - (int)status2->str ); val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = max(0, max_stat - (int)status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = max(0, max_stat - (int)status2->vit ); val3 |= cap_value(stat,0,0xFF);
+ stat = max(0, max_stat - (int)status2->int_); val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = max(0, max_stat - (int)status2->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = max(0, max_stat - (int)status2->luk ); val4 |= cap_value(stat,0,0xFF);
}
break;
case SC_SWORDREJECT:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_MEMORIZE:
val2 = 5; //Memorized casts.
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_GRAVITATION:
@@ -8623,11 +8391,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
if (src2 && sc2) {
if (!sce2) //Start lock on caster.
- sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
+ sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,total_tick+1000);
else { //Increase count of locked enemies and refresh time.
(sce2->val2)++;
timer->delete(sce2->timer, status->change_timer);
- sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
+ sce2->timer = timer->add(timer->gettick()+total_tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
}
} else //Status failed.
return 0;
@@ -8640,6 +8408,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
switch (val1) {
case 3: //33*3 + 1 -> 100%
val2++;
+ FALLTHROUGH
case 1:
case 2: //33, 66%
val2 += 33*val1;
@@ -8662,13 +8431,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
//val4: TK: Combo time
struct unit_data *ud = unit->bl2ud(bl);
if( ud && (!val3 || val3 == 2) ) {
- tick += 300 * battle_config.combo_delay_rate/100;
- ud->attackabletime = timer->gettick()+tick;
+ total_tick += 300 * battle_config.combo_delay_rate/100;
+ ud->attackabletime = timer->gettick()+total_tick;
if( !val3 )
- unit->set_walkdelay(bl, timer->gettick(), tick, 1);
+ unit->set_walkdelay(bl, timer->gettick(), total_tick, 1);
}
val3 = 0;
- val4 = tick;
+ val4 = total_tick;
break;
}
case SC_EARTHSCROLL:
@@ -8682,7 +8451,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_KAAHI:
val2 = 200*val1; //HP heal
@@ -8697,7 +8466,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_TRICKDEAD:
if (vd) vd->dead_sit = 1;
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_CONCENTRATION:
val2 = 2 + val1;
@@ -8715,20 +8484,21 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
//val2 holds if it was casted on self, or is bonus received from others
val3 = 5*val1; //Power increase
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_ADRENALINE2:
case SC_ADRENALINE:
val3 = (val2) ? 300 : 200; // aspd increase
+ FALLTHROUGH
case SC_WEAPONPERFECT:
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
+ total_tick += total_tick / 10;
break;
case SC_LKCONCENTRATION:
val2 = 5*val1; //Batk/Watk Increase
val3 = 10*val1; //Hit Increase
val4 = 5*val1; //Def reduction
- sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 1, total_tick); //Endure effect
break;
case SC_ANGELUS:
val2 = 5*val1; //def increase
@@ -8798,7 +8568,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = 12*val1; //mdef2 reduction.
break;
case SC_SKA:
- val2 = tick/1000;
+ val2 = total_tick/1000;
val3 = rnd()%100; //Def changes randomly every second...
tick_time = 1000; // [GodLesZ] tick time
break;
@@ -8811,7 +8581,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
// When renewing status' information
// val3 Return map_index
// val4 return coordinates
- tick = val1>0?1000:250;
+ total_tick = val1>0?1000:250;
if (sd)
{
if (sd->mapindex != val2)
@@ -8846,11 +8616,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_SWOO:
if(st->mode&MD_BOSS)
- tick /= 5; //TODO: Reduce skill's duration. But for how long?
+ total_tick /= 5; //TODO: Reduce skill's duration. But for how long?
break;
case SC_SPIDERWEB:
if( bl->type == BL_PC )
- tick /= 2;
+ total_tick /= 2;
break;
case SC_ARMOR:
//NPC_DEFENDER:
@@ -8915,7 +8685,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_KAIZEL:
val2 = 10*val1; //% of life to be revived with
break;
- // case SC_ARMORPROPERTY:
+ case SC_ARMORPROPERTY:
+ {
+ int ele = (val1 > 0 ? SC_RESIST_PROPERTY_WATER :
+ (val2 > 0 ? SC_RESIST_PROPERTY_GROUND :
+ (val3 > 0 ? SC_RESIST_PROPERTY_FIRE :
+ (val4 > 0 ? SC_RESIST_PROPERTY_WIND : SI_BLANK))));
+ clif->status_change(bl, status->get_sc_icon(ele), status->get_sc_relevant_bl_types(ele), 1, total_tick, 0, 0, 0);
+ break;
// case SC_ARMOR_RESIST:
// Mod your resistance against elements:
// val1 = water | val2 = earth | val3 = fire | val4 = wind
@@ -8924,7 +8701,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
//Place here SCs that have no SCB_* data, no skill associated, no ICON
//associated, and yet are not wrong/unknown. [Skotlex]
//break;
-
+ }
case SC_MER_FLEE:
case SC_MER_ATK:
case SC_MER_HIT:
@@ -8956,11 +8733,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
**/
case SC_FEAR:
val2 = 2;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BURNING:
- val4 = tick / 3000; // Total Ticks to Burn!!
+ val4 = total_tick / 3000; // Total Ticks to Burn!!
tick_time = 3000; // [GodLesZ] tick time
break;
/**
@@ -8974,14 +8751,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase
break;
case SC_ABUNDANCE:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
/**
* Arch Bishop
**/
case SC_RENOVATIO:
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000;
break;
case SC_SECRAMENT:
@@ -8992,28 +8769,28 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_WEAPONBLOCKING:
val2 = 10 + 2 * val1; // Chance
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_TOXIN:
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_MAGICMUSHROOM:
- val4 = tick / 4000;
+ val4 = total_tick / 4000;
tick_time = 4000; // [GodLesZ] tick time
break;
case SC_PYREXIA:
status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE); // Blind status that last for 30 seconds
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_LEECHESEND:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_OBLIVIONCURSE:
- val4 = tick / 3000;
+ val4 = total_tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_CLOAKINGEXCEED:
@@ -9052,7 +8829,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_SUMMON3:
case SC_SUMMON4:
case SC_SUMMON5:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
@@ -9067,19 +8844,19 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
break;
case SC_STEALTHFIELD_MASTER:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 2000 + (1000 * val1);
break;
case SC_ELECTRICSHOCKER:
case SC_COLD:
case SC_MEIKYOUSISUI:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
if( val4 < 1 )
val4 = 1;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_CAMOUFLAGE:
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_WUGDASH:
@@ -9090,17 +8867,17 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = (int)(currenttick&0x00000000ffffffffLL);
val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC__REPRODUCE:
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000;
break;
case SC__SHADOWFORM: {
struct map_session_data * s_sd = map->id2sd(val2);
if( s_sd )
s_sd->shadowform_id = bl->id;
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9111,7 +8888,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC__INVISIBILITY:
val2 = 50 - 10 * val1; // ASPD
val3 = 200 * val1; // CRITICAL
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC__ENERVATION:
@@ -9138,7 +8915,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (sd->status.pet_id > 0)
pet->menu(sd, 3);
if (homun_alive(sd->hd))
- homun->vaporize(sd,HOM_ST_REST);
+ homun->vaporize(sd, HOM_ST_REST, true);
if (sd->md)
mercenary->delete(sd->md,3);
}
@@ -9153,8 +8930,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC__WEAKNESS:
val2 = 10 * val1;
// bypasses coating protection and MADO
- sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick);
- sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick);
+ sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,total_tick);
+ sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,total_tick);
break;
case SC_GN_CARTBOOST:
if( val1 < 3 )
@@ -9174,7 +8951,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_STRIKING:
val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BLOOD_SUCKER:
@@ -9183,7 +8960,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = 1;
if(src2)
val3 = 200 + 100 * val1 + status_get_int(src2);
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
@@ -9204,22 +8981,22 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val2 = 5 + 5 * val1;
break;
case SC_SIREN:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_DEEP_SLEEP:
- val4 = tick / 2000;
+ val4 = total_tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_SIRCLEOFNATURE:
val2 = 40 * val1;//HP recovery
val3 = 4 * val1;//SP drain
- val4 = tick / 1000;
+ val4 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_SONG_OF_MANA:
val3 = 10 + 5 * val2;
- val4 = tick/5000;
+ val4 = total_tick/5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_SATURDAY_NIGHT_FEVER:
@@ -9227,7 +9004,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if ( val2 < 1000 )
val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech]
val3 = tick/val2;*/
- val3 = tick / 3000;
+ val3 = total_tick / 3000;
tick_time = 3000;// [GodLesZ] tick time
break;
case SC_GLOOMYDAY:
@@ -9263,7 +9040,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_MELODYOFSINK:
val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer.
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000;
break;
case SC_BEYOND_OF_WARCRY:
@@ -9281,13 +9058,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_LG_REFLECTDAMAGE:
val2 = 15 + 5 * val1;
val3 = 25 + 5 * val1; //Number of Reflects
- val4 = tick/1000;
+ val4 = total_tick/1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_FORCEOFVANGUARD:
val2 = 8 + 12 * val1; // Chance
val3 = 5 + 2 * val1; // Max rage counters
- tick = INFINITE_DURATION; //endless duration in the client
+ total_tick = INFINITE_DURATION; //endless duration in the client
break;
case SC_EXEEDBREAK:
if( sd ){
@@ -9310,7 +9087,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_MAGNETICFIELD:
- val3 = tick / 1000;
+ val3 = total_tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_INSPIRATION:
@@ -9318,7 +9095,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus
val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus
}
- val4 = tick / 5000;
+ val4 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
break;
@@ -9329,7 +9106,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
break;
case SC_RAISINGDRAGON:
- val3 = tick / 5000;
+ val3 = total_tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_GENTLETOUCH_CHANGE:
@@ -9415,17 +9192,20 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_WILD_STORM:
case SC_UPHEAVAL:
val2 += 10;
+ FALLTHROUGH
case SC_HEATER:
case SC_COOLER:
case SC_BLAST:
case SC_CURSED_SOIL:
val2 += 10;
+ FALLTHROUGH
case SC_PYROTECHNIC:
case SC_AQUAPLAY:
case SC_GUST:
case SC_PETROLOGY:
val2 += 5;
val3 += 9000;
+ FALLTHROUGH
case SC_CIRCLE_OF_FIRE:
case SC_WATER_SCREEN:
case SC_WIND_STEP:
@@ -9436,7 +9216,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_STONE_SHIELD:
val2 += 5;
val3 += 1000;
- val4 = tick;
+ val4 = total_tick;
tick_time = val3;
break;
case SC_WATER_BARRIER:
@@ -9459,18 +9239,18 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_STOMACHACHE:
val3 = 8; // SP consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_STEAMPACK: // [Frost]
val3 = 100; // HP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
- sc_start(src, bl, SC_ENDURE, 100, 10, tick); // Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 10, total_tick); // Endure effect
break;
case SC_MAGIC_CANDY: // [Frost]
val3 = 90; // SP Consume.
- val4 = tick / 10000;
+ val4 = total_tick / 10000;
tick_time = 10000;
break;
case SC_PROMOTE_HEALTH_RESERCH:
@@ -9507,8 +9287,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_KAGEMUSYA:
val3 = val1 * 2;
+ FALLTHROUGH
case SC_IZAYOI:
- val2 = tick/1000;
+ val2 = total_tick/1000;
tick_time = 1000;
break;
case SC_ZANGETSU:
@@ -9538,22 +9319,22 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
PER( 100 / (status_get_max_hp(bl) / hp), lv );
- status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
+ status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, STATUS_HEAL_FORCED);
PER( 100 / (status_get_max_sp(bl) / sp), lv );
- status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
+ status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), STATUS_HEAL_FORCED);
}
#undef PER
break;
case SC_ANGRIFFS_MODUS:
val2 = 50 + 20 * val1; //atk bonus
val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
+ val4 = total_tick/1000; // hp/sp reduction timer
tick_time = 1000;
break;
case SC_NEUTRALBARRIER:
- tick_time = tick;
- tick = INFINITE_DURATION;
+ tick_time = total_tick;
+ total_tick = INFINITE_DURATION;
break;
case SC_GOLDENE_FERSE:
val2 = 10 + 10*val1; //max hp bonus
@@ -9582,10 +9363,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
if(sc->data[SC_NEEDLE_OF_PARALYZE])
- sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ sc_start(src, bl, SC_ENDURE, 100, val1, total_tick); //start endure for same duration
break;
case SC_STYLE_CHANGE: //[Lighta] need real info
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
else val2 = MH_MD_FIGHTING;
break;
@@ -9593,12 +9374,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
status_percent_heal(bl,100,0);
val2 = 7 - val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_KINGS_GRACE:
val2 = 3 + val1;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_TELEKINESIS_INTENSE:
val2 = 10 * val1;
@@ -9611,7 +9392,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val2 = 5 * val1;
val3 = (20 * val1) + 80;
tick_time = 1000;
- val4 = tick / tick_time;
+ val4 = total_tick / tick_time;
break;
case SC_DARKCROW:
val2 = 30 * val1;
@@ -9620,8 +9401,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (!mob->db_checkid(val1))
val1 = MOBID_PORING;
break;
+ case SC_SPRITEMABLE:
case SC_ALL_RIDING:
- tick = INFINITE_DURATION;
+ total_tick = INFINITE_DURATION;
break;
case SC_FLASHCOMBO:
/**
@@ -9630,26 +9412,56 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
**/
val2 = 20+(20*val1);
break;
+ /**
+ * Summoner
+ */
+ case SC_FRESHSHRIMP:
+ val4 = total_tick / (10000 - ((val1 - 1) * 1000));
+ tick_time = 10000 - ((val1 - 1) * 1000);
+ if (val4 <= 0) // Prevents a negeative value from happening
+ val4 = 0;
+ break;
+ case SC_ARCLOUSEDASH:
+ val2 = 15 + 5 * val1; // AGI
+ val3 = 25; // Move speed increase
+ if (sd != NULL && (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)
+ val4 = 10; // Ranged ATK increase
+ break;
+ case SC_TUNAPARTY:
+ val2 = (st->max_hp * (val1 * 10) / 100); // %Max HP to absorb
+ break;
+ case SC_BITESCAR:
+ val2 = 2 * val1; // MHP% damage
+ val4 = total_tick / 1000;
+ tick_time = 1000;
+ break;
+ case SC_SHRIMP:
+ val2 = 10; // BATK%, MATK%
+ break;
+ case SC_CATNIPPOWDER:
+ val2 = 50; // WATK%, MATK%
+ val3 = 25 * val1; // Move speed reduction
+ break;
default:
- if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) {
- //Status change with no calc, no icon, and no skill associated...?
- ShowError("UnknownStatusChange [%d]\n", type);
+ if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag)) {
return 0;
}
}
- } else { //Special considerations when loading SC data.
- switch( type ) {
+ } else { // Special considerations when loading SC data.
+ switch (type) {
case SC_WEDDING:
case SC_XMAS:
case SC_SUMMER:
case SC_HANBOK:
case SC_OKTOBERFEST:
- if( !vd ) break;
- clif->changelook(bl,LOOK_BASE,vd->class_);
- clif->changelook(bl,LOOK_WEAPON,0);
- clif->changelook(bl,LOOK_SHIELD,0);
- clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- clif->changelook(bl,LOOK_BODY2,0);
+ case SC_DRESS_UP:
+ if (vd == NULL)
+ break;
+ clif->changelook(bl, LOOK_BASE, vd->class);
+ clif->changelook(bl, LOOK_WEAPON, 0);
+ clif->changelook(bl, LOOK_SHIELD, 0);
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, vd->cloth_color);
+ clif->changelook(bl, LOOK_BODY2, 0);
break;
case SC_KAAHI:
val4 = INVALID_TIMER;
@@ -9658,27 +9470,272 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
/* values that must be set regardless of SCFLAG_LOADED e.g. val_flag */
- switch(type) {
+ val_flag = status->get_val_flag(type);
+
+ /* [Ind/Hercules] */
+ status->change_start_display(sd, type, val1, val2, val3, val4);
+
+ //Those that make you stop attacking/walking....
+ status->change_start_stop_action(bl, type);
+
+ // Set option as needed.
+ opt_flag = status->change_start_set_option(bl, sc, type, val1, val2, val3, val4);
+
+ //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
+ if(opt_flag) {
+ clif->changeoption(bl);
+ if( sd && opt_flag&0x4 ) {
+ if (vd)
+ clif->changelook(bl, LOOK_BASE, vd->class);
+ clif->changelook(bl,LOOK_WEAPON,0);
+ clif->changelook(bl,LOOK_SHIELD,0);
+ if (vd)
+ clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
+ }
+ }
+ if (calc_flag&SCB_DYE) {
+ //Reset DYE color
+ if (vd && vd->cloth_color) {
+ val4 = vd->cloth_color;
+ clif->changelook(bl,LOOK_CLOTHES_COLOR,0);
+ }
+ calc_flag&=~SCB_DYE;
+ }
+
+#if 0 //Currently No SC's use this
+ if (calc_flag&SCB_BODY) {
+ //Reset Body Style
+ if (vd && vd->body_style) {
+ val4 = vd->body_style;
+ clif->changelook(bl,LOOK_BODY2,0);
+ }
+ calc_flag&=~SCB_BODY;
+ }
+#endif
+
+ if (!(flag & SCFLAG_LOADED))
+ tick = total_tick; // When starting a new SC (not loading), its remaining duration is the same as the total
+ if(!(flag & SCFLAG_NOICON) && !(flag & SCFLAG_LOADED && status->dbs->DisplayType[type]))
+ clif->status_change_sub(bl, status->get_sc_icon(type), status->get_sc_relevant_bl_types(type), 1, tick, total_tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0);
+
+ /**
+ * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
+ **/
+ if(tick_time)
+ tick = tick_time;
+
+ //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
+ if((sce=sc->data[type])) {// reuse old sc
+ if( sce->timer != INVALID_TIMER )
+ timer->delete(sce->timer, status->change_timer);
+ } else {// new sc
+ ++(sc->count);
+ sce = sc->data[type] = ers_alloc(status->data_ers, struct status_change_entry);
+ }
+
+ sce->val1 = val1;
+ sce->val2 = val2;
+ sce->val3 = val3;
+ sce->val4 = val4;
+ sce->total_tick = total_tick;
+
+ if (tick >= 0) {
+ sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
+ sce->infinite_duration = false;
+ } else {
+ sce->timer = INVALID_TIMER; //Infinite duration
+ sce->infinite_duration = true;
+ if( sd )
+ chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
+ }
+
+ if (calc_flag)
+ status_calc_bl(bl,calc_flag);
+
+ if(sd && sd->pd)
+ pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing
+
+ switch (type) {
+ case SC_BERSERK:
+ if (!(sce->val2)) { //don't heal if already set
+ status->heal(bl, st->max_hp, 0, STATUS_HEAL_FORCED); //Do not use percent_heal as this healing must override BERSERK's block.
+ status->set_sp(bl, 0, STATUS_HEAL_DEFAULT); //Damage all SP
+ }
+ sce->val2 = 5 * st->max_hp / 100;
+ break;
+ case SC_HLIF_CHANGE:
+ status_percent_heal(bl, 100, 100);
+ break;
+ case SC_RUN:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->run(bl, NULL, SC_RUN);
+ }
+ break;
+ case SC_CASH_BOSS_ALARM:
+ if( sd )
+ clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
+ break;
+ case SC_MER_HP:
+ status_percent_heal(bl, 100, 0); // Recover Full HP
+ break;
+ case SC_MER_SP:
+ status_percent_heal(bl, 0, 100); // Recover Full SP
+ break;
+ case SC_PROMOTE_HEALTH_RESERCH:
+ status_percent_heal(bl, sce->val4, 0);
+ break;
+ case SC_ENERGY_DRINK_RESERCH:
+ status_percent_heal(bl, 0, sce->val4);
+ break;
+ /**
+ * Ranger
+ **/
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->run(bl, sd, SC_WUGDASH);
+ }
+ break;
+ case SC_COMBOATTACK:
+ switch (sce->val1) {
+ case TK_STORMKICK:
+ clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ break;
+ case TK_DOWNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ break;
+ case TK_TURNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ break;
+ case TK_COUNTER:
+ clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ break;
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if (sd)
+ clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ break;
+ case TK_JUMPKICK:
+ if (sd)
+ clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ break;
+ case MO_TRIPLEATTACK:
+ if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
+ clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
+ break;
+ case SR_FALLENEMPIRE:
+ if (sd){
+ clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
+ clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
+ }
+ break;
+ }
+ break;
+ case SC_RAISINGDRAGON:
+ sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ break;
+ }
+
+ if( opt_flag&2 && sd && sd->touching_id )
+ npc->touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
+
+ return 1;
+}
+
+static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag)
+{
+ Assert_retr(false, type >= SC_NONE && type < SC_MAX);
+ if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->get_sc_icon(type) == SI_BLANK) {
+ //Status change with no calc, no icon, and no skill associated...?
+ ShowError("UnknownStatusChange [%d]\n", type);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Starts a status change in its full duration.
+ *
+ * @param src Status change source bl.
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ * @param rate Base success rate. 1 means 0.01%, 10000 means 100%.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ * @param tick Base duration (milliseconds).
+ * @param flag Special flags (@see enum scstart_flag).
+ *
+ * @retval 0 if no status change happened.
+ * @retval 1 if the status change was successfully applied.
+ */
+static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+{
+ return status->change_start_sub(src, bl, type, rate, val1, val2, val3, val4, 0, tick, flag);
+}
+
+static void status_change_start_display(struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4)
+{
+ Assert_retv(type >= SC_NONE && type < SC_MAX);
+
+ if (sd && status->dbs->DisplayType[type]) {
+ int dval1 = 0, dval2 = 0, dval3 = 0;
+ switch (type) {
+ case SC_ALL_RIDING:
+ dval1 = 1;
+ break;
+ case SC_CLAN_INFO:
+ dval1 = val1;
+ dval2 = val2;
+ dval3 = val3;
+ break;
+ default: /* all others: just copy val1 */
+ dval1 = val1;
+ break;
+ }
+ status->display_add(sd, type, dval1, dval2, dval3);
+ }
+}
+
+/**
+ * Return val_flag based on sc type.
+ *
+ * @param type Status change type.
+ *
+ * @retval val_flag.
+ */
+static int status_get_val_flag(enum sc_type type)
+{
+ int val_flag = 0;
+ switch (type) {
+ case SC_CLAN_INFO:
+ val_flag |= 1 | 2;
+ break;
case SC_FIGHTINGSPIRIT:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_VENOMIMPRESS:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_POISONINGWEAPON:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_WEAPONBLOCKING:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_ROLLINGCUTTER:
val_flag |= 1;
break;
case SC_CLOAKINGEXCEED:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_HALLUCINATIONWALK:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_SUMMON1:
case SC_SUMMON2:
@@ -9688,34 +9745,34 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val_flag |= 1;
break;
case SC__SHADOWFORM:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__INVISIBILITY:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC__ENERVATION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC__GROOMY:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__LAZINESS:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__UNLUCKY:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__WEAKNESS:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_PROPERTYWALK:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_FORCEOFVANGUARD:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_PRESTIGE:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_BANDING:
val_flag |= 1;
@@ -9723,56 +9780,56 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_SHIELDSPELL_DEF:
case SC_SHIELDSPELL_MDEF:
case SC_SHIELDSPELL_REF:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_SPELLFIST:
case SC_CURSEDCIRCLE_ATKER:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CRESCENTELBOW:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_LIGHTNINGWALK:
val_flag |= 1;
break;
case SC_PYROTECHNIC_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_HEATER_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_AQUAPLAY_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_COOLER_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CHILLY_AIR_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_GUST_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_BLAST_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_WILD_STORM_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_PETROLOGY_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CURSED_SOIL_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_UPHEAVAL_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_CIRCLE_OF_FIRE_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_WATER_BARRIER:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_KYOUGAKU:
val_flag |= 1;
@@ -9784,86 +9841,36 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_OVERLAPEXPUP:
val_flag |= 1;
break;
- }
-
- /* [Ind/Hercules] */
- if( sd && status->dbs->DisplayType[type] ) {
- int dval1 = 0, dval2 = 0, dval3 = 0;
- switch( type ) {
- case SC_ALL_RIDING:
- dval1 = 1;
- break;
- default: /* all others: just copy val1 */
- dval1 = val1;
- break;
- }
- status->display_add(sd,type,dval1,dval2,dval3);
- }
-
- //Those that make you stop attacking/walking....
- switch (type) {
- case SC_VACUUM_EXTREME:
- if(!map_flag_gvg(bl->m))
- unit->stop_walking(bl,1);
- break;
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_STONE:
- case SC_DEEP_SLEEP:
- if (sd && pc_issit(sd)) //Avoid sprite sync problems.
- pc->setstand(sd);
- case SC_TRICKDEAD:
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- // Cancel cast when get status [LuzZza]
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
- case SC_FALLENEMPIRE:
- case SC_WHITEIMPRISON:
- unit->stop_attack(bl);
- case SC_STOP:
- case SC_CONFUSION:
- case SC_RG_CCONFINE_M:
- case SC_RG_CCONFINE_S:
- case SC_SPIDERWEB:
- case SC_ELECTRICSHOCKER:
- case SC_WUGBITE:
- case SC_THORNS_TRAP:
- case SC__MANHOLE:
- case SC__CHAOS:
- case SC_COLD:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- case SC_FEAR:
- case SC_MEIKYOUSISUI:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEATHBOUND:
- case SC_NETHERWORLD:
- unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
- break;
- case SC_ANKLESNARE:
- if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
- unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
- break;
- case SC_HIDING:
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC_CHASEWALK:
- case SC_WEIGHTOVER90:
- case SC_CAMOUFLAGE:
- case SC_SIREN:
- case SC_ALL_RIDING:
- unit->stop_attack(bl);
+ case SC_DAILYSENDMAILCNT:
+ val_flag |= 1 | 2;
break;
- case SC_SILENCE:
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
+ case SC_MADOGEAR:
+ val_flag |= 1;
break;
}
+ return val_flag;
+}
- // Set option as needed.
- opt_flag = 1;
- switch(type) {
+/**
+ * Set new status values.
+ *
+ * @param bl Status change target bl.
+ * @param sc Current statuses.
+ * @param type Status change type.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ *
+ * @retval option flag.
+ */
+static int status_change_start_set_option(struct block_list *bl, struct status_change *sc, enum sc_type type, int val1, int val2, int val3, int val4)
+{
+ int opt_flag = 1;
+
+ nullpo_retr(true, bl);
+ nullpo_retr(true, sc);
+ switch (type) {
//OPT1
case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
@@ -9912,6 +9919,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
opt_flag = 0;
break;
}
+ FALLTHROUGH
case SC_EXPLOSIONSPIRITS:
sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
opt_flag = 0;
@@ -9940,7 +9948,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
#endif // 0
case SC_DANCING:
- if ((val1&0xFFFF) == CG_MOONLIT)
+ if ((val1 & 0xFFFF) == CG_MOONLIT)
sc->opt3 |= OPT3_MOONLIT;
opt_flag = 0;
break;
@@ -10026,6 +10034,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
sc->option |= OPTION_OKTOBERFEST;
opt_flag |= 0x4;
break;
+ case SC_DRESS_UP:
+ sc->option |= OPTION_SUMMER2;
+ opt_flag |= 0x4;
+ break;
case SC__FEINTBOMB_MASTER:
sc->option |= OPTION_INVISIBLE;
opt_flag |= 0x4;
@@ -10033,178 +10045,464 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
default:
opt_flag = 0;
}
+ return opt_flag;
+}
- //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
- if(opt_flag) {
- clif->changeoption(bl);
- if( sd && opt_flag&0x4 ) {
- if (vd)
- clif->changelook(bl,LOOK_BASE,vd->class_);
- clif->changelook(bl,LOOK_WEAPON,0);
- clif->changelook(bl,LOOK_SHIELD,0);
- if (vd)
- clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- }
- }
- if (calc_flag&SCB_DYE) {
- //Reset DYE color
- if (vd && vd->cloth_color) {
- val4 = vd->cloth_color;
- clif->changelook(bl,LOOK_CLOTHES_COLOR,0);
- }
- calc_flag&=~SCB_DYE;
- }
-
-#if 0 //Currently No SC's use this
- if (calc_flag&SCB_BODY) {
- //Reset Body Style
- if (vd && vd->body_style) {
- val4 = vd->body_style;
- clif->changelook(bl,LOOK_BODY2,0);
+/**
+ * Stop actions before start new sc.
+ *
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ */
+static void status_change_start_stop_action(struct block_list *bl, enum sc_type type)
+{
+ nullpo_retv(bl);
+ switch (type) {
+ case SC_VACUUM_EXTREME:
+ if (!map_flag_gvg(bl->m))
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
+ break;
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_STONE:
+ case SC_DEEP_SLEEP: {
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
+ if (sd && pc_issit(sd)) //Avoid sprite sync problems.
+ pc->setstand(sd);
+ FALLTHROUGH
}
- calc_flag&=~SCB_BODY;
- }
-#endif
-
- if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type]))
- clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
-
- /**
- * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
- **/
- if( tick_time )
- tick = tick_time;
-
- //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
- if((sce=sc->data[type])) {// reuse old sc
- if( sce->timer != INVALID_TIMER )
- timer->delete(sce->timer, status->change_timer);
- } else {// new sc
- ++(sc->count);
- sce = sc->data[type] = ers_alloc(status->data_ers, struct status_change_entry);
- }
-
- sce->val1 = val1;
- sce->val2 = val2;
- sce->val3 = val3;
- sce->val4 = val4;
-
- if (tick >= 0) {
- sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type);
- sce->infinite_duration = false;
- } else {
- sce->timer = INVALID_TIMER; //Infinite duration
- sce->infinite_duration = true;
- if( sd )
- chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
+ case SC_TRICKDEAD:
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ // Cancel cast when get status [LuzZza]
+ if (battle_config.sc_castcancel&bl->type)
+ unit->skillcastcancel(bl, 0);
+ FALLTHROUGH
+ case SC_FALLENEMPIRE:
+ case SC_WHITEIMPRISON:
+ unit->stop_attack(bl);
+ FALLTHROUGH
+ case SC_STOP:
+ case SC_CONFUSION:
+ case SC_RG_CCONFINE_M:
+ case SC_RG_CCONFINE_S:
+ case SC_SPIDERWEB:
+ case SC_ELECTRICSHOCKER:
+ case SC_WUGBITE:
+ case SC_THORNS_TRAP:
+ case SC__MANHOLE:
+ case SC__CHAOS:
+ case SC_COLD:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ case SC_FEAR:
+ case SC_MEIKYOUSISUI:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEATHBOUND:
+ case SC_NETHERWORLD:
+ case SC_SV_ROOTTWIST:
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
+ break;
+ case SC_ANKLESNARE:
+ if (battle_config.skill_trap_type || !map_flag_gvg(bl->m))
+ unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS);
+ break;
+ case SC_HIDING:
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC_CHASEWALK:
+ case SC_WEIGHTOVER90:
+ case SC_CAMOUFLAGE:
+ case SC_SIREN:
+ case SC_ALL_RIDING:
+ case SC_SUHIDE:
+ unit->stop_attack(bl);
+ break;
+ case SC_SILENCE:
+ if (battle_config.sc_castcancel & bl->type)
+ unit->skillcastcancel(bl, 0);
+ break;
}
+}
- if (calc_flag)
- status_calc_bl(bl,calc_flag);
-
- if(sd && sd->pd)
- pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing
+/**
+ * End sc before starting other sc.
+ *
+ * @param bl Status change target bl.
+ * @param st Status change data.
+ * @param sc Current statuses.
+ * @param type Status change type.
+ * @param undead_flag is bl undead.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ *
+ * @retval false if no status change happened, or the other sc can be started regardless.
+ * @retval true if the status change was successfully applied and the other sc shouldn't be started.
+ */
+static bool status_end_sc_before_start(struct block_list *bl, struct status_data *st, struct status_change *sc, enum sc_type type, int undead_flag, int val1, int val2, int val3, int val4)
+{
+ nullpo_retr(true, bl);
+ nullpo_retr(true, st);
+ nullpo_retr(true, sc);
switch (type) {
- case SC_BERSERK:
- if (!(sce->val2)) { //don't heal if already set
- status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status->set_sp(bl, 0, 0); //Damage all SP
+ case SC_BLESSING:
+ // TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
+ // but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
+ if ((undead_flag == 0 && st->race != RC_DEMON) || bl->type == BL_PC) {
+ bool prevent_start = false;
+ if (sc->data[SC_CURSE] != NULL) {
+ prevent_start = true;
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ }
+ if (sc->data[SC_STONE] != NULL && sc->opt1 == OPT1_STONE) {
+ prevent_start = true;
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ }
+ if (prevent_start)
+ return true;
}
- sce->val2 = 5 * st->max_hp / 100;
+ if (sc->data[SC_SOULLINK] != NULL && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_HLIF_CHANGE:
- status_percent_heal(bl, 100, 100);
+ case SC_INC_AGI:
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_RUN:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->run(bl, NULL, SC_RUN);
- }
+ case SC_QUAGMIRE:
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ FALLTHROUGH
+ //Also blocks the ones below...
+ case SC_DEC_AGI:
+ case SC_ADORAMUS:
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
+ //Also blocks the ones below...
+ FALLTHROUGH
+ case SC_DONTFORGETME:
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
break;
- case SC_CASH_BOSS_ALARM:
- if( sd )
- clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
+ case SC_ONEHANDQUICKEN:
+ //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
- case SC_MER_HP:
- status_percent_heal(bl, 100, 0); // Recover Full HP
+ case SC_OVERTHRUSTMAX:
+ //Cancels Normal Overthrust. [Skotlex]
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
break;
- case SC_MER_SP:
- status_percent_heal(bl, 0, 100); // Recover Full SP
+ case SC_KYRIE:
+ //Cancels Assumptio
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
- case SC_PROMOTE_HEALTH_RESERCH:
- status_percent_heal(bl, sce->val4, 0);
+ case SC_MAGNIFICAT:
+ //Cancels Offertorium
+ status_change_end(bl, SC_OFFERTORIUM, INVALID_TIMER);
break;
- case SC_ENERGY_DRINK_RESERCH:
- status_percent_heal(bl, 0, sce->val4);
+ case SC_OFFERTORIUM:
+ //Cancels Magnificat
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
break;
- /**
- * Ranger
- **/
- case SC_WUGDASH:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->run(bl, sd, SC_WUGDASH);
- }
+ case SC_DELUGE:
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
break;
- case SC_COMBOATTACK:
- switch (sce->val1) {
- case TK_STORMKICK:
- clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
- break;
- case TK_DOWNKICK:
- clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
- break;
- case TK_TURNKICK:
- clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
- break;
- case TK_COUNTER:
- clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
- break;
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if (sd)
- clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
- break;
- case TK_JUMPKICK:
- if (sd)
- clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
- break;
- case MO_TRIPLEATTACK:
- if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
- clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
- break;
- case SR_FALLENEMPIRE:
- if (sd){
- clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
- clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
- }
+ case SC_SILENCE:
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ break;
+ case SC_HIDING:
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
+ break;
+ case SC_BERSERK:
+ if (val3 == SC__BLOODYLUST)
break;
+ if (battle_config.berserk_cancels_buffs) {
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
}
+ #ifdef RENEWAL
+ else {
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ }
+ #endif
break;
- case SC_RAISINGDRAGON:
- sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ case SC_ASSUMPTIO:
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ break;
+ case SC_KAITE:
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_CARTBOOST:
+ if (sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS]) {
+ //Cancel Decrease Agi, but take no further effect [Skotlex]
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
+ return true;
+ }
+ break;
+ case SC_FUSION:
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
+ break;
+ case SC_GS_ADJUSTMENT:
+ status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
+ break;
+ case SC_GS_MADNESSCANCEL:
+ status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
+ break;
+ //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
+ case SC_PROPERTYUNDEAD:
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR_CASH:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI_CASH:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT_CASH:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT_CASH:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX_CASH:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK_CASH:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
+ break;
+ case SC_GM_BATTLE:
+ status_change_end(bl, SC_GM_BATTLE2, INVALID_TIMER);
+ break;
+ case SC_GM_BATTLE2:
+ status_change_end(bl, SC_GM_BATTLE, INVALID_TIMER);
+ break;
+ case SC_ENDURE:
+ if (val4 == 1)
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ break;
+ case SC_FIGHTINGSPIRIT:
+ case SC_OVERED_BOOST:
+ status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
+ break;
+ case SC_MARSHOFABYSS:
+ status_change_end(bl, SC_INCAGI, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
+ break;
+ //Group A Status (doesn't overlap)
+ case SC_SWING:
+ case SC_SYMPHONY_LOVE:
+ case SC_MOONLIT_SERENADE:
+ case SC_RUSH_WINDMILL:
+ case SC_ECHOSONG:
+ case SC_HARMONIZE:
+ case SC_FRIGG_SONG:
+ if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
+ if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
+ if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
+ if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
+ if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
+ break;
+ //Group B Status
+ case SC_SIREN:
+ case SC_DEEP_SLEEP:
+ case SC_SIRCLEOFNATURE:
+ case SC_LERADS_DEW:
+ case SC_MELODYOFSINK:
+ case SC_BEYOND_OF_WARCRY:
+ case SC_UNLIMITED_HUMMING_VOICE:
+ case SC_GLOOMYDAY:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
+ if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
+ if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
+ if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
+ if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
+ if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ break;
+ case SC_REFLECTSHIELD:
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
+ break;
+ case SC_LG_REFLECTDAMAGE:
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ break;
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ case SC_GENTLETOUCH_CHANGE:
+ case SC_GENTLETOUCH_REVITALIZE:
+ if (type != SC_GENTLETOUCH_REVITALIZE)
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ if (type != SC_GENTLETOUCH_ENERGYGAIN)
+ status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
+ if (type != SC_GENTLETOUCH_CHANGE)
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLE:
+ status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLEOFF:
+ status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
+ break;
+ case SC_MAGICPOWER:
+ status_change_end(bl, type, INVALID_TIMER);
break;
}
- if( opt_flag&2 && sd && sd->touching_id )
- npc->touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
+ return false;
+}
- return 1;
+/**
+ * Check is boss resist to given sc.
+ *
+ * @param type Status change type.
+ *
+ * @retval true if boss resist.
+ * @retval false if boss not resist.
+ */
+static bool status_is_boss_resist_sc(enum sc_type type)
+{
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ return true;
+
+ if (status->get_sc_type(type) & SC_NO_BOSS)
+ return true;
+
+ return false;
+}
+
+/**
+ * Initial check for current statuses immune to given sc.
+ *
+ * @param sc Current statuses.
+ * @param type Status change type.
+ *
+ * @retval true if immune resist.
+ * @retval false if not immune resist.
+ */
+static bool status_is_immune_to_status(struct status_change *sc, enum sc_type type)
+{
+ nullpo_retr(true, sc);
+ if (sc->data[SC_REFRESH]) {
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
+ return true; // Immune to status ailements
+ switch (type) {
+ case SC__CHAOS:
+ case SC_STONE:
+ case SC_FROSTMISTY:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_MARSHOFABYSS:
+ case SC_MANDRAGORA:
+ return true;
+ }
+ } else if (sc->data[SC_INSPIRATION]) {
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ return true; // Immune to status ailements
+ switch (type) {
+ case SC__CHAOS:
+ case SC_STONE:
+ case SC_FROSTMISTY:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC__BODYPAINT:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__IGNORANCE:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ return true;
+ }
+ }
+ return false;
}
+
/*==========================================
-* Ending all status except those listed.
-* @TODO maybe usefull for dispel instead reseting a liste there.
-* type:
-* 0 - PC killed -> Place here statuses that do not dispel on death.
-* 1 - If for some reason status_change_end decides to still keep the status when quitting.
-* 2 - Do clif
-* 3 - Do not remove some permanent/time-independent effects
-*------------------------------------------*/
-int status_change_clear(struct block_list* bl, int type) {
+ * Ending all status except those listed.
+ * @TODO maybe usefull for dispel instead reseting a liste there.
+ * type:
+ * 0 - PC killed -> Place here statuses that do not dispel on death.
+ * 1 - If for some reason status_change_end decides to still keep the status when quitting.
+ * 2 - Do clif
+ * 3 - Do not remove some permanent/time-independent effects
+ *------------------------------------------*/
+static int status_change_clear(struct block_list *bl, int type)
+{
struct status_change* sc;
int i;
@@ -10223,6 +10521,7 @@ int status_change_clear(struct block_list* bl, int type) {
case SC_ARMOR_PROPERTY://Only when its Holy or Dark that it doesn't dispell on death
if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
break;
+ FALLTHROUGH
default:
continue;
}
@@ -10259,18 +10558,17 @@ int status_change_clear(struct block_list* bl, int type) {
}
/*==========================================
-* Special condition we want to effectuate, check before ending a status.
-*------------------------------------------*/
-int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line) {
+ * Special condition we want to effectuate, check before ending a status.
+ *------------------------------------------*/
+static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, const char *file, int line)
+{
struct map_session_data *sd;
struct status_change *sc;
struct status_change_entry *sce;
struct status_data *st;
struct view_data *vd;
int opt_flag=0, calc_flag;
-#ifdef ANTI_MAYAP_CHEAT
bool invisible = false;
-#endif
nullpo_ret(bl);
@@ -10302,6 +10600,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
//trigger when it also removed one
case SC_STONE:
sce->val3 = 0; //Petrify time counter.
+ FALLTHROUGH
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
@@ -10324,10 +10623,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status->display_remove(sd,type);
}
-#ifdef ANTI_MAYAP_CHEAT
- if (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE))
+ if ((sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) != 0)
invisible = true;
-#endif
vd = status->get_viewdata(bl);
calc_flag = status->dbs->ChangeFlagTable[type];
@@ -10361,7 +10658,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
if (begin_spurt && sce->val1 >= 7
&& DIFF_TICK(timer->gettick(), starttick) <= 1000
- && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
+ && (!sd || (sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST))
)
sc_start(bl, bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1));
}
@@ -10379,10 +10676,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
struct map_session_data *tsd;
if( bl->type == BL_PC ) {
// Clear Status from others
- int i;
- for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
- if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL && tsd->sc.data[type])
- status_change_end(&tsd->bl, type, INVALID_TIMER);
+ if (sd != NULL ) {
+ int i;
+ for( i = 0; i < MAX_PC_DEVOTION; i++ ) {
+ if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL && tsd->sc.data[type])
+ status_change_end(&tsd->bl, type, INVALID_TIMER);
+ }
}
} else if (bl->type == BL_MER) {
struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
@@ -10476,7 +10775,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
if ((sce->val1&0xFFFF) == CG_MOONLIT)
- clif->sc_end(bl,bl->id,AREA,SI_MOON);
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_MOON));
status_change_end(bl, SC_LONGING, INVALID_TIMER);
}
@@ -10562,7 +10861,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_percent_heal(bl, 100, 0);
status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
} else if(st->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- status->set_hp(bl, 100, 0);
+ status->set_hp(bl, 100, STATUS_HEAL_DEFAULT);
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
sc->data[SC_ENDURE]->val4 = 0;
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
@@ -10614,8 +10913,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (tid == INVALID_TIMER)
break;
// "lose almost all their HP and SP" on natural expiration.
- status->set_hp(bl, 10, 0);
- status->set_sp(bl, 10, 0);
+ status->set_hp(bl, 10, STATUS_HEAL_DEFAULT);
+ status->set_sp(bl, 10, STATUS_HEAL_DEFAULT);
break;
case SC_AUTOTRADE:
if (tid == INVALID_TIMER)
@@ -10688,10 +10987,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_NEUTRALBARRIER_MASTER:
case SC_STEALTHFIELD_MASTER:
- if( sce->val2 ) {
+ case SC_SV_ROOTTWIST:
+ if (sce->val2) {
struct skill_unit_group* group = skill->id2group(sce->val2);
sce->val2 = 0;
- if( group ) /* might have been cleared before status ended, e.g. land protector */
+ if (group) /* might have been cleared before status ended, e.g. land protector */
skill->del_unitgroup(group,ALC_MARK);
}
break;
@@ -10826,6 +11126,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->option &= ~OPTION_OKTOBERFEST;
opt_flag |= 0x4;
break;
+ case SC_DRESS_UP:
+ sc->option &= ~OPTION_SUMMER2;
+ opt_flag |= 0x4;
+ break;
case SC__FEINTBOMB_MASTER:
sc->option &= ~OPTION_INVISIBLE;
opt_flag |= 0x4;
@@ -10868,6 +11172,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
opt_flag = 0;
break;
}
+ FALLTHROUGH
case SC_EXPLOSIONSPIRITS:
sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
opt_flag = 0;
@@ -10946,6 +11251,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
#endif
+ // update HP bar when becoming visible again
+ if (invisible && (sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) == 0) {
+ if (sd != NULL && battle_config.party_hp_mode == 0 && sd->status.party_id != 0)
+ clif->party_hp(sd);
+ }
+
if (calc_flag&SCB_DYE) { //Restore DYE color
if (vd && !vd->cloth_color && sce->val4)
clif->changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
@@ -10961,14 +11272,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
#endif
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
- clif->sc_end(bl,bl->id,AREA,status->dbs->IconChangeTable[type]);
+ clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(type));
if( opt_flag&8 ) //bugreport:681
clif->changeoption2(bl);
else if(opt_flag) {
clif->changeoption(bl);
if( sd && opt_flag&0x4 ) {
- clif->changelook(bl,LOOK_BASE,sd->vd.class_);
+ clif->changelook(bl, LOOK_BASE, sd->vd.class);
clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
clif->changelook(bl,LOOK_WEAPON,sd->vd.weapon);
clif->changelook(bl,LOOK_SHIELD,sd->vd.shield);
@@ -10994,7 +11305,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
return 1;
}
-int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) {
+static int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct block_list *bl;
struct status_change *sc;
struct status_change_entry *sce;
@@ -11019,17 +11331,18 @@ int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) {
hp = st->max_hp - st->hp;
if (hp > sce->val2)
hp = sce->val2;
- if (hp)
- status->heal(bl, hp, 0, 2);
+ if (hp != 0)
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sce->val4 = INVALID_TIMER;
return 1;
}
/*==========================================
-* For recusive status, like for each 5s we drop sp etc.
-* Reseting the end timer.
-*------------------------------------------*/
-int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
+ * For recusive status, like for each 5s we drop sp etc.
+ * Reseting the end timer.
+ *------------------------------------------*/
+static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
+{
enum sc_type type = (sc_type)data;
struct block_list *bl;
struct map_session_data *sd;
@@ -11150,23 +11463,26 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_POISON:
- if(st->hp <= max(st->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left.
+ if (st->hp <= max(st->max_hp / 4, sce->val4)) //Stop damaging after 25% HP left.
break;
+ FALLTHROUGH
case SC_DPOISON:
if (--(sce->val3) > 0) {
- if (!sc->data[SC_SLOWPOISON]) {
- if( sce->val2 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(sce->val2);
- if (src != NULL)
- mob->log_damage(BL_UCAST(BL_MOB, bl), src, sce->val4);
- }
- map->freeblock_lock();
- status_zap(bl, sce->val4, 0);
- if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
- sc_timer_next(1000 + tick, status->change_timer, bl->id, data );
- }
- map->freeblock_unlock();
+ if (sc->data[SC_SLOWPOISON] != NULL) {
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
+ return 0;
+ }
+ if (sce->val2 != 0 && bl->type == BL_MOB) {
+ struct block_list* src = map->id2bl(sce->val2);
+ if (src != NULL)
+ mob->log_damage(BL_UCAST(BL_MOB, bl), src, sce->val4);
+ }
+ map->freeblock_lock();
+ status_zap(bl, sce->val4, 0);
+ if (sc->data[type] != NULL) { // Check if the status still last (can be dead since then).
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
+ map->freeblock_unlock();
return 0;
}
break;
@@ -11222,7 +11538,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
int hp = 0;
if (st->hp < st->max_hp)
hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
- status->heal(bl, hp, 0, 2);
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11282,6 +11598,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
//Moonlit's cost is 4sp*skill_lv [Skotlex]
sp= 4*(sce->val1>>16);
//Upkeep is also every 10 secs.
+ FALLTHROUGH
case DC_DONTFORGETME:
s=10;
break;
@@ -11319,10 +11636,10 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_SPLASHER:
#if 0 // custom Venom Splasher countdown timer
- if (sce->val4 % 1000 == 0) {
+ if (sce->val4 % 1000 == 0 && bl && bl->type == BL_PC) {
char counter[10];
snprintf (counter, 10, "%d", sce->val4/1000);
- clif->message(bl, counter);
+ clif->message(BL_UCCAST(BL_PC, bl)->fd, counter);
}
#endif // 0
if((sce->val4 -= 500) > 0) {
@@ -11370,7 +11687,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_ABUNDANCE:
if(--(sce->val4) > 0) {
- status->heal(bl,0,60,0);
+ status->heal(bl, 0, 60, STATUS_HEAL_DEFAULT);
sc_timer_next(10000+tick, status->change_timer, bl->id, data);
}
break;
@@ -11429,17 +11746,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
mushroom_skill_id = skill->dbs->magicmushroom_db[i].skill_id;
} while (mushroom_skill_id == 0);
- switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
- case CAST_GROUND:
- skill->castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0);
- break;
- case CAST_NODAMAGE:
- skill->castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0);
- break;
- case CAST_DAMAGE:
- skill->castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0);
- break;
- }
+ skill->castend_type(skill->get_casttype(mushroom_skill_id), bl, bl, mushroom_skill_id, 1, tick, 0);
}
clif->emotion(bl,E_HEH);
@@ -11496,7 +11803,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
heal = ~heal + 1;
map->freeblock_lock();
- status->heal(bl, heal, 0, 2);
+ status->heal(bl, heal, 0, STATUS_HEAL_SHOWEFFECT);
if( sc->data[type] ) {
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
}
@@ -11610,7 +11917,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if( --(sce->val4) > 0 ) {
struct block_list *src = map->id2bl(sce->val2);
int damage;
- if( !src || (src && (status->isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
+ if (src == NULL || (status->isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12))
break;
map->freeblock_lock();
damage = sce->val3;
@@ -11619,7 +11926,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if ( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
- status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
+ status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, STATUS_HEAL_DEFAULT); // 5 + 5% per level
map->freeblock_unlock();
return 0;
}
@@ -11636,7 +11943,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_DEEP_SLEEP:
if( --(sce->val4) >= 0 )
{// Recovers 3% of the player's MaxHP/MaxSP every 2 seconds.
- status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, 2);
+ status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, STATUS_HEAL_SHOWEFFECT);
sc_timer_next(2000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11646,7 +11953,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if( --(sce->val4) >= 0 ) {
if( !status->charge(bl,0,sce->val3) )
break;
- status->heal(bl, sce->val2, 0, 1);
+ status->heal(bl, sce->val2, 0, STATUS_HEAL_FORCED);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11654,7 +11961,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_SONG_OF_MANA:
if( --(sce->val4) >= 0 ) {
- status->heal(bl,0,sce->val3,3);
+ status->heal(bl, 0, sce->val3, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11848,7 +12155,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
case SC_MEIKYOUSISUI:
if( --(sce->val4) > 0 ) {
- status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, 0);
+ status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, STATUS_HEAL_DEFAULT);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11884,7 +12191,20 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_FRIGG_SONG:
if( --(sce->val4) > 0 ) {
- status->heal(bl, sce->val3, 0, 0);
+ status->heal(bl, sce->val3, 0, STATUS_HEAL_DEFAULT);
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_FRESHSHRIMP:
+ if (--(sce->val4) >= 0) {
+ status_heal(bl, st->max_hp / 100, 0, 2);
+ sc_timer_next((10000 - ((sce->val1 - 1) * 1000)) + tick, status->change_timer, bl->id, data);
+ }
+ break;
+ case SC_BITESCAR:
+ if (--(sce->val4) >= 0) {
+ status_percent_damage(bl, bl, -(sce->val2), 0, 0);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11897,9 +12217,10 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
}
/*==========================================
-* Foreach iteration of repetitive status
-*------------------------------------------*/
-int status_change_timer_sub(struct block_list* bl, va_list ap) {
+ * Foreach iteration of repetitive status
+ *------------------------------------------*/
+static int status_change_timer_sub(struct block_list *bl, va_list ap)
+{
struct status_change* tsc;
struct block_list* src = va_arg(ap,struct block_list*);
@@ -11907,6 +12228,8 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) {
enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int
int64 tick = va_arg(ap, int64);
+ nullpo_ret(bl);
+
if (status->isdead(bl))
return 0;
@@ -11957,13 +12280,13 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) {
break;
case SC_RG_CCONFINE_M:
//Lock char has released the hold on everyone...
- if (tsc && tsc->data[SC_RG_CCONFINE_S] && tsc->data[SC_RG_CCONFINE_S]->val2 == src->id) {
+ if (tsc != NULL && src != NULL && tsc->data[SC_RG_CCONFINE_S] && tsc->data[SC_RG_CCONFINE_S]->val2 == src->id) {
tsc->data[SC_RG_CCONFINE_S]->val2 = 0;
status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
}
break;
case SC_CURSEDCIRCLE_TARGET:
- if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
+ if (tsc != NULL && src != NULL && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id) {
clif->bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
status_change_end(bl, type, INVALID_TIMER);
}
@@ -11972,14 +12295,24 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) {
return 0;
}
-int status_get_total_def(struct block_list *src) { return status->get_status_data(src)->def2 + (short)status->get_def(src); }
-int status_get_total_mdef(struct block_list *src) { return status->get_status_data(src)->mdef2 + (short)status_get_mdef(src); }
-int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag)
+static int status_get_total_def(struct block_list *src)
+{
+ return status->get_status_data(src)->def2 + (short)status->get_def(src);
+}
+
+static int status_get_total_mdef(struct block_list *src)
+{
+ return status->get_status_data(src)->mdef2 + (short)status_get_mdef(src);
+}
+
+static int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag)
{
#ifdef RENEWAL
int min = 0, max = 0;
struct status_change *sc = status->get_sc(bl);
+ nullpo_ret(bl);
+ nullpo_ret(watk);
if (bl->type == BL_PC && watk->atk) {
float strdex_bonus, variance;
int dstr;
@@ -12014,10 +12347,10 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
if ( bl->type == BL_PC && !(flag & 2) ) {
const struct map_session_data *sd = BL_UCCAST(BL_PC, bl);
- short index = sd->equip_index[EQI_HAND_R], refine;
+ short index = sd->equip_index[EQI_HAND_R], refine_level;
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON
- && (refine = sd->status.inventory[index].refine) < 16 && refine ) {
- int r = status->dbs->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100;
+ && (refine_level = sd->status.inventory[index].refine) < 16 && refine_level) {
+ int r = refine->get_randombonus_max(watk->wlv, refine_level + (4 - watk->wlv) + 1) / 100;
if ( r )
max += (rnd() % 100) % r + 1;
}
@@ -12035,13 +12368,14 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
}
/**
-* Get bl's matk_max and matk_min values depending on flag
-* @param flag
-* 0 - Get MATK
-* 1 - Get MATK w/o SC bonuses
-* 3 - Get MATK w/o EATK & SC bonuses
-**/
-void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min) {
+ * Get bl's matk_max and matk_min values depending on flag
+ * @param flag
+ * 0 - Get MATK
+ * 1 - Get MATK w/o SC bonuses
+ * 3 - Get MATK w/o EATK & SC bonuses
+ */
+static void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min)
+{
struct status_data *st;
struct status_change *sc;
struct map_session_data *sd;
@@ -12068,6 +12402,10 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
// Any +MATK you get from skills and cards, including cards in weapon, is added here.
if ( sd && sd->bonus.ematk > 0 && flag != 3 )
*matk_min += sd->bonus.ematk;
+ if (sd && pc->checkskill(sd, SU_POWEROFLAND) > 0) {
+ if (pc->checkskill(sd, SU_SV_STEMSPEAR) == 5 && pc->checkskill(sd, SU_CN_POWDERING) == 5 && pc->checkskill(sd, SU_CN_METEOR) == 5 && pc->checkskill(sd, SU_SV_ROOTTWIST) == 5)
+ *matk_min += *matk_min * 20 / 100;
+ }
if ( flag != 3 )
*matk_min = status->calc_ematk(bl, sc, *matk_min);
@@ -12079,6 +12417,8 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
if ( (st->rhw.matk + st->lhw.matk) > 0 ) {
int wMatk = st->rhw.matk + st->lhw.matk; // Left and right matk stacks
int variance = wMatk * st->rhw.wlv / 10; // Only use right hand weapon level
+ if (sc != NULL && sc->data[SC_CATNIPPOWDER])
+ wMatk -= wMatk * sc->data[SC_CATNIPPOWDER]->val2 / 100;
*matk_min += wMatk - variance;
*matk_max += wMatk + variance;
}
@@ -12107,8 +12447,8 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
}
#else // not RENEWAL
- *matk_min = status_base_matk_min(st) + (sd ? sd->bonus.ematk : 0);
- *matk_max = status_base_matk_max(st) + (sd ? sd->bonus.ematk : 0);
+ *matk_min = status->base_matk_min(st) + (sd ? sd->bonus.ematk : 0);
+ *matk_max = status->base_matk_max(st) + (sd ? sd->bonus.ematk : 0);
#endif
if ( sd && sd->matk_rate != 100 ) {
@@ -12122,10 +12462,10 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
#ifdef RENEWAL
if ( sd && !(flag & 2) ) {
- short index = sd->equip_index[EQI_HAND_R], refine;
+ short index = sd->equip_index[EQI_HAND_R], refine_level;
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON
- && (refine = sd->status.inventory[index].refine) < 16 && refine ) {
- int r = status->dbs->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100;
+ && (refine_level = sd->status.inventory[index].refine) < 16 && refine_level) {
+ int r = refine->get_randombonus_max(sd->inventory_data[index]->wlv, refine_level + (4 - sd->inventory_data[index]->wlv) + 1) / 100;
if ( r )
*matk_max += (rnd() % 100) % r + 1;
}
@@ -12146,9 +12486,10 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
#undef status_get_homluk
/**
-* Gets a random matk value depending on min matk and max matk
-**/
-unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk_min) {
+ * Gets a random matk value depending on min matk and max matk
+ */
+static unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk_min)
+{
if ( matk_max > matk_min )
return matk_min + rnd() % (matk_max - matk_min);
else
@@ -12156,17 +12497,18 @@ unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk
}
/**
-* Get bl's matk value depending on flag
-* @param flag [malufett]
-* 1 - Get MATK w/o SC bonuses
-* 2 - Get modified MATK
-* 3 - Get MATK w/o eATK & SC bonuses
-* @retval 1 failure
-* @retval MATK success
-*
-* Shouldn't change _any_ value! [Panikon]
-**/
-int status_get_matk(struct block_list *bl, int flag) {
+ * Get bl's matk value depending on flag
+ * @param flag [malufett]
+ * 1 - Get MATK w/o SC bonuses
+ * 2 - Get modified MATK
+ * 3 - Get MATK w/o eATK & SC bonuses
+ * @retval 1 failure
+ * @retval MATK success
+ *
+ * Shouldn't change _any_ value! [Panikon]
+ */
+static int status_get_matk(struct block_list *bl, int flag)
+{
struct status_data *st;
unsigned short matk_max, matk_min;
@@ -12192,9 +12534,10 @@ int status_get_matk(struct block_list *bl, int flag) {
}
/**
-* Updates bl's MATK values
-**/
-void status_update_matk(struct block_list *bl) {
+ * Updates bl's MATK values
+ */
+static void status_update_matk(struct block_list *bl)
+{
struct status_data *st;
struct status_change *sc;
unsigned short matk_max, matk_min;
@@ -12218,11 +12561,12 @@ void status_update_matk(struct block_list *bl) {
}
/*==========================================
-* Clears buffs/debuffs of a character.
-* type&1 -> buffs, type&2 -> debuffs
-* type&4 -> especific debuffs(implemented with refresh)
-*------------------------------------------*/
-int status_change_clear_buffs (struct block_list* bl, int type) {
+ * Clears buffs/debuffs of a character.
+ * type&1 -> buffs, type&2 -> debuffs
+ * type&4 -> especific debuffs(implemented with refresh)
+ *------------------------------------------*/
+static int status_change_clear_buffs(struct block_list *bl, int type)
+{
int i;
struct status_change *sc= status->get_sc(bl);
@@ -12283,7 +12627,8 @@ int status_change_clear_buffs (struct block_list* bl, int type) {
return 0;
}
-int status_change_spread( struct block_list *src, struct block_list *bl ) {
+static int status_change_spread(struct block_list *src, struct block_list *bl)
+{
int i, flag = 0;
struct status_change *sc = status->get_sc(src);
int64 tick;
@@ -12373,7 +12718,8 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
}
//Natural regen related stuff.
-int status_natural_heal(struct block_list* bl, va_list args) {
+static int status_natural_heal(struct block_list *bl, va_list args)
+{
struct regen_data *regen;
struct status_data *st;
struct status_change *sc;
@@ -12383,6 +12729,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
struct map_session_data *sd;
int val,rate,bonus = 0,flag;
+ nullpo_ret(bl);
regen = status->get_regen_data(bl);
if (!regen) return 0;
st = status->get_status_data(bl);
@@ -12426,7 +12773,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
sregen->tick.hp += val;
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp) {
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp) {
//Full
flag&=~(RGN_HP|RGN_SHP);
break;
@@ -12441,7 +12788,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
sregen->tick.sp += val;
while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, sregen->sp, 3) < sregen->sp) {
+ if (status->heal(bl, 0, sregen->sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->sp) {
//Full
flag&=~(RGN_SP|RGN_SSP);
break;
@@ -12490,7 +12837,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
val += regen->hp;
regen->tick.hp -= battle_config.natural_healhp_interval;
} while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
- if (status->heal(bl, val, 0, 1) < val)
+ if (status->heal(bl, val, 0, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SHP; //full.
}
}
@@ -12509,7 +12856,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
val += regen->sp;
regen->tick.sp -= battle_config.natural_healsp_interval;
} while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
- if (status->heal(bl, 0, val, 1) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SSP; //full.
}
}
@@ -12526,7 +12873,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp)
break; //Full
}
}
@@ -12541,7 +12888,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
if ((rate = pc->checkskill(sd,TK_SPTIME)))
sc_start(bl,bl,status->skill2sc(TK_SPTIME),
100,rate,skill->get_time(TK_SPTIME, rate));
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
&&rnd()%10000 < battle_config.sg_angel_skill_ratio
) {
//Angel of the Sun/Moon/Star
@@ -12551,7 +12898,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
}
}
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, val, 3) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < val)
break; //Full
}
}
@@ -12559,7 +12906,8 @@ int status_natural_heal(struct block_list* bl, va_list args) {
}
//Natural heal main timer.
-int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data) {
+static int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data)
+{
// This difference is always positive and lower than UINT_MAX (~24 days)
status->natural_heal_diff_tick = (unsigned int)cap_value(DIFF_TICK(tick,status->natural_heal_prev_tick), 0, UINT_MAX);
map->foreachregen(status->natural_heal);
@@ -12567,21 +12915,8 @@ int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-/**
-* Get the chance to upgrade a piece of equipment.
-* @param wlv The weapon type of the item to refine (see see enum refine_type)
-* @param refine The target refine level
-* @return The chance to refine the item, in percent (0~100)
-**/
-int status_get_refine_chance(enum refine_type wlv, int refine) {
-
- if ( refine < 0 || refine >= MAX_REFINE)
- return 0;
-
- return status->dbs->refine_info[wlv].chance[refine];
-}
-
-int status_get_sc_type(sc_type type) {
+static int status_get_sc_type(sc_type type)
+{
if( type <= SC_NONE || type >= SC_MAX )
return 0;
@@ -12589,10 +12924,11 @@ int status_get_sc_type(sc_type type) {
return status->dbs->sc_conf[type];
}
-void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *jdb)
+static void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *jdb)
{
struct config_setting_t *temp = NULL;
int i32 = 0;
+ const char *str = NULL;
struct {
const char *name;
@@ -12627,6 +12963,38 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
#endif
};
+ /**
+ * @field BaseExpGroup must be read before any other that deal with exp tables.
+ */
+ if (libconfig->setting_lookup_string(jdb, "BaseExpGroup", &str) != 0) {
+ int i = 0;
+ ARR_FIND(0, VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_BASE]), i, strcmp(str, VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_BASE], i).name) == 0);
+ if (i == VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_BASE])) {
+ ShowError("status_read_job_db: Unknown Base Exp Group '%s' provided for entry '%s'\n", str, name);
+ } else {
+ pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE] = &VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_BASE], i);
+ }
+ } else {
+ ShowError("status_read_job_db: BaseExpGroup setting not found for entry '%s', skipping..\n", name);
+ return;
+ }
+
+ /**
+ * @field JobExpGroup must be read before any other that deal with exp tables.
+ */
+ if (libconfig->setting_lookup_string(jdb, "JobExpGroup", &str) != 0) {
+ int i = 0;
+ ARR_FIND(0, VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_JOB]), i, strcmp(str, VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_JOB], i).name) == 0);
+ if (i == VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_JOB])) {
+ ShowError("status_read_job_db: Unknown Job Exp Group '%s' provided for entry '%s'\n", str, name);
+ } else {
+ pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_JOB] = &VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_JOB], i);
+ }
+ } else {
+ ShowError("status_read_job_db: JobExpGroup setting not found for entry '%s', skipping..\n", name);
+ return;
+ }
+
if ((temp = libconfig->setting_get_member(jdb, "Inherit"))) {
int nidx = 0;
const char *iname;
@@ -12651,7 +13019,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
}
@@ -12666,7 +13034,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp);
}
}
@@ -12692,7 +13060,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
}
}
@@ -12718,7 +13086,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp);
}
}
@@ -12760,7 +13128,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for (++level; level <= pc->max_level[idx][0]; ++level) { /* limit only to possible maximum level of the given class */
+ for (++level; level <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; ++level) { /* limit only to possible maximum level of the given class */
status->dbs->HP_table[idx][level] = min(base + avg_increment * level, battle_config.max_hp); /* some are still empty? then let's use the average increase */
}
}
@@ -12780,60 +13148,65 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for (++level; level <= pc->max_level[idx][0]; level++ ) {
+ for (++level; level <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; level++) {
status->dbs->SP_table[idx][level] = min(base + avg_increment * level, battle_config.max_sp);
}
}
}
+/* [malufett/Hercules] */
/*------------------------------------------
-* DB reading.
-* job_db.conf - weight, hp, sp, aspd
-* job_db2.txt - job level stat bonuses
-* size_fix.txt - size adjustment table for weapons
-* refine_db.txt - refining data table
-*------------------------------------------*/
-void status_read_job_db(void) { /* [malufett/Hercules] */
+ * DB reading.
+ * job_db.conf - weight, hp, sp, aspd
+ * job_db2.txt - job level stat bonuses
+ * size_fix.txt - size adjustment table for weapons
+ * refine_db.txt - refining data table
+ *------------------------------------------*/
+static void status_read_job_db(void)
+{
int i = 0;
struct config_t job_db_conf;
struct config_setting_t *jdb = NULL;
+ char config_filename[256];
+
#ifdef RENEWAL_ASPD
- const char *config_filename = "db/re/job_db.conf";
+ libconfig->format_db_path(DBPATH_RE"job_db.conf", config_filename, sizeof(config_filename));
#else
- const char *config_filename = "db/pre-re/job_db.conf";
+ libconfig->format_db_path(DBPATH_PRE"job_db.conf", config_filename, sizeof(config_filename));
#endif
if (!libconfig->load_file(&job_db_conf, config_filename))
return;
- while ( (jdb = libconfig->setting_get_elem(job_db_conf.root, i++)) ) {
- int class_, idx;
+ while ((jdb = libconfig->setting_get_elem(job_db_conf.root, i++))) {
+ int class, idx;
const char *name = config_setting_name(jdb);
- if ( (class_ = pc->check_job_name(name)) == -1 ) {
+ if ((class = pc->check_job_name(name)) == -1) {
ShowWarning("pc_read_job_db: '%s' unknown job name!\n", name);
continue;
}
- idx = pc->class2idx(class_);
+ idx = pc->class2idx(class);
status->read_job_db_sub(idx, name, jdb);
}
+
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename);
libconfig->destroy(&job_db_conf);
}
-bool status_readdb_job2(char* fields[], int columns, int current)
+static bool status_readdb_job2(char *fields[], int columns, int current)
{
- int idx, class_, i;
+ int idx, class, i;
- class_ = atoi(fields[0]);
+ nullpo_retr(false, fields);
+ class = atoi(fields[0]);
- if(!pc->db_checkid(class_))
- {
- ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class_);
+ if (!pc->db_checkid(class)) {
+ ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class);
return false;
}
- idx = pc->class2idx(class_);
+ idx = pc->class2idx(class);
for(i = 1; i < columns; i++)
{
@@ -12842,10 +13215,11 @@ bool status_readdb_job2(char* fields[], int columns, int current)
return true;
}
-bool status_readdb_sizefix(char* fields[], int columns, int current)
+static bool status_readdb_sizefix(char *fields[], int columns, int current)
{
unsigned int i;
+ nullpo_retr(false, fields);
for(i = 0; i < MAX_SINGLE_WEAPON_TYPE; i++)
{
status->dbs->atkmods[current][i] = atoi(fields[i]);
@@ -12853,150 +13227,114 @@ bool status_readdb_sizefix(char* fields[], int columns, int current)
return true;
}
-/**
- * Processes a refine_db.conf entry.
- *
- * @param r Libconfig setting entry. It is expected to be valid and it
- * won't be freed (it is care of the caller to do so if
- * necessary)
- * @param n Ordinal number of the entry, to be displayed in case of
- * validation errors.
- * @param source Source of the entry (file name), to be displayed in case of
- * validation errors.
- * @return # of the validated entry, or 0 in case of failure.
- */
-int status_readdb_refine_libconfig_sub(struct config_setting_t *r, const char *name, const char *source)
-{
- struct config_setting_t *rate = NULL;
- int type = REFINE_TYPE_ARMOR, bonus_per_level = 0, rnd_bonus_v = 0, rnd_bonus_lv = 0;
- char lv[4];
- nullpo_ret(r);
- nullpo_ret(name);
- nullpo_ret(source);
-
- if (strncmp(name, "Armors", 6) == 0) {
- type = REFINE_TYPE_ARMOR;
- } else if (strncmp(name, "WeaponLevel", 11) != 0 || !strspn(&name[strlen(name)-1], "0123456789") || (type = atoi(strncpy(lv, name+11, 2))) == REFINE_TYPE_ARMOR) {
- ShowError("status_readdb_refine_libconfig_sub: Invalid key name for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
- if (type < REFINE_TYPE_ARMOR || type >= REFINE_TYPE_MAX) {
- ShowError("status_readdb_refine_libconfig_sub: Out of range level for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
- if (!libconfig->setting_lookup_int(r, "StatsPerLevel", &bonus_per_level)) {
- ShowWarning("status_readdb_refine_libconfig_sub: Missing StatsPerLevel for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
- if (!libconfig->setting_lookup_int(r, "RandomBonusStartLevel", &rnd_bonus_lv)) {
- ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusStartLevel for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
- if (!libconfig->setting_lookup_int(r, "RandomBonusValue", &rnd_bonus_v)) {
- ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusValue for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
-
- if ((rate=libconfig->setting_get_member(r, "Rates")) != NULL && config_setting_is_group(rate)) {
- struct config_setting_t *t = NULL;
- bool duplicate[MAX_REFINE];
- int bonus[MAX_REFINE], rnd_bonus[MAX_REFINE], chance[MAX_REFINE];
- int i;
- memset(&duplicate, 0, sizeof(duplicate));
- memset(&bonus, 0, sizeof(bonus));
- memset(&rnd_bonus, 0, sizeof(rnd_bonus));
-
- for (i = 0; i < MAX_REFINE; i++) {
- chance[i] = 100;
- }
- i = 0;
- while ((t = libconfig->setting_get_elem(rate,i++)) != NULL && config_setting_is_group(t)) {
- int level = 0, i32;
- char *rlvl = config_setting_name(t);
- memset(&lv, 0, sizeof(lv));
- if (!strspn(&rlvl[strlen(rlvl)-1], "0123456789") || (level = atoi(strncpy(lv, rlvl+2, 3))) <= 0) {
- ShowError("status_readdb_refine_libconfig_sub: Invalid refine level format '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source);
- continue;
- }
- if (level <= 0 || level > MAX_REFINE) {
- ShowError("status_readdb_refine_libconfig_sub: Out of range refine level '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source);
- continue;
- }
- level--;
- if (duplicate[level]) {
- ShowWarning("status_readdb_refine_libconfig_sub: duplicate rate '%s' for entry %s in \"%s\", overwriting previous entry...\n", rlvl, name, source);
- } else {
- duplicate[level] = true;
- }
- if (libconfig->setting_lookup_int(t, "Chance", &i32))
- chance[level] = i32;
- else
- chance[level] = 100;
- if (libconfig->setting_lookup_int(t, "Bonus", &i32))
- bonus[level] += i32;
- if (level >= rnd_bonus_lv - 1)
- rnd_bonus[level] = rnd_bonus_v * (level - rnd_bonus_lv + 2);
- }
- for (i = 0; i < MAX_REFINE; i++) {
- status->dbs->refine_info[type].chance[i] = chance[i];
- status->dbs->refine_info[type].randombonus_max[i] = rnd_bonus[i];
- bonus[i] += bonus_per_level + (i > 0 ? bonus[i-1] : 0);
- status->dbs->refine_info[type].bonus[i] = bonus[i];
- }
- } else {
- ShowWarning("status_readdb_refine_libconfig_sub: Missing refine rates for entry '%s' in \"%s\", skipping.\n", name, source);
- return 0;
- }
- return type+1;
-}
-
-/**
- * Reads from a libconfig-formatted refine_db.conf file.
- *
- * @param *filename File name, relative to the database path.
- * @return The number of found entries.
- */
-int status_readdb_refine_libconfig(const char *filename) {
- bool duplicate[REFINE_TYPE_MAX];
- struct config_t refine_db_conf;
- struct config_setting_t *r;
+static bool status_read_scdb_libconfig(void)
+{
+ struct config_t status_conf;
char filepath[256];
- int i = 0, count = 0,type = 0;
+ safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, "sc_config.conf");
- sprintf(filepath, "%s/%s", map->db_path, filename);
- if (!libconfig->load_file(&refine_db_conf, filepath))
- return 0;
+ if (libconfig->load_file(&status_conf, filepath) == CONFIG_FALSE) {
+ ShowError("status_read_scdb_libconfig: can't read %s\n", filepath);
+ return false;
+ }
- memset(&duplicate,0,sizeof(duplicate));
+ int i = 0;
+ int count = 0;
+ struct config_setting_t *it = NULL;
- while((r = libconfig->setting_get_elem(refine_db_conf.root,i++))) {
- char *name = config_setting_name(r);
- if((type=status->readdb_refine_libconfig_sub(r, name, filename))) {
- if( duplicate[type-1] ) {
- ShowWarning("status_readdb_refine_libconfig: duplicate entry for %s in \"%s\", overwriting previous entry...\n", name, filename);
- } else duplicate[type-1] = true;
- count++;
- }
+ while ((it = libconfig->setting_get_elem(status_conf.root, i++)) != NULL) {
+ if (status->read_scdb_libconfig_sub(it, i - 1, filepath))
+ ++count;
}
- libconfig->destroy(&refine_db_conf);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename);
- return count;
+ // @TODO: find a better way of handling this
+ if (!battle_config.display_hallucination) //Disable Hallucination.
+ status->dbs->IconChangeTable[SC_ILLUSION].id = SI_BLANK;
+
+ libconfig->destroy(&status_conf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath);
+ return true;
}
-bool status_readdb_scconfig(char* fields[], int columns, int current) {
- int val = 0;
- char* type = fields[0];
+static bool status_read_scdb_libconfig_sub(struct config_setting_t *it, int idx, const char *source)
+{
+ nullpo_retr(false, it);
+ nullpo_retr(false, source);
+
+ int i32;
+ int status_id;
+ const char *name = config_setting_name(it);
- if( !script->get_constant(type, &val) ){
- ShowWarning("status_readdb_sc_conf: Invalid status type %s specified.\n", type);
+ if (!script->get_constant(name, &status_id) || status_id <= SC_NONE || status_id >= SC_MAX) {
+ ShowWarning("status_read_scdb_libconfig_sub: Invalid status type (%s) in \"%s\" entry #%d, skipping.\n", name, source, idx);
return false;
}
- status->dbs->sc_conf[val] = (int)strtol(fields[1], NULL, 0);
+ libconfig->setting_lookup_bool_real(it, "Visible", &status->dbs->DisplayType[status_id]);
+
+ struct config_setting_t *fg = libconfig->setting_get_member(it, "Flags");
+ if (fg != NULL)
+ status->read_scdb_libconfig_sub_flag(fg, status_id, source);
+ if (itemdb->lookup_const(it, "Icon", &i32) && i32 >= 0)
+ status->dbs->IconChangeTable[status_id].id = i32;
+ else
+ status->dbs->IconChangeTable[status_id].id = SI_BLANK;
+ return true;
+}
+
+static bool status_read_scdb_libconfig_sub_flag(struct config_setting_t *it, int type, const char *source)
+{
+ nullpo_retr(false, it);
+ nullpo_retr(false, source);
+ Assert_retr(false, type > SC_NONE && type < SC_MAX);
+
+ int i = 0;
+ struct config_setting_t *t = NULL;
+ while ((t = libconfig->setting_get_elem(it, i++)) != NULL) {
+ const char *flag = config_setting_name(t);
+ bool on = libconfig->setting_get_bool_real(t);
+ int j;
+
+ struct {
+ const char *name;
+ enum sc_conf_type value;
+ } flags[] = {
+ { "NoDeathReset", SC_NO_REM_DEATH },
+ { "NoSave", SC_NO_SAVE },
+ { "NoDispelReset", SC_NO_DISPELL },
+ { "NoClearanceReset", SC_NO_CLEARANCE },
+ { "Buff", SC_BUFF },
+ { "Debuff", SC_DEBUFF },
+ { "NoMadoReset", SC_MADO_NO_RESET },
+ { "NoAllReset", SC_NO_CLEAR },
+ { "NoBoss", SC_NO_BOSS },
+ };
+
+ ARR_FIND(0, ARRAYLENGTH(flags), j, strcmpi(flag, flags[j].name) == 0);
+ if (j != ARRAYLENGTH(flags)) {
+ if (strcmp(flag, flags[j].name) != 0) {
+ ShowWarning("status_read_scdb_libconfig_sub_flag: flag (%s) for status effect (%d) is casesensitive, correct it to (%s).", flag, type, flags[i].name);
+ }
+ if (on) {
+ status->dbs->sc_conf[type] |= flags[j].value;
+ } else {
+ status->dbs->sc_conf[type] &= ~flags[j].value;
+ }
+ } else {
+ if (!status->read_scdb_libconfig_sub_flag_additional(it, type, source))
+ ShowWarning("status_read_scdb_libconfig_sub_flag: invalid flag (%s) for status effect (%d).", flag, type);
+ }
+ }
return true;
}
+
+static bool status_read_scdb_libconfig_sub_flag_additional(struct config_setting_t *it, int type, const char *source)
+{
+ // to be used by plugins
+ return false;
+}
+
/**
* Read status db
* job1.txt
@@ -13004,7 +13342,7 @@ bool status_readdb_scconfig(char* fields[], int columns, int current) {
* size_fixe.txt
* refine_db.txt
**/
-int status_readdb(void)
+static int status_readdb(void)
{
int i, j;
@@ -13031,30 +13369,23 @@ int status_readdb(void)
for(j = 0; j < MAX_SINGLE_WEAPON_TYPE; j++)
status->dbs->atkmods[i][j] = 100;
- // refine_db.txt
- for(i=0;i<ARRAYLENGTH(status->dbs->refine_info);i++) {
- for(j=0;j<MAX_REFINE; j++) {
- status->dbs->refine_info[i].chance[j] = 100;
- status->dbs->refine_info[i].bonus[j] = 0;
- status->dbs->refine_info[i].randombonus_max[j] = 0;
- }
- }
-
// read databases
//
sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2);
sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_SINGLE_WEAPON_TYPE, MAX_SINGLE_WEAPON_TYPE, ARRAYLENGTH(status->dbs->atkmods), status->readdb_sizefix);
- status->readdb_refine_libconfig(DBPATH"refine_db.conf");
- sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig);
+ status->read_scdb_libconfig();
status->read_job_db();
+ pc->validate_levels();
+
return 0;
}
/*==========================================
-* Status db init and destroy.
-*------------------------------------------*/
-int do_init_status(bool minimal) {
+ * Status db init and destroy.
+ *------------------------------------------*/
+static int do_init_status(bool minimal)
+{
if (minimal)
return 0;
@@ -13069,16 +13400,19 @@ int do_init_status(bool minimal) {
timer->add_interval(status->natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status->natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
return 0;
}
-void do_final_status(void) {
+
+static void do_final_status(void)
+{
ers_destroy(status->data_ers);
}
/*=====================================
-* Default Functions : status.h
-* Generated by HerculesInterfaceMaker
-* created by Susu
-*-------------------------------------*/
-void status_defaults(void) {
+ * Default Functions : status.h
+ * Generated by HerculesInterfaceMaker
+ * created by Susu
+ *-------------------------------------*/
+void status_defaults(void)
+{
status = &status_s;
status->dbs = &statusdbs;
@@ -13096,13 +13430,13 @@ void status_defaults(void) {
status->natural_heal_prev_tick = 0;
status->natural_heal_diff_tick = 0;
/* funcs */
- status->get_refine_chance = status_get_refine_chance;
// for looking up associated data
status->skill2sc = status_skill2sc;
status->sc2skill = status_sc2skill;
status->sc2scb_flag = status_sc2scb_flag;
- status->type2relevant_bl_types = status_type2relevant_bl_types;
+ status->get_sc_relevant_bl_types = status_get_sc_relevant_bl_types;
status->get_sc_type = status_get_sc_type;
+ status->get_sc_icon = status_get_sc_icon;
status->damage = status_damage;
//Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills)
@@ -13140,6 +13474,7 @@ void status_defaults(void) {
status->get_sc_def = status_get_sc_def;
status->change_start = status_change_start;
+ status->change_start_sub = status_change_start_sub;
status->change_end_ = status_change_end_;
status->kaahi_heal_timer = kaahi_heal_timer;
status->change_timer = status_change_timer;
@@ -13147,11 +13482,18 @@ void status_defaults(void) {
status->change_clear = status_change_clear;
status->change_clear_buffs = status_change_clear_buffs;
+ status->is_immune_to_status = status_is_immune_to_status;
+ status->is_boss_resist_sc = status_is_boss_resist_sc;
+ status->end_sc_before_start = status_end_sc_before_start;
+ status->change_start_stop_action = status_change_start_stop_action;
+ status->change_start_set_option = status_change_start_set_option;
+ status->get_val_flag = status_get_val_flag;
status->calc_bl_ = status_calc_bl_;
status->calc_mob_ = status_calc_mob_;
status->calc_pet_ = status_calc_pet_;
status->calc_pc_ = status_calc_pc_;
status->calc_pc_additional = status_calc_pc_additional;
+ status->calc_pc_recover_hp = status_calc_pc_recover_hp;
status->calc_homunculus_ = status_calc_homunculus_;
status->calc_mercenary_ = status_calc_mercenary_;
status->calc_elemental_ = status_calc_elemental_;
@@ -13188,6 +13530,8 @@ void status_defaults(void) {
status->base_atk = status_base_atk;
status->get_base_maxhp = status_get_base_maxhp;
status->get_base_maxsp = status_get_base_maxsp;
+ status->get_restart_hp = status_get_restart_hp;
+ status->get_restart_sp = status_get_restart_sp;
status->calc_npc_ = status_calc_npc_;
status->calc_str = status_calc_str;
status->calc_agi = status_calc_agi;
@@ -13214,14 +13558,21 @@ void status_defaults(void) {
status->calc_ematk = status_calc_ematk;
status->calc_bl_main = status_calc_bl_main;
status->display_add = status_display_add;
+ status->change_start_display = status_change_start_display;
+ status->change_start_unknown_sc = status_change_start_unknown_sc;
status->display_remove = status_display_remove;
status->natural_heal = status_natural_heal;
status->natural_heal_timer = status_natural_heal_timer;
status->readdb_job2 = status_readdb_job2;
status->readdb_sizefix = status_readdb_sizefix;
- status->readdb_refine_libconfig = status_readdb_refine_libconfig;
- status->readdb_refine_libconfig_sub = status_readdb_refine_libconfig_sub;
- status->readdb_scconfig = status_readdb_scconfig;
+ status->read_scdb_libconfig = status_read_scdb_libconfig;
+ status->read_scdb_libconfig_sub = status_read_scdb_libconfig_sub;
+ status->read_scdb_libconfig_sub_flag = status_read_scdb_libconfig_sub_flag;
+ status->read_scdb_libconfig_sub_flag_additional = status_read_scdb_libconfig_sub_flag_additional;
status->read_job_db = status_read_job_db;
status->read_job_db_sub = status_read_job_db_sub;
+ status->set_sc = status_set_sc;
+ status->copy = status_copy;
+ status->base_matk_min = status_base_matk_min;
+ status->base_matk_max = status_base_matk_max;
}