mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
a56f17a9e5
@ -1,5 +1,59 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 12/29/2015 ==
|
||||||
|
Akkadius: Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true
|
||||||
|
- When a zone boots, it will spawn an invisible npc by the name of zone_controller
|
||||||
|
- Lua and Perl scripts can be represented with this npc as zone_controller.pl/lua
|
||||||
|
- This NPC's ID is ruled be define ZONE_CONTROLLER_NPC_ID 10
|
||||||
|
- Two EVENT's uniquely are handled with this NPC/controller (They only work with the zone_controller NPC)
|
||||||
|
- EVENT_SPAWN_ZONE :: All NPC spawns in the zone trigger the controller and pass the following variables:
|
||||||
|
$spawned_entity_id
|
||||||
|
$spawned_npc_id
|
||||||
|
- EVENT_DEATH_ZONE :: All NPC deaths in the zone trigger the controller event and pass the following variables:
|
||||||
|
$killer_id
|
||||||
|
$killer_damage
|
||||||
|
$killer_spell
|
||||||
|
$killer_skill
|
||||||
|
$killed_npc_id
|
||||||
|
|
||||||
|
== 12/28/2015 ==
|
||||||
|
Kinglykrab: Added GetInstanceTimer() to Perl and Lua.
|
||||||
|
- Added GetInstanceTimerByID(instance_id) to Perl and Lua.
|
||||||
|
- Note: If you do not provide an instance id in the method it defaults to instance id 0 and returns 0 for time remaining.
|
||||||
|
- Added UpdateZoneHeader(type, value) to Perl and Lua.
|
||||||
|
- Note: UpdateZoneHeader allows you to manipulate fog color, fog density, and many other zone header settings on the fly in Perl and Lua.
|
||||||
|
|
||||||
|
== 12/21/2015 ==
|
||||||
|
Natedog: Updated item table fields and added a few missing fields for evolving items
|
||||||
|
-DO NOT implement Heirloom items till the inventory code is fixed to allow placing NO DROP
|
||||||
|
items in your shared bank. (but item field located on items table)
|
||||||
|
-NYI - SkillModMax: Max skill point modification from the percent mods. EX:
|
||||||
|
100% 2HSlashing (Max 50) - can only increase 2hslash by 50 MAX! (item field located though)
|
||||||
|
Kinglykrab: Added GetMeleeMitigation() for NPCs and Clients in Perl and Lua.
|
||||||
|
- This allows you to check total item, spell, and AA melee mitigation contribution.
|
||||||
|
|
||||||
|
== 12/19/2015 ==
|
||||||
|
Kinglykrab: Added many methods to Perl and Lua, list below:
|
||||||
|
- SeeInvisible()
|
||||||
|
- SeeInvisibleUndead()
|
||||||
|
- SeeHide()
|
||||||
|
- SeeImprovedHide()
|
||||||
|
- GetNimbusEffect1() - returns first nimbus effect
|
||||||
|
- GetNimbusEffect2() - returns second nimbus effect
|
||||||
|
- GetNimbusEffect3() - returns third nimbus effect
|
||||||
|
- IsTargetable()
|
||||||
|
- HasShieldEquiped()
|
||||||
|
- HasTwoHandBluntEquiped()
|
||||||
|
- HasTwoHanderEquiped()
|
||||||
|
- GetHerosForgeModel() - returns int32 Hero's Forge model
|
||||||
|
- IsEliteMaterialItem() - returns uint32 Hero's Forge Model
|
||||||
|
- GetBaseSize() - returns Mob's base size
|
||||||
|
- HasOwner()
|
||||||
|
- IsPet()
|
||||||
|
- HasPet()
|
||||||
|
- IsSilenced()
|
||||||
|
- IsAmnesiad()
|
||||||
|
|
||||||
== 12/16/2015 ==
|
== 12/16/2015 ==
|
||||||
Noudess: Repaired issue with Bind Wounds on someone else. Message was not coming out on client (hold still) and a bind wounds on someone already binding their wounds would interrupt their bind and make them stand. Also removed some duplicate messaging.
|
Noudess: Repaired issue with Bind Wounds on someone else. Message was not coming out on client (hold still) and a bind wounds on someone already binding their wounds would interrupt their bind and make them stand. Also removed some duplicate messaging.
|
||||||
|
|
||||||
|
|||||||
@ -24,20 +24,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static const uint32 BIT_Client62 = 1;
|
static const uint32 BIT_Client62 = 0x00000001; // 1 (unsupported - placeholder for scripts)
|
||||||
static const uint32 BIT_Titanium = 2;
|
|
||||||
static const uint32 BIT_SoF = 4;
|
static const uint32 BIT_Titanium = 0x00000002; // 2
|
||||||
static const uint32 BIT_SoD = 8;
|
static const uint32 BIT_SoF = 0x00000004; // 4
|
||||||
static const uint32 BIT_UF = 16;
|
static const uint32 BIT_SoD = 0x00000008; // 8
|
||||||
static const uint32 BIT_RoF = 32;
|
static const uint32 BIT_UF = 0x00000010; // 16
|
||||||
static const uint32 BIT_RoF2 = 64;
|
static const uint32 BIT_RoF = 0x00000020; // 32
|
||||||
|
static const uint32 BIT_RoF2 = 0x00000040; // 64
|
||||||
|
|
||||||
|
static const uint32 BIT_TitaniumAndEarlier = 0x00000003; // 3
|
||||||
|
static const uint32 BIT_SoFAndEarlier = 0x00000007; // 7
|
||||||
|
static const uint32 BIT_SoDAndEarlier = 0x0000000F; // 15
|
||||||
|
static const uint32 BIT_UFAndEarlier = 0x0000001F; // 31
|
||||||
|
static const uint32 BIT_RoFAndEarlier = 0x0000003F; // 63
|
||||||
|
|
||||||
|
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC; // 4294967292
|
||||||
|
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8; // 4294967288
|
||||||
|
static const uint32 BIT_UFAndLater = 0xFFFFFFF0; // 4294967280
|
||||||
|
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0; // 4294967264
|
||||||
|
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0; // 4294967232
|
||||||
|
|
||||||
static const uint32 BIT_TitaniumAndEarlier = 0x00000003;
|
|
||||||
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC;
|
|
||||||
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8;
|
|
||||||
static const uint32 BIT_UFAndLater = 0xFFFFFFF0;
|
|
||||||
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
|
|
||||||
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
|
|
||||||
static const uint32 BIT_AllClients = 0xFFFFFFFF;
|
static const uint32 BIT_AllClients = 0xFFFFFFFF;
|
||||||
|
|
||||||
enum class ClientVersion
|
enum class ClientVersion
|
||||||
|
|||||||
@ -1183,22 +1183,17 @@ bool Database::CheckNameFilter(const char* name, bool surname)
|
|||||||
{
|
{
|
||||||
std::string str_name = name;
|
std::string str_name = name;
|
||||||
|
|
||||||
if(surname)
|
|
||||||
{
|
|
||||||
// the minimum 4 is enforced by the client too
|
// the minimum 4 is enforced by the client too
|
||||||
if(!name || strlen(name) < 3)
|
if (!name || strlen(name) < 4)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
// Given name length is enforced by the client too
|
||||||
{
|
if (!surname && strlen(name) > 15)
|
||||||
// the minimum 4 is enforced by the client too
|
|
||||||
if(!name || strlen(name) < 4 || strlen(name) > 15)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < str_name.size(); i++)
|
for (size_t i = 0; i < str_name.size(); i++)
|
||||||
{
|
{
|
||||||
@ -1564,7 +1559,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
|
|||||||
char *escape_str = new char[lines.size()*2+1];
|
char *escape_str = new char[lines.size()*2+1];
|
||||||
DoEscapeString(escape_str, lines.c_str(), lines.size());
|
DoEscapeString(escape_str, lines.c_str(), lines.size());
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str);
|
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", EscapeString(who).c_str(), EscapeString(against).c_str(), escape_str);
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
safe_delete_array(escape_str);
|
safe_delete_array(escape_str);
|
||||||
}
|
}
|
||||||
@ -2182,3 +2177,42 @@ void Database::ClearInvSnapshots(bool use_rule)
|
|||||||
std::string query = StringFormat("DELETE FROM inventory_snapshots WHERE time_index <= %lu", (unsigned long)del_time);
|
std::string query = StringFormat("DELETE FROM inventory_snapshots WHERE time_index <= %lu", (unsigned long)del_time);
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
||||||
|
{
|
||||||
|
|
||||||
|
TimeOfDay_Struct eqTime;
|
||||||
|
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success() || results.RowCount() == 0)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults.");
|
||||||
|
eqTime.minute = 0;
|
||||||
|
eqTime.hour = 9;
|
||||||
|
eqTime.day = 1;
|
||||||
|
eqTime.month = 1;
|
||||||
|
eqTime.year = 3100;
|
||||||
|
realtime = time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
eqTime.minute = atoi(row[0]);
|
||||||
|
eqTime.hour = atoi(row[1]);
|
||||||
|
eqTime.day = atoi(row[2]);
|
||||||
|
eqTime.month = atoi(row[3]);
|
||||||
|
eqTime.year = atoi(row[4]);
|
||||||
|
realtime = atoi(row[5]);
|
||||||
|
|
||||||
|
return eqTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year)
|
||||||
|
{
|
||||||
|
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(0));
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
return results.Success();
|
||||||
|
|
||||||
|
}
|
||||||
@ -241,6 +241,8 @@ public:
|
|||||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||||
|
|
||||||
void AddReport(std::string who, std::string against, std::string lines);
|
void AddReport(std::string who, std::string against, std::string lines);
|
||||||
|
struct TimeOfDay_Struct LoadTime(time_t &realtime);
|
||||||
|
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||||
void ClearMerchantTemp();
|
void ClearMerchantTemp();
|
||||||
void ClearPTimers(uint32 charid);
|
void ClearPTimers(uint32 charid);
|
||||||
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
|
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
|
||||||
|
|||||||
@ -493,7 +493,7 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
/* Check for a new version of this script, the arg passed
|
/* Check for a new version of this script, the arg passed
|
||||||
would have to be higher than the copy they have downloaded
|
would have to be higher than the copy they have downloaded
|
||||||
locally and they will re fetch */
|
locally and they will re fetch */
|
||||||
system("perl eqemu_update.pl V 13");
|
system("perl eqemu_update.pl V 14");
|
||||||
|
|
||||||
/* Run Automatic Database Upgrade Script */
|
/* Run Automatic Database Upgrade Script */
|
||||||
system("perl eqemu_update.pl ran_from_world");
|
system("perl eqemu_update.pl ran_from_world");
|
||||||
|
|||||||
@ -254,10 +254,6 @@ void EQEmuConfig::do_files(TiXmlElement *ele)
|
|||||||
if (text) {
|
if (text) {
|
||||||
OpCodesFile = text;
|
OpCodesFile = text;
|
||||||
}
|
}
|
||||||
text = ParseTextBlock(ele, "eqtime", true);
|
|
||||||
if (text) {
|
|
||||||
EQTimeFile = text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQEmuConfig::do_directories(TiXmlElement *ele)
|
void EQEmuConfig::do_directories(TiXmlElement *ele)
|
||||||
@ -408,9 +404,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
|||||||
if (var_name == "OpCodesFile") {
|
if (var_name == "OpCodesFile") {
|
||||||
return (OpCodesFile);
|
return (OpCodesFile);
|
||||||
}
|
}
|
||||||
if (var_name == "EQTimeFile") {
|
|
||||||
return (EQTimeFile);
|
|
||||||
}
|
|
||||||
if (var_name == "MapDir") {
|
if (var_name == "MapDir") {
|
||||||
return (MapDir);
|
return (MapDir);
|
||||||
}
|
}
|
||||||
@ -475,7 +468,6 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
||||||
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
||||||
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
||||||
std::cout << "EQTimeFile = " << EQTimeFile << std::endl;
|
|
||||||
std::cout << "MapDir = " << MapDir << std::endl;
|
std::cout << "MapDir = " << MapDir << std::endl;
|
||||||
std::cout << "QuestDir = " << QuestDir << std::endl;
|
std::cout << "QuestDir = " << QuestDir << std::endl;
|
||||||
std::cout << "PluginDir = " << PluginDir << std::endl;
|
std::cout << "PluginDir = " << PluginDir << std::endl;
|
||||||
|
|||||||
@ -79,7 +79,6 @@ class EQEmuConfig : public XMLParser
|
|||||||
// From <files/>
|
// From <files/>
|
||||||
std::string SpellsFile;
|
std::string SpellsFile;
|
||||||
std::string OpCodesFile;
|
std::string OpCodesFile;
|
||||||
std::string EQTimeFile;
|
|
||||||
|
|
||||||
// From <directories/>
|
// From <directories/>
|
||||||
std::string MapDir;
|
std::string MapDir;
|
||||||
@ -154,7 +153,6 @@ class EQEmuConfig : public XMLParser
|
|||||||
// Files
|
// Files
|
||||||
SpellsFile = "spells_us.txt";
|
SpellsFile = "spells_us.txt";
|
||||||
OpCodesFile = "opcodes.conf";
|
OpCodesFile = "opcodes.conf";
|
||||||
EQTimeFile = "eqtime.cfg";
|
|
||||||
// Dirs
|
// Dirs
|
||||||
MapDir = "Maps";
|
MapDir = "Maps";
|
||||||
QuestDir = "quests";
|
QuestDir = "quests";
|
||||||
|
|||||||
@ -133,72 +133,6 @@ int EQTime::SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//saveFile and loadFile need to use long for the save datatype...
|
|
||||||
//For some reason, ifstream/ofstream have problems with EQEmu datatypes in files.
|
|
||||||
bool EQTime::saveFile(const char *filename)
|
|
||||||
{
|
|
||||||
std::ofstream of;
|
|
||||||
of.open(filename);
|
|
||||||
if (!of)
|
|
||||||
{
|
|
||||||
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//Enable for debugging
|
|
||||||
of << EQT_VERSION << std::endl;
|
|
||||||
of << (long)eqTime.start_eqtime.day << std::endl;
|
|
||||||
of << (long)eqTime.start_eqtime.hour << std::endl;
|
|
||||||
of << (long)eqTime.start_eqtime.minute << std::endl;
|
|
||||||
of << (long)eqTime.start_eqtime.month << std::endl;
|
|
||||||
of << eqTime.start_eqtime.year << std::endl;
|
|
||||||
of << eqTime.start_realtime << std::endl;
|
|
||||||
of.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQTime::loadFile(const char *filename)
|
|
||||||
{
|
|
||||||
int version=0;
|
|
||||||
long in_data=0;
|
|
||||||
std::ifstream in;
|
|
||||||
in.open(filename);
|
|
||||||
if(!in)
|
|
||||||
{
|
|
||||||
Log.Out(Logs::General, Logs::Error, "Could not load EQTime file %s", filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
in >> version;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
if(version != EQT_VERSION)
|
|
||||||
{
|
|
||||||
Log.Out(Logs::General, Logs::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//in >> eqTime.start_eqtime.day;
|
|
||||||
in >> in_data;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
eqTime.start_eqtime.day = in_data;
|
|
||||||
//in >> eqTime.start_eqtime.hour;
|
|
||||||
in >> in_data;
|
|
||||||
eqTime.start_eqtime.hour = in_data;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
//in >> eqTime.start_eqtime.minute;
|
|
||||||
in >> in_data;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
eqTime.start_eqtime.minute = in_data;
|
|
||||||
//in >> eqTime.start_eqtime.month;
|
|
||||||
in >> in_data;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
eqTime.start_eqtime.month = in_data;
|
|
||||||
in >> eqTime.start_eqtime.year;
|
|
||||||
in.ignore(80, '\n');
|
|
||||||
in >> eqTime.start_realtime;
|
|
||||||
//Enable for debugging...
|
|
||||||
in.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
|
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
|
||||||
if (base->year > test->year)
|
if (base->year > test->year)
|
||||||
return(true);
|
return(true);
|
||||||
|
|||||||
@ -39,12 +39,6 @@ public:
|
|||||||
|
|
||||||
static void ToString(TimeOfDay_Struct *t, std::string &str);
|
static void ToString(TimeOfDay_Struct *t, std::string &str);
|
||||||
|
|
||||||
//Database functions
|
|
||||||
//bool loadDB(Database q);
|
|
||||||
//bool setDB(Database q);
|
|
||||||
bool loadFile(const char *filename);
|
|
||||||
bool saveFile(const char *filename);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//This is our reference clock.
|
//This is our reference clock.
|
||||||
eqTimeOfDay eqTime;
|
eqTimeOfDay eqTime;
|
||||||
|
|||||||
@ -233,6 +233,8 @@ enum { //some random constants
|
|||||||
#define GROUP_EXP_PER_POINT 1000
|
#define GROUP_EXP_PER_POINT 1000
|
||||||
#define RAID_EXP_PER_POINT 2000
|
#define RAID_EXP_PER_POINT 2000
|
||||||
|
|
||||||
|
#define ZONE_CONTROLLER_NPC_ID 10
|
||||||
|
|
||||||
//Some hard coded statuses from commands and other places:
|
//Some hard coded statuses from commands and other places:
|
||||||
enum {
|
enum {
|
||||||
minStatusToBeGM = 40,
|
minStatusToBeGM = 40,
|
||||||
|
|||||||
@ -41,6 +41,7 @@ F(ac)
|
|||||||
F(deity)
|
F(deity)
|
||||||
F(skillmodvalue)
|
F(skillmodvalue)
|
||||||
F(UNK033)
|
F(UNK033)
|
||||||
|
F(skillmodmax)
|
||||||
F(skillmodtype)
|
F(skillmodtype)
|
||||||
F(banedmgrace)
|
F(banedmgrace)
|
||||||
F(banedmgamt)
|
F(banedmgamt)
|
||||||
@ -172,7 +173,10 @@ F(bardlevel)
|
|||||||
F(questitemflag)
|
F(questitemflag)
|
||||||
F(svcorruption)
|
F(svcorruption)
|
||||||
F(purity)
|
F(purity)
|
||||||
|
F(evoitem)
|
||||||
|
F(evoid)
|
||||||
F(evolvinglevel)
|
F(evolvinglevel)
|
||||||
|
F(evomax)
|
||||||
F(backstabdmg)
|
F(backstabdmg)
|
||||||
F(dsmitigation)
|
F(dsmitigation)
|
||||||
F(heroic_str)
|
F(heroic_str)
|
||||||
|
|||||||
@ -130,6 +130,7 @@ struct Item_Struct {
|
|||||||
uint32 Deity; // Bitmask of Deities that can equip this item
|
uint32 Deity; // Bitmask of Deities that can equip this item
|
||||||
//uint32 Unk033
|
//uint32 Unk033
|
||||||
int32 SkillModValue; // % Mod to skill specified in SkillModType
|
int32 SkillModValue; // % Mod to skill specified in SkillModType
|
||||||
|
int32 SkillModMax; // Max skill point modification
|
||||||
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||||
uint32 BaneDmgRace; // Bane Damage Race
|
uint32 BaneDmgRace; // Bane Damage Race
|
||||||
int8 BaneDmgAmt; // Bane Damage Body Amount
|
int8 BaneDmgAmt; // Bane Damage Body Amount
|
||||||
@ -218,7 +219,10 @@ struct Item_Struct {
|
|||||||
// Begin SoF Fields
|
// Begin SoF Fields
|
||||||
int32 SVCorruption;
|
int32 SVCorruption;
|
||||||
uint32 Purity;
|
uint32 Purity;
|
||||||
|
uint8 EvolvingItem;
|
||||||
|
uint32 EvolvingID;
|
||||||
uint8 EvolvingLevel;
|
uint8 EvolvingLevel;
|
||||||
|
uint8 EvolvingMax;
|
||||||
uint32 BackstabDmg;
|
uint32 BackstabDmg;
|
||||||
uint32 DSMitigation;
|
uint32 DSMitigation;
|
||||||
int32 HeroicStr;
|
int32 HeroicStr;
|
||||||
|
|||||||
@ -5231,19 +5231,19 @@ namespace RoF
|
|||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
hdr.unknown048 = 0;
|
hdr.unknown048 = 0;
|
||||||
hdr.unknown052 = 0;
|
hdr.unknown052 = 0;
|
||||||
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
hdr.isEvolving = item->EvolvingItem;
|
||||||
ss.write((const char*)&hdr, sizeof(RoF::structs::ItemSerializationHeader));
|
ss.write((const char*)&hdr, sizeof(RoF::structs::ItemSerializationHeader));
|
||||||
|
|
||||||
if (item->EvolvingLevel > 0) {
|
if (item->EvolvingItem > 0) {
|
||||||
RoF::structs::EvolvingItem evotop;
|
RoF::structs::EvolvingItem evotop;
|
||||||
evotop.unknown001 = 0;
|
evotop.unknown001 = 0;
|
||||||
evotop.unknown002 = 0;
|
evotop.unknown002 = 0;
|
||||||
evotop.unknown003 = 0;
|
evotop.unknown003 = 0;
|
||||||
evotop.unknown004 = 0;
|
evotop.unknown004 = 0;
|
||||||
evotop.evoLevel = item->EvolvingLevel;
|
evotop.evoLevel = item->EvolvingLevel;
|
||||||
evotop.progress = 95.512;
|
evotop.progress = 0;
|
||||||
evotop.Activated = 1;
|
evotop.Activated = 1;
|
||||||
evotop.evomaxlevel = 7;
|
evotop.evomaxlevel = item->EvolvingMax;
|
||||||
ss.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem));
|
ss.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem));
|
||||||
}
|
}
|
||||||
//ORNAMENT IDFILE / ICON
|
//ORNAMENT IDFILE / ICON
|
||||||
@ -5353,7 +5353,7 @@ namespace RoF
|
|||||||
ibs.Races = item->Races;
|
ibs.Races = item->Races;
|
||||||
ibs.Deity = item->Deity;
|
ibs.Deity = item->Deity;
|
||||||
ibs.SkillModValue = item->SkillModValue;
|
ibs.SkillModValue = item->SkillModValue;
|
||||||
ibs.SkillModMax = 0xffffffff;
|
ibs.SkillModMax = item->SkillModMax;
|
||||||
ibs.SkillModType = (int8)(item->SkillModType);
|
ibs.SkillModType = (int8)(item->SkillModType);
|
||||||
ibs.SkillModExtra = 0;
|
ibs.SkillModExtra = 0;
|
||||||
ibs.BaneDmgRace = item->BaneDmgRace;
|
ibs.BaneDmgRace = item->BaneDmgRace;
|
||||||
|
|||||||
@ -5432,19 +5432,19 @@ namespace RoF2
|
|||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
hdr.unknown048 = 0;
|
hdr.unknown048 = 0;
|
||||||
hdr.unknown052 = 0;
|
hdr.unknown052 = 0;
|
||||||
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
hdr.isEvolving = item->EvolvingItem;
|
||||||
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
||||||
|
|
||||||
if (item->EvolvingLevel > 0) {
|
if (item->EvolvingItem > 0) {
|
||||||
RoF2::structs::EvolvingItem evotop;
|
RoF2::structs::EvolvingItem evotop;
|
||||||
evotop.unknown001 = 0;
|
evotop.unknown001 = 0;
|
||||||
evotop.unknown002 = 0;
|
evotop.unknown002 = 0;
|
||||||
evotop.unknown003 = 0;
|
evotop.unknown003 = 0;
|
||||||
evotop.unknown004 = 0;
|
evotop.unknown004 = 0;
|
||||||
evotop.evoLevel = item->EvolvingLevel;
|
evotop.evoLevel = item->EvolvingLevel;
|
||||||
evotop.progress = 95.512;
|
evotop.progress = 0;
|
||||||
evotop.Activated = 1;
|
evotop.Activated = 1;
|
||||||
evotop.evomaxlevel = 7;
|
evotop.evomaxlevel = item->EvolvingMax;
|
||||||
ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
|
ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
|
||||||
}
|
}
|
||||||
//ORNAMENT IDFILE / ICON
|
//ORNAMENT IDFILE / ICON
|
||||||
@ -5554,7 +5554,7 @@ namespace RoF2
|
|||||||
ibs.Races = item->Races;
|
ibs.Races = item->Races;
|
||||||
ibs.Deity = item->Deity;
|
ibs.Deity = item->Deity;
|
||||||
ibs.SkillModValue = item->SkillModValue;
|
ibs.SkillModValue = item->SkillModValue;
|
||||||
ibs.SkillModMax = 0xffffffff;
|
ibs.SkillModMax = item->SkillModMax;
|
||||||
ibs.SkillModType = (int8)(item->SkillModType);
|
ibs.SkillModType = (int8)(item->SkillModType);
|
||||||
ibs.SkillModExtra = 0;
|
ibs.SkillModExtra = 0;
|
||||||
ibs.BaneDmgRace = item->BaneDmgRace;
|
ibs.BaneDmgRace = item->BaneDmgRace;
|
||||||
|
|||||||
@ -3835,19 +3835,19 @@ namespace UF
|
|||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
hdr.unknown048 = 0;
|
hdr.unknown048 = 0;
|
||||||
hdr.unknown052 = 0;
|
hdr.unknown052 = 0;
|
||||||
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
hdr.isEvolving = item->EvolvingItem;
|
||||||
ss.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader));
|
ss.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader));
|
||||||
|
|
||||||
if (item->EvolvingLevel > 0) {
|
if (item->EvolvingItem > 0) {
|
||||||
UF::structs::EvolvingItem evotop;
|
UF::structs::EvolvingItem evotop;
|
||||||
evotop.unknown001 = 0;
|
evotop.unknown001 = 0;
|
||||||
evotop.unknown002 = 0;
|
evotop.unknown002 = 0;
|
||||||
evotop.unknown003 = 0;
|
evotop.unknown003 = 0;
|
||||||
evotop.unknown004 = 0;
|
evotop.unknown004 = 0;
|
||||||
evotop.evoLevel = item->EvolvingLevel;
|
evotop.evoLevel = item->EvolvingLevel;
|
||||||
evotop.progress = 95.512;
|
evotop.progress = 0;
|
||||||
evotop.Activated = 1;
|
evotop.Activated = 1;
|
||||||
evotop.evomaxlevel = 7;
|
evotop.evomaxlevel = item->EvolvingMax;
|
||||||
ss.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
|
ss.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
|
||||||
}
|
}
|
||||||
//ORNAMENT IDFILE / ICON -
|
//ORNAMENT IDFILE / ICON -
|
||||||
@ -3947,7 +3947,7 @@ namespace UF
|
|||||||
ibs.Races = item->Races;
|
ibs.Races = item->Races;
|
||||||
ibs.Deity = item->Deity;
|
ibs.Deity = item->Deity;
|
||||||
ibs.SkillModValue = item->SkillModValue;
|
ibs.SkillModValue = item->SkillModValue;
|
||||||
ibs.unknown5 = 0;
|
ibs.SkillModMax = item->SkillModMax;
|
||||||
ibs.SkillModType = item->SkillModType;
|
ibs.SkillModType = item->SkillModType;
|
||||||
ibs.BaneDmgRace = item->BaneDmgRace;
|
ibs.BaneDmgRace = item->BaneDmgRace;
|
||||||
ibs.BaneDmgBody = item->BaneDmgBody;
|
ibs.BaneDmgBody = item->BaneDmgBody;
|
||||||
|
|||||||
@ -4103,7 +4103,7 @@ struct ItemBodyStruct
|
|||||||
uint32 Races;
|
uint32 Races;
|
||||||
uint32 Deity;
|
uint32 Deity;
|
||||||
int32 SkillModValue;
|
int32 SkillModValue;
|
||||||
uint32 unknown5;
|
uint32 SkillModMax;
|
||||||
uint32 SkillModType;
|
uint32 SkillModType;
|
||||||
uint32 BaneDmgRace;
|
uint32 BaneDmgRace;
|
||||||
uint32 BaneDmgBody;
|
uint32 BaneDmgBody;
|
||||||
|
|||||||
@ -248,6 +248,26 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
|
|||||||
m_activeRuleset = ruleset_id;
|
m_activeRuleset = ruleset_id;
|
||||||
m_activeName = ruleset_name;
|
m_activeName = ruleset_name;
|
||||||
|
|
||||||
|
/* Load default ruleset values first if we're loading something other than default */
|
||||||
|
if (strcasecmp(ruleset_name, "default") != 0){
|
||||||
|
std::string default_ruleset_name = "default";
|
||||||
|
int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str());
|
||||||
|
if (default_ruleset_id < 0) {
|
||||||
|
Log.Out(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.", default_ruleset_name.c_str());
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
Log.Out(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", default_ruleset_name.c_str(), default_ruleset_id);
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d", default_ruleset_id);
|
||||||
|
auto results = database->QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
if (!SetRule(row[0], row[1], nullptr, false))
|
||||||
|
Log.Out(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id);
|
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id);
|
||||||
auto results = database->QueryDatabase(query);
|
auto results = database->QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
|
|||||||
@ -233,6 +233,7 @@ RULE_BOOL(Zone, LevelBasedEXPMods, false) // Allows you to use the level_exp_mod
|
|||||||
RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
||||||
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
||||||
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||||
|
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Map)
|
RULE_CATEGORY(Map)
|
||||||
@ -459,6 +460,8 @@ RULE_BOOL(Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arr
|
|||||||
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
RULE_BOOL(Combat, MeleePush, true) // enable melee push
|
||||||
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
||||||
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
||||||
|
RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist another NPC at once
|
||||||
|
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
@ -494,6 +497,7 @@ RULE_INT(Aggro, PetSpellAggroMod, 10)
|
|||||||
RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate generate this much hate on a Tunnel Vision mob
|
RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate generate this much hate on a Tunnel Vision mob
|
||||||
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
|
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
|
||||||
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
|
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
|
||||||
|
RULE_BOOL(Aggro, AllowTickPulling, false) // tick pulling is an exploit in an NPC's call for help fixed sometime in 2006 on live
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(TaskSystem)
|
RULE_CATEGORY(TaskSystem)
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||||
|
#include <algorithm>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "classes.h"
|
#include "classes.h"
|
||||||
#include "eq_packet_structs.h"
|
#include "eq_packet_structs.h"
|
||||||
#include "eqemu_exception.h"
|
#include "eqemu_exception.h"
|
||||||
@ -802,31 +806,32 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) {
|
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id)
|
||||||
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
|
{
|
||||||
|
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8 *>(data), size, items, max_item_id);
|
||||||
|
|
||||||
char ndbuffer[4];
|
char ndbuffer[4];
|
||||||
bool disableNoRent = false;
|
bool disableNoRent = false;
|
||||||
if(GetVariable("disablenorent", ndbuffer, 4)) {
|
if (GetVariable("disablenorent", ndbuffer, 4)) {
|
||||||
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
if (ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
||||||
disableNoRent = true;
|
disableNoRent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool disableNoDrop = false;
|
bool disableNoDrop = false;
|
||||||
if(GetVariable("disablenodrop", ndbuffer, 4)) {
|
if (GetVariable("disablenodrop", ndbuffer, 4)) {
|
||||||
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
if (ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
||||||
disableNoDrop = true;
|
disableNoDrop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool disableLoreGroup = false;
|
bool disableLoreGroup = false;
|
||||||
if(GetVariable("disablelore", ndbuffer, 4)) {
|
if (GetVariable("disablelore", ndbuffer, 4)) {
|
||||||
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
if (ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
||||||
disableLoreGroup = true;
|
disableLoreGroup = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool disableNoTransfer = false;
|
bool disableNoTransfer = false;
|
||||||
if(GetVariable("disablenotransfer", ndbuffer, 4)) {
|
if (GetVariable("disablenotransfer", ndbuffer, 4)) {
|
||||||
if(ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
if (ndbuffer[0] == '1' && ndbuffer[1] == '\0') {
|
||||||
disableNoTransfer = true;
|
disableNoTransfer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -843,13 +848,13 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
memset(&item, 0, sizeof(Item_Struct));
|
memset(&item, 0, sizeof(Item_Struct));
|
||||||
|
|
||||||
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
||||||
strcpy(item.Name,row[ItemField::name]);
|
strcpy(item.Name, row[ItemField::name]);
|
||||||
strcpy(item.Lore,row[ItemField::lore]);
|
strcpy(item.Lore, row[ItemField::lore]);
|
||||||
strcpy(item.IDFile,row[ItemField::idfile]);
|
strcpy(item.IDFile, row[ItemField::idfile]);
|
||||||
|
|
||||||
item.ID = (uint32)atoul(row[ItemField::id]);
|
item.ID = (uint32)atoul(row[ItemField::id]);
|
||||||
item.Weight = (uint8)atoi(row[ItemField::weight]);
|
item.Weight = (uint8)atoi(row[ItemField::weight]);
|
||||||
@ -860,7 +865,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.Price = (uint32)atoul(row[ItemField::price]);
|
item.Price = (uint32)atoul(row[ItemField::price]);
|
||||||
item.Icon = (uint32)atoul(row[ItemField::icon]);
|
item.Icon = (uint32)atoul(row[ItemField::icon]);
|
||||||
item.BenefitFlag = (atoul(row[ItemField::benefitflag]) != 0);
|
item.BenefitFlag = (atoul(row[ItemField::benefitflag]) != 0);
|
||||||
item.Tradeskills = (atoi(row[ItemField::tradeskills])==0) ? false : true;
|
item.Tradeskills = (atoi(row[ItemField::tradeskills]) == 0) ? false : true;
|
||||||
item.CR = (int8)atoi(row[ItemField::cr]);
|
item.CR = (int8)atoi(row[ItemField::cr]);
|
||||||
item.DR = (int8)atoi(row[ItemField::dr]);
|
item.DR = (int8)atoi(row[ItemField::dr]);
|
||||||
item.PR = (int8)atoi(row[ItemField::pr]);
|
item.PR = (int8)atoi(row[ItemField::pr]);
|
||||||
@ -878,12 +883,12 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.AC = (int32)atoul(row[ItemField::ac]);
|
item.AC = (int32)atoul(row[ItemField::ac]);
|
||||||
item.Deity = (uint32)atoul(row[ItemField::deity]);
|
item.Deity = (uint32)atoul(row[ItemField::deity]);
|
||||||
item.SkillModValue = (int32)atoul(row[ItemField::skillmodvalue]);
|
item.SkillModValue = (int32)atoul(row[ItemField::skillmodvalue]);
|
||||||
|
item.SkillModMax = (int32)atoul(row[ItemField::skillmodmax]);
|
||||||
item.SkillModType = (uint32)atoul(row[ItemField::skillmodtype]);
|
item.SkillModType = (uint32)atoul(row[ItemField::skillmodtype]);
|
||||||
item.BaneDmgRace = (uint32)atoul(row[ItemField::banedmgrace]);
|
item.BaneDmgRace = (uint32)atoul(row[ItemField::banedmgrace]);
|
||||||
item.BaneDmgAmt = (int8)atoi(row[ItemField::banedmgamt]);
|
item.BaneDmgAmt = (int8)atoi(row[ItemField::banedmgamt]);
|
||||||
item.BaneDmgBody = (uint32)atoul(row[ItemField::banedmgbody]);
|
item.BaneDmgBody = (uint32)atoul(row[ItemField::banedmgbody]);
|
||||||
item.Magic = (atoi(row[ItemField::magic])==0) ? false : true;
|
item.Magic = (atoi(row[ItemField::magic]) == 0) ? false : true;
|
||||||
item.CastTime_ = (int32)atoul(row[ItemField::casttime_]);
|
item.CastTime_ = (int32)atoul(row[ItemField::casttime_]);
|
||||||
item.ReqLevel = (uint8)atoi(row[ItemField::reqlevel]);
|
item.ReqLevel = (uint8)atoi(row[ItemField::reqlevel]);
|
||||||
item.BardType = (uint32)atoul(row[ItemField::bardtype]);
|
item.BardType = (uint32)atoul(row[ItemField::bardtype]);
|
||||||
@ -927,7 +932,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.FactionAmt3 = (int32)atoul(row[ItemField::factionamt3]);
|
item.FactionAmt3 = (int32)atoul(row[ItemField::factionamt3]);
|
||||||
item.FactionAmt4 = (int32)atoul(row[ItemField::factionamt4]);
|
item.FactionAmt4 = (int32)atoul(row[ItemField::factionamt4]);
|
||||||
|
|
||||||
strcpy(item.CharmFile,row[ItemField::charmfile]);
|
strcpy(item.CharmFile, row[ItemField::charmfile]);
|
||||||
|
|
||||||
item.AugType = (uint32)atoul(row[ItemField::augtype]);
|
item.AugType = (uint32)atoul(row[ItemField::augtype]);
|
||||||
item.AugSlotType[0] = (uint8)atoi(row[ItemField::augslot1type]);
|
item.AugSlotType[0] = (uint8)atoi(row[ItemField::augslot1type]);
|
||||||
@ -953,23 +958,23 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.LDoNPrice = (uint32)atoul(row[ItemField::ldonprice]);
|
item.LDoNPrice = (uint32)atoul(row[ItemField::ldonprice]);
|
||||||
item.LDoNSold = (uint32)atoul(row[ItemField::ldonsold]);
|
item.LDoNSold = (uint32)atoul(row[ItemField::ldonsold]);
|
||||||
item.BagType = (uint8)atoi(row[ItemField::bagtype]);
|
item.BagType = (uint8)atoi(row[ItemField::bagtype]);
|
||||||
item.BagSlots = (uint8)atoi(row[ItemField::bagslots]);
|
item.BagSlots = (uint8)std::min(atoi(row[ItemField::bagslots]), 10); // FIXME: remove when big bags supported
|
||||||
item.BagSize = (uint8)atoi(row[ItemField::bagsize]);
|
item.BagSize = (uint8)atoi(row[ItemField::bagsize]);
|
||||||
item.BagWR = (uint8)atoi(row[ItemField::bagwr]);
|
item.BagWR = (uint8)atoi(row[ItemField::bagwr]);
|
||||||
item.Book = (uint8)atoi(row[ItemField::book]);
|
item.Book = (uint8)atoi(row[ItemField::book]);
|
||||||
item.BookType = (uint32)atoul(row[ItemField::booktype]);
|
item.BookType = (uint32)atoul(row[ItemField::booktype]);
|
||||||
|
|
||||||
strcpy(item.Filename,row[ItemField::filename]);
|
strcpy(item.Filename, row[ItemField::filename]);
|
||||||
|
|
||||||
item.BaneDmgRaceAmt = (uint32)atoul(row[ItemField::banedmgraceamt]);
|
item.BaneDmgRaceAmt = (uint32)atoul(row[ItemField::banedmgraceamt]);
|
||||||
item.AugRestrict = (uint32)atoul(row[ItemField::augrestrict]);
|
item.AugRestrict = (uint32)atoul(row[ItemField::augrestrict]);
|
||||||
item.LoreGroup = disableLoreGroup ? (uint8)atoi("0") : atoi(row[ItemField::loregroup]);
|
item.LoreGroup = disableLoreGroup ? (uint8)atoi("0") : atoi(row[ItemField::loregroup]);
|
||||||
item.LoreFlag = item.LoreGroup!=0;
|
item.LoreFlag = item.LoreGroup != 0;
|
||||||
item.PendingLoreFlag = (atoi(row[ItemField::pendingloreflag])==0) ? false : true;
|
item.PendingLoreFlag = (atoi(row[ItemField::pendingloreflag]) == 0) ? false : true;
|
||||||
item.ArtifactFlag = (atoi(row[ItemField::artifactflag])==0) ? false : true;
|
item.ArtifactFlag = (atoi(row[ItemField::artifactflag]) == 0) ? false : true;
|
||||||
item.SummonedFlag = (atoi(row[ItemField::summonedflag])==0) ? false : true;
|
item.SummonedFlag = (atoi(row[ItemField::summonedflag]) == 0) ? false : true;
|
||||||
item.Favor = (uint32)atoul(row[ItemField::favor]);
|
item.Favor = (uint32)atoul(row[ItemField::favor]);
|
||||||
item.FVNoDrop = (atoi(row[ItemField::fvnodrop])==0) ? false : true;
|
item.FVNoDrop = (atoi(row[ItemField::fvnodrop]) == 0) ? false : true;
|
||||||
item.Endur = (uint32)atoul(row[ItemField::endur]);
|
item.Endur = (uint32)atoul(row[ItemField::endur]);
|
||||||
item.DotShielding = (uint32)atoul(row[ItemField::dotshielding]);
|
item.DotShielding = (uint32)atoul(row[ItemField::dotshielding]);
|
||||||
item.Attack = (uint32)atoul(row[ItemField::attack]);
|
item.Attack = (uint32)atoul(row[ItemField::attack]);
|
||||||
@ -982,20 +987,20 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.RecastType = (uint32)atoul(row[ItemField::recasttype]);
|
item.RecastType = (uint32)atoul(row[ItemField::recasttype]);
|
||||||
item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]);
|
item.GuildFavor = (uint32)atoul(row[ItemField::guildfavor]);
|
||||||
item.AugDistiller = (uint32)atoul(row[ItemField::augdistiller]);
|
item.AugDistiller = (uint32)atoul(row[ItemField::augdistiller]);
|
||||||
item.Attuneable = (atoi(row[ItemField::attuneable])==0) ? false : true;
|
item.Attuneable = (atoi(row[ItemField::attuneable]) == 0) ? false : true;
|
||||||
item.NoPet = (atoi(row[ItemField::nopet])==0) ? false : true;
|
item.NoPet = (atoi(row[ItemField::nopet]) == 0) ? false : true;
|
||||||
item.PointType = (uint32)atoul(row[ItemField::pointtype]);
|
item.PointType = (uint32)atoul(row[ItemField::pointtype]);
|
||||||
item.PotionBelt = (atoi(row[ItemField::potionbelt])==0) ? false : true;
|
item.PotionBelt = (atoi(row[ItemField::potionbelt]) == 0) ? false : true;
|
||||||
item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots])==0) ? false : true;
|
item.PotionBeltSlots = (atoi(row[ItemField::potionbeltslots]) == 0) ? false : true;
|
||||||
item.StackSize = (uint16)atoi(row[ItemField::stacksize]);
|
item.StackSize = (uint16)atoi(row[ItemField::stacksize]);
|
||||||
item.NoTransfer = disableNoTransfer ? false : (atoi(row[ItemField::notransfer])==0) ? false : true;
|
item.NoTransfer = disableNoTransfer ? false : (atoi(row[ItemField::notransfer]) == 0) ? false : true;
|
||||||
item.Stackable = (atoi(row[ItemField::stackable])==0) ? false : true;
|
item.Stackable = (atoi(row[ItemField::stackable]) == 0) ? false : true;
|
||||||
item.Click.Effect = (uint32)atoul(row[ItemField::clickeffect]);
|
item.Click.Effect = (uint32)atoul(row[ItemField::clickeffect]);
|
||||||
item.Click.Type = (uint8)atoul(row[ItemField::clicktype]);
|
item.Click.Type = (uint8)atoul(row[ItemField::clicktype]);
|
||||||
item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]);
|
item.Click.Level = (uint8)atoul(row[ItemField::clicklevel]);
|
||||||
item.Click.Level2 = (uint8)atoul(row[ItemField::clicklevel2]);
|
item.Click.Level2 = (uint8)atoul(row[ItemField::clicklevel2]);
|
||||||
|
|
||||||
strcpy(item.CharmFile,row[ItemField::charmfile]);
|
strcpy(item.CharmFile, row[ItemField::charmfile]);
|
||||||
|
|
||||||
item.Proc.Effect = (int32)atoul(row[ItemField::proceffect]);
|
item.Proc.Effect = (int32)atoul(row[ItemField::proceffect]);
|
||||||
item.Proc.Type = (uint8)atoul(row[ItemField::proctype]);
|
item.Proc.Type = (uint8)atoul(row[ItemField::proctype]);
|
||||||
@ -1017,10 +1022,13 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.Bard.Type = (uint8)atoul(row[ItemField::bardtype]);
|
item.Bard.Type = (uint8)atoul(row[ItemField::bardtype]);
|
||||||
item.Bard.Level = (uint8)atoul(row[ItemField::bardlevel]);
|
item.Bard.Level = (uint8)atoul(row[ItemField::bardlevel]);
|
||||||
item.Bard.Level2 = (uint8)atoul(row[ItemField::bardlevel2]);
|
item.Bard.Level2 = (uint8)atoul(row[ItemField::bardlevel2]);
|
||||||
item.QuestItemFlag = (atoi(row[ItemField::questitemflag])==0) ? false : true;
|
item.QuestItemFlag = (atoi(row[ItemField::questitemflag]) == 0) ? false : true;
|
||||||
item.SVCorruption = (int32)atoi(row[ItemField::svcorruption]);
|
item.SVCorruption = (int32)atoi(row[ItemField::svcorruption]);
|
||||||
item.Purity = (uint32)atoul(row[ItemField::purity]);
|
item.Purity = (uint32)atoul(row[ItemField::purity]);
|
||||||
|
item.EvolvingItem = (uint8)atoul(row[ItemField::evoitem]);
|
||||||
|
item.EvolvingID = (uint8)atoul(row[ItemField::evoid]);
|
||||||
item.EvolvingLevel = (uint8)atoul(row[ItemField::evolvinglevel]);
|
item.EvolvingLevel = (uint8)atoul(row[ItemField::evolvinglevel]);
|
||||||
|
item.EvolvingMax = (uint8)atoul(row[ItemField::evomax]);
|
||||||
item.BackstabDmg = (uint32)atoul(row[ItemField::backstabdmg]);
|
item.BackstabDmg = (uint32)atoul(row[ItemField::backstabdmg]);
|
||||||
item.DSMitigation = (uint32)atoul(row[ItemField::dsmitigation]);
|
item.DSMitigation = (uint32)atoul(row[ItemField::dsmitigation]);
|
||||||
item.HeroicStr = (int32)atoi(row[ItemField::heroic_str]);
|
item.HeroicStr = (int32)atoi(row[ItemField::heroic_str]);
|
||||||
@ -1043,20 +1051,19 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
item.ExpendableArrow = (uint16)atoul(row[ItemField::expendablearrow]);
|
item.ExpendableArrow = (uint16)atoul(row[ItemField::expendablearrow]);
|
||||||
item.Clairvoyance = (uint32)atoul(row[ItemField::clairvoyance]);
|
item.Clairvoyance = (uint32)atoul(row[ItemField::clairvoyance]);
|
||||||
|
|
||||||
strcpy(item.ClickName,row[ItemField::clickname]);
|
strcpy(item.ClickName, row[ItemField::clickname]);
|
||||||
strcpy(item.ProcName,row[ItemField::procname]);
|
strcpy(item.ProcName, row[ItemField::procname]);
|
||||||
strcpy(item.WornName,row[ItemField::wornname]);
|
strcpy(item.WornName, row[ItemField::wornname]);
|
||||||
strcpy(item.FocusName,row[ItemField::focusname]);
|
strcpy(item.FocusName, row[ItemField::focusname]);
|
||||||
strcpy(item.ScrollName,row[ItemField::scrollname]);
|
strcpy(item.ScrollName, row[ItemField::scrollname]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hash.insert(item.ID, item);
|
hash.insert(item.ID, item);
|
||||||
} catch(std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
Log.Out(Logs::General, Logs::Error, "Database::LoadItems: %s", ex.what());
|
Log.Out(Logs::General, Logs::Error, "Database::LoadItems: %s", ex.what());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
|
||||||
|
|||||||
@ -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 9091
|
#define CURRENT_BINARY_DATABASE_VERSION 9094
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -23,7 +23,7 @@ if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
|||||||
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||||
|
|
||||||
#::: If current version is less than what world is reporting, then download a new one...
|
#::: If current version is less than what world is reporting, then download a new one...
|
||||||
$current_version = 13;
|
$current_version = 14;
|
||||||
|
|
||||||
if($ARGV[0] eq "V"){
|
if($ARGV[0] eq "V"){
|
||||||
if($ARGV[1] > $current_version){
|
if($ARGV[1] > $current_version){
|
||||||
@ -107,6 +107,38 @@ if($path eq ""){
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($ARGV[0] eq "install_peq_db"){
|
||||||
|
|
||||||
|
$db_name = "peq";
|
||||||
|
if($ARGV[1]){
|
||||||
|
$db_name = $ARGV[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = $db_name;
|
||||||
|
|
||||||
|
#::: Database Routines
|
||||||
|
print "MariaDB :: Creating Database '" . $db_name . "'\n";
|
||||||
|
print `"$path" --host $host --user $user --password="$pass" -N -B -e "DROP DATABASE IF EXISTS $db_name;"`;
|
||||||
|
print `"$path" --host $host --user $user --password="$pass" -N -B -e "CREATE DATABASE $db_name"`;
|
||||||
|
if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); }
|
||||||
|
if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); }
|
||||||
|
$bin_db_ver = trim($db_version[1]);
|
||||||
|
check_db_version_table();
|
||||||
|
$local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1"));
|
||||||
|
fetch_peq_db_full();
|
||||||
|
print "\nFetching Latest Database Updates...\n";
|
||||||
|
main_db_management();
|
||||||
|
print "\nApplying Latest Database Updates...\n";
|
||||||
|
main_db_management();
|
||||||
|
|
||||||
|
print get_mysql_result("UPDATE `launcher` SET `dynamics` = 30 WHERE `name` = 'zone'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($ARGV[0] eq "remove_duplicate_rules"){
|
||||||
|
remove_duplicate_rule_values();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if($ARGV[0] eq "installer"){
|
if($ARGV[0] eq "installer"){
|
||||||
print "Running EQEmu Server installer routines...\n";
|
print "Running EQEmu Server installer routines...\n";
|
||||||
mkdir('logs');
|
mkdir('logs');
|
||||||
@ -152,6 +184,7 @@ if($ARGV[0] eq "installer"){
|
|||||||
|
|
||||||
if($OS eq "Windows"){
|
if($OS eq "Windows"){
|
||||||
check_windows_firewall_rules();
|
check_windows_firewall_rules();
|
||||||
|
do_windows_login_server_setup();
|
||||||
}
|
}
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@ -251,6 +284,7 @@ sub show_menu_prompt {
|
|||||||
11 => \&fetch_latest_windows_binaries,
|
11 => \&fetch_latest_windows_binaries,
|
||||||
12 => \&fetch_server_dlls,
|
12 => \&fetch_server_dlls,
|
||||||
13 => \&do_windows_login_server_setup,
|
13 => \&do_windows_login_server_setup,
|
||||||
|
14 => \&remove_duplicate_rule_values,
|
||||||
19 => \&do_bots_db_schema_drop,
|
19 => \&do_bots_db_schema_drop,
|
||||||
20 => \&do_update_self,
|
20 => \&do_update_self,
|
||||||
0 => \&script_exit,
|
0 => \&script_exit,
|
||||||
@ -328,6 +362,7 @@ return <<EO_MENU;
|
|||||||
11) [Windows Server Build] :: Download Latest and Stable Server Build (Overwrites existing .exe's, includes .dll's)
|
11) [Windows Server Build] :: Download Latest and Stable Server Build (Overwrites existing .exe's, includes .dll's)
|
||||||
12) [Windows Server .dll's] :: Download Pre-Requisite Server .dll's
|
12) [Windows Server .dll's] :: Download Pre-Requisite Server .dll's
|
||||||
13) [Windows Server Loginserver Setup] :: Download and install Windows Loginserver
|
13) [Windows Server Loginserver Setup] :: Download and install Windows Loginserver
|
||||||
|
14) [Remove Duplicate Rule Values] :: Looks for redundant rule_values entries and removes them
|
||||||
19) [EQEmu DB Drop Bots Schema] :: Remove Bots schema and return database to normal state
|
19) [EQEmu DB Drop Bots Schema] :: Remove Bots schema and return database to normal state
|
||||||
20) [Update the updater] Force update this script (Redownload)
|
20) [Update the updater] Force update this script (Redownload)
|
||||||
0) Exit
|
0) Exit
|
||||||
@ -521,6 +556,33 @@ sub opcodes_fetch{
|
|||||||
print "\nDone...\n\n";
|
print "\nDone...\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub remove_duplicate_rule_values{
|
||||||
|
$ruleset_id = trim(get_mysql_result("SELECT `ruleset_id` FROM `rule_sets` WHERE `name` = 'default'"));
|
||||||
|
print "Default Ruleset ID: " . $ruleset_id . "\n";
|
||||||
|
|
||||||
|
$total_removed = 0;
|
||||||
|
#::: Store Default values...
|
||||||
|
$mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` = " . $ruleset_id);
|
||||||
|
my @lines = split("\n", $mysql_result);
|
||||||
|
foreach my $val (@lines){
|
||||||
|
my @values = split("\t", $val);
|
||||||
|
$rule_set_values{$values[1]}[0] = $values[2];
|
||||||
|
}
|
||||||
|
#::: Compare default values against other rulesets to check for duplicates...
|
||||||
|
$mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` != " . $ruleset_id);
|
||||||
|
my @lines = split("\n", $mysql_result);
|
||||||
|
foreach my $val (@lines){
|
||||||
|
my @values = split("\t", $val);
|
||||||
|
if($values[2] == $rule_set_values{$values[1]}[0]){
|
||||||
|
print "DUPLICATE : " . $values[1] . " (Ruleset (" . $values[0] . ")) matches default value of : " . $values[2] . ", removing...\n";
|
||||||
|
get_mysql_result("DELETE FROM `rule_values` WHERE `ruleset_id` = " . $values[0] . " AND `rule_name` = '" . $values[1] . "'");
|
||||||
|
$total_removed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Total duplicate rules removed... " . $total_removed . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
sub copy_file{
|
sub copy_file{
|
||||||
$l_source_file = $_[0];
|
$l_source_file = $_[0];
|
||||||
$l_dest_file = $_[1];
|
$l_dest_file = $_[1];
|
||||||
@ -1316,8 +1378,14 @@ sub run_database_check{
|
|||||||
|
|
||||||
@total_updates = ();
|
@total_updates = ();
|
||||||
|
|
||||||
|
#::: This is where we set checkpoints for where a database might be so we don't check so far back in the manifest...
|
||||||
|
$revision_check = 1000;
|
||||||
|
if(get_mysql_result("SHOW TABLES LIKE 'character_data'") ne ""){
|
||||||
|
$revision_check = 9000;
|
||||||
|
}
|
||||||
|
|
||||||
#::: Iterate through Manifest backwards from binary version down to local version...
|
#::: Iterate through Manifest backwards from binary version down to local version...
|
||||||
for($i = $bin_db_ver; $i > 1000; $i--){
|
for($i = $bin_db_ver; $i > $revision_check; $i--){
|
||||||
if(!defined($m_d{$i}[0])){ next; }
|
if(!defined($m_d{$i}[0])){ next; }
|
||||||
|
|
||||||
$file_name = trim($m_d{$i}[1]);
|
$file_name = trim($m_d{$i}[1]);
|
||||||
|
|||||||
255
utils/scripts/import_13th_floor.pl
Normal file
255
utils/scripts/import_13th_floor.pl
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#::: 13th floor import script
|
||||||
|
#::: Current Source: http://items.sodeq.org/download.php
|
||||||
|
#::: Authors: (Natedog, Akkadius)
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
use DBI;
|
||||||
|
use DBD::mysql;
|
||||||
|
|
||||||
|
my $database_name = "";
|
||||||
|
my $total_items = 0;
|
||||||
|
my $read_items_file = "items.txt"; #default
|
||||||
|
my $dbh = LoadMysql();
|
||||||
|
|
||||||
|
read_items_file_from_13th_floor_text();
|
||||||
|
update_items_table();
|
||||||
|
|
||||||
|
sub LoadMysql{
|
||||||
|
#::: Config Variables
|
||||||
|
my $confile = "eqemu_config.xml";
|
||||||
|
open(F, "<$confile") or die "Unable to open config: $confile\n";
|
||||||
|
my $indb = 0;
|
||||||
|
while(<F>) {
|
||||||
|
s/\r//g;
|
||||||
|
if(/<database>/i) { $indb = 1; }
|
||||||
|
next unless($indb == 1);
|
||||||
|
if(/<\/database>/i) { $indb = 0; last; }
|
||||||
|
if(/<host>(.*)<\/host>/i) { $host = $1; }
|
||||||
|
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
|
||||||
|
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
|
||||||
|
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
|
||||||
|
}
|
||||||
|
$database_name = $db;
|
||||||
|
#::: DATA SOURCE NAME
|
||||||
|
$dsn = "dbi:mysql:$db:localhost:3306";
|
||||||
|
#::: PERL DBI CONNECT
|
||||||
|
$connect = DBI->connect($dsn, $user, $pass);
|
||||||
|
return $connect;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub read_items_file_from_13th_floor_text {
|
||||||
|
|
||||||
|
#::: Read from file and place into array
|
||||||
|
open(F, "<" . $read_items_file) or die "Unable to open itemfile: " . $read_items_file . "\n";
|
||||||
|
my @item_file_lines = <F>;
|
||||||
|
close(F);
|
||||||
|
|
||||||
|
#::: Chomp this array...
|
||||||
|
my @newitem_file_lines;
|
||||||
|
chomp($item_file_lines[0]);
|
||||||
|
@fields = split("(?<!\\\\)\\|", $item_file_lines[0]);
|
||||||
|
|
||||||
|
my $sth = $dbh->prepare("SHOW TABLES LIKE 'items_floor'");
|
||||||
|
$sth->execute();
|
||||||
|
my $has_items_floor = $sth->fetchrow_array();
|
||||||
|
|
||||||
|
#::: If we have items_floor
|
||||||
|
if ($has_items_floor eq '') {
|
||||||
|
$dbh->do("CREATE TABLE `items_floor` (`" . join("` VARCHAR(64) NOT NULL DEFAULT '', `", @fields). "` VARCHAR(64) NOT NULL DEFAULT '', UNIQUE INDEX `ID` (`id`)) COLLATE='latin1_swedish_ci' ENGINE=MyISAM");
|
||||||
|
$dbh->do("ALTER TABLE `items_floor` CHANGE `id` `id` INT(11) NOT NULL DEFAULT '0'");
|
||||||
|
printf "Database items_floor created\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Create REPLACE INTO header and define worker variables...
|
||||||
|
$master_insert = "REPLACE INTO `items_floor` (" . join(",", @fields) . ") VALUES ";
|
||||||
|
$query_insert_ph = ""; #::: Used for building placeholder values in query Ex: (?, ?, ?)
|
||||||
|
@field_values = (); #::: Used for stuffing mysql field values
|
||||||
|
$query_count = 0; #::: Used for chunking query updates
|
||||||
|
$print_cycle = 0; #::: Counter for console updates
|
||||||
|
$start_time = time(); #::: Start time for import
|
||||||
|
$total_items_file = scalar(grep $_, @item_file_lines) - 1; #::: Total items in text file
|
||||||
|
|
||||||
|
#::: Iterate through each item in items.txt
|
||||||
|
for (1 .. $#item_file_lines) {
|
||||||
|
@f = split("(?<!\\\\)\\|", $item_file_lines[$_]);
|
||||||
|
|
||||||
|
#::: Build our individual prepared statement (?, ?) values in the insert_ph
|
||||||
|
#::: ?, ? placeholders will be resolved via @field_values in the execute
|
||||||
|
$query_insert_ph .= " (";
|
||||||
|
foreach (@f) {
|
||||||
|
push (@field_values, trim($_));
|
||||||
|
$query_insert_ph .= "?, ";
|
||||||
|
}
|
||||||
|
$query_insert_ph = substr($query_insert_ph, 0, -2);
|
||||||
|
$query_insert_ph .= "), ";
|
||||||
|
|
||||||
|
#::: Let's chunk our updates so we can break up the amount of individual queries
|
||||||
|
if($query_count > 500){
|
||||||
|
$query_insert_ph = substr($query_insert_ph, 0, -2);
|
||||||
|
$dbh->prepare($master_insert . " " . $query_insert_ph)->execute(@field_values);
|
||||||
|
$query_count = 0;
|
||||||
|
$query_insert_ph = "";
|
||||||
|
@field_values = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Print updates to console
|
||||||
|
if($print_cycle > 25){
|
||||||
|
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
|
||||||
|
$print_cycle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Counters
|
||||||
|
$total_items++;
|
||||||
|
$query_count++;
|
||||||
|
$print_cycle++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: One last processing print
|
||||||
|
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
|
||||||
|
|
||||||
|
printf "\n" . $total_items . " items added to database... Took " . (time() - $start_time) . " second(s)... \n";
|
||||||
|
|
||||||
|
print "Flipping slots 21 and 22...";
|
||||||
|
$rows_affected = $dbh->prepare("
|
||||||
|
UPDATE `items_floor`
|
||||||
|
SET `slots` = (`slots` ^ 6291456)
|
||||||
|
WHERE (`slots` & 6291456)
|
||||||
|
IN (2097152, 4194304)")->execute();
|
||||||
|
print " Rows affected (" . $rows_affected . ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub update_items_table {
|
||||||
|
|
||||||
|
#::: Keep Items table sane
|
||||||
|
$query_handle = $dbh->prepare("
|
||||||
|
ALTER TABLE `items`
|
||||||
|
MODIFY COLUMN `UNK132` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
|
||||||
|
");
|
||||||
|
$query_handle->execute();
|
||||||
|
|
||||||
|
my @matching_table;
|
||||||
|
my @missing_items_table;
|
||||||
|
my @missing_items_floor_table;
|
||||||
|
|
||||||
|
#::: Get columns from `items`
|
||||||
|
my $sth = $dbh->prepare("SHOW COLUMNS FROM `items`;");
|
||||||
|
$sth->execute();
|
||||||
|
my @items_table;
|
||||||
|
while (my @row = $sth->fetchrow_array()) {
|
||||||
|
push(@items_table, $row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Get columns from `items_floor`
|
||||||
|
$sth2 = $dbh->prepare("SHOW COLUMNS FROM `items_floor`");
|
||||||
|
$sth2->execute();
|
||||||
|
my @items_floor_table;
|
||||||
|
while (my @row = $sth2->fetchrow_array()) {
|
||||||
|
push(@items_floor_table, $row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Go through the original items table columns and line them up with what columns match on 13th floor
|
||||||
|
#::: This is so we can use the matching columns to update and insert item data into `items` table
|
||||||
|
foreach $value (@items_table) {
|
||||||
|
if ( grep( /^$value$/i, @items_floor_table ) ) {
|
||||||
|
push(@matching_table, $value);
|
||||||
|
} else {
|
||||||
|
#::: What values are we missing from EMU items table..
|
||||||
|
push(@missing_items_table, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: What values are we missing from.. 13thFloor
|
||||||
|
foreach $value (@items_floor_table) {
|
||||||
|
if ( grep( /^$value$/i, @items_table ) ) {
|
||||||
|
#DO NOTHING...
|
||||||
|
} else {
|
||||||
|
push(@missing_items_floor_table, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Go through the matched columns and build our query strings...
|
||||||
|
|
||||||
|
my $items_field_list = ""; #::: Build the field list for the INSERT (field1, field2)
|
||||||
|
my $items_floor_field_list = ""; #::: What fields we will select from items_floor table to insert into items (matched columns)
|
||||||
|
my $update_fields = ""; #::: To update an existing item entry if it exists...
|
||||||
|
|
||||||
|
foreach $match (@matching_table) {
|
||||||
|
$match = lc($match);
|
||||||
|
$update_fields .= "`" . $match . "` = fi.`" . $match . "`, ";
|
||||||
|
$items_field_list .= "`" . $match . "`, ";
|
||||||
|
$items_floor_field_list .= "fi.`" . $match . "`, ";
|
||||||
|
}
|
||||||
|
#::: Trim ', ' off the ends
|
||||||
|
$update_fields = substr($update_fields, 0, -2);
|
||||||
|
$items_field_list = substr($items_field_list, 0, -2);
|
||||||
|
$items_floor_field_list = substr($items_floor_field_list, 0, -2);
|
||||||
|
|
||||||
|
#::: Mixed up fields...
|
||||||
|
$items_floor_field_list =~ s/booktype/booklang/g; #our booktype is mixed with theirs...
|
||||||
|
$update_fields =~ s/`booktype` = fi.`booktype`/`booktype` = fi.`booklang`/g;
|
||||||
|
|
||||||
|
#::: FIELDS THAT DO NOT MATCH GO HERE
|
||||||
|
my @items_add = (
|
||||||
|
"casttime_", "endur", "range", "attuneable", "evolvinglevel", "herosforgemodel", "scrolltype",
|
||||||
|
"scriptfileid", "powersourcecapacity", "augslot1unk2", "augslot2unk2", "augslot3unk2", "augslot4unk2",
|
||||||
|
"augslot5unk2", "augslot6unk2", "recskill", "book"
|
||||||
|
);
|
||||||
|
my @items_floor_add = (
|
||||||
|
"foodduration", "endurance", "therange", "attunable", "evolvl", "heroforge1", "scrolleffecttype",
|
||||||
|
"rightclickscriptid", "powersourcecap", "augslot1unk", "augslot2unk", "augslot3unk", "augslot4unk",
|
||||||
|
"augslot5unk", "augslot6unk", "reqskill", "booktype"
|
||||||
|
);
|
||||||
|
|
||||||
|
#::: Match the mis-matched fields...
|
||||||
|
my $spot = 0;
|
||||||
|
foreach $value (@items_add) {
|
||||||
|
$items_field_list .= ", `" . $value . "`";
|
||||||
|
$update_fields .= ", `" . $value . "` = fi.`" . $items_floor_add[$spot] . "`";
|
||||||
|
$spot++;
|
||||||
|
@missing_items_table = grep {$_ ne $value} @missing_items_table;
|
||||||
|
}
|
||||||
|
foreach $value (@items_floor_add) {
|
||||||
|
$items_floor_field_list .= ", fi.`" . $value . "`";
|
||||||
|
@missing_items_floor_table = grep {$_ ne $value} @missing_items_floor_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $update_query = "
|
||||||
|
INSERT INTO items (" . $items_field_list . ")
|
||||||
|
SELECT " . $items_floor_field_list . "
|
||||||
|
FROM items_floor fi
|
||||||
|
ON DUPLICATE KEY UPDATE " . $update_fields;
|
||||||
|
|
||||||
|
#::: Print missing fields to file
|
||||||
|
my $write_file = "missing_item_fields.txt";
|
||||||
|
|
||||||
|
open(F, ">$write_file") or die "Unable to open questfile: $write_file\n";
|
||||||
|
print F "$update_query \n\n";
|
||||||
|
print F "EQEMU items Table missing fields\n";
|
||||||
|
foreach $value (@missing_items_table) {
|
||||||
|
print F "$value\n";
|
||||||
|
}
|
||||||
|
print F "\n\n13thFloor items Table missing fields\n";
|
||||||
|
foreach $value (@missing_items_floor_table) {
|
||||||
|
print F "$value\n";
|
||||||
|
}
|
||||||
|
close(F);
|
||||||
|
|
||||||
|
#::: Number of rows affected by query
|
||||||
|
$rows = $dbh->do($update_query);
|
||||||
|
|
||||||
|
#::: Update stackables
|
||||||
|
$dbh->do("UPDATE items i SET i.stackable = 1 WHERE i.stacksize > 1");
|
||||||
|
|
||||||
|
print "Added all new items to Items table (" . $rows . ")!\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub trim($) {
|
||||||
|
my $string = shift;
|
||||||
|
$string =~ s/^\s+//;
|
||||||
|
$string =~ s/\s+$//;
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
@ -1,77 +0,0 @@
|
|||||||
#! /usr/bin/perl
|
|
||||||
|
|
||||||
use DBI;
|
|
||||||
use Getopt::Std;
|
|
||||||
|
|
||||||
getopts('d:h');
|
|
||||||
$conf = "eqemu_config.xml";
|
|
||||||
if($opt_h) {
|
|
||||||
die "Usage: load_13thfloor_items.pl [-d path/to/eqemu_config.xml]\n";
|
|
||||||
}
|
|
||||||
if($opt_d) {
|
|
||||||
$conf = $opt_d;
|
|
||||||
}
|
|
||||||
|
|
||||||
$db = "eq";
|
|
||||||
$user = "eq";
|
|
||||||
$pass = "eq";
|
|
||||||
$host = "localhost";
|
|
||||||
open(F, "<$conf") or die "Unable to open config $conf\n";
|
|
||||||
$indb = 0;
|
|
||||||
while(<F>) {
|
|
||||||
s/\r//g;
|
|
||||||
if(/<database>/i) {
|
|
||||||
$indb = 1;
|
|
||||||
}
|
|
||||||
next unless($indb == 1);
|
|
||||||
if(/<\/database>/i) {
|
|
||||||
$indb = 0;
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
if(/<host>(.*)<\/host>/i) {
|
|
||||||
$host = $1;
|
|
||||||
} elsif(/<username>(.*)<\/username>/i) {
|
|
||||||
$user = $1;
|
|
||||||
} elsif(/<password>(.*)<\/password>/i) {
|
|
||||||
$pass = $1;
|
|
||||||
} elsif(/<db>(.*)<\/db>/i) {
|
|
||||||
$db = $1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!$db || !$user || !$pass || !$host) {
|
|
||||||
die "Invalid db.ini, missing one of: host, user, password, database\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$source="DBI:mysql:database=$db;host=$host";
|
|
||||||
|
|
||||||
my $dbh = DBI->connect($source, $user, $pass) || die "Could not create db handle\n";
|
|
||||||
|
|
||||||
$_=<STDIN>;
|
|
||||||
chomp();
|
|
||||||
s/'/\\'/g;
|
|
||||||
@fields=split("(?<!\\\\)\\|", $_);
|
|
||||||
|
|
||||||
%conversions = (
|
|
||||||
"itemtype" => "itemuse"
|
|
||||||
);
|
|
||||||
|
|
||||||
$insert="replace into items (".join(",",@fields).",source,updated) values ('";
|
|
||||||
$insert=~s/UNK130/potionbeltslots/;
|
|
||||||
$insert=~s/UNK133/stackable/;
|
|
||||||
|
|
||||||
#select(STDOUT); $|=1;
|
|
||||||
while(<STDIN>) {
|
|
||||||
chomp();
|
|
||||||
s/'/\\'/g;
|
|
||||||
@f=split("(?<!\\\\)\\|", $_);
|
|
||||||
$insert2=join("','",@f);
|
|
||||||
$#f--;
|
|
||||||
grep(s/\\\|/\\\\\|/g,@f);
|
|
||||||
grep(s/"/\\\\"/g,@f);
|
|
||||||
$statement=sprintf("%s%s','13THFLOOR',now())",$insert,$insert2,join('|',@f));
|
|
||||||
$dbh->do($statement);
|
|
||||||
printf("Processing: %d %s \r",$f[4],$f[1]);
|
|
||||||
++$count;
|
|
||||||
}
|
|
||||||
printf("Processed: %d items(s) \n",$count);
|
|
||||||
|
|
||||||
@ -1,261 +1,261 @@
|
|||||||
5001|1_task_system.sql
|
5001|1_task_system.sql|SHOW TABLES LIKE 'tasks'|empty|
|
||||||
# 5002|2_optional_maxclients.sql
|
# 5002|2_optional_maxclients.sql
|
||||||
# 5003|14_optional_merchantlist.sql
|
# 5003|14_optional_merchantlist.sql
|
||||||
5004|35_task_stepped.sql
|
5004|35_task_stepped.sql|SHOW COLUMNS FROM `tasks` LIKE 'stepped'|not_empty|
|
||||||
5005|42_task_min_maxlevel.sql
|
5005|42_task_min_maxlevel.sql|SHOW COLUMNS FROM `tasks` LIKE 'minlevel'|empty|
|
||||||
5006|55_zone_shutdowndeleay.sql
|
5006|55_zone_shutdowndeleay.sql|SHOW COLUMNS FROM `zone` LIKE 'shutdowndelay'|empty|
|
||||||
# 5007|68_optional_character_maxexplevel.sql
|
# 5007|68_optional_character_maxexplevel.sql
|
||||||
# 5008|103_optional_chat_rules.sql
|
# 5008|103_optional_chat_rules.sql
|
||||||
5009|104_traps.sql
|
5009|104_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'respawn_time'|empty|
|
||||||
# 5010|106_optional_proc_rules.sql
|
# 5010|106_optional_proc_rules.sql
|
||||||
5011|120_damageshieldtypes.sql
|
5011|120_damageshieldtypes.sql|SHOW TABLES LIKE 'damageshieldtypes'|empty|
|
||||||
5012|125_aggrozone.sql
|
# 5012|125_aggrozone.sql
|
||||||
# 5013|127_optional_spell_rules.sql
|
# 5013|127_optional_spell_rules.sql
|
||||||
# 5014|129_optional_shared_plat_rule.sql
|
# 5014|129_optional_shared_plat_rule.sql
|
||||||
# 5015|131_optional_combat_rules.sql
|
# 5015|131_optional_combat_rules.sql
|
||||||
5016|133_task_repeatable.sql
|
5016|133_task_repeatable.sql|SHOW COLUMNS FROM `tasks` LIKE 'repeatable'|empty|
|
||||||
5017|142_deathpeace_and_lifetap_aas.sql
|
5017|142_deathpeace_and_lifetap_aas.sql|SELECT * FROM db_version WHERE version > 5016|empty|
|
||||||
# 5018|158_optional_death_exp_loss.sql
|
# 5018|158_optional_death_exp_loss.sql
|
||||||
5019|176_melody.sql
|
# 5019|176_melody.sql
|
||||||
5020|189_character_.sql
|
5020|189_character_.sql|SELECT * FROM db_version WHERE version >= 5020|empty|
|
||||||
5021|196_trader.sql
|
5021|196_trader.sql|SHOW TABLES LIKE 'trader'|empty|
|
||||||
5022|210_undyeme.sql
|
# 5022|210_undyeme.sql
|
||||||
5023|222_buyer.sql
|
5023|222_buyer.sql|SHOW TABLES LIKE 'buyer'|empty|
|
||||||
5024|226_account_limiting.sql
|
# 5024|226_account_limiting.sql
|
||||||
5025|230_spells_table.sql
|
5025|230_spells_table.sql|SHOW TABLES LIKE 'spells_new'|empty|
|
||||||
5026|235_horses_table.sql
|
5026|235_horses_table.sql|SHOW TABLES LIKE 'horses'|empty|
|
||||||
5027|243_spawn_timers.sql
|
5027|243_spawn_timers.sql|SHOW TABLES LIKE 'respawn_times'|empty|
|
||||||
5028|247_mail.sql
|
5028|247_mail.sql|SHOW TABLES LIKE 'mail'|empty|
|
||||||
5029|249_chatchannels.sql
|
5029|249_chatchannels.sql|SHOW TABLES LIKE 'chatchannels'|empty|
|
||||||
5030|250_bot_spell_update.sql
|
# 5030|250_bot_spell_update.sql
|
||||||
# 5031|250_optional_bot_spell_update.sql
|
# 5031|250_optional_bot_spell_update.sql
|
||||||
# 5032|285_optional_bot_spell_update.sql
|
# 5032|285_optional_bot_spell_update.sql
|
||||||
5033|292_augslots.sql
|
# 5033|292_augslots.sql|SELECT * FROM db_version WHERE version >= 5033|empty|
|
||||||
5034|294_merchant_logging.sql
|
5034|294_merchant_logging.sql|SHOW COLUMNS FROM `eventlog` LIKE 'event_nid'|empty|
|
||||||
5035|304_faction_list.sql
|
5035|304_faction_list.sql|SELECT * FROM db_version WHERE version >= 5035|empty|
|
||||||
5036|326_aas.sql
|
5036|326_aas.sql|SELECT * FROM db_version WHERE version > 5035|empty|
|
||||||
5037|328_bot_management.sql
|
# 5037|328_bot_management.sql
|
||||||
# 5038|328_optional_bot_management.sql
|
# 5038|328_optional_bot_management.sql
|
||||||
5039|340_gm_ips.sql
|
5039|340_gm_ips.sql|SHOW TABLES LIKE 'gm_ips'|empty|
|
||||||
5040|356_combat.sql
|
# 5040|356_combat.sql
|
||||||
5041|360_peqzone.sql
|
# 5041|360_peqzone.sql
|
||||||
5042|364_ranged_dist_rule.sql
|
# 5042|364_ranged_dist_rule.sql
|
||||||
5043|386_bot_save_raid.sql
|
# 5043|386_bot_save_raid.sql
|
||||||
# 5044|434_optional_rest_state_rules.sql
|
# 5044|434_optional_rest_state_rules.sql
|
||||||
5045|447_sof_startzone_rule.sql
|
# 5045|447_sof_startzone_rule.sql
|
||||||
5046|463_altadv_vars.sql
|
# 5046|463_altadv_vars.sql
|
||||||
5047|475_aa_actions.sql
|
# 5047|475_aa_actions.sql
|
||||||
5048|500_spawn2_optimization.sql
|
5048|500_spawn2_optimization.sql|SELECT * FROM db_version WHERE version >= 5048|empty|
|
||||||
5049|503_bugs.sql
|
5049|503_bugs.sql|SHOW TABLES LIKE 'bugs'|empty|
|
||||||
5050|518_drakkin_npc_type_features.sql
|
5050|518_drakkin_npc_type_features.sql|SHOW TABLES LIKE 'bugs'|empty|
|
||||||
5051|524_rule_values_notes.sql
|
5051|524_rule_values_notes.sql|SELECT * FROM db_version WHERE version >= 5051|empty|
|
||||||
5052|527_npc_armor_tint.sql
|
5052|527_npc_armor_tint.sql|SELECT * FROM db_version WHERE version >= 5052|empty|
|
||||||
5053|553_saylink_table.sql
|
5053|553_saylink_table.sql|SHOW TABLES LIKE 'saylink'|empty|
|
||||||
5054|564_nokeyring.sql
|
5054|564_nokeyring.sql|SHOW COLUMNS FROM `doors` LIKE 'nokeyring'|empty|
|
||||||
5055|600_group_leadership.sql
|
5055|600_group_leadership.sql|SELECT * FROM db_version WHERE version >= 5055|empty|
|
||||||
5056|612_instance_changes.sql
|
5056|612_instance_changes.sql|SELECT * FROM db_version WHERE version >= 5056|empty|
|
||||||
5057|615_adventure_assassination.sql
|
5057|615_adventure_assassination.sql|SELECT * FROM db_version WHERE version >= 5057|empty|
|
||||||
5058|619_Adventure_Recruiter_Flavor.sql
|
5058|619_Adventure_Recruiter_Flavor.sql|SELECT * FROM db_version WHERE version >= 5058|empty|
|
||||||
5059|621_LDoNTraps.sql
|
5059|621_LDoNTraps.sql|SHOW TABLES LIKE 'ldon_trap_templates'|empty|
|
||||||
5060|633_ucs.sql
|
5060|633_ucs.sql|SHOW TABLES LIKE 'friends'|empty|
|
||||||
5061|634_TrapTemplateDefaultValue.sql
|
5061|634_TrapTemplateDefaultValue.sql|SHOW COLUMNS FROM `npc_types` LIKE 'trap_template'|empty|
|
||||||
5062|643_BotsTable.sql
|
# 5062|643_BotsTable.sql
|
||||||
5063|646_archery_penalty_rule.sql
|
# 5063|646_archery_penalty_rule.sql
|
||||||
5064|665_heroic_resists.sql
|
5064|665_heroic_resists.sql|SELECT * FROM db_version WHERE version >= 5064|empty|
|
||||||
5065|667_titles.sql
|
5065|667_titles.sql|SHOW TABLES LIKE 'titles'|empty|
|
||||||
5066|687_aa_table_changes.sql
|
5066|687_aa_table_changes.sql|SELECT * FROM db_version WHERE version >= 5066|empty|
|
||||||
5067|699_peqzone_rule.sql
|
# 5067|699_peqzone_rule.sql
|
||||||
5068|702_aashieldblock_tint_table.sql
|
5068|702_aashieldblock_tint_table.sql|SHOW TABLES LIKE 'npc_types_tint'|empty|
|
||||||
5069|703_peqzone_rule.sql
|
# 5069|703_peqzone_rule.sql
|
||||||
5070|704_rules.sql
|
# 5070|704_rules.sql
|
||||||
5071|710_tint_set_naming.sql
|
5071|710_tint_set_naming.sql|SELECT * FROM db_version WHERE version >= 5071|empty|
|
||||||
5072|721_pathing_rules.sql
|
5072|721_pathing_rules.sql|SELECT * FROM db_version WHERE version >= 5072|empty|
|
||||||
5073|730_smart_delay_moving.sql
|
# 5073|730_smart_delay_moving.sql
|
||||||
5074|731_rule_assist_notarget_self.sql
|
# 5074|731_rule_assist_notarget_self.sql
|
||||||
5075|732_sacrifice_rules.sql
|
# 5075|732_sacrifice_rules.sql
|
||||||
5076|745_slow_mitigation.sql
|
5076|745_slow_mitigation.sql|SELECT * FROM db_version WHERE version >= 5076|empty|
|
||||||
5077|754_archery_base_damage_rule.sql
|
# 5077|754_archery_base_damage_rule.sql
|
||||||
5078|755_sof_altadv_vars_updates.sql
|
5078|755_sof_altadv_vars_updates.sql|SELECT * FROM db_version WHERE version >= 5078|empty|
|
||||||
5079|773_monk_rules.sql
|
# 5079|773_monk_rules.sql
|
||||||
# 5080|853_optional_rule_aaexp.sql
|
# 5080|853_optional_rule_aaexp.sql
|
||||||
# 5081|858_optional_rule_ip_limit_by_status.sql
|
# 5081|858_optional_rule_ip_limit_by_status.sql
|
||||||
# 5082|892_optional_bots_table_mod.sql
|
# 5082|892_optional_bots_table_mod.sql
|
||||||
# 5083|893_optional_bots_table_mod.sql
|
# 5083|893_optional_bots_table_mod.sql
|
||||||
5084|898_npc_maxlevel_scalerate.sql
|
5084|898_npc_maxlevel_scalerate.sql|SHOW COLUMNS FROM `npc_types` LIKE 'maxlevel'|empty|
|
||||||
# 5085|902_optional_rule_snareflee.sql
|
# 5085|902_optional_rule_snareflee.sql
|
||||||
5086|923_spawn2_enabled.sql
|
5086|923_spawn2_enabled.sql|SHOW COLUMNS FROM `spawn2` LIKE 'enabled'|empty|
|
||||||
5087|962_hot_zone.sql
|
5087|962_hot_zone.sql|SHOW COLUMNS FROM `zone` LIKE 'hotzone'|empty|
|
||||||
5088|964_reports.sql
|
5088|964_reports.sql|SHOW TABLES LIKE 'reports'|empty|
|
||||||
5089|971_veteran_rewards.sql
|
5089|971_veteran_rewards.sql|SHOW TABLES LIKE 'veteran_reward_templates'|empty|
|
||||||
5090|977_raid_npc_private_corpses.sql
|
5090|977_raid_npc_private_corpses.sql|SELECT * FROM db_version WHERE version >= 5090|empty|
|
||||||
5091|979_unique_spawn_by_name.sql
|
5091|979_unique_spawn_by_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'unique_spawn_by_name'|empty|
|
||||||
5092|980_account_ip.sql
|
5092|980_account_ip.sql|SHOW TABLES LIKE 'account_ip'|empty|
|
||||||
5093|1022_botadventuring.sql
|
# 5093|1022_botadventuring.sql
|
||||||
5094|1027_botactives.sql
|
# 5094|1027_botactives.sql
|
||||||
5095|1030_botzoningsupport.sql
|
# 5095|1030_botzoningsupport.sql
|
||||||
5096|1036_botbuffs.sql
|
# 5096|1036_botbuffs.sql
|
||||||
5097|1038_botpetstatepersists.sql
|
# 5097|1038_botpetstatepersists.sql
|
||||||
5098|1038_grouptablesuniquecolumndefinitions.sql
|
5098|1038_grouptablesuniquecolumndefinitions.sql|SELECT * FROM db_version WHERE version >= 5098|empty|
|
||||||
5099|1039_botguilds.sql
|
# 5099|1039_botguilds.sql
|
||||||
5100|1040_DeprecatedBotRaidsSystems.sql
|
# 5100|1040_DeprecatedBotRaidsSystems.sql
|
||||||
5101|1057_titles.sql
|
5101|1057_titles.sql|SHOW TABLES LIKE 'player_titlesets'|empty|
|
||||||
5102|1077_botgroups.sql
|
# 5102|1077_botgroups.sql
|
||||||
5103|1136_spell_globals.sql
|
5103|1136_spell_globals.sql|SHOW TABLES LIKE 'spell_globals'|empty|
|
||||||
# 5104|1144_optional_rule_return_nodrop.sql
|
# 5104|1144_optional_rule_return_nodrop.sql
|
||||||
5105|1195_account_suspendeduntil.sql
|
5105|1195_account_suspendeduntil.sql|SELECT * FROM db_version WHERE version >= 5105|empty|
|
||||||
5106|1259_npc_skill_types.sql
|
5106|1259_npc_skill_types.sql|SHOW COLUMNS FROM `npc_types` LIKE 'prim_melee_type'|empty|
|
||||||
5107|1280_bot_augs.sql
|
# 5107|1280_bot_augs.sql
|
||||||
# 5108|1290_optional_exp_loss_rule.sql
|
# 5108|1290_optional_exp_loss_rule.sql
|
||||||
5109|1293_guild_bank.sql
|
5109|1293_guild_bank.sql|SHOW TABLES LIKE 'guild_bank'|empty|
|
||||||
5110|1379_loginserver_trusted_server.sql
|
# 5110|1379_loginserver_trusted_server.sql
|
||||||
5111|1392_recipe_learning.sql
|
5111|1392_recipe_learning.sql|SELECT * FROM db_version WHERE version >= 5111|empty|
|
||||||
# 5112|1394_optional_rule_sod_hp_mana_end.sql
|
# 5112|1394_optional_rule_sod_hp_mana_end.sql
|
||||||
5113|1404_faction_list.sql
|
5113|1404_faction_list.sql|SELECT * FROM db_version WHERE version >= 5113|empty|
|
||||||
# 5114|1410_optional_sod_aas_ht_and_loh.sql
|
# 5114|1410_optional_sod_aas_ht_and_loh.sql
|
||||||
5115|1436_login_server_table_fix.sql
|
# 5115|1436_login_server_table_fix.sql
|
||||||
5116|1446_allowrest_optional.sql
|
# 5116|1446_allowrest_optional.sql
|
||||||
5117|1446_allowrest_required.sql
|
5117|1446_allowrest_required.sql|SELECT * FROM db_version WHERE version >= 5117|empty|
|
||||||
5118|1450_cvs.sql
|
# 5118|1450_cvs.sql
|
||||||
5119|1451_guilds.sql
|
5119|1451_guilds.sql|SELECT * FROM db_version WHERE version >= 5119|empty|
|
||||||
5120|1498_instance_adventure.sql
|
5120|1498_instance_adventure.sql|SELECT * FROM db_version WHERE version >= 5120|empty|
|
||||||
5121|1510_global_instances.sql
|
5121|1510_global_instances.sql|SELECT * FROM db_version WHERE version >= 5121|empty|
|
||||||
5122|1511_map_path_loading.sql
|
5122|1511_map_path_loading.sql|SHOW COLUMNS FROM `zone` LIKE 'map_file_name'|empty|
|
||||||
5123|1513_zone_points.sql
|
5123|1513_zone_points.sql|SELECT * FROM db_version WHERE version >= 5123|empty|
|
||||||
5124|1519_zone_primary_key_id.sql
|
5124|1519_zone_primary_key_id.sql|SELECT * FROM db_version WHERE version >= 5124|empty|
|
||||||
5125|1542_items_table_cleanup.sql
|
5125|1542_items_table_cleanup.sql|SELECT * FROM db_version WHERE version >= 5125|empty|
|
||||||
5126|1548_nimbuseffect_required.sql
|
5126|1548_nimbuseffect_required.sql|SELECT * FROM db_version WHERE version >= 5126|empty|
|
||||||
5127|1562_instanced_spawnconditions.sql
|
5127|1562_instanced_spawnconditions.sql|SHOW TABLES LIKE 'spawn_condition_values'|empty|
|
||||||
5128|1586_waypoints_optional.sql
|
# 5128|1586_waypoints_optional.sql
|
||||||
5129|1610_tradeskill_required.sql
|
5129|1610_tradeskill_required.sql|SELECT * FROM db_version WHERE version >= 5129|empty|
|
||||||
5130|1618_zone.sql
|
5130|1618_zone.sql|SELECT * FROM db_version WHERE version >= 5130|empty|
|
||||||
# 5131|1625_optional_rule_class_race_exp_bonus.sql
|
# 5131|1625_optional_rule_class_race_exp_bonus.sql
|
||||||
# 5132|1672_optional_rules_respawn_window.sql
|
# 5132|1672_optional_rules_respawn_window.sql
|
||||||
# 5133|1679_optional_rules_blocked_buffs.sql
|
# 5133|1679_optional_rules_blocked_buffs.sql
|
||||||
5134|1696_modify_zone_and_object_tables.sql
|
5134|1696_modify_zone_and_object_tables.sql|SELECT * FROM db_version WHERE version >= 5134|empty|
|
||||||
5135|1711_account_restricted_aa.sql
|
5135|1711_account_restricted_aa.sql|SHOW COLUMNS FROM `account` LIKE 'time_creation'|empty|
|
||||||
# 5136|1717_optional_rule_bash_stun_chance.sql
|
# 5136|1717_optional_rule_bash_stun_chance.sql
|
||||||
# 5137|1718_optional_rules_mod3s.sql
|
# 5137|1718_optional_rules_mod3s.sql
|
||||||
# 5138|1719_optional_triggerOnCastAAs.sql
|
# 5138|1719_optional_triggerOnCastAAs.sql
|
||||||
# 5139|1720_optional_sql_AAs.sql
|
# 5139|1720_optional_sql_AAs.sql
|
||||||
5140|1720_required_sql_AA_effects_update.sql
|
# 5140|1720_required_sql_AA_effects_update.sql
|
||||||
# 5141|1721_optional_sql_drakkin_breath_update.sql
|
# 5141|1721_optional_sql_drakkin_breath_update.sql
|
||||||
5142|1721_required_sql_altadv_vars_update.sql
|
# 5142|1721_required_sql_altadv_vars_update.sql
|
||||||
# 5143|1723_optional_sql_new_stats_window_rule.sql
|
# 5143|1723_optional_sql_new_stats_window_rule.sql
|
||||||
5144|1723_required_sql_corruption.sql
|
5144|1723_required_sql_corruption.sql|SELECT * FROM db_version WHERE version >= 5144|empty|
|
||||||
# 5145|1736_optional_sql_feral_swipe.sql
|
# 5145|1736_optional_sql_feral_swipe.sql
|
||||||
5146|1737_required_sql_rule_and_aa_update.sql
|
# 5146|1737_required_sql_rule_and_aa_update.sql
|
||||||
# 5147|1746_optional_sql_bot_manaregen.sql
|
# 5147|1746_optional_sql_bot_manaregen.sql
|
||||||
# 5148|1747_optional_HoT_zone_and_zonepoints.sql
|
# 5148|1747_optional_HoT_zone_and_zonepoints.sql
|
||||||
# 5149|1750_optional_sql_reflect_rule.sql
|
# 5149|1750_optional_sql_reflect_rule.sql
|
||||||
# 5150|1753_optional_haste_cap_rule.sql
|
# 5150|1753_optional_haste_cap_rule.sql
|
||||||
5151|1753_required_sql_healing_adept_aa.sql
|
# 5151|1753_required_sql_healing_adept_aa.sql
|
||||||
5152|1754_required_sql_healing_adept_aa_fix.sql
|
# 5152|1754_required_sql_healing_adept_aa_fix.sql
|
||||||
5153|1755_required_sql_fear_resist_aas.sql
|
# 5153|1755_required_sql_fear_resist_aas.sql
|
||||||
# 5154|1784_optional_corpsedrag_rules.sql
|
# 5154|1784_optional_corpsedrag_rules.sql
|
||||||
5155|1786_required_update_to_aas.sql
|
# 5155|1786_required_update_to_aas.sql
|
||||||
5156|1790_required_aa_required_level_cost.sql
|
# 5156|1790_required_aa_required_level_cost.sql
|
||||||
5157|1793_resist_adjust.sql
|
5157|1793_resist_adjust.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'resist_adjust'|empty|
|
||||||
# 5158|1799_optional_rest_regen_endurance_rule.sql
|
# 5158|1799_optional_rest_regen_endurance_rule.sql
|
||||||
5159|1802_required_doppelganger.sql
|
5159|1802_required_doppelganger.sql|SELECT * FROM db_version WHERE version >= 5159|empty|
|
||||||
5160|1803_required_tasks_xpreward_signed.sql
|
5160|1803_required_tasks_xpreward_signed.sql|SELECT * FROM db_version WHERE version >= 5160|empty|
|
||||||
5161|1804_required_ae_melee_updates.sql
|
5161|1804_required_ae_melee_updates.sql|SELECT * FROM db_version WHERE version >= 5161|empty|
|
||||||
# 5162|1809_optional_rules.sql
|
# 5162|1809_optional_rules.sql
|
||||||
5163|1813_required_doppelganger_npcid_change.sql
|
5163|1813_required_doppelganger_npcid_change.sql|SELECT * FROM db_version WHERE version >= 5163|empty|
|
||||||
# 5164|1817_optional_npc_archery_bonus_rule.sql
|
# 5164|1817_optional_npc_archery_bonus_rule.sql
|
||||||
# 5165|1823_optional_delay_death.sql
|
# 5165|1823_optional_delay_death.sql
|
||||||
5166|1847_required_doors_dest_zone_size_32.sql
|
5166|1847_required_doors_dest_zone_size_32.sql|SELECT * FROM db_version WHERE version >= 5166|empty|
|
||||||
# 5167|1859_optional_item_casts_use_focus_rule.sql
|
# 5167|1859_optional_item_casts_use_focus_rule.sql
|
||||||
# 5168|1884_optional_bot_spells_update.sql
|
# 5168|1884_optional_bot_spells_update.sql
|
||||||
# 5169|1885_optional_rules_fv_pvp_expansions.sql
|
# 5169|1885_optional_rules_fv_pvp_expansions.sql
|
||||||
# 5170|1889_optional_skill_cap_rule.sql
|
# 5170|1889_optional_skill_cap_rule.sql
|
||||||
5171|1908_required_npc_types_definitions.sql
|
5171|1908_required_npc_types_definitions.sql|SHOW COLUMNS FROM `npc_types` LIKE 'attack_count'|empty|
|
||||||
# 5172|1926_optional_stat_cap.sql
|
# 5172|1926_optional_stat_cap.sql
|
||||||
5173|1944_spawn2.sql
|
5173|1944_spawn2.sql|SHOW COLUMNS FROM `spawn2` LIKE 'animation'|empty|
|
||||||
5174|1946_doors.sql
|
5174|1946_doors.sql|SELECT * FROM db_version WHERE version >= 5166|empty|
|
||||||
# 5175|1960_optional_console_timeout_rule.sql
|
# 5175|1960_optional_console_timeout_rule.sql
|
||||||
# 5176|1962_optional_guild_creation_window_rules.sql
|
# 5176|1962_optional_guild_creation_window_rules.sql
|
||||||
# 5177|1963_optional_rule_live_like_focuses.sql
|
# 5177|1963_optional_rule_live_like_focuses.sql
|
||||||
# 5178|1968_optional_enrage_rules.sql
|
# 5178|1968_optional_enrage_rules.sql
|
||||||
# 5179|1972_optional_extradmg_item_cap.sql
|
# 5179|1972_optional_extradmg_item_cap.sql
|
||||||
5180|1974_required_bot_spells_update.sql
|
# 5180|1974_required_bot_spells_update.sql
|
||||||
5181|1977_underwater.sql
|
5181|1977_underwater.sql|SHOW COLUMNS FROM `npc_types` LIKE 'underwater'|empty|
|
||||||
# 5182|1998_optional_intoxication_and_looting_rules.sql
|
# 5182|1998_optional_intoxication_and_looting_rules.sql
|
||||||
5183|2004_charges_alt_currency.sql
|
5183|2004_charges_alt_currency.sql|SHOW TABLES LIKE 'alternate_currency'|empty|
|
||||||
# 5184|2015_optional_specialization_training_rule.sql
|
# 5184|2015_optional_specialization_training_rule.sql
|
||||||
# 5185|2016_optional_rule_bot_aa_expansion.sql
|
# 5185|2016_optional_rule_bot_aa_expansion.sql
|
||||||
# 5186|2023_optional_mysqlcli.sql
|
# 5186|2023_optional_mysqlcli.sql
|
||||||
# 5187|2024_optional_update_crystals.sql
|
# 5187|2024_optional_update_crystals.sql
|
||||||
5188|2024_required_update.sql
|
5188|2024_required_update.sql|SHOW TABLES LIKE 'char_create_combinations'|empty|
|
||||||
5189|2057_required_discovered_items.sql
|
5189|2057_required_discovered_items.sql|SHOW TABLES LIKE 'discovered_items'|empty|
|
||||||
# 5190|2058_optional_rule_discovered_items.sql
|
# 5190|2058_optional_rule_discovered_items.sql
|
||||||
5191|2062_required_version_changes.sql
|
5191|2062_required_version_changes.sql|SELECT * FROM db_version WHERE version >= 5191|empty|
|
||||||
5192|2069_required_pets.sql
|
5192|2069_required_pets.sql|SHOW TABLES LIKE 'pets_equipmentset'|empty|
|
||||||
5193|2079_player_speech.sql
|
# 5193|2079_player_speech.sql
|
||||||
5194|2087_required_bots_hp_and_mana_and_spell_updates.sql
|
# 5194|2087_required_bots_hp_and_mana_and_spell_updates.sql
|
||||||
5195|2098_required_zonepoint_version_changes.sql
|
5195|2098_required_zonepoint_version_changes.sql|SELECT * FROM db_version WHERE version >= 5195|empty|
|
||||||
5196|2099_required_discovered_items_account_status.sql
|
5196|2099_required_discovered_items_account_status.sql|SELECT * FROM db_version WHERE version >= 5196|empty|
|
||||||
5197|2104_required_group_roles.sql
|
5197|2104_required_group_roles.sql|SELECT * FROM db_version WHERE version >= 5197|empty|
|
||||||
5198|2107_required_bot_stances.sql
|
# 5198|2107_required_bot_stances.sql
|
||||||
5199|2129_required_lfguild.sql
|
5199|2129_required_lfguild.sql|SHOW TABLES LIKE 'lfguild'|empty|
|
||||||
5200|2133_required_faction_loot_despawn.sql
|
5200|2133_required_faction_loot_despawn.sql|SELECT * FROM db_version WHERE version >= 5200|empty|
|
||||||
5201|2136_extended_targets.sql
|
5201|2136_extended_targets.sql|SELECT * FROM db_version WHERE version >= 5201|empty|
|
||||||
5202|2142_emotes.sql
|
5202|2142_emotes.sql|SELECT * FROM db_version WHERE version >= 5202|empty|
|
||||||
# 5203|2154_optional_rule_spell_procs_resists_falloff.sql
|
# 5203|2154_optional_rule_spell_procs_resists_falloff.sql
|
||||||
# 5204|2156_optional_charm_break_rule.sql
|
# 5204|2156_optional_charm_break_rule.sql
|
||||||
# 5205|2159_optional_defensiveproc_rules.sql
|
# 5205|2159_optional_defensiveproc_rules.sql
|
||||||
5206|2164_require_bots_bottimers.sql
|
# 5206|2164_require_bots_bottimers.sql
|
||||||
# 5207|2171_optional_SpecialAttackACBonus_rule.sql
|
# 5207|2171_optional_SpecialAttackACBonus_rule.sql
|
||||||
# 5208|2176_optional_aa_expansion_SOF_fix.sql
|
# 5208|2176_optional_aa_expansion_SOF_fix.sql
|
||||||
# 5209|2176_optional_FrenzyBonus_rule.sql
|
# 5209|2176_optional_FrenzyBonus_rule.sql
|
||||||
5210|2176_required_aa_updates.sql
|
5210|2176_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5210|empty|
|
||||||
5211|2178_required_aa_updates.sql
|
5211|2178_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5211|empty|
|
||||||
# 5212|2183_optional_bot_xp_rule.sql
|
# 5212|2183_optional_bot_xp_rule.sql
|
||||||
# 5213|2185_optional_NPCFlurryChacne_rule
|
# 5213|2185_optional_NPCFlurryChacne_rule
|
||||||
# 5214|2185_optional_NPCFlurryChacne_rule.sql
|
# 5214|2185_optional_NPCFlurryChacne_rule.sql
|
||||||
# 5215|2185_optional_NPCFlurryChance_rule.sql
|
# 5215|2185_optional_NPCFlurryChance_rule.sql
|
||||||
5216|2185_required_aa_updates
|
5216|2185_required_aa_updates|SELECT * FROM db_version WHERE version >= 5216|empty|
|
||||||
5217|2185_required_aa_updates.sql
|
5217|2185_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5217|empty|
|
||||||
# 5218|2188_optional_miscspelleffect_rules
|
# 5218|2188_optional_miscspelleffect_rules
|
||||||
# 5219|2188_optional_miscspelleffect_rules.sql
|
# 5219|2188_optional_miscspelleffect_rules.sql
|
||||||
5220|2188_required_aa_updates
|
# 5220|2188_required_aa_updates
|
||||||
5221|2188_required_aa_updates.sql
|
5221|2188_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5221|empty|
|
||||||
# 5222|2189_optional_taunt_rules
|
# 5222|2189_optional_taunt_rules
|
||||||
# 5223|2189_optional_taunt_rules.sql
|
# 5223|2189_optional_taunt_rules.sql
|
||||||
5224|2195_required_sharedplatupdates.sql
|
5224|2195_required_sharedplatupdates.sql|SELECT * FROM db_version WHERE version >= 5224|empty|
|
||||||
# 5225|2208_optional_aa_stacking_rule.sql
|
# 5225|2208_optional_aa_stacking_rule.sql
|
||||||
# 5226|2208_optional_EnableSoulAbrasionAA.sql
|
# 5226|2208_optional_EnableSoulAbrasionAA.sql
|
||||||
5227|2208_required_aa_updates.sql
|
5227|2208_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5227|empty|
|
||||||
# 5228|2209_optional_additive_bonus_rule.sql
|
# 5228|2209_optional_additive_bonus_rule.sql
|
||||||
5229|2213_loot_changes.sql
|
5229|2213_loot_changes.sql|SELECT * FROM db_version WHERE version >= 5229|empty|
|
||||||
5230|2214_faction_list_mod.sql
|
5230|2214_faction_list_mod.sql|SHOW TABLES LIKE 'faction_list_mod'|empty|
|
||||||
5231|2215_required_aa_updates.sql
|
5231|2215_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5231|empty|
|
||||||
# 5232|2243_optional_char_max_level_rule.sql
|
# 5232|2243_optional_char_max_level_rule.sql
|
||||||
5233|2260_probability.sql
|
# 5233|2260_probability.sql
|
||||||
5234|2262_required_pet_discipline_update.sql
|
5234|2262_required_pet_discipline_update.sql|SELECT * FROM db_version WHERE version >= 5234|empty|
|
||||||
5235|2264_required_aa_updates.sql
|
5235|2264_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5235|empty|
|
||||||
5236|2268_QueryServ.sql
|
# 5236|2268_QueryServ.sql
|
||||||
5237|2268_required_updates.sql
|
5237|2268_required_updates.sql|SELECT * FROM db_version WHERE version >= 5237|empty|
|
||||||
# 5238|2274_optional_rule_iplimitdisconnectall.sql
|
# 5238|2274_optional_rule_iplimitdisconnectall.sql
|
||||||
# 5239|2278_optional_rule_targetableswarmpet.sql
|
# 5239|2278_optional_rule_targetableswarmpet.sql
|
||||||
# 5240|2280_optional_rule_targetableswarmpet-rename.sql
|
# 5240|2280_optional_rule_targetableswarmpet-rename.sql
|
||||||
5241|2283_required_npc_changes.sql
|
5241|2283_required_npc_changes.sql|SHOW COLUMNS FROM `npc_types` LIKE 'spellscale'|empty|
|
||||||
5242|2299_required_inspectmessage_fields.sql
|
5242|2299_required_inspectmessage_fields.sql|SELECT * FROM db_version WHERE version >= 5242|empty|
|
||||||
# 5243|2300_optional_loot_changes.sql
|
# 5243|2300_optional_loot_changes.sql
|
||||||
5244|2304_QueryServ.sql
|
# 5244|2304_QueryServ.sql
|
||||||
5245|2340_required_maxbuffslotspet.sql
|
# 5245|2340_required_maxbuffslotspet.sql
|
||||||
5246|2361_QueryServ.sql
|
# 5246|2361_QueryServ.sql
|
||||||
5247|2361_required_qs_rule_values.sql
|
# 5247|2361_required_qs_rule_values.sql
|
||||||
5248|2370_required_aa_updates.sql
|
5248|2370_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5248|empty|
|
||||||
5249|2376_required_aa_updates.sql
|
5249|2376_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5249|empty|
|
||||||
# 5250|2380_optional_merc_data.sql
|
5250|2380_optional_merc_data.sql|SELECT * FROM db_version WHERE version >= 5250|empty|
|
||||||
# 5251|2380_optional_merc_merchant_npctypes_update.sql
|
5251|2380_optional_merc_merchant_npctypes_update.sql|SELECT * FROM db_version WHERE version >= 5251|empty|
|
||||||
# 5252|2380_optional_merc_rules.sql
|
5252|2380_optional_merc_rules.sql|SELECT * FROM db_version WHERE version >= 5252|empty|
|
||||||
5253|2383_required_group_ismerc.sql
|
5253|2383_required_group_ismerc.sql|SELECT * FROM db_version WHERE version >= 5253|empty|
|
||||||
# 5254|2428_optional_levelbasedexpmods.sql
|
# 5254|2428_optional_levelbasedexpmods.sql
|
||||||
# 5255|2448_optional_stun_proc_aggro_rule.sql
|
# 5255|2448_optional_stun_proc_aggro_rule.sql
|
||||||
5256|2471_required_aa_updates.sql
|
5256|2471_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5256|empty|
|
||||||
5257|2482_required_start_zones.sql
|
5257|2482_required_start_zones.sql|SELECT * FROM db_version WHERE version >= 5257|empty|
|
||||||
5258|2504_required_aa_updates.sql
|
5258|2504_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5258|empty|
|
||||||
8000|mercs.sql|SHOW TABLES LIKE 'merc_stats'|empty|
|
8000|mercs.sql|SHOW TABLES LIKE 'merc_stats'|empty|
|
||||||
9000|2013_02_18_Merc_Rules_and_Tables.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Mercs:ResurrectRadius%'|empty|
|
9000|2013_02_18_Merc_Rules_and_Tables.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Mercs:ResurrectRadius%'|empty|
|
||||||
9001|2013_02_25_Impr_HT_LT.sql|SHOW TABLES LIKE 'merc_inventory'|empty|
|
9001|2013_02_25_Impr_HT_LT.sql|SHOW TABLES LIKE 'merc_inventory'|empty|
|
||||||
@ -345,6 +345,9 @@
|
|||||||
9089|2015_11_02_ai_idle_no_spell_recast_default_changes.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Spells:AI_IdleNoSpellMinRecast%' AND `rule_value` = '500'|not_empty|
|
9089|2015_11_02_ai_idle_no_spell_recast_default_changes.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Spells:AI_IdleNoSpellMinRecast%' AND `rule_value` = '500'|not_empty|
|
||||||
9090|2015_12_01_spell_scribe_restriction_rule.sql|SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Character:RestrictSpellScribing'|empty|
|
9090|2015_12_01_spell_scribe_restriction_rule.sql|SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Character:RestrictSpellScribing'|empty|
|
||||||
9091|2015_12_07_command_settings.sql|SHOW TABLES LIKE 'command_settings'|empty|
|
9091|2015_12_07_command_settings.sql|SHOW TABLES LIKE 'command_settings'|empty|
|
||||||
|
9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty|
|
||||||
|
9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty|
|
||||||
|
9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|empty|
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
3
utils/sql/git/optional/2015_12_26_oow_aa_missing.sql
Normal file
3
utils/sql/git/optional/2015_12_26_oow_aa_missing.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
INSERT INTO `aa_ranks` (`id`, `upper_hotkey_sid`, `lower_hotkey_sid`, `title_sid`, `desc_sid`, `cost`, `level_req`, `spell`, `spell_type`, `recast_time`, `expansion`, `prev_id`, `next_id`) VALUES (1015, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1014, 1016);
|
||||||
|
|
||||||
|
INSERT INTO `aa_rank_effects` (`rank_id`, `slot`, `effect_id`, `base1`, `base2`) VALUES (1015, 1, 262, 40, 7), (1015, 2, 262, 40, 8), (1015, 3, 262, 40, 9), (1015, 4, 262, 40, 10), (1015, 5, 262, 40, 11);
|
||||||
11
utils/sql/git/required/2015_12_17_eqtime.sql
Normal file
11
utils/sql/git/required/2015_12_17_eqtime.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
DROP TABLE IF EXISTS `eqtime`;
|
||||||
|
CREATE TABLE `eqtime` (
|
||||||
|
`minute` tinyint(4) not null default 0,
|
||||||
|
`hour` tinyint(4) not null default 0,
|
||||||
|
`day` tinyint(4) not null default 0,
|
||||||
|
`month` tinyint(4) not null default 0,
|
||||||
|
`year` int(4) not null default 0,
|
||||||
|
`realtime` int(11) not null default 0
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
INSERT INTO eqtime values (0,1,28,12,3766,1444035661);
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
ALTER TABLE `items`
|
||||||
|
ADD COLUMN `evoitem` INT(11) NOT NULL DEFAULT '0' AFTER `purity`,
|
||||||
|
ADD COLUMN `evoid` INT(11) NOT NULL DEFAULT '0' AFTER `evoitem`,
|
||||||
|
ADD COLUMN `evomax` INT(11) NOT NULL DEFAULT '0' AFTER `evolvinglevel`,
|
||||||
|
CHANGE `UNK038` `skillmodmax` INT(11) NOT NULL DEFAULT '0',
|
||||||
|
CHANGE `UNK222` `heirloom` INT(11) NOT NULL DEFAULT '0',
|
||||||
|
CHANGE `UNK235` `placeable` INT(11) NOT NULL DEFAULT '0',
|
||||||
|
CHANGE `UNK242` `epicitem` INT(11) NOT NULL DEFAULT '0';
|
||||||
4
utils/sql/git/required/2015_12_29_quest_zone_events.sql
Normal file
4
utils/sql/git/required/2015_12_29_quest_zone_events.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (81, 'EVENT_SPAWN_ZONE', 0, 0, 0, 0, 1);
|
||||||
|
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (82, 'EVENT_DEATH_ZONE', 0, 0, 0, 0, 1);
|
||||||
|
ALTER TABLE `rule_values`
|
||||||
|
MODIFY COLUMN `notes` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL AFTER `rule_value`;
|
||||||
@ -2532,6 +2532,7 @@ INSERT INTO `aa_ranks` (`id`, `upper_hotkey_sid`, `lower_hotkey_sid`, `title_sid
|
|||||||
(1012, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1011, 1013),
|
(1012, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1011, 1013),
|
||||||
(1013, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1012, 1014),
|
(1013, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1012, 1014),
|
||||||
(1014, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1013, 1015),
|
(1014, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1013, 1015),
|
||||||
|
(1015, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1014, 1016),
|
||||||
(1016, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1015, -1),
|
(1016, -1, -1, 1011, 1011, 0, 51, -1, 0, 0, 8, 1015, -1),
|
||||||
(1017, 1017, 1017, 1017, 1017, 6, 59, 16531, 75, 15, 15, -1, 13726),
|
(1017, 1017, 1017, 1017, 1017, 6, 59, 16531, 75, 15, 15, -1, 13726),
|
||||||
(1018, 1018, 1018, 1018, 1018, 2, 63, 16455, 69, 1, 15, -1, -1),
|
(1018, 1018, 1018, 1018, 1018, 2, 63, 16455, 69, 1, 15, -1, -1),
|
||||||
@ -9526,6 +9527,11 @@ INSERT INTO `aa_rank_effects` (`rank_id`, `slot`, `effect_id`, `base1`, `base2`)
|
|||||||
(1014, 3, 262, 32, 9),
|
(1014, 3, 262, 32, 9),
|
||||||
(1014, 4, 262, 32, 10),
|
(1014, 4, 262, 32, 10),
|
||||||
(1014, 5, 262, 32, 11),
|
(1014, 5, 262, 32, 11),
|
||||||
|
(1015, 1, 262, 40, 7),
|
||||||
|
(1015, 2, 262, 40, 8),
|
||||||
|
(1015, 3, 262, 40, 9),
|
||||||
|
(1015, 4, 262, 40, 10),
|
||||||
|
(1015, 5, 262, 40, 11),
|
||||||
(1016, 1, 262, 50, 7),
|
(1016, 1, 262, 50, 7),
|
||||||
(1016, 2, 262, 50, 8),
|
(1016, 2, 262, 50, 8),
|
||||||
(1016, 3, 262, 50, 9),
|
(1016, 3, 262, 50, 9),
|
||||||
|
|||||||
@ -345,8 +345,13 @@ int main(int argc, char** argv) {
|
|||||||
database.ClearMerchantTemp();
|
database.ClearMerchantTemp();
|
||||||
}
|
}
|
||||||
Log.Out(Logs::General, Logs::World_Server, "Loading EQ time of day..");
|
Log.Out(Logs::General, Logs::World_Server, "Loading EQ time of day..");
|
||||||
if (!zoneserver_list.worldclock.loadFile(Config->EQTimeFile.c_str()))
|
TimeOfDay_Struct eqTime;
|
||||||
Log.Out(Logs::General, Logs::World_Server, "Unable to load %s", Config->EQTimeFile.c_str());
|
time_t realtime;
|
||||||
|
eqTime = database.LoadTime(realtime);
|
||||||
|
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(eqTime, realtime);
|
||||||
|
Timer EQTimeTimer(600000);
|
||||||
|
EQTimeTimer.Start(600000);
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::World_Server, "Loading launcher list..");
|
Log.Out(Logs::General, Logs::World_Server, "Loading launcher list..");
|
||||||
launcher_list.LoadList();
|
launcher_list.LoadList();
|
||||||
|
|
||||||
@ -470,6 +475,16 @@ int main(int argc, char** argv) {
|
|||||||
database.PurgeExpiredInstances();
|
database.PurgeExpiredInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EQTimeTimer.Check())
|
||||||
|
{
|
||||||
|
TimeOfDay_Struct tod;
|
||||||
|
zoneserver_list.worldclock.GetCurrentEQTimeOfDay(time(0), &tod);
|
||||||
|
if (!database.SaveTime(tod.minute, tod.hour, tod.day, tod.month, tod.year))
|
||||||
|
Log.Out(Logs::General, Logs::World_Server, "Failed to save eqtime.");
|
||||||
|
else
|
||||||
|
Log.Out(Logs::Detail, Logs::World_Server, "EQTime successfully saved.");
|
||||||
|
}
|
||||||
|
|
||||||
//check for timeouts in other threads
|
//check for timeouts in other threads
|
||||||
timeout_manager.CheckTimeouts();
|
timeout_manager.CheckTimeouts();
|
||||||
loginserverlist.Process();
|
loginserverlist.Process();
|
||||||
@ -519,8 +534,6 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
void CatchSignal(int sig_num) {
|
void CatchSignal(int sig_num) {
|
||||||
Log.Out(Logs::General, Logs::World_Server,"Caught signal %d",sig_num);
|
Log.Out(Logs::General, Logs::World_Server,"Caught signal %d",sig_num);
|
||||||
if(zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str())==false)
|
|
||||||
Log.Out(Logs::General, Logs::World_Server,"Failed to save time file.");
|
|
||||||
RunLoops = false;
|
RunLoops = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -989,8 +989,8 @@ bool ZoneServer::Process() {
|
|||||||
Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime");
|
Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime");
|
||||||
eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer;
|
eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer;
|
||||||
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
||||||
Log.Out(Logs::Detail, Logs::World_Server,"New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
Log.Out(Logs::Detail, Logs::World_Server, "New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
||||||
zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str());
|
database.SaveTime((int)newtime->start_eqtime.minute, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.day, newtime->start_eqtime.month, newtime->start_eqtime.year);
|
||||||
zoneserver_list.SendTimeSync();
|
zoneserver_list.SendTimeSync();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,11 +431,20 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
|||||||
if (sender->GetPrimaryFaction() == 0 )
|
if (sender->GetPrimaryFaction() == 0 )
|
||||||
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
|
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
|
||||||
|
|
||||||
|
if (sender->HasAssistAggro())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
||||||
NPC *mob = it->second;
|
NPC *mob = it->second;
|
||||||
if (!mob)
|
if (!mob)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (mob->CheckAggro(attacker))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sender->NPCAssistCap() >= RuleI(Combat, NPCAssistCap))
|
||||||
|
break;
|
||||||
|
|
||||||
float r = mob->GetAssistRange();
|
float r = mob->GetAssistRange();
|
||||||
r = r * r;
|
r = r * r;
|
||||||
|
|
||||||
@ -476,7 +485,8 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
|||||||
attacker->GetName(), DistanceSquared(mob->GetPosition(),
|
attacker->GetName(), DistanceSquared(mob->GetPosition(),
|
||||||
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
||||||
#endif
|
#endif
|
||||||
mob->AddToHateList(attacker, 1, 0, false);
|
mob->AddToHateList(attacker, 25, 0, false);
|
||||||
|
sender->AddAssistCap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2009,15 +2009,15 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob->GetName(), damage, spell, attack_skill);
|
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killer_mob->GetName(), damage, spell, attack_skill);
|
||||||
|
|
||||||
Mob *oos = nullptr;
|
Mob *oos = nullptr;
|
||||||
if(killerMob) {
|
if(killer_mob) {
|
||||||
oos = killerMob->GetOwnerOrSelf();
|
oos = killer_mob->GetOwnerOrSelf();
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0)
|
if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0)
|
||||||
{
|
{
|
||||||
if(GetHP() < 0) {
|
if(GetHP() < 0) {
|
||||||
@ -2026,15 +2026,15 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(killerMob && killerMob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
if(killer_mob && killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
||||||
char val1[20]={0};
|
char val1[20]={0};
|
||||||
entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE,
|
entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE,
|
||||||
killerMob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
killer_mob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0)
|
if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0)
|
||||||
{
|
{
|
||||||
if(GetHP() < 0) {
|
if(GetHP() < 0) {
|
||||||
@ -2072,21 +2072,21 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct));
|
EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct));
|
||||||
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
||||||
d->spawn_id = GetID();
|
d->spawn_id = GetID();
|
||||||
d->killer_id = killerMob ? killerMob->GetID() : 0;
|
d->killer_id = killer_mob ? killer_mob->GetID() : 0;
|
||||||
d->bindzoneid = 0;
|
d->bindzoneid = 0;
|
||||||
d->spell_id = spell == SPELL_UNKNOWN ? 0xffffffff : spell;
|
d->spell_id = spell == SPELL_UNKNOWN ? 0xffffffff : spell;
|
||||||
d->attack_skill = SkillDamageTypes[attack_skill];
|
d->attack_skill = SkillDamageTypes[attack_skill];
|
||||||
d->damage = damage;
|
d->damage = damage;
|
||||||
app->priority = 6;
|
app->priority = 6;
|
||||||
entity_list.QueueClients(killerMob, app, false);
|
entity_list.QueueClients(killer_mob, app, false);
|
||||||
|
|
||||||
if(respawn2) {
|
if(respawn2) {
|
||||||
respawn2->DeathReset(1);
|
respawn2->DeathReset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killerMob) {
|
if (killer_mob) {
|
||||||
if(GetClass() != LDON_TREASURE)
|
if(GetClass() != LDON_TREASURE)
|
||||||
hate_list.AddEntToHateList(killerMob, damage);
|
hate_list.AddEntToHateList(killer_mob, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(app);
|
safe_delete(app);
|
||||||
@ -2148,8 +2148,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
{
|
{
|
||||||
if(!IsLdonTreasure && MerchantType == 0) {
|
if(!IsLdonTreasure && MerchantType == 0) {
|
||||||
kr->SplitExp((finalxp), this);
|
kr->SplitExp((finalxp), this);
|
||||||
if(killerMob && (kr->IsRaidMember(killerMob->GetName()) || kr->IsRaidMember(killerMob->GetUltimateOwner()->GetName())))
|
if(killer_mob && (kr->IsRaidMember(killer_mob->GetName()) || kr->IsRaidMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
/* Send the EVENT_KILLED_MERIT event for all raid members */
|
/* Send the EVENT_KILLED_MERIT event for all raid members */
|
||||||
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
||||||
@ -2193,8 +2193,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
{
|
{
|
||||||
if(!IsLdonTreasure && MerchantType == 0) {
|
if(!IsLdonTreasure && MerchantType == 0) {
|
||||||
kg->SplitExp((finalxp), this);
|
kg->SplitExp((finalxp), this);
|
||||||
if(killerMob && (kg->IsGroupMember(killerMob->GetName()) || kg->IsGroupMember(killerMob->GetUltimateOwner()->GetName())))
|
if(killer_mob && (kg->IsGroupMember(killer_mob->GetName()) || kg->IsGroupMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
/* Send the EVENT_KILLED_MERIT event and update kill tasks
|
/* Send the EVENT_KILLED_MERIT event and update kill tasks
|
||||||
* for all group members */
|
* for all group members */
|
||||||
@ -2244,8 +2244,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient()))
|
if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient()))
|
||||||
{
|
{
|
||||||
give_exp_client->AddEXP((finalxp), conlevel);
|
give_exp_client->AddEXP((finalxp), conlevel);
|
||||||
if(killerMob && (killerMob->GetID() == give_exp_client->GetID() || killerMob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
if(killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
||||||
killerMob->TrySpellOnKill(killed_level,spell);
|
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2393,20 +2393,30 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
uint16 emoteid = oos->GetEmoteID();
|
uint16 emoteid = oos->GetEmoteID();
|
||||||
if(emoteid != 0)
|
if(emoteid != 0)
|
||||||
oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid);
|
oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid);
|
||||||
killerMob->TrySpellOnKill(killed_level, spell);
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
p_depop = true;
|
p_depop = true;
|
||||||
if(killerMob && killerMob->GetTarget() == this) //we can kill things without having them targeted
|
if(killer_mob && killer_mob->GetTarget() == this) //we can kill things without having them targeted
|
||||||
killerMob->SetTarget(nullptr); //via AE effects and such..
|
killer_mob->SetTarget(nullptr); //via AE effects and such..
|
||||||
|
|
||||||
entity_list.UpdateFindableNPCState(this, true);
|
entity_list.UpdateFindableNPCState(this, true);
|
||||||
|
|
||||||
char buffer[48] = { 0 };
|
char buffer[48] = { 0 };
|
||||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, buffer, 0);
|
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, buffer, 0);
|
||||||
|
|
||||||
|
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||||
|
if (RuleB(Zone, UseZoneController)) {
|
||||||
|
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && this->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||||
|
char data_pass[100] = { 0 };
|
||||||
|
snprintf(data_pass, 99, "%d %d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill), this->GetNPCTypeID());
|
||||||
|
parse->EventNPC(EVENT_DEATH_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2422,6 +2432,11 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
|||||||
hate = 1;
|
hate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iYellForHelp)
|
||||||
|
SetPrimaryAggro(true);
|
||||||
|
else
|
||||||
|
SetAssistAggro(true);
|
||||||
|
|
||||||
bool wasengaged = IsEngaged();
|
bool wasengaged = IsEngaged();
|
||||||
Mob* owner = other->GetOwner();
|
Mob* owner = other->GetOwner();
|
||||||
Mob* mypet = this->GetPet();
|
Mob* mypet = this->GetPet();
|
||||||
@ -2688,16 +2703,38 @@ uint8 Mob::GetWeaponDamageBonus(const Item_Struct *weapon, bool offhand)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 2h damage bonus
|
// 2h damage bonus
|
||||||
|
int damage_bonus = 1 + (level - 28) / 3;
|
||||||
if (delay <= 27)
|
if (delay <= 27)
|
||||||
return 1 + ((level - 28) / 3);
|
return damage_bonus + 1;
|
||||||
else if (delay < 40)
|
// Client isn't reflecting what the dev quoted, this matches better
|
||||||
return 1 + ((level - 28) / 3) + ((level - 30) / 5);
|
if (level > 29) {
|
||||||
else if (delay < 43)
|
int level_bonus = (level - 30) / 5 + 1;
|
||||||
return 2 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
if (level > 50) {
|
||||||
else if (delay < 45)
|
level_bonus++;
|
||||||
return 3 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
int level_bonus2 = level - 50;
|
||||||
else if (delay >= 45)
|
if (level > 67)
|
||||||
return 4 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
level_bonus2 += 5;
|
||||||
|
else if (level > 59)
|
||||||
|
level_bonus2 += 4;
|
||||||
|
else if (level > 58)
|
||||||
|
level_bonus2 += 3;
|
||||||
|
else if (level > 56)
|
||||||
|
level_bonus2 += 2;
|
||||||
|
else if (level > 54)
|
||||||
|
level_bonus2++;
|
||||||
|
level_bonus += level_bonus2 * delay / 40;
|
||||||
|
}
|
||||||
|
damage_bonus += level_bonus;
|
||||||
|
}
|
||||||
|
if (delay >= 40) {
|
||||||
|
int delay_bonus = (delay - 40) / 3 + 1;
|
||||||
|
if (delay >= 45)
|
||||||
|
delay_bonus += 2;
|
||||||
|
else if (delay >= 43)
|
||||||
|
delay_bonus++;
|
||||||
|
damage_bonus += delay_bonus;
|
||||||
|
}
|
||||||
|
return damage_bonus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -490,6 +490,7 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
|
|||||||
(item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue))
|
(item->SkillModValue < 0 && newbon->skillmod[item->SkillModType] > item->SkillModValue))
|
||||||
{
|
{
|
||||||
newbon->skillmod[item->SkillModType] = item->SkillModValue;
|
newbon->skillmod[item->SkillModType] = item->SkillModValue;
|
||||||
|
newbon->skillmodmax[item->SkillModType] = item->SkillModMax;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -679,7 +679,7 @@ public:
|
|||||||
|
|
||||||
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
||||||
void IncreaseLanguageSkill(int skill_id, int value = 1);
|
void IncreaseLanguageSkill(int skill_id, int value = 1);
|
||||||
virtual uint16 GetSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return((itembonuses.skillmod[skill_id] > 0) ? m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100 : m_pp.skills[skill_id]); } return 0; }
|
virtual uint16 GetSkill(SkillUseTypes skill_id) const {if (skill_id <= HIGHEST_SKILL) {return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]);} return 0;}
|
||||||
uint32 GetRawSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
uint32 GetRawSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
||||||
bool HasSkill(SkillUseTypes skill_id) const;
|
bool HasSkill(SkillUseTypes skill_id) const;
|
||||||
bool CanHaveSkill(SkillUseTypes skill_id) const;
|
bool CanHaveSkill(SkillUseTypes skill_id) const;
|
||||||
|
|||||||
@ -2925,43 +2925,111 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delegate to tradeskill object to perform combine
|
|
||||||
AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer;
|
AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer;
|
||||||
bool deleteItems = false;
|
bool deleteItems = false;
|
||||||
if (GetClientVersion() >= ClientVersion::RoF)
|
if (GetClientVersion() >= ClientVersion::RoF)
|
||||||
{
|
{
|
||||||
ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
|
ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
|
||||||
|
|
||||||
//Message(15, "%i %i %i %i %i %i", in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id);
|
//Log.Out(Logs::DebugLevel::Moderate, Logs::Debug, "cslot: %i aslot: %i cidx: %i aidx: %i act: %i dest: %i",
|
||||||
|
// in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id);
|
||||||
|
|
||||||
// Adding augment
|
ItemInst *tobe_auged = nullptr, *old_aug = nullptr, *new_aug = nullptr, *aug = nullptr, *solvent = nullptr;
|
||||||
if (in_augment->augment_action == 0)
|
|
||||||
{
|
|
||||||
ItemInst *tobe_auged = nullptr, *auged_with = nullptr;
|
|
||||||
int8 slot = -1;
|
|
||||||
Inventory& user_inv = GetInv();
|
Inventory& user_inv = GetInv();
|
||||||
|
|
||||||
uint16 slot_id = in_augment->container_slot;
|
uint16 item_slot = in_augment->container_slot;
|
||||||
uint16 aug_slot_id = in_augment->augment_slot;
|
uint16 solvent_slot = in_augment->augment_slot;
|
||||||
if (slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX)
|
uint8 mat = Inventory::CalcMaterialFromSlot(item_slot); // for when player is augging a piece of equipment while they're wearing it
|
||||||
|
|
||||||
|
if (item_slot == INVALID_INDEX || solvent_slot == INVALID_INDEX)
|
||||||
{
|
{
|
||||||
Message(13, "Error: Invalid Aug Index.");
|
Message(13, "Error: Invalid Aug Index.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tobe_auged = user_inv.GetItem(slot_id);
|
tobe_auged = user_inv.GetItem(item_slot);
|
||||||
auged_with = user_inv.GetItem(MainCursor);
|
solvent = user_inv.GetItem(solvent_slot);
|
||||||
|
|
||||||
if (tobe_auged && auged_with)
|
if (!tobe_auged)
|
||||||
{
|
{
|
||||||
if (((tobe_auged->IsAugmentSlotAvailable(auged_with->GetAugmentType(), in_augment->augment_index)) != -1) &&
|
Message(13, "Error: Invalid item passed for augmenting.");
|
||||||
(tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots)))
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((in_augment->augment_action == 1) || (in_augment->augment_action == 2))
|
||||||
{
|
{
|
||||||
tobe_auged->PutAugment(in_augment->augment_index, *auged_with);
|
// Check for valid distiller if safely removing / swapping an augmentation
|
||||||
|
|
||||||
|
if (!solvent)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to safely remove an augment without a distiller.");
|
||||||
|
Message(13, "Error: Missing an augmentation distiller for safely removing this augment.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (solvent->GetItem()->ItemType == ItemUseTypes::ItemTypeAugmentationDistiller)
|
||||||
|
{
|
||||||
|
old_aug = tobe_auged->GetAugment(in_augment->augment_index);
|
||||||
|
|
||||||
|
if (!old_aug)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to safely remove a nonexistent augment.");
|
||||||
|
Message(13, "Error: No augment found in slot %i for safely removing.", in_augment->augment_index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (solvent->GetItem()->ID != old_aug->GetItem()->AugDistiller)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to safely remove an augment with the wrong distiller (item %u vs expected %u).", solvent->GetItem()->ID, old_aug->GetItem()->AugDistiller);
|
||||||
|
Message(13, "Error: Wrong augmentation distiller for safely removing this augment.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (solvent->GetItem()->ItemType != ItemUseTypes::ItemTypePerfectedAugmentationDistiller)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to safely remove an augment with a non-distiller item.");
|
||||||
|
Message(13, "Error: Invalid augmentation distiller for safely removing this augment.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (in_augment->augment_action)
|
||||||
|
{
|
||||||
|
case 0: // Adding an augment
|
||||||
|
case 2: // Swapping augment
|
||||||
|
new_aug = user_inv.GetItem(MainCursor);
|
||||||
|
|
||||||
|
if (!new_aug) // Shouldn't get the OP code without the augment on the user's cursor, but maybe it's h4x.
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "AugmentItem OpCode with 'Insert' or 'Swap' action received, but no augment on client's cursor.");
|
||||||
|
Message(13, "Error: No augment found on cursor for inserting.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (((tobe_auged->IsAugmentSlotAvailable(new_aug->GetAugmentType(), in_augment->augment_index)) != -1) &&
|
||||||
|
(tobe_auged->AvailableWearSlot(new_aug->GetItem()->Slots)))
|
||||||
|
{
|
||||||
|
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
|
||||||
|
if (old_aug)
|
||||||
|
{
|
||||||
|
// An old augment was removed in order to be replaced with the new one (augment_action 2)
|
||||||
|
|
||||||
|
CalcBonuses();
|
||||||
|
|
||||||
|
std::vector<EQEmu::Any> args;
|
||||||
|
args.push_back(old_aug);
|
||||||
|
parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
||||||
|
|
||||||
|
args.assign(1, tobe_auged);
|
||||||
|
args.push_back(false);
|
||||||
|
parse->EventItem(EVENT_AUGMENT_REMOVE, this, old_aug, nullptr, "", in_augment->augment_index, &args);
|
||||||
|
}
|
||||||
|
|
||||||
|
tobe_auged->PutAugment(in_augment->augment_index, *new_aug);
|
||||||
tobe_auged->UpdateOrnamentationInfo();
|
tobe_auged->UpdateOrnamentationInfo();
|
||||||
|
|
||||||
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index);
|
aug = tobe_auged->GetAugment(in_augment->augment_index);
|
||||||
if (aug) {
|
if (aug)
|
||||||
|
{
|
||||||
std::vector<EQEmu::Any> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(aug);
|
args.push_back(aug);
|
||||||
parse->EventItem(EVENT_AUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
parse->EventItem(EVENT_AUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
||||||
@ -2971,22 +3039,48 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Message(13, "Error: Could not find augmentation at index %i. Aborting.", in_augment->augment_index);
|
Message(13, "Error: Could not properly insert augmentation into augment slot %i. Aborting.", in_augment->augment_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemOneToPush = tobe_auged->Clone();
|
itemOneToPush = tobe_auged->Clone();
|
||||||
|
if (old_aug)
|
||||||
|
{
|
||||||
|
itemTwoToPush = old_aug->Clone();
|
||||||
|
}
|
||||||
|
|
||||||
// Must push items after the items in inventory are deleted - necessary due to lore items...
|
// Must push items after the items in inventory are deleted - necessary due to lore items...
|
||||||
if (itemOneToPush)
|
if (itemOneToPush)
|
||||||
{
|
{
|
||||||
DeleteItemInInventory(slot_id, 0, true);
|
DeleteItemInInventory(item_slot, 0, true);
|
||||||
DeleteItemInInventory(MainCursor, 0, true);
|
DeleteItemInInventory(MainCursor, new_aug->IsStackable() ? 1 : 0, true);
|
||||||
|
|
||||||
if (PutItemInInventory(slot_id, *itemOneToPush, true))
|
if (solvent)
|
||||||
|
{
|
||||||
|
// Consume the augment distiller
|
||||||
|
DeleteItemInInventory(solvent_slot, solvent->IsStackable() ? 1 : 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemTwoToPush)
|
||||||
|
{
|
||||||
|
// This is a swap. Return the old aug to the player's cursor.
|
||||||
|
if (!PutItemInInventory(MainCursor, *itemTwoToPush, true))
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Problem returning old augment to player's cursor after augmentation swap.");
|
||||||
|
Message(15, "Error: Failed to retrieve old augment after augmentation swap!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PutItemInInventory(item_slot, *itemOneToPush, true))
|
||||||
{
|
{
|
||||||
CalcBonuses();
|
|
||||||
// Successfully added an augment to the item
|
// Successfully added an augment to the item
|
||||||
return;
|
|
||||||
|
CalcBonuses();
|
||||||
|
|
||||||
|
if (mat != _MaterialInvalid)
|
||||||
|
{
|
||||||
|
SendWearChange(mat); // Visible item augged while equipped. Send WC in case ornamentation changed.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2997,37 +3091,17 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
Message(13, "Error in cloning item for augment. Aborted.");
|
Message(13, "Error in cloning item for augment. Aborted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Message(13, "Error: No available slot for augment in that item.");
|
Message(13, "Error: No available slot for augment in that item.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (in_augment->augment_action == 1)
|
case 1: // Removing augment safely (distiller)
|
||||||
|
aug = tobe_auged->GetAugment(in_augment->augment_index);
|
||||||
|
if (aug)
|
||||||
{
|
{
|
||||||
ItemInst *tobe_auged = nullptr, *auged_with = nullptr;
|
|
||||||
int8 slot = -1;
|
|
||||||
Inventory& user_inv = GetInv();
|
|
||||||
|
|
||||||
uint16 slot_id = in_augment->container_slot;
|
|
||||||
uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot
|
|
||||||
if (slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX)
|
|
||||||
{
|
|
||||||
Message(13, "Error: Invalid Aug Index.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tobe_auged = user_inv.GetItem(slot_id);
|
|
||||||
auged_with = user_inv.GetItem(aug_slot_id);
|
|
||||||
|
|
||||||
ItemInst *old_aug = nullptr;
|
|
||||||
if (!auged_with)
|
|
||||||
return;
|
|
||||||
const uint32 id = auged_with->GetID();
|
|
||||||
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index);
|
|
||||||
if (aug) {
|
|
||||||
std::vector<EQEmu::Any> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(aug);
|
args.push_back(aug);
|
||||||
parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
||||||
@ -3040,35 +3114,103 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Message(13, "Error: Could not find augmentation at index %i. Aborting.");
|
Message(13, "Error: Could not find augmentation to remove at index %i. Aborting.", in_augment->augment_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
|
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
|
||||||
tobe_auged->UpdateOrnamentationInfo();
|
tobe_auged->UpdateOrnamentationInfo();
|
||||||
|
|
||||||
itemOneToPush = tobe_auged->Clone();
|
itemOneToPush = tobe_auged->Clone();
|
||||||
if (old_aug)
|
if (old_aug)
|
||||||
itemTwoToPush = old_aug->Clone();
|
itemTwoToPush = old_aug->Clone();
|
||||||
if (itemOneToPush && itemTwoToPush && auged_with)
|
|
||||||
{
|
|
||||||
DeleteItemInInventory(slot_id, 0, true);
|
|
||||||
DeleteItemInInventory(aug_slot_id, auged_with->IsStackable() ? 1 : 0, true);
|
|
||||||
|
|
||||||
if (!PutItemInInventory(slot_id, *itemOneToPush, true))
|
if (itemOneToPush && itemTwoToPush)
|
||||||
{
|
{
|
||||||
Message(15, "Failed to remove augment properly!");
|
// Consume the augment distiller
|
||||||
|
DeleteItemInInventory(solvent_slot, solvent->IsStackable() ? 1 : 0, true);
|
||||||
|
|
||||||
|
// Remove the augmented item
|
||||||
|
DeleteItemInInventory(item_slot, 0, true);
|
||||||
|
|
||||||
|
// Replace it with the unaugmented item
|
||||||
|
if (!PutItemInInventory(item_slot, *itemOneToPush, true))
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Problem returning equipment item to player's inventory after safe augment removal.");
|
||||||
|
Message(15, "Error: Failed to return item after de-augmentation!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PutItemInInventory(MainCursor, *itemTwoToPush, true))
|
|
||||||
{
|
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
//Message(15, "Successfully removed an augmentation!");
|
|
||||||
|
if (mat != _MaterialInvalid)
|
||||||
|
{
|
||||||
|
SendWearChange(mat); // Visible item augged while equipped. Send WC in case ornamentation changed.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop the removed augment on the player's cursor
|
||||||
|
if (!PutItemInInventory(MainCursor, *itemTwoToPush, true))
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Problem returning augment to player's cursor after safe removal.");
|
||||||
|
Message(15, "Error: Failed to return augment after removal from item!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 3: // Destroying augment (formerly done in birdbath/sealer with a solvent)
|
||||||
|
|
||||||
|
// RoF client does not require an augmentation solvent for destroying an augmentation in an item.
|
||||||
|
// Augments can be destroyed with a right click -> Destroy at any time.
|
||||||
|
|
||||||
|
aug = tobe_auged->GetAugment(in_augment->augment_index);
|
||||||
|
if (aug)
|
||||||
|
{
|
||||||
|
std::vector<EQEmu::Any> args;
|
||||||
|
args.push_back(aug);
|
||||||
|
parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
|
||||||
|
|
||||||
|
args.assign(1, tobe_auged);
|
||||||
|
|
||||||
|
args.push_back(true);
|
||||||
|
|
||||||
|
parse->EventItem(EVENT_AUGMENT_REMOVE, this, aug, nullptr, "", in_augment->augment_index, &args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message(13, "Error: Could not find augmentation to remove at index %i. Aborting.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tobe_auged->DeleteAugment(in_augment->augment_index);
|
||||||
|
tobe_auged->UpdateOrnamentationInfo();
|
||||||
|
|
||||||
|
itemOneToPush = tobe_auged->Clone();
|
||||||
|
if (itemOneToPush)
|
||||||
|
{
|
||||||
|
DeleteItemInInventory(item_slot, 0, true);
|
||||||
|
|
||||||
|
if (!PutItemInInventory(item_slot, *itemOneToPush, true))
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Problem returning equipment item to player's inventory after augment deletion.");
|
||||||
|
Message(15, "Error: Failed to return item after destroying augment!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CalcBonuses();
|
||||||
|
|
||||||
|
if (mat != _MaterialInvalid)
|
||||||
|
{
|
||||||
|
SendWearChange(mat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // Unknown
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Unrecognized augmentation action - cslot: %i aslot: %i cidx: %i aidx: %i act: %i dest: %i",
|
||||||
|
in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Delegate to tradeskill object to perform combine
|
||||||
Object::HandleAugmentation(this, in_augment, m_tradeskill_object);
|
Object::HandleAugmentation(this, in_augment, m_tradeskill_object);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -278,6 +278,7 @@ struct StatBonuses {
|
|||||||
float AggroRange; // when calculate just replace original value with this
|
float AggroRange; // when calculate just replace original value with this
|
||||||
float AssistRange;
|
float AssistRange;
|
||||||
int32 skillmod[HIGHEST_SKILL+1];
|
int32 skillmod[HIGHEST_SKILL+1];
|
||||||
|
int32 skillmodmax[HIGHEST_SKILL+1];
|
||||||
int effective_casting_level;
|
int effective_casting_level;
|
||||||
int reflect_chance; // chance to reflect incoming spell
|
int reflect_chance; // chance to reflect incoming spell
|
||||||
uint32 singingMod;
|
uint32 singingMod;
|
||||||
|
|||||||
@ -114,7 +114,9 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_RESPAWN",
|
"EVENT_RESPAWN",
|
||||||
"EVENT_DEATH_COMPLETE",
|
"EVENT_DEATH_COMPLETE",
|
||||||
"EVENT_UNHANDLED_OPCODE",
|
"EVENT_UNHANDLED_OPCODE",
|
||||||
"EVENT_TICK"
|
"EVENT_TICK",
|
||||||
|
"EVENT_SPAWN_ZONE",
|
||||||
|
"EVENT_DEATH_ZONE",
|
||||||
};
|
};
|
||||||
|
|
||||||
PerlembParser::PerlembParser() : perl(nullptr) {
|
PerlembParser::PerlembParser() : perl(nullptr) {
|
||||||
@ -1424,6 +1426,21 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EVENT_SPAWN_ZONE: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "spawned_entity_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "spawned_npc_id", sep.arg[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EVENT_DEATH_ZONE: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||||
|
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||||
|
ExportVar(package_name.c_str(), "killed_npc_id", sep.arg[4]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -2919,6 +2919,29 @@ XS(XS__UpdateInstanceTimer) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__GetInstanceTimer);
|
||||||
|
XS(XS__GetInstanceTimer) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 0)
|
||||||
|
Perl_croak(aTHX_ "Usage: GetInstanceTimer()");
|
||||||
|
|
||||||
|
uint32 timer = quest_manager.GetInstanceTimer();
|
||||||
|
|
||||||
|
XSRETURN_UV(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS__GetInstanceTimerByID);
|
||||||
|
XS(XS__GetInstanceTimerByID) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: GetInstanceTimerByID(instance_id)");
|
||||||
|
|
||||||
|
uint16 instance_id = (uint16)SvUV(ST(0));
|
||||||
|
uint32 timer = quest_manager.GetInstanceTimerByID(instance_id);
|
||||||
|
|
||||||
|
XSRETURN_UV(timer);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__GetInstanceID);
|
XS(XS__GetInstanceID);
|
||||||
XS(XS__GetInstanceID) {
|
XS(XS__GetInstanceID) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -3614,6 +3637,19 @@ XS(XS__debug)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__UpdateZoneHeader);
|
||||||
|
XS(XS__UpdateZoneHeader) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: UpdateZoneHeader(type, value)");
|
||||||
|
|
||||||
|
std::string type = (std::string)SvPV_nolen(ST(0));
|
||||||
|
std::string value = (std::string)SvPV_nolen(ST(1));
|
||||||
|
quest_manager.UpdateZoneHeader(type, value);
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the callback perl will look for to setup the
|
This is the callback perl will look for to setup the
|
||||||
@ -3650,6 +3686,8 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||||
newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file);
|
newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file);
|
||||||
|
newXS(strcpy(buf, "GetInstanceTimer"), XS__GetInstanceTimer, file);
|
||||||
|
newXS(strcpy(buf, "GetInstanceTimerByID"), XS__GetInstanceTimerByID, file);
|
||||||
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
||||||
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
||||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||||
@ -3841,6 +3879,7 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
||||||
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
||||||
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
||||||
|
newXS(strcpy(buf, "UpdateZoneHeader"), XS__UpdateZoneHeader, file);
|
||||||
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
||||||
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
||||||
newXS(strcpy(buf, "we"), XS__we, file);
|
newXS(strcpy(buf, "we"), XS__we, file);
|
||||||
|
|||||||
@ -641,8 +641,18 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
|||||||
{
|
{
|
||||||
npc->SetID(GetFreeID());
|
npc->SetID(GetFreeID());
|
||||||
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
||||||
|
|
||||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||||
|
|
||||||
|
/* Zone controller process EVENT_SPAWN_ZONE */
|
||||||
|
if (RuleB(Zone, UseZoneController)) {
|
||||||
|
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||||
|
char data_pass[100] = { 0 };
|
||||||
|
snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID());
|
||||||
|
parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint16 emoteid = npc->GetEmoteID();
|
uint16 emoteid = npc->GetEmoteID();
|
||||||
if (emoteid != 0)
|
if (emoteid != 0)
|
||||||
npc->DoNPCEmote(ONSPAWN, emoteid);
|
npc->DoNPCEmote(ONSPAWN, emoteid);
|
||||||
|
|||||||
@ -83,7 +83,8 @@ typedef enum {
|
|||||||
EVENT_DEATH_COMPLETE,
|
EVENT_DEATH_COMPLETE,
|
||||||
EVENT_UNHANDLED_OPCODE,
|
EVENT_UNHANDLED_OPCODE,
|
||||||
EVENT_TICK,
|
EVENT_TICK,
|
||||||
|
EVENT_SPAWN_ZONE,
|
||||||
|
EVENT_DEATH_ZONE,
|
||||||
_LargestEventID
|
_LargestEventID
|
||||||
} QuestEventID;
|
} QuestEventID;
|
||||||
|
|
||||||
|
|||||||
@ -808,6 +808,14 @@ void lua_update_instance_timer(uint16 instance_id, uint32 new_duration) {
|
|||||||
quest_manager.UpdateInstanceTimer(instance_id, new_duration);
|
quest_manager.UpdateInstanceTimer(instance_id, new_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 lua_get_instance_timer() {
|
||||||
|
return quest_manager.GetInstanceTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 lua_get_instance_timer_by_id(uint16 instance_id) {
|
||||||
|
return quest_manager.GetInstanceTimerByID(instance_id);
|
||||||
|
}
|
||||||
|
|
||||||
int lua_get_instance_id(const char *zone, uint32 version) {
|
int lua_get_instance_id(const char *zone, uint32 version) {
|
||||||
return quest_manager.GetInstanceID(zone, version);
|
return quest_manager.GetInstanceID(zone, version);
|
||||||
}
|
}
|
||||||
@ -1296,6 +1304,10 @@ void lua_debug(std::string message, int level) {
|
|||||||
Log.Out(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
|
Log.Out(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_update_zone_header(std::string type, std::string value) {
|
||||||
|
quest_manager.UpdateZoneHeader(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||||
cur = table[#name]; \
|
cur = table[#name]; \
|
||||||
if(luabind::type(cur) != LUA_TNIL) { \
|
if(luabind::type(cur) != LUA_TNIL) { \
|
||||||
@ -1719,7 +1731,9 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
||||||
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
||||||
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
||||||
luabind::value("tick", static_cast<int>(EVENT_TICK))
|
luabind::value("tick", static_cast<int>(EVENT_TICK)),
|
||||||
|
luabind::value("spawn_zone", static_cast<int>(EVENT_SPAWN_ZONE)),
|
||||||
|
luabind::value("death_zone", static_cast<int>(EVENT_DEATH_ZONE))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
122
zone/lua_mob.cpp
122
zone/lua_mob.cpp
@ -1881,6 +1881,106 @@ bool Lua_Mob::IsBlind() {
|
|||||||
return self->IsBlind();
|
return self->IsBlind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 Lua_Mob::SeeInvisible() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->SeeInvisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::SeeInvisibleUndead() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->SeeInvisibleUndead();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::SeeHide() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->SeeHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::SeeImprovedHide() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->SeeImprovedHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Lua_Mob::GetNimbusEffect1() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetNimbusEffect1();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Lua_Mob::GetNimbusEffect2() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetNimbusEffect2();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Lua_Mob::GetNimbusEffect3() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetNimbusEffect3();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::IsTargetable() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsTargetable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::HasShieldEquiped() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasShieldEquiped();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::HasTwoHandBluntEquiped() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasTwoHandBluntEquiped();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::HasTwoHanderEquipped() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasTwoHanderEquipped();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Lua_Mob::GetHerosForgeModel(uint8 material_slot) {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetHerosForgeModel(material_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Lua_Mob::IsEliteMaterialItem(uint8 material_slot) {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->IsEliteMaterialItem(material_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Lua_Mob::GetBaseSize() {
|
||||||
|
Lua_Safe_Call_Real();
|
||||||
|
return self->GetBaseSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::HasOwner() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::IsPet() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsPet();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::HasPet() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->HasPet();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::IsSilenced() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsSilenced();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_Mob::IsAmnesiad() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsAmnesiad();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Lua_Mob::GetMeleeMitigation() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetMeleeMitigation();
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_mob() {
|
luabind::scope lua_register_mob() {
|
||||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@ -2203,7 +2303,27 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
||||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
||||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack)
|
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack)
|
||||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot);
|
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot)
|
||||||
|
.def("SeeInvisible", (uint8(Lua_Mob::*)(void))&Lua_Mob::SeeInvisible)
|
||||||
|
.def("SeeInvisibleUndead", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeInvisibleUndead)
|
||||||
|
.def("SeeHide", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeHide)
|
||||||
|
.def("SeeImprovedHide", (bool(Lua_Mob::*)(bool))&Lua_Mob::SeeImprovedHide)
|
||||||
|
.def("GetNimbusEffect1", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect1)
|
||||||
|
.def("GetNimbusEffect2", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect2)
|
||||||
|
.def("GetNimbusEffect3", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect3)
|
||||||
|
.def("IsTargetable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTargetable)
|
||||||
|
.def("HasShieldEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquiped)
|
||||||
|
.def("HasTwoHandBluntEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquiped)
|
||||||
|
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
|
||||||
|
.def("GetHerosForgeModel", (int32(Lua_Mob::*)(uint8))&Lua_Mob::GetHerosForgeModel)
|
||||||
|
.def("IsEliteMaterialItem", (uint32(Lua_Mob::*)(uint8))&Lua_Mob::IsEliteMaterialItem)
|
||||||
|
.def("GetBaseSize", (double(Lua_Mob::*)(void))&Lua_Mob::GetBaseSize)
|
||||||
|
.def("HasOwner", (bool(Lua_Mob::*)(void))&Lua_Mob::HasOwner)
|
||||||
|
.def("IsPet", (bool(Lua_Mob::*)(void))&Lua_Mob::IsPet)
|
||||||
|
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
||||||
|
.def("IsSilenced", (bool(Lua_Mob::*)(void))&Lua_Mob::IsSilenced)
|
||||||
|
.def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad)
|
||||||
|
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_special_abilities() {
|
luabind::scope lua_register_special_abilities() {
|
||||||
|
|||||||
@ -358,6 +358,26 @@ public:
|
|||||||
int CanBuffStack(int spell_id, int caster_level);
|
int CanBuffStack(int spell_id, int caster_level);
|
||||||
int CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite);
|
int CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite);
|
||||||
void SetPseudoRoot(bool in);
|
void SetPseudoRoot(bool in);
|
||||||
|
uint8 SeeInvisible();
|
||||||
|
bool SeeInvisibleUndead();
|
||||||
|
bool SeeHide();
|
||||||
|
bool SeeImprovedHide();
|
||||||
|
uint8 GetNimbusEffect1();
|
||||||
|
uint8 GetNimbusEffect2();
|
||||||
|
uint8 GetNimbusEffect3();
|
||||||
|
bool IsTargetable();
|
||||||
|
bool HasShieldEquiped();
|
||||||
|
bool HasTwoHandBluntEquiped();
|
||||||
|
bool HasTwoHanderEquipped();
|
||||||
|
uint32 GetHerosForgeModel(uint8 material_slot);
|
||||||
|
uint32 IsEliteMaterialItem(uint8 material_slot);
|
||||||
|
float GetBaseSize();
|
||||||
|
bool HasOwner();
|
||||||
|
bool IsPet();
|
||||||
|
bool HasPet();
|
||||||
|
bool IsSilenced();
|
||||||
|
bool IsAmnesiad();
|
||||||
|
int32 GetMeleeMitigation();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -117,7 +117,9 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_respawn",
|
"event_respawn",
|
||||||
"event_death_complete",
|
"event_death_complete",
|
||||||
"event_unhandled_opcode",
|
"event_unhandled_opcode",
|
||||||
"event_tick"
|
"event_tick",
|
||||||
|
"event_spawn_zone",
|
||||||
|
"event_death_zone"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
|
|||||||
13
zone/mob.cpp
13
zone/mob.cpp
@ -433,6 +433,9 @@ Mob::Mob(const char* in_name,
|
|||||||
|
|
||||||
emoteid = 0;
|
emoteid = 0;
|
||||||
endur_upkeep = false;
|
endur_upkeep = false;
|
||||||
|
PrimaryAggro = false;
|
||||||
|
AssistAggro = false;
|
||||||
|
npc_assist_cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob::~Mob()
|
Mob::~Mob()
|
||||||
@ -2693,6 +2696,8 @@ bool Mob::RemoveFromHateList(Mob* mob)
|
|||||||
{
|
{
|
||||||
AI_Event_NoLongerEngaged();
|
AI_Event_NoLongerEngaged();
|
||||||
zone->DelAggroMob();
|
zone->DelAggroMob();
|
||||||
|
if (IsNPC() && !RuleB(Aggro, AllowTickPulling))
|
||||||
|
ResetAssistCap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(GetTarget() == mob)
|
if(GetTarget() == mob)
|
||||||
@ -5677,3 +5682,11 @@ void Mob::SetCurrentSpeed(int in){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 Mob::GetMeleeMitigation() {
|
||||||
|
int32 mitigation = 0;
|
||||||
|
mitigation += spellbonuses.MeleeMitigationEffect;
|
||||||
|
mitigation += itembonuses.MeleeMitigationEffect;
|
||||||
|
mitigation += aabonuses.MeleeMitigationEffect;
|
||||||
|
return mitigation;
|
||||||
|
}
|
||||||
15
zone/mob.h
15
zone/mob.h
@ -504,6 +504,10 @@ public:
|
|||||||
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
|
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
|
||||||
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
|
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
|
||||||
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
||||||
|
bool HasPrimaryAggro() { return PrimaryAggro; }
|
||||||
|
bool HasAssistAggro() { return AssistAggro; }
|
||||||
|
void SetPrimaryAggro(bool value) { PrimaryAggro = value; if (value) AssistAggro = false; }
|
||||||
|
void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; }
|
||||||
bool HateSummon();
|
bool HateSummon();
|
||||||
void FaceTarget(Mob* MobToFace = 0);
|
void FaceTarget(Mob* MobToFace = 0);
|
||||||
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
||||||
@ -748,6 +752,7 @@ public:
|
|||||||
inline bool GetInvul(void) { return invulnerable; }
|
inline bool GetInvul(void) { return invulnerable; }
|
||||||
inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; }
|
inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; }
|
||||||
virtual int GetHaste();
|
virtual int GetHaste();
|
||||||
|
int32 GetMeleeMitigation();
|
||||||
|
|
||||||
uint8 GetWeaponDamageBonus(const Item_Struct* weapon, bool offhand = false);
|
uint8 GetWeaponDamageBonus(const Item_Struct* weapon, bool offhand = false);
|
||||||
uint16 GetDamageTable(SkillUseTypes skillinuse);
|
uint16 GetDamageTable(SkillUseTypes skillinuse);
|
||||||
@ -993,6 +998,11 @@ public:
|
|||||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||||
bool CheckAATimer(int timer);
|
bool CheckAATimer(int timer);
|
||||||
|
|
||||||
|
int NPCAssistCap() { return npc_assist_cap; }
|
||||||
|
void AddAssistCap() { ++npc_assist_cap; }
|
||||||
|
void DelAssistCap() { --npc_assist_cap; }
|
||||||
|
void ResetAssistCap() { npc_assist_cap = 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, int special = 0);
|
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, int special = 0);
|
||||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||||
@ -1293,6 +1303,11 @@ protected:
|
|||||||
glm::vec4 m_CurrentWayPoint;
|
glm::vec4 m_CurrentWayPoint;
|
||||||
int cur_wp_pause;
|
int cur_wp_pause;
|
||||||
|
|
||||||
|
bool PrimaryAggro;
|
||||||
|
bool AssistAggro;
|
||||||
|
int npc_assist_cap;
|
||||||
|
Timer assist_cap_timer; // clear assist cap so more nearby mobs can be called for help
|
||||||
|
|
||||||
|
|
||||||
int patrol;
|
int patrol;
|
||||||
glm::vec3 m_FearWalkTarget;
|
glm::vec3 m_FearWalkTarget;
|
||||||
|
|||||||
@ -1735,8 +1735,10 @@ void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
|
|||||||
if (iYellForHelp) {
|
if (iYellForHelp) {
|
||||||
if(IsPet()) {
|
if(IsPet()) {
|
||||||
GetOwner()->AI_Event_Engaged(attacker, iYellForHelp);
|
GetOwner()->AI_Event_Engaged(attacker, iYellForHelp);
|
||||||
} else {
|
} else if (!HasAssistAggro() && NPCAssistCap() < RuleI(Combat, NPCAssistCap)) {
|
||||||
entity_list.AIYellForHelp(this, attacker);
|
entity_list.AIYellForHelp(this, attacker);
|
||||||
|
if (NPCAssistCap() > 0 && !assist_cap_timer.Enabled())
|
||||||
|
assist_cap_timer.Start(RuleI(Combat, NPCAssistCapTimer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1787,6 +1789,8 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
|
|
||||||
if(IsNPC())
|
if(IsNPC())
|
||||||
{
|
{
|
||||||
|
SetPrimaryAggro(false);
|
||||||
|
SetAssistAggro(false);
|
||||||
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
if(CastToNPC()->GetCombatEvent() && GetHP() > 0)
|
||||||
{
|
{
|
||||||
if(entity_list.GetNPCByID(this->GetID()))
|
if(entity_list.GetNPCByID(this->GetID()))
|
||||||
|
|||||||
59
zone/npc.cpp
59
zone/npc.cpp
@ -712,8 +712,18 @@ bool NPC::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Handle assists...
|
//Handle assists...
|
||||||
if(assist_timer.Check() && IsEngaged() && !Charmed()) {
|
if (assist_cap_timer.Check()) {
|
||||||
|
if (NPCAssistCap() > 0)
|
||||||
|
DelAssistCap();
|
||||||
|
else
|
||||||
|
assist_cap_timer.Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assist_timer.Check() && IsEngaged() && !Charmed() && !HasAssistAggro() &&
|
||||||
|
NPCAssistCap() < RuleI(Combat, NPCAssistCap)) {
|
||||||
entity_list.AIYellForHelp(this, GetTarget());
|
entity_list.AIYellForHelp(this, GetTarget());
|
||||||
|
if (NPCAssistCap() > 0 && !assist_cap_timer.Enabled())
|
||||||
|
assist_cap_timer.Start(RuleI(Combat, NPCAssistCapTimer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(qGlobals)
|
if(qGlobals)
|
||||||
@ -833,6 +843,53 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NPC::SpawnZoneController(){
|
||||||
|
|
||||||
|
if (!RuleB(Zone, UseZoneController))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
NPCType* npc_type = new NPCType;
|
||||||
|
memset(npc_type, 0, sizeof(NPCType));
|
||||||
|
|
||||||
|
strncpy(npc_type->name, "zone_controller", 60);
|
||||||
|
npc_type->cur_hp = 2000000000;
|
||||||
|
npc_type->max_hp = 2000000000;
|
||||||
|
npc_type->hp_regen = 100000000;
|
||||||
|
npc_type->race = 240;
|
||||||
|
npc_type->gender = 2;
|
||||||
|
npc_type->class_ = 1;
|
||||||
|
npc_type->deity = 1;
|
||||||
|
npc_type->level = 200;
|
||||||
|
npc_type->npc_id = ZONE_CONTROLLER_NPC_ID;
|
||||||
|
npc_type->loottable_id = 0;
|
||||||
|
npc_type->texture = 3;
|
||||||
|
npc_type->runspeed = 0;
|
||||||
|
npc_type->d_melee_texture1 = 0;
|
||||||
|
npc_type->d_melee_texture2 = 0;
|
||||||
|
npc_type->merchanttype = 0;
|
||||||
|
npc_type->bodytype = 11;
|
||||||
|
|
||||||
|
npc_type->prim_melee_type = 28;
|
||||||
|
npc_type->sec_melee_type = 28;
|
||||||
|
|
||||||
|
npc_type->findable = 0;
|
||||||
|
npc_type->trackable = 0;
|
||||||
|
|
||||||
|
strcpy(npc_type->special_abilities, "12,1^13,1^14,1^15,1^16,1^17,1^19,1^22,1^24,1^25,1^28,1^31,1^35,1^39,1^42,1");
|
||||||
|
|
||||||
|
glm::vec4 point;
|
||||||
|
point.x = 5000;
|
||||||
|
point.y = 5000;
|
||||||
|
point.z = -5000;
|
||||||
|
|
||||||
|
NPC* npc = new NPC(npc_type, nullptr, point, FlyMode3);
|
||||||
|
npc->GiveNPCTypeData(npc_type);
|
||||||
|
|
||||||
|
entity_list.AddNPC(npc);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
|
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
|
||||||
if(spawncommand == 0 || spawncommand[0] == 0) {
|
if(spawncommand == 0 || spawncommand[0] == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -96,6 +96,7 @@ class NPC : public Mob
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr);
|
static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr);
|
||||||
|
static bool SpawnZoneController();
|
||||||
static int8 GetAILevel(bool iForceReRead = false);
|
static int8 GetAILevel(bool iForceReRead = false);
|
||||||
|
|
||||||
NPC(const NPCType* data, Spawn2* respawn, const glm::vec4& position, int iflymode, bool IsCorpse = false);
|
NPC(const NPCType* data, Spawn2* respawn, const glm::vec4& position, int iflymode, bool IsCorpse = false);
|
||||||
|
|||||||
@ -8490,6 +8490,524 @@ XS(XS_Mob_IsBlind) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_SeeInvisible);
|
||||||
|
XS(XS_Mob_SeeInvisible) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::SeeInvisible(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
uint8 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->SeeInvisible();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_SeeInvisibleUndead);
|
||||||
|
XS(XS_Mob_SeeInvisibleUndead) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::SeeInvisibleUndead(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->SeeInvisibleUndead();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_SeeHide);
|
||||||
|
XS(XS_Mob_SeeHide) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::SeeHide(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->SeeHide();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_SeeImprovedHide);
|
||||||
|
XS(XS_Mob_SeeImprovedHide) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::SeeImprovedHide(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->SeeImprovedHide();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetNimbusEffect1);
|
||||||
|
XS(XS_Mob_GetNimbusEffect1) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect1(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
uint8 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetNimbusEffect1();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetNimbusEffect2);
|
||||||
|
XS(XS_Mob_GetNimbusEffect2) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect2(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
uint8 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetNimbusEffect2();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetNimbusEffect3);
|
||||||
|
XS(XS_Mob_GetNimbusEffect3) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetNimbusEffect3(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
uint8 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetNimbusEffect3();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsTargetable);
|
||||||
|
XS(XS_Mob_IsTargetable) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsTargetable(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsTargetable();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_HasShieldEquiped);
|
||||||
|
XS(XS_Mob_HasShieldEquiped) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::HasShieldEquiped(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->HasShieldEquiped();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_HasTwoHandBluntEquiped);
|
||||||
|
XS(XS_Mob_HasTwoHandBluntEquiped) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::HasTwoHandBluntEquiped(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->HasTwoHandBluntEquiped();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_HasTwoHanderEquipped);
|
||||||
|
XS(XS_Mob_HasTwoHanderEquipped) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::HasTwoHanderEquipped(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->HasTwoHanderEquipped();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetHerosForgeModel);
|
||||||
|
XS(XS_Mob_GetHerosForgeModel) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetHerosForgeModel(THIS, material_slot)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
int32 RETVAL;
|
||||||
|
uint8 material_slot = (uint8)SvUV(ST(1));
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetHerosForgeModel(material_slot);
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHi((IV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsEliteMaterialItem);
|
||||||
|
XS(XS_Mob_IsEliteMaterialItem) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsEliteMaterialItem(THIS, material_slot)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
uint32 RETVAL;
|
||||||
|
uint8 material_slot = (uint8)SvUV(ST(1));
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsEliteMaterialItem(material_slot);
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetBaseSize);
|
||||||
|
XS(XS_Mob_GetBaseSize) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetBaseSize(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
float RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetBaseSize();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHn((double)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_HasOwner);
|
||||||
|
XS(XS_Mob_HasOwner) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::HasOwner(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->HasOwner();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsPet);
|
||||||
|
XS(XS_Mob_IsPet) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsPet(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsPet();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_HasPet);
|
||||||
|
XS(XS_Mob_HasPet) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::HasPet(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->HasPet();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsSilenced);
|
||||||
|
XS(XS_Mob_IsSilenced) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsSilenced(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsSilenced();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_IsAmnesiad);
|
||||||
|
XS(XS_Mob_IsAmnesiad) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::IsAmnesiad(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->IsAmnesiad();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_Mob_GetMeleeMitigation);
|
||||||
|
XS(XS_Mob_GetMeleeMitigation) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Mob::GetMeleeMitigation(THIS)");
|
||||||
|
{
|
||||||
|
Mob* THIS;
|
||||||
|
int32 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Mob")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Mob*, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||||
|
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetMeleeMitigation();
|
||||||
|
XSprePUSH;
|
||||||
|
PUSHi((IV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
@ -8803,6 +9321,26 @@ XS(boot_Mob)
|
|||||||
newXSproto(strcpy(buf, "CanClassEquipItem"), XS_Mob_CanClassEquipItem, file, "$$");
|
newXSproto(strcpy(buf, "CanClassEquipItem"), XS_Mob_CanClassEquipItem, file, "$$");
|
||||||
newXSproto(strcpy(buf, "IsFeared"), XS_Mob_IsFeared, file, "$");
|
newXSproto(strcpy(buf, "IsFeared"), XS_Mob_IsFeared, file, "$");
|
||||||
newXSproto(strcpy(buf, "IsBlind"), XS_Mob_IsBlind, file, "$");
|
newXSproto(strcpy(buf, "IsBlind"), XS_Mob_IsBlind, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "SeeInvisible"), XS_Mob_SeeInvisible, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "SeeInvisibleUndead"), XS_Mob_SeeInvisibleUndead, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "SeeHide"), XS_Mob_SeeHide, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "SeeImprovedHide"), XS_Mob_SeeImprovedHide, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetNimbusEffect1"), XS_Mob_GetNimbusEffect1, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetNimbusEffect2"), XS_Mob_GetNimbusEffect2, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetNimbusEffect3"), XS_Mob_GetNimbusEffect3, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsTargetable"), XS_Mob_IsTargetable, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "HasShieldEquiped"), XS_Mob_HasShieldEquiped, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "HasTwoHandBluntEquiped"), XS_Mob_HasTwoHandBluntEquiped, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "HasTwoHanderEquipped"), XS_Mob_HasTwoHanderEquipped, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetHerosForgeModel"), XS_Mob_GetHerosForgeModel, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "IsEliteMaterialItem"), XS_Mob_IsEliteMaterialItem, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "GetBaseSize"), XS_Mob_GetBaseSize, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "HasOwner"), XS_Mob_HasOwner, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsPet"), XS_Mob_IsPet, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "HasPet"), XS_Mob_HasPet, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsSilenced"), XS_Mob_IsSilenced, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "IsAmnesiad"), XS_Mob_IsAmnesiad, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetMeleeMitigation"), XS_Mob_GetMeleeMitigation, file, "$");
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -484,10 +484,17 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
|
|||||||
|
|
||||||
//second look for /quests/zone/npcname.ext (precedence)
|
//second look for /quests/zone/npcname.ext (precedence)
|
||||||
const NPCType *npc_type = database.LoadNPCTypesData(npcid);
|
const NPCType *npc_type = database.LoadNPCTypesData(npcid);
|
||||||
if(!npc_type) {
|
if (!npc_type && npcid != ZONE_CONTROLLER_NPC_ID) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::string npc_name = npc_type->name;
|
|
||||||
|
std::string npc_name;
|
||||||
|
if (npcid == ZONE_CONTROLLER_NPC_ID){
|
||||||
|
npc_name = "zone_controller";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
npc_name = npc_type->name;
|
||||||
|
}
|
||||||
int sz = static_cast<int>(npc_name.length());
|
int sz = static_cast<int>(npc_name.length());
|
||||||
for(int i = 0; i < sz; ++i) {
|
for(int i = 0; i < sz; ++i) {
|
||||||
if(npc_name[i] == '`') {
|
if(npc_name[i] == '`') {
|
||||||
|
|||||||
@ -2598,6 +2598,29 @@ void QuestManager::UpdateInstanceTimer(uint16 instance_id, uint32 new_duration)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 QuestManager::GetInstanceTimer() {
|
||||||
|
if (zone && zone->GetInstanceID() > 0 && zone->GetInstanceTimer()) {
|
||||||
|
uint32 ttime = zone->GetInstanceTimer()->GetRemainingTime();
|
||||||
|
return ttime;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 QuestManager::GetInstanceTimerByID(uint16 instance_id) {
|
||||||
|
if (instance_id == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT ((start_time + duration) - UNIX_TIMESTAMP()) AS `remaining` FROM `instance_list` WHERE `id` = %lu", (unsigned long)instance_id);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
auto row = results.begin();
|
||||||
|
uint32 timer = atoi(row[0]);
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint16 QuestManager::GetInstanceID(const char *zone, int16 version)
|
uint16 QuestManager::GetInstanceID(const char *zone, int16 version)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
@ -3070,3 +3093,75 @@ std::string QuestManager::GetEncounter() const {
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
|
||||||
|
if (strcasecmp(type.c_str(), "ztype") == 0)
|
||||||
|
zone->newzone_data.ztype = atoi(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "fog_red") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.fog_red[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "fog_green") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.fog_green[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "fog_blue") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.fog_blue[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "fog_minclip") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.fog_minclip[i] = atof(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "fog_maxclip") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.fog_maxclip[i] = atof(value.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type.c_str(), "gravity") == 0)
|
||||||
|
zone->newzone_data.gravity = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "time_type") == 0)
|
||||||
|
zone->newzone_data.time_type = atoi(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "rain_chance") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.rain_chance[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "rain_duration") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.rain_duration[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "snow_chance") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.snow_chance[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(type.c_str(), "snow_duration") == 0) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
zone->newzone_data.snow_duration[i] = atoi(value.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type.c_str(), "sky") == 0)
|
||||||
|
zone->newzone_data.sky = atoi(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "safe_x") == 0)
|
||||||
|
zone->newzone_data.safe_x = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "safe_y") == 0)
|
||||||
|
zone->newzone_data.safe_y = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "safe_z") == 0)
|
||||||
|
zone->newzone_data.safe_z = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "max_z") == 0)
|
||||||
|
zone->newzone_data.max_z = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "underworld") == 0)
|
||||||
|
zone->newzone_data.underworld = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "minclip") == 0)
|
||||||
|
zone->newzone_data.minclip = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "maxclip") == 0)
|
||||||
|
zone->newzone_data.maxclip = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "fog_density") == 0)
|
||||||
|
zone->newzone_data.fog_density = atof(value.c_str());
|
||||||
|
else if (strcasecmp(type.c_str(), "suspendbuffs") == 0)
|
||||||
|
zone->newzone_data.SuspendBuffs = atoi(value.c_str());
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||||
|
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||||
|
entity_list.QueueClients(0, outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
@ -218,6 +218,9 @@ public:
|
|||||||
uint32 MerchantCountItem(uint32 NPCid, uint32 itemid);
|
uint32 MerchantCountItem(uint32 NPCid, uint32 itemid);
|
||||||
uint16 CreateInstance(const char *zone, int16 version, uint32 duration);
|
uint16 CreateInstance(const char *zone, int16 version, uint32 duration);
|
||||||
void UpdateInstanceTimer(uint16 instance_id, uint32 new_duration);
|
void UpdateInstanceTimer(uint16 instance_id, uint32 new_duration);
|
||||||
|
void UpdateZoneHeader(std::string type, std::string value);
|
||||||
|
uint32 GetInstanceTimer();
|
||||||
|
uint32 GetInstanceTimerByID(uint16 instance_id = 0);
|
||||||
void DestroyInstance(uint16 instance_id);
|
void DestroyInstance(uint16 instance_id);
|
||||||
uint16 GetInstanceID(const char *zone, int16 version);
|
uint16 GetInstanceID(const char *zone, int16 version);
|
||||||
void AssignToInstance(uint16 instance_id);
|
void AssignToInstance(uint16 instance_id);
|
||||||
|
|||||||
@ -549,6 +549,8 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
|
|||||||
spawn2_list.Insert(new_spawn);
|
spawn2_list.Insert(new_spawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NPC::SpawnZoneController();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -166,25 +166,34 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ItemInst *old_aug = nullptr;
|
ItemInst *old_aug = nullptr;
|
||||||
const uint32 id = auged_with->GetID();
|
bool isSolvent = auged_with->GetItem()->ItemType == ItemUseTypes::ItemTypeAugmentationSolvent;
|
||||||
|
if (!isSolvent && auged_with->GetItem()->ItemType != ItemUseTypes::ItemTypeAugmentationDistiller)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to remove an augment without a solvent or distiller.");
|
||||||
|
user->Message(13, "Error: Missing an augmentation solvent or distiller for removing this augment.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot);
|
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot);
|
||||||
if(aug) {
|
if (aug) {
|
||||||
|
if (!isSolvent && auged_with->GetItem()->ID != aug->GetItem()->AugDistiller)
|
||||||
|
{
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Player tried to safely remove an augment with the wrong distiller (item %u vs expected %u).", auged_with->GetItem()->ID, aug->GetItem()->AugDistiller);
|
||||||
|
user->Message(13, "Error: Wrong augmentation distiller for safely removing this augment.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::vector<EQEmu::Any> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(aug);
|
args.push_back(aug);
|
||||||
parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
||||||
|
|
||||||
args.assign(1, tobe_auged);
|
args.assign(1, tobe_auged);
|
||||||
bool destroyed = false;
|
args.push_back(&isSolvent);
|
||||||
if(id == 40408 || id == 40409 || id == 40410) {
|
|
||||||
destroyed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
args.push_back(&destroyed);
|
|
||||||
|
|
||||||
parse->EventItem(EVENT_AUGMENT_REMOVE, user, aug, nullptr, "", slot, &args);
|
parse->EventItem(EVENT_AUGMENT_REMOVE, user, aug, nullptr, "", slot, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(id == 40408 || id == 40409 || id == 40410)
|
if (isSolvent)
|
||||||
tobe_auged->DeleteAugment(in_augment->augment_slot);
|
tobe_auged->DeleteAugment(in_augment->augment_slot);
|
||||||
else
|
else
|
||||||
old_aug = tobe_auged->RemoveAugment(in_augment->augment_slot);
|
old_aug = tobe_auged->RemoveAugment(in_augment->augment_slot);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user