View Single Post
  #1  
Old 03-17-2022, 03:50 PM
NatedogEZ's Avatar
NatedogEZ
Developer
 
Join Date: Dec 2012
Posts: 515
Default Easy to use Tiered Item Generator

Assign this script to an in-game NPC and hand them the item you want to turn into a tiered item.

It will keep its base stats and increase the all the values listed in the script by the assigned amount. Hailing the NPC will you give you a popup of what the current scale is for the NPC.

If you tell the npc "hp 1" it will increase the scale for HP or "hp -1" reduce scale by 1. The stat must match the hash value so.. "heroic_str 5" would increase the scale of heroic_str by 5.. or just alter the values in the script and do a #rq ... whichever way you prefer!

This is a script for GMs so you must have #gm on to hand in items and talk to this NPC.

(Max ranks for roman numerals is 3999 so be aware!)

Code:
use POSIX;


###################################################################
###################################################################
#####################Author: Natedog###############################
###################################################################
###################################################################

my $number_of_tiers = 101; #10== 0-9   101 == 1-100
my $naming = "roman"; #roman / decimal
					  #IV V  / +4 +5
					  
###################################################################
#these must match the database heroic_str ect...
#### EXAMPLE .1  would mean stat increases by 1 every 10 tiers 
#### EXAMPLE .01 would mean stat increases by 1 every 100 tiers
###################################################################
my %stat_types = (
	#HEROIC STATS
	"heroic_str" 	=> .1, #How much they increase by.. per turn in~
	"heroic_sta" 	=> .1,
	"heroic_dex" 	=> .1,
	"heroic_agi" 	=> .1,
	"heroic_int" 	=> .1,
	"heroic_wis" 	=> .1,
	"heroic_cha" 	=> .1,
	#AC \ HP \ MANA
	"ac"		 	=> 2,
	"hp"		 	=> 150,
	"mana"		 	=> 150,
	"endur"		 	=> 150,
	#DAMAGE \ HASTE
	"damage" 	 	=> .5, #Non-weapons it will not increase (items without damage already)
	"haste" 	 	=> .5,
	#BASIC STATS
	"astr" 	 	 	=> .2,
	"asta" 	 	 	=> .2,
	"aagi" 	 	 	=> .2,
	"adex" 	 	 	=> .2,
	"aint" 	 	 	=> .2,
	"awis" 	 	 	=> .2,
	"acha" 	 	 	=> .2,
	#MOD2 STATS
	"spelldmg"	 	=> 5,
	"healamt"	 	=> 5,
	"regen"		 	=> .5,
	"manaregen"	 	=> .5,
	"enduranceregen"=> .5,
	"damageshield"  => .4,
	"shielding"		=> .01,
	"strikethrough" => .1,
	"clairvoyance"  => .1,
	"dsmitigation"  => .1,
	"dotshielding"  => .1,
	"stunresist"    => .1,
	"avoidance"     => .1,
	"accuracy"      => .1,
	#RESISTS
	"pr" 			=> .1,
	"mr" 			=> .1,
	"dr" 			=> .1,
	"fr" 			=> .1,
	"cr" 			=> .1,
	"svcorruption"  => .01,
	"heroic_pr" 	=> .01,
	"heroic_mr" 	=> .01,
	"heroic_dr" 	=> .01,
	"heroic_fr" 	=> .01,
	"heroic_cr" 	=> .01,
  "heroic_svcorrup" => .01,
);
#####################################################################
#####################################################################
## These can be lowered but some are already at their max so be aware
#####################################################################
#####################################################################
my $weapon_damage_cap = 5000; #Not the cap.. but allows you to keep things from going too high
my $haste_item_cap = 300; #Not the cap.. but allows you to keep things from going too high
my $ac_item_cap = 25000;	#Not the cap.. but allows you to keep things from going too high
my $heroic_stat_cap = 127; #This cant go over 127.. but you can lower it if you don't want insane items..
my $basic_stat_cap = 127; #127 is cap.. but can lower as well
my $hp_mana_cap = 2000000; #No idea on cap.. but use common sense!
my $spell_heal_cap = 32767; #32767 cap i think? but lower if you wish
my $dmgshield_cap = 32767; #Cap? lower if you wish
my $regen_cap = 32767; #Cap? lower if you wish
my $av_ac_stun_strike_cap = 127;

