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

This commit is contained in:
Akkadius 2020-06-29 00:40:27 -05:00
commit e03ca7f65e
34 changed files with 1366 additions and 509 deletions

View File

@ -133,7 +133,7 @@ ENDIF(EQEMU_ENABLE_BOTS)
#database #database
IF(MySQL_FOUND AND MariaDB_FOUND) IF(MySQL_FOUND AND MariaDB_FOUND)
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use: SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
MySQL MySQL
MariaDB" MariaDB"
) )

View File

@ -17,9 +17,13 @@
|:---:|:---:|:---:| |:---:|:---:|:---:|
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)| |**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)|
### > Windows ### > Windows
* [Install](https://eqemu.gitbook.io/server/categories/how-to-guides/installation/server-installation-windows)
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-windows)
### > Debian/Ubuntu/CentOS/Fedora ### > Debian/Ubuntu/CentOS/Fedora
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-linux)
* You can use curl or wget to kick off the installer (whichever your OS has) * You can use curl or wget to kick off the installer (whichever your OS has)
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh > curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh

File diff suppressed because it is too large Load Diff

View File

@ -207,6 +207,10 @@
#define ServerOP_CZSetEntityVariableByGroupID 0x4022 #define ServerOP_CZSetEntityVariableByGroupID 0x4022
#define ServerOP_CZSetEntityVariableByRaidID 0x4023 #define ServerOP_CZSetEntityVariableByRaidID 0x4023
#define ServerOP_CZSetEntityVariableByGuildID 0x4024 #define ServerOP_CZSetEntityVariableByGuildID 0x4024
#define ServerOP_CZTaskAssign 0x4025
#define ServerOP_CZTaskAssignGroup 0x4026
#define ServerOP_CZTaskAssignRaid 0x4027
#define ServerOP_CZTaskAssignGuild 0x4028
/** /**
* QueryServer * QueryServer
@ -1171,6 +1175,34 @@ struct Server_Speech_Struct {
char message[0]; char message[0];
}; };
struct CZTaskAssign_Struct {
uint16 npc_entity_id;
int character_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignGroup_Struct {
uint16 npc_entity_id;
int group_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignRaid_Struct {
uint16 npc_entity_id;
int raid_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignGuild_Struct {
uint16 npc_entity_id;
int guild_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZClientSignal_Struct { struct CZClientSignal_Struct {
int charid; int charid;
uint32 data; uint32 data;

View File

@ -527,3 +527,51 @@ bool isAlphaNumeric(const char *text)
return true; return true;
} }
// Function to convert single digit or two digit number into words
std::string convert2digit(int n, std::string suffix)
{
// if n is zero
if (n == 0) {
return "";
}
// split n if it is more than 19
if (n > 19) {
return NUM_TO_ENGLISH_Y[n / 10] + NUM_TO_ENGLISH_X[n % 10] + suffix;
}
else {
return NUM_TO_ENGLISH_X[n] + suffix;
}
}
// Function to convert a given number (max 9-digits) into words
std::string numberToWords(unsigned long long int n)
{
// string to store word representation of given number
std::string res;
// this handles digits at ones & tens place
res = convert2digit((n % 100), "");
if (n > 100 && n % 100) {
res = "and " + res;
}
// this handles digit at hundreds place
res = convert2digit(((n / 100) % 10), "Hundred ") + res;
// this handles digits at thousands & tens thousands place
res = convert2digit(((n / 1000) % 100), "Thousand ") + res;
// this handles digits at hundred thousands & one millions place
res = convert2digit(((n / 100000) % 100), "Lakh, ") + res;
// this handles digits at ten millions & hundred millions place
res = convert2digit((n / 10000000) % 100, "Crore, ") + res;
// this handles digits at ten millions & hundred millions place
res = convert2digit((n / 1000000000) % 100, "Billion, ") + res;
return res;
}

View File

@ -43,6 +43,20 @@ std::vector<std::string> split(std::string str_to_split, char delimiter);
const std::string StringFormat(const char* format, ...); const std::string StringFormat(const char* format, ...);
const std::string vStringFormat(const char* format, va_list args); const std::string vStringFormat(const char* format, va_list args);
std::string implode(std::string glue, std::vector<std::string> src); std::string implode(std::string glue, std::vector<std::string> src);
std::string convert2digit(int n, std::string suffix);
std::string numberToWords(unsigned long long int n);
// For converstion of numerics into English
// Used for grid nodes, as NPC names remove numerals.
// But general purpose
const std::string NUM_TO_ENGLISH_X[] = { "", "One ", "Two ", "Three ", "Four ",
"Five ", "Six ", "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ",
"Twelve ", "Thirteen ", "Fourteen ", "Fifteen ",
"Sixteen ", "Seventeen ", "Eighteen ", "Nineteen " };
const std::string NUM_TO_ENGLISH_Y[] = { "", "", "Twenty ", "Thirty ", "Forty ",
"Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety " };
/** /**
* @param str * @param str
@ -189,5 +203,8 @@ uint32 hextoi(const char* num);
uint64 hextoi64(const char* num); uint64 hextoi64(const char* num);
void MakeLowerString(const char *source, char *target); void MakeLowerString(const char *source, char *target);
void RemoveApostrophes(std::string &s); void RemoveApostrophes(std::string &s);
std::string convert2digit(int n, std::string suffix);
std::string numberToWords(unsigned long long int n);
#endif #endif

File diff suppressed because one or more lines are too long

View File

@ -508,14 +508,19 @@ int main(int argc, char** argv) {
zoneserver_list.UpdateUCSServerAvailable(); zoneserver_list.UpdateUCSServerAvailable();
}); });
server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) { server_connection->OnConnectionRemoved(
LogInfo("Removed UCS Server connection from [{0}]", "UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
connection->GetUUID()); LogInfo("Connection lost from UCS Server [{0}]", connection->GetUUID());
auto ucs_connection = UCSLink.GetConnection();
if (ucs_connection->GetUUID() == connection->GetUUID()) {
LogInfo("Removing currently active UCS connection");
UCSLink.SetConnection(nullptr); UCSLink.SetConnection(nullptr);
zoneserver_list.UpdateUCSServerAvailable(false); zoneserver_list.UpdateUCSServerAvailable(false);
}); }
}
);
server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) { server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
LogInfo("New WebInterface Server connection from [{2}] at [{0}:{1}]", LogInfo("New WebInterface Server connection from [{2}] at [{0}:{1}]",

View File

@ -32,7 +32,12 @@ void UCSConnection::SetConnection(std::shared_ptr<EQ::Net::ServertalkServerConne
); );
} }
m_keepalive.reset(new EQ::Timer(5000, true, std::bind(&UCSConnection::OnKeepAlive, this, std::placeholders::_1))); m_keepalive.reset(new EQ::Timer(1000, true, std::bind(&UCSConnection::OnKeepAlive, this, std::placeholders::_1)));
}
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &UCSConnection::GetConnection() const
{
return connection;
} }
void UCSConnection::ProcessPacket(uint16 opcode, EQ::Net::Packet &p) void UCSConnection::ProcessPacket(uint16 opcode, EQ::Net::Packet &p)

View File

@ -16,6 +16,8 @@ public:
void SendPacket(ServerPacket* pack); void SendPacket(ServerPacket* pack);
void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); } void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); }
void SendMessage(const char *From, const char *Message); void SendMessage(const char *From, const char *Message);
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const;
private: private:
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; } inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection; std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;

View File

@ -1252,6 +1252,10 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
case ServerOP_CZSetEntityVariableByGroupID: case ServerOP_CZSetEntityVariableByGroupID:
case ServerOP_CZSetEntityVariableByRaidID: case ServerOP_CZSetEntityVariableByRaidID:
case ServerOP_CZSetEntityVariableByGuildID: case ServerOP_CZSetEntityVariableByGuildID:
case ServerOP_CZTaskAssign:
case ServerOP_CZTaskAssignGroup:
case ServerOP_CZTaskAssignRaid:
case ServerOP_CZTaskAssignGuild:
case ServerOP_WWMarquee: case ServerOP_WWMarquee:
case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopAllPlayersCorpses:
case ServerOP_DepopPlayerCorpse: case ServerOP_DepopPlayerCorpse:

View File

@ -634,6 +634,9 @@ public:
void MovePC(uint32 zoneID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); 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(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 MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
void MoveZone(const char *zone_short_name);
void MoveZoneGroup(const char *zone_short_name);
void MoveZoneRaid(const char *zone_short_name);
void SendToGuildHall(); void SendToGuildHall();
void AssignToInstance(uint16 instance_id); void AssignToInstance(uint16 instance_id);
void RemoveFromInstance(uint16 instance_id); void RemoveFromInstance(uint16 instance_id);
@ -949,7 +952,9 @@ public:
void DropInst(const EQ::ItemInstance* inst); void DropInst(const EQ::ItemInstance* inst);
bool TrainDiscipline(uint32 itemid); bool TrainDiscipline(uint32 itemid);
void TrainDiscBySpellID(int32 spell_id); void TrainDiscBySpellID(int32 spell_id);
uint32 GetDisciplineTimer(uint32 timer_id);
int GetDiscSlotBySpellID(int32 spellid); int GetDiscSlotBySpellID(int32 spellid);
void ResetDisciplineTimer(uint32 timer_id);
void SendDisciplineUpdate(); void SendDisciplineUpdate();
void SendDisciplineTimer(uint32 timer_id, uint32 duration); void SendDisciplineTimer(uint32 timer_id, uint32 duration);
bool UseDiscipline(uint32 spell_id, uint32 target); bool UseDiscipline(uint32 spell_id, uint32 target);

View File

@ -917,7 +917,7 @@ void Client::CompleteConnect()
worldserver.RequestTellQueue(GetName()); worldserver.RequestTellQueue(GetName());
entity_list.ScanCloseMobs(close_mobs, this); entity_list.ScanCloseMobs(close_mobs, this, true);
} }
// connecting opcode handlers // connecting opcode handlers

View File

@ -204,9 +204,10 @@ int command_init(void)
command_add("equipitem", "[slotid(0-21)] - Equip the item on your cursor into the specified slot", 50, command_equipitem) || command_add("equipitem", "[slotid(0-21)] - Equip the item on your cursor into the specified slot", 50, command_equipitem) ||
command_add("face", "- Change the face of your target", 80, command_face) || command_add("face", "- Change the face of your target", 80, command_face) ||
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", 80, command_faction) || command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", 80, command_faction) ||
command_add("findaliases", "[search term]- Searches for available command aliases, by alias or command", 0, command_findaliases) || 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("findnpctype", "[search criteria] - Search database NPC types", 100, command_findnpctype) ||
command_add("findspell", "[searchstring] - Search for a spell", 50, command_findspell) || 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("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) || 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) ||
command_add("flag", "[status] [acctname] - Refresh your admin status, or set an account's admin status if arguments provided", 0, command_flag) || command_add("flag", "[status] [acctname] - Refresh your admin status, or set an account's admin status if arguments provided", 0, command_flag) ||
@ -2437,10 +2438,10 @@ void command_grid(Client *c, const Seperator *sep)
} }
std::string query = StringFormat( std::string query = StringFormat(
"SELECT `x`, `y`, `z`, `heading`, `number`, `pause` " "SELECT `x`, `y`, `z`, `heading`, `number` "
"FROM `grid_entries` " "FROM `grid_entries` "
"WHERE `zoneid` = %u and `gridid` = %i " "WHERE `zoneid` = %u and `gridid` = %i "
"ORDER BY `number` ", "ORDER BY `number`",
zone->GetZoneID(), zone->GetZoneID(),
target->CastToNPC()->GetGrid() target->CastToNPC()->GetGrid()
); );
@ -2470,18 +2471,31 @@ void command_grid(Client *c, const Seperator *sep)
/** /**
* Spawn grid nodes * Spawn grid nodes
*/ */
for (auto row = results.begin(); row != results.end(); ++row) { std::map<std::vector<float>, int32> zoffset;
auto node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3]));
NPC *npc = NPC::SpawnGridNodeNPC( for (auto row = results.begin(); row != results.end(); ++row) {
target->GetCleanName(), glm::vec4 node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3]));
node_position,
static_cast<uint32>(target->CastToNPC()->GetGrid()), std::vector<float> node_loc {
static_cast<uint32>(atoi(row[4])), node_position.x,
static_cast<uint32>(atoi(row[5])) node_position.y,
); node_position.z
npc->SetFlyMode(GravityBehavior::Flying); };
npc->GMMove(node_position.x, node_position.y, node_position.z, node_position.w);
// If we already have a node at this location, set the z offset
// higher from the existing one so we can see it. Adjust so if
// there is another at the same spot we adjust again.
auto search = zoffset.find(node_loc);
if (search != zoffset.end()) {
search->second = search->second + 3;
}
else {
zoffset[node_loc] = 0.0;
}
node_position.z += zoffset[node_loc];
NPC::SpawnGridNodeNPC(node_position,atoi(row[4]),zoffset[node_loc]);
} }
} }
else if (strcasecmp("delete", sep->arg[1]) == 0) { else if (strcasecmp("delete", sep->arg[1]) == 0) {
@ -2627,6 +2641,46 @@ void command_showskills(Client *c, const Seperator *sep)
c->Message(Chat::White, "Skill [%d] is at [%d] - %u", i, t->GetSkill(i), t->GetRawSkill(i)); c->Message(Chat::White, "Skill [%d] is at [%d] - %u", i, t->GetSkill(i), t->GetRawSkill(i));
} }
void command_findrace(Client *c, const Seperator *sep)
{
if (sep->arg[1][0] == 0) {
c->Message(Chat::White, "Usage: #findrace [race name]");
} else if (Seperator::IsNumber(sep->argplus[1])) {
int search_id = atoi(sep->argplus[1]);
std::string race_name = GetRaceIDName(search_id);
if (race_name != std::string("")) {
c->Message(Chat::White, "Race %d: %s", search_id, race_name.c_str());
return;
}
} else {
const char *search_criteria = sep->argplus[1];
int found_count = 0;
char race_name[64];
char search_string[65];
strn0cpy(search_string, search_criteria, sizeof(search_string));
strupr(search_string);
char *string_location;
for (int race_id = RACE_HUMAN_1; race_id <= RT_PEGASUS_3; race_id++) {
strn0cpy(race_name, GetRaceIDName(race_id), sizeof(race_name));
strupr(race_name);
string_location = strstr(race_name, search_string);
if (string_location != nullptr) {
c->Message(Chat::White, "Race %d: %s", race_id, GetRaceIDName(race_id));
found_count++;
}
if (found_count == 20) {
break;
}
}
if (found_count == 20) {
c->Message(Chat::White, "20 Races found... max reached.");
} else {
c->Message(Chat::White, "%i Race(s) found.", found_count);
}
}
}
void command_findspell(Client *c, const Seperator *sep) void command_findspell(Client *c, const Seperator *sep)
{ {
if (sep->arg[1][0] == 0) if (sep->arg[1][0] == 0)
@ -4168,10 +4222,11 @@ void command_findzone(Client *c, const Seperator *sep)
c->Message( c->Message(
Chat::White, Chat::White,
fmt::format( fmt::format(
"[{}] [{}] [{}] Version ({}) [{}]", "[{}] [{}] [{}] ID ({}) Version ({}) [{}]",
(version == 0 ? command_zone : "zone"), (version == 0 ? command_zone : "zone"),
command_gmzone, command_gmzone,
short_name, short_name,
zone_id,
version, version,
long_name long_name
).c_str() ).c_str()

View File

@ -101,6 +101,7 @@ void command_face(Client *c, const Seperator *sep);
void command_faction(Client *c, const Seperator *sep); void command_faction(Client *c, const Seperator *sep);
void command_findaliases(Client *c, const Seperator *sep); void command_findaliases(Client *c, const Seperator *sep);
void command_findnpctype(Client *c, const Seperator *sep); void command_findnpctype(Client *c, const Seperator *sep);
void command_findrace(Client *c, const Seperator *sep);
void command_findspell(Client *c, const Seperator *sep); void command_findspell(Client *c, const Seperator *sep);
void command_findzone(Client *c, const Seperator *sep); void command_findzone(Client *c, const Seperator *sep);
void command_fixmob(Client *c, const Seperator *sep); void command_fixmob(Client *c, const Seperator *sep);

View File

@ -661,6 +661,23 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(true); return(true);
} }
uint32 Client::GetDisciplineTimer(uint32 timer_id) {
pTimerType disc_timer_id = pTimerDisciplineReuseStart + timer_id;
uint32 disc_timer = 0;
if (GetPTimers().Enabled((uint32)disc_timer_id)) {
disc_timer = GetPTimers().GetRemainingTime(disc_timer_id);
}
return disc_timer;
}
void Client::ResetDisciplineTimer(uint32 timer_id) {
pTimerType disc_timer_id = pTimerDisciplineReuseStart + timer_id;
if (GetPTimers().Enabled((uint32)disc_timer_id)) {
GetPTimers().Clear(&database, (uint32)disc_timer_id);
}
SendDisciplineTimer(timer_id, 0);
}
void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration) void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration)
{ {
if (timer_id < MAX_DISCIPLINE_TIMERS) if (timer_id < MAX_DISCIPLINE_TIMERS)

View File

@ -531,6 +531,32 @@ XS(XS__zone) {
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
XS(XS__zonegroup);
XS(XS__zonegroup) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: quest::zonegroup(string zone_name)");
char *zone_name = (char *) SvPV_nolen(ST(0));
quest_manager.ZoneGroup(zone_name);
XSRETURN_EMPTY;
}
XS(XS__zoneraid);
XS(XS__zoneraid) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: quest::zoneraid(string zone_name)");
char *zone_name = (char *) SvPV_nolen(ST(0));
quest_manager.ZoneRaid(zone_name);
XSRETURN_EMPTY;
}
XS(XS__settimer); XS(XS__settimer);
XS(XS__settimer) { XS(XS__settimer) {
dXSARGS; dXSARGS;
@ -1524,12 +1550,12 @@ XS(XS__addldonpoints) {
if (items != 2) if (items != 2)
Perl_croak(aTHX_ "Usage: quest::addldonpoints(int points, int theme_id)"); Perl_croak(aTHX_ "Usage: quest::addldonpoints(int points, int theme_id)");
long points = (long) SvIV(ST(0)); long points = (long)SvIV(ST(0));
unsigned long theme_id = (unsigned long) SvUV(ST(1)); unsigned long theme_id = (unsigned long)SvUV(ST(1));
quest_manager.addldonpoints(points, theme_id); quest_manager.addldonpoints(points, theme_id);
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
XS(XS__addldonwin); XS(XS__addldonwin);
@ -1538,8 +1564,8 @@ XS(XS__addldonwin) {
if (items != 2) if (items != 2)
Perl_croak(aTHX_ "Usage: quest::addldonwin(int wins, int theme_id)"); Perl_croak(aTHX_ "Usage: quest::addldonwin(int wins, int theme_id)");
long wins = (long) SvIV(ST(0)); long wins = (long)SvIV(ST(0));
unsigned long theme_id = (unsigned long) SvUV(ST(1)); unsigned long theme_id = (unsigned long)SvUV(ST(1));
quest_manager.addldonwin(wins, theme_id); quest_manager.addldonwin(wins, theme_id);
@ -1552,8 +1578,8 @@ XS(XS__addldonloss) {
if (items != 2) if (items != 2)
Perl_croak(aTHX_ "Usage: quest::addldonloss(int losses, int theme_id)"); Perl_croak(aTHX_ "Usage: quest::addldonloss(int losses, int theme_id)");
long losses = (long) SvIV(ST(0)); long losses = (long)SvIV(ST(0));
unsigned long theme_id = (unsigned long) SvUV(ST(1)); unsigned long theme_id = (unsigned long)SvUV(ST(1));
quest_manager.addldonloss(losses, theme_id); quest_manager.addldonloss(losses, theme_id);
@ -1566,7 +1592,7 @@ XS(XS__setnexthpevent) {
if (items != 1) if (items != 1)
Perl_croak(aTHX_ "Usage: quest::setnexthpevent(int at_mob_percentage)"); Perl_croak(aTHX_ "Usage: quest::setnexthpevent(int at_mob_percentage)");
int at = (int) SvIV(ST(0)); int at = (int)SvIV(ST(0));
quest_manager.setnexthpevent(at); quest_manager.setnexthpevent(at);
@ -1579,7 +1605,7 @@ XS(XS__setnextinchpevent) {
if (items != 1) if (items != 1)
Perl_croak(aTHX_ "Usage: quest::setnextinchpevent(int at_mob_percentage)"); Perl_croak(aTHX_ "Usage: quest::setnextinchpevent(int at_mob_percentage)");
int at = (int) SvIV(ST(0)); int at = (int)SvIV(ST(0));
quest_manager.setnextinchpevent(at); quest_manager.setnextinchpevent(at);
@ -1592,7 +1618,7 @@ XS(XS__sethp) {
if (items != 1) if (items != 1)
Perl_croak(aTHX_ "Usage: quest::sethp(int mob_health_percentage [0-100])"); Perl_croak(aTHX_ "Usage: quest::sethp(int mob_health_percentage [0-100])");
int hpperc = (int) SvIV(ST(0)); int hpperc = (int)SvIV(ST(0));
quest_manager.sethp(hpperc); quest_manager.sethp(hpperc);
@ -1605,14 +1631,21 @@ XS(XS__respawn) {
if (items != 2) if (items != 2)
Perl_croak(aTHX_ "Usage: quest::respawn(int npc_type_id, int grid_id)"); Perl_croak(aTHX_ "Usage: quest::respawn(int npc_type_id, int grid_id)");
int npc_type_id = (int) SvIV(ST(0)); int npc_type_id = (int)SvIV(ST(0));
int grid_id = (int) SvIV(ST(1)); int grid_id = (int)SvIV(ST(1));
quest_manager.respawn(npc_type_id, grid_id); quest_manager.respawn(npc_type_id, grid_id);
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
//64 bit windows seems to optimize something poorly here causing access violations.
//If you don't do anything with index before passing it to perl it gets optimized out
//Disabling optimization right now for msvc on this function is the best solution.
#ifdef _MSC_VER
#pragma optimize( "", off )
#endif
XS(XS__ChooseRandom); XS(XS__ChooseRandom);
XS(XS__ChooseRandom) { XS(XS__ChooseRandom) {
dXSARGS; dXSARGS;
@ -1621,7 +1654,7 @@ XS(XS__ChooseRandom) {
dXSTARG; dXSTARG;
int index = zone->random.Int(0, items - 1); int index = zone->random.Int(0, items - 1);
SV *RETVAL = ST(index); SV* RETVAL = ST(index);
XSprePUSH; XSprePUSH;
PUSHs(RETVAL); PUSHs(RETVAL);
@ -1629,6 +1662,10 @@ XS(XS__ChooseRandom) {
XSRETURN(1); //return 1 element from the stack (ST(0)) XSRETURN(1); //return 1 element from the stack (ST(0))
} }
#ifdef _MSC_VER
#pragma optimize( "", on )
#endif
XS(XS__set_proximity); XS(XS__set_proximity);
XS(XS__set_proximity) { XS(XS__set_proximity) {
dXSARGS; dXSARGS;
@ -3705,6 +3742,82 @@ XS(XS__GetTimeSeconds) {
XSRETURN_UV(seconds); XSRETURN_UV(seconds);
} }
XS(XS__crosszoneassigntaskbycharid);
XS(XS__crosszoneassigntaskbycharid) {
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbycharid(int character_id, uint32 task_id, [bool enforce_level_requirement = false])");
{
int character_id = (int) SvIV(ST(0));
uint32 task_id = (uint32) SvIV(ST(1));
bool enforce_level_requirement = false;
if (items == 3) {
enforce_level_requirement = (bool) SvTRUE(ST(2));
}
quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id, enforce_level_requirement);
}
XSRETURN_EMPTY;
}
XS(XS__crosszoneassigntaskbygroupid);
XS(XS__crosszoneassigntaskbygroupid) {
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbygroupid(int group_id, uint32 task_id, [bool enforce_level_requirement = false])");
{
int group_id = (int) SvIV(ST(0));
uint32 task_id = (uint32) SvIV(ST(1));
bool enforce_level_requirement = false;
if (items == 3) {
enforce_level_requirement = (bool) SvTRUE(ST(2));
}
quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id, enforce_level_requirement);
}
XSRETURN_EMPTY;
}
XS(XS__crosszoneassigntaskbyraidid);
XS(XS__crosszoneassigntaskbyraidid) {
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbyraidid(int raid_id, uint32 task_id, [bool enforce_level_requirement = false])");\
{
int raid_id = (int) SvIV(ST(0));
uint32 task_id = (uint32) SvIV(ST(1));
bool enforce_level_requirement = false;
if (items == 3) {
enforce_level_requirement = (bool) SvTRUE(ST(2));
}
quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id, enforce_level_requirement);
}
XSRETURN_EMPTY;
}
XS(XS__crosszoneassigntaskbyguildid);
XS(XS__crosszoneassigntaskbyguildid) {
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbyguildid(int guild_id, uint32 task_id, [bool enforce_level_requirement = false])");
{
int guild_id = (int) SvIV(ST(0));
uint32 task_id = (uint32) SvIV(ST(1));
bool enforce_level_requirement = false;
if (items == 3) {
enforce_level_requirement = (bool) SvTRUE(ST(2));
}
quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id, enforce_level_requirement);
}
XSRETURN_EMPTY;
}
XS(XS__crosszonesignalclientbycharid); XS(XS__crosszonesignalclientbycharid);
XS(XS__crosszonesignalclientbycharid) { XS(XS__crosszonesignalclientbycharid) {
dXSARGS; dXSARGS;
@ -5006,6 +5119,10 @@ EXTERN_C XS(boot_quest) {
newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file); newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file);
newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file); newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file);
newXS(strcpy(buf, "createguild"), XS__createguild, file); newXS(strcpy(buf, "createguild"), XS__createguild, file);
newXS(strcpy(buf, "crosszoneassigntaskbycharid"), XS__crosszoneassigntaskbycharid, file);
newXS(strcpy(buf, "crosszoneassigntaskbygroupid"), XS__crosszoneassigntaskbygroupid, file);
newXS(strcpy(buf, "crosszoneassigntaskbyraidid"), XS__crosszoneassigntaskbyraidid, file);
newXS(strcpy(buf, "crosszoneassigntaskbyguildid"), XS__crosszoneassigntaskbyguildid, file);
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file); newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
newXS(strcpy(buf, "crosszonemessageplayerbygroupid"), XS__crosszonemessageplayerbygroupid, file); newXS(strcpy(buf, "crosszonemessageplayerbygroupid"), XS__crosszonemessageplayerbygroupid, file);
newXS(strcpy(buf, "crosszonemessageplayerbyraidid"), XS__crosszonemessageplayerbyraidid, file); newXS(strcpy(buf, "crosszonemessageplayerbyraidid"), XS__crosszonemessageplayerbyraidid, file);
@ -5186,6 +5303,8 @@ EXTERN_C XS(boot_quest) {
newXS(strcpy(buf, "write"), XS__write, file); newXS(strcpy(buf, "write"), XS__write, file);
newXS(strcpy(buf, "ze"), XS__ze, file); newXS(strcpy(buf, "ze"), XS__ze, file);
newXS(strcpy(buf, "zone"), XS__zone, file); newXS(strcpy(buf, "zone"), XS__zone, file);
newXS(strcpy(buf, "zonegroup"), XS__zonegroup, file);
newXS(strcpy(buf, "zoneraid"), XS__zoneraid, file);
/** /**
* Expansions * Expansions

View File

@ -2694,7 +2694,11 @@ void EntityList::RemoveAuraFromMobs(Mob *aura)
* @param close_mobs * @param close_mobs
* @param scanning_mob * @param scanning_mob
*/ */
void EntityList::ScanCloseMobs(std::unordered_map<uint16, Mob *> &close_mobs, Mob *scanning_mob) void EntityList::ScanCloseMobs(
std::unordered_map<uint16, Mob *> &close_mobs,
Mob *scanning_mob,
bool add_self_to_other_lists
)
{ {
float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance); float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance);
@ -2714,9 +2718,17 @@ void EntityList::ScanCloseMobs(std::unordered_map<uint16, Mob *> &close_mobs, Mo
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition()); float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range) { if (distance <= scan_range) {
close_mobs.insert(std::pair<uint16, Mob *>(mob->GetID(), mob)); 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) { else if (mob->GetAggroRange() >= scan_range) {
close_mobs.insert(std::pair<uint16, Mob *>(mob->GetID(), mob)); 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));
}
} }
} }

View File

@ -523,7 +523,11 @@ public:
void RefreshAutoXTargets(Client *c); void RefreshAutoXTargets(Client *c);
void RefreshClientXTargets(Client *c); void RefreshClientXTargets(Client *c);
void SendAlternateAdvancementStats(); void SendAlternateAdvancementStats();
void ScanCloseMobs(std::unordered_map<uint16, Mob *> &close_mobs, Mob *scanning_mob); void ScanCloseMobs(
std::unordered_map<uint16, Mob *> &close_mobs,
Mob *scanning_mob,
bool add_self_to_other_lists = false
);
void GetTrapInfo(Client* client); void GetTrapInfo(Client* client);
bool IsTrapGroupSpawned(uint32 trap_id, uint8 group); bool IsTrapGroupSpawned(uint32 trap_id, uint8 group);

View File

@ -325,6 +325,21 @@ void Lua_Client::MovePCInstance(int zone, int instance, float x, float y, float
self->MovePC(zone, instance, x, y, z, heading); self->MovePC(zone, instance, x, y, z, heading);
} }
void Lua_Client::MoveZone(const char *zone_short_name) {
Lua_Safe_Call_Void();
self->MoveZone(zone_short_name);
}
void Lua_Client::MoveZoneGroup(const char *zone_short_name) {
Lua_Safe_Call_Void();
self->MoveZoneGroup(zone_short_name);
}
void Lua_Client::MoveZoneRaid(const char *zone_short_name) {
Lua_Safe_Call_Void();
self->MoveZoneRaid(zone_short_name);
}
void Lua_Client::ChangeLastName(const char *in) { void Lua_Client::ChangeLastName(const char *in) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
self->ChangeLastName(in); self->ChangeLastName(in);
@ -845,6 +860,16 @@ void Lua_Client::ResetTrade() {
self->ResetTrade(); self->ResetTrade();
} }
uint32 Lua_Client::GetDisciplineTimer(uint32 timer_id) {
Lua_Safe_Call_Int();
return self->GetDisciplineTimer(timer_id);
}
void Lua_Client::ResetDisciplineTimer(uint32 timer_id) {
Lua_Safe_Call_Void();
self->ResetDisciplineTimer(timer_id);
}
bool Lua_Client::UseDiscipline(int spell_id, int target_id) { bool Lua_Client::UseDiscipline(int spell_id, int target_id) {
Lua_Safe_Call_Bool(); Lua_Safe_Call_Bool();
return self->UseDiscipline(spell_id, target_id); return self->UseDiscipline(spell_id, target_id);
@ -1648,6 +1673,9 @@ luabind::scope lua_register_client() {
.def("SetSecondaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetSecondaryWeaponOrnamentation) .def("SetSecondaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetSecondaryWeaponOrnamentation)
.def("MovePC", (void(Lua_Client::*)(int,float,float,float,float))&Lua_Client::MovePC) .def("MovePC", (void(Lua_Client::*)(int,float,float,float,float))&Lua_Client::MovePC)
.def("MovePCInstance", (void(Lua_Client::*)(int,int,float,float,float,float))&Lua_Client::MovePCInstance) .def("MovePCInstance", (void(Lua_Client::*)(int,int,float,float,float,float))&Lua_Client::MovePCInstance)
.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("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName) .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("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) .def("SetFactionLevel", (void(Lua_Client::*)(uint32,uint32,int,int,int))&Lua_Client::SetFactionLevel)
@ -1752,6 +1780,8 @@ luabind::scope lua_register_client() {
.def("ForageItem", (void(Lua_Client::*)(bool))&Lua_Client::ForageItem) .def("ForageItem", (void(Lua_Client::*)(bool))&Lua_Client::ForageItem)
.def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod) .def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod)
.def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade) .def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade)
.def("GetDisciplineTimer", (uint32(Lua_Client::*)(uint32))&Lua_Client::GetDisciplineTimer)
.def("ResetDisciplineTimer", (void(Lua_Client::*)(uint32))&Lua_Client::ResetDisciplineTimer)
.def("UseDiscipline", (bool(Lua_Client::*)(int,int))&Lua_Client::UseDiscipline) .def("UseDiscipline", (bool(Lua_Client::*)(int,int))&Lua_Client::UseDiscipline)
.def("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel) .def("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel)
.def("SetZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::SetZoneFlag) .def("SetZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::SetZoneFlag)

View File

@ -91,6 +91,9 @@ public:
uint32 GetBindZoneID(int index); uint32 GetBindZoneID(int index);
void MovePC(int zone, float x, float y, float z, float heading); void MovePC(int zone, float x, float y, float z, float heading);
void MovePCInstance(int zone, int instance, float x, float y, float z, float heading); void MovePCInstance(int zone, int instance, float x, float y, float z, float heading);
void MoveZone(const char *zone_short_name);
void MoveZoneGroup(const char *zone_short_name);
void MoveZoneRaid(const char *zone_short_name);
void ChangeLastName(const char *in); void ChangeLastName(const char *in);
int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc); 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); void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity);
@ -196,6 +199,8 @@ public:
void ForageItem(bool guarantee); void ForageItem(bool guarantee);
float CalcPriceMod(Lua_Mob other, bool reverse); float CalcPriceMod(Lua_Mob other, bool reverse);
void ResetTrade(); void ResetTrade();
uint32 GetDisciplineTimer(uint32 timer_id);
void ResetDisciplineTimer(uint32 timer_id);
bool UseDiscipline(int spell_id, int target_id); bool UseDiscipline(int spell_id, int target_id);
int GetCharacterFactionLevel(int faction_id); int GetCharacterFactionLevel(int faction_id);
void SetZoneFlag(int zone_id); void SetZoneFlag(int zone_id);

