Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Cilraaz 2015-11-02 11:25:54 -05:00
commit 7b819c9edf
43 changed files with 735 additions and 342 deletions

View File

@ -1,5 +1,50 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 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
== 10/13/2015 ==
Uleat: Important update to 2015_09_30_bots.sql - fix for orphaned entries causing crashes during the conversion process
Note: Please visit the thread below if you encounter issues during the conversion process

View File

@ -23,6 +23,7 @@
#include "global_define.h"
#include "eqemu_logsys.h"
#include "types.h"
#include "dbcore.h"
#include "linked_list.h"

View File

@ -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";
}

View File

@ -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,

View File

@ -477,6 +477,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)

View File

@ -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 {

View File

@ -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 9088
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
#else

View File

@ -341,6 +341,7 @@
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|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -155,8 +155,8 @@ BEGIN
`poison` SMALLINT(5) NOT NULL DEFAULT '0',
`disease` SMALLINT(5) NOT NULL DEFAULT '0',
`corruption` SMALLINT(5) NOT NULL DEFAULT '0',
`show_helm` INT(11) UNSIGNED NOT NULL DEFAULT '0', -- Unused
`follow_distance` INT(11) UNSIGNED NOT NULL DEFAULT '200', -- Unused
`show_helm` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`follow_distance` INT(11) UNSIGNED NOT NULL DEFAULT '200',
PRIMARY KEY (`bot_id`)
) ENGINE=InnoDB;
CREATE TABLE `bot_inspect_messages` (

View File

@ -0,0 +1,7 @@
ALTER TABLE `spells_new` CHANGE `field209` `no_resist` INT(11) NOT NULL DEFAULT '0';
ALTER TABLE `spells_new` CHANGE `field232` `no_remove` INT(11) NOT NULL DEFAULT '0';
ALTER TABLE `spells_new` CHANGE `maxtargets` `no_hd_item_mod` INT(11) NOT NULL DEFAULT '0';
ALTER TABLE `spells_new` CHANGE `not_extendable` `not_focusable` INT(11) NOT NULL DEFAULT '0';
ALTER TABLE `spells_new` CHANGE `field217` `override_crit` INT(11) NOT NULL DEFAULT '0';

View File

@ -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');

View File

@ -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);
}

View File

@ -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();

View File

@ -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.
};

View File

