summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/script_commands.txt2
-rw-r--r--src/map/skill.c43
-rw-r--r--src/map/skill.h2
-rw-r--r--src/map/status.c6
4 files changed, 47 insertions, 6 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 638c959cb..45311592a 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -1140,7 +1140,7 @@ From here on, we will have the commands sorted as followed:
-- 5.1: Time-Related Commands
-- 5.2: Guild-Related Commands
6 - Other Commands
-7 - Instance Commands
+7 - Instance-Related Commands
8 - Quest Log Commands
9 - Battleground Commands
10 - Mercenary Commands
diff --git a/src/map/skill.c b/src/map/skill.c
index 6b64bb488..90c0bbec6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -15285,6 +15285,40 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
return wall;
}
+
+/**
+ * Verifies if an user can use SC_CLOAKING
+ **/
+bool skill_can_cloak(struct map_session_data *sd, struct block_list *bl) {
+ nullpo_retr(false, sd);
+ nullpo_retr(false, bl);
+
+ //Avoid cloaking with no wall and low skill level. [Skotlex]
+ //Due to the cloaking card, we have to check the wall versus to known
+ //skill level rather than the used one. [Skotlex]
+ //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
+ if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
+ return false;
+
+ return true;
+}
+
+/**
+ * Verifies if an user can still be cloaked (AS_CLOAKING)
+ * Is called via map->foreachinrange when any kind of wall disapears
+ **/
+int skill_check_cloaking_end(struct block_list *bl, va_list ap) {
+ TBL_PC *sd = (TBL_PC*)bl;
+
+ if( bl == NULL || sd == NULL )
+ return 0;
+
+ if( sd->sc.data[SC_CLOAKING] && !skill_can_cloak(sd, bl) )
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+
+ return 0;
+}
+
bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *sce)
{
static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1};
@@ -15433,6 +15467,13 @@ int skill_delunit (struct skill_unit* su) {
clif->changemapcell(0,su->bl.m,su->bl.x,su->bl.y,su->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug
skill->unitsetmapcell(su,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
map->list[su->bl.m].icewall_num--;
+ // AS_CLOAKING in low levels requires a wall to be cast, thus it needs to be
+ // checked again when a wall disapears! issue:8182 [Panikon]
+ map->foreachinarea(skill->check_cloaking_end, su->bl.m,
+ // Use 3x3 area to check for users near cell
+ su->bl.x - 1, su->bl.y - 1,
+ su->bl.x + 1, su->bl.x + 1,
+ BL_PC);
break;
case SA_LANDPROTECTOR:
skill->unitsetmapcell(su,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
@@ -18535,6 +18576,8 @@ void skill_defaults(void) {
skill->autospell = skill_autospell;
skill->calc_heal = skill_calc_heal;
skill->check_cloaking = skill_check_cloaking;
+ skill->check_cloaking_end = skill_check_cloaking_end;
+ skill->can_cloak = skill_can_cloak;
skill->enchant_elemental_end = skill_enchant_elemental_end;
skill->not_ok = skillnotok;
skill->not_ok_hom = skillnotok_hom;
diff --git a/src/map/skill.h b/src/map/skill.h
index 66d6dc39e..6939eda42 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1918,6 +1918,8 @@ struct skill_interface {
int (*autospell) (struct map_session_data *md,uint16 skill_id);
int (*calc_heal) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, bool heal);
bool (*check_cloaking) (struct block_list *bl, struct status_change_entry *sce);
+ int (*check_cloaking_end) (struct block_list *bl, va_list);
+ bool (*can_cloak) (struct map_session_data *sd, struct block_list *bl);
int (*enchant_elemental_end) (struct block_list *bl, int type);
int (*not_ok) (uint16 skill_id, struct map_session_data *sd);
int (*not_ok_hom) (uint16 skill_id, struct homun_data *hd);
diff --git a/src/map/status.c b/src/map/status.c
index 316dce8e6..e76cd86a3 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6944,11 +6944,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
break;
case SC_CLOAKING:
- //Avoid cloaking with no wall and low skill level. [Skotlex]
- //Due to the cloaking card, we have to check the wall versus to known
- //skill level rather than the used one. [Skotlex]
- //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
- if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
+ if( !skill->can_cloak(sd, bl) )
return 0;
break;
case SC_MODECHANGE: