mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 00:06:36 +00:00
Merge branch 'master' into loot
This commit is contained in:
+859
-1220
File diff suppressed because it is too large
Load Diff
+12
-5
@@ -1307,7 +1307,13 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
conn_state = ReceivedZoneEntry;
|
||||
|
||||
ClientVersion = Connection()->ClientVersion();
|
||||
ClientVersionBit = 1 << (ClientVersion - 1);
|
||||
if (ClientVersion != EQClientUnknown)
|
||||
ClientVersionBit = 1 << (ClientVersion - 1);
|
||||
else
|
||||
ClientVersionBit = 0;
|
||||
|
||||
bool siv = m_inv.SetInventoryVersion(ClientVersion);
|
||||
LogFile->write(EQEMuLog::Debug, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), EQClientVersionName(ClientVersion), ClientVersion);
|
||||
|
||||
/* Antighost code
|
||||
tmp var is so the search doesnt find this object
|
||||
@@ -3999,15 +4005,16 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
||||
else if ((castspell->slot == USE_ITEM_SPELL_SLOT) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // ITEM or POTION cast
|
||||
{
|
||||
//discipline, using the item spell slot
|
||||
if (castspell->inventoryslot == 0xFFFFFFFF) {
|
||||
if (castspell->inventoryslot == INVALID_INDEX) {
|
||||
if (!UseDiscipline(castspell->spell_id, castspell->target_id)) {
|
||||
LogFile->write(EQEMuLog::Debug, "Unknown ability being used by %s, spell being cast is: %i\n", GetName(), castspell->spell_id);
|
||||
InterruptSpell(castspell->spell_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ((castspell->inventoryslot <= EmuConstants::GENERAL_END) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // sanity check
|
||||
else if (m_inv.SupportsClickCasting(castspell->inventoryslot) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // sanity check
|
||||
{
|
||||
// packet field types will be reviewed as packet transistions occur -U
|
||||
const ItemInst* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field
|
||||
//bool cancast = true;
|
||||
if (inst && inst->IsType(ItemClassCommon))
|
||||
@@ -8555,7 +8562,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
||||
|
||||
LogFile->write(EQEMuLog::Debug, "OP ItemVerifyRequest: spell=%i, target=%i, inv=%i", spell_id, target_id, slot_id);
|
||||
|
||||
if ((slot_id < MainCursor) || (slot_id == MainPowerSource) || (slot_id > 250 && slot_id < 331 && ((item->ItemType == ItemTypePotion) || item->PotionBelt))) // sanity check
|
||||
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
|
||||
{
|
||||
ItemInst* p_inst = (ItemInst*)inst;
|
||||
|
||||
@@ -10686,7 +10693,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
Client *i = entity_list.GetClientByName(ri->player_name);
|
||||
if (i){
|
||||
if (IsRaidGrouped()){
|
||||
i->Message_StringID(0, 5060); //group failed, must invite members not in raid...
|
||||
i->Message_StringID(0, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid...
|
||||
return;
|
||||
}
|
||||
Raid *r = entity_list.GetRaidByClient(i);
|
||||
|
||||
@@ -1239,6 +1239,11 @@ void Lua_Client::SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in
|
||||
self->SendMarqueeMessage(type, priority, fade_in, fade_out, duration, msg);
|
||||
}
|
||||
|
||||
void Lua_Client::SendColoredText(uint32 type, std::string msg) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendColoredText(type, msg);
|
||||
}
|
||||
|
||||
void Lua_Client::PlayMP3(std::string file)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
@@ -1492,6 +1497,7 @@ luabind::scope lua_register_client() {
|
||||
.def("SetThirst", (void(Lua_Client::*)(int))&Lua_Client::SetThirst)
|
||||
.def("SetConsumption", (void(Lua_Client::*)(int, int))&Lua_Client::SetConsumption)
|
||||
.def("SendMarqueeMessage", (void(Lua_Client::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_Client::SendMarqueeMessage)
|
||||
.def("SendColoredText", (void(Lua_Client::*)(uint32, std::string))&Lua_Client::SendColoredText)
|
||||
.def("PlayMP3", (void(Lua_Client::*)(std::string))&Lua_Client::PlayMP3);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@ public:
|
||||
void SetThirst(int in_thirst);
|
||||
void SetConsumption(int in_hunger, int in_thirst);
|
||||
void SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg);
|
||||
void SendColoredText(uint32 type, std::string msg);
|
||||
void PlayMP3(std::string file);
|
||||
};
|
||||
|
||||
|
||||
+333
-221
@@ -965,240 +965,352 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z,
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn, uint32 extra) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
uint32 tmp = 0;
|
||||
uint32 tmp2 = 0;
|
||||
uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,Client *client, NPC* spawn, uint32 extra) {
|
||||
|
||||
uint32 npc_type_id = 0;
|
||||
|
||||
if (extra && client && client->GetZoneID())
|
||||
{
|
||||
// Set an npc_type ID within the standard range for the current zone if possible (zone_id * 1000)
|
||||
int starting_npc_id = client->GetZoneID() * 1000;
|
||||
|
||||
std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i",
|
||||
starting_npc_id, starting_npc_id + 1000);
|
||||
auto results = QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
if (results.RowCount() != 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
npc_type_id = 0;
|
||||
}
|
||||
else // No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
|
||||
char tmpstr[64];
|
||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||
std::string query;
|
||||
if (npc_type_id)
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
else
|
||||
{
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
npc_type_id = results.LastInsertedID();
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200,
|
||||
spawn->GetHeading(), spawngroupid);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
spawngroupid, npc_type_id, 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime) {
|
||||
uint32 last_insert_id = 0;
|
||||
|
||||
std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')",
|
||||
zone, spawn->GetName(), Timer::GetCurrentTime());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
last_insert_id = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (respawnTime)
|
||||
respawntime = respawnTime;
|
||||
else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime,
|
||||
spawn->GetHeading(), last_insert_id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
spawnid = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)",
|
||||
last_insert_id, spawn->GetNPCTypeID(), 100);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return spawnid;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC* spawn) {
|
||||
|
||||
std::string query = StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, "
|
||||
"hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, "
|
||||
"loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i",
|
||||
spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, spawn->GetNPCTypeID());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() && client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return results.Success() == true? 1: 0;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn) {
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE "
|
||||
"zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn) {
|
||||
|
||||
uint32 id = 0;
|
||||
uint32 spawngroupID = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
|
||||
"AND version = %u AND spawngroupID = %i",
|
||||
zone, zone_version, spawn->GetSp2());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (row[0])
|
||||
id = atoi(row[0]);
|
||||
|
||||
if (row[1])
|
||||
spawngroupID = atoi(row[1]);
|
||||
|
||||
query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID);
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID());
|
||||
results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 last_insert_id = 0;
|
||||
std::string query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, client->GetX(), client->GetY(), client->GetZ(),
|
||||
120, client->GetHeading(), spawnGroupID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) {
|
||||
|
||||
uint32 npc_type_id;
|
||||
char numberlessName[64];
|
||||
|
||||
EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName)));
|
||||
std::string query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
npc_type_id = results.LastInsertedID();
|
||||
|
||||
if(client)
|
||||
client->LogSQL(query.c_str());
|
||||
|
||||
if(client)
|
||||
client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn, uint32 extra) {
|
||||
|
||||
switch (command) {
|
||||
case 0: { // Create a new NPC and add all spawn related data
|
||||
uint32 npc_type_id = 0;
|
||||
uint32 spawngroupid;
|
||||
if (extra && c && c->GetZoneID())
|
||||
{
|
||||
// Set an npc_type ID within the standard range for the current zone if possible (zone_id * 1000)
|
||||
int starting_npc_id = c->GetZoneID() * 1000;
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i", starting_npc_id, (starting_npc_id + 1000)), errbuf, &result)) {
|
||||
row = mysql_fetch_row(result);
|
||||
if(row)
|
||||
{
|
||||
if (row[0])
|
||||
{
|
||||
npc_type_id = atoi(row[0]) + 1;
|
||||
// Prevent the npc_type id from exceeding the range for this zone
|
||||
if (npc_type_id >= (starting_npc_id + 1000))
|
||||
{
|
||||
npc_type_id = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// row[0] is nullptr - No npc_type IDs set in this range yet
|
||||
npc_type_id = starting_npc_id;
|
||||
}
|
||||
}
|
||||
|
||||
safe_delete_array(query);
|
||||
mysql_free_result(result);
|
||||
}
|
||||
}
|
||||
char tmpstr[64];
|
||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||
if (npc_type_id)
|
||||
{
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO npc_types (id, name, level, race, class, hp, gender, texture, helmtexture, size, loottable_id, merchant_id, face, runspeed, prim_melee_type, sec_melee_type) values(%i,\"%s\",%i,%i,%i,%i,%i,%i,%i,%f,%i,%i,%i,%f,%i,%i)", npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28), errbuf, 0, 0, &npc_type_id)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO npc_types (name, level, race, class, hp, gender, texture, helmtexture, size, loottable_id, merchant_id, face, runspeed, prim_melee_type, sec_melee_type) values(\"%s\",%i,%i,%i,%i,%i,%i,%i,%f,%i,%i,%i,%f,%i,%i)", tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28), errbuf, 0, 0, &npc_type_id)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
snprintf(tmpstr, sizeof(tmpstr), "%s-%s", zone, spawn->GetName());
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawngroup (id, name) values(%i, '%s')", tmp, tmpstr), errbuf, 0, 0, &spawngroupid)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) values('%s', %u, %f, %f, %f, %i, %f, %i)", zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(), spawngroupid), errbuf, 0, 0, &tmp)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawnentry (spawngroupID, npcID, chance) values(%i, %i, %i)", spawngroupid, npc_type_id, 100), errbuf, 0)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
break;
|
||||
return CreateNewNPCCommand(zone, zone_version, c, spawn, extra);
|
||||
}
|
||||
case 1:{ // Add new spawn group and spawn point for an existing NPC Type ID
|
||||
tmp2 = spawn->GetNPCTypeID();
|
||||
char tmpstr[64];
|
||||
snprintf(tmpstr, sizeof(tmpstr), "%s%s%i", zone, spawn->GetName(),Timer::GetCurrentTime());
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawngroup (name) values('%s')", tmpstr), errbuf, 0, 0, &last_insert_id)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
|
||||
uint32 respawntime = 0;
|
||||
uint32 spawnid = 0;
|
||||
if (extra)
|
||||
respawntime = extra;
|
||||
else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0)
|
||||
respawntime = spawn->respawn2->RespawnTimer();
|
||||
else
|
||||
respawntime = 1200;
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) values('%s', %u, %f, %f, %f, %i, %f, %i)", zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime, spawn->GetHeading(), last_insert_id), errbuf, 0, 0, &spawnid)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawnentry (spawngroupID, npcID, chance) values(%i, %i, %i)", last_insert_id, tmp2, 100), errbuf, 0)) {
|
||||
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query, errbuf);
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
return spawnid;
|
||||
break;
|
||||
return AddNewNPCSpawnGroupCommand(zone, zone_version, c, spawn, extra);
|
||||
}
|
||||
case 2: { // Update npc_type appearance and other data on targeted spawn
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE npc_types SET name=\"%s\", level=%i, race=%i, class=%i, hp=%i, gender=%i, texture=%i, helmtexture=%i, size=%i, loottable_id=%i, merchant_id=%i, face=%i, WHERE id=%i", spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), spawn->MerchantType, spawn->GetNPCTypeID()), errbuf, 0)) {
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
return UpdateNPCTypeAppearance(c, spawn);
|
||||
}
|
||||
case 3: { // delete spawn from spawning, but leave in npc_types table
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "SELECT id,spawngroupID from spawn2 where zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2()), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
return 0;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
if (row == nullptr) return false;
|
||||
if (row[0]) tmp = atoi(row[0]);
|
||||
if (row[1]) tmp2 = atoi(row[1]);
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawn2 WHERE id='%i'", tmp), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawngroup WHERE id='%i'", tmp2), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawnentry WHERE spawngroupID='%i'", tmp2), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
|
||||
|
||||
break;
|
||||
return DeleteSpawnLeaveInNPCTypeTable(zone, c, spawn);
|
||||
}
|
||||
case 4: { //delete spawn from DB (including npc_type)
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "SELECT id,spawngroupID from spawn2 where zone='%s' AND version=%u AND spawngroupID=%i", zone, zone_version, spawn->GetSp2()), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
return(0);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
if (row == nullptr) return false;
|
||||
if (row[0]) tmp = atoi(row[0]);
|
||||
if (row[1]) tmp2 = atoi(row[1]);
|
||||
mysql_free_result(result);
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawn2 WHERE id='%i'", tmp), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawngroup WHERE id='%i'", tmp2), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM spawnentry WHERE spawngroupID='%i'", tmp2), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM npc_types WHERE id='%i'", spawn->GetNPCTypeID()), errbuf,0)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
break;
|
||||
return DeleteSpawnRemoveFromNPCTypeTable(zone, zone_version, c, spawn);
|
||||
}
|
||||
case 5: { // add a spawn from spawngroup
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) values('%s', %u, %f, %f, %f, %i, %f, %i)", zone, zone_version, c->GetX(), c->GetY(), c->GetZ(), 120, c->GetHeading(), extra), errbuf, 0, 0, &tmp)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return AddSpawnFromSpawnGroup(zone, zone_version, c, spawn, extra);
|
||||
}
|
||||
case 6: { // add npc_type
|
||||
uint32 npc_type_id;
|
||||
char tmpstr[64];
|
||||
EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr)));
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO npc_types (name, level, race, class, hp, gender, texture, helmtexture, size, loottable_id, merchant_id, face, runspeed, prim_melee_type, sec_melee_type) values(\"%s\",%i,%i,%i,%i,%i,%i,%i,%f,%i,%i,%i,%f,%i,%i)", tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28), errbuf, 0, 0, &npc_type_id)) {
|
||||
safe_delete(query);
|
||||
return false;
|
||||
}
|
||||
if(c) c->LogSQL(query);
|
||||
safe_delete_array(query);
|
||||
if(c) c->Message(0, "%s npc_type ID %i created successfully!", tmpstr, npc_type_id);
|
||||
return true;
|
||||
break;
|
||||
return AddNPCTypes(zone, zone_version, c, spawn, extra);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1743,7 +1855,7 @@ void NPC::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
else
|
||||
ns->spawn.IsMercenary = 0;
|
||||
}
|
||||
|
||||
|
||||
//Not recommended if using above (However, this will work better on older clients).
|
||||
if (RuleB(Pets, UnTargetableSwarmPet)) {
|
||||
if(GetOwnerID() || GetSwarmOwner()) {
|
||||
|
||||
@@ -6020,6 +6020,32 @@ XS(XS_Client_SendMarqueeMessage)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_SendColoredText); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_SendColoredText)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: Client::SendColoredText(color, message)");
|
||||
{
|
||||
Client * THIS;
|
||||
uint32 color = (uint32)SvUV(ST(1));
|
||||
std::string msg = (std::string)SvPV_nolen(ST(2));
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
THIS->SendColoredText(color, msg);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
@@ -6259,6 +6285,7 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$");
|
||||
newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$");
|
||||
newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$");
|
||||
newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$");
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
+33
-21
@@ -26,6 +26,7 @@
|
||||
#include "string_ids.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
|
||||
int Mob::GetKickDamage() {
|
||||
@@ -346,15 +347,23 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
||||
ReuseTime = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction;
|
||||
|
||||
//Live AA - Technique of Master Wu
|
||||
uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack;
|
||||
if (bDoubleSpecialAttack && (bDoubleSpecialAttack >= 100 || bDoubleSpecialAttack > MakeRandomInt(0, 99))) {
|
||||
|
||||
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
||||
MonkSpecialAttack(GetTarget(), MonkSPA[MakeRandomInt(0, 4)]);
|
||||
|
||||
// always 1/4 of the double attack chance, 25% at rank 5 (100/4)
|
||||
if ((bDoubleSpecialAttack / 4) > MakeRandomInt(0, 99))
|
||||
MonkSpecialAttack(GetTarget(), MonkSPA[MakeRandomInt(0, 4)]);
|
||||
int wuchance = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack;
|
||||
if (wuchance) {
|
||||
if (wuchance >= 100 || wuchance > MakeRandomInt(0, 99)) {
|
||||
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
||||
int extra = 1;
|
||||
// always 1/4 of the double attack chance, 25% at rank 5 (100/4)
|
||||
if (wuchance / 4 > MakeRandomInt(0, 99))
|
||||
extra++;
|
||||
// They didn't add a string ID for this.
|
||||
std::string msg = StringFormat("The spirit of Master Wu fills you! You gain %d additional attack(s).", extra);
|
||||
// live uses 400 here -- not sure if it's the best for all clients though
|
||||
SendColoredText(400, msg);
|
||||
while (extra) {
|
||||
MonkSpecialAttack(GetTarget(), MonkSPA[MakeRandomInt(0, 4)]);
|
||||
extra--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ReuseTime < 100) {
|
||||
@@ -1743,18 +1752,21 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
||||
return;
|
||||
|
||||
//Live AA - Technique of Master Wu
|
||||
uint16 bDoubleSpecialAttack = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack;
|
||||
if( bDoubleSpecialAttack && (bDoubleSpecialAttack >= 100 || bDoubleSpecialAttack > MakeRandomInt(0,100))) {
|
||||
|
||||
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
||||
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
||||
|
||||
int TripleChance = 25;
|
||||
if (bDoubleSpecialAttack > 100)
|
||||
TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100;
|
||||
|
||||
if(TripleChance > MakeRandomInt(0,100)) {
|
||||
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
||||
int wuchance = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack;
|
||||
if (wuchance) {
|
||||
if (wuchance >= 100 || wuchance > MakeRandomInt(0, 99)) {
|
||||
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
||||
int extra = 1;
|
||||
if (wuchance / 4 > MakeRandomInt(0, 99))
|
||||
extra++;
|
||||
// They didn't add a string ID for this.
|
||||
std::string msg = StringFormat("The spirit of Master Wu fills you! You gain %d additional attack(s).", extra);
|
||||
// live uses 400 here -- not sure if it's the best for all clients though
|
||||
SendColoredText(400, msg);
|
||||
while (extra) {
|
||||
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0, 4)]);
|
||||
extra--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3205,55 +3205,55 @@ snare has both of them negative, yet their range should work the same:
|
||||
case 124: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += caster_level - 50;
|
||||
result += updownsign * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 125: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 2 * (caster_level - 50);
|
||||
result += updownsign * 2 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 126: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 3 * (caster_level - 50);
|
||||
result += updownsign * 3 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 127: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 4 * (caster_level - 50);
|
||||
result += updownsign * 4 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 128: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 5 * (caster_level - 50);
|
||||
result += updownsign * 5 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 129: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 10 * (caster_level - 50);
|
||||
result += updownsign * 10 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 130: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 15 * (caster_level - 50);
|
||||
result += updownsign * 15 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 131: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 20 * (caster_level - 50);
|
||||
result += updownsign * 20 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 132: // check sign
|
||||
result = ubase;
|
||||
if (caster_level > 50)
|
||||
result += 25 * (caster_level - 50);
|
||||
result += updownsign * 25 * (caster_level - 50);
|
||||
break;
|
||||
|
||||
case 137: // used in berserker AA desperation
|
||||
|
||||
@@ -484,6 +484,19 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
|
||||
return false;
|
||||
}
|
||||
|
||||
// This needs a bit more work for saving timer to PP for zoning etc
|
||||
if (IsClient() && item_slot != INVALID_INDEX && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT))) {
|
||||
ItemInst *itm = CastToClient()->GetInv().GetItem(item_slot);
|
||||
if (itm && itm->GetItem()->RecastDelay) {
|
||||
outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
|
||||
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
|
||||
ird->recast_delay = itm->GetItem()->RecastDelay;
|
||||
ird->recast_type = itm->GetItem()->RecastType;
|
||||
CastToClient()->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@
|
||||
#define TOLD_NOT_ONLINE 5046 //%1 is not online at this time.
|
||||
#define PETITION_NO_DELETE 5053 //You do not have a petition in the queue.
|
||||
#define PETITION_DELETED 5054 //Your petition was successfully deleted.
|
||||
#define ALREADY_IN_RAID 5060 //%1 is already in a raid.
|
||||
#define GAIN_RAIDEXP 5085 //You gained raid experience!
|
||||
#define DUNGEON_SEALED 5141 //The gateway to the dungeon is sealed off to you. Perhaps you would be able to enter if you needed to adventure there.
|
||||
#define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure.
|
||||
|
||||
+18
-18
@@ -1615,36 +1615,36 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
|
||||
|
||||
}
|
||||
|
||||
void Client::SendBazaarWelcome(){
|
||||
|
||||
void Client::SendBazaarWelcome()
|
||||
{
|
||||
const std::string query = "SELECT COUNT(DISTINCT char_id), count(char_id) FROM trader";
|
||||
auto results = database.QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success() && results.RowCount() == 1){
|
||||
auto row = results.begin();
|
||||
auto row = results.begin();
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
||||
|
||||
memset(outapp->pBuffer,0,outapp->size);
|
||||
memset(outapp->pBuffer,0,outapp->size);
|
||||
|
||||
BazaarWelcome_Struct* bws = (BazaarWelcome_Struct*)outapp->pBuffer;
|
||||
BazaarWelcome_Struct* bws = (BazaarWelcome_Struct*)outapp->pBuffer;
|
||||
|
||||
bws->Beginning.Action = BazaarWelcome;
|
||||
bws->Beginning.Action = BazaarWelcome;
|
||||
|
||||
bws->Traders = atoi(row[0]);
|
||||
bws->Items = atoi(row[1]);
|
||||
bws->Traders = atoi(row[0]);
|
||||
bws->Items = atoi(row[1]);
|
||||
|
||||
QueuePacket(outapp);
|
||||
QueuePacket(outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
}
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
const std::string buyerCountQuery = "SELECT COUNT(DISTINCT charid) FROM buyer";
|
||||
results = database.QueryDatabase(query);
|
||||
const std::string buyerCountQuery = "SELECT COUNT(DISTINCT charid) FROM buyer";
|
||||
results = database.QueryDatabase(buyerCountQuery);
|
||||
if (!results.Success() || results.RowCount() != 1)
|
||||
return;
|
||||
return;
|
||||
|
||||
auto row = results.begin();
|
||||
Message(10, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them, "
|
||||
auto row = results.begin();
|
||||
Message(10, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them, "
|
||||
"or use /buyer to set up your own Buy Lines.", atoi(row[0]));
|
||||
}
|
||||
|
||||
|
||||
@@ -376,6 +376,13 @@ public:
|
||||
/* NPCs */
|
||||
const NPCType* GetNPCType(uint32 id);
|
||||
uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete
|
||||
uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra);
|
||||
uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime);
|
||||
uint32 DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn);
|
||||
uint32 DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn);
|
||||
uint32 AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID);
|
||||
uint32 AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID);
|
||||
uint32 UpdateNPCTypeAppearance(Client *client, NPC* spawn);
|
||||
bool SetSpecialAttkFlag(uint8 id, const char* flag);
|
||||
bool GetPetEntry(const char *pet_type, PetRecord *into);
|
||||
bool GetPoweredPetEntry(const char *pet_type, int16 petpower, PetRecord *into);
|
||||
|
||||
Reference in New Issue
Block a user