@ -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) {

View File

@ -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) {
@ -66,7 +66,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
SetShowHelm(true);
CalcChanceToCast();
rest_timer.Disable();
SetFollowDistance(184);
SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
// Do this once and only in this constructor
GenerateAppearance();
GenerateBaseStats();
@ -144,7 +144,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
SetNumHealRotationMembers(0);
CalcChanceToCast();
rest_timer.Disable();
SetFollowDistance(184);
SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
strcpy(this->name, this->GetCleanName());
database.GetBotInspectMessage(this->GetBotID(), &_botInspectMessage);
LoadGuildMembership(&_guildId, &_guildRank, &_guildName);
@ -1593,7 +1593,9 @@ bool Bot::Save()
" `magic`,"
" `poison`,"
" `disease`,"
" `corruption`"
" `corruption`,"
" `show_helm`,"
" `follow_distance`"
")"
" VALUES ("
"'%u'," /*owner_id*/
@ -1635,7 +1637,9 @@ bool Bot::Save()
" '%i'," /*magic*/
" '%i'," /*poison*/
" '%i'," /*disease*/
" '%i'" /*corruption*/
" '%i'," /*corruption*/
" '1'," /*show_helm*/
" '%i'" /*follow_distance*/
")",
this->_botOwnerCharacterID,
this->GetBotSpellID(),
@ -1673,7 +1677,8 @@ bool Bot::Save()
GetMR(),
GetPR(),
GetDR(),
GetCorrup()
GetCorrup(),
BOT_DEFAULT_FOLLOW_DISTANCE
);
auto results = database.QueryDatabase(query);
if(!results.Success()) {
@ -1734,7 +1739,9 @@ bool Bot::Save()
" `magic` = '%i',"
" `poison` = '%i',"
" `disease` = '%i',"
" `corruption` = '%i'"
" `corruption` = '%i',"
" `show_helm` = '%i',"
" `follow_distance` = '%i'"
" WHERE `bot_id` = '%u'",
_botOwnerCharacterID,
this->GetBotSpellID(),
@ -1774,6 +1781,8 @@ bool Bot::Save()
_basePR,
_baseDR,
_baseCorrup,
(GetShowHelm() ? 1 : 0),
GetFollowDistance(),
GetBotID()
);
auto results = database.QueryDatabase(query);
@ -2277,7 +2286,7 @@ bool Bot::Process() {
BuffProcess();
CalcRestState();
if(curfp)
if(currently_fleeing)
ProcessFlee();
if(GetHP() < GetMaxHP())
@ -2676,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());
@ -2822,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;
@ -2958,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());
@ -2986,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);
@ -2995,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) {
@ -3626,13 +3635,13 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.is_npc = 0; // 0=no, 1=yes
ns->spawn.is_pet = 0;
ns->spawn.guildrank = 0;
ns->spawn.showhelm = GetShowHelm();
ns->spawn.showhelm = GetShowHelm() ? 1 : 0;
ns->spawn.flymode = 0;
ns->spawn.size = 0;
ns->spawn.NPC = 0; // 0=player,1=npc,2=pc corpse,3=npc corpse
UpdateActiveLight();
ns->spawn.light = m_Light.Type.Active;
ns->spawn.helm = (GetShowHelm() ? helmtexture : 0); //0xFF;
ns->spawn.helm = helmtexture; //(GetShowHelm() ? helmtexture : 0); //0xFF;
ns->spawn.equip_chest2 = texture; //0xFF;
const Item_Struct* item = 0;
const ItemInst* inst = 0;
@ -3696,7 +3705,6 @@ uint32 Bot::GetBotIDByBotName(std::string botName) {
Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
{
Bot* loadedBot = nullptr;
if(botID == 0)
return nullptr;
@ -3706,46 +3714,52 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
" `spells_id`,"
" `name`,"
" `last_name`,"
" `level`,"
" `title`," /*planned use[4]*/
" `suffix`," /*planned use[5]*/
" `zone_id`,"
" `gender`,"
" `race`,"
" `class`,"
" `gender`,"
" `level`,"
" `deity`," /*planned use[11]*/
" `creation_day`," /*not in-use[12]*/
" `last_spawn`," /*not in-use[13]*/
" `time_spawned`,"
" `size`,"
" `face`,"
" `hair_style`,"
" `hair_color`,"
" `hair_style`,"
" `beard`,"
" `beard_color`,"
" `eye_color_1`,"
" `eye_color_2`,"
" `beard_color`,"
" `beard`,"
" `drakkin_heritage`,"
" `drakkin_tattoo`,"
" `drakkin_details`,"
" `hp`,"
" `mana`,"
" `magic`,"
" `cold`,"
" `disease`,"
" `fire`,"
" `poison`,"
" `corruption`,"
" `ac`,"
" `str`,"
" `sta`,"
" `dex`,"
" `agi`,"
" `int`,"
" `wis`,"
" `cha`,"
" `ac`," /*not in-use[26]*/
" `atk`,"
" `creation_day`,"
" `last_spawn`,"
" `time_spawned`,"
" `zone_id`"
" `hp`,"
" `mana`," /*not in-use[29]*/
" `str`," /*not in-use[30]*/
" `sta`," /*not in-use[31]*/
" `cha`," /*not in-use[32]*/
" `dex`," /*not in-use[33]*/
" `int`," /*not in-use[34]*/
" `agi`," /*not in-use[35]*/
" `wis`," /*not in-use[36]*/
" `fire`," /*not in-use[37]*/
" `cold`," /*not in-use[38]*/
" `magic`," /*not in-use[39]*/
" `poison`," /*not in-use[40]*/
" `disease`," /*not in-use[41]*/
" `corruption`," /*not in-use[42]*/
" `show_helm`,"
" `follow_distance`"
" FROM `bot_data`"
" WHERE `bot_id` = '%u'",
botID
);
auto results = database.QueryDatabase(query);
if(!results.Success()) {
*errorMessage = std::string(results.ErrorMessage());
@ -3755,29 +3769,30 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
if (results.RowCount() == 0)
return nullptr;
// TODO: Consider removing resists and basic attributes from the load query above since we're using defaultNPCType values instead
auto row = results.begin();
NPCType defaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), atoi(row[7]));
NPCType defaultNPCTypeStruct = CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[10]), atoi(row[8]), atoi(row[9]), atoi(row[7]));
NPCType tempNPCStruct = FillNPCTypeStruct(
atoi(row[1]),
std::string(row[2]),
std::string(row[3]),
atoi(row[4]),
atoi(row[5]),
atoi(row[6]),
atoi(row[7]),
atof(row[8]),
atoi(row[9]),
atoi(row[10]),
atoi(row[11]),
atoi(row[12]),
atoi(row[13]),
atoi(row[14]),
atoi(row[15]),
atoi(row[8]),
atoi(row[9]),
atoi(row[7]),
atof(row[15]),
atoi(row[16]),
atoi(row[17]),
atoi(row[18]),
atoi(row[19]),
atoi(row[17]),
atoi(row[21]),
atoi(row[22]),
atoi(row[20]),
atoi(row[19]),
atoi(row[23]),
atoi(row[24]),
atoi(row[25]),
atoi(row[27]),
atoi(row[28]),
defaultNPCTypeStruct.MR,
defaultNPCTypeStruct.CR,
defaultNPCTypeStruct.DR,
@ -3794,7 +3809,13 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
defaultNPCTypeStruct.CHA,
defaultNPCTypeStruct.ATK
);
loadedBot = new Bot(botID, atoi(row[0]), atoi(row[1]), atof(row[38]), atoi(row[39]), tempNPCStruct);
Bot* loadedBot = new Bot(botID, atoi(row[0]), atoi(row[1]), atof(row[14]), atoi(row[6]), tempNPCStruct);
if (loadedBot) {
loadedBot->SetShowHelm((atoi(row[43]) > 0 ? true : false));
loadedBot->SetFollowDistance(atoi(row[44]));
}
return loadedBot;
}
@ -9244,6 +9265,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
c->Message(0, "#bot botgroup help - Displays the commands available to manage bot ONLY groups.");
c->Message(0, "#bot mana [<bot name or target> | all] - Displays a mana report for all your spawned bots.");
c->Message(0, "#bot setfollowdistance ### - sets target bots follow distance to ### (ie 30 or 250).");
c->Message(0, "#bot clearfollowdistance [<target> | spawned | all] - clears user-defined follow distance setting for bot target, spawned or all - includes spawned and unspawned.");
c->Message(0, "#bot [hair|haircolor|beard|beardcolor|face|eyes|heritage|tattoo|details <value>] - Change your bot's appearance.");
c->Message(0, "#bot armorcolor <slot> <red> <green> <blue> - #bot help armorcolor for info");
c->Message(0, "#bot taunt [on|off] - Determines whether or not your targeted bot will taunt.");
@ -9300,6 +9322,43 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
return;
}
if (!strcasecmp(sep->arg[1], "clearfollowdistance")) {
bool case_all = !strcasecmp(sep->arg[2], "all");
bool case_spawned = !strcasecmp(sep->arg[2], "spawned");
if (case_all || case_spawned) {
if (case_all) {
std::string query = StringFormat(
"UPDATE `bot_data`"
" SET `follow_distance` = '%u'"
" WHERE `owner_id` = '%u'",
BOT_DEFAULT_FOLLOW_DISTANCE,
c->CharacterID()
);
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
}
std::list<Bot*> spawnedBots = entity_list.GetBotsByBotOwnerCharacterID(c->CharacterID());
if (!spawnedBots.empty()) {
for (std::list<Bot*>::iterator botsListItr = spawnedBots.begin(); botsListItr != spawnedBots.end(); ++botsListItr) {
Bot* tempBot = *botsListItr;
if (tempBot) {
tempBot->SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
}
}
}
}
else if ((c->GetTarget() == nullptr) || (c->GetTarget() == c) || (!c->GetTarget()->IsBot()) || (c->GetTarget()->CastToBot()->GetBotOwner() != c)) {
c->Message(15, "You must target a bot you own!");
}
else {
c->GetTarget()->SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
}
return;
}
//bot armor colors
if(!strcasecmp(sep->arg[1], "armorcolor")) {
if(c->GetTarget() && c->GetTarget()->IsBot() && (c->GetTarget()->CastToBot()->GetBotOwner() == c)) {
@ -12713,6 +12772,19 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
Bot* b = target->CastToBot();
if (b) {
b->SetShowHelm(showhelm);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
/*
[10-16-2015 :: 14:58:02] [Packet :: Client -> Server (Dump)] [OP_SpawnAppearance - 0x01d1] [Size: 10]
0: A4 02 [2B 00] 00 00 00 00 - showhelm = false
[10-16-2015 :: 14:57:56] [Packet :: Client -> Server (Dump)] [OP_SpawnAppearance - 0x01d1] [Size: 10]
0: A4 02 [2B 00] 01 00 00 00 - showhelm = true
*/
sa_out->spawn_id = b->GetID();
sa_out->type = AT_ShowHelm; // value = 43 (0x002B)
sa_out->parameter = (showhelm ? 1 : 0);
entity_list.QueueClients(b, outapp, true);
safe_delete(outapp);
c->Message(0, "Your bot will %s show their helmet.", (showhelm ? "now" : "no longer"));
}
}

View File

@ -18,6 +18,8 @@
#include <sstream>
#define BOT_DEFAULT_FOLLOW_DISTANCE 184
extern WorldServer worldserver;
const int BotAISpellRange = 100; // TODO: Write a method that calcs what the bot's spell range is based on spell, equipment, AA, whatever and replace this

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) ||
@ -10768,4 +10769,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);
}
}

