finally harvesting T2 in frostfang, i getting glowing material way to often and sometime getting 3, on live you never get more that minimum # of one (old days) or 2 new days
also seems to be trigguring way to often
most likely the RNG but ill turn on some additaonla checks here, and tets and post a fix
Harvesting bug
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Harvesting bug
ok after some digging in the DB found that the imbue item is entered the same way that normal on imbue items are, so that would explain why getting them often and also able to get multiples in a single harvest it glowing material is in the list as rare = 0
i ill work on this, but here is some of the issue
this is in groundspawn.cpp
in this section of code that is checking each item in the groundspawn list means that no item will be award if the rnd of the harvest roll matched imbue
becuase imbue is harvest_type 4 but the groundspawn entry has rare = 0 so we need to identify the imbue in the DB as an imbue
i would also recommend and will change here for testing that the grounspawns items table either
1. add a field for is_imbue or
2. use the is_rare field 1 = rare, 2= imbue item, 3 = something else if we ever decide to have it
then change the code to dish out the proper item based on that
i ill work on this, but here is some of the issue
this is in groundspawn.cpp
in this section of code that is checking each item in the groundspawn list means that no item will be award if the rnd of the harvest roll matched imbue
becuase imbue is harvest_type 4 but the groundspawn entry has rare = 0 so we need to identify the imbue in the DB as an imbue
i would also recommend and will change here for testing that the grounspawns items table either
1. add a field for is_imbue or
2. use the is_rare field 1 = rare, 2= imbue item, 3 = something else if we ever decide to have it
then change the code to dish out the proper item based on that
Code: Select all
// if this is a Rare, or an Imbue, but is_rare flag is 0, skip item
if( (harvest_type == 5 || harvest_type == 4) && entry->is_rare == 0 )
continue;- Ememjr
- Team Member
- Posts: 975
- Joined: Wed Mar 15, 2017 9:41 am
- EQ2Emu Server: Perseverance
Re: Harvesting bug
here is a fix for the harvesting issues, it fixes the not getting an imbue issue and not getting a single rare issue,
in order for this to work you in ground spawn items the imbue harvest item needs is_rare set to 2
in order for this to work you in ground spawn items the imbue harvest item needs is_rare set to 2
Code: Select all
void GroundSpawn::ProcessHarvest(Client* client)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Process harvesting for player '%s' (%u)", client->GetPlayer()->GetName(), client->GetPlayer()->GetID());
MHarvest.lock();
vector<GroundSpawnEntry*>* groundspawn_entries = GetZone()->GetGroundSpawnEntries(groundspawn_id);
vector<GroundSpawnEntryItem*>* groundspawn_items = GetZone()->GetGroundSpawnEntryItems(groundspawn_id);
Item* master_item = 0;
Item* master_rare = 0;
Item* item = 0;
Item* item_rare = 0;
int16 lowest_skill_level = 0;
int16 table_choice = 0;
int32 item_choice = 0;
int32 rare_choice = 0;
int8 harvest_type = 0;
int32 item_harvested = 0;
int8 reward_total = 1;
int32 rare_harvested = 0;
int8 rare_item = 0;
bool is_collection = false;
if(!groundspawn_entries || !groundspawn_items)
{
LogWrite(GROUNDSPAWN__ERROR, 3, "GSpawn", "No groundspawn entries or items assigned to groundspawn id: %u", groundspawn_id);
client->Message(CHANNEL_COLOR_RED, "Error: There are no groundspawn entries or items assigned to groundspawn id: %u", groundspawn_id);
MHarvest.unlock();
return;
}
if(number_harvests == 0)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Total harvests depleated for groundspawn id: %u", groundspawn_id);
client->SimpleMessage(CHANNEL_COLOR_RED, "Error: This spawn has nothing more to harvest!");
MHarvest.unlock();
return;
}
Skill* skill = 0;
if (collection_skill == "Collecting")
{
skill = client->GetPlayer()->GetSkillByName("Gathering");
is_collection = true;
}
else
skill = client->GetPlayer()->GetSkillByName(collection_skill.c_str(), true);
if(!skill)
{
LogWrite(GROUNDSPAWN__WARNING, 3, "GSpawn", "Player '%s' lacks the skill: '%s'", client->GetPlayer()->GetName(), collection_skill.c_str());
client->Message(CHANNEL_COLOR_RED, "Error: You do not have the '%s' skill!", collection_skill.c_str());
MHarvest.unlock();
return;
}
for(int8 i=0;i<num_attempts_per_harvest; i++)
{
vector<GroundSpawnEntry*> mod_groundspawn_entries;
if(groundspawn_entries)
{
vector<GroundSpawnEntry*> highest_match;
vector<GroundSpawnEntry*>::iterator itr;
GroundSpawnEntry* entry = 0; // current data
GroundSpawnEntry* selected_table = 0; // selected table data
// first, iterate through groundspawn_entries, discard tables player cannot use
for(itr = groundspawn_entries->begin(); itr != groundspawn_entries->end(); itr++)
{
entry = *itr;
// if player lacks skill, skip table
if( entry->min_skill_level > skill->current_val )
continue;
// if bonus, but player lacks level, skip table
if( entry->bonus_table && (client->GetPlayer()->GetLevel() < entry->min_adventure_level) )
continue;
// build modified entries table
mod_groundspawn_entries.push_back(entry);
LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "Keeping groundspawn_entry: %i", entry->min_skill_level);
}
// if anything remains, find lowest min_skill_level in remaining set(s)
if(mod_groundspawn_entries.size() > 0)
{
vector<GroundSpawnEntry*>::iterator itr;
GroundSpawnEntry* entry = 0;
for(itr = mod_groundspawn_entries.begin(); itr != mod_groundspawn_entries.end(); itr++)
{
entry = *itr;
// find the low range of available tables for random roll
if(lowest_skill_level > entry->min_skill_level || lowest_skill_level == 0)
lowest_skill_level = entry->min_skill_level;
}
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Lowest Skill Level: %i", lowest_skill_level);
}
else
{
// if no tables chosen, you must lack the skills
// TODO: move this check to LUA when harvest command is first selected
client->Message(CHANNEL_COLOR_RED, "You lack the skills to harvest this node!");
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "All groundspawn_entry tables tossed! No Skills? Something broke?");
MHarvest.unlock();
return;
}
// now roll to see which table to use
table_choice = MakeRandomInt(lowest_skill_level, skill->current_val);
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Random INT for Table by skill level: %i", table_choice);
int16 highest_score = 0;
for(itr = mod_groundspawn_entries.begin(); itr != mod_groundspawn_entries.end(); itr++)
{
entry = *itr;
// determines the highest min_skill_level in the current set of tables (if multiple tables)
if(table_choice >= entry->min_skill_level && (highest_score == 0 || highest_score < table_choice))
{
// removes old highest for the new one
highest_match.clear();
highest_score = entry->min_skill_level;
}
// if the score = level, push into highest_match set
if(highest_score == entry->min_skill_level)
highest_match.push_back(entry);
}
// if there is STILL more than 1 table player qualifies for, rand() and pick one
if(highest_match.size() > 1){
int16 rand_index = rand()%highest_match.size();
selected_table = highest_match.at(rand_index);
}
else if(highest_match.size() > 0)
selected_table = highest_match.at(0);
// by this point, we should have 1 table who's min skill matches the score (selected_table)
if(selected_table)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Using Table: %i, %i, %i, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %i",
selected_table->min_skill_level,
selected_table->min_adventure_level,
selected_table->bonus_table,
selected_table->harvest1,
selected_table->harvest3,
selected_table->harvest5,
selected_table->harvest_imbue,
selected_table->harvest_rare,
selected_table->harvest10,
selected_table->harvest_coin);
// roll 1-100 for chance-to-harvest percentage
float chance = MakeRandomFloat(0, 100);
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Random FLOAT for harvest percentages: %.2f", chance);
// starting with the lowest %, select a harvest type + reward qty
if(chance <= selected_table->harvest10 && is_collection == false)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest 10 items + Rare Item from table : %i", selected_table->min_skill_level);
harvest_type = 6;
reward_total = 10;
}
else if(chance <= selected_table->harvest_rare && is_collection == false)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest Rare Item from table : %i", selected_table->min_skill_level);
harvest_type = 5;
}
else if(chance <= selected_table->harvest_imbue && is_collection == false)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest Imbue Item from table : %i", selected_table->min_skill_level);
harvest_type = 4;
}
else if(chance <= selected_table->harvest5 && is_collection == false)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest 5 Items from table : %i", selected_table->min_skill_level);
harvest_type = 3;
reward_total = 5;
}
else if(chance <= selected_table->harvest3 && is_collection == false)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest 3 Items from table : %i", selected_table->min_skill_level);
harvest_type = 2;
reward_total = 3;
}
else if( chance <= selected_table->harvest1 || skill->current_val == skill->max_val || is_collection )
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest 1 Item from table : %i", selected_table->min_skill_level);
harvest_type = 1;
}
else
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Harvest nothing...");
}
// once you know how many and what type of item to harvest, pick an item from the list
if(harvest_type)
{
vector<GroundSpawnEntryItem*> mod_groundspawn_items;
vector<GroundSpawnEntryItem*> mod_groundspawn_rares;
vector<GroundSpawnEntryItem*> mod_groundspawn_imbue;
vector<GroundSpawnEntryItem*>::iterator itr;
GroundSpawnEntryItem* entry = 0;
// iterate through groundspawn_items, discard items player cannot roll for
for(itr = groundspawn_items->begin(); itr != groundspawn_items->end(); itr++)
{
entry = *itr;
// if this is a Rare, or an Imbue, but is_rare flag is 0, skip item
if( (harvest_type == 5 || harvest_type == 4) && entry->is_rare == 0 )
continue;
// if it is a 1, 3, or 5 and is_rare = 1, skip
else if( harvest_type < 4 && entry->is_rare == 1 )
continue;
// if the grid_id on the item matches player grid, or is 0, keep the item
if( !entry->grid_id || (entry->grid_id == client->GetPlayer()->appearance.pos.grid_id) )
{
// build modified entries table
if ((entry->is_rare == 1 && harvest_type == 5) || (entry->is_rare == 1 && harvest_type == 6))
{
// if the matching item is rare, or harvest10 push to mod rares
mod_groundspawn_rares.push_back(entry);
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Keeping groundspawn_rare_item: %u", entry->item_id);
}
if (entry->is_rare == 0 && harvest_type != 4 && harvest_type != 5)
{
// if the matching item is normal,or harvest 10 push to mod items
mod_groundspawn_items.push_back(entry);
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Keeping groundspawn_common_item: %u", entry->item_id);
}
if (entry->is_rare == 2 && harvest_type == 4)
{
// if the matching item is imbue item, push to mod imbue
mod_groundspawn_imbue.push_back(entry);
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Keeping groundspawn_imbue_item: %u", entry->item_id);
}
}
}
// if any items remain in the list, random to see which one gets awarded
if(mod_groundspawn_items.size() > 0)
{
// roll to see which item index to use
item_choice = rand()%mod_groundspawn_items.size();
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Random INT for which item to award: %i", item_choice);
// set item_id to be awarded
item_harvested = mod_groundspawn_items[item_choice]->item_id;
// if reward is rare, set flag
rare_item = mod_groundspawn_items[item_choice]->is_rare;
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Item ID to award: %u, Rare = %i", item_harvested, item_rare);
// if 10+rare, handle additional "rare" reward
if( harvest_type == 6 )
{
// make sure there is a rare table to choose from!
if( mod_groundspawn_rares.size() > 0 )
{
// roll to see which rare index to use
rare_choice = rand()%mod_groundspawn_rares.size();
// set (rare) item_id to be awarded
rare_harvested = mod_groundspawn_rares[rare_choice]->item_id;
// we're picking a rare here, so obviously this is true ;)
rare_item = 1;
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "RARE Item ID to award: %u", rare_harvested);
}
else
{
// all rare entries were eliminated above, or none are assigned. Either way, shouldn't be here!
LogWrite(GROUNDSPAWN__ERROR, 3, "GSpawn", "Groundspawn Entry for '%s' (%i) has no RARE items!", GetName(), GetID());
}
}
}
else if (mod_groundspawn_rares.size() > 0)
{
// roll to see which rare index to use
item_choice = rand() % mod_groundspawn_rares.size();
// set (rare) item_id to be awarded
item_harvested = mod_groundspawn_rares[item_choice]->item_id;
// we're picking a rare here, so obviously this is true ;)
rare_item = 1;
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "RARE Item ID to award: %u", rare_harvested);
}
else if (mod_groundspawn_imbue.size() > 0)
{
// roll to see which rare index to use
item_choice = rand() % mod_groundspawn_imbue.size();
// set (rare) item_id to be awarded
item_harvested = mod_groundspawn_imbue[item_choice]->item_id;
// we're picking a rare here, so obviously this is true ;)
rare_item = 0;
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "imbue Item ID to award: %u", rare_harvested);
}
else
{
// all item entries were eliminated above, or none are assigned. Either way, shouldn't be here!
LogWrite(GROUNDSPAWN__ERROR, 0, "GSpawn", "Groundspawn Entry for '%s' (%i) has no items!", GetName(), GetID());
}
// if an item was harvested, send updates to client, add item to inventory
if(item_harvested)
{
char tmp[200] = {0};
// set Normal item harvested
master_item = master_item_list.GetItem(item_harvested);
if(master_item)
{
// set details of Normal item
item = new Item(master_item);
// set how many of this item the player receives
item->details.count = reward_total;
// chat box update for normal item (todo: verify output text)
client->Message(CHANNEL_COLOR_HARVEST, "You %s %i \\aITEM %u %u:%s\\/a from the %s.", GetHarvestMessageName(true).c_str(), item->details.count, item->details.item_id, item->details.unique_id, item->name.c_str(), GetName());
// add Normal item to player inventory
client->AddItem(item);
//Check if the player has a harvesting quest for this
client->GetPlayer()->CheckQuestsHarvestUpdate(item, reward_total);
// if this is a 10+rare, handle sepErately
if(harvest_type == 6 && rare_item == 1)
{
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Item ID %u is Normal. Qty %i", item_harvested, item->details.count);
// send Normal harvest message to client
sprintf(tmp, "\\#64FFFFYou have %s:\12\\#C8FFFF%i %s", GetHarvestMessageName().c_str(), item->details.count, item->name.c_str());
client->SendPopupMessage(10, tmp, "ui_harvested_normal", 2.25, 0xFF, 0xFF, 0xFF);
client->GetPlayer()->UpdatePlayerStatistic(STAT_PLAYER_ITEMS_HARVESTED, item->details.count);
// set Rare item harvested
master_rare = master_item_list.GetItem(rare_harvested);
if(master_rare)
{
// set details of Rare item
item_rare = new Item(master_rare);
// count of Rare is always 1
item_rare->details.count = 1;
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Item ID %u is RARE!", rare_harvested);
// send Rare harvest message to client
sprintf(tmp, "\\#FFFF6ERare item found!\12%s: \\#C8FFFF%i %s", GetHarvestMessageName().c_str(), item_rare->details.count, item_rare->name.c_str());
client->Message(CHANNEL_COLOR_HARVEST, "You have found a rare item!");
client->SendPopupMessage(11, tmp, "ui_harvested_rare", 2.25, 0xFF, 0xFF, 0xFF);
client->GetPlayer()->UpdatePlayerStatistic(STAT_PLAYER_RARES_HARVESTED, item_rare->details.count);
// chat box update for rare item (todo: verify output text)
client->Message(CHANNEL_COLOR_HARVEST, "You %s %i \\aITEM %u %u:%s\\/a from the %s.", GetHarvestMessageName(true).c_str(), item_rare->details.count, item_rare->details.item_id, item_rare->details.unique_id, item_rare->name.c_str(), GetName());
// add Rare item to player inventory
client->AddItem(item_rare);
//Check if the player has a harvesting quest for this
client->GetPlayer()->CheckQuestsHarvestUpdate(item_rare, 1);
}
}
else if(rare_item == 1)
{
// if harvest signaled rare or imbue type
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Item ID %u is RARE! Qty: %i", item_harvested, item->details.count);
// send Rare harvest message to client
sprintf(tmp, "\\#FFFF6ERare item found!\12%s: \\#C8FFFF%i %s", GetHarvestMessageName().c_str(), item->details.count, item->name.c_str());
client->Message(CHANNEL_COLOR_HARVEST, "You have found a rare item!");
client->SendPopupMessage(11, tmp, "ui_harvested_rare", 2.25, 0xFF, 0xFF, 0xFF);
client->GetPlayer()->UpdatePlayerStatistic(STAT_PLAYER_RARES_HARVESTED, item->details.count);
}
else
{
// send Normal harvest message to client
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "Item ID %u is Normal. Qty %i", item_harvested, item->details.count);
sprintf(tmp, "\\#64FFFFYou have %s:\12\\#C8FFFF%i %s", GetHarvestMessageName().c_str(), item->details.count, item->name.c_str());
client->SendPopupMessage(10, tmp, "ui_harvested_normal", 2.25, 0xFF, 0xFF, 0xFF);
client->GetPlayer()->UpdatePlayerStatistic(STAT_PLAYER_ITEMS_HARVESTED, item->details.count);
}
}
else
{
// error!
LogWrite(GROUNDSPAWN__ERROR, 0, "GSpawn", "Error: Item ID Not Found - %u", item_harvested);
client->Message(CHANNEL_COLOR_RED, "Error: Unable to find item id %u", item_harvested);
}
// decrement # of pulls on this node before it despawns
number_harvests--;
}
else
{
// if no item harvested
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "No item_harvested");
client->Message(CHANNEL_COLOR_HARVEST, "You failed to %s anything from %s.", GetHarvestMessageName(true, true).c_str(), GetName());
}
}
else
{
// if no harvest type
LogWrite(GROUNDSPAWN__DEBUG, 3, "GSpawn", "No harvest_type");
client->Message(CHANNEL_COLOR_HARVEST, "You failed to %s anything from %s.", GetHarvestMessageName(true, true).c_str(), GetName());
}
}
} // cycle through num_attempts_per_harvest
MHarvest.unlock();
LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "Process harvest complete for player '%s' (%u)", client->GetPlayer()->GetName(), client->GetPlayer()->GetID());
}-
Jabantiz
- Lead Developer
- Posts: 2912
- Joined: Wed Jul 25, 2007 2:52 pm
- Location: California
Re: Harvesting bug
Committed to dev svn.
Side not I noticed in the GroundSpawnEntryItem struct is_rare was an int32, changed it to an int8
Side not I noticed in the GroundSpawnEntryItem struct is_rare was an int32, changed it to an int8
Who is online
Users browsing this forum: No registered users and 0 guests