mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Add client->SendToGuildHall - have instances properly cycle out IDs
This commit is contained in:
parent
1728923bbb
commit
88ff56b2f2
@ -159,7 +159,7 @@ public:
|
||||
uint16 GetInstanceID(const char* zone, uint32 charid, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
uint16 GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool is_perma = false);
|
||||
uint32 VersionFromInstanceID(uint16 instance_id);
|
||||
uint32 ZoneIDFromInstanceID(uint16 instance_id);
|
||||
|
||||
@ -196,19 +196,19 @@ public:
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 acctid);
|
||||
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
|
||||
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
|
||||
@ -97,42 +97,53 @@ bool Database::CheckInstanceExists(uint16 instance_id) {
|
||||
bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||
{
|
||||
|
||||
int32 start_time = 0;
|
||||
int32 duration = 0;
|
||||
int32 start_time = 0;
|
||||
int32 duration = 0;
|
||||
uint32 never_expires = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||
std::string query = StringFormat(
|
||||
"SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u",
|
||||
instance_id
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
if (!results.Success()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
if (results.RowCount() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
never_expires = atoi(row[2]);
|
||||
|
||||
if (never_expires == 1)
|
||||
if (never_expires == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
timeval tv;
|
||||
timeval tv{};
|
||||
gettimeofday(&tv, nullptr);
|
||||
|
||||
if ((start_time + duration) <= tv.tv_sec)
|
||||
return true;
|
||||
return (start_time + duration) <= tv.tv_sec;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||
{
|
||||
std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||
" values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)",
|
||||
(unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration);
|
||||
std::string query = StringFormat(
|
||||
"INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||
" values (%u, %u, %u, UNIX_TIMESTAMP(), %u)",
|
||||
instance_id,
|
||||
zone_id,
|
||||
version,
|
||||
duration
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
@ -140,66 +151,79 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
||||
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 count = RuleI(Zone, ReservedInstances);
|
||||
uint32 max = 65535;
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max = 32000;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u",
|
||||
max_reserved_instance_id,
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
query = (
|
||||
SQL(
|
||||
SELECT i.id + 1 AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||
WHERE i2.id IS NULL
|
||||
ORDER BY i.id
|
||||
LIMIT 0, 1;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (atoi(row[0]) <= max)
|
||||
{
|
||||
if (atoi(row[0]) <= max) {
|
||||
instance_id = atoi(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", max_reserved_instance_id);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
if (count < atoi(row[0]))
|
||||
{
|
||||
instance_id = count;
|
||||
max_reserved_instance_id++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
if (max_reserved_instance_id < atoi(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count > max)
|
||||
{
|
||||
if (max_reserved_instance_id > max) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
max_reserved_instance_id++;
|
||||
}
|
||||
|
||||
instance_id = count;
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -357,7 +381,7 @@ uint16 Database::GetInstanceVersion(uint16 instance_id) {
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
||||
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool is_perma)
|
||||
{
|
||||
uint32 start_time = 0;
|
||||
uint32 duration = 0;
|
||||
@ -548,17 +572,36 @@ void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &ch
|
||||
|
||||
void Database::PurgeExpiredInstances()
|
||||
{
|
||||
std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0");
|
||||
|
||||
/**
|
||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
||||
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
||||
* has not been fully de-allocated
|
||||
*/
|
||||
std::string query =
|
||||
SQL(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
instance_list
|
||||
where
|
||||
(start_time + duration) <= (UNIX_TIMESTAMP() + 86400)
|
||||
and never_expires = 0
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
if (results.RowCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
DeleteInstance(atoi(row[0]));
|
||||
}
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
@ -566,4 +609,4 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
|
||||
"duration=%u WHERE id=%u", new_duration, instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +270,6 @@ RULE_INT(Zone, PEQZoneDebuff1, 4454, "First debuff casted by #peqzone Default is
|
||||
RULE_INT(Zone, PEQZoneDebuff2, 2209, "Second debuff casted by #peqzone Default is Tendrils of Apathy")
|
||||
RULE_BOOL(Zone, UsePEQZoneDebuffs, true, "Will determine if #peqzone will debuff players or not when used")
|
||||
RULE_REAL(Zone, HotZoneBonus, 0.75, "")
|
||||
RULE_INT(Zone, ReservedInstances, 30, "Will reserve this many instance ids for globals... probably not a good idea to change this while a server is running")
|
||||
RULE_INT(Zone, EbonCrystalItemID, 40902, "")
|
||||
RULE_INT(Zone, RadiantCrystalItemID, 40903, "")
|
||||
RULE_BOOL(Zone, LevelBasedEXPMods, false, "Allows you to use the level_exp_mods table in consideration to your players EXP hits")
|
||||
@ -775,6 +774,12 @@ RULE_BOOL(HotReload, QuestsRepopWhenPlayersNotInCombat, true, "When a hot reload
|
||||
RULE_BOOL(HotReload, QuestsResetTimersWithReload, true, "When a hot reload is triggered, quest timers will be reset")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Instances)
|
||||
RULE_INT(Instances, ReservedInstances, 30, "Will reserve this many instance ids for globals... probably not a good idea to change this while a server is running")
|
||||
RULE_BOOL(Instances, RecycleInstanceIds, true, "Will recycle free instance ids instead of gradually running out at 32k")
|
||||
RULE_INT(Instances, GuildHallExpirationDays, 90, "Amount of days before a Guild Hall instance expires")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
#undef RULE_CATEGORY
|
||||
#undef RULE_INT
|
||||
#undef RULE_REAL
|
||||
|
||||
@ -129,13 +129,17 @@ void Timer::SetTimer(uint32 set_timer_time) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Timer::GetRemainingTime() const {
|
||||
uint32 Timer::GetRemainingTime() const
|
||||
{
|
||||
if (enabled) {
|
||||
if (current_time - start_time > timer_time)
|
||||
if (current_time - start_time > timer_time) {
|
||||
return 0;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return (start_time + timer_time) - current_time;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1918,7 +1918,7 @@ void Client::CheckManaEndUpdate() {
|
||||
else if (group) {
|
||||
group->SendEndurancePacketFrom(this);
|
||||
}
|
||||
|
||||
|
||||
auto endurance_packet = new EQApplicationPacket(OP_EnduranceUpdate, sizeof(EnduranceUpdate_Struct));
|
||||
EnduranceUpdate_Struct* endurance_update = (EnduranceUpdate_Struct*)endurance_packet->pBuffer;
|
||||
endurance_update->cur_end = GetEndurance();
|
||||
@ -8756,7 +8756,7 @@ void Client::CheckRegionTypeChanges()
|
||||
// still same region, do nothing
|
||||
if (last_region_type == new_region)
|
||||
return;
|
||||
|
||||
|
||||
// If we got out of water clear any water aggro for water only npcs
|
||||
if (last_region_type == RegionTypeWater) {
|
||||
entity_list.ClearWaterAggro(this);
|
||||
@ -9203,7 +9203,7 @@ void Client::SetSecondaryWeaponOrnamentation(uint32 model_id)
|
||||
secondary_item->SetOrnamentationIDFile(model_id);
|
||||
SendItemPacket(EQEmu::invslot::slotSecondary, secondary_item, ItemPacketTrade);
|
||||
WearChange(EQEmu::textures::weaponSecondary, static_cast<uint16>(model_id), 0);
|
||||
|
||||
|
||||
Message(Chat::Yellow, "Your secondary weapon appearance has been modified");
|
||||
}
|
||||
}
|
||||
@ -9292,3 +9292,41 @@ void Client::SetBotOption(BotOwnerOption boo, bool flag) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Client::SendToGuildHall()
|
||||
{
|
||||
std::string zone_short_name = "guildhall";
|
||||
uint32 zone_id = database.GetZoneID(zone_short_name.c_str());
|
||||
if (zone_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 expiration_time = (RuleI(Instances, GuildHallExpirationDays) * 86400);
|
||||
uint16 instance_id = 0;
|
||||
std::string guild_hall_instance_key = fmt::format("guild-hall-instance-{}", GuildID());
|
||||
std::string instance_data = DataBucket::GetData(guild_hall_instance_key);
|
||||
if (!instance_data.empty() && std::stoi(instance_data) > 0) {
|
||||
instance_id = std::stoi(instance_data);
|
||||
}
|
||||
|
||||
if (instance_id <= 0) {
|
||||
if (!database.GetUnusedInstanceID(instance_id)) {
|
||||
Message(Chat::Red, "Server was unable to find a free instance id.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!database.CreateInstance(instance_id, zone_id, 0, expiration_time)) {
|
||||
Message(Chat::Red, "Server was unable to create a new instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
DataBucket::SetData(
|
||||
guild_hall_instance_key,
|
||||
std::to_string(instance_id),
|
||||
std::to_string(expiration_time)
|
||||
);
|
||||
}
|
||||
|
||||
AssignToInstance(instance_id);
|
||||
MovePC(345, instance_id, -1.00, -1.00, 3.34, 0, 1);
|
||||
}
|
||||
|
||||
@ -633,6 +633,7 @@ public:
|
||||
void MovePC(uint32 zoneID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
void MovePC(float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
void SendToGuildHall();
|
||||
void AssignToInstance(uint16 instance_id);
|
||||
void RemoveFromInstance(uint16 instance_id);
|
||||
void WhoAll();
|
||||
@ -691,7 +692,7 @@ public:
|
||||
|
||||
int GetClientMaxLevel() const { return client_max_level; }
|
||||
void SetClientMaxLevel(int max_level) { client_max_level = max_level; }
|
||||
|
||||
|
||||
void CheckManaEndUpdate();
|
||||
void SendManaUpdate();
|
||||
void SendEnduranceUpdate();
|
||||
@ -1293,7 +1294,7 @@ public:
|
||||
void SendHPUpdateMarquee();
|
||||
|
||||
void CheckRegionTypeChanges();
|
||||
|
||||
|
||||
WaterRegionType GetLastRegion() { return last_region_type; }
|
||||
|
||||
int32 CalcATK();
|
||||
@ -1635,9 +1636,9 @@ private:
|
||||
bool InterrogateInventory_error(int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, int depth);
|
||||
|
||||
int client_max_level;
|
||||
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
|
||||
public:
|
||||
enum BotOwnerOption : size_t {
|
||||
booDeathMarquee,
|
||||
@ -1654,7 +1655,7 @@ public:
|
||||
|
||||
bool GetBotOption(BotOwnerOption boo) const;
|
||||
void SetBotOption(BotOwnerOption boo, bool flag = true);
|
||||
|
||||
|
||||
bool GetBotPulling() { return m_bot_pulling; }
|
||||
void SetBotPulling(bool flag = true) { m_bot_pulling = flag; }
|
||||
|
||||
|
||||
@ -599,7 +599,7 @@ void Client::CompleteConnect()
|
||||
if (group)
|
||||
group->SendHPManaEndPacketsTo(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//bulk raid send in here eventually
|
||||
|
||||
@ -818,35 +818,46 @@ void Client::CompleteConnect()
|
||||
database.QueryDatabase(
|
||||
StringFormat(
|
||||
"UPDATE `character_data` SET `last_login` = UNIX_TIMESTAMP() WHERE id = %u",
|
||||
this->CharacterID()
|
||||
CharacterID()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (zone) {
|
||||
if (zone->GetInstanceTimer()) {
|
||||
uint32 ttime = zone->GetInstanceTimer()->GetRemainingTime();
|
||||
uint32 day = (ttime / 86400000);
|
||||
uint32 hour = (ttime / 3600000) % 24;
|
||||
uint32 minute = (ttime / 60000) % 60;
|
||||
uint32 second = (ttime / 1000) % 60;
|
||||
if (day) {
|
||||
Message(Chat::Yellow, "%s(%u) will expire in %u days, %u hours, %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), day, hour, minute, second);
|
||||
}
|
||||
else if (hour) {
|
||||
Message(Chat::Yellow, "%s(%u) will expire in %u hours, %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), hour, minute, second);
|
||||
}
|
||||
else if (minute) {
|
||||
Message(Chat::Yellow, "%s(%u) will expire in %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), minute, second);
|
||||
}
|
||||
else {
|
||||
Message(Chat::Yellow, "%s(%u) will expire in in %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), second);
|
||||
}
|
||||
if (zone && zone->GetInstanceID() > 0) {
|
||||
|
||||
uint32 remaining_time_seconds = zone->GetInstanceTimeRemaining();
|
||||
uint32 day = (remaining_time_seconds / 86400);
|
||||
uint32 hour = (remaining_time_seconds / 3600) % 24;
|
||||
uint32 minute = (remaining_time_seconds / 60) % 60;
|
||||
uint32 second = (remaining_time_seconds / 1) % 60;
|
||||
|
||||
LogInfo("Remaining time seconds [{}]", remaining_time_seconds);
|
||||
|
||||
if (day) {
|
||||
Message(
|
||||
Chat::Yellow, "%s (%u) will expire in %u days, %u hours, %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), day, hour, minute, second
|
||||
);
|
||||
}
|
||||
else if (hour) {
|
||||
Message(
|
||||
Chat::Yellow, "%s (%u) will expire in %u hours, %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), hour, minute, second
|
||||
);
|
||||
}
|
||||
else if (minute) {
|
||||
Message(
|
||||
Chat::Yellow, "%s (%u) will expire in %u minutes, and %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), minute, second
|
||||
);
|
||||
}
|
||||
else {
|
||||
Message(
|
||||
Chat::Yellow, "%s (%u) will expire in in %u seconds.",
|
||||
zone->GetLongName(), zone->GetInstanceID(), second
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SendRewards();
|
||||
@ -1237,7 +1248,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */
|
||||
// set to full support in case they're a gm with items in disabled expansion slots..but, have their gm flag off...
|
||||
// item loss will occur when they use the 'empty' slots, if this is not done
|
||||
m_inv.SetGMInventory(true);
|
||||
m_inv.SetGMInventory(true);
|
||||
loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */
|
||||
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
||||
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
||||
@ -1341,7 +1352,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
client_max_level = GetCharMaxLevelFromBucket();
|
||||
}
|
||||
SetClientMaxLevel(client_max_level);
|
||||
|
||||
|
||||
// we know our class now, so we might have to fix our consume timer!
|
||||
if (class_ == MONK)
|
||||
consume_food_timer.SetTimer(CONSUMPTION_MNK_TIMER);
|
||||
@ -2840,7 +2851,7 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app)
|
||||
// rogue simply won't apply at all, no skill check done.
|
||||
|
||||
uint16 poison_skill = GetSkill(EQEmu::skills::SkillApplyPoison);
|
||||
|
||||
|
||||
if (ChanceRoll < (.75 + poison_skill / 1000)) {
|
||||
ApplyPoisonSuccessResult = 1;
|
||||
AddProcToWeapon(poison->Proc.Effect, false, (GetDEX() / 100) + 103, POISON_PROC);
|
||||
@ -3917,7 +3928,7 @@ void Client::Handle_OP_Bug(const EQApplicationPacket *app)
|
||||
Message(0, "Bug reporting is disabled on this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (app->size != sizeof(BugReport_Struct)) {
|
||||
printf("Wrong size of BugReport_Struct got %d expected %zu!\n", app->size, sizeof(BugReport_Struct));
|
||||
}
|
||||
@ -4017,7 +4028,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
||||
//Message(Chat::Red, "You cant cast right now, you arent in control of yourself!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Hack for broken RoF2 which allows casting after a zoned IVU/IVA
|
||||
if (invisible_undead || invisible_animals) {
|
||||
BuffFadeByEffect(SE_InvisVsAnimals);
|
||||
@ -4370,9 +4381,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
sizeof(PlayerPositionUpdateClient_Struct), app->size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PlayerPositionUpdateClient_Struct *ppu = (PlayerPositionUpdateClient_Struct *) app->pBuffer;
|
||||
|
||||
|
||||
/* Boat handling */
|
||||
if (ppu->spawn_id != GetID()) {
|
||||
/* If player is controlling boat */
|
||||
@ -4382,16 +4393,16 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
controlling_boat_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
|
||||
boat->SetDelta(boat_delta);
|
||||
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct *ppus = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer;
|
||||
boat->MakeSpawnUpdate(ppus);
|
||||
entity_list.QueueCloseClients(boat, outapp, true, 300, this, false);
|
||||
safe_delete(outapp);
|
||||
|
||||
|
||||
/* Update the boat's position on the server, without sending an update */
|
||||
boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false);
|
||||
return;
|
||||
@ -4406,9 +4417,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
if (cmob != nullptr) {
|
||||
cmob->SetPosition(ppu->x_pos, ppu->y_pos, ppu->z_pos);
|
||||
cmob->SetHeading(EQ12toFloat(ppu->heading));
|
||||
mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0,
|
||||
mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0,
|
||||
0.0, 0, ClientRangeAny, nullptr, this);
|
||||
cmob->CastToNPC()->SaveGuardSpot(glm::vec4(ppu->x_pos,
|
||||
cmob->CastToNPC()->SaveGuardSpot(glm::vec4(ppu->x_pos,
|
||||
ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading)));
|
||||
}
|
||||
}
|
||||
@ -4426,7 +4437,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
// From this point forward, we need to use a new set of variables for client
|
||||
// position. If the client is in a boat, we need to add the boat pos and
|
||||
// the client offset together.
|
||||
|
||||
|
||||
float cx = ppu->x_pos;
|
||||
float cy = ppu->y_pos;
|
||||
float cz = ppu->z_pos;
|
||||
@ -4451,45 +4462,45 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
/* Check to see if PPU should trigger an update to the rewind position. */
|
||||
float rewind_x_diff = 0;
|
||||
float rewind_y_diff = 0;
|
||||
|
||||
|
||||
rewind_x_diff = cx - m_RewindLocation.x;
|
||||
rewind_x_diff *= rewind_x_diff;
|
||||
rewind_y_diff = cy - m_RewindLocation.y;
|
||||
rewind_y_diff *= rewind_y_diff;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
We only need to store updated values if the player has moved.
|
||||
If the player has moved more than units for x or y, then we'll store
|
||||
his pre-PPU x and y for /rewind, in case he gets stuck.
|
||||
*/
|
||||
|
||||
|
||||
if ((rewind_x_diff > 750) || (rewind_y_diff > 750))
|
||||
m_RewindLocation = glm::vec3(m_Position);
|
||||
|
||||
|
||||
/*
|
||||
If the PPU was a large jump, such as a cross zone gate or Call of Hero,
|
||||
just update rewind coordinates to the new ppu coordinates. This will prevent exploitation.
|
||||
*/
|
||||
|
||||
|
||||
if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000))
|
||||
m_RewindLocation = glm::vec3(cx, cy, cz);
|
||||
|
||||
|
||||
if (proximity_timer.Check()) {
|
||||
entity_list.ProcessMove(this, glm::vec3(cx, cy, cz));
|
||||
if (RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem, EnableTaskProximity))
|
||||
ProcessTaskProximities(cx, cy, cz);
|
||||
|
||||
|
||||
m_Proximity = glm::vec3(cx, cy, cz);
|
||||
}
|
||||
|
||||
|
||||
/* Update internal state */
|
||||
m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
|
||||
|
||||
|
||||
if (IsTracking() && ((m_Position.x != cx) || (m_Position.y != cy))) {
|
||||
if (zone->random.Real(0, 100) < 70)//should be good
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillTracking, nullptr, -20);
|
||||
}
|
||||
|
||||
|
||||
/* Break Hide if moving without sneaking and set rewind timer if moved */
|
||||
if (cy != m_Position.y || cx != m_Position.x) {
|
||||
if ((hidden || improved_hidden) && !sneaking) {
|
||||
@ -4508,7 +4519,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
}
|
||||
rewind_timer.Start(30000, true);
|
||||
}
|
||||
|
||||
|
||||
/* Handle client aggro scanning timers NPCs */
|
||||
is_client_moving = (cy == m_Position.y && cx == m_Position.x) ? false : true;
|
||||
|
||||
@ -4572,55 +4583,55 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
int32 new_animation = ppu->animation;
|
||||
|
||||
|
||||
/* Update internal server position from what the client has sent */
|
||||
m_Position.x = cx;
|
||||
m_Position.y = cy;
|
||||
m_Position.z = cz;
|
||||
|
||||
|
||||
/* Visual Debugging */
|
||||
if (RuleB(Character, OPClientUpdateVisualDebug)) {
|
||||
LogDebug("ClientUpdate: ppu x: [{}] y: [{}] z: [{}] h: [{}]", cx, cy, cz, new_heading);
|
||||
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
||||
this->SendAppearanceEffect(41, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Only feed real time updates when client is moving */
|
||||
if (is_client_moving || new_heading != m_Position.w || new_animation != animation) {
|
||||
|
||||
|
||||
animation = ppu->animation;
|
||||
m_Position.w = new_heading;
|
||||
|
||||
|
||||
/* Broadcast update to other clients */
|
||||
auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer;
|
||||
|
||||
|
||||
MakeSpawnUpdate(position_update);
|
||||
|
||||
|
||||
if (gm_hide_me) {
|
||||
entity_list.QueueClientsStatus(this, outapp, true, Admin(), 255);
|
||||
} else {
|
||||
entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Always send position updates to group - send when beyond normal ClientPositionUpdate range */
|
||||
Group *group = this->GetGroup();
|
||||
Raid *raid = this->GetRaid();
|
||||
|
||||
|
||||
if (raid) {
|
||||
raid->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1));
|
||||
} else if (group) {
|
||||
group->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1));
|
||||
}
|
||||
|
||||
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
|
||||
if (zone->watermap) {
|
||||
if (zone->watermap->InLiquid(glm::vec3(m_Position))) {
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17);
|
||||
|
||||
|
||||
// Dismount horses when entering water
|
||||
if (GetHorseId() && RuleB(Character, DismountWater)) {
|
||||
SetHorseId(0);
|
||||
@ -5757,23 +5768,23 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
printf("Error in FindPersonRequest_Struct. Expected size of: %zu, but got: %i\n", sizeof(FindPersonRequest_Struct), app->size);
|
||||
else {
|
||||
FindPersonRequest_Struct* t = (FindPersonRequest_Struct*)app->pBuffer;
|
||||
|
||||
|
||||
std::vector<FindPerson_Point> points;
|
||||
Mob* target = entity_list.GetMob(t->npc_id);
|
||||
|
||||
|
||||
if (target == nullptr) {
|
||||
//empty length packet == not found.
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!RuleB(Pathing, Find) && RuleB(Bazaar, EnableWarpToTrader) && target->IsClient() && (target->CastToClient()->Trader ||
|
||||
target->CastToClient()->Buyer)) {
|
||||
Message(Chat::Yellow, "Moving you to Trader %s", target->GetName());
|
||||
MovePC(zone->GetZoneID(), zone->GetInstanceID(), target->GetX(), target->GetY(), target->GetZ(), 0.0f);
|
||||
}
|
||||
|
||||
|
||||
if (!RuleB(Pathing, Find) || !zone->pathing)
|
||||
{
|
||||
//fill in the path array...
|
||||
@ -5796,40 +5807,40 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
glm::vec3 Start(GetX(), GetY(), GetZ() + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
|
||||
glm::vec3 End(target->GetX(), target->GetY(), target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION);
|
||||
|
||||
|
||||
bool partial = false;
|
||||
bool stuck = false;
|
||||
auto pathlist = zone->pathing->FindRoute(Start, End, partial, stuck);
|
||||
|
||||
|
||||
if (pathlist.empty() || partial)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Live appears to send the points in this order:
|
||||
// Final destination.
|
||||
// Current Position.
|
||||
// rest of the points.
|
||||
FindPerson_Point p;
|
||||
|
||||
|
||||
int PointNumber = 0;
|
||||
|
||||
|
||||
bool LeadsToTeleporter = false;
|
||||
|
||||
|
||||
auto v = pathlist.back();
|
||||
|
||||
|
||||
p.x = v.pos.x;
|
||||
p.y = v.pos.y;
|
||||
p.z = v.pos.z;
|
||||
points.push_back(p);
|
||||
|
||||
|
||||
p.x = GetX();
|
||||
p.y = GetY();
|
||||
p.z = GetZ();
|
||||
points.push_back(p);
|
||||
|
||||
|
||||
for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
|
||||
{
|
||||
if ((*Iterator).teleport) // Teleporter
|
||||
@ -5837,7 +5848,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
LeadsToTeleporter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 v = (*Iterator).pos;
|
||||
p.x = v.x;
|
||||
p.y = v.y;
|
||||
@ -5845,17 +5856,17 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
points.push_back(p);
|
||||
++PointNumber;
|
||||
}
|
||||
|
||||
|
||||
if (!LeadsToTeleporter)
|
||||
{
|
||||
p.x = target->GetX();
|
||||
p.y = target->GetY();
|
||||
p.z = target->GetZ();
|
||||
|
||||
|
||||
points.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SendPathPacket(points);
|
||||
}
|
||||
}
|
||||
@ -11098,14 +11109,14 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
{
|
||||
case RaidCommandInviteIntoExisting:
|
||||
case RaidCommandInvite: {
|
||||
|
||||
|
||||
Client *player_to_invite = entity_list.GetClientByName(raid_command_packet->player_name);
|
||||
|
||||
if (!player_to_invite)
|
||||
break;
|
||||
|
||||
Group *player_to_invite_group = player_to_invite->GetGroup();
|
||||
|
||||
|
||||
if (player_to_invite->HasRaid()) {
|
||||
Message(Chat::Red, "%s is already in a raid.", player_to_invite->GetName());
|
||||
break;
|
||||
@ -11120,7 +11131,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
Message(Chat::Red, "You can only invite an ungrouped player or group leader to join your raid.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Send out invite to the client */
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
|
||||
RaidGeneral_Struct *raid_command = (RaidGeneral_Struct*)outapp->pBuffer;
|
||||
@ -11132,7 +11143,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
raid_command->action = 20;
|
||||
|
||||
player_to_invite->QueuePacket(outapp);
|
||||
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
break;
|
||||
@ -11228,7 +11239,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
}
|
||||
if (player_invited_group->IsLeader(player_invited_group->members[x])) {
|
||||
Client *c = nullptr;
|
||||
|
||||
|
||||
if (player_invited_group->members[x]->IsClient())
|
||||
c = player_invited_group->members[x]->CastToClient();
|
||||
else
|
||||
@ -11238,24 +11249,24 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, true, true, true);
|
||||
raid->SendBulkRaid(c);
|
||||
|
||||
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Client *c = nullptr;
|
||||
|
||||
|
||||
if (player_invited_group->members[x]->IsClient())
|
||||
c = player_invited_group->members[x]->CastToClient();
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id);
|
||||
raid->SendBulkRaid(c);
|
||||
|
||||
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
@ -11289,12 +11300,12 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
c = group->members[x]->CastToClient();
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id, false, true);
|
||||
raid->SendBulkRaid(c);
|
||||
|
||||
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
@ -11302,17 +11313,17 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
else
|
||||
{
|
||||
Client *c = nullptr;
|
||||
|
||||
|
||||
if (group->members[x]->IsClient())
|
||||
c = group->members[x]->CastToClient();
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
raid->SendRaidCreate(c);
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, raid_free_group_id);
|
||||
raid->SendBulkRaid(c);
|
||||
|
||||
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
@ -11329,7 +11340,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
if (player_invited_group) {
|
||||
|
||||
raid = new Raid(player_accepting_invite);
|
||||
|
||||
|
||||
entity_list.AddRaid(raid);
|
||||
raid->SetRaidDetails();
|
||||
Client *addClientig = nullptr;
|
||||
@ -11353,7 +11364,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
raid->SendMakeLeaderPacketTo(raid->leadername, c);
|
||||
raid->AddMember(c, 0, true, true, true);
|
||||
raid->SendBulkRaid(c);
|
||||
|
||||
|
||||
if (raid->IsLocked()) {
|
||||
raid->SendRaidLockTo(c);
|
||||
}
|
||||
@ -11478,7 +11489,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
raid->SetGroupLeader(raid_command_packet->leader_name, false);
|
||||
|
||||
/* We were the leader of our old group */
|
||||
if (old_group < 12) {
|
||||
if (old_group < 12) {
|
||||
/* Assign new group leader if we can */
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if (raid->members[x].GroupNumber == old_group) {
|
||||
@ -11507,7 +11518,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
strn0cpy(raid_command_packet->playername, raid->members[x].membername, 64);
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
|
||||
|
||||
safe_delete(pack);
|
||||
}
|
||||
break;
|
||||
@ -11553,7 +11564,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
raid->SetGroupLeader(raid_command_packet->leader_name, false);
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if (raid->members[x].GroupNumber == oldgrp && strlen(raid->members[x].membername) > 0 && strcmp(raid->members[x].membername, raid_command_packet->leader_name) != 0){
|
||||
|
||||
|
||||
raid->SetGroupLeader(raid->members[x].membername);
|
||||
raid->UpdateGroupAAs(oldgrp);
|
||||
|
||||
@ -11576,7 +11587,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
strn0cpy(raid_command->playername, raid->members[x].membername, 64);
|
||||
raid_command->zoneid = zone->GetZoneID();
|
||||
raid_command->instance_id = zone->GetInstanceID();
|
||||
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
@ -11591,14 +11602,14 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
else {
|
||||
auto pack = new ServerPacket(ServerOP_RaidGroupDisband, sizeof(ServerRaidGeneralAction_Struct));
|
||||
ServerRaidGeneralAction_Struct* raid_command = (ServerRaidGeneralAction_Struct*)pack->pBuffer;
|
||||
|
||||
|
||||
raid_command->rid = raid->GetID();
|
||||
raid_command->zoneid = zone->GetZoneID();
|
||||
raid_command->instance_id = zone->GetInstanceID();
|
||||
strn0cpy(raid_command->playername, raid_command_packet->leader_name, 64);
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
|
||||
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,11 @@ void Lua_Client::SetPVP(bool v) {
|
||||
self->SetPVP(v);
|
||||
}
|
||||
|
||||
void Lua_Client::SendToGuildHall() {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendToGuildHall();
|
||||
}
|
||||
|
||||
bool Lua_Client::GetPVP() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->GetPVP();
|
||||
@ -1584,6 +1589,7 @@ luabind::scope lua_register_client() {
|
||||
.def("Disconnect", (void(Lua_Client::*)(void))&Lua_Client::Disconnect)
|
||||
.def("IsLD", (bool(Lua_Client::*)(void))&Lua_Client::IsLD)
|
||||
.def("WorldKick", (void(Lua_Client::*)(void))&Lua_Client::WorldKick)
|
||||
.def("SendToGuildHall", (void(Lua_Client::*)(void))&Lua_Client::SendToGuildHall)
|
||||
.def("GetAnon", (bool(Lua_Client::*)(void))&Lua_Client::GetAnon)
|
||||
.def("Duck", (void(Lua_Client::*)(void))&Lua_Client::Duck)
|
||||
.def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand)
|
||||
|
||||
@ -39,6 +39,7 @@ public:
|
||||
void Disconnect();
|
||||
bool IsLD();
|
||||
void WorldKick();
|
||||
void SendToGuildHall();
|
||||
bool GetAnon();
|
||||
void Duck();
|
||||
void Stand();
|
||||
|
||||
@ -245,6 +245,27 @@ XS(XS_Client_WorldKick) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_SendToGuildHall); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_SendToGuildHall) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::SendToGuildHall(THIS)");
|
||||
{
|
||||
Client *THIS;
|
||||
|
||||
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 == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->SendToGuildHall();
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GetAnon); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GetAnon) {
|
||||
dXSARGS;
|
||||
@ -2439,7 +2460,7 @@ XS(XS_Client_MemmedCount) {
|
||||
|
||||
RETVAL = THIS->MemmedCount();
|
||||
XSprePUSH;
|
||||
PUSHu((UV) RETVAL);
|
||||
PUSHu((UV) RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
@ -4786,7 +4807,7 @@ XS(XS_Client_AddLevelBasedExp) {
|
||||
|
||||
if (items > 2)
|
||||
max_level = (uint8) SvUV(ST(2));
|
||||
|
||||
|
||||
if (items > 3)
|
||||
ignore_mods = (bool) SvTRUE(ST(3));
|
||||
|
||||
@ -6564,6 +6585,7 @@ XS(boot_Client) {
|
||||
newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$");
|
||||
newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$");
|
||||
newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$");
|
||||
newXSproto(strcpy(buf, "SendToGuildHall"), XS_Client_SendToGuildHall, file, "$");
|
||||
newXSproto(strcpy(buf, "SendWebLink"), XS_Client_SendWebLink, file, "$:$");
|
||||
newXSproto(strcpy(buf, "SendZoneFlagInfo"), XS_Client_SendZoneFlagInfo, file, "$$");
|
||||
newXSproto(strcpy(buf, "SetAAPoints"), XS_Client_SetAAPoints, file, "$$");
|
||||
|
||||
@ -140,7 +140,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
if(iInstanceID != 0)
|
||||
{
|
||||
auto pack = new ServerPacket(ServerOP_AdventureZoneData, sizeof(uint16));
|
||||
*((uint16*)pack->pBuffer) = iInstanceID;
|
||||
*((uint16*)pack->pBuffer) = iInstanceID;
|
||||
worldserver.SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
@ -491,7 +491,7 @@ void Zone::LoadNewMerchantData(uint32 merchantid) {
|
||||
|
||||
void Zone::GetMerchantDataForZoneLoad() {
|
||||
LogInfo("Loading Merchant Lists");
|
||||
std::string query = StringFormat(
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"DISTINCT ml.merchantid, "
|
||||
"ml.slot, "
|
||||
@ -816,7 +816,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
{
|
||||
LogDebug("Graveyard ID is [{}]", graveyard_id());
|
||||
bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.x, &m_Graveyard.y, &m_Graveyard.z, &m_Graveyard.w);
|
||||
|
||||
|
||||
if (GraveYardLoaded) {
|
||||
LogDebug("Loaded a graveyard for zone [{}]: graveyard zoneid is [{}] at [{}]", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str());
|
||||
}
|
||||
@ -907,7 +907,7 @@ Zone::~Zone() {
|
||||
//Modified for timezones.
|
||||
bool Zone::Init(bool iStaticZone) {
|
||||
SetStaticZone(iStaticZone);
|
||||
|
||||
|
||||
//load the zone config file.
|
||||
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion())) // try loading the zone name...
|
||||
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
|
||||
@ -1018,6 +1018,10 @@ bool Zone::Init(bool iStaticZone) {
|
||||
petition_list.ClearPetitions();
|
||||
petition_list.ReadDatabase();
|
||||
|
||||
if (zone->GetInstanceID() > 0) {
|
||||
zone->SetInstanceTimeRemaining(database.GetTimeRemainingInstance(zone->GetInstanceID()));
|
||||
}
|
||||
|
||||
LogInfo("Loading timezone data");
|
||||
zone->zone_time.setEQTimeZone(database.GetZoneTZ(zoneid, GetInstanceVersion()));
|
||||
|
||||
@ -1089,7 +1093,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id)
|
||||
if (instance_id != 0)
|
||||
{
|
||||
safe_delete_array(map_name);
|
||||
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate,
|
||||
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate,
|
||||
can_castoutdoor, is_city, is_hotzone, allow_mercs, max_movement_update_range, zone_type, default_ruleset, &map_name))
|
||||
{
|
||||
LogError("Error loading the Zone Config");
|
||||
@ -2455,3 +2459,13 @@ void Zone::SetQuestHotReloadQueued(bool in_quest_hot_reload_queued)
|
||||
{
|
||||
quest_hot_reload_queued = in_quest_hot_reload_queued;
|
||||
}
|
||||
|
||||
uint32 Zone::GetInstanceTimeRemaining() const
|
||||
{
|
||||
return instance_time_remaining;
|
||||
}
|
||||
|
||||
void Zone::SetInstanceTimeRemaining(uint32 instance_time_remaining)
|
||||
{
|
||||
Zone::instance_time_remaining = instance_time_remaining;
|
||||
}
|
||||
|
||||
@ -278,6 +278,9 @@ public:
|
||||
ZonePoint *GetClosestZonePoint(const glm::vec3 &location, uint32 to, Client *client, float max_distance = 40000.0f);
|
||||
ZonePoint *GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
|
||||
|
||||
uint32 GetInstanceTimeRemaining() const;
|
||||
void SetInstanceTimeRemaining(uint32 instance_time_remaining);
|
||||
|
||||
/**
|
||||
* GMSay Callback for LogSys
|
||||
*
|
||||
@ -361,6 +364,7 @@ private:
|
||||
uint8 zone_type;
|
||||
uint16 instanceversion;
|
||||
uint32 instanceid;
|
||||
uint32 instance_time_remaining;
|
||||
uint32 pgraveyard_id, pgraveyard_zoneid;
|
||||
uint32 pMaxClients;
|
||||
uint32 zoneid;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user