Ver código fonte

Merge pull request #288 from 'hotfix/issue139'

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
Cydh Ramdh 10 anos atrás
pai
commit
cb2ffa24c8
5 arquivos alterados com 51 adições e 15 exclusões
  1. 1 1
      db/re/skill_cast_db.txt
  2. 2 2
      src/map/mob.c
  3. 12 5
      src/map/skill.c
  4. 35 7
      src/map/status.c
  5. 1 0
      src/map/status.h

+ 1 - 1
db/re/skill_cast_db.txt

@@ -1544,7 +1544,7 @@
 //-- 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
 //-- SO_VACUUM_EXTREME
-2453,1000:1500:2000:2500:3000,1000,0,4000:6000:8000:10000:12000,1000,5000,-1
+2453,1000:1500:2000:2500:3000,1000,0,4000:6000:8000:10000:12000,2000,5000,-1
 //-- SO_VARETYR_SPEAR
 2454,2200:2400:2600:2800:3000,1000,0,0,2200:2400:2600:2800:3000,2000,1800:1600:1400:1200:1000
 //-- SO_ARRULLO

+ 2 - 2
src/map/mob.c

@@ -1457,7 +1457,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
 		view_range = md->db->range2;
 	mode = status_get_mode(&md->bl);
 
-	can_move = (mode&MD_CANMOVE)&&unit_can_move(&md->bl);
+	can_move = (mode&MD_CANMOVE) && unit_can_move(&md->bl);
 
 	if (md->target_id)
 	{	//Check validity of current target. [Skotlex]
@@ -1561,7 +1561,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
 		return true;
 
 	// Scan area for targets
-	if (!tbl && mode&MD_LOOTER && md->lootitem && DIFF_TICK(tick, md->ud.canact_tick) > 0 &&
+	if (!tbl && can_move && mode&MD_LOOTER && md->lootitem && DIFF_TICK(tick, md->ud.canact_tick) > 0 &&
 		(md->lootitem_count < LOOTITEM_SIZE || battle_config.monster_loot_type != 1))
 	{	// Scan area for items to loot, avoid trying to loot if the mob is full and can't consume the items.
 		map_foreachinshootrange (mob_ai_sub_hard_lootsearch, &md->bl, view_range, BL_ITEM, md, &tbl);

+ 12 - 5
src/map/skill.c

@@ -12332,6 +12332,13 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 	case HW_GRAVITATION:
 		if(sc && sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
 			link_group_id = sc->data[SC_GRAVITATION]->val4;
+		break;
+	case SO_VACUUM_EXTREME:
+		// Coordinates
+		val1 = x;
+		val2 = y;
+		val3 = 0; // Suck target at n seconds.
+		break;
 	}
 
 	// Init skill unit group
@@ -13426,12 +13433,12 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 			break;
 
 		case UNT_VACUUM_EXTREME:
-			if ( tsc && tsc->data[SC_HALLUCINATIONWALK] )
+			if (tsc && (tsc->data[SC_HALLUCINATIONWALK] || tsc->data[SC_HOVERING] || tsc->data[SC_VACUUM_EXTREME] ||
+				(tsc->data[SC_VACUUM_EXTREME_POSTDELAY] && tsc->data[SC_VACUUM_EXTREME_POSTDELAY]->val2 == sg->group_id))) // Ignore post delay from other vacuum (this will make stack effect enabled)
 				return 0;
-			else {
-				sg->limit -= 100 * tstatus->str/20;
-				sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit);
-			}
+			else
+				// Apply effect and suck targets one-by-one each n seconds
+				sc_start4(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->group_id, (sg->val1<<16)|(sg->val2), ++sg->val3*500, (sg->limit - DIFF_TICK(tick, sg->tick)));
 			break;
 
 		case UNT_BANDING:

+ 35 - 7
src/map/status.c

@@ -1201,6 +1201,7 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC_KYOUGAKU]				|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_PARALYSIS]			|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_KINGS_GRACE]			|= SCS_NOMOVE;
+	StatusChangeStateTable[SC_VACUUM_EXTREME]		|= SCS_NOMOVE;
 
 	/* StatusChangeState (SCS_) NOPICKUPITEMS */
 	StatusChangeStateTable[SC_HIDING]				|= SCS_NOPICKITEM;
