mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 20:56:37 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into integration/multi-tenancy-expansions-repository
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include "map.h"
|
||||
#include "water_map.h"
|
||||
|
||||
extern Zone* zone;
|
||||
//#define LOSDEBUG 6
|
||||
@@ -237,6 +238,11 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
if (!mob->CastToClient()->ClientFinishedLoading() || mob->CastToClient()->IsHoveringForRespawn() || mob->CastToClient()->bZoning)
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't want to aggro clients outside of water if we're water only.
|
||||
if (mob->IsClient() && mob->CastToClient()->GetLastRegion() != RegionTypeWater && IsUnderwaterOnly()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pets shouldn't scan for aggro
|
||||
|
||||
+46
-2
@@ -256,6 +256,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
TotalSecondsPlayed = 0;
|
||||
keyring.clear();
|
||||
bind_sight_target = nullptr;
|
||||
p_raid_instance = nullptr;
|
||||
mercid = 0;
|
||||
mercSlot = 0;
|
||||
InitializeMercInfo();
|
||||
@@ -1918,7 +1919,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();
|
||||
@@ -8758,6 +8759,11 @@ void Client::CheckRegionTypeChanges()
|
||||
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);
|
||||
}
|
||||
|
||||
// region type changed
|
||||
last_region_type = new_region;
|
||||
|
||||
@@ -9199,7 +9205,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");
|
||||
}
|
||||
}
|
||||
@@ -9288,3 +9294,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, 1, 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);
|
||||
}
|
||||
|
||||
+10
-4
@@ -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();
|
||||
@@ -1294,6 +1295,8 @@ public:
|
||||
|
||||
void CheckRegionTypeChanges();
|
||||
|
||||
WaterRegionType GetLastRegion() { return last_region_type; }
|
||||
|
||||
int32 CalcATK();
|
||||
|
||||
uint32 trapid; //ID of trap player has triggered. This is cleared when the player leaves the trap's radius, or it despawns.
|
||||
@@ -1301,6 +1304,8 @@ public:
|
||||
void SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update);
|
||||
glm::vec4 &GetLastPositionBeforeBulkUpdate();
|
||||
|
||||
Raid *p_raid_instance;
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
@@ -1340,6 +1345,7 @@ protected:
|
||||
char *adv_data;
|
||||
|
||||
private:
|
||||
|
||||
eqFilterMode ClientFilters[_FilterCount];
|
||||
int32 HandlePacket(const EQApplicationPacket *app);
|
||||
void OPTGB(const EQApplicationPacket *app);
|
||||
@@ -1633,9 +1639,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,
|
||||
@@ -1652,7 +1658,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; }
|
||||
|
||||
|
||||
+35
-25
@@ -819,35 +819,45 @@ 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->GetInstanceTimer()) {
|
||||
|
||||
bool is_permanent = false;
|
||||
uint32 remaining_time_seconds = database.GetTimeRemainingInstance(zone->GetInstanceID(), is_permanent);
|
||||
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;
|
||||
|
||||
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();
|
||||
@@ -4018,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);
|
||||
|
||||
+40
-2
@@ -3314,6 +3314,43 @@ XS(XS__getcharidbyname) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getclassname);
|
||||
XS(XS__getclassname) {
|
||||
dXSARGS;
|
||||
if (items < 1 || items > 2)
|
||||
Perl_croak(aTHX_ "Usage: quest::getclassname(uint8 class_id, [uint8 level = 0])");
|
||||
dXSTARG;
|
||||
|
||||
std::string RETVAL;
|
||||
uint8 class_id = (int) SvUV(ST(0));
|
||||
uint8 level = 0;
|
||||
if (items > 1)
|
||||
level = (int) SvUV(ST(1));
|
||||
|
||||
RETVAL = quest_manager.getclassname(class_id, level);
|
||||
sv_setpv(TARG, RETVAL.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getcurrencyitemid);
|
||||
XS(XS__getcurrencyitemid) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getcurrencyitemid(int currency_id)");
|
||||
dXSTARG;
|
||||
|
||||
int RETVAL;
|
||||
int currency_id = (int) SvUV(ST(0));
|
||||
|
||||
RETVAL = quest_manager.getcurrencyitemid(currency_id);
|
||||
|
||||
XSprePUSH;
|
||||
PUSHi((IV)RETVAL);
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getcurrencyid);
|
||||
XS(XS__getcurrencyid) {
|
||||
dXSARGS;
|
||||
@@ -3322,12 +3359,11 @@ XS(XS__getcurrencyid) {
|
||||
dXSTARG;
|
||||
|
||||
int RETVAL;
|
||||
uint32 item_id = (int) SvUV(ST(0));;
|
||||
uint32 item_id = (int) SvUV(ST(0));
|
||||
|
||||
RETVAL = quest_manager.getcurrencyid(item_id);
|
||||
XSprePUSH;
|
||||
PUSHi((IV)RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
@@ -4821,6 +4857,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
|
||||
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
|
||||
newXS(strcpy(buf, "getcharidbyname"), XS__getcharidbyname, file);
|
||||
newXS(strcpy(buf, "getclassname"), XS__getclassname, file);
|
||||
newXS(strcpy(buf, "getcurrencyid"), XS__getcurrencyid, file);
|
||||
newXS(strcpy(buf, "getinventoryslotid"), XS__getinventoryslotid, file);
|
||||
newXS(strcpy(buf, "getitemname"), XS__getitemname, file);
|
||||
@@ -4828,6 +4865,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "getnpcnamebyid"), XS__getnpcnamebyid, file);
|
||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||
newXS(strcpy(buf, "getcharnamebyid"), XS__getcharnamebyid, file);
|
||||
newXS(strcpy(buf, "getcurrencyitemid"), XS__getcurrencyitemid, file);
|
||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||
newXS(strcpy(buf, "getguildidbycharid"), XS__getguildidbycharid, file);
|
||||
newXS(strcpy(buf, "getgroupidbycharid"), XS__getgroupidbycharid, file);
|
||||
|
||||
+46
-9
@@ -498,7 +498,7 @@ void EntityList::MobProcess()
|
||||
size_t sz = mob_list.size();
|
||||
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
if (numclients > 0 ||
|
||||
if (numclients > 0 ||
|
||||
mob->GetWanderType() == 4 || mob->GetWanderType() == 6) {
|
||||
// Normal processing, or assuring that spawns that should
|
||||
// path and depop do that. Otherwise all of these type mobs
|
||||
@@ -931,12 +931,12 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
|
||||
memcpy(new_door.name, door->GetDoorName(), 32);
|
||||
|
||||
auto position = door->GetPosition();
|
||||
|
||||
|
||||
new_door.xPos = position.x;
|
||||
new_door.yPos = position.y;
|
||||
new_door.zPos = position.z;
|
||||
new_door.heading = position.w;
|
||||
|
||||
|
||||
new_door.incline = door->GetIncline();
|
||||
new_door.size = door->GetSize();
|
||||
new_door.doorId = door->GetDoorID();
|
||||
@@ -1984,17 +1984,26 @@ Raid *EntityList::GetRaidByID(uint32 id)
|
||||
|
||||
Raid *EntityList::GetRaidByClient(Client* client)
|
||||
{
|
||||
std::list<Raid *>::iterator iterator;
|
||||
if (client->p_raid_instance) {
|
||||
return client->p_raid_instance;
|
||||
}
|
||||
|
||||
std::list<Raid *>::iterator iterator;
|
||||
iterator = raid_list.begin();
|
||||
|
||||
while (iterator != raid_list.end()) {
|
||||
for (int x = 0; x < MAX_RAID_MEMBERS; x++)
|
||||
if ((*iterator)->members[x].member)
|
||||
if((*iterator)->members[x].member == client)
|
||||
for (auto &member : (*iterator)->members) {
|
||||
if (member.member) {
|
||||
if (member.member == client) {
|
||||
client->p_raid_instance = *iterator;
|
||||
return *iterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++iterator;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -3277,13 +3286,15 @@ void EntityList::Evade(Mob *who)
|
||||
void EntityList::ClearAggro(Mob* targ)
|
||||
{
|
||||
Client *c = nullptr;
|
||||
if (targ->IsClient())
|
||||
if (targ->IsClient()) {
|
||||
c = targ->CastToClient();
|
||||
}
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
if (it->second->CheckAggro(targ)) {
|
||||
if (c)
|
||||
if (c) {
|
||||
c->RemoveXTarget(it->second, false);
|
||||
}
|
||||
it->second->RemoveFromHateList(targ);
|
||||
}
|
||||
if (c && it->second->IsOnFeignMemory(c)) {
|
||||
@@ -3294,6 +3305,32 @@ void EntityList::ClearAggro(Mob* targ)
|
||||
}
|
||||
}
|
||||
|
||||
//removes "targ" from all hate lists of mobs that are water only.
|
||||
void EntityList::ClearWaterAggro(Mob* targ)
|
||||
{
|
||||
Client *c = nullptr;
|
||||
if (targ->IsClient()) {
|
||||
c = targ->CastToClient();
|
||||
}
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
if (it->second->IsUnderwaterOnly()) {
|
||||
if (it->second->CheckAggro(targ)) {
|
||||
if (c) {
|
||||
c->RemoveXTarget(it->second, false);
|
||||
}
|
||||
it->second->RemoveFromHateList(targ);
|
||||
}
|
||||
if (c && it->second->IsOnFeignMemory(c)) {
|
||||
it->second->RemoveFromFeignMemory(c); //just in case we feigned
|
||||
c->RemoveXTarget(it->second, false);
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EntityList::ClearFeignAggro(Mob *targ)
|
||||
{
|
||||
auto it = npc_list.begin();
|
||||
|
||||
@@ -447,6 +447,7 @@ public:
|
||||
|
||||
void Process();
|
||||
void ClearAggro(Mob* targ);
|
||||
void ClearWaterAggro(Mob* targ);
|
||||
void ClearFeignAggro(Mob* targ);
|
||||
void ClearZoneFeignAggro(Client* targ);
|
||||
void AggroZone(Mob* who, uint32 hate = 0);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -887,10 +887,22 @@ uint32 lua_get_char_id_by_name(const char* name) {
|
||||
return quest_manager.getcharidbyname(name);
|
||||
}
|
||||
|
||||
std::string lua_get_class_name(uint8 class_id) {
|
||||
return quest_manager.getclassname(class_id);
|
||||
}
|
||||
|
||||
std::string lua_get_class_name(uint8 class_id, uint8 level) {
|
||||
return quest_manager.getclassname(class_id, level);
|
||||
}
|
||||
|
||||
int lua_get_currency_id(uint32 item_id) {
|
||||
return quest_manager.getcurrencyid(item_id);
|
||||
}
|
||||
|
||||
int lua_get_currency_item_id(int currency_id) {
|
||||
return quest_manager.getcurrencyitemid(currency_id);
|
||||
}
|
||||
|
||||
const char *lua_get_guild_name_by_id(uint32 guild_id) {
|
||||
return quest_manager.getguildnamebyid(guild_id);
|
||||
}
|
||||
@@ -2012,7 +2024,10 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("delete_data", (bool(*)(std::string))&lua_delete_data),
|
||||
luabind::def("get_char_name_by_id", &lua_get_char_name_by_id),
|
||||
luabind::def("get_char_id_by_name", (uint32(*)(const char*))&lua_get_char_id_by_name),
|
||||
luabind::def("get_class_name", (std::string(*)(uint8))&lua_get_class_name),
|
||||
luabind::def("get_class_name", (std::string(*)(uint8,uint8))&lua_get_class_name),
|
||||
luabind::def("get_currency_id", &lua_get_currency_id),
|
||||
luabind::def("get_currency_item_id", &lua_get_currency_item_id),
|
||||
luabind::def("get_guild_name_by_id", &lua_get_guild_name_by_id),
|
||||
luabind::def("get_guild_id_by_char_id", &lua_get_guild_id_by_char_id),
|
||||
luabind::def("get_group_id_by_char_id", &lua_get_group_id_by_char_id),
|
||||
|
||||
+5
-5
@@ -694,11 +694,6 @@ void NPC::RemoveCash() {
|
||||
|
||||
bool NPC::Process()
|
||||
{
|
||||
if (IsStunned() && stunned_timer.Check()) {
|
||||
Mob::UnStun();
|
||||
this->spun_timer.Disable();
|
||||
}
|
||||
|
||||
if (p_depop)
|
||||
{
|
||||
Mob* owner = entity_list.GetMob(this->ownerid);
|
||||
@@ -711,6 +706,11 @@ bool NPC::Process()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsStunned() && stunned_timer.Check()) {
|
||||
Mob::UnStun();
|
||||
this->spun_timer.Disable();
|
||||
}
|
||||
|
||||
SpellProcess();
|
||||
|
||||
|
||||
+24
-2
@@ -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, "$$");
|
||||
|
||||
@@ -2962,6 +2962,10 @@ uint32 QuestManager::getcharidbyname(const char* name) {
|
||||
return database.GetCharacterID(name);
|
||||
}
|
||||
|
||||
std::string QuestManager::getclassname(uint8 class_id, uint8 level) {
|
||||
return GetClassIDName(class_id, level);
|
||||
}
|
||||
|
||||
int QuestManager::getcurrencyid(uint32 item_id) {
|
||||
auto iter = zone->AlternateCurrencies.begin();
|
||||
while (iter != zone->AlternateCurrencies.end()) {
|
||||
@@ -2973,6 +2977,19 @@ int QuestManager::getcurrencyid(uint32 item_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QuestManager::getcurrencyitemid(int currency_id) {
|
||||
if (currency_id > 0) {
|
||||
auto iter = zone->AlternateCurrencies.begin();
|
||||
while (iter != zone->AlternateCurrencies.end()) {
|
||||
if (currency_id == (*iter).id) {
|
||||
return (*iter).item_id;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* QuestManager::getguildnamebyid(int guild_id) {
|
||||
if (guild_id > 0)
|
||||
return guild_mgr.GetGuildName(guild_id);
|
||||
|
||||
@@ -259,7 +259,9 @@ public:
|
||||
std::string saylink(char *saylink_text, bool silent, const char *link_name);
|
||||
const char* getcharnamebyid(uint32 char_id);
|
||||
uint32 getcharidbyname(const char* name);
|
||||
std::string getclassname(uint8 class_id, uint8 level = 0);
|
||||
int getcurrencyid(uint32 item_id);
|
||||
int getcurrencyitemid(int currency_id);
|
||||
const char* getguildnamebyid(int guild_id);
|
||||
int getguildidbycharid(uint32 char_id);
|
||||
int getgroupidbycharid(uint32 char_id);
|
||||
|
||||
+6
-4
@@ -177,6 +177,7 @@ void Raid::RemoveMember(const char *characterName)
|
||||
if(client) {
|
||||
client->SetRaidGrouped(false);
|
||||
client->LeaveRaidXTargets(this);
|
||||
client->p_raid_instance = nullptr;
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_RaidRemove, sizeof(ServerRaidGeneralAction_Struct));
|
||||
@@ -1078,8 +1079,9 @@ void Raid::SendRaidRemoveAll(const char *who)
|
||||
|
||||
void Raid::SendRaidDisband(Client *to)
|
||||
{
|
||||
if(!to)
|
||||
if (!to) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
|
||||
RaidGeneral_Struct *rg = (RaidGeneral_Struct*)outapp->pBuffer;
|
||||
@@ -1614,7 +1616,7 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob)
|
||||
return;
|
||||
|
||||
uint32 group_id = 0;
|
||||
|
||||
|
||||
if(mob->IsClient())
|
||||
group_id = this->GetGroup(mob->CastToClient());
|
||||
|
||||
@@ -1622,7 +1624,7 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob)
|
||||
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
|
||||
|
||||
mob->CreateHPPacket(&hpapp);
|
||||
|
||||
|
||||
for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
|
||||
if(members[x].member) {
|
||||
if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
|
||||
@@ -1633,7 +1635,7 @@ void Raid::SendHPManaEndPacketsFrom(Mob *mob)
|
||||
mana_update->spawn_id = mob->GetID();
|
||||
mana_update->mana = mob->GetManaPercent();
|
||||
members[x].member->QueuePacket(&outapp, false);
|
||||
|
||||
|
||||
outapp.SetOpcode(OP_MobEnduranceUpdate);
|
||||
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
|
||||
endurance_update->endurance = mob->GetEndurancePercent();
|
||||
|
||||
+4
-8
@@ -3979,6 +3979,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
cd->hit_heading = action->hit_heading;
|
||||
cd->hit_pitch = action->hit_pitch;
|
||||
cd->damage = 0;
|
||||
|
||||
auto spellOwner = GetOwnerOrSelf();
|
||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity) && !is_damage_or_lifetap_spell){
|
||||
entity_list.QueueCloseClients(
|
||||
spelltar, /* Sender */
|
||||
@@ -3989,14 +3991,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
true, /* Packet ACK */
|
||||
(spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells) /* Message Filter Type: (8 or 9) */
|
||||
);
|
||||
} else if (is_damage_or_lifetap_spell &&
|
||||
(IsClient() ||
|
||||
(HasOwner() &&
|
||||
GetOwner()->IsClient()
|
||||
)
|
||||
)
|
||||
) {
|
||||
(HasOwner() ? GetOwner() : this)->CastToClient()->QueuePacket(
|
||||
} else if (is_damage_or_lifetap_spell && spellOwner->IsClient()) {
|
||||
spellOwner->CastToClient()->QueuePacket(
|
||||
message_packet,
|
||||
true,
|
||||
Mob::CLIENT_CONNECTINGALL,
|
||||
|
||||
@@ -1881,9 +1881,11 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
case ServerOP_UCSServerStatusReply:
|
||||
{
|
||||
auto ucsss = (UCSServerStatus_Struct*)pack->pBuffer;
|
||||
if (zone)
|
||||
auto ucsss = (UCSServerStatus_Struct *) pack->pBuffer;
|
||||
if (zone) {
|
||||
zone->SetUCSServerAvailable((ucsss->available != 0), ucsss->timestamp);
|
||||
LogInfo("UCS Server is now [{}]", (ucsss->available == 1 ? "online" : "offline"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
||||
|
||||
+11
-2
@@ -584,7 +584,6 @@ void Zone::GetMerchantDataForZoneLoad() {
|
||||
std::map<uint32, std::list<MerchantList> >::iterator merchant_list;
|
||||
|
||||
uint32 npc_id = 0;
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
LogDebug("No Merchant Data found for [{}]", GetShortName());
|
||||
return;
|
||||
@@ -809,7 +808,7 @@ void Zone::Shutdown(bool quiet)
|
||||
|
||||
if (RuleB(Zone, KillProcessOnDynamicShutdown)) {
|
||||
LogInfo("[KillProcessOnDynamicShutdown] Shutting down");
|
||||
std::exit(EXIT_SUCCESS);
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2562,3 +2561,13 @@ Timer Zone::GetInitgridsTimer()
|
||||
{
|
||||
return initgrids_timer;
|
||||
}
|
||||
|
||||
uint32 Zone::GetInstanceTimeRemaining() const
|
||||
{
|
||||
return instance_time_remaining;
|
||||
}
|
||||
|
||||
void Zone::SetInstanceTimeRemaining(uint32 instance_time_remaining)
|
||||
{
|
||||
Zone::instance_time_remaining = instance_time_remaining;
|
||||
}
|
||||
|
||||
@@ -285,6 +285,8 @@ public:
|
||||
ZonePoint *GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
|
||||
|
||||
Timer GetInitgridsTimer();
|
||||
uint32 GetInstanceTimeRemaining() const;
|
||||
void SetInstanceTimeRemaining(uint32 instance_time_remaining);
|
||||
|
||||
/**
|
||||
* GMSay Callback for LogSys
|
||||
@@ -368,6 +370,7 @@ private:
|
||||
uint8 zone_type;
|
||||
uint16 instanceversion;
|
||||
uint32 instanceid;
|
||||
uint32 instance_time_remaining;
|
||||
uint32 pgraveyard_id, pgraveyard_zoneid;
|
||||
uint32 pMaxClients;
|
||||
uint32 zoneid;
|
||||
|
||||
Reference in New Issue
Block a user