From 1b827f192497a2b57150df9f56d0fa82df890b0b Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 19 Dec 2014 01:17:24 +0300 Subject: Allow move from sit state. --- src/Makefile.am | 2 + src/map/init.c | 2 + src/map/unit.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/unit.h | 9 ++++ 4 files changed, 145 insertions(+) create mode 100644 src/map/unit.c create mode 100644 src/map/unit.h 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 +#include +#include + +#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 -- cgit v1.2.3-70-g09d2