EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development: Custom Code (https://www.eqemulator.org/forums/forumdisplay.php?f=665)
-   -   Bazaar bots (https://www.eqemulator.org/forums/showthread.php?t=32821)

provocating 01-11-2011 02:50 PM

Okay I will start to reference Lucy's to see what is off. Wonder if it was done with a PERL CGI script and if someone still has it ?

Derision 01-11-2011 03:01 PM

I think Cavedude just periodically downloads the items database from 13th floor and imports it into PEQ.

http://eqitems.13th-floor.org/

The item DB (as a delimited text file) is under the downloads link.

provocating 01-11-2011 03:04 PM

I have been visiting their site, but did not notice they had downloads.....cool stuff.

Caryatis 01-11-2011 07:10 PM

Quote:

If all else fails I could rather easily just do this. Set up a spawn point, make that spawn point randomly spawn maybe 10 vendors, each with a 10 percent chance of being spawned. Each vendor has different items. The vendors have player names instead of npc names, makes it more real. Have them do random calls, at random times. This would give an element of randomness. That vendor stays there for an amount of time then despawns at a random time, then it repeats. Do this for maybe 50-100 spawn points would be a start. It is not what I want though. What I actually want are the items randomly generated. As far as getting the items in the database and random items that seems easy with MySQL DBI statements in the vendor Perl file. It is getting that NPC to do the trader things I am getting stuck at.
The idea of an auction bot is attractive to most players, your version of it though I'm not sure(not sure how random items play into an auction bot). While this may be possible using only Perl, I think the more elegant solution is going to involve more C++ than Perl.

Derision only said that currently its not possible for the bazaar code to handle NPCs, without ever having looked at the code I wonder if making it recognize NPCs is not the best way to go in this situation. In this case I think the NPC is little more than visual placeholder, would have to track the items for sale more reliably than in a bag on an NPC.

I envison it more like walking up to a generic NPC and purchasing a place in the bazaar, this would copy the look and name of your character onto that NPC and load any previous items you had for sale into his inventory. Then by giving him items, he writes those to the db and updates his list. Clients can then use the bazaar window to search for items as they would if the player was in zone as well. If it got paired up with the barter window as well, might be able to do the reverse and have roving NPC buyers who buy things for their clients as they are put up for sale.

Without using any c++ I think the best you could do is have the NPCs /auc items, then when players hail the NPC they are given a list of saylinks of the items for sale with prices. If they have enough plat when they click the desired link, it removes the plat from their char, deletes the item from the sellers db and then summons one to their cursor.

provocating 01-11-2011 07:17 PM

Well the best I can do is Perl coding at the moment. I can read some C++ but it is still out of my league. In my case I just want something a little different. Crazy thing I always feel like I am slightly cheating when I use BOTS, I know it is crazy but when I can not even have to cast or send a pet out I feel like I am cheating. Hell I can just make a hotkey with a group of BOTS and the mob is dead. I am not quite sure what I want but I think trying to recreate the bazaar like live is a first step for me.

Akkadius 01-11-2011 07:35 PM

While this is something I have been wanting to get done, it hasn't been at the top of my list like I was saying. Also, it would need player-base time-tweaking over an extended period of time. The reason why I say it would take an extended period of time is because you would want it flexible enough to not only store player trades, but you would also want to be able to classify the items that are being put for auction in a menu so that when you have 20,000 items on an auction/trade system, you will be able to navigate it all without it being utter chaos.

Just to shoot some examples would be to sort by latest posting, the most popularly bought items that are up for post again.

-Maintaining a system of average prices and color coating the messages based on auctions being a good deal or costing more than the average cost of the item.
-You could limit each account or player to a certain amount of items to put up for auction.
-After so long of an item sitting on auction, it either A) Get's returned back to the players inventory B) Threatens to get deleted or C) Goes to a collections bin after so long
-Being able to set rules on your item max/min and your rate for decreasing each day.

And I'm sure there are other features I am missing right now because you have the player base to tell you what should be added to it over time.

I will definitely implement this on my own server, but it may not be as soon as you'd like it.

BrandeX 08-21-2011 11:25 PM

Quote:

Originally Posted by Secrets (Post 195819)
I've been thinking about implementing something like this in perl for a while now.

Wouldn't be *that* hard with perl's DBI module.

Just gotta make a table to store items you hand to an NPC, and then have someone who can buy the items search like they do normally in the bazaar, just with mysql queries in perl instead of C++. Table doesn't have to be complex either; just id, itemid, sellername, price, sold (this will be one or zero.)

Hopefully that lets you brainstorm a bit,

They have seller "bots" on EQTitan server. You hand them items and set a price via # commands. The bots sell them while you are elsewhere or offline, and you collect the cash when you zone in to baz.

provocating 11-28-2011 10:57 AM

Well after months of letting it sit I finally got back on this during the Thanksgiving Holidays.

What I ended up doing is starting with just one NPC. The NPC randomly pulls a small list of items from the item table, based on certain criteria. The items are then loading into him like a vendor would. He randomly yells in the zone with random text and links to what is for sale. I know it is a lot of randomness but I did not want anything to be static. I am thinking having him randomly spawn / despawn and during the respawn the items clear out.

It sounds easy to do all of this, but it has not been super easy for me to do with my lack of coding experience, but it is now done. I had to modify the server code a bit because clearing out the vendors items did not seem to have a built in routine. Also the pricing in the database was an issue as some items had a zero value. I found someone had a post on modifying server pricing and used it. I need to go back through that and critique the pricing.

Now all I have left to do is come up with shouts for zone, then make 30+ of these guys with different names, looks, shouts and behaviors.....tada.....East Commons tunnel is now alive.

provocating 11-28-2011 05:47 PM

So far so good, I am sure it needs tons of tweeking, but he is working.

http://reefcrazed.dyndns.org:82/scre...s/EQ000066.jpg

Furinex 04-15-2012 10:17 AM

You should share this... Im looking for something for solo servers that allows the acquisition of items unattainable solo. This looks like the solution.

provocating 04-15-2012 10:28 AM

Well I have started and stopped multiple times. I did code out some that just sat in East Commons, announced items. Basically they pulled random items out of the database based on type and price. I will definitely share it but keep in mind, I wrote it months ago and never went back and tweaked it out.

It was not so much a "bazaar bot" but East Commons NPC's that pull random items from the items table, set prices and announced. It may not even be what a server admin would want. Some of the things that bothered me was it used Perl DBI and also the fact the config sat in the Perl file. It was not the elegant solution I really wanted so I ditched the idea.

chrsschb 04-15-2012 12:00 PM

By sharing it you allow more experienced coders to fine tune it.

provocating 04-15-2012 12:08 PM

This was one of them in East Commons.

Code:

#Battlestaff Fuzzietoe 22210
INSERT INTO `npc_types` (id, name, lastname, level, race, class, bodytype, hp, mana, gender, texture, helmtexture, size, hp_regen_rate, mana_regen_rate, loottable_id, merchant_id, alt_currency_id, npc_spells_id, npc_faction_id, adventure_template_id, trap_template, mindmg, maxdmg, attack_count, npcspecialattks, aggroradius, face, luclin_hairstyle, luclin_haircolor, luclin_eyecolor, luclin_eyecolor2, luclin_beardcolor, luclin_beard, drakkin_heritage, drakkin_tattoo, drakkin_details, armortint_id, armortint_red, armortint_green, armortint_blue, d_meele_texture1, d_meele_texture2, prim_melee_type, sec_melee_type, runspeed, MR, CR, DR, FR, PR, Corrup, see_invis, see_invis_undead, qglobal, AC, npc_aggro, spawn_limit, attack_speed, findable, STR, STA, DEX, AGI, _INT, WIS, CHA, see_hide, see_improved_hide, trackable, isbot, exclude, ATK, Accuracy, slow_mitigation, version, maxlevel, scalerate, private_corpse, unique_spawn_by_name, underwater) VALUES ('22210', 'Battlestaff_Fuzzietoe', '', '65', '11', '41', '1', '4476', '0', '0', '2', '0', '5', '0', '0', '0', '346724', '0', '0', '0', '0', '0', '54', '110', '-1', '', '70', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '28', '28', '1.25', '9', '9', '9', '9', '9', '9', '0', '0', '0', '614', '0', '0', '-7.37742', '0', '137', '137', '137', '137', '137', '137', '137', '0', '0', '1', '0', '1', '0', '0', '0', '0', '0', '100', '0', '0', '0');
INSERT INTO `spawngroup` (`id`, `name`, `spawn_limit`, `dist`, `max_x`, `min_x`, `max_y`, `min_y`, `delay`) VALUES (200005, 'ecommons_200005', 0, 0, 0, 0, 0, 0, 0);
INSERT INTO `spawn2` (`id`, `spawngroupID`, `zone`, `version`, `x`, `y`, `z`, `heading`, `respawntime`, `variance`, `pathgrid`, `_condition`, `cond_value`, `enabled`, `animation`) VALUES (300005, 200005, 'ecommons', 0, 888.600000, -1056.700000, -3.2, 233.8, 1200, 0, 0, 0, 1, 1, 0);
INSERT INTO `spawnentry` (`spawngroupID`, `npcID`, `chance`) VALUES (200005, 22210, 100);
INSERT INTO `merchantlist` (`merchantid`, `slot`, `item`, `faction_required`, `level_required`, `alt_currency_cost`) VALUES (346724, 1, 13006, -100, 0, 0);

Battlestaff_Fuzzietoe.pl

Code:

#!/usr/bin/perl -w
use DBI;

$db_login='eqemu';
$db_password='pass';
$db_host='127.0.0.1';
$db_database='peq';

# 1 warrior, 2 cleric, 4 paladin, 8 ranger, 16 sk, 32, druid, 64 monk, 128 bard, 256, rogue,
# 512 shaman, 1024 necro, 2048 wiz, 4096 mage, 8192 enchant, 16384 beast, 32768 beserk
$target_class=0;

$min_vendor_count=20;
$max_vendor_count=100;

@random_result_set=();

$size=0;
$announce_time=600; #Random announce time offset.
$reload_items_time=14400; #Random reload time offset. (3600=one hour, 14400=four hours, 86400=one day)
$initial_stock_delay=12; #NPC is not always up on slow loading zones.

$dbh=DBI->connect('DBI:mysql:' . $db_database . ';host=' . $db_host, $db_login, $db_password
                  ) || die "Could not connect to database: $DBI::errstr";

$sth = $dbh->prepare('SELECT id FROM items WHERE nodrop=1 and norent=1 and questitemflag=0 and stacksize=1 AND price>0 AND classes > ' . $target_class );
$sth->execute();
while (@row=$sth->fetchrow_array){
                push (@random_result_set, $row[0]);
        }
$size=@random_result_set;
$vendor_item_count=$min_vendor_count+int(rand($max_vendor_count-$min_vendor_count));

sub EVENT_SPAWN
{
        quest::settimer("initial_stock", $initial_stock_delay);
        quest::settimer("reload_items", int(rand($reload_items_time)+3600)); #Timer for item inventory reload.
        quest::settimer("announce", int(rand($announce_time)+240)); #Random announcements.
}

sub EVENT_TIMER
{
        if($timer eq "initial_stock")
                {
                LOAD_VENDOR();
                quest::stoptimer("initial_stock");       
                }

        if($timer eq "reload_items")
                {
                LOAD_VENDOR();       
                }
               
        if($timer eq "announce")
                {
                        if(@random_result_set>0)
                        {
                                $rand=int(rand(6));
                                    if ($rand==0) {quest::shout(sprintf("%s%s%s%s%s%s%s","New vendor up in the east commons tunnel check these items for sale (" . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                                elsif ($rand==1) {quest::shout(sprintf("%s%s%s%s%s%s%s","Check out my wares just inside the east commons tunnel (" . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                                elsif ($rand==2) {quest::shout(sprintf("%s%s%s%s%s%s%s","Lowest prices in Norath !!!  Check out my " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                                elsif ($rand==3) {quest::shout(sprintf("%s%s%s%s%s%s%s","WTS  " . ANNOUNCE(int(rand($vendor_item_count)+1)) . " and " . ANNOUNCE(int(rand($vendor_item_count)+1)) . " and " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                                elsif ($rand==4) {quest::shout(sprintf("%s%s","Selling  " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                                elsif ($rand==5) {quest::shout(sprintf("%s%s","Come visit Battlestaff Fuzzietoe at the entrance to the East Commons tunnel, great prices on items like this " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
                        }
                        $npc->SetAppearance(int(rand(2)));
                }
               
        if($timer eq "initial_load_vendor")
                {
                #quest::shout('end load');
                LOAD_VENDOR();       
                #quest::shout('end load2');
                quest::stoptimer("initial_load_vendor");
                }       
}
 
sub ANNOUNCE
{
        sprintf("%c%06X%s%s%c",0x12,$random_result_set[$_[0]],"00000000000000000000000000000000000000000000",quest::itemname($random_result_set[$_[0]]),0x12);
}
 
 sub LOAD_VENDOR
 {
        quest::merchantclear($npc->GetNPCTypeID());
       
        fisher_yates_shuffle( \@random_result_set);
       
        #Iterate through current items, add them.
        for ($i=0; $i<=$vendor_item_count; $i++)
                {
                        #quest::emote("Adding item " . $random_result_set[$i]);
                        quest::MerchantSetItem($npc->GetNPCTypeID(), $random_result_set[$i], 1);
                }
 }
 
 sub fisher_yates_shuffle
{
    my $array=shift;
    my $i=@$array;
    while ( --$i )
    {
        my $j = int rand( $i+1 );
        @$array[$i,$j]=@$array[$j,$i];
    }
}

$dbh ->disconnect();



All times are GMT -4. The time now is 02:35 AM.

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