View File

@ -332,6 +332,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);

View File

@ -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 {

View File

@ -75,6 +75,7 @@ public:
virtual std::string GetVar(std::string name);
virtual void ReloadQuests();
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
private:
Embperl *perl;

View File

@ -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;
@ -2340,7 +2340,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;

View File

@ -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);

View File

@ -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];

View File

@ -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();
}

View File

@ -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`

View File

@ -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
//

View File

@ -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.
@ -1363,7 +1368,7 @@ void Mob::AI_Process() {
if (tmptar)
AddToHateList(tmptar);
}
else if (AImovement_timer->Check() && !IsRooted())
else if (AI_movement_timer->Check() && !IsRooted())
{
if (IsPet())
{
@ -1534,10 +1539,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 +1552,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 +1573,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 +1764,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,9 +1861,6 @@ 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)) {

View File

@ -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();

View File

@ -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;
@ -1978,6 +1978,8 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
else if(id == "loottable_id") { loottable_id = atof(val.c_str()); return; }
else if(id == "healscale") { healscale = atof(val.c_str()); return; }
else if(id == "spellscale") { spellscale = atof(val.c_str()); return; }
else if(id == "npc_spells_id") { AI_AddNPCSpells(atoi(val.c_str())); return; }
else if(id == "npc_spells_effects_id") { AI_AddNPCSpellsEffects(atoi(val.c_str())); CalcBonuses(); return; }
}
void NPC::LevelScale() {

View File

@ -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]);
}
}

View File

@ -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);

View File

@ -38,7 +38,7 @@
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
@ -864,7 +864,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
}
CalculateNewFearpoint();
if(curfp)
if(currently_fleeing)
{
break;
}
@ -3944,8 +3944,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 +3958,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
CastToClient()->AI_Stop();
}
if(curfp) {
curfp = false;
if(currently_fleeing) {
currently_fleeing = false;
break;
}
}
@ -3974,7 +3974,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
{
if(RuleB(Combat, EnableFearPathing)){
if(flee_mode) {
curfp = true;
currently_fleeing = true;
CheckFlee();
break;
}

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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); }

View File

@ -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);

View File

@ -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]);
}

View File

@ -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;