Merge branch 'master' of https://github.com/EQEmu/Server into integration/multi-tenancy-expansions-repository

This commit is contained in:
Akkadius 2020-07-07 01:32:17 -05:00
commit b7e2261e16
23 changed files with 633 additions and 70 deletions

View File

@ -211,6 +211,10 @@
#define ServerOP_CZTaskAssignGroup 0x4026
#define ServerOP_CZTaskAssignRaid 0x4027
#define ServerOP_CZTaskAssignGuild 0x4028
#define ServerOP_CZMovePlayer 0x4029
#define ServerOP_CZMoveGroup 0x4030
#define ServerOP_CZMoveRaid 0x4031
#define ServerOP_CZMoveGuild 0x4032
/**
* QueryServer
@ -1408,6 +1412,26 @@ struct CZMessageGuild_Struct {
char Message[512];
};
struct CZMovePlayer_Struct {
int character_id;
char zone_short_name[32];
};
struct CZMoveGroup_Struct {
int group_id;
char zone_short_name[32];
};
struct CZMoveRaid_Struct {
int raid_id;
char zone_short_name[32];
};
struct CZMoveGuild_Struct {
int guild_id;
char zone_short_name[32];
};
struct WWMarquee_Struct {
uint32 Type;
uint32 Priority;

View File

@ -927,6 +927,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
EQ::IPCMutex mutex("items");
mutex.Lock();
std::string file_name = Config->SharedMemDir + prefix + std::string("items");
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
items_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
items_hash = std::unique_ptr<EQ::FixedMemoryHashSet<EQ::ItemData>>(new EQ::FixedMemoryHashSet<EQ::ItemData>(reinterpret_cast<uint8*>(items_mmf->Get()), items_mmf->Size()));
mutex.Unlock();
@ -1351,6 +1352,7 @@ bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
EQ::IPCMutex mutex("faction");
mutex.Lock();
std::string file_name = Config->SharedMemDir + prefix + std::string("faction");
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
faction_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
faction_hash = std::unique_ptr<EQ::FixedMemoryHashSet<NPCFactionList>>(new EQ::FixedMemoryHashSet<NPCFactionList>(reinterpret_cast<uint8*>(faction_mmf->Get()), faction_mmf->Size()));
mutex.Unlock();
@ -1552,6 +1554,7 @@ bool SharedDatabase::LoadSkillCaps(const std::string &prefix) {
EQ::IPCMutex mutex("skill_caps");
mutex.Lock();
std::string file_name = Config->SharedMemDir + prefix + std::string("skill_caps");
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
skill_caps_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
mutex.Unlock();
} catch(std::exception &ex) {
@ -1710,6 +1713,7 @@ bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const
std::string file_name = Config->SharedMemDir + prefix + std::string("spells");
spells_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
LogInfo("[Shared Memory] Attempting to load file [{}]", file_name);
*records = *reinterpret_cast<uint32*>(spells_mmf->Get());
*sp = reinterpret_cast<const SPDat_Spell_Struct*>((char*)spells_mmf->Get() + 4);
mutex.Unlock();

View File

@ -438,18 +438,36 @@ bool WorldDatabase::GetStartZone(
p_player_profile_struct->binds[0].instance_id = 0;
// see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids
std::string query = StringFormat(
"SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i %s",
p_char_create_struct->start_zone,
p_char_create_struct->class_,
p_char_create_struct->deity,
p_char_create_struct->race,
ContentFilterCriteria::apply().c_str()
);
std::string query;
auto results = QueryDatabase(query);
if (!results.Success()) {
if (is_titanium) {
// Titanium sends player choice (starting city) instead of a zone id
query = StringFormat(
"SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE player_choice = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i %s",
p_char_create_struct->start_zone,
p_char_create_struct->class_,
p_char_create_struct->deity,
p_char_create_struct->race,
ContentFilterCriteria::apply().c_str()
);
LogInfo("Titanium Start zone query: [{}]\n", query.c_str());
}
else {
query = StringFormat(
"SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i %s",
p_char_create_struct->start_zone,
p_char_create_struct->class_,
p_char_create_struct->deity,
p_char_create_struct->race,
ContentFilterCriteria::apply().c_str()
);
LogInfo("SoF Start zone query: [{}]\n", query.c_str());
}
auto results = QueryDatabase(query);
if(!results.Success()) {
return false;
}

View File

@ -1256,6 +1256,10 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
case ServerOP_CZTaskAssignGroup:
case ServerOP_CZTaskAssignRaid:
case ServerOP_CZTaskAssignGuild:
case ServerOP_CZMovePlayer:
case ServerOP_CZMoveGroup:
case ServerOP_CZMoveRaid:
case ServerOP_CZMoveGuild:
case ServerOP_WWMarquee:
case ServerOP_DepopAllPlayersCorpses:
case ServerOP_DepopPlayerCorpse:

View File

@ -780,7 +780,7 @@ int Mob::GetClassRaceACBonus()
return ac_bonus;
}
int Mob::ACSum()
int Mob::ACSum(bool skip_caps)
{
int ac = 0; // this should be base AC whenever shrouds come around
ac += itembonuses.AC; // items + food + tribute
@ -799,7 +799,7 @@ int Mob::ACSum()
// EQ math
ac = (ac * 4) / 3;
// anti-twink
if (IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl))
if (!skip_caps && IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl))
ac = std::min(ac, 25 + 6 * GetLevel());
ac = std::max(0, ac + GetClassRaceACBonus());
if (IsNPC()) {
@ -835,11 +835,11 @@ int Mob::ACSum()
if (ac < 0)
ac = 0;
if (IsClient()
if (!skip_caps && (IsClient()
#ifdef BOTS
|| IsBot()
#endif
) {
)) {
auto softcap = GetACSoftcap();
auto returns = GetSoftcapReturns();
int total_aclimitmod = aabonuses.CombatStability + itembonuses.CombatStability + spellbonuses.CombatStability;

View File

@ -277,6 +277,7 @@ public:
GetItems_Struct* GetTraderItems();
void SendBazaarWelcome();
void DyeArmor(EQ::TintProfile* dye);
void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint = 0x00);
uint8 SlotConvert(uint8 slot,bool bracer=false);
void MessageString(uint32 type, uint32 string_id, uint32 distance = 0);
void MessageString(uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0);
@ -637,6 +638,9 @@ public:
void MoveZone(const char *zone_short_name);
void MoveZoneGroup(const char *zone_short_name);
void MoveZoneRaid(const char *zone_short_name);
void MoveZoneInstance(uint16 instance_id);
void MoveZoneInstanceGroup(uint16 instance_id);
void MoveZoneInstanceRaid(uint16 instance_id);
void SendToGuildHall();
void AssignToInstance(uint16 instance_id);
void RemoveFromInstance(uint16 instance_id);

View File

@ -257,7 +257,7 @@ bool Client::Process() {
* Used in aggro checks
*/
if (mob_close_scan_timer.Check()) {
entity_list.ScanCloseMobs(close_mobs, this);
entity_list.ScanCloseMobs(close_mobs, this, true);
}
bool may_use_attacks = false;