View File

@ -1023,6 +1023,38 @@ void lua_send_mail(const char *to, const char *from, const char *subject, const
quest_manager.SendMail(to, from, subject, message); quest_manager.SendMail(to, from, subject, message);
} }
void lua_cross_zone_assign_task_by_char_id(int character_id, uint32 task_id) {
quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id);
}
void lua_cross_zone_assign_task_by_char_id(int character_id, uint32 task_id, bool enforce_level_requirement) {
quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id, enforce_level_requirement);
}
void lua_cross_zone_assign_task_by_group_id(int group_id, uint32 task_id) {
quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id);
}
void lua_cross_zone_assign_task_by_group_id(int group_id, uint32 task_id, bool enforce_level_requirement) {
quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id, enforce_level_requirement);
}
void lua_cross_zone_assign_task_by_raid_id(int raid_id, uint32 task_id) {
quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id);
}
void lua_cross_zone_assign_task_by_raid_id(int raid_id, uint32 task_id, bool enforce_level_requirement) {
quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id, enforce_level_requirement);
}
void lua_cross_zone_assign_task_by_guild_id(int guild_id, uint32 task_id) {
quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id);
}
void lua_cross_zone_assign_task_by_guild_id(int guild_id, uint32 task_id, bool enforce_level_requirement) {
quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id, enforce_level_requirement);
}
void lua_cross_zone_signal_client_by_char_id(uint32 player_id, int signal) { void lua_cross_zone_signal_client_by_char_id(uint32 player_id, int signal) {
quest_manager.CrossZoneSignalPlayerByCharID(player_id, signal); quest_manager.CrossZoneSignalPlayerByCharID(player_id, signal);
} }
@ -1147,6 +1179,18 @@ Lua_EntityList lua_get_entity_list() {
return Lua_EntityList(&entity_list); return Lua_EntityList(&entity_list);
} }
void lua_zone(const char* zone_name) {
quest_manager.Zone(zone_name);
}
void lua_zone_group(const char* zone_name) {
quest_manager.ZoneGroup(zone_name);
}
void lua_zone_raid(const char* zone_name) {
quest_manager.ZoneRaid(zone_name);
}
int lua_get_zone_id() { int lua_get_zone_id() {
if(!zone) if(!zone)
return 0; return 0;
@ -2103,6 +2147,14 @@ luabind::scope lua_register_general() {
luabind::def("wear_change", &lua_wear_change), luabind::def("wear_change", &lua_wear_change),
luabind::def("voice_tell", &lua_voice_tell), luabind::def("voice_tell", &lua_voice_tell),
luabind::def("send_mail", &lua_send_mail), luabind::def("send_mail", &lua_send_mail),
luabind::def("cross_zone_assign_task_by_char_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_char_id),
luabind::def("cross_zone_assign_task_by_char_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_char_id),
luabind::def("cross_zone_assign_task_by_group_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_group_id),
luabind::def("cross_zone_assign_task_by_group_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_group_id),
luabind::def("cross_zone_assign_task_by_raid_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_raid_id),
luabind::def("cross_zone_assign_task_by_raid_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_raid_id),
luabind::def("cross_zone_assign_task_by_guild_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_guild_id),
luabind::def("cross_zone_assign_task_by_guild_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_guild_id),
luabind::def("cross_zone_signal_client_by_char_id", &lua_cross_zone_signal_client_by_char_id), luabind::def("cross_zone_signal_client_by_char_id", &lua_cross_zone_signal_client_by_char_id),
luabind::def("cross_zone_signal_client_by_group_id", &lua_cross_zone_signal_client_by_group_id), luabind::def("cross_zone_signal_client_by_group_id", &lua_cross_zone_signal_client_by_group_id),
luabind::def("cross_zone_signal_client_by_raid_id", &lua_cross_zone_signal_client_by_raid_id), luabind::def("cross_zone_signal_client_by_raid_id", &lua_cross_zone_signal_client_by_raid_id),
@ -2122,6 +2174,9 @@ luabind::scope lua_register_general() {
luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC))&lua_get_qglobals), luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC))&lua_get_qglobals),
luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*))&lua_get_qglobals), luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*))&lua_get_qglobals),
luabind::def("get_entity_list", &lua_get_entity_list), luabind::def("get_entity_list", &lua_get_entity_list),
luabind::def("zone", &lua_zone),
luabind::def("zone_group", &lua_zone_group),
luabind::def("zone_raid", &lua_zone_raid),
luabind::def("get_zone_id", &lua_get_zone_id), luabind::def("get_zone_id", &lua_get_zone_id),
luabind::def("get_zone_long_name", &lua_get_zone_long_name), luabind::def("get_zone_long_name", &lua_get_zone_long_name),
luabind::def("get_zone_short_name", &lua_get_zone_short_name), luabind::def("get_zone_short_name", &lua_get_zone_short_name),

