mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-18 10:42:25 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0c56660692
@ -1,5 +1,64 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 11/7/2015 ==
|
||||
Akkadius: Implemented #repopclose [distance in units] - Used for development purposes, defaults to 500 units
|
||||
- Real case use: Large zones with 700 NPC's and you are making fast quick tweaks to nearby NPC's you can refresh just the NPC's around you instead of all in the zone
|
||||
- This can be quite the time saver
|
||||
- This command will depop all NPC's and only respawn the NPC's that are 500 units around you or unless you specify otherwise
|
||||
|
||||
== 11/2/2015 ==
|
||||
Akkadius: Performance boost (exponential) - Adjusted default idle cast check timers in rules
|
||||
- Spells:AI_IdleNoSpellMinRecast 500 (Now 6000) 6 seconds
|
||||
- Spells:AI_IdleNoSpellMaxRecast 2000 (Now 60000) 60 seconds
|
||||
- Database version 9089 will take care of this update automatically only if you used the default values
|
||||
- The CPU cost of NPC's checking the entire entity list to cast beneficial spells (Heals/Buffs) becomes extremely high when higher NPC count zones exist (Based off of process profiling)
|
||||
- Distance checks for every single NPC to every single other NPC who are casting beneficial spells occur every .5 - 2 seconds unless npc_spells dictates other values, which most of the time it does not
|
||||
- Zones that once fluctuated from 1-8% CPU with no activity (Idle but players present) now idle at .5% based on my testings due
|
||||
to this change in conjunction with the past few performance commits, these are zones that have 600-800 NPC's in them
|
||||
- These values normally are overidden by the spells table (npc_spells), fields (idle_no_sp_recast_min, idle_no_sp_recast_max)
|
||||
|
||||
== 11/1/2015 ==
|
||||
Akkadius: Made many performance optimizing oriented code changes in the source
|
||||
- Added Rate limit the rate in which signals are processed for NPC's (.5 seconds instead of .01 seconds)
|
||||
Akkadius: Added Perl Export Settings which should heavily reduce the Perl footprint
|
||||
- Normally when any sub EVENT_ gets triggered, all kinds of variables have to get exported every single time an event is triggered and
|
||||
this can make Perl very slow when events are triggered constantly
|
||||
- The two most taxing variable exports are the item variables ($itemcount{} $hasitem{} $oncursor{}) and qglobals ($qglobals{})
|
||||
- qglobals can pose to be an issue quickly when global qglobals build up, it is highly recommend to use the GetGlobal() and SetGlobal()
|
||||
methods instead as they don't reference the hashmap $qglobals{} that is rebuilt every single time a sub event is triggered
|
||||
- A stress test conducted with 10,000 samples shows an excess of time taken to export variables: http://i.imgur.com/NEpW1tS.png
|
||||
- After the Perl Export Settings table is implemented, and all exports are shut off you see the following test result:
|
||||
http://i.imgur.com/Du5hth9.png
|
||||
- The difference of eliminating uneeded exports brings the overhead and footprint of 10,000 triggers from 54 seconds to 2 seconds
|
||||
- In a 10,000 sample test (10,000 sub event triggers), exporting item variables adds 12 seconds alone, when item variables are only needed in
|
||||
EVENT_ITEM and EVENT_SAY a majority of the time if at all
|
||||
- In a 10,000 sample test (10,000 sub event triggers), exporting qglobals with approximately 1,000 global qglobals in the database creates
|
||||
about 11-20 seconds of delay on its own (Depending on hardware of course)
|
||||
- I've written a parser that has determined which of these exports are needed in which sub routines and have turned off all of the unneeded
|
||||
exports in sub routines that do not need them and used it to create the default table that will be installed in the database.
|
||||
- The export table is called 'perl_event_export_settings' and it resembles the following structure and contains all current 81 EVENTS
|
||||
- If an entry doesn't exist in this table and a new subroutine is added to the source, all exports will be on by default for that routine
|
||||
|
||||
+----------+-----------------------------------------+-----------------+------------+-------------+-------------+--------------+
|
||||
| event_id | event_description | export_qglobals | export_mob | export_zone | export_item | export_event |
|
||||
+----------+-----------------------------------------+-----------------+------------+-------------+-------------+--------------+
|
||||
| 0 | EVENT_SAY | 1 | 1 | 1 | 1 | 1 |
|
||||
| 1 | EVENT_ITEM | 1 | 1 | 1 | 0 | 1 |
|
||||
| 2 | EVENT_DEATH | 1 | 1 | 1 | 0 | 1 |
|
||||
| 3 | EVENT_SPAWN | 1 | 1 | 1 | 0 | 1 |
|
||||
| 4 | EVENT_ATTACK | 0 | 1 | 1 | 0 | 1 |
|
||||
| 5 | EVENT_COMBAT | 1 | 1 | 1 | 0 | 1 |
|
||||
+----------+-----------------------------------------+-----------------+------------+-------------+-------------+--------------+
|
||||
|
||||
- If a change is made to this table while the server is live and running, you can hot reload all zone process settings via:
|
||||
#reloadperlexportsettings
|
||||
- For those who wonder what "exports" are, they are reference to variables that are made available at runtime of the sub event, such as:
|
||||
(export_qglobals) (Heavy) : $qglobals https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L916
|
||||
(export_item) (Heavy) : $itemcount{} $hasitem{} $oncursor{} https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1103
|
||||
(export_zone) : $zoneid, $instanceid, $zoneln etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1083
|
||||
(export_mob) : $x, $y, $z, $h, $hpratio etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1032
|
||||
(export_event) : (event specific) IE: EVENT_SAY ($text) https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1141
|
||||
|
||||
== 10/16/2015 ==
|
||||
Uleat: Added command '#bot clearfollowdistance [ <target> | spawned | all ]' to coincide with the activation of the load/save feature for follow_distance
|
||||
|
||||
|
||||
@ -21,6 +21,12 @@ IF(MYSQL_ROOT)
|
||||
NAMES mysql.h
|
||||
PATHS ${MYSQL_ROOT}/include
|
||||
PATH_SUFFIXES mysql
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
FIND_PATH(MySQL_INCLUDE_DIR
|
||||
NAMES mysql.h
|
||||
PATH_SUFFIXES mysql
|
||||
)
|
||||
ELSE(MYSQL_ROOT)
|
||||
FIND_PATH(MySQL_INCLUDE_DIR
|
||||
@ -30,49 +36,46 @@ ELSE(MYSQL_ROOT)
|
||||
ENDIF(MYSQL_ROOT)
|
||||
|
||||
# Library
|
||||
SET(MySQL_NAMES libmysql mysqlclient_r mysqlclient)
|
||||
SET(MySQL_NAMES libmysql)
|
||||
IF(MYSQL_ROOT)
|
||||
FIND_LIBRARY(MySQL_LIBRARY_DEBUG
|
||||
FIND_LIBRARY(MySQL_LIBRARY
|
||||
NAMES ${MySQL_NAMES}
|
||||
PATHS ${MYSQL_ROOT}/lib/debug /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATHS ${MYSQL_ROOT}/lib
|
||||
PATH_SUFFIXES mysql
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(MySQL_LIBRARY_RELEASE
|
||||
|
||||
FIND_LIBRARY(MySQL_LIBRARY
|
||||
NAMES ${MySQL_NAMES}
|
||||
PATHS ${MYSQL_ROOT}/lib /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATH_SUFFIXES mysql
|
||||
)
|
||||
ELSE(MYSQL_ROOT)
|
||||
FIND_LIBRARY(MySQL_LIBRARY_DEBUG
|
||||
NAMES ${MySQL_NAMES}
|
||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATH_SUFFIXES mysql
|
||||
)
|
||||
|
||||
FIND_LIBRARY(MySQL_LIBRARY_RELEASE
|
||||
NAMES ${MySQL_NAMES}
|
||||
FIND_LIBRARY(MySQL_LIBRARY
|
||||
NAMES ${MySQL_NAMES} mysqlclient_r mysqlclient
|
||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATH_SUFFIXES mysql
|
||||
)
|
||||
ENDIF(MYSQL_ROOT)
|
||||
|
||||
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
|
||||
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
||||
SET(MySQL_FOUND TRUE)
|
||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_DEBUG} ${MySQL_LIBRARY_RELEASE} )
|
||||
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
|
||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY} )
|
||||
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
||||
SET(MySQL_FOUND FALSE)
|
||||
SET( MySQL_LIBRARIES )
|
||||
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY_DEBUG AND MySQL_LIBRARY_RELEASE)
|
||||
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
||||
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set MySQL_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MySQL DEFAULT_MSG MySQL_LIBRARY_DEBUG MySQL_LIBRARY_RELEASE MySQL_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MySQL DEFAULT_MSG MySQL_LIBRARY MySQL_INCLUDE_DIR)
|
||||
|
||||
IF(MySQL_FOUND)
|
||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_DEBUG} ${MySQL_LIBRARY_RELEASE} )
|
||||
SET( MySQL_LIBRARY_RELEASE ${MySQL_LIBRARY} )
|
||||
SET( MySQL_LIBRARY_DEBUG ${MySQL_LIBRARY} )
|
||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_RELEASE} ${MySQL_LIBRARY_DEBUG} )
|
||||
ELSE(MySQL_FOUND)
|
||||
SET( MySQL_LIBRARIES )
|
||||
ENDIF(MySQL_FOUND)
|
||||
|
||||
@ -67,6 +67,8 @@ public:
|
||||
|
||||
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
|
||||
uint8 ReadUInt8(uint32 Offset) const { uint8 value = *(uint8 *)(pBuffer + Offset); return value; }
|
||||
uint16 ReadUInt16() { uint16 value = *(uint16 *)(pBuffer + _rpos); _rpos += sizeof(uint16); return value; }
|
||||
uint16 ReadUInt16(uint32 Offset) const { uint16 value = *(uint16 *)(pBuffer + Offset); return value; }
|
||||
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
|
||||
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
|
||||
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
#include "global_define.h"
|
||||
#include "eqemu_logsys.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "dbcore.h"
|
||||
#include "linked_list.h"
|
||||
|
||||
@ -128,7 +128,12 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
|
||||
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
|
||||
|
||||
if (Log.log_settings[Logs::MySQLQuery].is_category_enabled == 1)
|
||||
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u rows returned)", query, rowCount, requestResult.RowCount());
|
||||
{
|
||||
if ((strncasecmp(query, "select", 6) == 0))
|
||||
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
|
||||
else
|
||||
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
@ -215,6 +215,7 @@ N(OP_GroupUpdate),
|
||||
N(OP_GroupUpdateB),
|
||||
N(OP_GroupUpdateLeaderAA),
|
||||
N(OP_GuildBank),
|
||||
N(OP_GuildBankItemList),
|
||||
N(OP_GuildCreate),
|
||||
N(OP_GuildDelete),
|
||||
N(OP_GuildDemote),
|
||||
@ -535,6 +536,8 @@ N(OP_WorldLogout),
|
||||
N(OP_WorldObjectsSent),
|
||||
N(OP_WorldUnknown001),
|
||||
N(OP_XTargetAutoAddHaters),
|
||||
N(OP_XTargetOpen),
|
||||
N(OP_XTargetOpenResponse),
|
||||
N(OP_XTargetRequest),
|
||||
N(OP_XTargetResponse),
|
||||
N(OP_YellForHelp),
|
||||
|
||||
@ -4724,6 +4724,22 @@ struct GuildBankItemUpdate_Struct
|
||||
/*226*/ uint16 Unknown226;
|
||||
};
|
||||
|
||||
// newer clients (RoF+) send a list that contains 240 entries
|
||||
// The packets don't actually use all 64 chars in the strings, but we'll just overallocate for these
|
||||
struct GuildBankItemListEntry_Struct
|
||||
{
|
||||
uint8 vaild;
|
||||
uint32 permissions;
|
||||
char whofor[64];
|
||||
char donator[64];
|
||||
uint32 item_id;
|
||||
uint32 item_icon;
|
||||
uint32 quantity;
|
||||
uint8 allow_merge; // 1 here for non-full stacks
|
||||
uint8 usable;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
struct GuildBankClear_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
|
||||
@ -116,7 +116,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
platform_file_name = "ucs";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
|
||||
platform_file_name = "login";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
|
||||
platform_file_name = "launcher";
|
||||
}
|
||||
|
||||
|
||||
@ -154,11 +154,12 @@ enum { //reuse times
|
||||
enum { //timer settings, all in milliseconds
|
||||
AImovement_duration = 100,
|
||||
AIthink_duration = 150,
|
||||
AIscanarea_delay = 500,
|
||||
AIscanarea_delay = 6000,
|
||||
AIfeignremember_delay = 500,
|
||||
AItarget_check_duration = 500,
|
||||
AIClientScanarea_delay = 750, //used in REVERSE_AGGRO
|
||||
AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help
|
||||
AI_check_signal_timer_delay = 500, // How often EVENT_SIGNAL checks are processed
|
||||
ClientProximity_interval = 150,
|
||||
CombatEventTimer_expire = 12000,
|
||||
Tribute_duration = 600000,
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
**
|
||||
*/
|
||||
struct ItemEffect_Struct {
|
||||
int16 Effect;
|
||||
int32 Effect;
|
||||
uint8 Type;
|
||||
uint8 Level;
|
||||
uint8 Level2;
|
||||
|
||||
@ -1179,6 +1179,54 @@ namespace RoF
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildBank)
|
||||
{
|
||||
auto in = *p;
|
||||
*p = nullptr;
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBank, in->size + 4); // all of them are 4 bytes bigger
|
||||
|
||||
// The first action in the enum was removed, everything 1 less
|
||||
// Normally we cast them to their structs, but there are so many here! will only do when it's easier
|
||||
switch (in->ReadUInt32()) {
|
||||
case 10: // GuildBankAcknowledge
|
||||
outapp->WriteUInt32(9);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
outapp->WriteUInt32(0);
|
||||
break;
|
||||
case 5: // GuildBankDeposit (ack)
|
||||
outapp->WriteUInt32(4);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
break;
|
||||
case 1: { // GuildBankItemUpdate
|
||||
auto emu = (GuildBankItemUpdate_Struct *)in->pBuffer;
|
||||
auto eq = (structs::GuildBankItemUpdate_Struct *)outapp->pBuffer;
|
||||
eq->Action = 0;
|
||||
OUT(Unknown004);
|
||||
eq->Unknown08 = 0;
|
||||
OUT(SlotID);
|
||||
OUT(Area);
|
||||
OUT(Unknown012);
|
||||
OUT(ItemID);
|
||||
OUT(Icon);
|
||||
OUT(Quantity);
|
||||
OUT(Permissions);
|
||||
OUT(AllowMerge);
|
||||
OUT(Useable);
|
||||
OUT_str(ItemName);
|
||||
OUT_str(Donator);
|
||||
OUT_str(WhoFor);
|
||||
OUT(Unknown226);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete in;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildMemberList)
|
||||
{
|
||||
//consume the packet
|
||||
@ -4590,6 +4638,92 @@ namespace RoF
|
||||
DECODE_FORWARD(OP_GroupInvite);
|
||||
}
|
||||
|
||||
DECODE(OP_GuildBank)
|
||||
{
|
||||
// all actions are 1 off due to the removal of one of enums
|
||||
switch (__packet->ReadUInt32()) {
|
||||
case 2: {// GuildBankPromote
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankPromote_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankPromote_Struct, structs::GuildBankPromote_Struct);
|
||||
emu->Action = 3;
|
||||
IN(Unknown04);
|
||||
IN(Slot);
|
||||
IN(Slot2);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 3: { // GuildBankViewItem
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankViewItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankViewItem_Struct, structs::GuildBankViewItem_Struct);
|
||||
emu->Action = 4;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Unknown16);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 4: { // GuildBankDeposit
|
||||
__packet->WriteUInt32(5);
|
||||
return;
|
||||
}
|
||||
case 5: { // GuildBankPermissions
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankPermissions_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankPermissions_Struct, structs::GuildBankPermissions_Struct);
|
||||
emu->Action = 6;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Unknown10);
|
||||
IN(ItemID);
|
||||
IN(Permissions);
|
||||
strn0cpy(emu->MemberName, eq->MemberName, 64);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 6: { // GuildBankWithdraw
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 7;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 7: { // GuildBankSplitStacks
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 8;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 8: { // GuildBankMergeStacks
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 9;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_GuildDemote)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::GuildDemoteStruct);
|
||||
|
||||
@ -1250,6 +1250,54 @@ namespace RoF2
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildBank)
|
||||
{
|
||||
auto in = *p;
|
||||
*p = nullptr;
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBank, in->size + 4); // all of them are 4 bytes bigger
|
||||
|
||||
// The first action in the enum was removed, everything 1 less
|
||||
// Normally we cast them to their structs, but there are so many here! will only do when it's easier
|
||||
switch (in->ReadUInt32()) {
|
||||
case 10: // GuildBankAcknowledge
|
||||
outapp->WriteUInt32(9);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
outapp->WriteUInt32(0);
|
||||
break;
|
||||
case 5: // GuildBankDeposit (ack)
|
||||
outapp->WriteUInt32(4);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(in->ReadUInt32());
|
||||
break;
|
||||
case 1: { // GuildBankItemUpdate
|
||||
auto emu = (GuildBankItemUpdate_Struct *)in->pBuffer;
|
||||
auto eq = (structs::GuildBankItemUpdate_Struct *)outapp->pBuffer;
|
||||
eq->Action = 0;
|
||||
OUT(Unknown004);
|
||||
eq->Unknown08 = 0;
|
||||
OUT(SlotID);
|
||||
OUT(Area);
|
||||
OUT(Unknown012);
|
||||
OUT(ItemID);
|
||||
OUT(Icon);
|
||||
OUT(Quantity);
|
||||
OUT(Permissions);
|
||||
OUT(AllowMerge);
|
||||
OUT(Useable);
|
||||
OUT_str(ItemName);
|
||||
OUT_str(Donator);
|
||||
OUT_str(WhoFor);
|
||||
OUT(Unknown226);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete in;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildMemberList)
|
||||
{
|
||||
//consume the packet
|
||||
@ -4739,6 +4787,92 @@ namespace RoF2
|
||||
DECODE_FORWARD(OP_GroupInvite);
|
||||
}
|
||||
|
||||
DECODE(OP_GuildBank)
|
||||
{
|
||||
// all actions are 1 off due to the removal of one of enums
|
||||
switch (__packet->ReadUInt32()) {
|
||||
case 2: {// GuildBankPromote
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankPromote_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankPromote_Struct, structs::GuildBankPromote_Struct);
|
||||
emu->Action = 3;
|
||||
IN(Unknown04);
|
||||
IN(Slot);
|
||||
IN(Slot2);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 3: { // GuildBankViewItem
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankViewItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankViewItem_Struct, structs::GuildBankViewItem_Struct);
|
||||
emu->Action = 4;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Unknown16);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 4: { // GuildBankDeposit
|
||||
__packet->WriteUInt32(5);
|
||||
return;
|
||||
}
|
||||
case 5: { // GuildBankPermissions
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankPermissions_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankPermissions_Struct, structs::GuildBankPermissions_Struct);
|
||||
emu->Action = 6;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Unknown10);
|
||||
IN(ItemID);
|
||||
IN(Permissions);
|
||||
strn0cpy(emu->MemberName, eq->MemberName, 64);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 6: { // GuildBankWithdraw
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 7;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 7: { // GuildBankSplitStacks
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 8;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
case 8: { // GuildBankMergeStacks
|
||||
DECODE_LENGTH_EXACT(structs::GuildBankWithdrawItem_Struct);
|
||||
SETUP_DIRECT_DECODE(GuildBankWithdrawItem_Struct, structs::GuildBankWithdrawItem_Struct);
|
||||
emu->Action = 9;
|
||||
IN(Unknown04);
|
||||
IN(SlotID);
|
||||
IN(Area);
|
||||
IN(Unknown12);
|
||||
IN(Quantity);
|
||||
FINISH_DIRECT_DECODE();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_GuildDemote)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::GuildDemoteStruct);
|
||||
|
||||
@ -57,6 +57,7 @@ E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildBank)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberUpdate)
|
||||
E(OP_GuildsList)
|
||||
@ -152,6 +153,7 @@ D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_GuildBank)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_GuildRemove)
|
||||
D(OP_GuildStatus)
|
||||
|
||||
@ -1859,6 +1859,114 @@ struct GuildUpdate_Struct {
|
||||
GuildsListEntry_Struct entry;
|
||||
};
|
||||
|
||||
struct GuildBankAck_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 10
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
};
|
||||
|
||||
struct GuildBankDepositAck_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 10
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint32 Fail; //1 = Fail, 0 = Success
|
||||
};
|
||||
|
||||
struct GuildBankPromote_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 3
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*12*/ uint32 Slot;
|
||||
/*16*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
|
||||
/*20*/ uint32 unknown20;
|
||||
};
|
||||
|
||||
struct GuildBankPermissions_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 6
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID;
|
||||
/*10*/ uint16 Unknown10; // Saw 1, probably indicating it is the main area rather than deposits
|
||||
/*12*/ uint32 ItemID;
|
||||
/*16*/ uint32 Permissions;
|
||||
/*20*/ char MemberName[64];
|
||||
};
|
||||
|
||||
struct GuildBankViewItem_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID; // 0 = Deposit area, 1 = Main area
|
||||
/*10*/ uint16 Area;
|
||||
/*12*/ uint32 Unknown12;
|
||||
/*16*/ uint32 Unknown16;
|
||||
};
|
||||
|
||||
struct GuildBankWithdrawItem_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID;
|
||||
/*10*/ uint16 Area;
|
||||
/*12*/ uint32 Unknown12;
|
||||
/*16*/ uint32 Quantity;
|
||||
/*20*/
|
||||
};
|
||||
|
||||
struct GuildBankItemUpdate_Struct
|
||||
{
|
||||
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
|
||||
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
|
||||
{
|
||||
Action = inAction;
|
||||
Unknown004 = inUnknown004;
|
||||
SlotID = inSlotID;
|
||||
Area = inArea;
|
||||
Unknown012 = inUnknown012;
|
||||
ItemID = inItemID;
|
||||
Icon = inIcon;
|
||||
Quantity = inQuantity;
|
||||
Permissions = inPermissions;
|
||||
AllowMerge = inAllowMerge;
|
||||
Useable = inUseable;
|
||||
ItemName[0] = '\0';
|
||||
Donator[0] = '\0';
|
||||
WhoFor[0] = '\0';
|
||||
};
|
||||
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*012*/ uint16 SlotID;
|
||||
/*014*/ uint16 Area;
|
||||
/*016*/ uint32 Unknown012;
|
||||
/*020*/ uint32 ItemID;
|
||||
/*024*/ uint32 Icon;
|
||||
/*028*/ uint32 Quantity;
|
||||
/*032*/ uint32 Permissions;
|
||||
/*036*/ uint8 AllowMerge;
|
||||
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
|
||||
/*038*/ char ItemName[64];
|
||||
/*102*/ char Donator[64];
|
||||
/*166*/ char WhoFor[64];
|
||||
/*230*/ uint16 Unknown226;
|
||||
};
|
||||
|
||||
struct GuildBankClear_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*12*/ uint32 DepositAreaCount;
|
||||
/*16*/ uint32 MainAreaCount;
|
||||
};
|
||||
|
||||
/*
|
||||
** Money Loot
|
||||
** Length: 22 Bytes
|
||||
@ -4624,7 +4732,7 @@ struct ClickEffectStruct
|
||||
|
||||
struct ProcEffectStruct
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
@ -4639,7 +4747,7 @@ struct ProcEffectStruct
|
||||
|
||||
struct WornEffectStruct //worn, focus and scroll effect
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
|
||||
@ -42,6 +42,7 @@ E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildBank)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberUpdate)
|
||||
E(OP_GuildsList)
|
||||
@ -137,6 +138,7 @@ D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_GuildBank)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_GuildRemove)
|
||||
D(OP_GuildStatus)
|
||||
|
||||
@ -1889,6 +1889,114 @@ struct GuildUpdate_Struct {
|
||||
GuildsListEntry_Struct entry;
|
||||
};
|
||||
|
||||
struct GuildBankAck_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 10
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
};
|
||||
|
||||
struct GuildBankDepositAck_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 10
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint32 Fail; //1 = Fail, 0 = Success
|
||||
};
|
||||
|
||||
struct GuildBankPromote_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 3
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*12*/ uint32 Slot;
|
||||
/*16*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
|
||||
/*20*/ uint32 unknown20;
|
||||
};
|
||||
|
||||
struct GuildBankPermissions_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; // 6
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID;
|
||||
/*10*/ uint16 Unknown10; // Saw 1, probably indicating it is the main area rather than deposits
|
||||
/*12*/ uint32 ItemID;
|
||||
/*16*/ uint32 Permissions;
|
||||
/*20*/ char MemberName[64];
|
||||
};
|
||||
|
||||
struct GuildBankViewItem_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID; // 0 = Deposit area, 1 = Main area
|
||||
/*10*/ uint16 Area;
|
||||
/*12*/ uint32 Unknown12;
|
||||
/*16*/ uint32 Unknown16;
|
||||
};
|
||||
|
||||
struct GuildBankWithdrawItem_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*08*/ uint16 SlotID;
|
||||
/*10*/ uint16 Area;
|
||||
/*12*/ uint32 Unknown12;
|
||||
/*16*/ uint32 Quantity;
|
||||
/*20*/
|
||||
};
|
||||
|
||||
struct GuildBankItemUpdate_Struct
|
||||
{
|
||||
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
|
||||
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
|
||||
{
|
||||
Action = inAction;
|
||||
Unknown004 = inUnknown004;
|
||||
SlotID = inSlotID;
|
||||
Area = inArea;
|
||||
Unknown012 = inUnknown012;
|
||||
ItemID = inItemID;
|
||||
Icon = inIcon;
|
||||
Quantity = inQuantity;
|
||||
Permissions = inPermissions;
|
||||
AllowMerge = inAllowMerge;
|
||||
Useable = inUseable;
|
||||
ItemName[0] = '\0';
|
||||
Donator[0] = '\0';
|
||||
WhoFor[0] = '\0';
|
||||
};
|
||||
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*012*/ uint16 SlotID;
|
||||
/*014*/ uint16 Area;
|
||||
/*016*/ uint32 Unknown012;
|
||||
/*020*/ uint32 ItemID;
|
||||
/*024*/ uint32 Icon;
|
||||
/*028*/ uint32 Quantity;
|
||||
/*032*/ uint32 Permissions;
|
||||
/*036*/ uint8 AllowMerge;
|
||||
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
|
||||
/*038*/ char ItemName[64];
|
||||
/*102*/ char Donator[64];
|
||||
/*166*/ char WhoFor[64];
|
||||
/*230*/ uint16 Unknown226;
|
||||
};
|
||||
|
||||
struct GuildBankClear_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint32 Unknown04;
|
||||
/*08*/ uint32 Unknown08;
|
||||
/*12*/ uint32 DepositAreaCount;
|
||||
/*16*/ uint32 MainAreaCount;
|
||||
};
|
||||
|
||||
/*
|
||||
** Money Loot
|
||||
** Length: 22 Bytes
|
||||
@ -4623,7 +4731,7 @@ struct ClickEffectStruct
|
||||
|
||||
struct ProcEffectStruct
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
@ -4638,7 +4746,7 @@ struct ProcEffectStruct
|
||||
|
||||
struct WornEffectStruct //worn, focus and scroll effect
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
|
||||
@ -4111,7 +4111,7 @@ struct ClickEffectStruct
|
||||
|
||||
struct ProcEffectStruct
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
@ -4126,7 +4126,7 @@ struct ProcEffectStruct
|
||||
|
||||
struct WornEffectStruct //worn, focus and scroll effect
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
|
||||
@ -3965,7 +3965,7 @@ struct ClickEffectStruct
|
||||
|
||||
struct ProcEffectStruct
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
@ -3980,7 +3980,7 @@ struct ProcEffectStruct
|
||||
|
||||
struct WornEffectStruct //worn, focus and scroll effect
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
|
||||
@ -4206,7 +4206,7 @@ struct ClickEffectStruct
|
||||
|
||||
struct ProcEffectStruct
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
@ -4221,7 +4221,7 @@ struct ProcEffectStruct
|
||||
|
||||
struct WornEffectStruct //worn, focus and scroll effect
|
||||
{
|
||||
uint32 effect;
|
||||
int32 effect;
|
||||
uint8 level2;
|
||||
uint32 type;
|
||||
uint8 level;
|
||||
|
||||
@ -347,8 +347,8 @@ RULE_INT(Spells, AI_EngagedDetrimentalChance, 20) // Chance during third AI Cast
|
||||
RULE_INT(Spells, AI_PursueNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while chasing target. (min time in random)
|
||||
RULE_INT(Spells, AI_PursueNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
||||
RULE_INT(Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing target to cast a detrimental spell.
|
||||
RULE_INT(Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
|
||||
RULE_INT(Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
||||
RULE_INT(Spells, AI_IdleNoSpellMinRecast, 6000) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
|
||||
RULE_INT(Spells, AI_IdleNoSpellMaxRecast, 60000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
||||
RULE_INT(Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
|
||||
RULE_BOOL(Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false)
|
||||
RULE_BOOL(Spells, Jun182014HundredHandsRevamp, false) // this should be true for if you import a spell file newer than June 18, 2014
|
||||
@ -475,6 +475,8 @@ RULE_BOOL(NPC, ReturnNonQuestNoDropItems, false) // Returns NO DROP items on NPC
|
||||
RULE_INT(NPC, StartEnrageValue, 9) // % HP that an NPC will begin to enrage
|
||||
RULE_BOOL(NPC, LiveLikeEnrage, false) // If set to true then only player controlled pets will enrage
|
||||
RULE_BOOL(NPC, EnableMeritBasedFaction, false) // If set to true, faction will given in the same way as experience (solo/group/raid)
|
||||
RULE_INT(NPC, NPCToNPCAggroTimerMin, 500)
|
||||
RULE_INT(NPC, NPCToNPCAggroTimerMax, 6000)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Aggro)
|
||||
|
||||
@ -182,6 +182,7 @@
|
||||
#define ServerOP_CZMessagePlayer 0x4008
|
||||
#define ServerOP_ReloadWorld 0x4009
|
||||
#define ServerOP_ReloadLogs 0x4010
|
||||
#define ServerOP_ReloadPerlExportSettings 0x4011
|
||||
/* Query Server OP Codes */
|
||||
#define ServerOP_QSPlayerLogTrades 0x5010
|
||||
#define ServerOP_QSPlayerLogHandins 0x5011
|
||||
@ -548,6 +549,7 @@ struct ServerConnectInfo {
|
||||
char address[250];
|
||||
char local_address[250];
|
||||
uint16 port;
|
||||
uint32 process_id;
|
||||
};
|
||||
|
||||
struct ServerGMGoto_Struct {
|
||||
|
||||
@ -997,23 +997,23 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
|
||||
strcpy(item.CharmFile,row[ItemField::charmfile]);
|
||||
|
||||
item.Proc.Effect = (uint16)atoul(row[ItemField::proceffect]);
|
||||
item.Proc.Effect = (int32)atoul(row[ItemField::proceffect]);
|
||||
item.Proc.Type = (uint8)atoul(row[ItemField::proctype]);
|
||||
item.Proc.Level = (uint8)atoul(row[ItemField::proclevel]);
|
||||
item.Proc.Level2 = (uint8)atoul(row[ItemField::proclevel2]);
|
||||
item.Worn.Effect = (uint16)atoul(row[ItemField::worneffect]);
|
||||
item.Worn.Effect = (int32)atoul(row[ItemField::worneffect]);
|
||||
item.Worn.Type = (uint8)atoul(row[ItemField::worntype]);
|
||||
item.Worn.Level = (uint8)atoul(row[ItemField::wornlevel]);
|
||||
item.Worn.Level2 = (uint8)atoul(row[ItemField::wornlevel2]);
|
||||
item.Focus.Effect = (uint16)atoul(row[ItemField::focuseffect]);
|
||||
item.Focus.Effect = (int32)atoul(row[ItemField::focuseffect]);
|
||||
item.Focus.Type = (uint8)atoul(row[ItemField::focustype]);
|
||||
item.Focus.Level = (uint8)atoul(row[ItemField::focuslevel]);
|
||||
item.Focus.Level2 = (uint8)atoul(row[ItemField::focuslevel2]);
|
||||
item.Scroll.Effect = (uint16)atoul(row[ItemField::scrolleffect]);
|
||||
item.Scroll.Effect = (int32)atoul(row[ItemField::scrolleffect]);
|
||||
item.Scroll.Type = (uint8)atoul(row[ItemField::scrolltype]);
|
||||
item.Scroll.Level = (uint8)atoul(row[ItemField::scrolllevel]);
|
||||
item.Scroll.Level2 = (uint8)atoul(row[ItemField::scrolllevel2]);
|
||||
item.Bard.Effect = (uint16)atoul(row[ItemField::bardeffect]);
|
||||
item.Bard.Effect = (int32)atoul(row[ItemField::bardeffect]);
|
||||
item.Bard.Type = (uint8)atoul(row[ItemField::bardtype]);
|
||||
item.Bard.Level = (uint8)atoul(row[ItemField::bardlevel]);
|
||||
item.Bard.Level2 = (uint8)atoul(row[ItemField::bardlevel2]);
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9087
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9089
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
||||
#else
|
||||
|
||||
@ -131,6 +131,7 @@ OP_GuildPromote=0x2945
|
||||
OP_GuildPublicNote=0x3c2c
|
||||
OP_GuildManageBanker=0x389c # Was 0x096d
|
||||
OP_GuildBank=0x2ab0 # Was 0x10c3
|
||||
OP_GuildBankItemList=0x1cbf
|
||||
OP_SetGuildRank=0x3599
|
||||
OP_GuildUpdateURLAndChannel=0x7851
|
||||
OP_GuildStatus=0x25a5
|
||||
@ -235,6 +236,8 @@ OP_TargetHoTT=0x3af5
|
||||
OP_XTargetResponse=0x7f64
|
||||
OP_XTargetRequest=0x6753
|
||||
OP_XTargetAutoAddHaters=0x5f51
|
||||
OP_XTargetOpen=0x7423
|
||||
OP_XTargetOpenResponse=0x27e8
|
||||
OP_TargetBuffs=0x1c71
|
||||
OP_BuffCreate=0x71f5
|
||||
OP_BuffRemoveRequest=0x7efd
|
||||
|
||||
@ -130,6 +130,7 @@ OP_GuildPromote=0x6a98
|
||||
OP_GuildPublicNote=0x5053
|
||||
OP_GuildManageBanker=0x3f35
|
||||
OP_GuildBank=0x5134
|
||||
OP_GuildBankItemList=0x7850
|
||||
OP_SetGuildRank=0x0b9c
|
||||
OP_GuildUpdateURLAndChannel=0x2958
|
||||
OP_GuildStatus=0x7326
|
||||
@ -235,6 +236,8 @@ OP_TargetBuffs=0x4f4b
|
||||
OP_XTargetResponse=0x4d59
|
||||
OP_XTargetRequest=0x3763
|
||||
OP_XTargetAutoAddHaters=0x672f
|
||||
OP_XTargetOpen=0x61df
|
||||
OP_XTargetOpenResponse=0x3ef8
|
||||
OP_BuffCreate=0x3377
|
||||
OP_BuffRemoveRequest=0x64f2
|
||||
OP_DeleteSpawn=0x7280
|
||||
|
||||
@ -239,6 +239,8 @@ OP_TargetHoTT=0x790c # C
|
||||
OP_XTargetResponse=0x6eb5 #
|
||||
OP_XTargetRequest=0x4750 #
|
||||
OP_XTargetAutoAddHaters=0x1a28 #
|
||||
OP_XTargetOpen=0x11ae
|
||||
OP_XTargetOpenResponse=0x45d3
|
||||
OP_TargetBuffs=0x3f24 # C
|
||||
OP_BuffCreate=0x2121 # V
|
||||
OP_BuffRemoveRequest=0x4065
|
||||
|
||||
@ -341,6 +341,8 @@
|
||||
9085|2015_07_01_Marquee_Rule.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Character:MarqueeHPUpdates%'|empty|
|
||||
9086|2015_07_02_aa_rework.sql|SHOW TABLES LIKE 'aa_ranks'|empty|
|
||||
9087|2015_09_25_inventory_snapshots.sql|SHOW TABLES LIKE 'inventory_snapshots'|empty|
|
||||
9088|2015_11_01_perl_event_export_settings.sql|SHOW TABLES LIKE 'perl_event_export_settings'|empty|
|
||||
9089|2015_11_02_ai_idle_no_spell_recast_default_changes.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Spells:AI_IdleNoSpellMinRecast%' AND `rule_value` = '500'|not_empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
CREATE TABLE `perl_event_export_settings` (
|
||||
`event_id` int(11) NOT NULL,
|
||||
`event_description` varchar(150) DEFAULT NULL,
|
||||
`export_qglobals` smallint(11) DEFAULT '0',
|
||||
`export_mob` smallint(11) DEFAULT '0',
|
||||
`export_zone` smallint(11) DEFAULT '0',
|
||||
`export_item` smallint(11) DEFAULT '0',
|
||||
`export_event` smallint(11) DEFAULT '0',
|
||||
PRIMARY KEY (`event_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of perl_event_export_settings
|
||||
-- ----------------------------
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('0', 'EVENT_SAY', '1', '1', '1', '1', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('1', 'EVENT_ITEM', '1', '1', '1', '1', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('2', 'EVENT_DEATH', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('3', 'EVENT_SPAWN', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('4', 'EVENT_ATTACK', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('5', 'EVENT_COMBAT', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('6', 'EVENT_AGGRO', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('7', 'EVENT_SLAY', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('8', 'EVENT_NPC_SLAY', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('9', 'EVENT_WAYPOINT_ARRIVE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('10', 'EVENT_WAYPOINT_DEPART', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('11', 'EVENT_TIMER', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('12', 'EVENT_SIGNAL', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('13', 'EVENT_HP', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('14', 'EVENT_ENTER', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('15', 'EVENT_EXIT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('16', 'EVENT_ENTERZONE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('17', 'EVENT_CLICKDOOR', '1', '1', '1', '1', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('18', 'EVENT_LOOT', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('19', 'EVENT_ZONE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('20', 'EVENT_LEVEL_UP', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('21', 'EVENT_KILLED_MERIT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('22', 'EVENT_CAST_ON', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('23', 'EVENT_TASKACCEPTED', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('24', 'EVENT_TASK_STAGE_COMPLETE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('25', 'EVENT_TASK_UPDATE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('26', 'EVENT_TASK_COMPLETE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('27', 'EVENT_TASK_FAIL', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('28', 'EVENT_AGGRO_SAY', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('29', 'EVENT_PLAYER_PICKUP', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('30', 'EVENT_POPUPRESPONSE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('31', 'EVENT_ENVIRONMENTAL_DAMAGE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('32', 'EVENT_PROXIMITY_SAY', '1', '1', '1', '1', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('33', 'EVENT_CAST', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('34', 'EVENT_CAST_BEGIN', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('35', 'EVENT_SCALE_CALC', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('36', 'EVENT_ITEM_ENTER_ZONE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('37', 'EVENT_TARGET_CHANGE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('38', 'EVENT_HATE_LIST', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('39', 'EVENT_SPELL_EFFECT_CLIENT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('40', 'EVENT_SPELL_EFFECT_NPC', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('41', 'EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('42', 'EVENT_SPELL_EFFECT_BUFF_TIC_NPC', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('43', 'EVENT_SPELL_FADE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('44', 'EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('45', 'EVENT_COMBINE_SUCCESS', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('46', 'EVENT_COMBINE_FAILURE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('47', 'EVENT_ITEM_CLICK', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('48', 'EVENT_ITEM_CLICK_CAST', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('49', 'EVENT_GROUP_CHANGE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('50', 'EVENT_FORAGE_SUCCESS', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('51', 'EVENT_FORAGE_FAILURE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('52', 'EVENT_FISH_START', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('53', 'EVENT_FISH_SUCCESS', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('54', 'EVENT_FISH_FAILURE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('55', 'EVENT_CLICK_OBJECT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('56', 'EVENT_DISCOVER_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('57', 'EVENT_DISCONNECT', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('58', 'EVENT_CONNECT', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('59', 'EVENT_ITEM_TICK', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('60', 'EVENT_DUEL_WIN', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('61', 'EVENT_DUEL_LOSE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('62', 'EVENT_ENCOUNTER_LOAD', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('63', 'EVENT_ENCOUNTER_UNLOAD', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('64', 'EVENT_SAY', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('65', 'EVENT_DROP_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('66', 'EVENT_DESTROY_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('67', 'EVENT_FEIGN_DEATH', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('68', 'EVENT_WEAPON_PROC', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('69', 'EVENT_EQUIP_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('70', 'EVENT_UNEQUIP_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('71', 'EVENT_AUGMENT_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('72', 'EVENT_UNAUGMENT_ITEM', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('73', 'EVENT_AUGMENT_INSERT', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('74', 'EVENT_AUGMENT_REMOVE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('75', 'EVENT_ENTER_AREA', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('76', 'EVENT_LEAVE_AREA', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('77', 'EVENT_RESPAWN', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('78', 'EVENT_DEATH_COMPLETE', '1', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('79', 'EVENT_UNHANDLED_OPCODE', '0', '1', '1', '0', '1');
|
||||
INSERT INTO `perl_event_export_settings` VALUES ('80', 'EVENT_TICK', '0', '1', '1', '0', '1');
|
||||
@ -0,0 +1,2 @@
|
||||
UPDATE `rule_values` SET `rule_value` = '6000' WHERE `rule_value` = '500' AND `rule_name` = 'Spells:AI_IdleNoSpellMinRecast';
|
||||
UPDATE `rule_values` SET `rule_value` = '60000' WHERE `rule_value` = '2000' AND `rule_name` = 'Spells:AI_IdleNoSpellMaxRecast';
|
||||
@ -283,57 +283,84 @@ void ZSList::ListLockedZones(const char* to, WorldTCPConnection* connection) {
|
||||
}
|
||||
|
||||
void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* connection) {
|
||||
|
||||
LinkedListIterator<ZoneServer*> iterator(list);
|
||||
struct in_addr in;
|
||||
|
||||
iterator.Reset();
|
||||
char locked[4];
|
||||
if (WorldConfig::get()->Locked == true)
|
||||
if (WorldConfig::get()->Locked == true){
|
||||
strcpy(locked, "Yes");
|
||||
else
|
||||
}
|
||||
else {
|
||||
strcpy(locked, "No");
|
||||
}
|
||||
|
||||
char* output = 0;
|
||||
uint32 outsize = 0, outlen = 0;
|
||||
if (connection->IsConsole())
|
||||
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s\r\n", locked);
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s^", locked);
|
||||
if (connection->IsConsole())
|
||||
}
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:\r\n");
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:^");
|
||||
// connection->SendEmoteMessage(to, 0, 0, 0, "World Locked: %s", locked);
|
||||
// connection->SendEmoteMessage(to, 0, 0, 0, "Zoneservers online:");
|
||||
int v=0, w=0, x=0, y=0, z=0;
|
||||
char tmpStatic[2] = { 0, 0 }, tmpZone[64];
|
||||
memset(tmpZone, 0, sizeof(tmpZone));
|
||||
ZoneServer* zs = 0;
|
||||
while(iterator.MoreElements()) {
|
||||
zs = iterator.GetData();
|
||||
in.s_addr = zs->GetIP();
|
||||
}
|
||||
|
||||
if(zs->IsStaticZone())
|
||||
int v = 0, w = 0, x = 0, y = 0, z = 0;
|
||||
char is_static_string[2] = { 0, 0 }, zone_data_string[64];
|
||||
memset(zone_data_string, 0, sizeof(zone_data_string));
|
||||
|
||||
ZoneServer* zone_server_data = 0;
|
||||
|
||||
while (iterator.MoreElements()) {
|
||||
zone_server_data = iterator.GetData();
|
||||
in.s_addr = zone_server_data->GetIP();
|
||||
|
||||
if (zone_server_data->IsStaticZone()){
|
||||
z++;
|
||||
else if (zs->GetZoneID() != 0)
|
||||
}
|
||||
else if (zone_server_data->GetZoneID() != 0){
|
||||
w++;
|
||||
else if(zs->GetZoneID() == 0 && !zs->IsBootingUp())
|
||||
}
|
||||
else if (zone_server_data->GetZoneID() == 0 && !zone_server_data->IsBootingUp()){
|
||||
v++;
|
||||
}
|
||||
|
||||
if (zs->IsStaticZone())
|
||||
tmpStatic[0] = 'S';
|
||||
if (zone_server_data->IsStaticZone())
|
||||
is_static_string[0] = 'S';
|
||||
else
|
||||
tmpStatic[0] = ' ';
|
||||
is_static_string[0] = 'D';
|
||||
|
||||
if (admin >= 150) {
|
||||
if (zs->GetZoneID())
|
||||
snprintf(tmpZone, sizeof(tmpZone), "%s (%i)", zs->GetZoneName(), zs->GetZoneID());
|
||||
else if (zs->IsBootingUp())
|
||||
strcpy(tmpZone, "...");
|
||||
else
|
||||
tmpZone[0] = 0;
|
||||
if (zone_server_data->GetZoneID()){
|
||||
snprintf(zone_data_string, sizeof(zone_data_string), "%s (%i)", zone_server_data->GetZoneName(), zone_server_data->GetZoneID());
|
||||
}
|
||||
else if (zone_server_data->IsBootingUp()){
|
||||
strcpy(zone_data_string, "...");
|
||||
}
|
||||
else{
|
||||
zone_data_string[0] = 0;
|
||||
}
|
||||
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%-3i %s %15s:%-5i %2i %s:%i %s", zs->GetID(), tmpStatic, inet_ntoa(in), zs->GetPort(), zs->NumPlayers(), zs->GetCAddress(), zs->GetCPort(), tmpZone);
|
||||
AppendAnyLenString(&output, &outsize, &outlen,
|
||||
"#%-3i :: %s :: %15s:%-5i :: %2i :: %s:%i :: %s :: (%u)",
|
||||
zone_server_data->GetID(),
|
||||
is_static_string,
|
||||
inet_ntoa(in),
|
||||
zone_server_data->GetPort(),
|
||||
zone_server_data->NumPlayers(),
|
||||
zone_server_data->GetCAddress(),
|
||||
zone_server_data->GetCPort(),
|
||||
zone_data_string,
|
||||
zone_server_data->GetZoneOSProcessID()
|
||||
);
|
||||
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
@ -348,12 +375,12 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con
|
||||
}
|
||||
x++;
|
||||
}
|
||||
else if (zs->GetZoneID() != 0) {
|
||||
if (zs->GetZoneID())
|
||||
strcpy(tmpZone, zs->GetZoneName());
|
||||
else if (zone_server_data->GetZoneID() != 0) {
|
||||
if (zone_server_data->GetZoneID())
|
||||
strcpy(zone_data_string, zone_server_data->GetZoneName());
|
||||
else
|
||||
tmpZone[0] = 0;
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zs->GetID(), tmpStatic, tmpZone);
|
||||
zone_data_string[0] = 0;
|
||||
AppendAnyLenString(&output, &outsize, &outlen, " #%i %s %s", zone_server_data->GetID(), is_static_string, zone_data_string);
|
||||
if (outlen >= 3584) {
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
safe_delete(output);
|
||||
@ -361,25 +388,32 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con
|
||||
outlen = 0;
|
||||
}
|
||||
else {
|
||||
if (connection->IsConsole())
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
|
||||
else
|
||||
}
|
||||
else{
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "^");
|
||||
}
|
||||
}
|
||||
x++;
|
||||
}
|
||||
y++;
|
||||
iterator.Advance();
|
||||
}
|
||||
if (connection->IsConsole())
|
||||
|
||||
if (connection->IsConsole()){
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.\r\n", x, y);
|
||||
else
|
||||
}
|
||||
else {
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.^", x, y);
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
|
||||
// connection->SendEmoteMessage(to, 0, 0, "%i servers listed. %i servers online.", x, y);
|
||||
// connection->SendEmoteMessage(to,0,0,"%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
|
||||
if (output)
|
||||
}
|
||||
|
||||
AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.", z, w, v);
|
||||
|
||||
if (output){
|
||||
connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
|
||||
}
|
||||
|
||||
safe_delete(output);
|
||||
}
|
||||
|
||||
|
||||
@ -49,20 +49,24 @@ extern QueryServConnection QSLink;
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
ZoneServer::ZoneServer(EmuTCPConnection* itcpc)
|
||||
: WorldTCPConnection(), tcpc(itcpc), ls_zboot(5000) {
|
||||
ID = zoneserver_list.GetNextID();
|
||||
: WorldTCPConnection(), tcpc(itcpc), zone_boot_timer(5000) {
|
||||
|
||||
/* Set Process tracking variable defaults */
|
||||
|
||||
memset(zone_name, 0, sizeof(zone_name));
|
||||
memset(compiled, 0, sizeof(compiled));
|
||||
zoneID = 0;
|
||||
instanceID = 0;
|
||||
memset(client_address, 0, sizeof(client_address));
|
||||
memset(client_local_address, 0, sizeof(client_local_address));
|
||||
|
||||
memset(clientaddress, 0, sizeof(clientaddress));
|
||||
memset(clientlocaladdress, 0, sizeof(clientlocaladdress));
|
||||
clientport = 0;
|
||||
BootingUp = false;
|
||||
authenticated = false;
|
||||
staticzone = false;
|
||||
pNumPlayers = 0;
|
||||
zone_server_id = zoneserver_list.GetNextID();
|
||||
zone_server_zone_id = 0;
|
||||
instance_id = 0;
|
||||
zone_os_process_id = 0;
|
||||
client_port = 0;
|
||||
is_booting_up = false;
|
||||
is_authenticated = false;
|
||||
is_static_zone = false;
|
||||
zone_player_count = 0;
|
||||
}
|
||||
|
||||
ZoneServer::~ZoneServer() {
|
||||
@ -72,7 +76,7 @@ ZoneServer::~ZoneServer() {
|
||||
}
|
||||
|
||||
bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
BootingUp = false;
|
||||
is_booting_up = false;
|
||||
|
||||
const char* zn = MakeLowerString(database.GetZoneName(iZoneID));
|
||||
char* longname;
|
||||
@ -81,17 +85,17 @@ bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Setting to '%s' (%d:%d)%s",(zn) ? zn : "",iZoneID, iInstanceID,
|
||||
iStaticZone ? " (Static)" : "");
|
||||
|
||||
zoneID = iZoneID;
|
||||
instanceID = iInstanceID;
|
||||
zone_server_zone_id = iZoneID;
|
||||
instance_id = iInstanceID;
|
||||
if(iZoneID!=0)
|
||||
oldZoneID = iZoneID;
|
||||
if (zoneID == 0) {
|
||||
zone_server_previous_zone_id = iZoneID;
|
||||
if (zone_server_zone_id == 0) {
|
||||
client_list.CLERemoveZSRef(this);
|
||||
pNumPlayers = 0;
|
||||
zone_player_count = 0;
|
||||
LSSleepUpdate(GetPrevZoneID());
|
||||
}
|
||||
|
||||
staticzone = iStaticZone;
|
||||
is_static_zone = iStaticZone;
|
||||
|
||||
if (zn)
|
||||
{
|
||||
@ -111,7 +115,7 @@ bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
}
|
||||
|
||||
client_list.ZoneBootup(this);
|
||||
ls_zboot.Start();
|
||||
zone_boot_timer.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -172,19 +176,19 @@ void ZoneServer::LSSleepUpdate(uint32 zoneid){
|
||||
bool ZoneServer::Process() {
|
||||
if (!tcpc->Connected())
|
||||
return false;
|
||||
if(ls_zboot.Check()){
|
||||
if(zone_boot_timer.Check()){
|
||||
LSBootUpdate(GetZoneID(), true);
|
||||
ls_zboot.Disable();
|
||||
zone_boot_timer.Disable();
|
||||
}
|
||||
ServerPacket *pack = 0;
|
||||
while((pack = tcpc->PopPacket())) {
|
||||
if (!authenticated) {
|
||||
if (!is_authenticated) {
|
||||
if (WorldConfig::get()->SharedKey.length() > 0) {
|
||||
if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) {
|
||||
uint8 tmppass[16];
|
||||
MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass);
|
||||
if (memcmp(pack->pBuffer, tmppass, 16) == 0)
|
||||
authenticated = true;
|
||||
is_authenticated = true;
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
@ -210,7 +214,7 @@ bool ZoneServer::Process() {
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthroized zone access.");
|
||||
authenticated = true;
|
||||
is_authenticated = true;
|
||||
}
|
||||
}
|
||||
switch(pack->opcode) {
|
||||
@ -582,29 +586,33 @@ bool ZoneServer::Process() {
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer;
|
||||
|
||||
if (!sci->port) {
|
||||
clientport = zoneserver_list.GetAvailableZonePort();
|
||||
client_port = zoneserver_list.GetAvailableZonePort();
|
||||
|
||||
ServerPacket p(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo));
|
||||
memset(p.pBuffer,0,sizeof(ServerConnectInfo));
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*) p.pBuffer;
|
||||
sci->port = clientport;
|
||||
sci->port = client_port;
|
||||
SendPacket(&p);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",clientport);
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",client_port);
|
||||
} else {
|
||||
clientport = sci->port;
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",clientport);
|
||||
client_port = sci->port;
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",client_port);
|
||||
}
|
||||
|
||||
if(sci->address[0]) {
|
||||
strn0cpy(clientaddress, sci->address, 250);
|
||||
strn0cpy(client_address, sci->address, 250);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone specified address %s.", sci->address);
|
||||
}
|
||||
|
||||
if(sci->local_address[0]) {
|
||||
strn0cpy(clientlocaladdress, sci->local_address, 250);
|
||||
strn0cpy(client_local_address, sci->local_address, 250);
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "Zone specified local address %s.", sci->address);
|
||||
}
|
||||
|
||||
if (sci->process_id){
|
||||
zone_os_process_id = sci->process_id;
|
||||
}
|
||||
|
||||
}
|
||||
case ServerOP_SetLaunchName: {
|
||||
if(pack->size != sizeof(LaunchName_Struct))
|
||||
@ -818,6 +826,11 @@ bool ZoneServer::Process() {
|
||||
RuleManager::Instance()->LoadRules(&database, "default");
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadPerlExportSettings:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CameraShake:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
@ -1411,13 +1424,13 @@ void ZoneServer::ChangeWID(uint32 iCharID, uint32 iWID) {
|
||||
|
||||
|
||||
void ZoneServer::TriggerBootup(uint32 iZoneID, uint32 iInstanceID, const char* adminname, bool iMakeStatic) {
|
||||
BootingUp = true;
|
||||
zoneID = iZoneID;
|
||||
instanceID = iInstanceID;
|
||||
is_booting_up = true;
|
||||
zone_server_zone_id = iZoneID;
|
||||
instance_id = iInstanceID;
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_ZoneBootup, sizeof(ServerZoneStateChange_struct));
|
||||
ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer;
|
||||
s->ZoneServerID = ID;
|
||||
s->ZoneServerID = zone_server_id;
|
||||
if (adminname != 0)
|
||||
strcpy(s->adminname, adminname);
|
||||
|
||||
@ -1434,7 +1447,7 @@ void ZoneServer::TriggerBootup(uint32 iZoneID, uint32 iInstanceID, const char* a
|
||||
}
|
||||
|
||||
void ZoneServer::IncomingClient(Client* client) {
|
||||
BootingUp = true;
|
||||
is_booting_up = true;
|
||||
auto pack = new ServerPacket(ServerOP_ZoneIncClient, sizeof(ServerZoneIncomingClient_Struct));
|
||||
ServerZoneIncomingClient_Struct* s = (ServerZoneIncomingClient_Struct*) pack->pBuffer;
|
||||
s->zoneid = GetZoneID();
|
||||
|
||||
@ -44,7 +44,7 @@ public:
|
||||
void LSBootUpdate(uint32 zoneid, uint32 iInstanceID = 0, bool startup = false);
|
||||
void LSSleepUpdate(uint32 zoneid);
|
||||
void LSShutDownUpdate(uint32 zoneid);
|
||||
uint32 GetPrevZoneID() { return oldZoneID; }
|
||||
uint32 GetPrevZoneID() { return zone_server_previous_zone_id; }
|
||||
void ChangeWID(uint32 iCharID, uint32 iWID);
|
||||
void SendGroupIDs();
|
||||
|
||||
@ -52,41 +52,45 @@ public:
|
||||
inline const char* GetZoneLongName() const { return long_name; }
|
||||
const char* GetCompileTime() const{ return compiled; }
|
||||
void SetCompile(char* in_compile){ strcpy(compiled,in_compile); }
|
||||
inline uint32 GetZoneID() const { return zoneID; }
|
||||
inline uint32 GetZoneID() const { return zone_server_zone_id; }
|
||||
inline uint32 GetIP() const { return tcpc->GetrIP(); }
|
||||
inline uint16 GetPort() const { return tcpc->GetrPort(); }
|
||||
inline const char* GetCAddress() const { return clientaddress; }
|
||||
inline const char* GetCLocalAddress() const { return clientlocaladdress; }
|
||||
inline uint16 GetCPort() const { return clientport; }
|
||||
inline uint32 GetID() const { return ID; }
|
||||
inline bool IsBootingUp() const { return BootingUp; }
|
||||
inline bool IsStaticZone() const{ return staticzone; }
|
||||
inline uint32 NumPlayers() const { return pNumPlayers; }
|
||||
inline void AddPlayer() { pNumPlayers++; }
|
||||
inline void RemovePlayer() { pNumPlayers--; }
|
||||
inline const char* GetCAddress() const { return client_address; }
|
||||
inline const char* GetCLocalAddress() const { return client_local_address; }
|
||||
inline uint16 GetCPort() const { return client_port; }
|
||||
inline uint32 GetID() const { return zone_server_id; }
|
||||
inline bool IsBootingUp() const { return is_booting_up; }
|
||||
inline bool IsStaticZone() const{ return is_static_zone; }
|
||||
inline uint32 NumPlayers() const { return zone_player_count; }
|
||||
inline void AddPlayer() { zone_player_count++; }
|
||||
inline void RemovePlayer() { zone_player_count--; }
|
||||
inline const char * GetLaunchName() const { return(launcher_name.c_str()); }
|
||||
inline const char * GetLaunchedName() const { return(launched_name.c_str()); }
|
||||
|
||||
inline uint32 GetInstanceID() { return instanceID; }
|
||||
inline void SetInstanceID(uint32 i) { instanceID = i; }
|
||||
inline uint32 GetInstanceID() { return instance_id; }
|
||||
inline void SetInstanceID(uint32 i) { instance_id = i; }
|
||||
|
||||
inline uint32 GetZoneOSProcessID() { return zone_os_process_id; }
|
||||
|
||||
private:
|
||||
EmuTCPConnection* const tcpc;
|
||||
|
||||
uint32 ID;
|
||||
char clientaddress[250];
|
||||
char clientlocaladdress[250];
|
||||
uint16 clientport;
|
||||
bool BootingUp;
|
||||
bool staticzone;
|
||||
bool authenticated;
|
||||
uint32 pNumPlayers;
|
||||
uint32 zone_server_id;
|
||||
char client_address[250];
|
||||
char client_local_address[250];
|
||||
uint16 client_port;
|
||||
bool is_booting_up;
|
||||
bool is_static_zone;
|
||||
bool is_authenticated;
|
||||
uint32 zone_player_count;
|
||||
char compiled[25];
|
||||
char zone_name[32];
|
||||
char long_name[256];
|
||||
uint32 zoneID;
|
||||
uint32 oldZoneID;
|
||||
Timer ls_zboot;
|
||||
uint32 instanceID; //instance ids contain a zone id, and a zone version
|
||||
uint32 zone_server_zone_id;
|
||||
uint32 zone_server_previous_zone_id;
|
||||
Timer zone_boot_timer;
|
||||
uint32 instance_id; //instance ids contain a zone id, and a zone version
|
||||
uint32 zone_os_process_id;
|
||||
std::string launcher_name; //the launcher which started us
|
||||
std::string launched_name; //the name of the zone we launched.
|
||||
};
|
||||
|
||||
@ -1189,21 +1189,21 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
|
||||
}
|
||||
|
||||
void Mob::AddFeignMemory(Client* attacker) {
|
||||
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Start(AIfeignremember_delay);
|
||||
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Start(AIfeignremember_delay);
|
||||
feign_memory_list.insert(attacker->CharacterID());
|
||||
}
|
||||
|
||||
void Mob::RemoveFromFeignMemory(Client* attacker) {
|
||||
feign_memory_list.erase(attacker->CharacterID());
|
||||
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
if(feign_memory_list.empty())
|
||||
{
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
if(AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1220,8 +1220,8 @@ void Mob::ClearFeignMemory() {
|
||||
feign_memory_list.clear();
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
if(AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
}
|
||||
|
||||
bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
|
||||
24
zone/bot.cpp
24
zone/bot.cpp
@ -6,7 +6,7 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
// This constructor is used during the bot create command
|
||||
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm::vec4(), 0, false), rest_timer(1) {
|
||||
@ -2286,7 +2286,7 @@ bool Bot::Process() {
|
||||
|
||||
BuffProcess();
|
||||
CalcRestState();
|
||||
if(curfp)
|
||||
if(currently_fleeing)
|
||||
ProcessFlee();
|
||||
|
||||
if(GetHP() < GetMaxHP())
|
||||
@ -2685,7 +2685,7 @@ void Bot::AI_Process() {
|
||||
|
||||
if(GetHasBeenSummoned()) {
|
||||
if(IsBotCaster() || IsBotArcher()) {
|
||||
if (AImovement_timer->Check()) {
|
||||
if (AI_movement_timer->Check()) {
|
||||
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistanceSquaredNoZ(static_cast<glm::vec3>(m_Position), m_PreSummonLocation) < 10)) {
|
||||
if(GetTarget())
|
||||
FaceTarget(GetTarget());
|
||||
@ -2831,7 +2831,7 @@ void Bot::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
if(AImovement_timer->Check()) {
|
||||
if(AI_movement_timer->Check()) {
|
||||
if(!IsMoving() && GetClass() == ROGUE && !BehindMob(GetTarget(), GetX(), GetY())) {
|
||||
// Move the rogue to behind the mob
|
||||
float newX = 0;
|
||||
@ -2967,7 +2967,7 @@ void Bot::AI_Process() {
|
||||
AI_PursueCastCheck();
|
||||
}
|
||||
|
||||
if (AImovement_timer->Check()) {
|
||||
if (AI_movement_timer->Check()) {
|
||||
if(!IsRooted()) {
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
||||
@ -2995,7 +2995,7 @@ void Bot::AI_Process() {
|
||||
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||
SendRemovePlayerState(PlayerState::Aggressive);
|
||||
|
||||
if(!IsMoving() && AIthink_timer->Check() && !spellend_timer.Enabled()) {
|
||||
if(!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled()) {
|
||||
if(GetBotStance() != BotStancePassive) {
|
||||
if(!AI_IdleCastCheck() && !IsCasting())
|
||||
BotMeditate(true);
|
||||
@ -3004,7 +3004,7 @@ void Bot::AI_Process() {
|
||||
BotMeditate(true);
|
||||
}
|
||||
|
||||
if(AImovement_timer->Check()) {
|
||||
if(AI_movement_timer->Check()) {
|
||||
if(GetFollowID()) {
|
||||
Mob* follow = entity_list.GetMob(GetFollowID());
|
||||
if(follow) {
|
||||
@ -3737,9 +3737,9 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
|
||||
" `drakkin_tattoo`,"
|
||||
" `drakkin_details`,"
|
||||
" `ac`," /*not in-use[26]*/
|
||||
" `atk`,"
|
||||
" `atk`," /*not in-use[27]*/
|
||||
" `hp`,"
|
||||
" `mana`," /*not in-use[29]*/
|
||||
" `mana`,"
|
||||
" `str`," /*not in-use[30]*/
|
||||
" `sta`," /*not in-use[31]*/
|
||||
" `cha`," /*not in-use[32]*/
|
||||
@ -3753,8 +3753,8 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
|
||||
" `poison`," /*not in-use[40]*/
|
||||
" `disease`," /*not in-use[41]*/
|
||||
" `corruption`," /*not in-use[42]*/
|
||||
" `show_helm`,"
|
||||
" `follow_distance`"
|
||||
" `show_helm`,"//43
|
||||
" `follow_distance`"//44
|
||||
" FROM `bot_data`"
|
||||
" WHERE `bot_id` = '%u'",
|
||||
botID
|
||||
@ -3791,8 +3791,8 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
|
||||
atoi(row[23]),
|
||||
atoi(row[24]),
|
||||
atoi(row[25]),
|
||||
atoi(row[27]),
|
||||
atoi(row[28]),
|
||||
atoi(row[29]),
|
||||
defaultNPCTypeStruct.MR,
|
||||
defaultNPCTypeStruct.CR,
|
||||
defaultNPCTypeStruct.DR,
|
||||
|
||||
@ -53,7 +53,7 @@ extern volatile bool RunLoops;
|
||||
extern QueryServ* QServ;
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern uint32 numclients;
|
||||
extern PetitionList petition_list;
|
||||
@ -371,7 +371,7 @@ Client::~Client() {
|
||||
GetTarget()->IsTargeted(-1);
|
||||
|
||||
//if we are in a group and we are not zoning, force leave the group
|
||||
if(isgrouped && !zoning && ZoneLoaded)
|
||||
if(isgrouped && !zoning && is_zone_loaded)
|
||||
LeaveGroup();
|
||||
|
||||
UpdateWho(2);
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern EntityList entity_list;
|
||||
@ -386,6 +386,7 @@ void MapOpcodes()
|
||||
ConnectedOpcodes[OP_WhoAllRequest] = &Client::Handle_OP_WhoAllRequest;
|
||||
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
|
||||
ConnectedOpcodes[OP_XTargetAutoAddHaters] = &Client::Handle_OP_XTargetAutoAddHaters;
|
||||
ConnectedOpcodes[OP_XTargetOpen] = &Client::Handle_OP_XTargetOpen;
|
||||
ConnectedOpcodes[OP_XTargetRequest] = &Client::Handle_OP_XTargetRequest;
|
||||
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
|
||||
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
|
||||
@ -6682,20 +6683,6 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
|
||||
uint32 Action = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
|
||||
uint32 sentAction = Action;
|
||||
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
Action += 1;
|
||||
/*
|
||||
// Need to find all of the action types for RoF and switch case here
|
||||
switch(Action)
|
||||
{
|
||||
case 4:
|
||||
Action = 5;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (!IsInAGuild())
|
||||
{
|
||||
Message(13, "You must be in a Guild to use the Guild Bank.");
|
||||
@ -13925,6 +13912,18 @@ void Client::Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app)
|
||||
XTargetAutoAddHaters = app->ReadUInt8(0);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_XTargetOpen(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != 4) {
|
||||
Log.Out(Logs::General, Logs::None, "Size mismatch in OP_XTargetOpen, expected 1, got %i", app->size);
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_XTargetOpenResponse, 0);
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size < 12)
|
||||
|
||||
@ -292,6 +292,7 @@
|
||||
void Handle_OP_WearChange(const EQApplicationPacket *app);
|
||||
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetOpen(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
|
||||
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern EntityList entity_list;
|
||||
|
||||
@ -334,6 +334,7 @@ int command_init(void) {
|
||||
command_add("reloadallrules", "Executes a reload of all rules.", 80, command_reloadallrules) ||
|
||||
command_add("reloademote", "Reloads NPC Emotes", 80, command_reloademote) ||
|
||||
command_add("reloadlevelmods", nullptr,255, command_reloadlevelmods) ||
|
||||
command_add("reloadperlexportsettings", nullptr, 255, command_reloadperlexportsettings) ||
|
||||
command_add("reloadqst", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
|
||||
command_add("reloadquest", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
|
||||
command_add("reloadrulesworld", "Executes a reload of all rules in world specifically.", 80, command_reloadworldrules) ||
|
||||
@ -343,6 +344,7 @@ int command_init(void) {
|
||||
command_add("reloadzonepoints", "- Reload zone points from database", 150, command_reloadzps) ||
|
||||
command_add("reloadzps", nullptr,0, command_reloadzps) ||
|
||||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
|
||||
command_add("repopclose", "[distance in units] Repops only NPC's nearby for fast development purposes", 100, command_repopclose) ||
|
||||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
|
||||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
|
||||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
|
||||
@ -3920,9 +3922,11 @@ void command_repop(Client *c, const Seperator *sep)
|
||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
std::string query = StringFormat("DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
||||
(unsigned long)iterator.GetData()->GetID(),
|
||||
(unsigned long)zone->GetInstanceID());
|
||||
std::string query = StringFormat(
|
||||
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
||||
(unsigned long)iterator.GetData()->GetID(),
|
||||
(unsigned long)zone->GetInstanceID()
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
iterator.Advance();
|
||||
}
|
||||
@ -3939,6 +3943,33 @@ void command_repop(Client *c, const Seperator *sep)
|
||||
zone->Repop(atoi(sep->arg[timearg])*1000);
|
||||
}
|
||||
|
||||
void command_repopclose(Client *c, const Seperator *sep)
|
||||
{
|
||||
int repop_distance = 500;
|
||||
|
||||
if (sep->arg[1] && strcasecmp(sep->arg[1], "force") == 0) {
|
||||
|
||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
std::string query = StringFormat(
|
||||
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
||||
(unsigned long)iterator.GetData()->GetID(),
|
||||
(unsigned long)zone->GetInstanceID()
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
iterator.Advance();
|
||||
}
|
||||
c->Message(0, "Zone depop: Force resetting spawn timers.");
|
||||
}
|
||||
if (sep->IsNumber(1)) {
|
||||
repop_distance = atoi(sep->arg[1]);
|
||||
}
|
||||
|
||||
c->Message(0, "Zone depoped. Repopping NPC's within %i distance units", repop_distance);
|
||||
zone->RepopClose(c->GetPosition(), repop_distance);
|
||||
}
|
||||
|
||||
void command_spawnstatus(Client *c, const Seperator *sep)
|
||||
{
|
||||
if((sep->arg[1][0] == 'e') | (sep->arg[1][0] == 'E'))
|
||||
@ -10768,4 +10799,16 @@ void command_apply_shared_memory(Client *c, const Seperator *sep) {
|
||||
strcpy((char*)pack.pBuffer, hotfix_name.c_str());
|
||||
}
|
||||
worldserver.SendPacket(&pack);
|
||||
}
|
||||
|
||||
void command_reloadperlexportsettings(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_ReloadPerlExportSettings, 0);
|
||||
worldserver.SendPacket(pack);
|
||||
c->Message(13, "Successfully sent the packet to world to reload Perl Export settings");
|
||||
safe_delete(pack);
|
||||
|
||||
}
|
||||
}
|
||||
@ -187,6 +187,7 @@ void command_myskills(Client *c, const Seperator *sep);
|
||||
void command_depop(Client *c, const Seperator *sep);
|
||||
void command_depopzone(Client *c, const Seperator *sep);
|
||||
void command_repop(Client *c, const Seperator *sep);
|
||||
void command_repopclose(Client *c, const Seperator *sep);
|
||||
void command_spawnstatus(Client *c, const Seperator *sep);
|
||||
void command_nukebuffs(Client *c, const Seperator *sep);
|
||||
void command_zuwcoords(Client *c, const Seperator *sep);
|
||||
@ -332,6 +333,7 @@ void command_load_shared_memory(Client *c, const Seperator *sep);
|
||||
void command_apply_shared_memory(Client *c, const Seperator *sep);
|
||||
void command_untraindisc(Client *c, const Seperator *sep);
|
||||
void command_untraindiscs(Client *c, const Seperator *sep);
|
||||
void command_reloadperlexportsettings(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
|
||||
@ -183,15 +183,31 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
||||
|
||||
int char_id = 0;
|
||||
ExportCharID(package_name, char_id, npcmob, mob);
|
||||
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, npcmob, mob, char_id);
|
||||
|
||||
/* Check for QGlobal export event enable */
|
||||
if (parse->perl_event_export_settings[event].qglobals){
|
||||
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, npcmob, mob, char_id);
|
||||
}
|
||||
|
||||
//ExportGenericVariables();
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, mob, npcmob);
|
||||
ExportZoneVariables(package_name);
|
||||
ExportItemVariables(package_name, mob);
|
||||
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
|
||||
/* Check for Mob export event enable */
|
||||
if (parse->perl_event_export_settings[event].mob){
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, mob, npcmob);
|
||||
}
|
||||
|
||||
/* Check for Zone export event enable */
|
||||
if (parse->perl_event_export_settings[event].zone){
|
||||
ExportZoneVariables(package_name);
|
||||
}
|
||||
|
||||
/* Check for Item export event enable */
|
||||
if (parse->perl_event_export_settings[event].item){
|
||||
ExportItemVariables(package_name, mob);
|
||||
}
|
||||
|
||||
/* Check for Event export event enable */
|
||||
if (parse->perl_event_export_settings[event].event_variables){
|
||||
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
|
||||
}
|
||||
|
||||
if(isPlayerQuest || isGlobalPlayerQuest){
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
|
||||
@ -199,8 +215,7 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
||||
else if(isItemQuest) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
|
||||
}
|
||||
else if(isSpellQuest)
|
||||
{
|
||||
else if(isSpellQuest){
|
||||
if(mob) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
|
||||
} else {
|
||||
|
||||
@ -75,6 +75,7 @@ public:
|
||||
virtual std::string GetVar(std::string name);
|
||||
virtual void ReloadQuests();
|
||||
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
|
||||
|
||||
private:
|
||||
Embperl *perl;
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
#endif
|
||||
|
||||
extern Zone *zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern NetConnection net;
|
||||
extern uint32 numclients;
|
||||
@ -2350,7 +2350,7 @@ void EntityList::Clear()
|
||||
|
||||
void EntityList::UpdateWho(bool iSendFullUpdate)
|
||||
{
|
||||
if ((!worldserver.Connected()) || !ZoneLoaded)
|
||||
if ((!worldserver.Connected()) || !is_zone_loaded)
|
||||
return;
|
||||
uint32 tmpNumUpdates = numclients + 5;
|
||||
ServerPacket* pack = 0;
|
||||
@ -2448,6 +2448,8 @@ void EntityList::Depop(bool StartSpawnTimer)
|
||||
if (pnpc->IsFindable())
|
||||
UpdateFindableNPCState(pnpc, true);
|
||||
|
||||
pnpc->WipeHateList();
|
||||
|
||||
pnpc->Depop(StartSpawnTimer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ extern Zone* zone;
|
||||
//this is called whenever we are damaged to process possible fleeing
|
||||
void Mob::CheckFlee() {
|
||||
//if were allready fleeing, dont need to check more...
|
||||
if(flee_mode && curfp)
|
||||
if(flee_mode && currently_fleeing)
|
||||
return;
|
||||
|
||||
//dont bother if we are immune to fleeing
|
||||
@ -101,7 +101,7 @@ void Mob::ProcessFlee()
|
||||
//When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee.
|
||||
if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) &&
|
||||
!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ void Mob::ProcessFlee()
|
||||
//see if we are legitimately feared or blind now
|
||||
if (!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
|
||||
//not feared or blind... were done...
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ void Mob::CalculateNewFearpoint()
|
||||
if(Route.size() > 0)
|
||||
{
|
||||
m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z);
|
||||
curfp = true;
|
||||
currently_fleeing = true;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
|
||||
return;
|
||||
@ -151,7 +151,7 @@ void Mob::CalculateNewFearpoint()
|
||||
|
||||
int loop = 0;
|
||||
float ranx, rany, ranz;
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
while (loop < 100) //Max 100 tries
|
||||
{
|
||||
int ran = 250 - (loop*2);
|
||||
@ -164,11 +164,11 @@ void Mob::CalculateNewFearpoint()
|
||||
float fdist = ranz - GetZ();
|
||||
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
|
||||
{
|
||||
curfp = true;
|
||||
currently_fleeing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curfp)
|
||||
if (currently_fleeing)
|
||||
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
||||
else //Break fear
|
||||
BuffFadeByEffect(SE_Fear);
|
||||
|
||||
@ -248,7 +248,9 @@ void Client::RefreshGuildInfo()
|
||||
|
||||
if((guild_id != OldGuildID) && GuildBanks)
|
||||
{
|
||||
ClearGuildBank();
|
||||
// Unsure about this for RoF+ ... But they don't have that action anymore so fuck it
|
||||
if (GetClientVersion() < ClientVersion::RoF)
|
||||
ClearGuildBank();
|
||||
|
||||
if(guild_id != GUILD_NONE)
|
||||
GuildBanks->SendGuildBank(this);
|
||||
|
||||
@ -29,7 +29,7 @@ ZoneGuildManager guild_mgr;
|
||||
GuildBankManager *GuildBanks;
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
void ZoneGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation) {
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild refresh for %d to world, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
|
||||
@ -334,7 +334,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_GuildRankUpdate:
|
||||
{
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
if(pack->size != sizeof(ServerGuildRankUpdate_Struct))
|
||||
{
|
||||
@ -388,7 +388,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
{
|
||||
ServerGuildMemberUpdate_Struct *sgmus = (ServerGuildMemberUpdate_Struct*)pack->pBuffer;
|
||||
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
|
||||
@ -407,7 +407,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
break;
|
||||
}
|
||||
case ServerOP_OnlineGuildMembersResponse:
|
||||
if (ZoneLoaded)
|
||||
if (is_zone_loaded)
|
||||
{
|
||||
char *Buffer = (char *)pack->pBuffer;
|
||||
|
||||
@ -443,7 +443,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_LFGuildUpdate:
|
||||
{
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
char GuildName[33];
|
||||
char Comments[257];
|
||||
@ -688,11 +688,68 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
return;
|
||||
}
|
||||
|
||||
auto &guild_bank = *Iterator;
|
||||
|
||||
// RoF+ uses a bulk list packet -- This is also how the Action 0 of older clients basically works
|
||||
if (c->GetClientVersionBit() & BIT_RoFAndLater) {
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBankItemList, sizeof(GuildBankItemListEntry_Struct) * 240);
|
||||
for (int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) {
|
||||
const Item_Struct *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
|
||||
if (Item) {
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Permissions);
|
||||
outapp->WriteString(guild_bank->Items.DepositArea[i].WhoFor);
|
||||
outapp->WriteString(guild_bank->Items.DepositArea[i].Donator);
|
||||
outapp->WriteUInt32(Item->ID);
|
||||
outapp->WriteUInt32(Item->Icon);
|
||||
if (Item->Stackable) {
|
||||
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Quantity);
|
||||
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.DepositArea[i].Quantity ? 0 : 1);
|
||||
} else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt8(0);
|
||||
}
|
||||
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
|
||||
outapp->WriteString(Item->Name);
|
||||
} else {
|
||||
outapp->WriteUInt8(0); // empty
|
||||
}
|
||||
}
|
||||
outapp->SetWritePosition(outapp->GetWritePosition() + 20); // newer clients have 40 deposit slots, keep them 0 for now
|
||||
|
||||
for (int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) {
|
||||
const Item_Struct *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
|
||||
if (Item) {
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Permissions);
|
||||
outapp->WriteString(guild_bank->Items.MainArea[i].WhoFor);
|
||||
outapp->WriteString(guild_bank->Items.MainArea[i].Donator);
|
||||
outapp->WriteUInt32(Item->ID);
|
||||
outapp->WriteUInt32(Item->Icon);
|
||||
if (Item->Stackable) {
|
||||
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Quantity);
|
||||
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.MainArea[i].Quantity ? 0 : 1);
|
||||
} else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt8(0);
|
||||
}
|
||||
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
|
||||
outapp->WriteString(Item->Name);
|
||||
} else {
|
||||
outapp->WriteUInt8(0); // empty
|
||||
}
|
||||
}
|
||||
|
||||
outapp->size = outapp->GetWritePosition(); // truncate to used size
|
||||
c->FastQueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
||||
{
|
||||
if((*Iterator)->Items.DepositArea[i].ItemID > 0)
|
||||
if(guild_bank->Items.DepositArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID);
|
||||
const Item_Struct *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
@ -703,22 +760,22 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
|
||||
if(!Item->Stackable)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon, 1,
|
||||
(*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
|
||||
guild_bank->Items.DepositArea[i].Permissions, 0, 0);
|
||||
else
|
||||
{
|
||||
if((*Iterator)->Items.DepositArea[i].Quantity == Item->StackSize)
|
||||
if(guild_bank->Items.DepositArea[i].Quantity == Item->StackSize)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
|
||||
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 0, 0);
|
||||
else
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 1, 0);
|
||||
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 1, 0);
|
||||
}
|
||||
|
||||
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
|
||||
|
||||
strn0cpy(gbius->Donator, (*Iterator)->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
|
||||
strn0cpy(gbius->Donator, guild_bank->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
|
||||
|
||||
strn0cpy(gbius->WhoFor, (*Iterator)->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
strn0cpy(gbius->WhoFor, guild_bank->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
|
||||
c->FastQueuePacket(&outapp);
|
||||
}
|
||||
@ -726,9 +783,9 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||
{
|
||||
if((*Iterator)->Items.MainArea[i].ItemID > 0)
|
||||
if(guild_bank->Items.MainArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID);
|
||||
const Item_Struct *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
@ -741,22 +798,22 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
|
||||
if(!Item->Stackable)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon, 1,
|
||||
(*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
|
||||
guild_bank->Items.MainArea[i].Permissions, 0, Useable);
|
||||
else
|
||||
{
|
||||
if((*Iterator)->Items.MainArea[i].Quantity == Item->StackSize)
|
||||
if(guild_bank->Items.MainArea[i].Quantity == Item->StackSize)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
|
||||
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 0, Useable);
|
||||
else
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 1, Useable);
|
||||
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 1, Useable);
|
||||
}
|
||||
|
||||
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
|
||||
|
||||
strn0cpy(gbius->Donator, (*Iterator)->Items.MainArea[i].Donator, sizeof(gbius->Donator));
|
||||
strn0cpy(gbius->Donator, guild_bank->Items.MainArea[i].Donator, sizeof(gbius->Donator));
|
||||
|
||||
strn0cpy(gbius->WhoFor, (*Iterator)->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
strn0cpy(gbius->WhoFor, guild_bank->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
|
||||
c->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/rulesys.h"
|
||||
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
||||
: NPC(d, nullptr, glm::vec4(x, y, z, heading), 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
|
||||
@ -1428,7 +1428,7 @@ void Merc::AI_Process() {
|
||||
|
||||
if(RuleB(Combat, EnableFearPathing)) {
|
||||
CalculateNewFearpoint();
|
||||
if(curfp) {
|
||||
if(currently_fleeing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1500,7 +1500,7 @@ void Merc::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
if(AImovement_timer->Check())
|
||||
if(AI_movement_timer->Check())
|
||||
{
|
||||
if(!IsMoving() && GetClass() == ROGUE && !BehindMob(GetTarget(), GetX(), GetY()))
|
||||
{
|
||||
@ -1645,7 +1645,7 @@ void Merc::AI_Process() {
|
||||
AI_PursueCastCheck();
|
||||
}
|
||||
|
||||
if (AImovement_timer->Check())
|
||||
if (AI_movement_timer->Check())
|
||||
{
|
||||
if(!IsRooted()) {
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
||||
@ -1687,7 +1687,7 @@ void Merc::AI_Process() {
|
||||
if(!check_target_timer.Enabled())
|
||||
check_target_timer.Start(2000, false);
|
||||
|
||||
if(!IsMoving() && AIthink_timer->Check() && !spellend_timer.Enabled())
|
||||
if(!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled())
|
||||
{
|
||||
//TODO: Implement passive stances.
|
||||
//if(GetStance() != MercStancePassive) {
|
||||
@ -1698,7 +1698,7 @@ void Merc::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
if(AImovement_timer->Check())
|
||||
if(AI_movement_timer->Check())
|
||||
{
|
||||
if(GetFollowID())
|
||||
{
|
||||
@ -5777,7 +5777,7 @@ bool Merc::RemoveMercFromGroup(Merc* merc, Group* group) {
|
||||
{
|
||||
merc->SetFollowID(0);
|
||||
|
||||
if (group->GroupCount() <= 2 && merc->GetGroup() == group && ZoneLoaded)
|
||||
if (group->GroupCount() <= 2 && merc->GetGroup() == group && is_zone_loaded)
|
||||
{
|
||||
group->DisbandGroup();
|
||||
}
|
||||
|
||||
@ -192,6 +192,7 @@ public:
|
||||
virtual void ScaleStats(int scalepercent, bool setmax = false);
|
||||
virtual void CalcBonuses();
|
||||
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
|
||||
inline uint8 GetEndurancePercent() { return (uint8)((float)cur_end / (float)max_end * 100.0f); }
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetATK() const { return ATK; }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
|
||||
14
zone/mob.cpp
14
zone/mob.cpp
@ -113,7 +113,7 @@ Mob::Mob(const char* in_name,
|
||||
targeted = 0;
|
||||
tar_ndx=0;
|
||||
tar_vector=0;
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
|
||||
AI_Init();
|
||||
SetMoving(false);
|
||||
@ -371,7 +371,7 @@ Mob::Mob(const char* in_name,
|
||||
follow=0;
|
||||
follow_dist = 100; // Default Distance for Follow
|
||||
flee_mode = false;
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
flee_timer.Start();
|
||||
|
||||
permarooted = (runspeed > 0) ? false : true;
|
||||
@ -503,13 +503,9 @@ void Mob::SetInvisible(uint8 state)
|
||||
SendAppearancePacket(AT_Invis, invisible);
|
||||
// Invis and hide breaks charms
|
||||
|
||||
if ((this->GetPetType() == petCharmed) && (invisible || hidden || improved_hidden))
|
||||
{
|
||||
Mob* formerpet = this->GetPet();
|
||||
|
||||
if(formerpet)
|
||||
formerpet->BuffFadeByEffect(SE_Charm);
|
||||
}
|
||||
auto formerpet = GetPet();
|
||||
if (formerpet && formerpet->GetPetType() == petCharmed && (invisible || hidden || improved_hidden))
|
||||
formerpet->BuffFadeByEffect(SE_Charm);
|
||||
}
|
||||
|
||||
//check to see if `this` is invisible to `other`
|
||||
|
||||
19
zone/mob.h
19
zone/mob.h
@ -925,8 +925,8 @@ public:
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
|
||||
|
||||
inline bool IsTrackable() const { return(trackable); }
|
||||
Timer* GetAIThinkTimer() { return AIthink_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AImovement_timer.get(); }
|
||||
Timer* GetAIThinkTimer() { return AI_think_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AI_movement_timer.get(); }
|
||||
Timer GetAttackTimer() { return attack_timer; }
|
||||
Timer GetAttackDWTimer() { return attack_dw_timer; }
|
||||
inline bool IsFindable() { return findable; }
|
||||
@ -1254,14 +1254,15 @@ protected:
|
||||
uint32 maxLastFightingDelayMoving;
|
||||
float pAggroRange;
|
||||
float pAssistRange;
|
||||
std::unique_ptr<Timer> AIthink_timer;
|
||||
std::unique_ptr<Timer> AImovement_timer;
|
||||
std::unique_ptr<Timer> AItarget_check_timer;
|
||||
std::unique_ptr<Timer> AI_think_timer;
|
||||
std::unique_ptr<Timer> AI_movement_timer;
|
||||
std::unique_ptr<Timer> AI_target_check_timer;
|
||||
bool movetimercompleted;
|
||||
bool permarooted;
|
||||
std::unique_ptr<Timer> AIscanarea_timer;
|
||||
std::unique_ptr<Timer> AIwalking_timer;
|
||||
std::unique_ptr<Timer> AIfeignremember_timer;
|
||||
std::unique_ptr<Timer> AI_scan_area_timer;
|
||||
std::unique_ptr<Timer> AI_walking_timer;
|
||||
std::unique_ptr<Timer> AI_feign_remember_timer;
|
||||
std::unique_ptr<Timer> AI_check_signal_timer;
|
||||
uint32 pLastFightingDelayMoving;
|
||||
HateList hate_list;
|
||||
std::set<uint32> feign_memory_list;
|
||||
@ -1295,7 +1296,7 @@ protected:
|
||||
|
||||
int patrol;
|
||||
glm::vec3 m_FearWalkTarget;
|
||||
bool curfp;
|
||||
bool currently_fleeing;
|
||||
|
||||
// Pathing
|
||||
//
|
||||
|
||||
110
zone/mob_ai.cpp
110
zone/mob_ai.cpp
@ -423,12 +423,14 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
|
||||
void Mob::AI_Init()
|
||||
{
|
||||
pAIControlled = false;
|
||||
AIthink_timer.reset(nullptr);
|
||||
AIwalking_timer.reset(nullptr);
|
||||
AImovement_timer.reset(nullptr);
|
||||
AItarget_check_timer.reset(nullptr);
|
||||
AIfeignremember_timer.reset(nullptr);
|
||||
AIscanarea_timer.reset(nullptr);
|
||||
AI_think_timer.reset(nullptr);
|
||||
AI_walking_timer.reset(nullptr);
|
||||
AI_movement_timer.reset(nullptr);
|
||||
AI_target_check_timer.reset(nullptr);
|
||||
AI_feign_remember_timer.reset(nullptr);
|
||||
AI_scan_area_timer.reset(nullptr);
|
||||
AI_check_signal_timer.reset(nullptr);
|
||||
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
|
||||
@ -472,16 +474,18 @@ void Mob::AI_Start(uint32 iMoveDelay) {
|
||||
pLastFightingDelayMoving = 0;
|
||||
|
||||
pAIControlled = true;
|
||||
AIthink_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
|
||||
AIthink_timer->Trigger();
|
||||
AIwalking_timer = std::unique_ptr<Timer>(new Timer(0));
|
||||
AImovement_timer = std::unique_ptr<Timer>(new Timer(AImovement_duration));
|
||||
AItarget_check_timer = std::unique_ptr<Timer>(new Timer(AItarget_check_duration));
|
||||
AIfeignremember_timer = std::unique_ptr<Timer>(new Timer(AIfeignremember_delay));
|
||||
AIscanarea_timer = std::unique_ptr<Timer>(new Timer(AIscanarea_delay));
|
||||
AI_think_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
|
||||
AI_think_timer->Trigger();
|
||||
AI_walking_timer = std::unique_ptr<Timer>(new Timer(0));
|
||||
AI_movement_timer = std::unique_ptr<Timer>(new Timer(AImovement_duration));
|
||||
AI_target_check_timer = std::unique_ptr<Timer>(new Timer(AItarget_check_duration));
|
||||
AI_feign_remember_timer = std::unique_ptr<Timer>(new Timer(AIfeignremember_delay));
|
||||
AI_scan_area_timer = std::unique_ptr<Timer>(new Timer(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax))));
|
||||
AI_check_signal_timer = std::unique_ptr<Timer>(new Timer(AI_check_signal_timer_delay));
|
||||
|
||||
#ifdef REVERSE_AGGRO
|
||||
if(IsNPC() && !CastToNPC()->WillAggroNPCs())
|
||||
AIscanarea_timer->Disable();
|
||||
AI_scan_area_timer->Disable();
|
||||
#endif
|
||||
|
||||
if (GetAggroRange() == 0)
|
||||
@ -538,12 +542,13 @@ void Mob::AI_Stop() {
|
||||
|
||||
pAIControlled = false;
|
||||
|
||||
AIthink_timer.reset(nullptr);
|
||||
AIwalking_timer.reset(nullptr);
|
||||
AImovement_timer.reset(nullptr);
|
||||
AItarget_check_timer.reset(nullptr);
|
||||
AIscanarea_timer.reset(nullptr);
|
||||
AIfeignremember_timer.reset(nullptr);
|
||||
AI_think_timer.reset(nullptr);
|
||||
AI_walking_timer.reset(nullptr);
|
||||
AI_movement_timer.reset(nullptr);
|
||||
AI_target_check_timer.reset(nullptr);
|
||||
AI_scan_area_timer.reset(nullptr);
|
||||
AI_feign_remember_timer.reset(nullptr);
|
||||
AI_check_signal_timer.reset(nullptr);
|
||||
|
||||
hate_list.WipeHateList();
|
||||
}
|
||||
@ -725,7 +730,7 @@ void Client::AI_Process()
|
||||
if (!IsAIControlled())
|
||||
return;
|
||||
|
||||
if (!(AIthink_timer->Check() || attack_timer.Check(false)))
|
||||
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
|
||||
return;
|
||||
|
||||
if (IsCasting())
|
||||
@ -759,7 +764,7 @@ void Client::AI_Process()
|
||||
}
|
||||
|
||||
if(RuleB(Combat, EnableFearPathing)){
|
||||
if(curfp) {
|
||||
if(currently_fleeing) {
|
||||
if(IsRooted()) {
|
||||
//make sure everybody knows were not moving, for appearance sake
|
||||
if(IsMoving())
|
||||
@ -771,7 +776,7 @@ void Client::AI_Process()
|
||||
//continue on to attack code, ensuring that we execute the engaged code
|
||||
engaged = true;
|
||||
} else {
|
||||
if(AImovement_timer->Check()) {
|
||||
if(AI_movement_timer->Check()) {
|
||||
int speed = GetFearSpeed();
|
||||
animation = speed;
|
||||
speed *= 2;
|
||||
@ -808,7 +813,7 @@ void Client::AI_Process()
|
||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||
else
|
||||
{
|
||||
if(AItarget_check_timer->Check())
|
||||
if(AI_target_check_timer->Check())
|
||||
{
|
||||
SetTarget(hate_list.GetEntWithMostHateOnList(this));
|
||||
}
|
||||
@ -832,7 +837,7 @@ void Client::AI_Process()
|
||||
DoClassAttacks(GetTarget());
|
||||
}
|
||||
|
||||
if (AImovement_timer->Check()) {
|
||||
if (AI_movement_timer->Check()) {
|
||||
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) !=
|
||||
m_Position.w) {
|
||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||
@ -858,7 +863,7 @@ void Client::AI_Process()
|
||||
} else {
|
||||
if(!IsRooted())
|
||||
{
|
||||
if(AImovement_timer->Check())
|
||||
if(AI_movement_timer->Check())
|
||||
{
|
||||
int newspeed = GetRunspeed();
|
||||
animation = newspeed;
|
||||
@ -889,7 +894,7 @@ void Client::AI_Process()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(AIfeignremember_timer->Check()) {
|
||||
if(AI_feign_remember_timer->Check()) {
|
||||
std::set<uint32>::iterator RememberedCharID;
|
||||
RememberedCharID = feign_memory_list.begin();
|
||||
while (RememberedCharID != feign_memory_list.end()) {
|
||||
@ -917,7 +922,7 @@ void Client::AI_Process()
|
||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||
if (dist >= 400)
|
||||
{
|
||||
if(AImovement_timer->Check())
|
||||
if(AI_movement_timer->Check())
|
||||
{
|
||||
int nspeed = (dist >= 5625 ? GetRunspeed() : GetWalkspeed());
|
||||
animation = nspeed;
|
||||
@ -943,7 +948,7 @@ void Mob::AI_Process() {
|
||||
if (!IsAIControlled())
|
||||
return;
|
||||
|
||||
if (!(AIthink_timer->Check() || attack_timer.Check(false)))
|
||||
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
|
||||
return;
|
||||
|
||||
if (IsCasting())
|
||||
@ -955,7 +960,7 @@ void Mob::AI_Process() {
|
||||
// Begin: Additions for Wiz Fear Code
|
||||
//
|
||||
if(RuleB(Combat, EnableFearPathing)){
|
||||
if(curfp) {
|
||||
if(currently_fleeing) {
|
||||
if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) {
|
||||
//make sure everybody knows were not moving, for appearance sake
|
||||
if(IsMoving())
|
||||
@ -968,7 +973,7 @@ void Mob::AI_Process() {
|
||||
//continue on to attack code, ensuring that we execute the engaged code
|
||||
engaged = true;
|
||||
} else {
|
||||
if(AImovement_timer->Check()) {
|
||||
if(AI_movement_timer->Check()) {
|
||||
// Check if we have reached the last fear point
|
||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||
@ -998,7 +1003,7 @@ void Mob::AI_Process() {
|
||||
}
|
||||
|
||||
// trigger EVENT_SIGNAL if required
|
||||
if(IsNPC()) {
|
||||
if (AI_check_signal_timer->Check() && IsNPC()) {
|
||||
CastToNPC()->CheckSignal();
|
||||
}
|
||||
|
||||
@ -1012,7 +1017,7 @@ void Mob::AI_Process() {
|
||||
SetTarget(hate_list.GetClosestEntOnHateList(this));
|
||||
else
|
||||
{
|
||||
if(AItarget_check_timer->Check())
|
||||
if(AI_target_check_timer->Check())
|
||||
{
|
||||
if (IsFocused()) {
|
||||
if (!target) {
|
||||
@ -1074,7 +1079,7 @@ void Mob::AI_Process() {
|
||||
|
||||
if (is_combat_range)
|
||||
{
|
||||
if (AImovement_timer->Check())
|
||||
if (AI_movement_timer->Check())
|
||||
{
|
||||
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
||||
{
|
||||
@ -1268,7 +1273,7 @@ void Mob::AI_Process() {
|
||||
WipeHateList();
|
||||
Heal();
|
||||
BuffFadeAll();
|
||||
AIwalking_timer->Start(100);
|
||||
AI_walking_timer->Start(100);
|
||||
pLastFightingDelayMoving = Timer::GetCurrentTime();
|
||||
return;
|
||||
} else if(tar != nullptr) {
|
||||
@ -1290,7 +1295,7 @@ void Mob::AI_Process() {
|
||||
if(AI_PursueCastCheck()){
|
||||
//we did something, so do not process movement.
|
||||
}
|
||||
else if (AImovement_timer->Check())
|
||||
else if (AI_movement_timer->Check())
|
||||
{
|
||||
if(!IsRooted()) {
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
|
||||
@ -1323,7 +1328,7 @@ void Mob::AI_Process() {
|
||||
{
|
||||
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||
SendRemovePlayerState(PlayerState::Aggressive);
|
||||
if(AIfeignremember_timer->Check()) {
|
||||
if(AI_feign_remember_timer->Check()) {
|
||||
// 6/14/06
|
||||
// Improved Feign Death Memory
|
||||
// check to see if any of our previous feigned targets have gotten up.
|
||||
@ -1348,7 +1353,7 @@ void Mob::AI_Process() {
|
||||
{
|
||||
//we processed a spell action, so do nothing else.
|
||||
}
|
||||
else if (AIscanarea_timer->Check())
|
||||
else if (AI_scan_area_timer->Check())
|
||||
{
|
||||
/*
|
||||
* This is where NPCs look around to see if they want to attack anybody.
|
||||
@ -1359,11 +1364,16 @@ void Mob::AI_Process() {
|
||||
*
|
||||
*/
|
||||
|
||||
Mob* tmptar = entity_list.AICheckCloseAggro(this, GetAggroRange(), GetAssistRange());
|
||||
if (tmptar)
|
||||
AddToHateList(tmptar);
|
||||
Mob* temp_target = entity_list.AICheckCloseAggro(this, GetAggroRange(), GetAssistRange());
|
||||
if (temp_target){
|
||||
AddToHateList(temp_target);
|
||||
}
|
||||
|
||||
AI_scan_area_timer->Disable();
|
||||
AI_scan_area_timer->Start(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)), false);
|
||||
|
||||
}
|
||||
else if (AImovement_timer->Check() && !IsRooted())
|
||||
else if (AI_movement_timer->Check() && !IsRooted())
|
||||
{
|
||||
if (IsPet())
|
||||
{
|
||||
@ -1534,10 +1544,10 @@ void NPC::AI_DoMovement() {
|
||||
}
|
||||
else if (roamer)
|
||||
{
|
||||
if (AIwalking_timer->Check())
|
||||
if (AI_walking_timer->Check())
|
||||
{
|
||||
movetimercompleted=true;
|
||||
AIwalking_timer->Disable();
|
||||
AI_walking_timer->Disable();
|
||||
}
|
||||
|
||||
|
||||
@ -1547,7 +1557,7 @@ void NPC::AI_DoMovement() {
|
||||
if (movetimercompleted==true) { // time to pause at wp is over
|
||||
AI_SetupNextWaypoint();
|
||||
} // endif (movetimercompleted==true)
|
||||
else if (!(AIwalking_timer->Enabled()))
|
||||
else if (!(AI_walking_timer->Enabled()))
|
||||
{ // currently moving
|
||||
bool doMove = true;
|
||||
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
|
||||
@ -1568,7 +1578,7 @@ void NPC::AI_DoMovement() {
|
||||
sprintf(temp, "%d", cur_wp);
|
||||
parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0);
|
||||
// start moving directly to next waypoint if we're at a 0 pause waypoint and we didn't get quest halted.
|
||||
if (!AIwalking_timer->Enabled())
|
||||
if (!AI_walking_timer->Enabled())
|
||||
AI_SetupNextWaypoint();
|
||||
else
|
||||
doMove = false;
|
||||
@ -1759,7 +1769,7 @@ void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
|
||||
void Mob::AI_Event_NoLongerEngaged() {
|
||||
if (!IsAIControlled())
|
||||
return;
|
||||
this->AIwalking_timer->Start(RandomTimer(3000,20000));
|
||||
this->AI_walking_timer->Start(RandomTimer(3000,20000));
|
||||
pLastFightingDelayMoving = Timer::GetCurrentTime();
|
||||
if (minLastFightingDelayMoving == maxLastFightingDelayMoving)
|
||||
pLastFightingDelayMoving += minLastFightingDelayMoving;
|
||||
@ -1856,15 +1866,15 @@ bool NPC::AI_PursueCastCheck() {
|
||||
|
||||
bool NPC::AI_IdleCastCheck() {
|
||||
if (AIautocastspell_timer->Check(false)) {
|
||||
#if MobAI_DEBUG_Spells >= 25
|
||||
std::cout << "Non-Engaged autocast check triggered: " << this->GetName() << std::endl;
|
||||
#endif
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
if (!AICastSpell(this, AISpellVar.idle_beneficial_chance, SpellType_Heal | SpellType_Buff | SpellType_Pet)) {
|
||||
if(!entity_list.AICheckCloseBeneficialSpells(this, 33, MobAISpellRange, SpellType_Heal | SpellType_Buff)) {
|
||||
//if we didnt cast any spells, our autocast timer just resets to the
|
||||
//last duration it was set to... try to put up a more reasonable timer...
|
||||
AIautocastspell_timer->Start(RandomTimer(AISpellVar.idle_no_sp_recast_min, AISpellVar.idle_no_sp_recast_max), false);
|
||||
|
||||
Log.Out(Logs::Moderate, Logs::Spells, "Triggering AI_IdleCastCheck :: Mob %s - Min : %u Max : %u", this->GetCleanName(), AISpellVar.idle_no_sp_recast_min, AISpellVar.idle_no_sp_recast_max);
|
||||
|
||||
} //else, spell casting finishing will reset the timer.
|
||||
} //else, spell casting finishing will reset the timer.
|
||||
return(true);
|
||||
|
||||
19
zone/net.cpp
19
zone/net.cpp
@ -84,7 +84,7 @@
|
||||
#endif
|
||||
|
||||
volatile bool RunLoops = true;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
TimeoutManager timeout_manager;
|
||||
NetConnection net;
|
||||
@ -110,6 +110,7 @@ extern void MapOpcodes();
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformZone);
|
||||
Log.LoadLogSettingsDefaults();
|
||||
|
||||
set_exception_handler();
|
||||
QServ = new QueryServ;
|
||||
|
||||
@ -339,6 +340,10 @@ int main(int argc, char** argv) {
|
||||
#ifdef EMBPERL
|
||||
PerlembParser *perl_parser = new PerlembParser();
|
||||
parse->RegisterQuestInterface(perl_parser, "pl");
|
||||
|
||||
/* Load Perl Event Export Settings */
|
||||
parse->LoadPerlEventExportSettings(parse->perl_event_export_settings);
|
||||
|
||||
#endif
|
||||
|
||||
//now we have our parser, load the quests
|
||||
@ -388,10 +393,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
worldserver.Process();
|
||||
|
||||
if (!eqsf.IsOpen() && Config->ZonePort!=0) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d",Config->ZonePort);
|
||||
if (!eqsf.IsOpen() && Config->ZonePort != 0) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
|
||||
if (!eqsf.Open(Config->ZonePort)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to open port %d",Config->ZonePort);
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to open port %d", Config->ZonePort);
|
||||
ZoneConfig::SetZonePort(0);
|
||||
worldserver.Disconnect();
|
||||
worldwasconnected = false;
|
||||
@ -405,7 +410,7 @@ int main(int argc, char** argv) {
|
||||
//structures and opcodes for that patch.
|
||||
struct in_addr in;
|
||||
in.s_addr = eqss->GetRemoteIP();
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in), ntohs(eqss->GetRemotePort()));
|
||||
stream_identifier.AddStream(eqss); //takes the stream
|
||||
}
|
||||
|
||||
@ -437,12 +442,12 @@ int main(int argc, char** argv) {
|
||||
worldwasconnected = true;
|
||||
}
|
||||
else {
|
||||
if (worldwasconnected && ZoneLoaded)
|
||||
if (worldwasconnected && is_zone_loaded)
|
||||
entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
|
||||
worldwasconnected = false;
|
||||
}
|
||||
|
||||
if (ZoneLoaded && zoneupdate_timer.Check()) {
|
||||
if (is_zone_loaded && zoneupdate_timer.Check()) {
|
||||
{
|
||||
if(net.group_timer.Enabled() && net.group_timer.Check())
|
||||
entity_list.GroupProcess();
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
#endif
|
||||
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern EntityList entity_list;
|
||||
|
||||
NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int iflymode, bool IsCorpse)
|
||||
@ -605,7 +605,7 @@ bool NPC::Process()
|
||||
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
||||
BuffProcess();
|
||||
|
||||
if(curfp)
|
||||
if(currently_fleeing)
|
||||
ProcessFlee();
|
||||
|
||||
uint32 bonus = 0;
|
||||
|
||||
@ -1032,3 +1032,42 @@ int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings) {
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading Perl Event Export Settings...");
|
||||
|
||||
/* Write Defaults First (All Enabled) */
|
||||
for (int i = 0; i < _LargestEventID; i++){
|
||||
perl_event_export_settings[i].qglobals = 1;
|
||||
perl_event_export_settings[i].mob = 1;
|
||||
perl_event_export_settings[i].zone = 1;
|
||||
perl_event_export_settings[i].item = 1;
|
||||
perl_event_export_settings[i].event_variables = 1;
|
||||
}
|
||||
|
||||
std::string query =
|
||||
"SELECT "
|
||||
"event_id, "
|
||||
"event_description, "
|
||||
"export_qglobals, "
|
||||
"export_mob, "
|
||||
"export_zone, "
|
||||
"export_item, "
|
||||
"export_event "
|
||||
"FROM "
|
||||
"perl_event_export_settings "
|
||||
"ORDER BY event_id";
|
||||
|
||||
int event_id = 0;
|
||||
auto results = database.QueryDatabase(query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
event_id = atoi(row[0]);
|
||||
perl_event_export_settings[event_id].qglobals = atoi(row[2]);
|
||||
perl_event_export_settings[event_id].mob = atoi(row[3]);
|
||||
perl_event_export_settings[event_id].zone = atoi(row[4]);
|
||||
perl_event_export_settings[event_id].item = atoi(row[5]);
|
||||
perl_event_export_settings[event_id].event_variables = atoi(row[6]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -77,6 +77,27 @@ public:
|
||||
|
||||
void GetErrors(std::list<std::string> &err);
|
||||
|
||||
/*
|
||||
Internally used memory reference for all Perl Event Export Settings
|
||||
Some exports are very taxing on CPU given how much an event is called.
|
||||
|
||||
These are loaded via DB and have defaults loaded in PerlEventExportSettingsDefaults.
|
||||
|
||||
Database loaded via Database::LoadPerlEventExportSettings(log_settings)
|
||||
*/
|
||||
|
||||
struct PerlEventExportSettings {
|
||||
uint8 qglobals;
|
||||
uint8 mob;
|
||||
uint8 zone;
|
||||
uint8 item;
|
||||
uint8 event_variables;
|
||||
};
|
||||
|
||||
PerlEventExportSettings perl_event_export_settings[_LargestEventID];
|
||||
|
||||
void LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings);
|
||||
|
||||
private:
|
||||
bool HasQuestSubLocal(uint32 npcid, QuestEventID evt);
|
||||
bool HasQuestSubGlobal(QuestEventID evt);
|
||||
|
||||
106
zone/spawn2.cpp
106
zone/spawn2.cpp
@ -351,6 +351,112 @@ void Spawn2::DeathReset(bool realdeath)
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance)
|
||||
{
|
||||
std::unordered_map<uint32, uint32> spawn_times;
|
||||
|
||||
float mob_distance = 0;
|
||||
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
|
||||
/* Bulk Load NPC Types Data into the cache */
|
||||
database.LoadNPCTypesData(0, true);
|
||||
|
||||
std::string spawn_query = StringFormat(
|
||||
"SELECT "
|
||||
"respawn_times.id, "
|
||||
"respawn_times.`start`, "
|
||||
"respawn_times.duration "
|
||||
"FROM "
|
||||
"respawn_times "
|
||||
"WHERE instance_id = %u",
|
||||
zone->GetInstanceID()
|
||||
);
|
||||
auto results = QueryDatabase(spawn_query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
uint32 start_duration = atoi(row[1]) > 0 ? atoi(row[1]) : 0;
|
||||
uint32 end_duration = atoi(row[2]) > 0 ? atoi(row[2]) : 0;
|
||||
|
||||
/* Our current time was expired */
|
||||
if ((start_duration + end_duration) <= tv.tv_sec) {
|
||||
spawn_times[atoi(row[0])] = 0;
|
||||
}
|
||||
/* We still have time left on this timer */
|
||||
else {
|
||||
spawn_times[atoi(row[0])] = ((start_duration + end_duration) - tv.tv_sec) * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
const char *zone_name = database.GetZoneName(zoneid);
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"id, "
|
||||
"spawngroupID, "
|
||||
"x, "
|
||||
"y, "
|
||||
"z, "
|
||||
"heading, "
|
||||
"respawntime, "
|
||||
"variance, "
|
||||
"pathgrid, "
|
||||
"_condition, "
|
||||
"cond_value, "
|
||||
"enabled, "
|
||||
"animation "
|
||||
"FROM "
|
||||
"spawn2 "
|
||||
"WHERE zone = '%s' AND version = %u",
|
||||
zone_name,
|
||||
version
|
||||
);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
|
||||
uint32 spawn_time_left = 0;
|
||||
Spawn2* new_spawn = 0;
|
||||
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
|
||||
|
||||
if (spawn_times.count(atoi(row[0])) != 0)
|
||||
spawn_time_left = spawn_times[atoi(row[0])];
|
||||
|
||||
glm::vec4 point;
|
||||
point.x = atof(row[2]);
|
||||
point.y = atof(row[3]);
|
||||
|
||||
mob_distance = DistanceNoZ(client_position, point);
|
||||
|
||||
if (mob_distance > repop_distance)
|
||||
continue;
|
||||
|
||||
new_spawn = new Spawn2( //
|
||||
atoi(row[0]), // uint32 in_spawn2_id
|
||||
atoi(row[1]), // uint32 spawngroup_id
|
||||
atof(row[2]), // float in_x
|
||||
atof(row[3]), // float in_y
|
||||
atof(row[4]), // float in_z
|
||||
atof(row[5]), // float in_heading
|
||||
atoi(row[6]), // uint32 respawn
|
||||
atoi(row[7]), // uint32 variance
|
||||
spawn_time_left, // uint32 timeleft
|
||||
atoi(row[8]), // uint32 grid
|
||||
atoi(row[9]), // uint16 in_cond_id
|
||||
atoi(row[10]), // int16 in_min_value
|
||||
perl_enabled, // bool in_enabled
|
||||
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
|
||||
);
|
||||
|
||||
spawn2_list.Insert(new_spawn);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
|
||||
|
||||
std::unordered_map<uint32, uint32> spawn_times;
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
|
||||
@ -283,9 +283,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
|
||||
//do any AAs apply to these spells?
|
||||
if(dmg < 0) {
|
||||
if (!PassCastRestriction(false, spells[spell_id].base2[i], true))
|
||||
break;
|
||||
dmg = -dmg;
|
||||
Damage(caster, dmg, spell_id, spell.skill, false, buffslot, false);
|
||||
} else {
|
||||
if (!PassCastRestriction(false, spells[spell_id].base2[i], false))
|
||||
break;
|
||||
HealDamage(dmg, caster);
|
||||
}
|
||||
break;
|
||||
@ -864,7 +868,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
}
|
||||
|
||||
CalculateNewFearpoint();
|
||||
if(curfp)
|
||||
if(currently_fleeing)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -3429,6 +3433,8 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
||||
|
||||
switch (effect) {
|
||||
case SE_CurrentHP: {
|
||||
if (!PassCastRestriction(false, spells[buff.spellid].base2[i], true))
|
||||
break;
|
||||
effect_value = CalcSpellEffectValue(buff.spellid, i, buff.casterlevel, buff.instrument_mod,
|
||||
caster, buff.ticsremaining);
|
||||
// Handle client cast DOTs here.
|
||||
@ -3944,8 +3950,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
}
|
||||
|
||||
case SE_Blind:
|
||||
if (curfp && !FindType(SE_Fear))
|
||||
curfp = false;
|
||||
if (currently_fleeing && !FindType(SE_Fear))
|
||||
currently_fleeing = false;
|
||||
break;
|
||||
|
||||
case SE_Fear:
|
||||
@ -3958,8 +3964,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
CastToClient()->AI_Stop();
|
||||
}
|
||||
|
||||
if(curfp) {
|
||||
curfp = false;
|
||||
if(currently_fleeing) {
|
||||
currently_fleeing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3974,7 +3980,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
{
|
||||
if(RuleB(Combat, EnableFearPathing)){
|
||||
if(flee_mode) {
|
||||
curfp = true;
|
||||
currently_fleeing = true;
|
||||
CheckFlee();
|
||||
break;
|
||||
}
|
||||
@ -6224,16 +6230,17 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
Range 410 - 411 : UNKOWN
|
||||
Range 500 - 599 : Heal if HP less than a specified value
|
||||
Range 600 - 699 : Limit to Body Type [base2 - 600 = Body]
|
||||
Range 700 : UNKNOWN
|
||||
Range 700 : NPC only -- from patch notes "Wizard - Arcane Fusion no longer deals damage to non-NPC targets. This should ensure that wizards who fail their Bucolic Gambit are slightly less likely to annihilate themselves."
|
||||
Range 701 : NOT PET
|
||||
Range 800 : UKNOWN
|
||||
Range 818 - 819 : If Undead/If Not Undead
|
||||
Range 820 - 822 : UKNOWN
|
||||
Range 835 : Unknown *not implemented
|
||||
Range 836 - 837 : Progression Server / Live Server *not implemented
|
||||
Range 839 : Unknown *not implemented
|
||||
Range 836 - 837 : Progression Server / Live Server *not fully implemented
|
||||
Range 839 : Progression Server and GoD released -- broken until Oct 21 2015 on live *not fully implemented
|
||||
Range 842 - 844 : Humaniod lv MAX ((842 - 800) * 2)
|
||||
Range 845 - 847 : UNKNOWN
|
||||
Range 860 - 871 : Humanoid lv MAX 860 = 90, 871 = 104 *not implemented
|
||||
Range 10000 - 11000 : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
|
||||
THIS IS A WORK IN PROGRESS
|
||||
*/
|
||||
@ -6387,6 +6394,11 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 700:
|
||||
if (IsNPC())
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 701:
|
||||
if (!IsPet())
|
||||
return true;
|
||||
@ -6402,6 +6414,15 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 836:
|
||||
return true; // todo implement progression flag assume not progression for now
|
||||
|
||||
case 837:
|
||||
return false; // todo implement progression flag assume not progression for now
|
||||
|
||||
case 839:
|
||||
return true; // todo implement progression flag assume not progression for now, this one is a check if GoD is live
|
||||
|
||||
case 842:
|
||||
if (GetBodyType() == BT_Humanoid && GetLevel() <= 84)
|
||||
return true;
|
||||
@ -6789,4 +6810,4 @@ void Client::BreakFeignDeathWhenCastOn(bool IsResisted)
|
||||
SetFeigned(false);
|
||||
Message_StringID(MT_SpellFailure,FD_CAST_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
// this is run constantly for every mob
|
||||
@ -2267,7 +2267,9 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
}
|
||||
}
|
||||
// one may want to check if this is a disc or not, but we actually don't, there are non disc stuff that have end cost
|
||||
if (spells[spell_id].EndurCost) {
|
||||
// lets not consume end for custom items that have disc procs.
|
||||
// One might also want to filter out USE_ITEM_SPELL_SLOT, but DISCIPLINE_SPELL_SLOT are both #defined to the same thing ...
|
||||
if (spells[spell_id].EndurCost && !isproc) {
|
||||
auto end_cost = spells[spell_id].EndurCost;
|
||||
if (mgb)
|
||||
end_cost *= 2;
|
||||
|
||||
@ -94,7 +94,7 @@ void NPC::ResumeWandering()
|
||||
{
|
||||
if (GetGrid() < 0)
|
||||
{ // we were paused by a quest
|
||||
AIwalking_timer->Disable();
|
||||
AI_walking_timer->Disable();
|
||||
SetGrid( 0 - GetGrid());
|
||||
if (cur_wp==-1)
|
||||
{ // got here by a MoveTo()
|
||||
@ -103,10 +103,10 @@ void NPC::ResumeWandering()
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Pathing, "Resume Wandering requested. Grid %d, wp %d", GetGrid(), cur_wp);
|
||||
}
|
||||
else if (AIwalking_timer->Enabled())
|
||||
else if (AI_walking_timer->Enabled())
|
||||
{ // we are at a waypoint paused normally
|
||||
Log.Out(Logs::Detail, Logs::Pathing, "Resume Wandering on timed pause. Grid %d, wp %d", GetGrid(), cur_wp);
|
||||
AIwalking_timer->Trigger(); // disable timer to end pause now
|
||||
AI_walking_timer->Trigger(); // disable timer to end pause now
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -145,7 +145,7 @@ void NPC::PauseWandering(int pausetime)
|
||||
}
|
||||
else
|
||||
{ // specified waiting time, he'll resume after that
|
||||
AIwalking_timer->Start(pausetime*1000); // set the timer
|
||||
AI_walking_timer->Start(pausetime*1000); // set the timer
|
||||
}
|
||||
} else {
|
||||
Log.Out(Logs::General, Logs::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID());
|
||||
@ -162,7 +162,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
|
||||
SetGrid( 0 - GetGrid()); // get him moving again
|
||||
Log.Out(Logs::Detail, Logs::AI, "MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.", GetGrid());
|
||||
}
|
||||
AIwalking_timer->Disable(); // disable timer in case he is paused at a wp
|
||||
AI_walking_timer->Disable(); // disable timer in case he is paused at a wp
|
||||
if (cur_wp>=0)
|
||||
{ // we've not already done a MoveTo()
|
||||
save_wp=cur_wp; // save the current waypoint
|
||||
@ -193,8 +193,8 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
|
||||
m_CurrentWayPoint = position;
|
||||
cur_wp_pause = 0;
|
||||
pLastFightingDelayMoving = 0;
|
||||
if(AIwalking_timer->Enabled())
|
||||
AIwalking_timer->Start(100);
|
||||
if(AI_walking_timer->Enabled())
|
||||
AI_walking_timer->Start(100);
|
||||
}
|
||||
|
||||
void NPC::UpdateWaypoint(int wp_index)
|
||||
@ -393,8 +393,8 @@ void NPC::SetWaypointPause()
|
||||
//Declare time to wait on current WP
|
||||
|
||||
if (cur_wp_pause == 0) {
|
||||
AIwalking_timer->Start(100);
|
||||
AIwalking_timer->Trigger();
|
||||
AI_walking_timer->Start(100);
|
||||
AI_walking_timer->Trigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -402,13 +402,13 @@ void NPC::SetWaypointPause()
|
||||
switch (pausetype)
|
||||
{
|
||||
case 0: //Random Half
|
||||
AIwalking_timer->Start((cur_wp_pause - zone->random.Int(0, cur_wp_pause-1)/2)*1000);
|
||||
AI_walking_timer->Start((cur_wp_pause - zone->random.Int(0, cur_wp_pause-1)/2)*1000);
|
||||
break;
|
||||
case 1: //Full
|
||||
AIwalking_timer->Start(cur_wp_pause*1000);
|
||||
AI_walking_timer->Start(cur_wp_pause*1000);
|
||||
break;
|
||||
case 2: //Random Full
|
||||
AIwalking_timer->Start(zone->random.Int(0, cur_wp_pause-1)*1000);
|
||||
AI_walking_timer->Start(zone->random.Int(0, cur_wp_pause-1)*1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -484,7 +484,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
||||
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
|
||||
return true;
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
|
||||
// Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
|
||||
return false;
|
||||
} else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) {
|
||||
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "client.h"
|
||||
#include "corpse.h"
|
||||
#include "entity.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "mob.h"
|
||||
#include "net.h"
|
||||
@ -53,13 +54,16 @@
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern void CatchSignal(int);
|
||||
extern WorldServer worldserver;
|
||||
extern NetConnection net;
|
||||
extern PetitionList petition_list;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
extern QuestParserCollection *parse;
|
||||
|
||||
// QuestParserCollection *parse = 0;
|
||||
|
||||
WorldServer::WorldServer()
|
||||
: WorldConnection(EmuTCPConnection::packetModeZone)
|
||||
@ -85,7 +89,7 @@ WorldServer::~WorldServer() {
|
||||
safe_delete(pack);
|
||||
}*/
|
||||
|
||||
void WorldServer::SetZone(uint32 iZoneID, uint32 iInstanceID) {
|
||||
void WorldServer::SetZoneData(uint32 iZoneID, uint32 iInstanceID) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_SetZone, sizeof(SetZone_Struct));
|
||||
SetZone_Struct* szs = (SetZone_Struct*) pack->pBuffer;
|
||||
szs->zoneid = iZoneID;
|
||||
@ -99,10 +103,9 @@ void WorldServer::SetZone(uint32 iZoneID, uint32 iInstanceID) {
|
||||
|
||||
void WorldServer::OnConnected() {
|
||||
WorldConnection::OnConnected();
|
||||
|
||||
ServerPacket* pack;
|
||||
|
||||
//tell the launcher what name we were started with.
|
||||
/* Tell the launcher what our information is */
|
||||
pack = new ServerPacket(ServerOP_SetLaunchName,sizeof(LaunchName_Struct));
|
||||
LaunchName_Struct* ln = (LaunchName_Struct*)pack->pBuffer;
|
||||
strn0cpy(ln->launcher_name, m_launcherName.c_str(), 32);
|
||||
@ -110,28 +113,38 @@ void WorldServer::OnConnected() {
|
||||
SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
/* Tell the Worldserver basic information about this zone process */
|
||||
pack = new ServerPacket(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo));
|
||||
ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer;
|
||||
|
||||
auto config = ZoneConfig::get();
|
||||
sci->port = ZoneConfig::get()->ZonePort;
|
||||
if(config->WorldAddress.length() > 0) {
|
||||
strn0cpy(sci->address, config->WorldAddress.c_str(), 250);
|
||||
}
|
||||
|
||||
if(config->LocalAddress.length() > 0) {
|
||||
strn0cpy(sci->local_address, config->LocalAddress.c_str(), 250);
|
||||
}
|
||||
|
||||
/* Fetch process ID */
|
||||
if (getpid()){
|
||||
sci->process_id = getpid();
|
||||
}
|
||||
else {
|
||||
sci->process_id = 0;
|
||||
}
|
||||
|
||||
SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
if (ZoneLoaded) {
|
||||
this->SetZone(zone->GetZoneID(), zone->GetInstanceID());
|
||||
if (is_zone_loaded) {
|
||||
this->SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
|
||||
entity_list.UpdateWho(true);
|
||||
this->SendEmoteMessage(0, 0, 15, "Zone connect: %s", zone->GetLongName());
|
||||
zone->GetTimeSync();
|
||||
} else {
|
||||
this->SetZone(0);
|
||||
zone->GetTimeSync();
|
||||
}
|
||||
else {
|
||||
this->SetZoneData(0);
|
||||
}
|
||||
|
||||
pack = new ServerPacket(ServerOP_LSZoneBoot,sizeof(ZoneBoot_Struct));
|
||||
@ -174,7 +187,7 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
case ServerOP_ChannelMessage: {
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer;
|
||||
if (scm->deliverto[0] == 0) {
|
||||
@ -207,7 +220,7 @@ void WorldServer::Process() {
|
||||
}
|
||||
case ServerOP_VoiceMacro: {
|
||||
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
|
||||
ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer;
|
||||
@ -264,7 +277,7 @@ void WorldServer::Process() {
|
||||
case ServerOP_SpawnCondition: {
|
||||
if(pack->size != sizeof(ServerSpawnCondition_Struct))
|
||||
break;
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*) pack->pBuffer;
|
||||
|
||||
@ -274,7 +287,7 @@ void WorldServer::Process() {
|
||||
case ServerOP_SpawnEvent: {
|
||||
if(pack->size != sizeof(ServerSpawnEvent_Struct))
|
||||
break;
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*) pack->pBuffer;
|
||||
|
||||
@ -285,7 +298,7 @@ void WorldServer::Process() {
|
||||
case ServerOP_AcceptWorldEntrance: {
|
||||
if(pack->size != sizeof(WorldToZone_Struct))
|
||||
break;
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer;
|
||||
|
||||
@ -300,7 +313,7 @@ void WorldServer::Process() {
|
||||
case ServerOP_ZoneToZoneRequest: {
|
||||
if(pack->size != sizeof(ZoneToZone_Struct))
|
||||
break;
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer;
|
||||
|
||||
@ -376,7 +389,7 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
case ServerOP_WhoAllReply:{
|
||||
if(!ZoneLoaded)
|
||||
if(!is_zone_loaded)
|
||||
break;
|
||||
|
||||
|
||||
@ -403,7 +416,7 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
case ServerOP_EmoteMessage: {
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer;
|
||||
if (sem->to[0] != 0) {
|
||||
@ -461,8 +474,8 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
// Annouce the change to the world
|
||||
if (!ZoneLoaded) {
|
||||
SetZone(0);
|
||||
if (!is_zone_loaded) {
|
||||
SetZoneData(0);
|
||||
}
|
||||
else {
|
||||
SendEmoteMessage(0, 0, 15, "Zone shutdown: %s", zone->GetLongName());
|
||||
@ -479,8 +492,8 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer;
|
||||
if (ZoneLoaded) {
|
||||
SetZone(zone->GetZoneID(), zone->GetInstanceID());
|
||||
if (is_zone_loaded) {
|
||||
SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
|
||||
if (zst->zoneid == zone->GetZoneID()) {
|
||||
// This packet also doubles as "incoming client" notification, lets not shut down before they get here
|
||||
zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
|
||||
@ -503,8 +516,8 @@ void WorldServer::Process() {
|
||||
break;
|
||||
}
|
||||
ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*) pack->pBuffer;
|
||||
if (ZoneLoaded) {
|
||||
SetZone(zone->GetZoneID(), zone->GetInstanceID());
|
||||
if (is_zone_loaded) {
|
||||
SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
|
||||
if (szic->zoneid == zone->GetZoneID()) {
|
||||
zone->AddAuth(szic);
|
||||
// This packet also doubles as "incoming client" notification, lets not shut down before they get here
|
||||
@ -540,7 +553,7 @@ void WorldServer::Process() {
|
||||
if (client != 0) {
|
||||
if (skp->adminrank >= client->Admin()) {
|
||||
client->WorldKick();
|
||||
if (ZoneLoaded)
|
||||
if (is_zone_loaded)
|
||||
SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted in zone %s.", skp->name, zone->GetShortName());
|
||||
else
|
||||
SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted.", skp->name);
|
||||
@ -556,7 +569,7 @@ void WorldServer::Process() {
|
||||
if (client != 0) {
|
||||
if (skp->admin >= client->Admin()) {
|
||||
client->GMKill();
|
||||
if (ZoneLoaded)
|
||||
if (is_zone_loaded)
|
||||
SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed in zone %s.", skp->target, zone->GetShortName());
|
||||
else
|
||||
SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed.", skp->target);
|
||||
@ -594,7 +607,7 @@ void WorldServer::Process() {
|
||||
std::cout << "Wrong size on ServerOP_GMGoto. Got: " << pack->size << ", Expected: " << sizeof(ServerGMGoto_Struct) << std::endl;
|
||||
break;
|
||||
}
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
break;
|
||||
ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer;
|
||||
Client* client = entity_list.GetClientByName(gmg->gotoname);
|
||||
@ -1733,6 +1746,10 @@ void WorldServer::Process() {
|
||||
database.LoadLogSettings(Log.log_settings);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadPerlExportSettings: {
|
||||
parse->LoadPerlEventExportSettings(parse->perl_event_export_settings);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CameraShake:
|
||||
{
|
||||
if(zone)
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
bool SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 type, const char* message, ...);
|
||||
bool SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
|
||||
bool SendVoiceMacro(Client* From, uint32 Type, char* Target, uint32 MacroNumber, uint32 GroupOrRaidID = 0);
|
||||
void SetZone(uint32 iZoneID, uint32 iInstanceID = 0);
|
||||
void SetZoneData(uint32 iZoneID, uint32 iInstanceID = 0);
|
||||
uint32 SendGroupIdRequest();
|
||||
bool RezzPlayer(EQApplicationPacket* rpack, uint32 rezzexp, uint32 dbid, uint16 opcode);
|
||||
bool IsOOCMuted() const { return(oocmuted); }
|
||||
|
||||
@ -74,7 +74,7 @@ extern Zone* zone;
|
||||
|
||||
Mutex MZoneShutdown;
|
||||
|
||||
volatile bool ZoneLoaded = false;
|
||||
volatile bool is_zone_loaded = false;
|
||||
Zone* zone = 0;
|
||||
|
||||
bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
@ -82,9 +82,9 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
|
||||
if (iZoneID == 0 || zonename == 0)
|
||||
return false;
|
||||
if (zone != 0 || ZoneLoaded) {
|
||||
if (zone != 0 || is_zone_loaded) {
|
||||
std::cerr << "Error: Zone::Bootup call when zone already booted!" << std::endl;
|
||||
worldserver.SetZone(0);
|
||||
worldserver.SetZoneData(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
if (!zone->Init(iStaticZone)) {
|
||||
safe_delete(zone);
|
||||
std::cerr << "Zone->Init failed" << std::endl;
|
||||
worldserver.SetZone(0);
|
||||
worldserver.SetZoneData(0);
|
||||
return false;
|
||||
}
|
||||
zone->zonemap = Map::LoadMapFile(zone->map_name);
|
||||
@ -131,9 +131,9 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
}
|
||||
}
|
||||
|
||||
ZoneLoaded = true;
|
||||
is_zone_loaded = true;
|
||||
|
||||
worldserver.SetZone(iZoneID, iInstanceID);
|
||||
worldserver.SetZoneData(iZoneID, iInstanceID);
|
||||
if(iInstanceID != 0)
|
||||
{
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_AdventureZoneData, sizeof(uint16));
|
||||
@ -660,12 +660,12 @@ void Zone::LoadMercSpells(){
|
||||
}
|
||||
|
||||
bool Zone::IsLoaded() {
|
||||
return ZoneLoaded;
|
||||
return is_zone_loaded;
|
||||
}
|
||||
|
||||
void Zone::Shutdown(bool quite)
|
||||
{
|
||||
if (!ZoneLoaded)
|
||||
if (!is_zone_loaded)
|
||||
return;
|
||||
|
||||
entity_list.StopMobAI();
|
||||
@ -699,7 +699,7 @@ void Zone::Shutdown(bool quite)
|
||||
zone->SetZoneHasCurrentTime(false);
|
||||
if (!quite)
|
||||
Log.Out(Logs::General, Logs::Normal, "Zone shutdown: going to sleep");
|
||||
ZoneLoaded = false;
|
||||
is_zone_loaded = false;
|
||||
|
||||
zone->ResetAuth();
|
||||
safe_delete(zone);
|
||||
@ -846,7 +846,7 @@ Zone::~Zone() {
|
||||
safe_delete(watermap);
|
||||
safe_delete(pathing);
|
||||
if (worldserver.Connected()) {
|
||||
worldserver.SetZone(0);
|
||||
worldserver.SetZoneData(0);
|
||||
}
|
||||
safe_delete_array(short_name);
|
||||
safe_delete_array(long_name);
|
||||
@ -1445,6 +1445,29 @@ void Zone::ClearNPCTypeCache(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::RepopClose(const glm::vec4& client_position, uint32 repop_distance)
|
||||
{
|
||||
|
||||
if (!Depop())
|
||||
return;
|
||||
|
||||
LinkedListIterator<Spawn2*> iterator(spawn2_list);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
iterator.RemoveCurrent();
|
||||
}
|
||||
|
||||
quest_manager.ClearAllTimers();
|
||||
|
||||
if (!database.PopulateZoneSpawnListClose(zoneid, spawn2_list, GetInstanceVersion(), client_position, repop_distance))
|
||||
Log.Out(Logs::General, Logs::None, "Error in Zone::Repop: database.PopulateZoneSpawnList failed");
|
||||
|
||||
initgrids_timer.Start();
|
||||
|
||||
mod_repop();
|
||||
}
|
||||
|
||||
void Zone::Repop(uint32 delay) {
|
||||
|
||||
if(!Depop())
|
||||
|
||||
@ -140,6 +140,7 @@ public:
|
||||
|
||||
bool Depop(bool StartSpawnTimer = false);
|
||||
void Repop(uint32 delay = 0);
|
||||
void RepopClose(const glm::vec4& client_position, uint32 repop_distance);
|
||||
void ClearNPCTypeCache(int id);
|
||||
void SpawnStatus(Mob* client);
|
||||
void ShowEnabledSpawnStatus(Mob* client);
|
||||
|
||||
@ -46,7 +46,7 @@ void ZoneDatabase::ZDBInitVars() {
|
||||
ZoneDatabase::~ZoneDatabase() {
|
||||
unsigned int x;
|
||||
if (npc_spells_cache) {
|
||||
for (x=0; x<=npc_spells_maxid; x++) {
|
||||
for (x = 0; x <= npc_spells_maxid; x++) {
|
||||
safe_delete_array(npc_spells_cache[x]);
|
||||
}
|
||||
safe_delete_array(npc_spells_cache);
|
||||
@ -54,7 +54,7 @@ ZoneDatabase::~ZoneDatabase() {
|
||||
safe_delete_array(npc_spells_loadtried);
|
||||
|
||||
if (npc_spellseffects_cache) {
|
||||
for (x=0; x<=npc_spellseffects_maxid; x++) {
|
||||
for (x = 0; x <= npc_spellseffects_maxid; x++) {
|
||||
safe_delete_array(npc_spellseffects_cache[x]);
|
||||
}
|
||||
safe_delete_array(npc_spellseffects_cache);
|
||||
@ -62,7 +62,7 @@ ZoneDatabase::~ZoneDatabase() {
|
||||
safe_delete_array(npc_spellseffects_loadtried);
|
||||
|
||||
if (faction_array != nullptr) {
|
||||
for (x=0; x <= max_faction; x++) {
|
||||
for (x = 0; x <= max_faction; x++) {
|
||||
if (faction_array[x] != 0)
|
||||
safe_delete(faction_array[x]);
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "../common/faction.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "aa_ability.h"
|
||||
#include "event_codes.h"
|
||||
|
||||
class Client;
|
||||
class Corpse;
|
||||
@ -358,6 +359,7 @@ public:
|
||||
bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list);
|
||||
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
|
||||
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
|
||||
bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance);
|
||||
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
|
||||
bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value);
|
||||
void UpdateRespawnTime(uint32 id, uint16 instance_id,uint32 timeleft);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user