View File

@ -206,7 +206,7 @@ int command_init(void)
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", 80, command_faction) ||
command_add("findaliases", "[search criteria]- Searches for available command aliases, by alias or command", 0, command_findaliases) ||
command_add("findnpctype", "[search criteria] - Search database NPC types", 100, command_findnpctype) ||
command_add("findrace", "[search criteria] - Search for a race", 50, command_findrace) ||
command_add("findrace", "[search criteria] - Search for a race", 50, command_findrace) ||
command_add("findspell", "[search criteria] - Search for a spell", 50, command_findspell) ||
command_add("findzone", "[search criteria] - Search database zones", 100, command_findzone) ||
command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", 80, command_fixmob) ||
@ -2477,8 +2477,8 @@ void command_grid(Client *c, const Seperator *sep)
glm::vec4 node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3]));
std::vector<float> node_loc {
node_position.x,
node_position.y,
node_position.x,
node_position.y,
node_position.z
};
@ -4179,7 +4179,7 @@ void command_findzone(Client *c, const Seperator *sep)
if (id == 0) {
query = fmt::format(
"SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%' OR `short_name` LIKE '%{}%'",
EscapeString(sep->arg[1]),
EscapeString(sep->arg[1]),
EscapeString(sep->arg[1])
);
}
@ -12847,15 +12847,27 @@ void command_hotfix(Client *c, const Seperator *sep)
c->Message(Chat::White, "Creating and applying hotfix");
std::thread t1(
[c, hotfix_name]() {
#ifdef WIN32
if(hotfix_name.length() > 0) {
if(system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()));
} else {
if(system(StringFormat("shared_memory").c_str()));
}
#else
std::string shared_memory_path = "./shared_memory";
std::string shared_memory_path;
#ifdef WIN32
shared_memory_path = "shared_memory";
if (file_exists("bin/shared_memory.exe")) {
shared_memory_path = "bin\\shared_memory.exe";
}
std::string hotfix_command;
if (hotfix_name.length() > 0) {
hotfix_command = fmt::format("\"{}\" -hotfix={}", shared_memory_path, hotfix_name);
}
else {
hotfix_command = fmt::format("\"{}\"", shared_memory_path, hotfix_name);
}
LogInfo("Running hotfix command [{}]", hotfix_command);
if (system(hotfix_command.c_str())) {}
#else
shared_memory_path = "./shared_memory";
if (file_exists("./bin/shared_memory")) {
shared_memory_path = "./bin/shared_memory";
}

View File

@ -3977,6 +3977,70 @@ XS(XS__crosszonemessageplayerbyguildid) {
XSRETURN_EMPTY;
}
XS(XS__crosszonemoveplayerbycharid);
XS(XS__crosszonemoveplayerbycharid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbycharid(int character_id, string zone_short_name)");
if (items == 2) {
int character_id = (int) SvIV(ST(0));
char *zone_short_name = (char *) SvPV_nolen(ST(1));
quest_manager.CrossZoneMovePlayerByCharID(character_id, zone_short_name);
}
XSRETURN_EMPTY;
}
XS(XS__crosszonemoveplayerbygroupid);
XS(XS__crosszonemoveplayerbygroupid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbygroupid(int group_id, string zone_short_name)");
if (items == 2) {
int group_id = (int) SvIV(ST(0));
char *zone_short_name = (char *) SvPV_nolen(ST(1));
quest_manager.CrossZoneMovePlayerByGroupID(group_id, zone_short_name);
}
XSRETURN_EMPTY;
}
XS(XS__crosszonemoveplayerbyraidid);
XS(XS__crosszonemoveplayerbyraidid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbyraidid(int raid_id, string zone_short_name)");
if (items == 2) {
int raid_id = (int) SvIV(ST(0));
char *zone_short_name = (char *) SvPV_nolen(ST(1));
quest_manager.CrossZoneMovePlayerByRaidID(raid_id, zone_short_name);
}
XSRETURN_EMPTY;
}
XS(XS__crosszonemoveplayerbyguildid);
XS(XS__crosszonemoveplayerbyguildid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbyguildid(int guild_id, string zone_short_name)");
if (items == 2) {
int guild_id = (int) SvIV(ST(0));
char *zone_short_name = (char *) SvPV_nolen(ST(1));
quest_manager.CrossZoneMovePlayerByGuildID(guild_id, zone_short_name);
}
XSRETURN_EMPTY;
}
XS(XS__enablerecipe);
XS(XS__enablerecipe) {
dXSARGS;
@ -5127,6 +5191,10 @@ EXTERN_C XS(boot_quest) {
newXS(strcpy(buf, "crosszonemessageplayerbygroupid"), XS__crosszonemessageplayerbygroupid, file);
newXS(strcpy(buf, "crosszonemessageplayerbyraidid"), XS__crosszonemessageplayerbyraidid, file);
newXS(strcpy(buf, "crosszonemessageplayerbyguildid"), XS__crosszonemessageplayerbyguildid, file);
newXS(strcpy(buf, "crosszonemoveplayerbycharid"), XS__crosszonemoveplayerbycharid, file);
newXS(strcpy(buf, "crosszonemoveplayerbygroupid"), XS__crosszonemoveplayerbygroupid, file);
newXS(strcpy(buf, "crosszonemoveplayerbyraidid"), XS__crosszonemoveplayerbyraidid, file);
newXS(strcpy(buf, "crosszonemoveplayerbyguildid"), XS__crosszonemoveplayerbyguildid, file);
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
newXS(strcpy(buf, "crosszonesetentityvariablebyclientname"), XS__crosszonesetentityvariablebyclientname, file);
newXS(strcpy(buf, "crosszonesetentityvariablebygroupid"), XS__crosszonesetentityvariablebygroupid, file);

View File

@ -2716,18 +2716,22 @@ void EntityList::ScanCloseMobs(
}
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range) {
if (distance <= scan_range || mob->GetAggroRange() >= scan_range) {
close_mobs.insert(std::pair<uint16, Mob *>(mob->GetID(), mob));
if (add_self_to_other_lists) {
mob->close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
}
}
else if (mob->GetAggroRange() >= scan_range) {
close_mobs.insert(std::pair<uint16, Mob *>(mob->GetID(), mob));
bool has_mob = false;
if (add_self_to_other_lists) {
mob->close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
for (auto &cm: mob->close_mobs) {
if (scanning_mob->GetID() == cm.first) {
has_mob = true;
break;
}
}
if (!has_mob) {
mob->close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
}
}
}
}

View File

@ -2229,6 +2229,22 @@ void Client::DyeArmor(EQ::TintProfile* dye){
}
void Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint) {
uint8 item_slot = SlotConvert(slot);
EQ::ItemInstance* item_instance = this->m_inv.GetItem(item_slot);
if (item_instance) {
uint32 armor_color = ((uint32)red << 16) | ((uint32)green << 8) | ((uint32)blue);
item_instance->SetColor(armor_color);
database.SaveCharacterMaterialColor(this->CharacterID(), slot, armor_color);
database.SaveInventory(CharacterID(), item_instance, item_slot);
m_pp.item_tint.Slot[slot].UseTint = (use_tint ? 0xFF : 0x00);
}
m_pp.item_tint.Slot[slot].Red = red;
m_pp.item_tint.Slot[slot].Green = green;
m_pp.item_tint.Slot[slot].Blue = blue;
SendWearChange(slot);
}
#if 0
bool Client::DecreaseByItemType(uint32 type, uint8 amt) {
const ItemData* TempItem = 0;

View File

@ -75,6 +75,16 @@ void Lua_Client::Duck() {
self->Duck();
}
void Lua_Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue) {
Lua_Safe_Call_Void();
self->DyeArmorBySlot(slot, red, green, blue);
}
void Lua_Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint) {
Lua_Safe_Call_Void();
self->DyeArmorBySlot(slot, red, green, blue, use_tint);
}
void Lua_Client::Stand() {
Lua_Safe_Call_Void();
self->Stand();
@ -340,6 +350,21 @@ void Lua_Client::MoveZoneRaid(const char *zone_short_name) {
self->MoveZoneRaid(zone_short_name);
}
void Lua_Client::MoveZoneInstance(uint16 instance_id) {
Lua_Safe_Call_Void();
self->MoveZoneInstance(instance_id);
}
void Lua_Client::MoveZoneInstanceGroup(uint16 instance_id) {
Lua_Safe_Call_Void();
self->MoveZoneInstanceGroup(instance_id);
}
void Lua_Client::MoveZoneInstanceRaid(uint16 instance_id) {
Lua_Safe_Call_Void();
self->MoveZoneInstanceRaid(instance_id);
}
void Lua_Client::ChangeLastName(const char *in) {
Lua_Safe_Call_Void();
self->ChangeLastName(in);
@ -1622,6 +1647,8 @@ luabind::scope lua_register_client() {
.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("DyeArmorBySlot", (void(Lua_Client::*)(uint8,uint8,uint8,uint8))&Lua_Client::DyeArmorBySlot)
.def("DyeArmorBySlot", (void(Lua_Client::*)(uint8,uint8,uint8,uint8,uint8))&Lua_Client::DyeArmorBySlot)
.def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand)
.def("SetGM", (void(Lua_Client::*)(bool))&Lua_Client::SetGM)
.def("SetPVP", (void(Lua_Client::*)(bool))&Lua_Client::SetPVP)
@ -1676,6 +1703,9 @@ luabind::scope lua_register_client() {
.def("MoveZone", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZone)
.def("MoveZoneGroup", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneGroup)
.def("MoveZoneRaid", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneRaid)
.def("MoveZoneInstance", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstance)
.def("MoveZoneInstanceGroup", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstanceGroup)
.def("MoveZoneInstanceRaid", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstanceRaid)
.def("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName)
.def("GetFactionLevel", (int(Lua_Client::*)(uint32,uint32,uint32,uint32,uint32,uint32,Lua_NPC))&Lua_Client::GetFactionLevel)
.def("SetFactionLevel", (void(Lua_Client::*)(uint32,uint32,int,int,int))&Lua_Client::SetFactionLevel)

View File

@ -42,6 +42,8 @@ public:
void SendToGuildHall();
bool GetAnon();
void Duck();
void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue);
void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint);
void Stand();
void SetGM(bool v);
void SetPVP(bool v);
@ -94,6 +96,9 @@ public:
void MoveZone(const char *zone_short_name);
void MoveZoneGroup(const char *zone_short_name);
void MoveZoneRaid(const char *zone_short_name);
void MoveZoneInstance(uint16 instance_id);
void MoveZoneInstanceGroup(uint16 instance_id);
void MoveZoneInstanceRaid(uint16 instance_id);
void ChangeLastName(const char *in);
int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc);
void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity);