View File

@ -115,7 +115,7 @@ Mob::Mob(
tmHidden(-1), tmHidden(-1),
mitigation_ac(0), mitigation_ac(0),
m_specialattacks(eSpecialAttacks::None), m_specialattacks(eSpecialAttacks::None),
attack_anim_timer(1000), attack_anim_timer(500),
position_update_melee_push_timer(500), position_update_melee_push_timer(500),
hate_list_cleanup_timer(6000), hate_list_cleanup_timer(6000),
mob_scan_close(6000), mob_scan_close(6000),
@ -1645,15 +1645,17 @@ void Mob::ShowStats(Client* client)
} }
} }
void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter) { void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter)
if (!attack_anim_timer.Check()) {
if (!attack_anim_timer.Check()) {
return; return;
}
auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct));
Animation_Struct* anim = (Animation_Struct*)outapp->pBuffer; auto *anim = (Animation_Struct *) outapp->pBuffer;
anim->spawnid = GetID(); anim->spawnid = GetID();
if(type == 0){ if (type == 0) {
anim->action = animnum; anim->action = animnum;
anim->speed = 10; anim->speed = 10;
} }

View File

@ -1319,7 +1319,10 @@ void Mob::AI_Process() {
FaceTarget(); FaceTarget();
} }
} }
else if (AI_movement_timer->Check() && target) { // mob/npc waits until call for help complete, others can move
else if (AI_movement_timer->Check() && target &&
(GetOwnerID() || IsBot() ||
CastToNPC()->GetCombatEvent())) {
if (!IsRooted()) { if (!IsRooted()) {
LogAI("Pursuing [{}] while engaged", target->GetName()); LogAI("Pursuing [{}] while engaged", target->GetName());
RunTo(target->GetX(), target->GetY(), target->GetZ()); RunTo(target->GetX(), target->GetY(), target->GetZ());

View File

@ -1068,12 +1068,18 @@ bool NPC::SpawnZoneController()
return true; return true;
} }
NPC * NPC::SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 grid_id, uint32 grid_number, uint32 pause) { void NPC::SpawnGridNodeNPC(const glm::vec4 &position, int32 grid_number, int32 zoffset) {
auto npc_type = new NPCType; auto npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType)); memset(npc_type, 0, sizeof(NPCType));
sprintf(npc_type->name, "%u_%u", grid_id, grid_number); std::string str_zoffset = numberToWords(zoffset);
sprintf(npc_type->lastname, "Number: %u Grid: %u Pause: %u", grid_number, grid_id, pause); std::string str_number = numberToWords(grid_number);
strcpy(npc_type->name, str_number.c_str());
if (zoffset != 0) {
strcat(npc_type->name, "(Stacked)");
}
npc_type->current_hp = 4000000; npc_type->current_hp = 4000000;
npc_type->max_hp = 4000000; npc_type->max_hp = 4000000;
@ -1095,11 +1101,12 @@ NPC * NPC::SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32
auto node_position = glm::vec4(position.x, position.y, position.z, position.w); auto node_position = glm::vec4(position.x, position.y, position.z, position.w);
auto npc = new NPC(npc_type, nullptr, node_position, GravityBehavior::Flying); auto npc = new NPC(npc_type, nullptr, node_position, GravityBehavior::Flying);
npc->name[strlen(npc->name)-3] = (char) NULL;
npc->GiveNPCTypeData(npc_type); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true); entity_list.AddNPC(npc);
return npc;
} }
NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position) { NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position) {

View File

@ -113,7 +113,7 @@ public:
virtual ~NPC(); virtual ~NPC();
static NPC *SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position); static NPC *SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 &position);
static NPC *SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 grid_id, uint32 grid_number, uint32 pause); static void SpawnGridNodeNPC(const glm::vec4 &position, int32 grid_number, int32 zoffset);
//abstract virtual function implementations requird by base abstract class //abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill); virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill);