###################################################################
#DO NOT EDIT BELOW HERE
###################################################################
sub EVENT_SAY { 
	if(!$array_fields[0]) {
		LoadData();
	}
	
	if (!$client->GetGM()) {
		$client->Message(315, "You must be a GM to access me!");
		return;
	}
	
	if($text=~/Hail/i) {
		quest::whisper("Hand me an item to create multiple tiers of it.");
		$client->Message(335, "CURRENT SCALE");
		foreach my $t (sort keys %stat_types) {
			$client->Message(335,quest::saylink("$t -10", 1, "10 ") . quest::saylink("$t -5", 1, "5 ") . quest::saylink("$t -1", 1, "1") . " - $t: " . ($stat_types{$t} + $npc->GetEntityVariable("$t")) . " + " . quest::saylink("$t 1", 1, "1 ") . quest::saylink("$t 5", 1, "5 ") . quest::saylink("$t 10", 1, "10 "));
			$$t = ($stat_types{$t} + $npc->GetEntityVariable("$t"));
		}
		Item_Popup();
	} else {
		$text = lc($text);
		my @args = split(" ", $text);
		if (exists($stat_types{$args[0]})) {
			$npc->SetEntityVariable("$args[0]", ($npc->GetEntityVariable("$args[0]") + $args[1]));
			foreach my $t (sort keys %stat_types) {
				$$t = ($stat_types{$t} + $npc->GetEntityVariable("$t"));
			}
			Item_Popup();
		}
	}
}

sub Item_Popup {
	my $ptext = 	"<table>
					<tr><td>{y}LIFE~</td></tr>
					<tr><td>AC: $ac</td></tr>
					<tr><td>HP: $hp</td></tr>
					<tr><td>MANA: $mana</td></tr>
					<tr><td>ENDUR: $endur</td></tr>
					</table>
					<table>
					<tr><td>{y}BASIC STATS~</td><td>{y}HEROIC STATS~</td><td>{y}OTHER~</td></tr>
					<tr><td>STR: $astr</td> <td>H-STR: $heroic_str</td><td>Damage: $damage</td></tr>
					<tr><td>STA: $asta</td> <td>H-STA: $heroic_sta</td><td>Haste: $haste</td></tr>
					<tr><td>INT: $aint</td> <td>H-INT: $heroic_int</td><td>Spelldmg: $spelldmg</td></tr>
					<tr><td>WIS: $awis</td> <td>H-WIS: $heroic_wis</td><td>Healamt: $healamt</td></tr>
					<tr><td>AGI: $aagi</td> <td>H-AGI: $heroic_agi</td><td>Shielding: $shielding</td></tr>
					<tr><td>DEX: $adex</td> <td>H-DEX: $heroic_dex</td><td>Damageshield: $damageshield</td></tr>
					<tr><td>CHA: $acha</td> <td>H-CHA: $heroic_cha</td><td>Strikethrough: $strikethrough</td></tr>
					
					<tr><td>PR: $pr</td> <td>H-PR: $heroic_pr</td><td>Avoidance: $avoidance</td></tr>
					<tr><td>MR: $mr</td> <td>H-MR: $heroic_mr</td><td>Accuracy: $accuracy</td></tr>
					<tr><td>DR: $dr</td> <td>H-DR: $heroic_dr</td><td>Dotshielding: $dotshielding</td></tr>
					<tr><td>FR: $fr</td> <td>H-FR: $heroic_fr</td><td>Clairvoyance: $clairvoyance</td></tr>
					<tr><td>CR: $cr</td> <td>H-CR: $heroic_cr</td><td>dsmitigation: $dsmitigation</td></tr>
					<tr><td>Corr: $svcorruption</td> <td>H-Corr: $heroic_svcorrup</td><td>stunresist: $stunresist</td></tr>
					</table> hiddenresponse";
	$client->DialogueWindow($ptext);
}

