mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-08 05:52:26 +00:00
commit
54c3f9ab94
@ -22,7 +22,7 @@
|
|||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
#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,
|
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
|
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_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|||||||
@ -329,6 +329,7 @@
|
|||||||
9073|2015_01_31_character_item_recast.sql|SHOW TABLES LIKE 'character_item_recast'|empty|
|
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|
|
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|
|
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:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# 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/global_define.h"
|
||||||
#include "../common/loottable.h"
|
#include "../common/loottable.h"
|
||||||
#include "../common/misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
|
#include "../common/data_verification.h"
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
@ -35,7 +36,7 @@
|
|||||||
|
|
||||||
// Queries the loottable: adds item & coin to the npc
|
// 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) {
|
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;
|
*copper = 0;
|
||||||
*silver = 0;
|
*silver = 0;
|
||||||
*gold = 0;
|
*gold = 0;
|
||||||
@ -45,44 +46,39 @@ void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* ite
|
|||||||
if (!lts)
|
if (!lts)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// do coin
|
uint32 min_cash = lts->mincash;
|
||||||
if (lts->mincash > lts->maxcash) {
|
uint32 max_cash = lts->maxcash;
|
||||||
std::cerr << "Error in loottable #" << loottable_id << ": mincash > maxcash" << std::endl;
|
if(min_cash > max_cash) {
|
||||||
|
uint32 t = min_cash;
|
||||||
|
min_cash = max_cash;
|
||||||
|
max_cash = t;
|
||||||
}
|
}
|
||||||
else if (lts->maxcash != 0) {
|
|
||||||
uint32 cash = 0;
|
uint32 cash = 0;
|
||||||
if (lts->mincash == lts->maxcash)
|
if(max_cash > 0 && lts->avgcoin > 0 && EQEmu::ValueWithin(lts->avgcoin, min_cash, max_cash)) {
|
||||||
cash = lts->mincash;
|
float upper_chance = (float)(lts->avgcoin - min_cash) / (float)(max_cash - min_cash);
|
||||||
else
|
float avg_cash_roll = (float)zone->random.Real(0.0, 1.0);
|
||||||
cash = zone->random.Int(lts->mincash, lts->maxcash);
|
|
||||||
|
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) {
|
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;
|
*plat = cash / 1000;
|
||||||
cash -= *plat * 1000;
|
cash -= *plat * 1000;
|
||||||
uint32 gold2 = cash / 100;
|
|
||||||
cash -= gold2 * 100;
|
*gold = cash / 100;
|
||||||
uint32 silver2 = cash / 10;
|
cash -= *gold * 100;
|
||||||
cash -= silver2 * 10;
|
|
||||||
*gold += gold2;
|
*silver = cash / 10;
|
||||||
*silver += silver2;
|
cash -= *silver * 10;
|
||||||
*copper += cash;
|
|
||||||
}
|
*copper = cash;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do items
|
// Do items
|
||||||
@ -97,10 +93,10 @@ void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* ite
|
|||||||
|
|
||||||
float drop_chance = 0.0f;
|
float drop_chance = 0.0f;
|
||||||
if(ltchance > 0.0 && ltchance < 100.0) {
|
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)) {
|
if (ltchance != 0.0 && (ltchance == 100.0 || drop_chance <= ltchance)) {
|
||||||
AddLootDropToNPC(npc, lts->Entries[i].lootdrop_id, itemlist, droplimit, mindrop);
|
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) {
|
if (!lds) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(lds->NumEntries == 0) //nothing possible to add
|
|
||||||
|
if(lds->NumEntries == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Too long a list needs to be limited.
|
if(droplimit == 0 && mindrop == 0) {
|
||||||
if(lds->NumEntries > 99 && droplimit < 1)
|
for(uint32 i = 0; i < lds->NumEntries; ++i) {
|
||||||
droplimit = lds->NumEntries/100;
|
int charges = lds->Entries[i].multiplier;
|
||||||
|
for(int j = 0; j < charges; ++j) {
|
||||||
uint8 limit = 0;
|
if(zone->random.Real(0.0, 100.0) <= lds->Entries[i].chance) {
|
||||||
// Start at a random point in itemlist.
|
const Item_Struct* dbitem = GetItem(lds->Entries[i].item_id);
|
||||||
uint32 item = zone->random.Int(0, lds->NumEntries-1);
|
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||||
// Main loop.
|
lds->Entries[i].maxlevel, lds->Entries[i].equip_item > 0 ? true : false, false);
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Items with multipliers only count as 1 towards the limit.
|
}
|
||||||
if(pickedcharges > 0)
|
return;
|
||||||
limit++;
|
}
|
||||||
|
|
||||||
// If true, limit reached.
|
if(lds->NumEntries > 100 && droplimit == 0) {
|
||||||
if(limit >= droplimit && droplimit > 0)
|
droplimit = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(droplimit < mindrop) {
|
||||||
|
droplimit = mindrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
|
}
|
||||||
item++;
|
else {
|
||||||
i++;
|
roll -= lds->Entries[j].chance;
|
||||||
|
}
|
||||||
// We didn't reach our minimium, run loop again.
|
|
||||||
if(i == lds->NumEntries){
|
|
||||||
if(limit < mindrop){
|
|
||||||
i = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // We either ran out of items or reached our limit.
|
} // 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->attuned = 0;
|
||||||
item->min_level = minlevel;
|
item->min_level = minlevel;
|
||||||
item->max_level = maxlevel;
|
item->max_level = maxlevel;
|
||||||
|
|
||||||
if (equipit) {
|
if (equipit) {
|
||||||
uint8 eslot = 0xFF;
|
uint8 eslot = 0xFF;
|
||||||
char newid[20];
|
char newid[20];
|
||||||
|
|||||||
@ -622,7 +622,7 @@ public:
|
|||||||
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
|
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
|
||||||
bool ImprovedTaunt();
|
bool ImprovedTaunt();
|
||||||
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
|
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);
|
void CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster = nullptr);
|
||||||
inline int16 GetSpellPowerDistanceMod() const { return SpellPowerDistanceMod; };
|
inline int16 GetSpellPowerDistanceMod() const { return SpellPowerDistanceMod; };
|
||||||
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
|
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
|
||||||
|
|||||||
@ -253,7 +253,7 @@ public:
|
|||||||
|
|
||||||
uint32 GetMaxDMG() const {return max_dmg;}
|
uint32 GetMaxDMG() const {return max_dmg;}
|
||||||
uint32 GetMinDMG() const {return min_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;}
|
float GetAttackSpeed() const {return attack_speed;}
|
||||||
uint8 GetAttackDelay() const {return attack_delay;}
|
uint8 GetAttackDelay() const {return attack_delay;}
|
||||||
bool IsAnimal() const { return(bodytype == BT_Animal); }
|
bool IsAnimal() const { return(bodytype == BT_Animal); }
|
||||||
|
|||||||
@ -2076,7 +2076,7 @@ XS(XS_NPC_GetSlowMitigation)
|
|||||||
Perl_croak(aTHX_ "Usage: NPC::GetSlowMitigation(THIS)");
|
Perl_croak(aTHX_ "Usage: NPC::GetSlowMitigation(THIS)");
|
||||||
{
|
{
|
||||||
NPC * THIS;
|
NPC * THIS;
|
||||||
int16 RETVAL;
|
float RETVAL;
|
||||||
dXSTARG;
|
dXSTARG;
|
||||||
|
|
||||||
if (sv_derived_from(ST(0), "NPC")) {
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
@ -2089,7 +2089,7 @@ XS(XS_NPC_GetSlowMitigation)
|
|||||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
RETVAL = THIS->GetSlowMitigation();
|
RETVAL = THIS->GetSlowMitigation();
|
||||||
XSprePUSH; PUSHn((UV)RETVAL);
|
XSprePUSH; PUSHn((double)RETVAL);
|
||||||
}
|
}
|
||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user