View File

@ -1319,6 +1319,132 @@ XS(XS_Client_MovePCInstance) {
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
XS(XS_Client_MoveZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZone) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZone(THIS, string zone_short_name)");
{
Client *THIS;
const char *zone_short_name = (const char *) SvPV_nolen(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->MoveZone(zone_short_name);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process an Unknown type reference");
}
Perl_croak(aTHX_ "THIS is not of type Client");
}
}
XSRETURN_EMPTY;
}
XS(XS_Client_MoveZoneGroup); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZoneGroup) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZoneGroup(THIS, string zone_short_name)");
{
Client *THIS;
const char *zone_short_name = (const char *) SvPV_nolen(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->MoveZoneGroup(zone_short_name);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process an Unknown type reference");
}
Perl_croak(aTHX_ "THIS is not of type Client");
}
}
XSRETURN_EMPTY;
}
XS(XS_Client_MoveZoneRaid); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MoveZoneRaid) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::MoveZoneRaid(THIS, string zone_short_name)");
{
Client *THIS;
const char *zone_short_name = (const char *) SvPV_nolen(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->MoveZoneRaid(zone_short_name);
} else {
if (THIS->IsMerc()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type Merc reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type NPC reference");
}
else {
LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) 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); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_ChangeLastName) { XS(XS_Client_ChangeLastName) {
dXSARGS; dXSARGS;
@ -3670,6 +3796,54 @@ XS(XS_Client_UseDiscipline) {
XSRETURN(1); XSRETURN(1);
} }
XS(XS_Client_GetDisciplineTimer); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_GetDisciplineTimer) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::GetDisciplineTimer(THIS, uint32 timer_id)");
{
Client *THIS;
uint32 RETVAL;
dXSTARG;
uint32 timer_id = (uint32) 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.");
RETVAL = THIS->GetDisciplineTimer(timer_id);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Client_ResetDisciplineTimer); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_ResetDisciplineTimer) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::ResetDisciplineTimer(THIS, uint32 timer_id)");
{
Client *THIS;
uint32 timer_id = (uint32) 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.");
THIS->ResetDisciplineTimer(timer_id);
}
XSRETURN_EMPTY;
}
XS(XS_Client_GetCharacterFactionLevel); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_GetCharacterFactionLevel); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_GetCharacterFactionLevel) { XS(XS_Client_GetCharacterFactionLevel) {
dXSARGS; dXSARGS;
@ -6451,6 +6625,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$");
newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$");
newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$"); newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$");
newXSproto(strcpy(buf, "GetDisciplineTimer"), XS_Client_GetDisciplineTimer, file, "$$");
newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$");
newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$");
newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$");
@ -6537,6 +6712,9 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$");
newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$");
newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$");
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, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$");
newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$");
newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$");
@ -6548,6 +6726,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$");
newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$");
newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$");
newXSproto(strcpy(buf, "ResetDisciplineTimer"), XS_Client_ResetDisciplineTimer, file, "$$");
newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$");
newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$");
newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$"); newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$");

