mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 16:41:29 +00:00
commit
c799267c86
@ -328,7 +328,10 @@ IF(UNIX)
|
|||||||
IF(NOT DARWIN)
|
IF(NOT DARWIN)
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
|
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
# Freebsd provides uuids in the C library
|
||||||
|
IF(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||||
|
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
||||||
|
|||||||
@ -118,6 +118,11 @@ void set_exception_handler() {
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void print_trace()
|
void print_trace()
|
||||||
{
|
{
|
||||||
auto uid = geteuid();
|
auto uid = geteuid();
|
||||||
|
|||||||
@ -515,8 +515,7 @@ void Database::BuryCorpsesInInstance(uint16 instance_id) {
|
|||||||
void Database::DeleteInstance(uint16 instance_id)
|
void Database::DeleteInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id);
|
std::string query;
|
||||||
QueryDatabase(query);
|
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
|
|||||||
@ -434,6 +434,7 @@ namespace EQEmu
|
|||||||
//uint32 Unk054;
|
//uint32 Unk054;
|
||||||
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
|
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
|
||||||
uint8 ItemType; // Item Type/Skill (itemClass* from above)
|
uint8 ItemType; // Item Type/Skill (itemClass* from above)
|
||||||
|
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
||||||
uint8 Material; // Item material type
|
uint8 Material; // Item material type
|
||||||
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
|
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
|
||||||
float SellRate; // Sell rate
|
float SellRate; // Sell rate
|
||||||
|
|||||||
@ -203,3 +203,4 @@ F(procname)
|
|||||||
F(wornname)
|
F(wornname)
|
||||||
F(focusname)
|
F(focusname)
|
||||||
F(scrollname)
|
F(scrollname)
|
||||||
|
F(subtype)
|
||||||
|
|||||||
@ -5504,6 +5504,7 @@ namespace RoF
|
|||||||
iqbs.HealAmt = item->HealAmt;
|
iqbs.HealAmt = item->HealAmt;
|
||||||
iqbs.SpellDmg = item->SpellDmg;
|
iqbs.SpellDmg = item->SpellDmg;
|
||||||
iqbs.Clairvoyance = item->Clairvoyance;
|
iqbs.Clairvoyance = item->Clairvoyance;
|
||||||
|
iqbs.SubType = item->SubType;
|
||||||
iqbs.unknown28 = 0;
|
iqbs.unknown28 = 0;
|
||||||
iqbs.unknown30 = 0;
|
iqbs.unknown30 = 0;
|
||||||
iqbs.unknown39 = 1;
|
iqbs.unknown39 = 1;
|
||||||
|
|||||||
@ -5759,6 +5759,7 @@ namespace RoF2
|
|||||||
iqbs.HealAmt = item->HealAmt;
|
iqbs.HealAmt = item->HealAmt;
|
||||||
iqbs.SpellDmg = item->SpellDmg;
|
iqbs.SpellDmg = item->SpellDmg;
|
||||||
iqbs.Clairvoyance = item->Clairvoyance;
|
iqbs.Clairvoyance = item->Clairvoyance;
|
||||||
|
iqbs.SubType = item->SubType;
|
||||||
|
|
||||||
//unknown18; //Power Source Capacity or evolve filename?
|
//unknown18; //Power Source Capacity or evolve filename?
|
||||||
//evolve_string; // Some String, but being evolution related is just a guess
|
//evolve_string; // Some String, but being evolution related is just a guess
|
||||||
|
|||||||
@ -4804,8 +4804,8 @@ struct ItemQuaternaryBodyStruct
|
|||||||
int32 HealAmt;
|
int32 HealAmt;
|
||||||
int32 SpellDmg;
|
int32 SpellDmg;
|
||||||
int32 Clairvoyance;
|
int32 Clairvoyance;
|
||||||
uint8 unknown18; //Power Source Capacity or evolve filename?
|
int32 SubType;
|
||||||
uint32 evolve_string; // Some String, but being evolution related is just a guess
|
uint8 evolve_string; // Some String, but being evolution related is just a guess
|
||||||
uint8 unknown19;
|
uint8 unknown19;
|
||||||
uint16 unknown20;
|
uint16 unknown20;
|
||||||
uint8 unknown21;
|
uint8 unknown21;
|
||||||
|
|||||||
@ -4744,8 +4744,8 @@ struct ItemQuaternaryBodyStruct
|
|||||||
int32 HealAmt;
|
int32 HealAmt;
|
||||||
int32 SpellDmg;
|
int32 SpellDmg;
|
||||||
int32 Clairvoyance;
|
int32 Clairvoyance;
|
||||||
uint8 unknown18; //Power Source Capacity or evolve filename?
|
int32 SubType;
|
||||||
uint32 evolve_string; // Some String, but being evolution related is just a guess
|
uint8 evolve_string; // Some String, but being evolution related is just a guess
|
||||||
uint8 unknown19;
|
uint8 unknown19;
|
||||||
uint32 unknown20; // Bard Stuff?
|
uint32 unknown20; // Bard Stuff?
|
||||||
//uint32 unknown21;
|
//uint32 unknown21;
|
||||||
|
|||||||
@ -4106,7 +4106,8 @@ namespace UF
|
|||||||
iqbs.HealAmt = item->HealAmt;
|
iqbs.HealAmt = item->HealAmt;
|
||||||
iqbs.SpellDmg = item->SpellDmg;
|
iqbs.SpellDmg = item->SpellDmg;
|
||||||
iqbs.Clairvoyance = item->Clairvoyance;
|
iqbs.Clairvoyance = item->Clairvoyance;
|
||||||
|
iqbs.SubType = item->SubType;
|
||||||
|
|
||||||
ob.write((const char*)&iqbs, sizeof(UF::structs::ItemQuaternaryBodyStruct));
|
ob.write((const char*)&iqbs, sizeof(UF::structs::ItemQuaternaryBodyStruct));
|
||||||
|
|
||||||
EQEmu::OutBuffer::pos_type count_pos = ob.tellp();
|
EQEmu::OutBuffer::pos_type count_pos = ob.tellp();
|
||||||
|
|||||||
@ -4215,8 +4215,8 @@ struct ItemQuaternaryBodyStruct
|
|||||||
int32 HealAmt;
|
int32 HealAmt;
|
||||||
int32 SpellDmg;
|
int32 SpellDmg;
|
||||||
int32 Clairvoyance;
|
int32 Clairvoyance;
|
||||||
uint8 unknown18; //Power Source Capacity or evolve filename?
|
int32 SubType;
|
||||||
uint32 evolve_string; // Some String, but being evolution related is just a guess
|
uint8 evolve_string; // Some String, but being evolution related is just a guess
|
||||||
uint8 unknown19;
|
uint8 unknown19;
|
||||||
uint32 unknown20; // Bard Stuff?
|
uint32 unknown20; // Bard Stuff?
|
||||||
uint32 unknown21;
|
uint32 unknown21;
|
||||||
|
|||||||
@ -24,6 +24,10 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
//I forced this object to become a singleton because it registers its
|
//I forced this object to become a singleton because it registers its
|
||||||
//signal handler for UNIX
|
//signal handler for UNIX
|
||||||
class ProcLauncher {
|
class ProcLauncher {
|
||||||
|
|||||||
@ -198,6 +198,8 @@
|
|||||||
#define ServerOP_UCSServerStatusRequest 0x4013
|
#define ServerOP_UCSServerStatusRequest 0x4013
|
||||||
#define ServerOP_UCSServerStatusReply 0x4014
|
#define ServerOP_UCSServerStatusReply 0x4014
|
||||||
#define ServerOP_HotReloadQuests 0x4015
|
#define ServerOP_HotReloadQuests 0x4015
|
||||||
|
#define ServerOP_CZSignalGroup 0x4016
|
||||||
|
#define ServerOP_CZMessageGuild 0x4021
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QueryServer
|
* QueryServer
|
||||||
@ -1167,6 +1169,11 @@ struct CZClientSignal_Struct {
|
|||||||
uint32 data;
|
uint32 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CZGroupSignal_Struct {
|
||||||
|
int group_id;
|
||||||
|
uint32 data;
|
||||||
|
};
|
||||||
|
|
||||||
struct CZNPCSignal_Struct {
|
struct CZNPCSignal_Struct {
|
||||||
uint32 npctype_id;
|
uint32 npctype_id;
|
||||||
uint32 data;
|
uint32 data;
|
||||||
@ -1334,6 +1341,12 @@ struct CZMessagePlayer_Struct {
|
|||||||
char Message[512];
|
char Message[512];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CZMessageGuild_Struct {
|
||||||
|
uint32 Type;
|
||||||
|
int GuildID;
|
||||||
|
char Message[512];
|
||||||
|
};
|
||||||
|
|
||||||
struct WWMarquee_Struct {
|
struct WWMarquee_Struct {
|
||||||
uint32 Type;
|
uint32 Type;
|
||||||
uint32 Priority;
|
uint32 Priority;
|
||||||
|
|||||||
@ -1029,6 +1029,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
|
|
||||||
item.MaxCharges = (int16)atoi(row[ItemField::maxcharges]);
|
item.MaxCharges = (int16)atoi(row[ItemField::maxcharges]);
|
||||||
item.ItemType = (uint8)atoi(row[ItemField::itemtype]);
|
item.ItemType = (uint8)atoi(row[ItemField::itemtype]);
|
||||||
|
item.SubType = atoi(row[ItemField::subtype]);
|
||||||
item.Material = (uint8)atoi(row[ItemField::material]);
|
item.Material = (uint8)atoi(row[ItemField::material]);
|
||||||
item.HerosForgeModel = (uint32)atoi(row[ItemField::herosforgemodel]);
|
item.HerosForgeModel = (uint32)atoi(row[ItemField::herosforgemodel]);
|
||||||
item.SellRate = (float)atof(row[ItemField::sellrate]);
|
item.SellRate = (float)atof(row[ItemField::sellrate]);
|
||||||
|
|||||||
@ -634,7 +634,7 @@ typedef enum {
|
|||||||
#define SE_LimitRace 412 // implemented - Limits to spells cast by a certain race (Note: not used in any known live spells)
|
#define SE_LimitRace 412 // implemented - Limits to spells cast by a certain race (Note: not used in any known live spells)
|
||||||
#define SE_FcBaseEffects 413 // implemented - Increases the power of bard songs, skill attacks, runes, bard allowed foci, damage/heal
|
#define SE_FcBaseEffects 413 // implemented - Increases the power of bard songs, skill attacks, runes, bard allowed foci, damage/heal
|
||||||
#define SE_LimitCastingSkill 414 // implemented - Limit a focus to include spells cast using a specific skill.
|
#define SE_LimitCastingSkill 414 // implemented - Limit a focus to include spells cast using a specific skill.
|
||||||
//#define SE_FFItemClass 415 // not used
|
//#define SE_FFItemClass 415 // not used - base1 matches ItemType, base2 matches SubType, -1 ignored, max is bitmask of valid slots
|
||||||
#define SE_ACv2 416 // implemented - New AC spell effect
|
#define SE_ACv2 416 // implemented - New AC spell effect
|
||||||
#define SE_ManaRegen_v2 417 // implemented - New mana regen effect
|
#define SE_ManaRegen_v2 417 // implemented - New mana regen effect
|
||||||
#define SE_SkillDamageAmount2 418 // implemented - adds skill damage directly to certain attacks
|
#define SE_SkillDamageAmount2 418 // implemented - adds skill damage directly to certain attacks
|
||||||
|
|||||||
@ -14,6 +14,10 @@
|
|||||||
#include <CoreFoundation/CFUUID.h>
|
#include <CoreFoundation/CFUUID.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <uuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char hexDigitToChar(char ch)
|
unsigned char hexDigitToChar(char ch)
|
||||||
{
|
{
|
||||||
if (ch > 47 && ch < 58)
|
if (ch > 47 && ch < 58)
|
||||||
@ -126,6 +130,15 @@ EQ::Util::UUID EQ::Util::UUID::Generate()
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
uuid_t l_id;
|
||||||
|
char l_uuid[37];
|
||||||
|
uint32_t l_ignored;
|
||||||
|
uuid_create(&l_id, &l_ignored);
|
||||||
|
uuid_to_string(&l_id, (char**) &l_uuid, &l_ignored);
|
||||||
|
return FromString(l_uuid);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Util::UUID EQ::Util::UUID::FromString(const std::string &str)
|
EQ::Util::UUID EQ::Util::UUID::FromString(const std::string &str)
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9152
|
#define CURRENT_BINARY_DATABASE_VERSION 9153
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9027
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9027
|
||||||
|
|||||||
@ -406,6 +406,7 @@
|
|||||||
9150|2020_02_06_aa_reset_on_death.sql|SHOW COLUMNS FROM `aa_ability` LIKE 'reset_on_death'|empty|
|
9150|2020_02_06_aa_reset_on_death.sql|SHOW COLUMNS FROM `aa_ability` LIKE 'reset_on_death'|empty|
|
||||||
9151|2020_03_05_npc_always_aggro.sql|SHOW COLUMNS FROM `npc_types` LIKE 'always_aggro'|empty|
|
9151|2020_03_05_npc_always_aggro.sql|SHOW COLUMNS FROM `npc_types` LIKE 'always_aggro'|empty|
|
||||||
9152|2020_03_09_convert_myisam_to_innodb.sql|SELECT * FROM db_version WHERE version >= 9152|empty|
|
9152|2020_03_09_convert_myisam_to_innodb.sql|SELECT * FROM db_version WHERE version >= 9152|empty|
|
||||||
|
9153|2020_05_09_items_subtype.sql|SHOW COLUMNS from `items` LIKE 'UNK219'|not_empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
1
utils/sql/git/required/2020_05_09_items_subtype.sql
Normal file
1
utils/sql/git/required/2020_05_09_items_subtype.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `items` CHANGE `UNK219` `subtype` int(11) not null default '0';
|
||||||
@ -1238,9 +1238,11 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
}
|
}
|
||||||
case ServerOP_CZSignalClientByName:
|
case ServerOP_CZSignalClientByName:
|
||||||
case ServerOP_CZMessagePlayer:
|
case ServerOP_CZMessagePlayer:
|
||||||
|
case ServerOP_CZMessageGuild:
|
||||||
case ServerOP_CZSignalNPC:
|
case ServerOP_CZSignalNPC:
|
||||||
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
||||||
case ServerOP_CZSignalClient:
|
case ServerOP_CZSignalClient:
|
||||||
|
case ServerOP_CZSignalGroup:
|
||||||
case ServerOP_CZSetEntityVariableByClientName:
|
case ServerOP_CZSetEntityVariableByClientName:
|
||||||
case ServerOP_WWMarquee:
|
case ServerOP_WWMarquee:
|
||||||
case ServerOP_DepopAllPlayersCorpses:
|
case ServerOP_DepopAllPlayersCorpses:
|
||||||
|
|||||||
@ -4125,7 +4125,8 @@ void command_findzone(Client *c, const Seperator *sep)
|
|||||||
*/
|
*/
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%'",
|
"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])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3721,19 +3721,37 @@ XS(XS__crosszonesignalclientbycharid) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__crosszonesignalclientbygroupid);
|
||||||
|
XS(XS__crosszonesignalclientbygroupid) {
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbygroupid(int group_id, int value)");
|
||||||
|
|
||||||
|
if (items == 2) {
|
||||||
|
int group_id = (int) SvIV(ST(0));
|
||||||
|
uint32 int_value = (uint32) SvIV(ST(1));
|
||||||
|
quest_manager.CrossZoneSignalPlayerByGroupID(group_id, int_value);
|
||||||
|
} else {
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbygroupid(int group_id, int value)");
|
||||||
|
}
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__crosszonesignalclientbyname);
|
XS(XS__crosszonesignalclientbyname);
|
||||||
XS(XS__crosszonesignalclientbyname) {
|
XS(XS__crosszonesignalclientbyname) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
|
|
||||||
if (items != 2)
|
if (items != 2)
|
||||||
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(string name, int value)");
|
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbyname(string name, int value)");
|
||||||
|
|
||||||
if (items == 2) {
|
if (items == 2) {
|
||||||
char *name = (char *) SvPV_nolen(ST(0));
|
char *name = (char *) SvPV_nolen(ST(0));
|
||||||
uint32 int_value = (uint32) SvIV(ST(1));
|
uint32 int_value = (uint32) SvIV(ST(1));
|
||||||
quest_manager.CrossZoneSignalPlayerByName(name, int_value);
|
quest_manager.CrossZoneSignalPlayerByName(name, int_value);
|
||||||
} else {
|
} else {
|
||||||
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbycharid(string name, int value)");
|
Perl_croak(aTHX_ "Usage: quest::crosszonesignalclientbyname(string name, int value)");
|
||||||
}
|
}
|
||||||
|
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
@ -3757,6 +3775,23 @@ XS(XS__crosszonemessageplayerbyname) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__crosszonemessageplayerbyguildid);
|
||||||
|
XS(XS__crosszonemessageplayerbyguildid) {
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
if (items != 3)
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::crosszonemessageplayerbyguildid(int typ, int guild_id, string message)");
|
||||||
|
|
||||||
|
if (items == 3) {
|
||||||
|
uint32 type = (uint32) SvIV(ST(0));
|
||||||
|
int guild_id = (int) SvIV(ST(1));
|
||||||
|
char *message = (char *) SvPV_nolen(ST(2));
|
||||||
|
quest_manager.CrossZoneMessagePlayerByGuildID(type, guild_id, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__enablerecipe);
|
XS(XS__enablerecipe);
|
||||||
XS(XS__enablerecipe) {
|
XS(XS__enablerecipe) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -4173,9 +4208,11 @@ EXTERN_C XS(boot_quest) {
|
|||||||
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, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
|
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
|
||||||
|
newXS(strcpy(buf, "crosszonemessageplayerbyguildid"), XS__crosszonemessageplayerbyguildid, file);
|
||||||
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
|
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
|
||||||
newXS(strcpy(buf, "crosszonesetentityvariablebyclientname"), XS__crosszonesetentityvariablebyclientname, file);
|
newXS(strcpy(buf, "crosszonesetentityvariablebyclientname"), XS__crosszonesetentityvariablebyclientname, file);
|
||||||
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
|
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
|
||||||
|
newXS(strcpy(buf, "crosszonesignalclientbygroupid"), XS__crosszonesignalclientbygroupid, file);
|
||||||
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
|
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
|
||||||
newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file);
|
newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file);
|
||||||
newXS(strcpy(buf, "worldwidemarquee"), XS__worldwidemarquee, file);
|
newXS(strcpy(buf, "worldwidemarquee"), XS__worldwidemarquee, file);
|
||||||
|
|||||||
@ -1116,6 +1116,22 @@ NPC *EntityList::GetNPCByNPCTypeID(uint32 npc_id)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NPC *EntityList::GetNPCBySpawnID(uint32 spawn_id)
|
||||||
|
{
|
||||||
|
if (spawn_id == 0 || npc_list.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = npc_list.begin();
|
||||||
|
while (it != npc_list.end()) {
|
||||||
|
if (it->second->GetSpawnGroupId() == spawn_id) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Mob *EntityList::GetMob(uint16 get_id)
|
Mob *EntityList::GetMob(uint16 get_id)
|
||||||
{
|
{
|
||||||
Entity *ent = nullptr;
|
Entity *ent = nullptr;
|
||||||
|
|||||||
@ -166,6 +166,7 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
NPC *GetNPCByNPCTypeID(uint32 npc_id);
|
NPC *GetNPCByNPCTypeID(uint32 npc_id);
|
||||||
|
NPC *GetNPCBySpawnID(uint32 spawn_id);
|
||||||
inline Merc *GetMercByID(uint16 id)
|
inline Merc *GetMercByID(uint16 id)
|
||||||
{
|
{
|
||||||
auto it = merc_list.find(id);
|
auto it = merc_list.find(id);
|
||||||
|
|||||||
@ -2913,23 +2913,33 @@ void Client::SendItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, Item
|
|||||||
if (!inst)
|
if (!inst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
if (packet_type != ItemPacketMerchant) {
|
||||||
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
||||||
return;
|
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0) {
|
||||||
}
|
LogError("Item not sent to merchant : slot [{}]", slot_id);
|
||||||
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
return;
|
||||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
}
|
||||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
}
|
||||||
return;
|
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
||||||
}
|
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||||
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
|
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0) {
|
||||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
|
LogError("Item not sent to merchant2 : slot [{}]", slot_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
}
|
||||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
|
||||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
|
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank) {
|
||||||
return;
|
LogError("Item not sent to merchant3 : slot [{}]", slot_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
||||||
|
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||||
|
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank) {
|
||||||
|
LogError("Item not sent to merchant4 : slot [{}]", slot_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize item into |-delimited string (Titanium- uses '|' delimiter .. newer clients use pure data serialization)
|
// Serialize item into |-delimited string (Titanium- uses '|' delimiter .. newer clients use pure data serialization)
|
||||||
|
|||||||
@ -1210,6 +1210,11 @@ void Lua_Client::OpenLFGuildWindow() {
|
|||||||
self->OpenLFGuildWindow();
|
self->OpenLFGuildWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Client::NotifyNewTitlesAvailable() {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->NotifyNewTitlesAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
void Lua_Client::Signal(uint32 id) {
|
void Lua_Client::Signal(uint32 id) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->Signal(id);
|
self->Signal(id);
|
||||||
@ -1820,6 +1825,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("GetAllMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetAllMoney)
|
.def("GetAllMoney", (uint64(Lua_Client::*)(void))&Lua_Client::GetAllMoney)
|
||||||
.def("GetMoney", (uint32(Lua_Client::*)(uint8, uint8))&Lua_Client::GetMoney)
|
.def("GetMoney", (uint32(Lua_Client::*)(uint8, uint8))&Lua_Client::GetMoney)
|
||||||
.def("OpenLFGuildWindow", (void(Lua_Client::*)(void))&Lua_Client::OpenLFGuildWindow)
|
.def("OpenLFGuildWindow", (void(Lua_Client::*)(void))&Lua_Client::OpenLFGuildWindow)
|
||||||
|
.def("NotifyNewTitlesAvailable", (void(Lua_Client::*)(void))&Lua_Client::NotifyNewTitlesAvailable)
|
||||||
.def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal)
|
.def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal)
|
||||||
.def("AddAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::AddAlternateCurrencyValue)
|
.def("AddAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::AddAlternateCurrencyValue)
|
||||||
.def("SetAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::SetAlternateCurrencyValue)
|
.def("SetAlternateCurrencyValue", (void(Lua_Client::*)(uint32,int))&Lua_Client::SetAlternateCurrencyValue)
|
||||||
|
|||||||
@ -269,6 +269,7 @@ public:
|
|||||||
uint64 GetAllMoney();
|
uint64 GetAllMoney();
|
||||||
uint32 GetMoney(uint8 type, uint8 subtype);
|
uint32 GetMoney(uint8 type, uint8 subtype);
|
||||||
void OpenLFGuildWindow();
|
void OpenLFGuildWindow();
|
||||||
|
void NotifyNewTitlesAvailable();
|
||||||
void Signal(uint32 id);
|
void Signal(uint32 id);
|
||||||
void AddAlternateCurrencyValue(uint32 currency, int amount);
|
void AddAlternateCurrencyValue(uint32 currency, int amount);
|
||||||
void SetAlternateCurrencyValue(uint32 currency, int amount);
|
void SetAlternateCurrencyValue(uint32 currency, int amount);
|
||||||
|
|||||||
@ -80,6 +80,11 @@ Lua_NPC Lua_EntityList::GetNPCByNPCTypeID(int npc_type) {
|
|||||||
return Lua_NPC(self->GetNPCByNPCTypeID(npc_type));
|
return Lua_NPC(self->GetNPCByNPCTypeID(npc_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lua_NPC Lua_EntityList::GetNPCBySpawnID(uint32 spawn_id) {
|
||||||
|
Lua_Safe_Call_Class(Lua_NPC);
|
||||||
|
return Lua_NPC(self->GetNPCBySpawnID(spawn_id));
|
||||||
|
}
|
||||||
|
|
||||||
Lua_Client Lua_EntityList::GetClientByName(const char *name) {
|
Lua_Client Lua_EntityList::GetClientByName(const char *name) {
|
||||||
Lua_Safe_Call_Class(Lua_Client);
|
Lua_Safe_Call_Class(Lua_Client);
|
||||||
return Lua_Client(self->GetClientByName(name));
|
return Lua_Client(self->GetClientByName(name));
|
||||||
@ -449,6 +454,7 @@ luabind::scope lua_register_entity_list() {
|
|||||||
.def("IsMobSpawnedByNpcTypeID", (bool(Lua_EntityList::*)(int))&Lua_EntityList::IsMobSpawnedByNpcTypeID)
|
.def("IsMobSpawnedByNpcTypeID", (bool(Lua_EntityList::*)(int))&Lua_EntityList::IsMobSpawnedByNpcTypeID)
|
||||||
.def("GetNPCByID", (Lua_NPC(Lua_EntityList::*)(int))&Lua_EntityList::GetNPCByID)
|
.def("GetNPCByID", (Lua_NPC(Lua_EntityList::*)(int))&Lua_EntityList::GetNPCByID)
|
||||||
.def("GetNPCByNPCTypeID", (Lua_NPC(Lua_EntityList::*)(int))&Lua_EntityList::GetNPCByNPCTypeID)
|
.def("GetNPCByNPCTypeID", (Lua_NPC(Lua_EntityList::*)(int))&Lua_EntityList::GetNPCByNPCTypeID)
|
||||||
|
.def("GetNPCBySpawnID", (Lua_NPC(Lua_EntityList::*)(int))&Lua_EntityList::GetNPCBySpawnID)
|
||||||
.def("GetClientByName", (Lua_Client(Lua_EntityList::*)(const char*))&Lua_EntityList::GetClientByName)
|
.def("GetClientByName", (Lua_Client(Lua_EntityList::*)(const char*))&Lua_EntityList::GetClientByName)
|
||||||
.def("GetClientByAccID", (Lua_Client(Lua_EntityList::*)(uint32))&Lua_EntityList::GetClientByAccID)
|
.def("GetClientByAccID", (Lua_Client(Lua_EntityList::*)(uint32))&Lua_EntityList::GetClientByAccID)
|
||||||
.def("GetClientByID", (Lua_Client(Lua_EntityList::*)(int))&Lua_EntityList::GetClientByID)
|
.def("GetClientByID", (Lua_Client(Lua_EntityList::*)(int))&Lua_EntityList::GetClientByID)
|
||||||
|
|||||||
@ -54,6 +54,7 @@ public:
|
|||||||
bool IsMobSpawnedByNpcTypeID(int npc_type);
|
bool IsMobSpawnedByNpcTypeID(int npc_type);
|
||||||
Lua_NPC GetNPCByID(int id);
|
Lua_NPC GetNPCByID(int id);
|
||||||
Lua_NPC GetNPCByNPCTypeID(int npc_type);
|
Lua_NPC GetNPCByNPCTypeID(int npc_type);
|
||||||
|
Lua_NPC GetNPCBySpawnID(uint32 spawn_id);
|
||||||
Lua_Client GetClientByName(const char *name);
|
Lua_Client GetClientByName(const char *name);
|
||||||
Lua_Client GetClientByAccID(uint32 acct_id);
|
Lua_Client GetClientByAccID(uint32 acct_id);
|
||||||
Lua_Client GetClientByID(int id);
|
Lua_Client GetClientByID(int id);
|
||||||
|
|||||||
@ -1026,6 +1026,10 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_cross_zone_signal_client_by_group_id(uint32 group_id, int signal) {
|
||||||
|
quest_manager.CrossZoneSignalPlayerByGroupID(group_id, signal);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_cross_zone_signal_client_by_name(const char *player, int signal) {
|
void lua_cross_zone_signal_client_by_name(const char *player, int signal) {
|
||||||
quest_manager.CrossZoneSignalPlayerByName(player, signal);
|
quest_manager.CrossZoneSignalPlayerByName(player, signal);
|
||||||
}
|
}
|
||||||
@ -1034,6 +1038,10 @@ void lua_cross_zone_message_player_by_name(uint32 type, const char *player, cons
|
|||||||
quest_manager.CrossZoneMessagePlayerByName(type, player, message);
|
quest_manager.CrossZoneMessagePlayerByName(type, player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_cross_zone_message_player_by_guild_id(uint32 type, int guild_id, const char *message) {
|
||||||
|
quest_manager.CrossZoneMessagePlayerByGuildID(type, guild_id, message);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_cross_zone_set_entity_variable_by_client_name(const char *player, const char *id, const char *m_var) {
|
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);
|
quest_manager.CrossZoneSetEntityVariableByClientName(player, id, m_var);
|
||||||
}
|
}
|
||||||
@ -1839,8 +1847,10 @@ luabind::scope lua_register_general() {
|
|||||||
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_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_name", &lua_cross_zone_signal_client_by_name),
|
luabind::def("cross_zone_signal_client_by_name", &lua_cross_zone_signal_client_by_name),
|
||||||
luabind::def("cross_zone_message_player_by_name", &lua_cross_zone_message_player_by_name),
|
luabind::def("cross_zone_message_player_by_name", &lua_cross_zone_message_player_by_name),
|
||||||
|
luabind::def("cross_zone_message_player_by_guild_id", &lua_cross_zone_message_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_client_name", &lua_cross_zone_set_entity_variable_by_client_name),
|
||||||
luabind::def("world_wide_marquee", &lua_world_wide_marquee),
|
luabind::def("world_wide_marquee", &lua_world_wide_marquee),
|
||||||
luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC,Lua_Client))&lua_get_qglobals),
|
luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC,Lua_Client))&lua_get_qglobals),
|
||||||
|
|||||||
@ -92,6 +92,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/unix.h"
|
#include "../common/unix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <pthread_np.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
extern volatile bool is_zone_loaded;
|
extern volatile bool is_zone_loaded;
|
||||||
|
|
||||||
EntityList entity_list;
|
EntityList entity_list;
|
||||||
@ -431,8 +435,10 @@ int main(int argc, char** argv) {
|
|||||||
EQStreamIdentifier stream_identifier;
|
EQStreamIdentifier stream_identifier;
|
||||||
RegisterAllPatches(stream_identifier);
|
RegisterAllPatches(stream_identifier);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifdef __linux__
|
||||||
LogDebug("Main thread running with thread id [{}]", pthread_self());
|
LogDebug("Main thread running with thread id [{}]", pthread_self());
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
LogDebug("Main thread running with thread id [{}]", pthread_getthreadid_np());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool worldwasconnected = worldserver.Connected();
|
bool worldwasconnected = worldserver.Connected();
|
||||||
|
|||||||
@ -263,6 +263,146 @@ protected:
|
|||||||
double m_total_v_dist;
|
double m_total_v_dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FlyToCommand : public IMovementCommand {
|
||||||
|
public:
|
||||||
|
FlyToCommand(float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
|
{
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_move_to_x = x;
|
||||||
|
m_move_to_y = y;
|
||||||
|
m_move_to_z = z;
|
||||||
|
m_move_to_mode = mob_movement_mode;
|
||||||
|
m_last_sent_time = 0.0;
|
||||||
|
m_last_sent_speed = 0;
|
||||||
|
m_started = false;
|
||||||
|
m_total_h_dist = 0.0;
|
||||||
|
m_total_v_dist = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~FlyToCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mob_movement_manager
|
||||||
|
* @param mob
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob)
|
||||||
|
{
|
||||||
|
if (!mob->IsAIControlled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send a movement packet when you start moving
|
||||||
|
double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
|
||||||
|
int current_speed = 0;
|
||||||
|
|
||||||
|
if (m_move_to_mode == MovementRunning) {
|
||||||
|
if (mob->IsFeared()) {
|
||||||
|
current_speed = mob->GetFearSpeed();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_speed = mob->GetRunspeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_speed = mob->GetWalkspeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_started) {
|
||||||
|
m_started = true;
|
||||||
|
//rotate to the point
|
||||||
|
mob->SetMoving(true);
|
||||||
|
mob->SetHeading(mob->CalculateHeadingToTarget(m_move_to_x, m_move_to_y));
|
||||||
|
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
m_total_h_dist = DistanceNoZ(mob->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f));
|
||||||
|
m_total_v_dist = m_move_to_z - mob->GetZ();
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
//When speed changes
|
||||||
|
if (current_speed != m_last_sent_speed) {
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If x seconds have passed without sending an update.
|
||||||
|
if (current_time - m_last_sent_time >= 0.5) {
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &p = mob->GetPosition();
|
||||||
|
glm::vec2 tar(m_move_to_x, m_move_to_y);
|
||||||
|
glm::vec2 pos(p.x, p.y);
|
||||||
|
double len = glm::distance(pos, tar);
|
||||||
|
if (len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetMoved(true);
|
||||||
|
|
||||||
|
glm::vec2 dir = tar - pos;
|
||||||
|
glm::vec2 ndir = glm::normalize(dir);
|
||||||
|
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||||
|
|
||||||
|
if (distance_moved > len) {
|
||||||
|
if (mob->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(mob->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
|
||||||
|
if (RuleB(Map, FixZWhenPathing)) {
|
||||||
|
mob->FixZ();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glm::vec2 npos = pos + (ndir * static_cast<float>(distance_moved));
|
||||||
|
|
||||||
|
len -= distance_moved;
|
||||||
|
double total_distance_traveled = m_total_h_dist - len;
|
||||||
|
double start_z = m_move_to_z - m_total_v_dist;
|
||||||
|
double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist));
|
||||||
|
|
||||||
|
if (mob->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(mob->CastToNPC(), npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetPosition(npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Started() const
|
||||||
|
{
|
||||||
|
return m_started;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double m_distance_moved_since_correction;
|
||||||
|
double m_move_to_x;
|
||||||
|
double m_move_to_y;
|
||||||
|
double m_move_to_z;
|
||||||
|
MobMovementMode m_move_to_mode;
|
||||||
|
bool m_started;
|
||||||
|
|
||||||
|
double m_last_sent_time;
|
||||||
|
int m_last_sent_speed;
|
||||||
|
double m_total_h_dist;
|
||||||
|
double m_total_v_dist;
|
||||||
|
};
|
||||||
|
|
||||||
class SwimToCommand : public MoveToCommand {
|
class SwimToCommand : public MoveToCommand {
|
||||||
public:
|
public:
|
||||||
SwimToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) : MoveToCommand(x, y, z, mob_movement_mode)
|
SwimToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) : MoveToCommand(x, y, z, mob_movement_mode)
|
||||||
@ -921,6 +1061,8 @@ void MobMovementManager::FillCommandStruct(
|
|||||||
*/
|
*/
|
||||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
{
|
{
|
||||||
|
Mob *target=who->GetTarget();
|
||||||
|
|
||||||
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
||||||
auto iter = _impl->Entries.find(who);
|
auto iter = _impl->Entries.find(who);
|
||||||
auto &ent = (*iter);
|
auto &ent = (*iter);
|
||||||
@ -936,6 +1078,16 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
else if (who->IsUnderwaterOnly()) {
|
else if (who->IsUnderwaterOnly()) {
|
||||||
UpdatePathUnderwater(who, x, y, z, mob_movement_mode);
|
UpdatePathUnderwater(who, x, y, z, mob_movement_mode);
|
||||||
}
|
}
|
||||||
|
// If we can fly, and we have a target and we have LoS, simply fly to them.
|
||||||
|
// if we ever lose LoS we go back to mesh run mode.
|
||||||
|
else if (target && who->GetFlyMode() == GravityBehavior::Flying &&
|
||||||
|
who->CheckLosFN(x,y,z,target->GetSize())) {
|
||||||
|
auto iter = _impl->Entries.find(who);
|
||||||
|
auto &ent = (*iter);
|
||||||
|
|
||||||
|
PushFlyTo(ent.second, x, y, z, mob_movement_mode);
|
||||||
|
PushStopMoving(ent.second);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
UpdatePathGround(who, x, y, z, mob_movement_mode);
|
UpdatePathGround(who, x, y, z, mob_movement_mode);
|
||||||
}
|
}
|
||||||
@ -1275,6 +1427,18 @@ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to,
|
|||||||
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode)));
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ent
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @param mob_movement_mode
|
||||||
|
*/
|
||||||
|
void MobMovementManager::PushFlyTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
|
{
|
||||||
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new FlyToCommand(x, y, z, mob_movement_mode)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mob_movement_entry
|
* @param mob_movement_entry
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -85,6 +85,7 @@ private:
|
|||||||
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
||||||
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
|
void PushFlyTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode);
|
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode);
|
||||||
void PushStopMoving(MobMovementEntry &mob_movement_entry);
|
void PushStopMoving(MobMovementEntry &mob_movement_entry);
|
||||||
void PushEvadeCombat(MobMovementEntry &mob_movement_entry);
|
void PushEvadeCombat(MobMovementEntry &mob_movement_entry);
|
||||||
|
|||||||
31
zone/npc.cpp
31
zone/npc.cpp
@ -2443,18 +2443,27 @@ void NPC::LevelScale() {
|
|||||||
|
|
||||||
if (RuleB(NPC, NewLevelScaling)) {
|
if (RuleB(NPC, NewLevelScaling)) {
|
||||||
if (scalerate == 0 || maxlevel <= 25) {
|
if (scalerate == 0 || maxlevel <= 25) {
|
||||||
// pre-pop seems to scale by 20 HP increments while newer by 100
|
// Don't add HP to dynamically scaled NPCs since this will be calculated later
|
||||||
// We also don't want 100 increments on newer noobie zones, check level
|
if (max_hp > 0 || skip_auto_scale)
|
||||||
if (zone->GetZoneID() < 200 || level < 48) {
|
{
|
||||||
max_hp += (random_level - level) * 20;
|
// pre-pop seems to scale by 20 HP increments while newer by 100
|
||||||
base_hp += (random_level - level) * 20;
|
// We also don't want 100 increments on newer noobie zones, check level
|
||||||
} else {
|
if (zone->GetZoneID() < 200 || level < 48) {
|
||||||
max_hp += (random_level - level) * 100;
|
max_hp += (random_level - level) * 20;
|
||||||
base_hp += (random_level - level) * 100;
|
base_hp += (random_level - level) * 20;
|
||||||
|
} else {
|
||||||
|
max_hp += (random_level - level) * 100;
|
||||||
|
base_hp += (random_level - level) * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_hp = max_hp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't add max_dmg to dynamically scaled NPCs since this will be calculated later
|
||||||
|
if (max_dmg > 0 || skip_auto_scale)
|
||||||
|
{
|
||||||
|
max_dmg += (random_level - level) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_hp = max_hp;
|
|
||||||
max_dmg += (random_level - level) * 2;
|
|
||||||
} else {
|
} else {
|
||||||
uint8 scale_adjust = 1;
|
uint8 scale_adjust = 1;
|
||||||
|
|
||||||
|
|||||||
@ -5522,6 +5522,27 @@ XS(XS_Client_OpenLFGuildWindow) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_Client_NotifyNewTitlesAvailable); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_Client_NotifyNewTitlesAvailable) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: Client::NotifyNewTitlesAvailable(THIS)");
|
||||||
|
{
|
||||||
|
Client *THIS;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "Client")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(Client *, tmp);
|
||||||
|
} else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
if (THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
THIS->NotifyNewTitlesAvailable();
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_Client_SignalClient); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_Client_SignalClient); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_Client_SignalClient) {
|
XS(XS_Client_SignalClient) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -6568,6 +6589,7 @@ XS(boot_Client) {
|
|||||||
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, "$");
|
||||||
|
newXSproto(strcpy(buf, "NotifyNewTitlesAvailable"), XS_Client_NotifyNewTitlesAvailable, file, "$");
|
||||||
newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$");
|
newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$");
|
||||||
newXSproto(strcpy(buf, "Popup2"), XS_Client_Popup2, file, "$$$;$$$$$$$");
|
newXSproto(strcpy(buf, "Popup2"), XS_Client_Popup2, file, "$$$;$$$$$$$");
|
||||||
newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$");
|
newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$");
|
||||||
|
|||||||
@ -219,6 +219,34 @@ XS(XS_EntityList_GetNPCByNPCTypeID) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_EntityList_GetNPCBySpawnID); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_EntityList_GetNPCBySpawnID) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: EntityList::GetNPCBySpawnID(THIS, spawn_id)");
|
||||||
|
{
|
||||||
|
EntityList *THIS;
|
||||||
|
NPC *RETVAL;
|
||||||
|
uint32 spawn_id = (uint32) SvUV(ST(1));
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "EntityList")) {
|
||||||
|
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(EntityList *, tmp);
|
||||||
|
} else {
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type EntityList");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (THIS == nullptr) {
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
}
|
||||||
|
|
||||||
|
RETVAL = THIS->GetNPCBySpawnID(spawn_id);
|
||||||
|
ST(0) = sv_newmortal();
|
||||||
|
sv_setref_pv(ST(0), "NPC", (void *) RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_EntityList_GetClientByName); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_EntityList_GetClientByName); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_EntityList_GetClientByName) {
|
XS(XS_EntityList_GetClientByName) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -1998,6 +2026,7 @@ XS(boot_EntityList) {
|
|||||||
newXSproto(strcpy(buf, "IsMobSpawnedByNpcTypeID"), XS_EntityList_IsMobSpawnedByNpcTypeID, file, "$$");
|
newXSproto(strcpy(buf, "IsMobSpawnedByNpcTypeID"), XS_EntityList_IsMobSpawnedByNpcTypeID, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetNPCByID"), XS_EntityList_GetNPCByID, file, "$$");
|
newXSproto(strcpy(buf, "GetNPCByID"), XS_EntityList_GetNPCByID, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetNPCByNPCTypeID"), XS_EntityList_GetNPCByNPCTypeID, file, "$$");
|
newXSproto(strcpy(buf, "GetNPCByNPCTypeID"), XS_EntityList_GetNPCByNPCTypeID, file, "$$");
|
||||||
|
newXSproto(strcpy(buf, "GetNPCBySpawnID"), XS_EntityList_GetNPCBySpawnID, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetClientByName"), XS_EntityList_GetClientByName, file, "$$");
|
newXSproto(strcpy(buf, "GetClientByName"), XS_EntityList_GetClientByName, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetClientByAccID"), XS_EntityList_GetClientByAccID, file, "$$");
|
newXSproto(strcpy(buf, "GetClientByAccID"), XS_EntityList_GetClientByAccID, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetClientByID"), XS_EntityList_GetClientByID, file, "$$");
|
newXSproto(strcpy(buf, "GetClientByID"), XS_EntityList_GetClientByID, file, "$$");
|
||||||
|
|||||||
@ -3211,6 +3211,15 @@ void QuestManager::CrossZoneSignalPlayerByCharID(int charid, uint32 data){
|
|||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::CrossZoneSignalPlayerByGroupID(int group_id, uint32 data){
|
||||||
|
auto pack = new ServerPacket(ServerOP_CZSignalGroup, sizeof(CZGroupSignal_Struct));
|
||||||
|
CZGroupSignal_Struct* CZGS = (CZGroupSignal_Struct*) pack->pBuffer;
|
||||||
|
CZGS->group_id = group_id;
|
||||||
|
CZGS->data = data;
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
}
|
||||||
|
|
||||||
void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data){
|
void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data){
|
||||||
uint32 message_len = strlen(CharName) + 1;
|
uint32 message_len = strlen(CharName) + 1;
|
||||||
auto pack = new ServerPacket(ServerOP_CZSignalClientByName, sizeof(CZClientSignalByName_Struct) + message_len);
|
auto pack = new ServerPacket(ServerOP_CZSignalClientByName, sizeof(CZClientSignalByName_Struct) + message_len);
|
||||||
@ -3234,6 +3243,17 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam
|
|||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, const char *Message){
|
||||||
|
uint32 message_len = strlen(Message) + 1;
|
||||||
|
auto pack = new ServerPacket(ServerOP_CZMessageGuild, sizeof(CZMessageGuild_Struct) + message_len);
|
||||||
|
CZMessageGuild_Struct* CZGM = (CZMessageGuild_Struct*) pack->pBuffer;
|
||||||
|
CZGM->Type = Type;
|
||||||
|
CZGM->GuildID = GuildID;
|
||||||
|
strn0cpy(CZGM->Message, Message, 512);
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
}
|
||||||
|
|
||||||
void QuestManager::CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var){
|
void QuestManager::CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var){
|
||||||
uint32 message_len = strlen(id) + 1;
|
uint32 message_len = strlen(id) + 1;
|
||||||
uint32 message_len2 = strlen(m_var) + 1;
|
uint32 message_len2 = strlen(m_var) + 1;
|
||||||
|
|||||||
@ -279,11 +279,13 @@ public:
|
|||||||
int32 GetZoneID(const char *zone);
|
int32 GetZoneID(const char *zone);
|
||||||
const char *GetZoneLongName(const char *zone);
|
const char *GetZoneLongName(const char *zone);
|
||||||
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
|
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
|
||||||
|
void CrossZoneSignalPlayerByGroupID(int group_id, uint32 data);
|
||||||
void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data);
|
void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data);
|
||||||
void CrossZoneSignalPlayerByName(const char *CharName, uint32 data);
|
void CrossZoneSignalPlayerByName(const char *CharName, uint32 data);
|
||||||
void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var);
|
void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var);
|
||||||
void CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var);
|
void CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var);
|
||||||
void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message);
|
void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message);
|
||||||
|
void CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, const char *Message);
|
||||||
void WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message);
|
void WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message);
|
||||||
bool EnableRecipe(uint32 recipe_id);
|
bool EnableRecipe(uint32 recipe_id);
|
||||||
bool DisableRecipe(uint32 recipe_id);
|
bool DisableRecipe(uint32 recipe_id);
|
||||||
|
|||||||
@ -1915,6 +1915,17 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_CZSignalClientByName:
|
case ServerOP_CZSignalClientByName:
|
||||||
{
|
{
|
||||||
CZClientSignalByName_Struct* CZCS = (CZClientSignalByName_Struct*)pack->pBuffer;
|
CZClientSignalByName_Struct* CZCS = (CZClientSignalByName_Struct*)pack->pBuffer;
|
||||||
@ -1933,6 +1944,17 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_CZMessageGuild:
|
||||||
|
{
|
||||||
|
CZMessageGuild_Struct* CZGM = (CZMessageGuild_Struct*)pack->pBuffer;
|
||||||
|
auto client_list = entity_list.GetClientList();
|
||||||
|
for (auto client : client_list) {
|
||||||
|
if (client.second->GuildID() > 0 && client.second->GuildID() == CZGM->GuildID) {
|
||||||
|
client.second->Message(CZGM->Type, CZGM->Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_CZSetEntityVariableByClientName:
|
case ServerOP_CZSetEntityVariableByClientName:
|
||||||
{
|
{
|
||||||
CZSetEntVarByClientName_Struct* CZCS = (CZSetEntVarByClientName_Struct*)pack->pBuffer;
|
CZSetEntVarByClientName_Struct* CZCS = (CZSetEntVarByClientName_Struct*)pack->pBuffer;
|
||||||
|
|||||||
185
zone/zone.cpp
185
zone/zone.cpp
@ -330,81 +330,156 @@ bool Zone::LoadGroundSpawns() {
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Zone::SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold) {
|
void Zone::DumpMerchantList(uint32 npcid) {
|
||||||
int freeslot = 0;
|
|
||||||
std::list<MerchantList> merlist = merchanttable[merchantid];
|
|
||||||
std::list<MerchantList>::const_iterator itr;
|
|
||||||
uint32 i = 1;
|
|
||||||
for (itr = merlist.begin(); itr != merlist.end(); ++itr) {
|
|
||||||
MerchantList ml = *itr;
|
|
||||||
if (ml.item == item)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Account for merchant lists with gaps in them.
|
|
||||||
if (ml.slot >= i)
|
|
||||||
i = ml.slot + 1;
|
|
||||||
}
|
|
||||||
std::list<TempMerchantList> tmp_merlist = tmpmerchanttable[npcid];
|
std::list<TempMerchantList> tmp_merlist = tmpmerchanttable[npcid];
|
||||||
std::list<TempMerchantList>::const_iterator tmp_itr;
|
std::list<TempMerchantList>::const_iterator tmp_itr;
|
||||||
bool update_charges = false;
|
|
||||||
TempMerchantList ml;
|
TempMerchantList ml;
|
||||||
while (freeslot == 0 && !update_charges) {
|
|
||||||
freeslot = i;
|
for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) {
|
||||||
for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) {
|
ml = *tmp_itr;
|
||||||
ml = *tmp_itr;
|
|
||||||
if (ml.item == item) {
|
LogInventory("slot[{}] Orig[{}] Item[{}] Charges[{}]", ml.slot, ml.origslot, ml.item, ml.charges);
|
||||||
update_charges = true;
|
|
||||||
freeslot = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((ml.slot == i) || (ml.origslot == i)) {
|
|
||||||
freeslot = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
if (update_charges) {
|
}
|
||||||
|
|
||||||
|
int Zone::SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold) {
|
||||||
|
|
||||||
|
LogInventory("Transaction of [{}] [{}]", charges, item);
|
||||||
|
//DumpMerchantList(npcid);
|
||||||
|
// Iterate past main items.
|
||||||
|
// If the item being transacted is in this list, return 0;
|
||||||
|
std::list<MerchantList> merlist = merchanttable[merchantid];
|
||||||
|
std::list<MerchantList>::const_iterator itr;
|
||||||
|
uint32 temp_slot_index = 1;
|
||||||
|
for (itr = merlist.begin(); itr != merlist.end(); ++itr) {
|
||||||
|
MerchantList ml = *itr;
|
||||||
|
if (ml.item == item) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account for merchant lists with gaps in them.
|
||||||
|
if (ml.slot >= temp_slot_index) {
|
||||||
|
temp_slot_index = ml.slot + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInventory("Searching Temporary List. Main list ended at [{}]", temp_slot_index-1);
|
||||||
|
|
||||||
|
// Now search the temporary list.
|
||||||
|
std::list<TempMerchantList> tmp_merlist = tmpmerchanttable[npcid];
|
||||||
|
std::list<TempMerchantList>::const_iterator tmp_itr;
|
||||||
|
TempMerchantList ml;
|
||||||
|
uint32 first_empty_slot = 0; // Save 1st vacant slot while searching..
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) {
|
||||||
|
ml = *tmp_itr;
|
||||||
|
|
||||||
|
if (ml.item == item) {
|
||||||
|
found = true;
|
||||||
|
LogInventory("Item found in temp list at [{}] with [{}] charges", ml.origslot, ml.charges);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
tmp_merlist.clear();
|
tmp_merlist.clear();
|
||||||
std::list<TempMerchantList> oldtmp_merlist = tmpmerchanttable[npcid];
|
std::list<TempMerchantList> oldtmp_merlist = tmpmerchanttable[npcid];
|
||||||
for (tmp_itr = oldtmp_merlist.begin(); tmp_itr != oldtmp_merlist.end(); ++tmp_itr) {
|
for (tmp_itr = oldtmp_merlist.begin(); tmp_itr != oldtmp_merlist.end(); ++tmp_itr) {
|
||||||
TempMerchantList ml2 = *tmp_itr;
|
TempMerchantList ml2 = *tmp_itr;
|
||||||
if(ml2.item != item)
|
if(ml2.item != item)
|
||||||
tmp_merlist.push_back(ml2);
|
tmp_merlist.push_back(ml2);
|
||||||
|
else {
|
||||||
|
if (sold) {
|
||||||
|
LogInventory("Total charges is [{}] + [{}] charges", ml.charges, charges);
|
||||||
|
ml.charges = ml.charges + charges;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ml.charges = charges;
|
||||||
|
LogInventory("new charges is [{}] charges", ml.charges);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ml.origslot) {
|
||||||
|
ml.origslot = ml.slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charges > 0) {
|
||||||
|
database.SaveMerchantTemp(npcid, ml.origslot, item, ml.charges);
|
||||||
|
tmp_merlist.push_back(ml);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
database.DeleteMerchantTemp(npcid, ml.origslot);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sold)
|
|
||||||
ml.charges = ml.charges + charges;
|
|
||||||
else
|
|
||||||
ml.charges = charges;
|
|
||||||
if (!ml.origslot)
|
|
||||||
ml.origslot = ml.slot;
|
|
||||||
if (charges > 0) {
|
|
||||||
database.SaveMerchantTemp(npcid, ml.origslot, item, ml.charges);
|
|
||||||
tmp_merlist.push_back(ml);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
database.DeleteMerchantTemp(npcid, ml.origslot);
|
|
||||||
}
|
|
||||||
tmpmerchanttable[npcid] = tmp_merlist;
|
tmpmerchanttable[npcid] = tmp_merlist;
|
||||||
|
//DumpMerchantList(npcid);
|
||||||
if (sold)
|
return ml.slot;
|
||||||
return ml.slot;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (freeslot) {
|
else {
|
||||||
if (charges < 0) //sanity check only, shouldnt happen
|
if (charges < 0) { //sanity check only, shouldnt happen
|
||||||
charges = 0x7FFF;
|
charges = 0x7FFF;
|
||||||
database.SaveMerchantTemp(npcid, freeslot, item, charges);
|
}
|
||||||
|
|
||||||
|
// Find an ununsed db slot #
|
||||||
|
std::list<int> slots;
|
||||||
|
TempMerchantList ml3;
|
||||||
|
for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) {
|
||||||
|
ml3 = *tmp_itr;
|
||||||
|
slots.push_back(ml3.origslot);
|
||||||
|
}
|
||||||
|
slots.sort();
|
||||||
|
std::list<int>::const_iterator slots_itr;
|
||||||
|
uint32 first_empty_slot = 0;
|
||||||
|
uint32 idx = temp_slot_index;
|
||||||
|
for (slots_itr = slots.begin(); slots_itr != slots.end(); ++slots_itr) {
|
||||||
|
if (!first_empty_slot && *slots_itr > idx) {
|
||||||
|
LogInventory("Popped [{}]", *slots_itr);
|
||||||
|
LogInventory("First Gap Found at [{}]", idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_empty_slot = idx;
|
||||||
|
|
||||||
|
// Find an ununsed mslot
|
||||||
|
slots.clear();
|
||||||
|
for (tmp_itr = tmp_merlist.begin(); tmp_itr != tmp_merlist.end(); ++tmp_itr) {
|
||||||
|
ml3 = *tmp_itr;
|
||||||
|
slots.push_back(ml3.slot);
|
||||||
|
}
|
||||||
|
slots.sort();
|
||||||
|
uint32 first_empty_mslot=0;
|
||||||
|
idx = temp_slot_index;
|
||||||
|
for (slots_itr = slots.begin(); slots_itr != slots.end(); ++slots_itr) {
|
||||||
|
if (!first_empty_mslot && *slots_itr > idx) {
|
||||||
|
LogInventory("Popped [{}]", *slots_itr);
|
||||||
|
LogInventory("First Gap Found at [{}]", idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_empty_mslot = idx;
|
||||||
|
|
||||||
|
database.SaveMerchantTemp(npcid, first_empty_slot, item, charges);
|
||||||
tmp_merlist = tmpmerchanttable[npcid];
|
tmp_merlist = tmpmerchanttable[npcid];
|
||||||
TempMerchantList ml2;
|
TempMerchantList ml2;
|
||||||
ml2.charges = charges;
|
ml2.charges = charges;
|
||||||
|
LogInventory("Adding slot [{}] with [{}] charges.", first_empty_mslot, charges);
|
||||||
ml2.item = item;
|
ml2.item = item;
|
||||||
ml2.npcid = npcid;
|
ml2.npcid = npcid;
|
||||||
ml2.slot = freeslot;
|
ml2.slot = first_empty_mslot;
|
||||||
ml2.origslot = ml2.slot;
|
ml2.origslot = first_empty_slot;
|
||||||
tmp_merlist.push_back(ml2);
|
tmp_merlist.push_back(ml2);
|
||||||
tmpmerchanttable[npcid] = tmp_merlist;
|
tmpmerchanttable[npcid] = tmp_merlist;
|
||||||
|
//DumpMerchantList(npcid);
|
||||||
|
return ml2.slot;
|
||||||
}
|
}
|
||||||
return freeslot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) {
|
uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) {
|
||||||
@ -413,8 +488,10 @@ uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) {
|
|||||||
std::list<TempMerchantList>::const_iterator Iterator;
|
std::list<TempMerchantList>::const_iterator Iterator;
|
||||||
|
|
||||||
for (Iterator = TmpMerchantList.begin(); Iterator != TmpMerchantList.end(); ++Iterator)
|
for (Iterator = TmpMerchantList.begin(); Iterator != TmpMerchantList.end(); ++Iterator)
|
||||||
if ((*Iterator).slot == Slot)
|
if ((*Iterator).slot == Slot) {
|
||||||
|
LogInventory("Slot [{}] has [{}] charges.", Slot, (*Iterator).charges);
|
||||||
return (*Iterator).charges;
|
return (*Iterator).charges;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,6 +163,7 @@ public:
|
|||||||
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
||||||
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
||||||
int GetZoneTotalBlockedSpells() { return zone_total_blocked_spells; }
|
int GetZoneTotalBlockedSpells() { return zone_total_blocked_spells; }
|
||||||
|
void DumpMerchantList(uint32 npcid);
|
||||||
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold = false);
|
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold = false);
|
||||||
int32 MobsAggroCount() { return aggroedmobs; }
|
int32 MobsAggroCount() { return aggroedmobs; }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user