src/map/pc.c | 6 ++++--
src/map/pc.h | 3 +++
src/map/script.c | 32 ++++++++++++++++++++++++++++++++
src/map/status.c | 4 ++++
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/src/map/pc.c b/src/map/pc.c
index 4d4f415..a80bdb0 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -8890,7 +8890,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->state.blockedattack )
return false;
return true;
@@ -8906,7 +8907,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) ||
- (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ||
+ sd->state.blockedchat )
return false;
return true;
diff --git a/src/map/pc.h b/src/map/pc.h
index 2c8b24a..22bcf6b 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -172,6 +172,9 @@ struct map_session_data {
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 blockedattack :1;
+ unsigned int blockedskill :1;
+ unsigned int blockedchat :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;
diff --git a/src/map/script.c b/src/map/script.c
index 54d8d33..7ed3d93 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -16300,6 +16300,34 @@ BUILDIN(pcblockmove) {
return true;
}
+BUILDIN(pcblockattack) {
+ TBL_PC *sd = script_getnum(st,2) ? map->id2sd( script_getnum(st,2) ) : script_rid2sd(st);
+ if ( sd )
+ sd->state.blockedattack = script_getnum(st,3) > 0;
+ return true;
+}
+
+BUILDIN(pcblockskill) {
+ TBL_PC *sd = script_getnum(st,2) ? map->id2sd( script_getnum(st,2) ) : script_rid2sd(st);
+ if ( sd )
+ sd->state.blockedskill = script_getnum(st,3) > 0;
+ return true;
+}
+
+BUILDIN(pcblockchat) {
+ TBL_PC *sd = script_getnum(st,2) ? map->id2sd( script_getnum(st,2) ) : script_rid2sd(st);
+ if ( sd )
+ sd->state.blockedchat = script_getnum(st,3) > 0;
+ return true;
+}
+
+BUILDIN(pcimmune) {
+ TBL_PC *sd = script_getnum(st,2) ? map->id2sd( script_getnum(st,2) ) : script_rid2sd(st);
+ if ( sd )
+ sd->state.monster_ignore = script_getnum(st,3) > 0;
+ return true;
+}
+
BUILDIN(pcfollow) {
int id, targetid;
TBL_PC *sd = NULL;
@@ -20234,6 +20262,10 @@ void script_parse_builtin(void) {
BUILDIN_DEF(pcfollow,"ii"),
BUILDIN_DEF(pcstopfollow,"i"),
BUILDIN_DEF(pcblockmove,"ii"),
+ BUILDIN_DEF(pcblockattack,"ii"),
+ BUILDIN_DEF(pcblockskill,"ii"),
+ BUILDIN_DEF(pcblockchat,"ii"),
+ BUILDIN_DEF(pcimmune,"ii"),
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
BUILDIN_DEF(unitwalk,"ii?"),
diff --git a/src/map/status.c b/src/map/status.c
index 1a07f74..5306934 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1600,6 +1600,10 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
if( skill_id ) {
+ if ( src && src->type == BL_PC ) // *pcblockskill script command
+ if ( ((TBL_PC*)src)->state.blockedskill )
+ return 0;
+
if( src && !(src->type == BL_PC && ((TBL_PC*)src)->skillitem)) { // Items that cast skills using 'itemskill' will not be handled by map_zone_db.
int i;