@@ -7799,7 +7800,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		)
 			return 0;
 	case SC_VACUUM_EXTREME:
-		if(sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HOVERING])
+		if (sc && (sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HOVERING] || sc->data[SC_VACUUM_EXTREME] ||
+			(sc->data[SC_VACUUM_EXTREME_POSTDELAY] && sc->data[SC_VACUUM_EXTREME_POSTDELAY]->val2 == val2))) // Ignore post delay from other vacuum (this will make stack effect enabled)
 			return 0;
 		break;
 	case SC_STONE:
@@ -8160,6 +8162,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			case SC_ELECTRICSHOCKER:
 			case SC_MAGNETICFIELD:
 			case SC_NETHERWORLD:
+			case SC_VACUUM_EXTREME:
 				return 0;
 		}
 	}
@@ -9677,11 +9680,6 @@ 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_VACUUM_EXTREME:
-			tick -= (status->str / 20) * 1000;
-			val4 = val3 = tick / 100;
-			tick_time = 100; // [GodLesZ] tick time
-			break;
 		case SC_SWINGDANCE:
 			val3 = 5 * val1 + val2; // Walk speed and aspd reduction.
 			break;
@@ -10129,6 +10127,16 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			tick_time = 3000;
 			val4 = tick/tick_time;
 			break;
+		case SC_VACUUM_EXTREME:
+			// Suck target at n second, only if the n second is lower than the duration
+			// Doesn't apply to BL_PC
+			if (bl->type != BL_PC && val4 < tick && !unit_blown_immune(bl,0x1) && status->mode&MD_CANMOVE) {
+				tick_time = val4;
+				val4 = tick - tick_time;
+			}
+			else
+				val4 = 0;
+			break;
 
 		/* Rebellion */
 		case SC_B_TRAP:
@@ -10311,7 +10319,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_PARALYSIS:
 		case SC_MAGNETICFIELD:
 		case SC_ANKLE:
-		case SC_VACUUM_EXTREME:
 			if (!unit_blown_immune(bl,0x1))
 				unit_stop_walking(bl,1);
 			break;
@@ -10319,6 +10326,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			if (bl->type == BL_PC || !unit_blown_immune(bl,0x1))
 				unit_stop_walking(bl,1);
 			break;
+		case SC_VACUUM_EXTREME:
+			if (bl->type != BL_PC && !unit_blown_immune(bl,0x1)) {
+				unit_stop_walking(bl,1);
+				unit_stop_attack(bl);
+			}
+			break;
 		case SC_HIDING:
 		case SC_CLOAKING:
 		case SC_CLOAKINGEXCEED:
@@ -11308,6 +11321,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 				map_addflooritem(&it, it.amount, bl->m,bl->x, bl->y, caster->status.char_id, 0, 0, 4);
 			}
 			break;
+		case SC_VACUUM_EXTREME:
+			///< !CHECKME: Seems on official, there's delay before same target can be vacuumed in same area again [Cydh]
+			sc_start2(bl, bl, SC_VACUUM_EXTREME_POSTDELAY, 100, sce->val1, sce->val2, skill_get_time2(SO_VACUUM_EXTREME,sce->val1));
+			break;
 	}
 
 	opt_flag = 1;
@@ -12397,6 +12414,17 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 				break;
 			sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
 		}
+		break;
+	case SC_VACUUM_EXTREME:
+		if (sce->val4) {
+			if (unit_movepos(bl, sce->val3>>16, sce->val3&0xFFFF, 0, false)) {
+				clif_slide(bl, sce->val3>>16, sce->val3&0xFFFF);
+				clif_fixpos(bl);
+			}
+			sc_timer_next(tick+sce->val4, status_change_timer, bl->id, data);
+			sce->val4 = 0;
+		}
+		break;
 	}
 
 	// Default for all non-handled control paths is to end the status

+ 1 - 0
src/map/status.h

@@ -702,6 +702,7 @@ typedef enum sc_type {
 	SC__CHAOS,
 	SC_ELEMENTAL_SHIELD,
 	SC_CHASEWALK2,
+	SC_VACUUM_EXTREME_POSTDELAY,
 
 	SC_MTF_ASPD2,
 	SC_MTF_RANGEATK2,