EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Completed (https://www.eqemulator.org/forums/forumdisplay.php?f=633)
-   -   Easy to use Tiered Item Generator (https://www.eqemulator.org/forums/showthread.php?t=43601)

NatedogEZ 03-17-2022 03:50 PM

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;
}

https://img001.prntscr.com/file/img0...xOpDJ6NdTg.png

Example image of an earring with 3000 ranks

theoneptd 04-17-2022 11:51 PM

Using the pre-compiled download, how are you able to let the system recognize those high heal and spell damage amounts. I did some testing and changed the rule_values for the Character:ItemHealAmtCap and it appears to stop at a certain amount.

Jahosphat 09-02-2022 10:43 AM

By the way.. This is rad. Thank You.
I did notice that Strike through once generated keeps getting more negative.

Fridgecritter 03-06-2023 11:04 AM

Modified for player hand-ins?
 
I am curious if this could be tied to a quest turn-in snippet check, and give stats to players who do a collection quest and hand it in to upgrade their armor.


All times are GMT -4. The time now is 12:44 AM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.