瀏覽代碼

Corrected Cloud Kill effect (fixes #407)
* Properly implemented the Cloud Kill status icon.
* Poison duration is not reduced and lasts if the target leaves the AoE.
- Walking into the AoE a second time resets the Poison status.

aleos89 9 年之前
父節點
當前提交
e5a197ad70
共有 6 個文件被更改,包括 28 次插入9 次删除
  1. 1 1
      db/pre-re/skill_unit_db.txt
  2. 1 1
      db/re/skill_unit_db.txt
  3. 1 0
      src/map/script_constants.h
  4. 8 6
      src/map/skill.c
  5. 15 1
      src/map/status.c
  6. 2 0
      src/map/status.h

+ 1 - 1
db/pre-re/skill_unit_db.txt

@@ -147,7 +147,7 @@
 2446,0x86,    ,  0, 3:3:3:4:4,1000,enemy, 0x018	//SO_EARTHGRAVE
 2447,0x86,    ,  0, 3:3:3:4:4,1000,enemy, 0x018	//SO_DIAMONDDUST
 2449,0xdf,    ,  0, 3:3:4:4:5,500,enemy,  0x018	//SO_PSYCHIC_WAVE
-2450,0xe0,    ,  0, 3, 500,enemy, 0x8010	//SO_CLOUD_KILL
+2450,0xe0,    ,  3, 0,  -1,enemy, 0xA010	//SO_CLOUD_KILL
 2452,0xe4,    ,  3, 0,  -1,all,   0xA010	//SO_WARMER
 2453,0xeb,    ,  0, 1:1:2:2:3,500,enemy,0x8010	//SO_VACUUM_EXTREME
 2465,0xf1,    ,  0, 1,1000,all,   0x010	//SO_FIRE_INSIGNIA

+ 1 - 1
db/re/skill_unit_db.txt

@@ -148,7 +148,7 @@
 2446,0x86,    ,  0, 3:3:3:4:4,1000,enemy, 0x018	//SO_EARTHGRAVE
 2447,0x86,    ,  0, 3:3:3:4:4,1000,enemy, 0x018	//SO_DIAMONDDUST
 2449,0xdf,    ,  0, 3:3:4:4:5,500,enemy,  0x018	//SO_PSYCHIC_WAVE
-2450,0xe0,    ,  0, 3, 500,enemy, 0x8010	//SO_CLOUD_KILL
+2450,0xe0,    ,  3, 0,  -1,enemy, 0xA010	//SO_CLOUD_KILL
 2452,0xe4,    ,  3, 0,  -1,all,   0xA010	//SO_WARMER
 2453,0xeb,    ,  0, 1:1:2:2:3,500,enemy,0x8010	//SO_VACUUM_EXTREME
 2465,0xf1,    ,  0, 1,1000,all,   0x010	//SO_FIRE_INSIGNIA

+ 1 - 0
src/map/script_constants.h

@@ -1362,6 +1362,7 @@
 	export_constant(SC_SHRIMP);
 	export_constant(SC_FRESHSHRIMP);
 	export_constant(SC_ACTIVE_MONSTER_TRANSFORM);
+	export_constant(SC_CLOUD_KILL);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif

+ 8 - 6
src/map/skill.c

@@ -13295,6 +13295,13 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
 				status_change_start(ss, bl, type, 10000, sg->skill_lv, 0, 0, 0, sg->limit, SCSTART_NOICON);
 			break;
 
+		case UNT_CLOUD_KILL:
+			if(!sce) {
+				sc_start4(ss, bl, type, 100, sg->skill_lv, ss->id, unit->bl.id, 0, skill_get_time(sg->skill_id, sg->skill_lv));
+				status_change_start(ss, bl, SC_POISON, 10000, sg->skill_lv, ss->id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
+			}
+			break;
+
 		case UNT_WARMER:
 			if (!sce && bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON)
 				sc_start2(ss, bl, type, 100, sg->skill_lv, ss->id, skill_get_time(sg->skill_id, sg->skill_lv));
@@ -13930,12 +13937,6 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 				sg->limit = DIFF_TICK(tick, sg->tick) + 100;
 			break;
 
-		case UNT_CLOUD_KILL:
-			if(tsc && !tsc->data[type])
-				status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),SCSTART_NORATEDEF);
-			skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
-			break;
-
 		case UNT_ZEPHYR:
 			if (ss == bl)
 				break; // Doesn't affect the Elemental
@@ -14216,6 +14217,7 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, unsigned int tick)
 		case EL_WATER_BARRIER:
 		case EL_ZEPHYR:
 		case EL_POWER_OF_GAIA:
+		case SO_CLOUD_KILL:
 		case SO_WARMER:
 		case SO_FIRE_INSIGNIA:
 		case SO_WATER_INSIGNIA:

+ 15 - 1
src/map/status.c

@@ -753,7 +753,7 @@ void initChangeTables(void)
 	set_sc( SO_ELECTRICWALK		, SC_PROPERTYWALK	, SI_PROPERTYWALK	, SCB_NONE );
 	set_sc( SO_SPELLFIST		, SC_SPELLFIST		, SI_SPELLFIST		, SCB_NONE );
 	set_sc_with_vfx( SO_DIAMONDDUST	, SC_CRYSTALIZE		, SI_COLD		, SCB_NONE );
-	set_sc( SO_CLOUD_KILL   , SC_POISON         , SI_CLOUDKILL      , SCB_NONE );
+	set_sc( SO_CLOUD_KILL   , SC_CLOUD_KILL         , SI_CLOUDKILL      , SCB_NONE );
 	set_sc( SO_STRIKING		, SC_STRIKING		, SI_STRIKING		, SCB_WATK|SCB_CRI );
 	set_sc( SO_WARMER		, SC_WARMER		, SI_WARMER		, SCB_NONE );
 	set_sc( SO_VACUUM_EXTREME	, SC_VACUUM_EXTREME	, SI_VACUUM_EXTREME	, SCB_NONE );
@@ -9891,6 +9891,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_PROPERTYWALK:
 			val3 = 0;
 			break;
+		case SC_CLOUD_KILL:
+			val4 = tick / 500;
+			tick = -1; // Duration sent to the client should be infinite
+			tick_time = 500;
+			break;
 		case SC_STRIKING:
 			// val2 = watk bonus already calc
 			val3 = 6 - val1;// spcost = 6 - level (lvl1:5 ... lvl 5: 1)
@@ -12427,6 +12432,15 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 		}
 		break;
 
+	case SC_CLOUD_KILL: {
+			struct block_list *src = map_id2bl(sce->val2), *unit_bl = map_id2bl(sce->val3);
+
+			if (src && unit_bl)
+				skill_attack(skill_get_type(status_sc2skill(type)), src, unit_bl, bl, SO_CLOUD_KILL, sce->val1, tick, 0);
+			sc_timer_next(500 + tick, status_change_timer, bl->id, data);
+		}
+		break;
+
 	case SC_WARMER: {
 			int hp = 0;
 			struct status_change *ssc = status_get_sc(map_id2bl(sce->val2));

+ 2 - 0
src/map/status.h

@@ -758,6 +758,8 @@ typedef enum sc_type {
 
 	SC_ACTIVE_MONSTER_TRANSFORM,
 
+	SC_CLOUD_KILL,
+
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 #endif