View Single Post
  #37  
Old 05-11-2018, 11:16 AM
Splose
Banned
 
Join Date: Apr 2014
Posts: 279
Default

Quote:
Originally Posted by jpyou127 View Post
Most excellent Splose!
I completely forgot about this!

A quick disclaimer I have a HEAVILY modified zone_controller.pl and had to quickly go through and remove everything that's not "stock" as far as the auto scaling goes. A quick test has this working on my server. If any of you have any issues I will try and fix them to the best of my ability.

Make sure you have the rule Zone::UseZoneController enabled. Place the following code into a file named zone_controller.pl in your quests/global folder.

Code:
sub EVENT_SPAWN {
	#$Debug = " ";
	
	quest::gmsay("Zone Scaling Sequence Initiated.", 18);
	quest::gmsay("Zone: $zonesn", 18);
	quest::gmsay("Instance Version: $instanceversion", 18);
	quest::gmsay("Instance ID: $instanceversion", 18);

	LoadStaticNPCScaling($zonesn); #:::  Load NPC Static Scaling
	LoadStaticZoneScaling(); #:::  Load Zone Static Scaling


	quest::settimer("scaleall", 1); #:::  Run Scaling routine 
	quest::settimer("scaleall", 3); #:::  Run Scaling routine 
	$ScalingLoaded = "";
}

sub EVENT_SIGNAL {
	ScaleProcedure($signal);
}


sub EVENT_SPAWN_ZONE {
	my $Pet = $entity_list->GetNPCByID($spawned_entity_id)->GetPetSpellID();
	if(!$Pet) {ScaleProcedure($spawned_entity_id);}
	else {
		quest::settimer("scale",1);
	}
}


sub EVENT_TIMER{
	if($timer eq "scaleall"){ ScaleProcedure(); quest::stoptimer("scaleall");  quest::gmsay("Scaling Sequence SUCCESSFUL (TEST)", 14);  }
	if($timer eq "scale"){quest::stoptimer("scale"); ScaleProcedure($spawned_entity_id);}
}



sub ScaleMob {
	my $npc_ent = $entity_list->GetNPCByID($_[0]);
}

