Loading...   


###########################################################
#::: Akka's Diablo Loot
#::: This script is designed to generate thousands of lootdrop entries to be dynamically assigned on top of an NPC's original loot.
#::: This script is ran pre-server-up once, or as many times as you wish until you feel like you have your loot the way you want it.
#::: This script has been designed to be ran as many times as you wish as it will purge all of the created entries each time you run it, only to create loads of new entries based on the new criteria that you have fed it.
#::: All criteria that this script uses is strictly specified in the table `cust_npc_loot_scale` that is shown below
#::: Example: perl DiabloLoot.pl
###########################################################

if(!$ARGV[0]) { print "Usage create - creates entries, delete - deletes entries, all - does a complete cycle"; }
else{
	use DBI;
	use DBD::mysql;
	my $start_run = time();

	my $Debug = 1;
	
	my $confile = "eqemu_config.xml"; #default
	open(F, "<$confile") or die "Unable to open config: $confile\n";
	my $indb = 0;
	while(<F>) {
		s/\r//g;
		if(/<database>/i) { $indb = 1; }
		next unless($indb == 1);
		if(/<\/database>/i) { $indb = 0; last; }
		if(/<host>(.*)<\/host>/i) { $host = $1; } 
		elsif(/<username>(.*)<\/username>/i) { $user = $1; } 
		elsif(/<password>(.*)<\/password>/i) { $pass = $1; } 
		elsif(/<db>(.*)<\/db>/i) { $db = $1; }
	}

	# PERL DBI CONNECT
	$dsn = "dbi:mysql:$db:localhost:3306";
	if(!$connect){ $connect = DBI->connect($dsn, $user, $pass); }
	if(!$connect2){ $connect2 = DBI->connect($dsn, $user, $pass); }
	#####################################################

	$n = 0;
	while($ARGV[$n]){ if($ARGV[$n] eq "debug"){ $Debug = " " ; } else{ $Debug = ""; } $n++; }

	#::: Script Options :::#
	$MaxLevel = 110;
	$BaseLoottableID = 200000;
	$BaseLoottableIDAugs = 210000;
	$TypeMultiplier = 1000;
	$GenName = "Akkas_Diablo_Loot";
	$GenNameAugs = "Akkas_Diablo_Loot_Augs";

	####################
	
	###  Load Loot Definitions into Memory so it can be quickly iterated through
	print "Loading Loot Definitions...";
	$query_handle = $connect->prepare("SELECT level, type, hp_min, hp_max, drop_chance, loottable_multiplier, min_plat, max_plat, aug_hp_min, aug_hp_max, aug_ac_max, aug_drop_chance, aug_drop_multiplier FROM `cust_npc_loot_scale` ORDER BY `type`, `level`"); $query_handle->execute();
	while(@row = $query_handle->fetchrow_array()){ $LootDefs[$row[0]][$row[1]] = [@row]; }
	print " Done\n\n";
	
	if($ARGV[0] eq "delete" || $ARGV[0] eq "all"){
		for($i = 0; $i <= 1; $i++){
			if($i == 0){ $ID = $BaseLoottableID; $LT = "'General Loot'"; }
			elsif($i == 1) { $ID = $BaseLoottableIDAugs; $LT = "'Aug Loot'"; }
			print "Creating Loot Table ID's\n" if $Debug;
			$query = "DELETE FROM `lootdrop_entries` WHERE `lootdrop_id` >= " . $ID . " AND `lootdrop_id` <= " . ($ID + 3000) . ";";	
			$query_handle = $connect->prepare($query);
			my $row = $query_handle->execute(); if($row eq "0E0"){ $row = 0; }
			print "Purging Diablo lootdrop_entries... " . $LT . " rows affected ". $row . "\n"; 
			
			$query = "DELETE FROM `lootdrop` WHERE `id` >= " . $ID . " AND `id` <= " . ($ID + 3000) . ";";	
			$query_handle = $connect->prepare($query);
			my $row = $query_handle->execute(); if($row eq "0E0"){ $row = 0; }
			print "Purging Diablo lootdrop... " . $LT . " rows affected ". $row . "\n"; 
			
			$query = "DELETE FROM `loottable_entries` WHERE `lootdrop_id` >= " . $ID . " AND `lootdrop_id` <= " . ($ID + 3000) . ";";	
			$query_handle = $connect->prepare($query);
			my $row = $query_handle->execute(); if($row eq "0E0"){ $row = 0; }
			print "Purging Diablo loottable_entries... " . $LT . " rows affected ". $row . "\n"; 
			
			$query = "DELETE FROM `loottable` WHERE `id` >= " . $ID . " AND `id` <= " . ($ID + 3000) . ";";	
			$query_handle = $connect->prepare($query);
			my $row = $query_handle->execute(); if($row eq "0E0"){ $row = 0; }
			print "Purging Diablo loottable... " . $LT . " rows affected ". $row . "\n"; 
			
		}
		if($ARGV[0] eq "delete"){ return; }
	}

	if($ARGV[0] eq "create" || $ARGV[0] eq "all"){
		print "Creating Loot Table ID's\n" if $Debug;
		for($t = 0; $t <= 2; $t++){
			for($i = 1; $i < $MaxLevel; $i++){
			
				### Create General Loot Tables ###
				$ID = ($BaseLoottableID + ($TypeMultiplier * $t) + $i);
				$query_handle = $connect->prepare("REPLACE INTO `loottable` (id, name, mincash, maxcash, avgcoin) VALUES (?, ?, ?, ?, ?)"); 
				$query_handle->execute($ID, $ID . "_" . $GenName, ($LootDefs[$i][$t][6] * 1000),($LootDefs[$i][$t][7] * 1000), 0);
				$query_handle = $connect->prepare("REPLACE INTO `lootdrop` (id, name) VALUES (?, ?)"); 
				$query_handle->execute($ID, $ID . "_" . $GenName);
				$query_handle = $connect->prepare("REPLACE INTO `loottable_entries` (loottable_id, lootdrop_id, multiplier, droplimit, mindrop, probability) VALUES (?, ?, ?, ?, ?, ?)"); 
				$query_handle->execute($ID, $ID, $LootDefs[$i][$t][5], 1, 0, 100);
				#sprint $LootDefs[$i][$t][5] . "\n";
				
				### Create Augment Tables ###
				$ID = ($BaseLoottableIDAugs + ($TypeMultiplier * $t) + $i);
				$query_handle = $connect->prepare("REPLACE INTO `loottable` (id, name, mincash, maxcash, avgcoin) VALUES (?, ?, ?, ?, ?)"); 
				$query_handle->execute($ID, $ID . "_" . $GenNameAugs, 0, 0, 0);
				$query_handle = $connect->prepare("REPLACE INTO `lootdrop` (id, name) VALUES (?, ?)"); 
				$query_handle->execute($ID, $ID . "_" . $GenNameAugs);
				$query_handle = $connect->prepare("REPLACE INTO `loottable_entries` (loottable_id, lootdrop_id, multiplier, droplimit, mindrop, probability) VALUES (?, ?, ?, ?, ?, ?)"); 
				$query_handle->execute($ID, $ID, $LootDefs[$i][$t][12], 1, 0, 100);
			}
		}
		if($ARGV[0] eq "create"){ return; }
	}
	
	$query_handle = $connect->prepare("SELECT
		items.id,
		items.minstatus,
		items.`Name`,
		items.augtype,
		items.hp,
		items.mana,
		items.ac,
		items.price,
		items.reclevel,
		items.reqlevel,
		items.itemtype
		FROM
		items
		WHERE hp > 0
		AND augtype = 0
		AND minstatus = 0
		AND hp > " . $LootDefs[1][0][3] . "
		ORDER by hp"); $query_handle->execute();
	print "Generating General Loot... Please wait...\n";
	
	$n = 0;
	while(@row = $query_handle->fetchrow_array()){
		my ($id, $MinStatus, $Name, $AugType, $hp, $mana, $ac, $price, $reclevel, $reqlevel, $itemtype) = ($row[0], $row[1], $row[2], $row[3], $row[4], $row[5], $row[6], $row[7], $row[8],  $row[9], $row[10]);
		print "Loop: $n HP: " . $row[4] . " ID: " .  $row[0] . " NAME: " . $row[2] . " "  . "\n" if $Debug;
		
		$TypeCycle = 0;
		while($TypeCycle <= 2){
			$InRange = 0;
			$LevIter = 1;
			while($LevIter < 250){
				$Mult = 1;
				if($itemtype == 1 || $itemtype == 4 || $itemtype == 35){ $Mult = 1.79 } ### We use a multiplier for 2 handed weapons...
				$HPMIN = $LootDefs[$LevIter][$TypeCycle][2] * $Mult;
				$HPMAX = $LootDefs[$LevIter][$TypeCycle][3] * $Mult;
				if($hp > $HPMIN && $hp < $HPMAX){
					print "(($BaseLoottableID + ($TypeMultiplier * $TypeCycle)) + $LevIter);\n" if $Debug;
					$ID = (($BaseLoottableID + ($TypeMultiplier * $TypeCycle)) + $LevIter);
					if($TypeCycle == 1){ print "INSERTING REG - ITEM ID: " . $id . " HP " . $hp . " "  . $ID . " LVL " . $LevIter . " Type " . $TypeCycle . "\n" if $Debug; }
					$query_handle2 = $connect2->prepare("INSERT INTO `lootdrop_entries` (lootdrop_id, item_id, item_charges, equip_item, chance, minlevel, maxlevel, multiplier) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 
					$query_handle2->execute($ID, $id, 1, 1, $LootDefs[$LevIter][$TypeCycle][4], 0, 110, 1);
					$InRange = 1;
				}
				elsif($InRange == 1){ last; }
				$LevIter++;
			}
			#if($TypeCycle > 0){ print $TypeCycle . "\n"; }
			$TypeCycle++;
		}
		$n++;
	}
	
	print "Items Processed: " . $n . "\n";
	
	### Process Augment Items ###
	$query_handle = $connect->prepare("SELECT
		items.id,
		items.minstatus,
		items.`Name`,
		items.augtype,
		items.hp,
		items.mana,
		items.ac,
		items.price,
		items.reclevel,
		items.reqlevel
		FROM
		items
		WHERE hp > 0
		AND augtype > 0
		AND minstatus = 0
		ORDER by hp"); $query_handle->execute();
	print "Generating Augments Loot... Please wait...\n";
	
	while(@row = $query_handle->fetchrow_array()){
		my ($id, $MinStatus, $Name, $AugType, $hp, $mana, $ac, $price, $reclevel, $reqlevel) = ($row[0], $row[1], $row[2], $row[3], $row[4], $row[5], $row[6], $row[7], $row[8],  $row[9]);
		print "Loop: $n HP: " . $row[4] . " ID: " .  $row[0] . " NAME: " . $row[2] . " "  . "\n" if $Debug;
		$TypeCycle = 0;
		while($TypeCycle <= 2){
			$InRange = 0;
			$LevIter = 1;
			while($LevIter < 250){
				### Make sure the definitions fall within the stat ranges specified
				if($hp > $LootDefs[$LevIter][$TypeCycle][8] && $hp < $LootDefs[$LevIter][$TypeCycle][9]){
					$ID = (($BaseLoottableIDAugs + ($TypeMultiplier * $TypeCycle)) + $LevIter);
					$query_handle2 = $connect2->prepare("INSERT INTO `lootdrop_entries` (lootdrop_id, item_id, item_charges, equip_item, chance, minlevel, maxlevel, multiplier) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 
					$query_handle2->execute($ID, $id, 1, 1, $LootDefs[$LevIter][$TypeCycle][11], 0, 110, 1);
					$InRange = 1;
				}
				elsif($InRange == 1){ last; }
				$LevIter++;
			}
			#if($TypeCycle > 0){ print $TypeCycle . "\n"; }
			$TypeCycle++;
		}
		$n++;
	}

	print "\n Loot has been successfully generated\n";
	print "Items Processed: " . $n . "\n";
	
	my $end_run = time();
	my $run_time = $end_run - $start_run;
	print "\n\nJob took $run_time seconds\n";

}

Raw Paste Data