sub EVENT_ITEM {
	my $aug_slots_in = AugTypes(@aug_slots_used);
	if(!$array_fields[0]) {
		LoadData();
	}
	
	my $item_count = 0;
	my @turnin = ();
	if ($item1 > 0) { push(@turnin, $item1); $item_count++; }
	if ($item2 > 0) { push(@turnin, $item2); $item_count++; }
	if ($item3 > 0) { push(@turnin, $item3); $item_count++; }
	if ($item4 > 0) { push(@turnin, $item4); $item_count++; }
	
	if ($item_count != 1 || !$client->GetGM()) {  #too many or too little items.. return them...
		plugin::return_items(\%itemcount);
		$client->AddMoneyToPP($copper, $silver, $gold, $platinum, 1); #They fucked up the turnin... give back their money
		$client->Message(335, "That doesn't look correct!");
		return;
	}

	my $dbh = plugin::LoadMysql();
	#get the stats on each of the items given to the NPC
	my $sth = $dbh->prepare( "SELECT * FROM items where id = $turnin[0];");  #This way it won't matter what slot the item is in...
	$sth->execute();
	
	#create variable to store tier (Used for pricing increases)
	my $tier = 0;
	my $client_name = $name;
	
	my @values = $sth->fetchrow_array();
	my $line = "";
	my $current_value = "";
	
	#FOR PRICING~
	my $cost = 0;
	my $heroic_stats = 0;
	my $regular_stats = 0;
	my $ac_hp_mana_stats = 0;
	my $haste_damage_stats = 0;
	my $mod2_stats = 0;
	
	my $item_name_slot = 0;
	my @new_values = ();
	my $multiplier = 0;
	my @combined_values = ();
	
	my $max_item_id = MaxIDSearch("items", "id");
	
	for $imake ( 1 .. $number_of_tiers-1) {
		@new_values = ();
		#$line = "";
		$line .= "\n(";
	
		for $x (0 .. $#array_fields) {
			#$fieldname = $array_fields[$x];
			$current_value = $values[$x]; #~whatever field are on is set here now..
			if (exists $stat_types{$array_fields[$x]}) {
				if ($array_fields[$x]=~/^damage$/i) {
					if ($current_value > 0) {
						$current_value += floor($imake * ($stat_types{$array_fields[$x]} + $npc->GetEntityVariable("$array_fields[$x]"))); #Only increment damage on things that already have damage stat
					}
				} else {
					$current_value += floor($imake * ($stat_types{$array_fields[$x]} + $npc->GetEntityVariable("$array_fields[$x]"))); #increment the stats based on the hash at the top
				}
			}
			
			#DEFAULT VALUES~
			if ($array_fields[$x]=~/^itemtype$/i) {
				#$current_value = 54; #DO NOT CHANGE
			#} elsif ($array_fields[$x]=~/^augtype$/i) {
			#	$current_value = $aug_slots_in;  ##VALUE AT TOP OF SCRIPT DICTATES THIS 1 -30
			} elsif ($array_fields[$x]=~/^name$/i) {
				#$current_value = "$client_name`s Ornamentation";
				$item_name_slot = $x;
			#} elsif ($array_fields[$x]=~/^clickeffect$/i) {
			#	$current_value = -1;
			#} elsif ($array_fields[$x]=~/^clicktype$|^delay$|augslot1type|augslot2type|augslot3type|augslot4type|augslot5type/i) {  ##All these are 0'ed out
			#	$current_value = 0;
			} elsif ($array_fields[$x]=~/^loregroup$/i) {
				#$current_value = 0;
			} elsif ($array_fields[$x]=~/^UNK214$/i) {
				if ($tier <= 0) {
					$current_value = $values[$x] > 0 ? $values[$x] : 0;
					$tier = $current_value;
				} else {
					$current_value = $tier;
				}
				$current_value++; 
				$tier++;
				if ($naming=~/roman/i) {
					$new_values[$item_name_slot] = "$new_values[$item_name_slot] " . decimal_to_roman($imake);
				} else {
					$new_values[$item_name_slot] = "$new_values[$item_name_slot] +" . $imake;
				}
			} elsif ($array_fields[$x]=~/^heroic_str$|^heroic_sta$|^heroic_dex$|^heroic_agi$|^heroic_wis$|^heroic_int$|^heroic_cha$/i) {
				if ($current_value > $heroic_stat_cap) {
					$current_value = $heroic_stat_cap;
				}
				$heroic_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^spelldmg$|^healamt$|^clairvoyance$/i) {
				if ($current_value > $spell_heal_cap) {
					$current_value = $spell_heal_cap;
				}
				$mod2_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^astr$|^asta$|^aagi$|^adex$|^awis$|^aint$|^acha$|^pr$|^mr$|^dr$|^fr$|^cr$|^svcorruption$|^heroic_pr$|^heroic_mr$|^heroic_dr$|^heroic_fr$|^heroic_cr$|^heroic_svcorrup$/i) {
				if ($current_value > $basic_stat_cap) {
					$current_value = $basic_stat_cap;
				}
				$regular_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^hp$|^mana$/i) {
				if ($current_value > $hp_mana_cap) {
					$current_value = $hp_mana_cap;
				}
				$ac_hp_mana_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^ac$/i) {
				if ($current_value > $ac_item_cap) {
					$current_value = $ac_item_cap;
				}
				$ac_hp_mana_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^damage$/i) {
				if ($current_value > $weapon_damage_cap) { #Cap aug weapon damage.. 
					$current_value = $weapon_damage_cap;
				}
				$weapon_damage_array_slot = $x;
				$haste_damage_stats+= $current_value;
			} elsif ($array_fields[$x]=~/^haste$/i) {
				if ($current_value > $haste_item_cap) {
					$current_value = $haste_item_cap;
				}
				$haste_damage_stats+= $current_value;
			} elsif ($array_fields[$x]=~/^damageshield$/i) {
				if ($current_value > $dmgshield_cap) {
					$current_value = $dmgshield_cap;
				}
				$mod2_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^regen$|^manaregen$/i) {
				if ($current_value > $regen_cap) {
					$current_value = $regen_cap;
				}
				$mod2_stats+=$current_value;
			} elsif ($array_fields[$x]=~/^avoidance$|^accuracy$|^stunresist$|^strikethrough$|^shielding$/i) {
				if ($current_value > $av_ac_stun_strike_cap) {
					$current_value = $av_ac_stun_strike_cap;
				}
			} elsif ($array_fields[$x]=~/^id$/i) {
				$max_item_id++;
				$current_value = $max_item_id;
			}
	
				
			$line .= "?, ";
			push(@new_values, trim($current_value));
		}
		$line = substr($line, 0, -2);
		$line .= "), ";
		
		push(@combined_values, @new_values);
	}
	$line = substr($line, 0, -2);
	my $master_item_insert = "INSERT INTO `items` (" . join(",", @array_fields_tilde) . ") VALUES $line";
	$dbh->prepare($master_item_insert)->execute(@combined_values);
	
	quest::whisper("Items created");
}