sub ScaleProcedure{
	#quest::shout("scaling " . $_[0] . "");
	#:::  Read from DB
	if(!$SD[1][0][0]){ LoadScaling(); } #:::  Scaling Vars Empty, reload them from DB
	$NPC = 0; $pop = "";
	
	if($_[0]){ 
		@ent = $entity_list->GetNPCByID($_[0]); 
		$pop = " POP"; 
		#quest::gmsay("Scaling NPC ID " . $_[0], 15);
	}
	else{ @ent = $entity_list->GetNPCList(); $ScalingLoaded = 2; }
	foreach $NPC (@ent){ 	
		#:::  Hide Invis NPC Names 
		if(($NPC->GetRace() == 127 || $NPC->GetRace() == 240) && $NPC->GetLevel() < 100 && $NPC->GetNPCTypeID() > 1000){ if($NPC->GetCleanName()=~/shadowed/i){} else{ $NPC->TempName(""); $NPC->ModifyNPCStat("special_attacks", "AZ"); } }
		
		if($NPC->GetEntityVariable("Scaled") != 1){
			#Static NPC Scaling
			$n_name = $NPC->GetCleanName(); $n_name =~ tr/ /_/;
			if($N_SD{$n_name}[0]){  ScaleNPCStatic($NPC, $n_name);  }
		}
		#:::  SCALING
		#$NPC->Say("Scaling...");
		if($NPC->GetPetSpellID() == 0 && $NPC->GetRace() != 127 && $NPC->GetRace() != 240 && $NPC->GetClass() < 20 && $NPC->GetNPCTypeID() > 1000 && $NPC->GetEntityVariable("Scaled") != 1){

			
			$NTYPE = 0; $NN = "NPC";
			if(substr($NPC->GetName(), 0, 1) eq "#" && substr($NPC->GetName(), 1, 2) ne "#"){ $NTYPE = 1; $NN = "Named"; } 
			if(substr($NPC->GetName(), 0, 2) eq "##" && substr($NPC->GetName(), 2, 3) ne "#"){ $NTYPE = 2; $NN = "Raid"; }
			
			$NPC->ModifyNPCStat("max_hp", $SD[$NPC->GetLevel()][$NTYPE][2] * $SZD{$zonesn}[$instanceversion][$NTYPE][2]);
			$NPC->ModifyNPCStat("max_mana", $SD[$NPC->GetLevel()][$NTYPE][3]  * $SZD{$zonesn}[$instanceversion][$NTYPE][3]);
			$NPC->ModifyNPCStat("min_hit", $SD[$NPC->GetLevel()][$NTYPE][4] *  $SZD{$zonesn}[$instanceversion][$NTYPE][4]);
			$NPC->ModifyNPCStat("max_hit", $SD[$NPC->GetLevel()][$NTYPE][5] *  $SZD{$zonesn}[$instanceversion][$NTYPE][5]);
			$NPC->ModifyNPCStat("attack_speed", $SD[$NPC->GetLevel()][$NTYPE][6] *  $SZD{$zonesn}[$instanceversion][$NTYPE][6]);
			$NPC->ModifyNPCStat("ac", $SD[$NPC->GetLevel()][$NTYPE][7] *  $SZD{$zonesn}[$instanceversion][$NTYPE][7]);
			$NPC->ModifyNPCStat("str", $SD[$NPC->GetLevel()][$NTYPE][8]);
			$NPC->ModifyNPCStat("sta", $SD[$NPC->GetLevel()][$NTYPE][9]);
			$NPC->ModifyNPCStat("dex", $SD[$NPC->GetLevel()][$NTYPE][10]);
			$NPC->ModifyNPCStat("agi", $SD[$NPC->GetLevel()][$NTYPE][11]);
			$NPC->ModifyNPCStat("int", $SD[$NPC->GetLevel()][$NTYPE][12]);
			$NPC->ModifyNPCStat("wis", $SD[$NPC->GetLevel()][$NTYPE][13]);
			$NPC->ModifyNPCStat("cha", $SD[$NPC->GetLevel()][$NTYPE][14]);
			$NPC->ModifyNPCStat("mr", $SD[$NPC->GetLevel()][$NTYPE][15]);
			$NPC->ModifyNPCStat("cr", $SD[$NPC->GetLevel()][$NTYPE][16]);
			$NPC->ModifyNPCStat("dr", $SD[$NPC->GetLevel()][$NTYPE][17]);
			$NPC->ModifyNPCStat("fr", $SD[$NPC->GetLevel()][$NTYPE][18]);
			$NPC->ModifyNPCStat("pr", $SD[$NPC->GetLevel()][$NTYPE][19]);
			$NPC->ModifyNPCStat("accuracy", 100);
			if($SZD{$zonesn}[$instanceversion][$NTYPE][13]){ 
				$NPC->ModifyNPCStat("accuracy", $SZD{$zonesn}[$instanceversion][$NTYPE][13]); 
			}
			
			if($Debug){
				$NPC->SetEntityVariable("max_hp", $SD[$NPC->GetLevel()][$NTYPE][2] * $SZD{$zonesn}[$instanceversion][$NTYPE][2]);
				$NPC->SetEntityVariable("max_mana", $SD[$NPC->GetLevel()][$NTYPE][3]  * $SZD{$zonesn}[$instanceversion][$NTYPE][3]);
				$NPC->SetEntityVariable("min_hit", $SD[$NPC->GetLevel()][$NTYPE][4] *  $SZD{$zonesn}[$instanceversion][$NTYPE][4]);
				$NPC->SetEntityVariable("max_hit", $SD[$NPC->GetLevel()][$NTYPE][5] *  $SZD{$zonesn}[$instanceversion][$NTYPE][5]);
				$NPC->SetEntityVariable("attack_speed", $SD[$NPC->GetLevel()][$NTYPE][6] *  $SZD{$zonesn}[$instanceversion][$NTYPE][6]);
				$NPC->SetEntityVariable("ac", $SD[$NPC->GetLevel()][$NTYPE][7] *  $SZD{$zonesn}[$instanceversion][$NTYPE][7]);
				$NPC->SetEntityVariable("str", $SD[$NPC->GetLevel()][$NTYPE][8]);
				$NPC->SetEntityVariable("sta", $SD[$NPC->GetLevel()][$NTYPE][9]);
				$NPC->SetEntityVariable("dex", $SD[$NPC->GetLevel()][$NTYPE][10]);
				$NPC->SetEntityVariable("agi", $SD[$NPC->GetLevel()][$NTYPE][11]);
				$NPC->SetEntityVariable("int", $SD[$NPC->GetLevel()][$NTYPE][12]);
				$NPC->SetEntityVariable("wis", $SD[$NPC->GetLevel()][$NTYPE][13]);
				$NPC->SetEntityVariable("cha", $SD[$NPC->GetLevel()][$NTYPE][14]);
				$NPC->SetEntityVariable("mr", $SD[$NPC->GetLevel()][$NTYPE][15]);
				$NPC->SetEntityVariable("cr", $SD[$NPC->GetLevel()][$NTYPE][16]);
				$NPC->SetEntityVariable("dr", $SD[$NPC->GetLevel()][$NTYPE][17]);
				$NPC->SetEntityVariable("fr", $SD[$NPC->GetLevel()][$NTYPE][18]);
				$NPC->SetEntityVariable("pr", $SD[$NPC->GetLevel()][$NTYPE][19]);
				if($SZD{$zonesn}[$instanceversion][$NTYPE][13]){ 
					$NPC->SetEntityVariable("accuracy", $SZD{$zonesn}[$instanceversion][$NTYPE][13]); 
				}
			}
			
			#:::  Is there a static zone entry?
			if($SZD{$zonesn}[$instanceversion][$NTYPE][11] != 1){
				$NPC->ModifyNPCStat("special_attacks", $SZD{$zonesn}[$instanceversion][$NTYPE][11]);
			}else{
				$NPC->ModifyNPCStat("special_attacks", $SD[$NPC->GetLevel()][$NTYPE][21]);
			}
			$NPC->ModifyNPCStat("hp_regen", $SD[$NPC->GetLevel()][$NTYPE][20]  *  $SZD{$zonesn}[$instanceversion][$NTYPE][10]);
			$NPC->SetEntityVariable("hpregen", $SD[$NPC->GetLevel()][$NTYPE][20]  *  $SZD{$zonesn}[$instanceversion][$NTYPE][10]);
			$NPC->ModifyNPCStat("spellscale", $SD[$NPC->GetLevel()][$NTYPE][22]  *  $SZD{$zonesn}[$instanceversion][$NTYPE][9]);
			$NPC->ModifyNPCStat("healscale", $SD[$NPC->GetLevel()][$NTYPE][23]  *  $SZD{$zonesn}[$instanceversion][$NTYPE][8]);
			
			$LID = (200000 + ($NTYPE * 1000) + $NPC->GetLevel());
			if($NPC->GetLoottableID() != $LID){
				$NPC->ModifyNPCStat("loottable_id", (210000 + ($NTYPE * 1000) + $NPC->GetLevel())); $NPC->AddLootTable();
				$NPC->ModifyNPCStat("loottable_id", (200000 + ($NTYPE * 1000) + $NPC->GetLevel())); $NPC->AddLootTable();  
			}
			$NPC->SetHP($NPC->GetMaxHP());
			$NPC->SetEntityVariable("Scaled", 1); if($Debug){ $NPC->SetEntityVariable("ScaledType", 1); } 
			
			if($Debug){
				quest::gmsay("Scaling $pop $NN [" . $NPC->GetCleanName() . "] 
					HP:[". $SD[$NPC->GetLevel()][$NTYPE][2] * $SZD{$zonesn}[$instanceversion][$NTYPE][2] . "]
					hp_regen:[". ($SD[$NPC->GetLevel()][$NTYPE][20]  *  $SZD{$zonesn}[$instanceversion][$NTYPE][10]) . "]
					min_hit:[". ($SD[$NPC->GetLevel()][$NTYPE][4] *  $SZD{$zonesn}[$instanceversion][$NTYPE][4]) . "]
					max_hit:[".( $SD[$NPC->GetLevel()][$NTYPE][5] *  $SZD{$zonesn}[$instanceversion][$NTYPE][5]) . "]
					spec:[". $SD[$NPC->GetLevel()][$NTYPE][21] . "] 
					NTYPE:[". $NTYPE . "] 
					", 15);
			}
			
			if(!$SD[$NPC->GetLevel()][$NTYPE][0]){ quest::gmsay($NPC->GetCleanName() . ": ERROR! Missing Scaling Entry! For level " . $NPC->GetLevel() . " Type: $NTYPE", 13); }
		}
		# Level 255 NPC's are considered quest NPC's and shall not be attacked #
		if($NPC->GetLevel() == 255){ $NPC->ModifyNPCStat("special_attacks", "AHGZ"); $NPC->SetEntityVariable("max_hp", 100000); } 
	}
	if($ScalingLoaded == 2){ $ScalingLoaded = 3; }
}

sub LoadScaling{
	$connect = plugin::LoadMysql();
	$query = "SELECT
		cust_npc_scaling.level,
		cust_npc_scaling.type,
		cust_npc_scaling.hp,
		cust_npc_scaling.mana,
		cust_npc_scaling.mindmg,
		cust_npc_scaling.maxdmg,
		cust_npc_scaling.attack_speed,
		cust_npc_scaling.AC,
		cust_npc_scaling.STR,
		cust_npc_scaling.STA,
		cust_npc_scaling.DEX,
		cust_npc_scaling.AGI,
		cust_npc_scaling._INT,
		cust_npc_scaling.WIS,
		cust_npc_scaling.CHA,
		cust_npc_scaling.MR,
		cust_npc_scaling.CR,
		cust_npc_scaling.DR,
		cust_npc_scaling.FR,
		cust_npc_scaling.PR,
		cust_npc_scaling.hp_regen,
		cust_npc_scaling.npcspecialattks,
		cust_npc_scaling.spellscale,
		cust_npc_scaling.healscale
		FROM
		cust_npc_scaling
		ORDER BY cust_npc_scaling.level, cust_npc_scaling.type";
	$query_handle = $connect->prepare($query);
	$query_handle->execute();
	$NTYPE = 0;
	while (@row = $query_handle->fetchrow_array()){ $SD[$row[0]][$row[1]] = [@row]; }
}

sub LoadStaticZoneScaling{
	#:::  Load Static Zone Scaling Data #:::  
	$connect = plugin::LoadMysql();
	#:::  Default empty values to 1
	for($i = 2; $i < 17; $i++){ 
		for($t = 0; $t < 3; $t++){
			if(!$SZD{$zonesn}[$instanceversion][$t][$i] || $SZD{$zonesn}[$instanceversion][$t][$i] == 0){ 
				$SZD{$zonesn}[$instanceversion][$t][$i] = 1; 
			}
		}
	} 
	
	$query = "SELECT `zonesn`, `version`, `hp`, `mana`, `mindmg`, `maxdmg`, `attack_speed`, `ac`, `healscale`, `spellscale`, `hpregen`, `specialattacks`, `type`, `accuracy` FROM `cust_npc_zonescale_static` WHERE `zonesn` = '" . $zonesn . "'"; $query_handle = $connect->prepare($query); $query_handle->execute(); my @SZD;
	while (@row = $query_handle->fetchrow_array()){ 
		$SZD{$row[0]}[$row[1]][$row[12]] = [@row];  
		if($SZD{$zonesn}[$instanceversion][0]){
			$Mod = $SZD{$zonesn}[$instanceversion][2]; $npc->SetEntityVariable("ScaleMod", $Mod);
			quest::gmsay("[Zonecontroller] (Static Data) [Type] : " . $row[12] . " Zone Data: HP=" . ($SZD{$zonesn}[$instanceversion][$row[12]][2] * 100) . "(%%) Mana=" . ($SZD{$zonesn}[$instanceversion][$row[12]][3] * 100) . "(%%) MINDMG=" . ($SZD{$zonesn}[$instanceversion][$row[12]][4] * 100) . "(%%) MAXDMG=" . ($SZD{$zonesn}[$instanceversion][$row[12]][5] * 100) . "(%%) ATK_SPD=" . ($SZD{$zonesn}[$instanceversion][$row[12]][6] * 100) . "(%%) AC=" . ($SZD{$zonesn}[$instanceversion][$row[12]][7] * 100) . "(%%) SPELLSCALE=" . ($SZD{$zonesn}[$instanceversion][$row[12]][8] * 100) . "(%%) HEALSCALE=" . ($SZD{$zonesn}[$instanceversion][$row[12]][9] * 100) . "(%%) HPREGEN=" . ($SZD{$zonesn}[$instanceversion][$row[12]][10] * 100) . "(%%)", 15);
			
		}
	}
}

sub LoadStaticNPCScaling{
	$connect = plugin::LoadMysql();
	$query = "SELECT
		cust_npc_scale_static.`name`,
		cust_npc_scale_static.zonesn,
		cust_npc_scale_static.hp,
		cust_npc_scale_static.mana,
		cust_npc_scale_static.mindmg,
		cust_npc_scale_static.maxdmg,
		cust_npc_scale_static.attack_speed,
		cust_npc_scale_static.AC,
		cust_npc_scale_static.STR,
		cust_npc_scale_static.STA,
		cust_npc_scale_static.DEX,
		cust_npc_scale_static.AGI,
		cust_npc_scale_static._INT,
		cust_npc_scale_static.WIS,
		cust_npc_scale_static.CHA,
		cust_npc_scale_static.MR,
		cust_npc_scale_static.CR,
		cust_npc_scale_static.DR,
		cust_npc_scale_static.FR,
		cust_npc_scale_static.PR,
		cust_npc_scale_static.hp_regen,
		cust_npc_scale_static.spellscale,
		cust_npc_scale_static.healscale,
		cust_npc_scale_static.npcspecialattks,
		cust_npc_scale_static.usediabloloot,
		cust_npc_scale_static.localloottable
		FROM
		cust_npc_scale_static
		WHERE cust_npc_scale_static.zonesn = '" . $_[0] . "' OR cust_npc_scale_static.zonesn = 'global'";
	$query_handle = $connect->prepare($query);
	$query_handle->execute();
	$NTYPE = 0;
	while (@row = $query_handle->fetchrow_array()){ $N_SD{$row[0]} = [@row]; quest::gmsay("[Zonecontroller]: Loading static NPC data for NPC: '" . $row[0] ."'", 15); }
}


sub ScaleNPCStatic{
	my $SS = $_[0];
	quest::shout("Found data for NPC " . $SS->GetCleanName() . ' - ' . $_[1]);
	$NTYPE = 0; $NN = "NPC";
	if(substr($SS->GetName(), 0, 1) eq "#" && substr($SS->GetName(), 1, 2) ne "#"){ $NTYPE = 1; $NN = "Named"; }
	if(substr($SS->GetName(), 0, 2) eq "##" && substr($SS->GetName(), 2, 3) ne "#"){ $NTYPE = 2; $NN = "Raid"; }

	$SS->ModifyNPCStat("max_hp", $N_SD{$_[1]}[2]);
	$SS->ModifyNPCStat("max_mana", $N_SD{$_[1]}[3]);
	$SS->ModifyNPCStat("min_hit", $N_SD{$_[1]}[4]);
	$SS->ModifyNPCStat("max_hit", $N_SD{$_[1]}[5]);
	$SS->ModifyNPCStat("attack_speed", $N_SD{$_[1]}[6]);
	$SS->ModifyNPCStat("ac", $N_SD{$_[1]}[7]);
	$SS->ModifyNPCStat("str", $N_SD{$_[1]}[8]);
	$SS->ModifyNPCStat("sta", $N_SD{$_[1]}[9]);
	$SS->ModifyNPCStat("dex", $N_SD{$_[1]}[10]);
	$SS->ModifyNPCStat("agi", $N_SD{$_[1]}[11]);
	$SS->ModifyNPCStat("int", $N_SD{$_[1]}[12]);
	$SS->ModifyNPCStat("wis", $N_SD{$_[1]}[13]);
	$SS->ModifyNPCStat("cha", $N_SD{$_[1]}[14]);
	$SS->ModifyNPCStat("mr", $N_SD{$_[1]}[15]);
	$SS->ModifyNPCStat("cr", $N_SD{$_[1]}[16]);
	$SS->ModifyNPCStat("dr", $N_SD{$_[1]}[17]);
	$SS->ModifyNPCStat("fr", $N_SD{$_[1]}[18]);
	$SS->ModifyNPCStat("pr", $N_SD{$_[1]}[19]);
	$SS->ModifyNPCStat("hp_regen", $N_SD{$_[1]}[20]);
	$SS->ModifyNPCStat("spellscale", $N_SD{$_[1]}[21]);
	$SS->ModifyNPCStat("healscale", $N_SD{$_[1]}[22]);
	$SS->ModifyNPCStat("special_attacks", $N_SD{$_[1]}[23]);
	
	if($N_SD{$_[1]}[24] == 1){ #:::  Tells Static Entry to use Diablo Loot
		$LID = (200000 + ($NTYPE * 1000) + $SS->GetLevel());
		if($SS->GetLoottableID() != $LID){
			$SS->ModifyNPCStat("loottable_id", (210000 + ($NTYPE * 1000) + $SS->GetLevel())); $SS->AddLootTable();
			$SS->ModifyNPCStat("loottable_id", (200000 + ($NTYPE * 1000) + $SS->GetLevel())); $SS->AddLootTable();  
		}
	}
	
	if($N_SD{$_[1]}[25] > 0){ #:::  Add an additional Loot table
		$SS->ModifyNPCStat("loottable_id", $N_SD{$_[1]}[25]); $SS->AddLootTable();  
	}
	
	$SS->SetEntityVariable("Scaled", 1); if($Debug){ $SS->SetEntityVariable("ScaledType", 2); }
}


sub RandomRange {

	my $MinRandom = $_[0];
	my $MaxRandom = $_[1];

	my $RandomResult = int(rand(($MaxRandom + 1) - $MinRandom)) + $MinRandom;
	if ($RandomResult > $MaxRandom)
	{
		return $MaxRandom;
	}
	return $RandomResult;

}
Reply With Quote