View File

@ -1091,6 +1091,22 @@ void lua_cross_zone_message_player_by_guild_id(uint32 type, int guild_id, const
quest_manager.CrossZoneMessagePlayerByGuildID(type, guild_id, message);
}
void lua_cross_zone_move_player_by_char_id(int character_id, const char *zone_short_name) {
quest_manager.CrossZoneMovePlayerByCharID(character_id, zone_short_name);
}
void lua_cross_zone_move_player_by_group_id(int group_id, const char *zone_short_name) {
quest_manager.CrossZoneMovePlayerByGroupID(group_id, zone_short_name);
}
void lua_cross_zone_move_player_by_raid_id(int raid_id, const char *zone_short_name) {
quest_manager.CrossZoneMovePlayerByRaidID(raid_id, zone_short_name);
}
void lua_cross_zone_move_player_by_guild_id(int guild_id, const char *zone_short_name) {
quest_manager.CrossZoneMovePlayerByGuildID(guild_id, zone_short_name);
}
void lua_cross_zone_set_entity_variable_by_client_name(const char *player, const char *id, const char *m_var) {
quest_manager.CrossZoneSetEntityVariableByClientName(player, id, m_var);
}
@ -2164,6 +2180,10 @@ luabind::scope lua_register_general() {
luabind::def("cross_zone_message_player_by_group_id", &lua_cross_zone_message_player_by_group_id),
luabind::def("cross_zone_message_player_by_raid_id", &lua_cross_zone_message_player_by_raid_id),
luabind::def("cross_zone_message_player_by_guild_id", &lua_cross_zone_message_player_by_guild_id),
luabind::def("cross_zone_move_player_by_char_id", &lua_cross_zone_move_player_by_char_id),
luabind::def("cross_zone_move_player_by_group_id", &lua_cross_zone_move_player_by_group_id),
luabind::def("cross_zone_move_player_by_raid_id", &lua_cross_zone_move_player_by_raid_id),
luabind::def("cross_zone_move_player_by_guild_id", &lua_cross_zone_move_player_by_guild_id),
luabind::def("cross_zone_set_entity_variable_by_client_name", &lua_cross_zone_set_entity_variable_by_client_name),
luabind::def("cross_zone_set_entity_variable_by_group_id", &lua_cross_zone_set_entity_variable_by_group_id),
luabind::def("cross_zone_set_entity_variable_by_raid_id", &lua_cross_zone_set_entity_variable_by_raid_id),

View File

@ -532,6 +532,11 @@ int Lua_Mob::GetAC() {
return self->GetAC();
}
int Lua_Mob::GetDisplayAC() {
Lua_Safe_Call_Int();
return self->GetDisplayAC();
}
int Lua_Mob::GetATK() {
Lua_Safe_Call_Int();
return self->GetATK();
@ -2344,6 +2349,7 @@ luabind::scope lua_register_mob() {
.def("SetMana", &Lua_Mob::SetMana)
.def("GetManaRatio", &Lua_Mob::GetManaRatio)
.def("GetAC", &Lua_Mob::GetAC)
.def("GetDisplayAC", &Lua_Mob::GetDisplayAC)
.def("GetATK", &Lua_Mob::GetATK)
.def("GetSTR", &Lua_Mob::GetSTR)
.def("GetSTA", &Lua_Mob::GetSTA)

View File

@ -124,6 +124,7 @@ public:
int SetMana(int mana);
double GetManaRatio();
int GetAC();
int GetDisplayAC();
int GetATK();
int GetSTR();
int GetSTA();

View File

@ -211,7 +211,8 @@ public:
int TryAssassinate(Mob* defender, EQ::skills::SkillType skillInUse);
virtual void DoRiposte(Mob* defender);
void ApplyMeleeDamageMods(uint16 skill, int &damage, Mob * defender = nullptr, ExtraAttackOptions *opts = nullptr);
int ACSum();
int ACSum(bool skip_caps = false);
inline int GetDisplayAC() { return 1000 * (ACSum(true) + compute_defense()) / 847; }
int offense(EQ::skills::SkillType skill);
int GetBestMeleeSkill();
void CalcAC() { mitigation_ac = ACSum(); }

View File

@ -312,6 +312,34 @@ XS(XS_Client_Duck) {
XSRETURN_EMPTY;
}
XS(XS_Client_DyeArmorBySlot); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_DyeArmorBySlot) {
dXSARGS;
if (items != 5 && items != 6)
Perl_croak(aTHX_ "Usage: Client::DyeArmorBySlot(THIS, uint8 slot, uint8 red, uint8 green, uint8 blue, [uint8 use_tint = 0x00])");
{
Client *THIS;
uint8 slot = (uint8) SvUV(ST(1));
uint8 red = (uint8) SvUV(ST(2));
uint8 green = (uint8) SvUV(ST(3));
uint8 blue = (uint8) SvUV(ST(4));
uint8 use_tint = 0x00;
if (items == 6) {
use_tint = (uint8) SvUV(ST(5));
}
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->DyeArmorBySlot(slot, red, green, blue, use_tint);
}
XSRETURN_EMPTY;
}
XS(XS_Client_Stand); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_Stand) {
dXSARGS;
@ -1445,6 +1473,132 @@ XS(XS_Client_MoveZoneRaid) {
XSRETURN_EMPTY;
}
XS(XS_Client_MoveZoneInstance); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZoneInstance) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZoneInstance(THIS, uint16 instance_id)");
{
Client *THIS;
uint16 instance_id = (uint16) SvUV(ST(1));
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.");
if (THIS->IsClient()) {
THIS->MoveZoneInstance(instance_id);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process an Unknown type reference");
}
Perl_croak(aTHX_ "THIS is not of type Client");
}
}
XSRETURN_EMPTY;
}
XS(XS_Client_MoveZoneInstanceGroup); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZoneInstanceGroup) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZoneInstanceGroup(THIS, uint16 instance_id)");
{
Client *THIS;
uint16 instance_id = (uint16) SvUV(ST(1));
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.");
if (THIS->IsClient()) {
THIS->MoveZoneInstanceGroup(instance_id);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process an Unknown type reference");
}
Perl_croak(aTHX_ "THIS is not of type Client");
}
}
XSRETURN_EMPTY;
}
XS(XS_Client_MoveZoneInstanceRaid); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZoneInstanceRaid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZoneInstanceRaid(THIS, uint16 instance_id)");
{
Client *THIS;
uint16 instance_id = (uint16) SvUV(ST(1));
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.");
if (THIS->IsClient()) {
THIS->MoveZoneInstanceRaid(instance_id);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process an Unknown type reference");
}
Perl_croak(aTHX_ "THIS is not of type Client");
}
}
XSRETURN_EMPTY;
}
XS(XS_Client_ChangeLastName); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_ChangeLastName) {
dXSARGS;
@ -6585,6 +6739,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$");
newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$");
newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$");
newXSproto(strcpy(buf, "DyeArmorBySlot"), XS_Client_DyeArmorBySlot, file, "$$$$$;$");
newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$");
newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$");
newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$");
@ -6715,6 +6870,9 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "MoveZone"), XS_Client_MoveZone, file, "$$");
newXSproto(strcpy(buf, "MoveZoneGroup"), XS_Client_MoveZoneGroup, file, "$$");
newXSproto(strcpy(buf, "MoveZoneRaid"), XS_Client_MoveZoneRaid, file, "$$");
newXSproto(strcpy(buf, "MoveZoneInstance"), XS_Client_MoveZoneInstance, file, "$$");
newXSproto(strcpy(buf, "MoveZoneInstanceGroup"), XS_Client_MoveZoneInstanceGroup, file, "$$");
newXSproto(strcpy(buf, "MoveZoneInstanceRaid"), XS_Client_MoveZoneInstanceRaid, file, "$$");
newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$");
newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$");
newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$");