sub MaxIDSearch {
	my $dbh = plugin::LoadMysql();
	my $table = shift;
	my $field = shift;
	my $max_search = "SELECT max($field) FROM $table";
	$sth = $dbh->prepare($max_search);
	$sth->execute();
	return $sth->fetchrow_array();
}

sub trim($) {
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;
}

sub AugTypes {
	my @types = @_;
	my %aug_values = (
		1  => 1,
		2  => 2,
		3  => 4,
		4  => 8,
		5  => 16,
		6  => 32,
		7  => 64,
		8  => 128,
		9  => 256,
		10 => 512,
		11 => 1024,
		12 => 2048,
		13 => 4096,
		14 => 8192,
		15 => 16384,
		16 => 32768,
		17 => 65536,
		18 => 131072,
		19 => 262144,
		20 => 524288,
		21 => 1048576,
		22 => 2097152,
		23 => 4194304,
		24 => 8388608,
		25 => 16777216,
		26 => 33554432,
		27 => 67108864,
		28 => 134217728,
		29 => 268435456,
		30 => 536870912
	);
	my $aug_return = 0;
	foreach $t (@types) {
		$aug_return += $aug_values{$t};
	}
	return $aug_return;
}

sub LoadData {
	my $dbh = plugin::LoadMysql();
	my $sth = $dbh->prepare("SHOW COLUMNS FROM items");
	$sth->execute();
	@array_fields = ();
	while (@row = $sth->fetchrow_array()){
		push(@array_fields, "$row[0]");
		push(@array_fields_tilde, "`$row[0]`");
	}
}


sub decimal_to_roman {
	my $decimal = shift;
    my $str = '';

    my (@conversions) = (
        M  => 1000,
        CM => 900,
        D  => 500,
        CD => 400,
        C  => 100,
        XC => 90,
        L  => 50,
        XL => 40,
        X  => 10,
        IX => 9,
        V  => 5,
        IV => 4,
        I  => 1,
    );

    while (@conversions) {
        my $r = shift @conversions;
        my $v = shift @conversions;

        while ( $decimal >= $v ) {
            $decimal -= $v;
            $str .= $r;
        }
    }

    return $str;
}


Example image of an earring with 3000 ranks
Reply With Quote