浏览代码

Fixed SC_KEEPING and SC_BARRIER exploit after classchange (#4486)

* Fixed monsters affected by SC_KEEPING and SC_BARRIER not moving or attacking after classchange
* Thanks to @aleos89
Daegaladh 5 年之前
父节点
当前提交
28c70cde3d
共有 3 个文件被更改,包括 19 次插入15 次删除
  1. 1 0
      src/map/mob.cpp
  2. 2 15
      src/map/skill.cpp
  3. 16 0
      src/map/status.cpp

+ 1 - 0
src/map/mob.cpp

@@ -3243,6 +3243,7 @@ int mob_class_change (struct mob_data *md, int mob_id)
 		memcpy(md->name,md->db->jname,NAME_LENGTH);
 
 	status_change_end(&md->bl,SC_KEEPING,INVALID_TIMER); // End before calling status_calc_mob().
+	status_change_end(&md->bl,SC_BARRIER,INVALID_TIMER);
 	mob_stop_attack(md);
 	mob_stop_walking(md, 0);
 	unit_skillcastcancel(&md->bl, 0);

+ 2 - 15
src/map/skill.cpp

@@ -6752,6 +6752,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case NPC_DEFENDER:
 	case NPC_MAGICMIRROR:
 	case ST_PRESERVE:
+	case NPC_KEEPING:
+	case NPC_BARRIER:
 	case NPC_INVINCIBLE:
 	case NPC_INVINCIBLEOFF:
 	case MER_INVINCIBLEOFF2:
@@ -8222,21 +8224,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		if (md) mob_unlocktarget(md, tick);
 		break;
 
-	case NPC_KEEPING:
-	case NPC_BARRIER:
-		{
-			int skill_time = skill_get_time(skill_id,skill_lv);
-			struct unit_data *ud = unit_bl2ud(bl);
-			if (clif_skill_nodamage(src,bl,skill_id,skill_lv,
-					sc_start(src,bl,type,100,skill_lv,skill_time))
-			&& ud) {	//Disable attacking/acting/moving for skill's duration.
-				ud->attackabletime =
-				ud->canact_tick =
-				ud->canmove_tick = tick + skill_time;
-			}
-		}
-		break;
-
 	case NPC_REBIRTH:
 		if( md && md->state.rebirth )
 			break; // only works once

+ 16 - 0
src/map/status.cpp

@@ -9553,6 +9553,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			tick = INFINITE_TICK;
 			break;
 
+		case SC_KEEPING:
+		case SC_BARRIER: {
+			unit_data *ud = unit_bl2ud(bl);
+
+			if (ud)
+				ud->attackabletime = ud->canact_tick = ud->canmove_tick = gettick() + tick;
+		}
+			break;
 		case SC_DECREASEAGI:
 		case SC_INCREASEAGI:
 		case SC_ADORAMUS:
@@ -12178,6 +12186,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 	vd = status_get_viewdata(bl);
 	calc_flag = static_cast<scb_flag>(StatusChangeFlagTable[type]);
 	switch(type) {
+		case SC_KEEPING:
+		case SC_BARRIER: {
+			unit_data *ud = unit_bl2ud(bl);
+
+			if (ud)
+				ud->attackabletime = ud->canact_tick = ud->canmove_tick = gettick();
+		}
+			break;
 		case SC_GRANITIC_ARMOR:
 			{
 				int damage = status->max_hp*sce->val3/100;