View File

@ -2506,6 +2506,31 @@ XS(XS_Mob_GetAC) {
XSRETURN(1);
}
XS(XS_Mob_GetDisplayAC); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetDisplayAC) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::GetDisplayAC(THIS)");
{
Mob *THIS;
uint32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV *) SvRV(ST(0)));
THIS = INT2PTR(Mob *, tmp);
} else
Perl_croak(aTHX_ "THIS is not of type Mob");
if (THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetDisplayAC();
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Mob_GetATK); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetATK) {
dXSARGS;
@ -8676,6 +8701,7 @@ XS(boot_Mob) {
newXSproto(strcpy(buf, "SetMana"), XS_Mob_SetMana, file, "$$");
newXSproto(strcpy(buf, "GetManaRatio"), XS_Mob_GetManaRatio, file, "$");
newXSproto(strcpy(buf, "GetAC"), XS_Mob_GetAC, file, "$");
newXSproto(strcpy(buf, "GetDisplayAC"), XS_Mob_GetDisplayAC, file, "$");
newXSproto(strcpy(buf, "GetATK"), XS_Mob_GetATK, file, "$");
newXSproto(strcpy(buf, "GetSTR"), XS_Mob_GetSTR, file, "$");
newXSproto(strcpy(buf, "GetSTA"), XS_Mob_GetSTA, file, "$");

View File

@ -3429,6 +3429,46 @@ void QuestManager::CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, con
safe_delete(pack);
}
void QuestManager::CrossZoneMovePlayerByCharID(int character_id, const char *zone_short_name){
uint32 message_len = strlen(zone_short_name) + 1;
auto pack = new ServerPacket(ServerOP_CZMovePlayer, sizeof(CZMovePlayer_Struct) + message_len);
CZMovePlayer_Struct* CZGM = (CZMovePlayer_Struct*) pack->pBuffer;
CZGM->character_id = character_id;
strn0cpy(CZGM->zone_short_name, zone_short_name, 32);
worldserver.SendPacket(pack);
safe_delete(pack);
}
void QuestManager::CrossZoneMovePlayerByGroupID(int group_id, const char *zone_short_name){
uint32 message_len = strlen(zone_short_name) + 1;
auto pack = new ServerPacket(ServerOP_CZMoveGroup, sizeof(CZMoveGroup_Struct) + message_len);
CZMoveGroup_Struct* CZGM = (CZMoveGroup_Struct*) pack->pBuffer;
CZGM->group_id = group_id;
strn0cpy(CZGM->zone_short_name, zone_short_name, 32);
worldserver.SendPacket(pack);
safe_delete(pack);
}
void QuestManager::CrossZoneMovePlayerByRaidID(int raid_id, const char *zone_short_name){
uint32 message_len = strlen(zone_short_name) + 1;
auto pack = new ServerPacket(ServerOP_CZMoveRaid, sizeof(CZMoveRaid_Struct) + message_len);
CZMoveRaid_Struct* CZRM = (CZMoveRaid_Struct*) pack->pBuffer;
CZRM->raid_id = raid_id;
strn0cpy(CZRM->zone_short_name, zone_short_name, 32);
worldserver.SendPacket(pack);
safe_delete(pack);
}
void QuestManager::CrossZoneMovePlayerByGuildID(int guild_id, const char *zone_short_name){
uint32 message_len = strlen(zone_short_name) + 1;
auto pack = new ServerPacket(ServerOP_CZMoveGuild, sizeof(CZMoveGuild_Struct) + message_len);
CZMoveGuild_Struct* CZGM = (CZMoveGuild_Struct*) pack->pBuffer;
CZGM->guild_id = guild_id;
strn0cpy(CZGM->zone_short_name, zone_short_name, 32);
worldserver.SendPacket(pack);
safe_delete(pack);
}
void QuestManager::CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var){
uint32 message_len = strlen(id) + 1;
uint32 message_len2 = strlen(m_var) + 1;

View File

@ -299,6 +299,10 @@ public:
void CrossZoneMessagePlayerByGroupID(uint32 Type, int GroupID, const char *Message);
void CrossZoneMessagePlayerByRaidID(uint32 Type, int RaidID, const char *Message);
void CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, const char *Message);
void CrossZoneMovePlayerByCharID(int character_id, const char *zone_short_name);
void CrossZoneMovePlayerByGroupID(int group_id, const char *zone_short_name);
void CrossZoneMovePlayerByRaidID(int raid_id, const char *zone_short_name);
void CrossZoneMovePlayerByGuildID(int guild_id, const char *zone_short_name);
void WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message);
bool EnableRecipe(uint32 recipe_id);
bool DisableRecipe(uint32 recipe_id);

