Fixed merchantlist probability.

NPCs were setting a singular chance value and each item was checking based on this value, making the probability field not a random chance per item.
This removes the probability field from NPCs, SetMerchantProbability() and GetMerchantProbability() and makes the probability field truly random chance.

Special thanks to ChaosSlayerZ for noticing the issue here: http://www.eqemulator.org/forums/showthread.php?t=41731
This commit is contained in:
Kinglykrab 2018-01-27 18:32:00 -05:00
parent 8e9fa38197
commit ceb2b287bb
11 changed files with 12 additions and 84 deletions

View File

@ -887,7 +887,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
uint8 handychance = 0;
for (itr = merlist.begin(); itr != merlist.end() && i <= numItemSlots; ++itr) {
MerchantList ml = *itr;
if (merch->CastToNPC()->GetMerchantProbability() > ml.probability)
if (ml.probability != 100 && zone->random.Int(1, 100) > ml.probability)
continue;
if (GetLevel() < ml.level_required)

View File

@ -2998,7 +2998,7 @@ void command_reloadworld(Client *c, const Seperator *sep)
}
void command_reloadmerchants(Client *c, const Seperator *sep) {
zone->ReloadMerchants();
entity_list.ReloadMerchants();
c->Message(15, "Reloading merchants.");
}

View File

@ -644,7 +644,6 @@ void EntityList::AddCorpse(Corpse *corpse, uint32 in_id)
void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
{
npc->SetID(GetFreeID());
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
@ -4871,3 +4870,12 @@ void EntityList::SendAlternateAdvancementStats() {
c.second->SendAlternateAdvancementPoints();
}
}
void EntityList::ReloadMerchants() {
for (auto it = npc_list.begin();it != npc_list.end(); ++it) {
NPC *cur = it->second;
if (cur->MerchantType != 0) {
zone->LoadNewMerchantData(cur->MerchantType);
}
}
}

View File

@ -244,6 +244,7 @@ public:
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
void RemoveArea(int id);
void ClearAreas();
void ReloadMerchants();
void ProcessProximitySay(const char *Message, Client *c, uint8 language = 0);
void SendAATimer(uint32 charid,UseAA_Struct* uaa);
Doors *FindDoor(uint8 door_id);

View File

@ -1464,7 +1464,6 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
LuaCreateNPCParse(healscale, float, 0);
LuaCreateNPCParse(no_target_hotkey, bool, false);
LuaCreateNPCParse(raid_target, bool, false);
LuaCreateNPCParse(probability, uint8, 0);
NPC* npc = new NPC(npc_type, nullptr, glm::vec4(x, y, z, heading), FlyMode3);
npc->GiveNPCTypeData(npc_type);

View File

@ -488,16 +488,6 @@ void Lua_NPC::MerchantCloseShop() {
self->MerchantCloseShop();
}
void Lua_NPC::SetMerchantProbability(uint8 amt) {
Lua_Safe_Call_Void();
self->SetMerchantProbability(amt);
}
uint8 Lua_NPC::GetMerchantProbability() {
Lua_Safe_Call_Int();
return self->GetMerchantProbability();
}
int Lua_NPC::GetRawAC() {
Lua_Safe_Call_Int();
return self->GetRawAC();
@ -608,8 +598,6 @@ luabind::scope lua_register_npc() {
.def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore)
.def("MerchantOpenShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantOpenShop)
.def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop)
.def("SetMerchantProbability", (void(Lua_NPC::*)(void))&Lua_NPC::SetMerchantProbability)
.def("GetMerchantProbability", (uint8(Lua_NPC::*)(void))&Lua_NPC::GetMerchantProbability)
.def("GetRawAC", (int(Lua_NPC::*)(void))&Lua_NPC::GetRawAC)
.def("GetAvoidanceRating", &Lua_NPC::GetAvoidanceRating);
}

View File

@ -123,8 +123,6 @@ public:
int GetScore();
void MerchantOpenShop();
void MerchantCloseShop();
void SetMerchantProbability(uint8 amt);
uint8 GetMerchantProbability();
int GetRawAC();
int GetAvoidanceRating();
};

View File

@ -403,8 +403,6 @@ public:
uint32 GetSpawnKillCount();
int GetScore();
void SetMerchantProbability(uint8 amt) { probability = amt; }
uint8 GetMerchantProbability() { return probability; }
void mod_prespawn(Spawn2 *sp);
int mod_npc_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const EQEmu::ItemData* weapon, Mob* other);
void mod_npc_killed_merit(Mob* c);
@ -537,7 +535,6 @@ protected:
std::list<MercData> mercDataList;
bool raid_target;
uint8 probability;
bool ignore_despawn; //NPCs with this set to 1 will ignore the despawn value in spawngroup
private:

View File

@ -2304,54 +2304,6 @@ XS(XS_NPC_GetScore)
XSRETURN(1);
}
XS(XS_NPC_SetMerchantProbability);
XS(XS_NPC_SetMerchantProbability) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: NPC::SetMerchantProbability(THIS, Probability)");
{
NPC *THIS;
uint8 Probability = (uint8)SvIV(ST(1));
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetMerchantProbability(Probability);
}
XSRETURN_EMPTY;
}
XS(XS_NPC_GetMerchantProbability);
XS(XS_NPC_GetMerchantProbability) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetMerchantProbability(THIS)");
{
NPC *THIS;
uint8 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
RETVAL = THIS->GetMerchantProbability();
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
XS(XS_NPC_AddMeleeProc);
XS(XS_NPC_AddMeleeProc) {
dXSARGS;
@ -2677,8 +2629,6 @@ XS(boot_NPC)
newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$");
newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$");
newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$");
newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$");
newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$");
newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$");
newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$");
newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$");

View File

@ -2272,18 +2272,6 @@ void Zone::ReloadWorld(uint32 Option){
}
}
void Zone::ReloadMerchants() {
std::list<NPC*> npc_list;
entity_list.GetNPCList(npc_list);
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = *itr;
if (npc->MerchantType != 0) {
zone->LoadNewMerchantData(npc->MerchantType);
}
}
}
void Zone::LoadTickItems()
{
tick_items.clear();

View File

@ -126,7 +126,6 @@ struct NPCType
float healscale;
bool no_target_hotkey;
bool raid_target;
uint8 probability;
uint8 armtexture;
uint8 bracertexture;
uint8 handtexture;