From 90be2a7937e7552a72d1e7eb632e6bc2d01443ef Mon Sep 17 00:00:00 2001 From: AnnieRuru Date: Fri, 4 May 2018 15:11:44 +0800 Subject: Add setpcblock & checkpcblock script commands thanks to @MishimaHaruna for the updated syntax --- src/map/atcommand.c | 8 +++-- src/map/battle.c | 2 +- src/map/clif.c | 6 ++++ src/map/pc.c | 9 +++-- src/map/pc.h | 12 +++++-- src/map/script.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/map/script.h | 16 +++++++++ src/map/status.c | 3 ++ src/map/unit.c | 2 +- 9 files changed, 144 insertions(+), 12 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 9deed0098..c7a1446e2 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -7522,11 +7522,11 @@ ACMD(sizeguild) *------------------------------------------*/ ACMD(monsterignore) { - if (!sd->state.monster_ignore) { - sd->state.monster_ignore = 1; + if (!sd->block_action.immune) { + sd->block_action.immune = 1; clif->message(sd->fd, msg_fd(fd,1305)); // You are now immune to attacks. } else { - sd->state.monster_ignore = 0; + sd->block_action.immune = 0; clif->message(sd->fd, msg_fd(fd,1306)); // Returned to normal state. } @@ -10090,6 +10090,8 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa return false; } } + if (sd->block_action.commands) // *pcblock script command + return false; if (*message == atcommand->char_symbol) is_atcommand = false; diff --git a/src/map/battle.c b/src/map/battle.c index f257f3c84..6a961afeb 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6649,7 +6649,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if (t_bl == s_bl) break; - if( sd->state.monster_ignore && flag&BCT_ENEMY ) + if (sd->block_action.immune && flag&BCT_ENEMY) return 0; // Global immunity only to Attacks if (sd->status.karma && s_bl->type == BL_PC && BL_UCCAST(BL_PC, s_bl)->status.karma) state |= BCT_ENEMY; // Characters with bad karma may fight amongst them diff --git a/src/map/clif.c b/src/map/clif.c index 47d5a1586..847bca096 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10488,6 +10488,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, return; } + if (sd->block_action.sitstand) // *pcblock script command + break; + if (sd->ud.skilltimer != INVALID_TIMER || (sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING )) break; @@ -10515,6 +10518,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, return; } + if (sd->block_action.sitstand) // *pcblock script command + break; + pc->update_idle_time(sd, BCIDLE_SIT); pc->setstand(sd); diff --git a/src/map/pc.c b/src/map/pc.c index 8dd216f55..1a26ef0d3 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5162,6 +5162,9 @@ int pc_useitem(struct map_session_data *sd,int n) { if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 ) return 0; + if (sd->block_action.useitem) // *pcblock script command + return 0; + if( !pc->isUseitem(sd,n) ) return 0; @@ -9321,7 +9324,8 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) { (sd->sc.data[SC_SIREN] && sd->sc.data[SC_SIREN]->val2 == target_id) || sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_DEEP_SLEEP] || - sd->sc.data[SC_FALLENEMPIRE] ) + sd->sc.data[SC_FALLENEMPIRE] || + sd->block_action.attack) return false; return true; @@ -9337,7 +9341,8 @@ bool pc_can_talk( struct map_session_data *sd ) { if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || - pc_ismuted(&sd->sc, MANNER_NOCHAT) ) + pc_ismuted(&sd->sc, MANNER_NOCHAT) || + sd->block_action.chat) return false; return true; diff --git a/src/map/pc.h b/src/map/pc.h index 49c102206..768bd4255 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -201,10 +201,8 @@ struct map_session_data { unsigned int noask :1; // [LuzZza] unsigned int trading :1; //[Skotlex] is 1 only after a trade has started. unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE - unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo] unsigned int size :2; // for tiny/large types unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex] - unsigned int blockedmove :1; unsigned int using_fake_npc :1; unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex] unsigned int killer : 1; @@ -621,6 +619,16 @@ END_ZEROED_BLOCK; // HatEffect VECTOR_DECL(int) hatEffectId; + struct { + unsigned move : 1; + unsigned attack : 1; + unsigned skill : 1; + unsigned useitem : 1; + unsigned chat : 1; + unsigned immune : 1; + unsigned sitstand : 1; + unsigned commands : 1; + } block_action; }; #define EQP_WEAPON EQP_HAND_R diff --git a/src/map/script.c b/src/map/script.c index 8e6ad5dcf..43f1252c7 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18062,9 +18062,88 @@ BUILDIN(pcblockmove) { else sd = script->rid2sd(st); - if (sd != NULL) - sd->state.blockedmove = flag > 0; + if (!sd) + return true; + + if (flag) + sd->block_action.move = 1; + else + sd->block_action.move = 0; + + return true; +} + +BUILDIN(setpcblock) +{ + struct map_session_data *sd = script->rid2sd(st); + enum pcblock_action_flag type = script_getnum(st, 2); + int state = (script_getnum(st, 3) > 0) ? 1 : 0; + + if (sd == NULL) + return true; + + if ((type & PCBLOCK_MOVE) != 0) + sd->block_action.move = state; + + if ((type & PCBLOCK_ATTACK) != 0) + sd->block_action.attack = state; + + if ((type & PCBLOCK_SKILL) != 0) + sd->block_action.skill = state; + + if ((type & PCBLOCK_USEITEM) != 0) + sd->block_action.useitem = state; + + if ((type & PCBLOCK_CHAT) != 0) + sd->block_action.chat = state; + + if ((type & PCBLOCK_IMMUNE) != 0) + sd->block_action.immune = state; + + if ((type & PCBLOCK_SITSTAND) != 0) + sd->block_action.sitstand = state; + + if ((type & PCBLOCK_COMMANDS) != 0) + sd->block_action.commands = state; + + return true; +} + +BUILDIN(checkpcblock) +{ + struct map_session_data *sd = script->rid2sd(st); + int retval = PCBLOCK_NONE; + + if (sd == NULL) { + script_pushint(st, PCBLOCK_NONE); + return true; + } + + if (sd->block_action.move != 0) + retval |= PCBLOCK_MOVE; + + if (sd->block_action.attack != 0) + retval |= PCBLOCK_ATTACK; + + if (sd->block_action.skill != 0) + retval |= PCBLOCK_SKILL; + + if (sd->block_action.useitem != 0) + retval |= PCBLOCK_USEITEM; + + if (sd->block_action.chat != 0) + retval |= PCBLOCK_CHAT; + + if (sd->block_action.immune != 0) + retval |= PCBLOCK_IMMUNE; + + if (sd->block_action.sitstand != 0) + retval |= PCBLOCK_SITSTAND; + + if (sd->block_action.commands != 0) + retval |= PCBLOCK_COMMANDS; + script_pushint(st, retval); return true; } @@ -24520,7 +24599,9 @@ void script_parse_builtin(void) { BUILDIN_DEF(rid2name,"i"), BUILDIN_DEF(pcfollow,"ii"), BUILDIN_DEF(pcstopfollow,"i"), - BUILDIN_DEF(pcblockmove,"ii"), + BUILDIN_DEF_DEPRECATED(pcblockmove,"ii"), // Deprecated 2018-05-04 + BUILDIN_DEF(setpcblock, "ii"), + BUILDIN_DEF(checkpcblock, ""), // <--- [zBuffer] List of player cont commands // [zBuffer] List of mob control commands ---> BUILDIN_DEF(getunittype,"i"), @@ -25093,6 +25174,17 @@ void script_hardcoded_constants(void) script->set_constant("MST_AROUND3", MST_AROUND3, false, false); script->set_constant("MST_AROUND4", MST_AROUND4, false, false); script->set_constant("MST_AROUND", MST_AROUND , false, false); + + script->constdb_comment("pc block constants, use with *setpcblock* and *checkpcblock*"); + script->set_constant("PCBLOCK_NONE", PCBLOCK_NONE, false, false); + script->set_constant("PCBLOCK_MOVE", PCBLOCK_MOVE, false, false); + script->set_constant("PCBLOCK_ATTACK", PCBLOCK_ATTACK, false, false); + script->set_constant("PCBLOCK_SKILL", PCBLOCK_SKILL, false, false); + script->set_constant("PCBLOCK_USEITEM", PCBLOCK_USEITEM, false, false); + script->set_constant("PCBLOCK_CHAT", PCBLOCK_CHAT, false, false); + script->set_constant("PCBLOCK_IMMUNE", PCBLOCK_IMMUNE, false, false); + script->set_constant("PCBLOCK_SITSTAND", PCBLOCK_SITSTAND, false, false); + script->set_constant("PCBLOCK_COMMANDS", PCBLOCK_COMMANDS, false, false); script->constdb_comment("Renewal"); #ifdef RENEWAL diff --git a/src/map/script.h b/src/map/script.h index ede786481..7bf20a741 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -453,6 +453,22 @@ enum script_iteminfo_types { ITEMINFO_MAX }; +/** + * Player blocking actions related flags. + */ +enum pcblock_action_flag { + PCBLOCK_NONE = 0x00, + PCBLOCK_MOVE = 0x01, + PCBLOCK_ATTACK = 0x02, + PCBLOCK_SKILL = 0x04, + PCBLOCK_USEITEM = 0x08, + PCBLOCK_CHAT = 0x10, + PCBLOCK_IMMUNE = 0x20, + PCBLOCK_SITSTAND = 0x40, + PCBLOCK_COMMANDS = 0x80, + PCBLOCK_ALL = 0xFF, +}; + /** * Structures **/ diff --git a/src/map/status.c b/src/map/status.c index 972d1eca9..030a45793 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1761,6 +1761,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. diff --git a/src/map/unit.c b/src/map/unit.c index 64bd17edc..d9cae3e3e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1091,7 +1091,7 @@ int unit_can_move(struct block_list *bl) pc_issit(sd) || sd->state.vending || sd->state.buyingstore || - sd->state.blockedmove + sd->block_action.move )) return 0; //Can't move -- cgit v1.2.3-60-g2f50