View File

@ -1918,10 +1918,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZSignalGroup:
{
CZGroupSignal_Struct* CZGS = (CZGroupSignal_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZGS->group_id) {
client.second->Signal(CZGS->data);
auto client_group = entity_list.GetGroupByID(CZGS->group_id);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->Signal(CZGS->data);
}
}
}
break;
@ -1929,10 +1932,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZSignalRaid:
{
CZRaidSignal_Struct* CZRS = (CZRaidSignal_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZRS->raid_id) {
client.second->Signal(CZRS->data);
auto client_raid = entity_list.GetRaidByID(CZRS->raid_id);
if (client_raid) {
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->Signal(CZRS->data);
}
}
}
break;
@ -1969,10 +1975,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZMessageGroup:
{
CZMessageGroup_Struct* CZGM = (CZMessageGroup_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZGM->GroupID) {
client.second->Message(CZGM->Type, CZGM->Message);
auto client_group = entity_list.GetGroupByID(CZGM->GroupID);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->Message(CZGM->Type, CZGM->Message);
}
}
}
break;
@ -1980,10 +1989,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZMessageRaid:
{
CZMessageRaid_Struct* CZRM = (CZMessageRaid_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZRM->RaidID) {
client.second->Message(CZRM->Type, CZRM->Message);
auto client_raid = entity_list.GetRaidByID(CZRM->RaidID);
if (client_raid) {
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->Message(CZRM->Type, CZRM->Message);
}
}
}
break;
@ -2011,10 +2023,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZSetEntityVariableByGroupID:
{
CZSetEntVarByGroupID_Struct* CZCS = (CZSetEntVarByGroupID_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZCS->group_id) {
client.second->SetEntityVariable(CZCS->id, CZCS->m_var);
auto client_group = entity_list.GetGroupByID(CZCS->group_id);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->SetEntityVariable(CZCS->id, CZCS->m_var);
}
}
}
break;
@ -2022,10 +2037,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZSetEntityVariableByRaidID:
{
CZSetEntVarByRaidID_Struct* CZCS = (CZSetEntVarByRaidID_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZCS->raid_id) {
client.second->SetEntityVariable(CZCS->id, CZCS->m_var);
auto client_raid = entity_list.GetRaidByID(CZCS->raid_id);
if (client_raid) {
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->SetEntityVariable(CZCS->id, CZCS->m_var);
}
}
}
break;
@ -2044,7 +2062,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZTaskAssign:
{
CZTaskAssign_Struct* CZTA = (CZTaskAssign_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
Client* client = entity_list.GetClientByCharID(CZTA->character_id);
if (client != 0) {
client->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
@ -2054,10 +2071,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZTaskAssignGroup:
{
CZTaskAssignGroup_Struct* CZTA = (CZTaskAssignGroup_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZTA->group_id) {
client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
auto client_group = entity_list.GetGroupByID(CZTA->group_id);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
}
}
}
break;
@ -2065,10 +2085,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
case ServerOP_CZTaskAssignRaid:
{
CZTaskAssignRaid_Struct* CZTA = (CZTaskAssignRaid_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZTA->raid_id) {
client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
auto client_raid = entity_list.GetRaidByID(CZTA->raid_id);
if (client_raid) {
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
}
}
}
break;
@ -2084,6 +2107,54 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
break;
}
case ServerOP_CZMovePlayer:
{
CZMovePlayer_Struct* CZMP = (CZMovePlayer_Struct*)pack->pBuffer;
Client* client = entity_list.GetClientByCharID(CZMP->character_id);
if (client != 0) {
client->MoveZone(CZMP->zone_short_name);
}
break;
}
case ServerOP_CZMoveGroup:
{
CZMoveGroup_Struct* CZMG = (CZMoveGroup_Struct*)pack->pBuffer;
auto client_group = entity_list.GetGroupByID(CZMG->group_id);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->MoveZone(CZMG->zone_short_name);
}
}
}
break;
}
case ServerOP_CZMoveRaid:
{
CZMoveRaid_Struct* CZMR = (CZMoveRaid_Struct*)pack->pBuffer;
auto client_raid = entity_list.GetRaidByID(CZMR->raid_id);
if (client_raid) {
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->MoveZone(CZMR->zone_short_name);
}
}
}
break;
}
case ServerOP_CZMoveGuild:
{
CZMoveGuild_Struct* CZMG = (CZMoveGuild_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GuildID() > 0 && client.second->GuildID() == CZMG->guild_id) {
client.second->MoveZone(CZMG->zone_short_name);
}
}
break;
}
case ServerOP_WWMarquee:
{
WWMarquee_Struct* WWMS = (WWMarquee_Struct*)pack->pBuffer;

View File

@ -489,6 +489,53 @@ void Client::MoveZoneRaid(const char *zone_short_name) {
}
}
void Client::MoveZoneInstance(uint16 instance_id) {
if (!database.CharacterInInstanceGroup(instance_id, CharacterID())) {
database.AddClientToInstance(instance_id, CharacterID());
}
auto pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct));
ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer;
ztz->response = 0;
ztz->current_zone_id = zone->GetZoneID();
ztz->current_instance_id = zone->GetInstanceID();
ztz->requested_zone_id = database.ZoneIDFromInstanceID(instance_id);
ztz->requested_instance_id = instance_id;
ztz->admin = Admin();
strcpy(ztz->name, GetName());
ztz->guild_id = GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
}
void Client::MoveZoneInstanceGroup(uint16 instance_id) {
if (!GetGroup()) {
MoveZoneInstance(instance_id);
} else {
auto client_group = GetGroup();
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->MoveZoneInstance(instance_id);
}
}
}
}
void Client::MoveZoneInstanceRaid(uint16 instance_id) {
if (!GetRaid()) {
MoveZoneInstance(instance_id);
} else {
auto client_raid = GetRaid();
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->MoveZoneInstance(instance_id);
}
}
}
}
void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm)
{
// From what I have read, dragged corpses should stay with the player for Intra-zone summons etc, but we can implement that later.