summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-06-01 18:42:35 +0000
committershennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-06-01 18:42:35 +0000
commit67a0736c51678e453497660ef7df7bd601e57101 (patch)
tree0e908e5b0dbfb84632347d71aeda3b3a4a93913a
parent2d2262df9727b962135d39b6f22a1a092dc80175 (diff)
downloadhercules-67a0736c51678e453497660ef7df7bd601e57101.tar.gz
hercules-67a0736c51678e453497660ef7df7bd601e57101.tar.bz2
hercules-67a0736c51678e453497660ef7df7bd601e57101.tar.xz
hercules-67a0736c51678e453497660ef7df7bd601e57101.zip
performance improvement initial commit for status change state functionality, this first commit covers status that makes you unable to move.
-- this cache the status changes into states saving dozens of checks whenever a unit moves/per cell. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16209 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--src/map/status.c79
-rw-r--r--src/map/status.h9
-rw-r--r--src/map/unit.c36
3 files changed, 88 insertions, 36 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 74badf09e..91cb23df7 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -84,6 +84,8 @@ static int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is
static unsigned int StatusChangeFlagTable[SC_MAX]; // status -> flags
static int StatusSkillChangeTable[SC_MAX]; // status -> skill
static int StatusRelevantBLTypes[SI_MAX]; // "icon" -> enum bl_type (for clif_status_change to identify for which bl types to send packets)
+static unsigned int StatusChangeStateTable[SC_MAX]; // status -> flags
+
/**
* Returns the status change associated with a skill.
@@ -172,18 +174,22 @@ static void set_sc(int skill, sc_type sc, int icon, unsigned int flag)
SkillStatusChangeTable[sk] = sc;
}
-void initChangeTables(void)
-{
+void initChangeTables(void) {
int i;
+
for (i = 0; i < SC_MAX; i++)
StatusIconChangeTable[i] = SI_BLANK;
+
for (i = 0; i < MAX_SKILL; i++)
SkillStatusChangeTable[i] = SC_NONE;
+
for (i = 0; i < SI_MAX; i++)
StatusRelevantBLTypes[i] = BL_PC;
memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
+ memset(StatusChangeStateTable, 0, sizeof(StatusChangeStateTable));
+
//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 );
@@ -934,6 +940,33 @@ void initChangeTables(void)
if( !battle_config.display_hallucination ) //Disable Hallucination.
StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
+
+ /* StatusChangeState (SCS_) NOMOVE */
+ StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_TRICKDEAD] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BLADESTOP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BLADESTOP_WAIT] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_SPIDERWEB] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_DANCING] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_GOSPEL] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_BASILICA] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_STOP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CLOSECONFINE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CLOSECONFINE2] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CLOAKING] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_MADNESSCANCEL] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_GRAVITATION] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_ELECTRICSHOCKER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_BITE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_THORNSTRAP] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_MAGNETICFIELD] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC__MANHOLE] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_VACUUM_EXTREME] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_FEAR] |= SCS_NOMOVE|SCS_CONDITION;
+ StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER] |= SCS_NOMOVE;
+ StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOMOVE;
}
static void initDummyData(void)
@@ -3348,7 +3381,41 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
regen->flag&=~sce->val4; //Remove regen as specified by val4
}
}
-
+void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) {
+ bool has_condition = ( flag&SCS_CONDITION ) ? true : false;
+
+ /* no sc at all, we can zero without any extra weight over our conciousness */
+ if( !sc->count ) {
+ memset(&sc->cant, 0, sizeof (sc->cant));
+ return;
+ }
+
+
+ if( flag&SCS_NOMOVE ) {
+ if( !has_condition ) {
+ sc->cant.move += ( start ? 1 : -1 );
+ } else if(
+ (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
+ || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
+ !sc->data[SC_LONGING] ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
+ ) )
+ || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
+ || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
+ || (sc->data[SC_CLOAKING] && //Need wall at level 1-2
+ sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
+ || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
+ ) {
+ sc->cant.move += ( start ? 1 : -1 );
+ }
+ }
+
+ /* others e.g. cant.cast, cant.pickup (check clif_parse_TakeItem) */
+
+ return;
+}
/// 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)
@@ -8179,6 +8246,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (calc_flag)
status_calc_bl(bl,calc_flag);
+ if ( StatusChangeStateTable[type] ) /* non-zero */
+ status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
+
if(sd && sd->pd)
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
@@ -8414,6 +8484,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
}
+ if ( StatusChangeStateTable[type] )
+ status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
+
sc->data[type] = NULL;
(sc->count)--;
diff --git a/src/map/status.h b/src/map/status.h
index 56a019682..5b6c2296a 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1408,6 +1408,12 @@ enum manner_flags
MANNER_NOROOM = 0x10,
};
+/* Status Change State Flags */
+enum scs_flag {
+ SCS_CONDITION = 0x00000001, /* this implies the flag has a condition (if-checkin) */
+ SCS_NOMOVE = 0x00000002, /* unit unable to move */
+};
+
//Define flags for the status_calc_bl function. [Skotlex]
enum scb_flag
{
@@ -1556,6 +1562,9 @@ struct status_change {
unsigned char count;
//TODO: See if it is possible to implement the following SC's without requiring extra parameters while the SC is inactive.
unsigned char jb_flag; //Joint Beat type flag
+ struct {
+ unsigned char move;
+ } cant;/* status change state flags */
//int sg_id; //ID of the previous Storm gust that hit you
short comet_x, comet_y; // Point where src casted Comet - required to calculate damage from this point
/**
diff --git a/src/map/unit.c b/src/map/unit.c
index e58c003e9..47f9b5a39 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -886,45 +886,15 @@ int unit_can_move(struct block_list *bl)
return 0; //Can't move
if (sc) {
+ if( sc->cant.move )
+ return 0;
+
if (sc->opt1 > 0 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING)
return 0;
if ((sc->option & OPTION_HIDE) && (!sd || pc_checkskill(sd, RG_TUNNELDRIVE) <= 0))
return 0;
- if (sc->count && (
- sc->data[SC_ANKLE]
- || sc->data[SC_AUTOCOUNTER]
- || sc->data[SC_TRICKDEAD]
- || sc->data[SC_BLADESTOP]
- || sc->data[SC_BLADESTOP_WAIT]
- || (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
- || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
- !sc->data[SC_LONGING] ||
- (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
- (sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
- ))
- || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
- || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
- || sc->data[SC_STOP]
- || sc->data[SC_CLOSECONFINE]
- || sc->data[SC_CLOSECONFINE2]
- || (sc->data[SC_CLOAKING] && //Need wall at level 1-2
- sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
- || sc->data[SC_MADNESSCANCEL]
- || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
- || sc->data[SC_WHITEIMPRISON]
- || sc->data[SC_ELECTRICSHOCKER]
- || sc->data[SC_BITE]
- || sc->data[SC_THORNSTRAP]
- || sc->data[SC_MAGNETICFIELD]
- || sc->data[SC__MANHOLE]
- || sc->data[SC_VACUUM_EXTREME]
- || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
- || sc->data[SC_CURSEDCIRCLE_ATKER]
- || sc->data[SC_CURSEDCIRCLE_TARGET]
- ))
- return 0;
}
return 1;
}