Просмотр исходного кода

Corrected Warmer's effect (fixes #1097)
* Moved the healing effect to status change timer.
* Warmer's effect will now last the entire life of the unit.
* Warmer's effect will now be removed when a player leaves the unit.
* Corrected Cloud Kill unit flag not being applied.

aleos89 9 лет назад
Родитель
Сommit
ab576e9bf8
6 измененных файлов с 36 добавлено и 25 удалено
  1. 1 1
      db/pre-re/skill_cast_db.txt
  2. 1 1
      db/pre-re/skill_unit_db.txt
  3. 1 1
      db/re/skill_cast_db.txt
  4. 1 1
      db/re/skill_unit_db.txt
  5. 10 21
      src/map/skill.c
  6. 22 0
      src/map/status.c

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

@@ -1534,7 +1534,7 @@
 //-- SO_STRIKING
 2451,1000,1000,0,60000,0,2000
 //-- SO_WARMER
-2452,2200:2400:2600:2800:3000,1000,0,40000:45000:50000:55000:60000,30000,35000:40000:45000:50000:55000
+2452,2200:2400:2600:2800:3000,1000,0,40000:45000:50000:55000:60000,0,35000:40000:45000:50000:55000
 //-- SO_VACUUM_EXTREME
 2453,1000:1500:2000:2500:3000,1000,0,4000:6000:8000:10000:12000,2000,5000
 //-- SO_VARETYR_SPEAR

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

@@ -148,7 +148,7 @@
 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
-2452,0xe4,    ,  0, 3,3000,all,   0x8010	//SO_WARMER
+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
 2466,0xf2,    ,  0, 1,1000,all,   0x010	//SO_WATER_INSIGNIA

+ 1 - 1
db/re/skill_cast_db.txt

@@ -1550,7 +1550,7 @@
 //-- SO_STRIKING
 2451,1000,1000,0,60000,0,2000,-1
 //-- SO_WARMER
-2452,2200:2400:2600:2800:3000,1000,0,40000:45000:50000:55000:60000,30000,35000:40000:45000:50000:55000,1800:1600:1400:1200:1000
+2452,2200:2400:2600:2800:3000,1000,0,40000:45000:50000:55000:60000,0,35000:40000:45000:50000:55000,1800:1600:1400:1200:1000
 //-- SO_VACUUM_EXTREME
 2453,1000:1500:2000:2500:3000,1000,0,4000:6000:8000:10000:12000,2000,5000,-1
 //-- SO_VARETYR_SPEAR

+ 1 - 1
db/re/skill_unit_db.txt

@@ -149,7 +149,7 @@
 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
-2452,0xe4,    ,  0, 3,3000,all,   0x8010	//SO_WARMER
+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
 2466,0xf2,    ,  0, 1,1000,all,   0x010	//SO_WATER_INSIGNIA

+ 10 - 21
src/map/skill.c

@@ -11681,8 +11681,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
 		break;
 
 	case SO_WARMER:
-		flag|= 8;
 	case SO_CLOUD_KILL:
+		flag |= (skill_id == SO_WARMER) ? 8 : 4;
 		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
 		break;
 
@@ -13038,6 +13038,7 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
 	struct block_list *ss; // Actual source that cast the skill unit
 	struct status_change *sc;
 	struct status_change_entry *sce;
+	struct status_data *tstatus;
 	enum sc_type type;
 	uint16 skill_id;
 
@@ -13050,6 +13051,8 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un
 	nullpo_ret(sg = unit->group);
 	nullpo_ret(ss = map_id2bl(sg->src_id));
 
+	tstatus = status_get_status_data(bl);
+
 	if( (skill_get_type(sg->skill_id) == BF_MAGIC && map_getcell(unit->bl.m, unit->bl.x, unit->bl.y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR) ||
 		map_getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) )
 		return 0; //AoE skills are ineffective. [Skotlex]
@@ -13302,6 +13305,11 @@ 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_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));
+			break;
+
 		case UNT_CATNIPPOWDER:
 			if (sg->src_id == bl->id)
 				break; // Does not affect the caster or Boss.
@@ -13938,25 +13946,6 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 			skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 			break;
 
-		case UNT_WARMER:
-			if( bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON ) {
-				int hp = 0;
-				struct status_change *ssc = status_get_sc(ss);
-
-				if( ssc && ssc->data[SC_HEATER_OPTION] )
-					hp = tstatus->max_hp * 3 * sg->skill_lv / 100;
-				else
-					hp = tstatus->max_hp * sg->skill_lv / 100;
-				if( tstatus->hp != tstatus->max_hp )
-					clif_skill_nodamage(&unit->bl, bl, AL_HEAL, hp, 0);
-				if( tsc && tsc->data[SC_AKAITSUKI] && hp )
-					hp = ~hp + 1;
-				status_heal(bl, hp, 0, 0);
-				if (tsc && !tsc->data[type]) // Don't apply the status again if it's already active.
-					sc_start(ss, bl, type, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv));
-			}
-			break;
-
 		case UNT_ZEPHYR:
 			if (ss == bl)
 				break; // Doesn't affect the Elemental
@@ -14137,7 +14126,6 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, unsigned int
 		case UNT_SAFETYWALL:
 		case UNT_PNEUMA:
 		case UNT_EPICLESIS://Arch Bishop
-		case UNT_WARMER:
 			if (sce)
 				status_change_end(bl, type, INVALID_TIMER);
 			break;
@@ -14238,6 +14226,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_WARMER:
 		case SO_FIRE_INSIGNIA:
 		case SO_WATER_INSIGNIA:
 		case SO_WIND_INSIGNIA:

+ 22 - 0
src/map/status.c

@@ -9907,6 +9907,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			val4 = tick / 1000;
 			tick_time = 1000; // [GodLesZ] tick time
 			break;
+		case SC_WARMER:
+			val4 = tick / 3000;
+			tick = -1; // Duration sent to the client should be infinite
+			tick_time = 3000;
+			break;
 		case SC_BLOODSUCKER:
 			val4 = tick / 1000;
 			tick_time = 1000; // [GodLesZ] tick time
@@ -12432,6 +12437,23 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 			return 0;
 		}
 		break;
+
+	case SC_WARMER: {
+			int hp = 0;
+			struct status_change *ssc = status_get_sc(map_id2bl(sce->val2));
+
+			if (ssc && ssc->data[SC_HEATER_OPTION])
+				hp = status->max_hp * 3 * sce->val1 / 100;
+			else
+				hp = status->max_hp * sce->val1 / 100;
+			if (sc && sc->data[SC_AKAITSUKI] && hp)
+				hp = ~hp + 1;
+			if (status->hp != status->max_hp)
+				status_heal(bl, hp, 0, 0);
+			sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
+			return 0;
+		}
+
 	case SC_BLOODSUCKER:
 		if( --(sce->val4) >= 0 ) {
 			struct block_list *src = map_id2bl(sce->val2);