summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/map/init.c2
-rw-r--r--src/map/unit.c132
-rw-r--r--src/map/unit.h9
4 files changed, 145 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 289c775..3bb63c2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -46,6 +46,8 @@ MAP_SRC = map/clif.c \
map/send.h \
map/status.c \
map/status.h \
+ map/unit.c \
+ map/unit.h \
map/data/itemd.c \
map/data/itemd.h \
map/data/mapd.c \
diff --git a/src/map/init.c b/src/map/init.c
index 1ce4a78..6a025a8 100644
--- a/src/map/init.c
+++ b/src/map/init.c
@@ -39,6 +39,7 @@
#include "map/lang.h"
#include "map/map.h"
#include "map/npc.h"
+#include "map/unit.h"
#include "map/parse.h"
#include "map/pc.h"
#include "map/quest.h"
@@ -112,6 +113,7 @@ HPExport void plugin_init (void)
addHookPre("clif->send_actual", eclif_send_actual);
addHookPre("itemdb->is_item_usable", eitemdb_is_item_usable);
addHookPre("itemdb->readdb_additional_fields", eitemdb_readdb_additional_fields);
+ addHookPre("unit->can_move", eunit_can_move);
addHookPost("clif->getareachar_unit", eclif_getareachar_unit_post);
addHookPost("clif->authok", eclif_authok_post);
diff --git a/src/map/unit.c b/src/map/unit.c
new file mode 100644
index 0000000..df875cf
--- /dev/null
+++ b/src/map/unit.c
@@ -0,0 +1,132 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2014 Evol developers
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../../common/HPMi.h"
+#include "../../../common/malloc.h"
+#include "../../../common/mmo.h"
+#include "../../../common/socket.h"
+#include "../../../common/strlib.h"
+#include "../../../common/timer.h"
+#include "../../../map/unit.h"
+#include "../../../map/map.h"
+#include "../../../map/mob.h"
+#include "../../../map/pc.h"
+#include "../../../map/skill.h"
+#include "../../../map/status.h"
+
+#include "map/unit.h"
+
+int eunit_can_move(struct block_list *bl)
+{
+ struct map_session_data *sd;
+ struct unit_data *ud;
+ struct status_change *sc;
+
+ hookStop();
+
+ if (!bl)
+ return 0;
+ ud = unit->bl2ud(bl);
+ sc = status->get_sc(bl);
+ sd = BL_CAST(BL_PC, bl);
+
+ if (!ud)
+ return 0;
+
+ if (ud->skilltimer != INVALID_TIMER
+ && ud->skill_id != LG_EXEEDBREAK
+ && (!sd
+ || !pc->checkskill(sd, SA_FREECAST)
+ || skill->get_inf2(ud->skill_id)&INF2_GUILD_SKILL))
+ {
+ return 0; // prevent moving while casting
+ }
+
+ if (DIFF_TICK(ud->canmove_tick, timer->gettick()) > 0)
+ return 0;
+
+ if (sd && (
+ sd->state.vending ||
+ sd->state.buyingstore ||
+ sd->state.blockedmove))
+ {
+ return 0; //Can't move
+ }
+
+ // Status changes that block movement
+ if (sc)
+ {
+ if (sc->count && (
+ sc->data[SC_ANKLESNARE]
+ || sc->data[SC_AUTOCOUNTER]
+ || sc->data[SC_TRICKDEAD]
+ || sc->data[SC_BLADESTOP]
+ || sc->data[SC_BLADESTOP_WAIT]
+ || (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_FALLENEMPIRE]
+ || sc->data[SC_RG_CCONFINE_M]
+ || sc->data[SC_RG_CCONFINE_S]
+ || sc->data[SC_GS_MADNESSCANCEL]
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
+ || sc->data[SC_WHITEIMPRISON]
+ || sc->data[SC_ELECTRICSHOCKER]
+ || sc->data[SC_WUGBITE]
+ || sc->data[SC_THORNS_TRAP]
+ || ( sc->data[SC_MAGNETICFIELD] && !sc->data[SC_HOVERING] )
+ || sc->data[SC__MANHOLE]
+ || sc->data[SC_CURSEDCIRCLE_ATKER]
+ || sc->data[SC_CURSEDCIRCLE_TARGET]
+ || (sc->data[SC_COLD] && bl->type != BL_MOB)
+ || sc->data[SC_DEEP_SLEEP]
+ || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3 && !(sc->data[SC_CAMOUFLAGE]->val3&1))
+ || sc->data[SC_MEIKYOUSISUI]
+ || sc->data[SC_KG_KAGEHUMI]
+ || sc->data[SC_NEEDLE_OF_PARALYZE]
+ || sc->data[SC_VACUUM_EXTREME]
+ || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
+ || (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
+ || (sc->data[SC_CLOAKING] && sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1)) //Need wall at level 1-2
+ || (
+ 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))))
+ {
+ return 0;
+ }
+ if (sc->opt1 > 0
+ && sc->opt1 != OPT1_STONEWAIT
+ && sc->opt1 != OPT1_BURNING
+ && !(sc->opt1 == OPT1_CRYSTALIZE
+ && bl->type == BL_MOB))
+ {
+ return 0;
+ }
+
+ if ((sc->option & OPTION_HIDE) && (!sd || pc->checkskill(sd, RG_TUNNELDRIVE) <= 0))
+ {
+ return 0;
+ }
+ }
+
+ // Icewall walk block special trapped monster mode
+ if(bl->type == BL_MOB)
+ {
+ struct mob_data *md = BL_CAST(BL_MOB, bl);
+ if(md && ((md->status.mode&MD_BOSS && battle->bc->boss_icewall_walk_block == 1 && map->getcell(bl->m,bl->x,bl->y,CELL_CHKICEWALL))
+ || (!(md->status.mode&MD_BOSS) && battle->bc->mob_icewall_walk_block == 1 && map->getcell(bl->m,bl->x,bl->y,CELL_CHKICEWALL))))
+ {
+ md->walktoxy_fail_count = 1; //Make sure rudeattacked skills are invoked
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/src/map/unit.h b/src/map/unit.h
new file mode 100644
index 0000000..00fba4a
--- /dev/null
+++ b/src/map/unit.h
@@ -0,0 +1,9 @@
+// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// Copyright (c) 2014 Evol developers
+
+#ifndef EVOL_MAP_UNIT
+#define EVOL_MAP_UNIT
+
+int eunit_can_move(struct block_list *bl);
+
+#endif // EVOL_MAP_UNIT