mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-21 05:22:24 +00:00
commit
54c3f9ab94
@ -22,7 +22,7 @@
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
||||
|
||||
#define CURRENT_VERSION "1.0.0"
|
||||
#define CURRENT_VERSION "1.1.3"
|
||||
|
||||
/*
|
||||
Everytime a Database SQL is added to Github,
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9075
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9076
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
|
||||
@ -329,6 +329,7 @@
|
||||
9073|2015_01_31_character_item_recast.sql|SHOW TABLES LIKE 'character_item_recast'|empty|
|
||||
9074|2015_02_01_logsys_packet_logs.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Packet: Server -> Client'|empty|
|
||||
9075|2015_02_02_logsys_packet_logs_with_dump.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Packet: Server -> Client With Dump'|empty|
|
||||
9076|2014_10_30_special_abilities_null.sql|SHOW COLUMNS FROM `loottable` WHERE Field = 'avgcoin'|contains|smallint
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
2
utils/sql/git/required/2015_02_04_average_coin.sql
Normal file
2
utils/sql/git/required/2015_02_04_average_coin.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `loottable` CHANGE COLUMN `avgcoin` `avgcoin` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `maxcash`;
|
||||
UPDATE `loottable` SET avgcoin = 0;
|
||||
@ -19,6 +19,7 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/loottable.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/data_verification.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
@ -35,7 +36,7 @@
|
||||
|
||||
// Queries the loottable: adds item & coin to the npc
|
||||
void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) {
|
||||
const LootTable_Struct* lts = 0;
|
||||
const LootTable_Struct* lts = nullptr;
|
||||
*copper = 0;
|
||||
*silver = 0;
|
||||
*gold = 0;
|
||||
@ -45,44 +46,39 @@ void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* ite
|
||||
if (!lts)
|
||||
return;
|
||||
|
||||
// do coin
|
||||
if (lts->mincash > lts->maxcash) {
|
||||
std::cerr << "Error in loottable #" << loottable_id << ": mincash > maxcash" << std::endl;
|
||||
uint32 min_cash = lts->mincash;
|
||||
uint32 max_cash = lts->maxcash;
|
||||
if(min_cash > max_cash) {
|
||||
uint32 t = min_cash;
|
||||
min_cash = max_cash;
|
||||
max_cash = t;
|
||||
}
|
||||
else if (lts->maxcash != 0) {
|
||||
uint32 cash = 0;
|
||||
if (lts->mincash == lts->maxcash)
|
||||
cash = lts->mincash;
|
||||
else
|
||||
cash = zone->random.Int(lts->mincash, lts->maxcash);
|
||||
if (cash != 0) {
|
||||
if (lts->avgcoin != 0) {
|
||||
//this is some crazy ass stuff... and makes very little sense... dont use it, k?
|
||||
uint32 mincoin = (uint32) (lts->avgcoin * 0.75 + 1);
|
||||
uint32 maxcoin = (uint32) (lts->avgcoin * 1.25 + 1);
|
||||
*copper = zone->random.Int(mincoin, maxcoin);
|
||||
*silver = zone->random.Int(mincoin, maxcoin);
|
||||
*gold = zone->random.Int(mincoin, maxcoin);
|
||||
if(*copper > cash) { *copper = cash; }
|
||||
cash -= *copper;
|
||||
if(*silver>(cash/10)) { *silver = (cash/10); }
|
||||
cash -= *silver*10;
|
||||
if(*gold > (cash/100)) { *gold = (cash/100); }
|
||||
cash -= *gold*100;
|
||||
}
|
||||
if (cash < 0) {
|
||||
cash = 0;
|
||||
}
|
||||
*plat = cash / 1000;
|
||||
cash -= *plat * 1000;
|
||||
uint32 gold2 = cash / 100;
|
||||
cash -= gold2 * 100;
|
||||
uint32 silver2 = cash / 10;
|
||||
cash -= silver2 * 10;
|
||||
*gold += gold2;
|
||||
*silver += silver2;
|
||||
*copper += cash;
|
||||
|
||||
uint32 cash = 0;
|
||||
if(max_cash > 0 && lts->avgcoin > 0 && EQEmu::ValueWithin(lts->avgcoin, min_cash, max_cash)) {
|
||||
float upper_chance = (float)(lts->avgcoin - min_cash) / (float)(max_cash - min_cash);
|
||||
float avg_cash_roll = (float)zone->random.Real(0.0, 1.0);
|
||||
|
||||
if(avg_cash_roll < upper_chance) {
|
||||
cash = zone->random.Int(lts->avgcoin, max_cash);
|
||||
} else {
|
||||
cash = zone->random.Int(min_cash, lts->avgcoin);
|
||||
}
|
||||
} else {
|
||||
cash = zone->random.Int(min_cash, max_cash);
|
||||
}
|
||||
|
||||
if(cash != 0) {
|
||||
*plat = cash / 1000;
|
||||
cash -= *plat * 1000;
|
||||
|
||||
*gold = cash / 100;
|
||||
cash -= *gold * 100;
|
||||
|
||||
*silver = cash / 10;
|
||||
cash -= *silver * 10;
|
||||
|
||||
*copper = cash;
|
||||
}
|
||||
|
||||
// Do items
|
||||
@ -97,11 +93,11 @@ void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* ite
|
||||
|
||||
float drop_chance = 0.0f;
|
||||
if(ltchance > 0.0 && ltchance < 100.0) {
|
||||
drop_chance = zone->random.Real(0.0, 100.0);
|
||||
drop_chance = (float)zone->random.Real(0.0, 100.0);
|
||||
}
|
||||
|
||||
if (ltchance != 0.0 && (ltchance == 100.0 || drop_chance < ltchance)) {
|
||||
AddLootDropToNPC(npc,lts->Entries[i].lootdrop_id, itemlist, droplimit, mindrop);
|
||||
if (ltchance != 0.0 && (ltchance == 100.0 || drop_chance <= ltchance)) {
|
||||
AddLootDropToNPC(npc, lts->Entries[i].lootdrop_id, itemlist, droplimit, mindrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,63 +110,76 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
if (!lds) {
|
||||
return;
|
||||
}
|
||||
if(lds->NumEntries == 0) //nothing possible to add
|
||||
|
||||
if(lds->NumEntries == 0)
|
||||
return;
|
||||
|
||||
// Too long a list needs to be limited.
|
||||
if(lds->NumEntries > 99 && droplimit < 1)
|
||||
droplimit = lds->NumEntries/100;
|
||||
|
||||
uint8 limit = 0;
|
||||
// Start at a random point in itemlist.
|
||||
uint32 item = zone->random.Int(0, lds->NumEntries-1);
|
||||
// Main loop.
|
||||
for (uint32 i=0; i<lds->NumEntries;)
|
||||
{
|
||||
//Force the itemlist back to beginning.
|
||||
if (item > (lds->NumEntries-1))
|
||||
item = 0;
|
||||
|
||||
uint8 charges = lds->Entries[item].multiplier;
|
||||
uint8 pickedcharges = 0;
|
||||
// Loop to check multipliers.
|
||||
for (uint32 x=1; x<=charges; x++)
|
||||
{
|
||||
// Actual roll.
|
||||
float thischance = 0.0;
|
||||
thischance = lds->Entries[item].chance;
|
||||
|
||||
float drop_chance = 0.0;
|
||||
if(thischance != 100.0)
|
||||
drop_chance = zone->random.Real(0.0, 100.0);
|
||||
|
||||
#if EQDEBUG>=11
|
||||
Log.Out(Logs::General, Logs::None, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
|
||||
#endif
|
||||
if (thischance == 100.0 || drop_chance < thischance)
|
||||
{
|
||||
uint32 itemid = lds->Entries[item].item_id;
|
||||
|
||||
const Item_Struct* dbitem = GetItem(itemid);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[item].item_charges, lds->Entries[item].minlevel, lds->Entries[item].maxlevel, lds->Entries[item].equip_item, false);
|
||||
pickedcharges++;
|
||||
if(droplimit == 0 && mindrop == 0) {
|
||||
for(uint32 i = 0; i < lds->NumEntries; ++i) {
|
||||
int charges = lds->Entries[i].multiplier;
|
||||
for(int j = 0; j < charges; ++j) {
|
||||
if(zone->random.Real(0.0, 100.0) <= lds->Entries[i].chance) {
|
||||
const Item_Struct* dbitem = GetItem(lds->Entries[i].item_id);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||
lds->Entries[i].maxlevel, lds->Entries[i].equip_item > 0 ? true : false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Items with multipliers only count as 1 towards the limit.
|
||||
if(pickedcharges > 0)
|
||||
limit++;
|
||||
return;
|
||||
}
|
||||
|
||||
// If true, limit reached.
|
||||
if(limit >= droplimit && droplimit > 0)
|
||||
break;
|
||||
if(lds->NumEntries > 100 && droplimit == 0) {
|
||||
droplimit = 10;
|
||||
}
|
||||
|
||||
item++;
|
||||
i++;
|
||||
if(droplimit < mindrop) {
|
||||
droplimit = mindrop;
|
||||
}
|
||||
|
||||
// We didn't reach our minimium, run loop again.
|
||||
if(i == lds->NumEntries){
|
||||
if(limit < mindrop){
|
||||
i = 0;
|
||||
float roll_t = 0.0f;
|
||||
bool active_item_list = false;
|
||||
for(uint32 i = 0; i < lds->NumEntries; ++i) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[i].item_id);
|
||||
if(db_item) {
|
||||
roll_t += lds->Entries[i].chance;
|
||||
active_item_list = true;
|
||||
}
|
||||
}
|
||||
|
||||
roll_t = EQEmu::ClampLower(roll_t, 100.0f);
|
||||
|
||||
if(!active_item_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
mindrop = EQEmu::ClampLower(mindrop, (uint8)1);
|
||||
int item_count = zone->random.Int(mindrop, droplimit);
|
||||
for(int i = 0; i < item_count; ++i) {
|
||||
float roll = (float)zone->random.Real(0.0, roll_t);
|
||||
for(uint32 j = 0; j < lds->NumEntries; ++j) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[j].item_id);
|
||||
if(db_item) {
|
||||
if(roll < lds->Entries[j].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
lds->Entries[j].maxlevel, lds->Entries[j].equip_item > 0 ? true : false, false);
|
||||
|
||||
int charges = (int)lds->Entries[i].multiplier;
|
||||
charges = EQEmu::ClampLower(charges, 1);
|
||||
|
||||
for(int k = 1; k < charges; ++k) {
|
||||
float c_roll = (float)zone->random.Real(0.0, 100.0);
|
||||
if(c_roll <= lds->Entries[i].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
lds->Entries[j].maxlevel, lds->Entries[j].equip_item > 0 ? true : false, false);
|
||||
}
|
||||
}
|
||||
|
||||
j = lds->NumEntries;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
roll -= lds->Entries[j].chance;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // We either ran out of items or reached our limit.
|
||||
@ -215,6 +224,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
item->attuned = 0;
|
||||
item->min_level = minlevel;
|
||||
item->max_level = maxlevel;
|
||||
|
||||
if (equipit) {
|
||||
uint8 eslot = 0xFF;
|
||||
char newid[20];
|
||||
|
||||
@ -622,7 +622,7 @@ public:
|
||||
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
|
||||
bool ImprovedTaunt();
|
||||
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
|
||||
int16 GetSlowMitigation() const {return slow_mitigation;}
|
||||
float GetSlowMitigation() const { return slow_mitigation; }
|
||||
void CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster = nullptr);
|
||||
inline int16 GetSpellPowerDistanceMod() const { return SpellPowerDistanceMod; };
|
||||
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
|
||||
|
||||
@ -253,7 +253,7 @@ public:
|
||||
|
||||
uint32 GetMaxDMG() const {return max_dmg;}
|
||||
uint32 GetMinDMG() const {return min_dmg;}
|
||||
int16 GetSlowMitigation() const {return slow_mitigation;}
|
||||
float GetSlowMitigation() const { return slow_mitigation; }
|
||||
float GetAttackSpeed() const {return attack_speed;}
|
||||
uint8 GetAttackDelay() const {return attack_delay;}
|
||||
bool IsAnimal() const { return(bodytype == BT_Animal); }
|
||||
|
||||
@ -2076,7 +2076,7 @@ XS(XS_NPC_GetSlowMitigation)
|
||||
Perl_croak(aTHX_ "Usage: NPC::GetSlowMitigation(THIS)");
|
||||
{
|
||||
NPC * THIS;
|
||||
int16 RETVAL;
|
||||
float RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "NPC")) {
|
||||
@ -2089,7 +2089,7 @@ XS(XS_NPC_GetSlowMitigation)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetSlowMitigation();
|
||||
XSprePUSH; PUSHn((UV)RETVAL);
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user