View File

@ -2479,7 +2479,7 @@ XS(XS_NPC_SetSimpleRoamBox) {
XS(XS_NPC_RecalculateSkills); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_RecalculateSkills); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_RecalculateSkills) { XS(XS_NPC_RecalculateSkills) {
dXSARGS; dXSARGS;
if (items != 2) if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::RecalculateSkills(THIS)"); Perl_croak(aTHX_ "Usage: NPC::RecalculateSkills(THIS)");
{ {
NPC *THIS; NPC *THIS;

View File

@ -408,6 +408,84 @@ void QuestManager::Zone(const char *zone_name) {
} }
} }
void QuestManager::ZoneGroup(const char *zone_name) {
QuestManagerCurrentQuestVars();
if (initiator && initiator->IsClient()) {
if (!initiator->GetGroup()) {
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.GetZoneID(zone_name);
ztz->admin = initiator->Admin();
strcpy(ztz->name, initiator->GetName());
ztz->guild_id = initiator->GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
} else {
auto client_group = initiator->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();
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.GetZoneID(zone_name);
ztz->admin = group_member->Admin();
strcpy(ztz->name, group_member->GetName());
ztz->guild_id = group_member->GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
}
}
}
void QuestManager::ZoneRaid(const char *zone_name) {
QuestManagerCurrentQuestVars();
if (initiator && initiator->IsClient()) {
if (!initiator->GetRaid()) {
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.GetZoneID(zone_name);
ztz->admin = initiator->Admin();
strcpy(ztz->name, initiator->GetName());
ztz->guild_id = initiator->GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
} else {
auto client_raid = initiator->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();
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.GetZoneID(zone_name);
ztz->admin = raid_member->Admin();
strcpy(ztz->name, raid_member->GetName());
ztz->guild_id = raid_member->GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
}
}
}
void QuestManager::settimer(const char *timer_name, int seconds) { void QuestManager::settimer(const char *timer_name, int seconds) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
@ -3194,6 +3272,62 @@ const char* QuestManager::GetZoneLongName(const char *zone) {
return ln.c_str(); return ln.c_str();
} }
void QuestManager::CrossZoneAssignTaskByCharID(int character_id, uint32 task_id, bool enforce_level_requirement) {
QuestManagerCurrentQuestVars();
if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) {
auto pack = new ServerPacket(ServerOP_CZTaskAssign, sizeof(CZTaskAssign_Struct));
CZTaskAssign_Struct* CZTA = (CZTaskAssign_Struct*)pack->pBuffer;
CZTA->npc_entity_id = owner->GetID();
CZTA->character_id = character_id;
CZTA->task_id = task_id;
CZTA->enforce_level_requirement = enforce_level_requirement;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
void QuestManager::CrossZoneAssignTaskByGroupID(int group_id, uint32 task_id, bool enforce_level_requirement) {
QuestManagerCurrentQuestVars();
if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) {
auto pack = new ServerPacket(ServerOP_CZTaskAssignGroup, sizeof(CZTaskAssignGroup_Struct));
CZTaskAssignGroup_Struct* CZTA = (CZTaskAssignGroup_Struct*)pack->pBuffer;
CZTA->npc_entity_id = owner->GetID();
CZTA->group_id = group_id;
CZTA->task_id = task_id;
CZTA->enforce_level_requirement = enforce_level_requirement;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
void QuestManager::CrossZoneAssignTaskByRaidID(int raid_id, uint32 task_id, bool enforce_level_requirement) {
QuestManagerCurrentQuestVars();
if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) {
auto pack = new ServerPacket(ServerOP_CZTaskAssignRaid, sizeof(CZTaskAssignRaid_Struct));
CZTaskAssignRaid_Struct* CZTA = (CZTaskAssignRaid_Struct*) pack->pBuffer;
CZTA->npc_entity_id = owner->GetID();
CZTA->raid_id = raid_id;
CZTA->task_id = task_id;
CZTA->enforce_level_requirement = enforce_level_requirement;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
void QuestManager::CrossZoneAssignTaskByGuildID(int guild_id, uint32 task_id, bool enforce_level_requirement) {
QuestManagerCurrentQuestVars();
if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) {
auto pack = new ServerPacket(ServerOP_CZTaskAssignGuild, sizeof(CZTaskAssignGuild_Struct));
CZTaskAssignGuild_Struct* CZTA = (CZTaskAssignGuild_Struct*) pack->pBuffer;
CZTA->npc_entity_id = owner->GetID();
CZTA->guild_id = guild_id;
CZTA->task_id = task_id;
CZTA->enforce_level_requirement = enforce_level_requirement;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
void QuestManager::CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data){ void QuestManager::CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data){
auto pack = new ServerPacket(ServerOP_CZSignalNPC, sizeof(CZNPCSignal_Struct)); auto pack = new ServerPacket(ServerOP_CZSignalNPC, sizeof(CZNPCSignal_Struct));
CZNPCSignal_Struct* CZSN = (CZNPCSignal_Struct*)pack->pBuffer; CZNPCSignal_Struct* CZSN = (CZNPCSignal_Struct*)pack->pBuffer;

View File

@ -77,6 +77,8 @@ public:
void selfcast(int spell_id); void selfcast(int spell_id);
void addloot(int item_id, int charges = 0, bool equipitem = true, int aug1 = 0, int aug2 = 0, int aug3 = 0, int aug4 = 0, int aug5 = 0, int aug6 = 0); void addloot(int item_id, int charges = 0, bool equipitem = true, int aug1 = 0, int aug2 = 0, int aug3 = 0, int aug4 = 0, int aug5 = 0, int aug6 = 0);
void Zone(const char *zone_name); void Zone(const char *zone_name);
void ZoneGroup(const char *zone_name);
void ZoneRaid(const char *zone_name);
void settimer(const char *timer_name, int seconds); void settimer(const char *timer_name, int seconds);
void settimerMS(const char *timer_name, int milliseconds); void settimerMS(const char *timer_name, int milliseconds);
void settimerMS(const char *timer_name, int milliseconds, EQ::ItemInstance *inst); void settimerMS(const char *timer_name, int milliseconds, EQ::ItemInstance *inst);
@ -278,6 +280,10 @@ public:
uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size); uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size);
int32 GetZoneID(const char *zone); int32 GetZoneID(const char *zone);
const char *GetZoneLongName(const char *zone); const char *GetZoneLongName(const char *zone);
void CrossZoneAssignTaskByCharID(int character_id, uint32 task_id, bool enforce_level_requirement = false);
void CrossZoneAssignTaskByGroupID(int group_id, uint32 task_id, bool enforce_level_requirement = false);
void CrossZoneAssignTaskByRaidID(int raid_id, uint32 task_id, bool enforce_level_requirement = false);
void CrossZoneAssignTaskByGuildID(int guild_id, uint32 task_id, bool enforce_level_requirement = false);
void CrossZoneSignalPlayerByCharID(int charid, uint32 data); void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
void CrossZoneSignalPlayerByGroupID(int group_id, uint32 data); void CrossZoneSignalPlayerByGroupID(int group_id, uint32 data);
void CrossZoneSignalPlayerByRaidID(int raid_id, uint32 data); void CrossZoneSignalPlayerByRaidID(int raid_id, uint32 data);

View File

@ -192,7 +192,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
DoAttack(who, my_hit); DoAttack(who, my_hit);
who->AddToHateList(this, hate, 0, false); who->AddToHateList(this, hate, 0);
if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skill && if (my_hit.damage_done > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skill &&
IsValidSpell(aabonuses.SkillAttackProc[2])) { IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f; float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
@ -870,7 +870,7 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, co
} }
if (IsClient() && !CastToClient()->GetFeigned()) if (IsClient() && !CastToClient()->GetFeigned())
other->AddToHateList(this, hate, 0, false); other->AddToHateList(this, hate, 0);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillArchery); other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillArchery);
@ -1200,9 +1200,9 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha
if (TotalDmg > 0) { if (TotalDmg > 0) {
TotalDmg += TotalDmg * damage_mod / 100; TotalDmg += TotalDmg * damage_mod / 100;
other->AddToHateList(this, TotalDmg, 0, false); other->AddToHateList(this, TotalDmg, 0);
} else { } else {
other->AddToHateList(this, 0, 0, false); other->AddToHateList(this, 0, 0);
} }
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse); other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse);
@ -1384,7 +1384,7 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQ::ItemInstance *RangeWeapon, c
} }
if (IsClient() && !CastToClient()->GetFeigned()) if (IsClient() && !CastToClient()->GetFeigned())
other->AddToHateList(this, WDmg, 0, false); other->AddToHateList(this, WDmg, 0);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillThrowing); other->Damage(this, TotalDmg, SPELL_UNKNOWN, EQ::skills::SkillThrowing);
@ -2158,7 +2158,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQ::skills::Sk
CanSkillProc = false; // Disable skill procs CanSkillProc = false; // Disable skill procs
} }
other->AddToHateList(this, hate, 0, false); other->AddToHateList(this, hate, 0);
if (damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skillinuse && if (damage > 0 && aabonuses.SkillAttackProc[0] && aabonuses.SkillAttackProc[1] == skillinuse &&
IsValidSpell(aabonuses.SkillAttackProc[2])) { IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f; float chance = aabonuses.SkillAttackProc[0] / 1000.0f;

View File

@ -3310,18 +3310,13 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor
taskmanager->SendSingleActiveTaskToClient(c, *active_slot, false, true); taskmanager->SendSingleActiveTaskToClient(c, *active_slot, false, true);
c->Message(Chat::White, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str()); c->Message(Chat::White, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str());
taskmanager->SaveClientState(c, this);
std::string buf = std::to_string(TaskID); std::string buf = std::to_string(TaskID);
NPC *npc = entity_list.GetID(NPCID)->CastToNPC(); NPC *npc = entity_list.GetID(NPCID)->CastToNPC();
if(!npc) { if(npc) {
c->Message(Chat::Yellow, "Task Giver ID is %i", NPCID);
c->Message(Chat::Red, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug.");
return;
}
taskmanager->SaveClientState(c, this);
parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0); parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0);
}
} }
void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) { void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) {

View File

@ -2041,6 +2041,49 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
} }
break; break;
} }
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);
}
break;
}
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);
}
}
break;
}
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);
}
}
break;
}
case ServerOP_CZTaskAssignGuild:
{
CZTaskAssignGuild_Struct* CZTA = (CZTaskAssignGuild_Struct*)pack->pBuffer;
auto client_list = entity_list.GetClientList();
for (auto client : client_list) {
if (client.second->GuildID() > 0 && client.second->GuildID() == CZTA->guild_id) {
client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement);
}
}
break;
}
case ServerOP_WWMarquee: case ServerOP_WWMarquee:
{ {
WWMarquee_Struct* WWMS = (WWMarquee_Struct*)pack->pBuffer; WWMarquee_Struct* WWMS = (WWMarquee_Struct*)pack->pBuffer;

View File

@ -446,6 +446,48 @@ void Client::MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z,
ProcessMovePC(zoneID, instanceID, x, y, z, heading, ignorerestrictions, zm); ProcessMovePC(zoneID, instanceID, x, y, z, heading, ignorerestrictions, zm);
} }
void Client::MoveZone(const char *zone_short_name) {
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.GetZoneID(zone_short_name);
ztz->admin = Admin();
strcpy(ztz->name, GetName());
ztz->guild_id = GuildID();
ztz->ignorerestrictions = 3;
worldserver.SendPacket(pack);
safe_delete(pack);
}
void Client::MoveZoneGroup(const char *zone_short_name) {
if (!GetGroup()) {
MoveZone(zone_short_name);
} 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->MoveZone(zone_short_name);
}
}
}
}
void Client::MoveZoneRaid(const char *zone_short_name) {
if (!GetRaid()) {
MoveZone(zone_short_name);
} 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->MoveZone(zone_short_name);
}
}
}
}
void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm)
{ {