mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 19:51:29 +00:00
Merge branch 'master' into eqstream
This commit is contained in:
commit
25cbdf5f2c
@ -1,5 +1,51 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 02/27/2017 ==
|
||||||
|
Uleat: Notes on bot movement speed changes:
|
||||||
|
- Clients (players) appear to be on a different speed scale than other entities (NPCs, etc...)
|
||||||
|
- The server does not calculate deltas/velocities for moving players..those come the client itself
|
||||||
|
- GetBotWalkspeed() and GetBotRunspeed() are specific to bot movement calculations
|
||||||
|
- The class Mob equivilents are not scalared so that a 'client-oriented' value can still be attained
|
||||||
|
- The value of ~1.786f is derived from the ratio of 1.25f/0.7f (npc speed/client speed)
|
||||||
|
- Modifying the two speeds like this is a rough guess-timate..but, appears to at least bring the incongruous behavior to acceptable levels
|
||||||
|
|
||||||
|
== 02/26/2017 ==
|
||||||
|
Uleat: Moved bot `npc_spells` entries from '701-712' to 3000 + <class_id> .. also, added melee types for future expansion
|
||||||
|
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
||||||
|
- Each entry uses a 3-dimensional identifier: [spell type index][class id][stance index]
|
||||||
|
- [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead
|
||||||
|
- [class id] values of 1-16 are valid and hold a direct correlation to server-coded player class values
|
||||||
|
- [stance index] is a direct correlation (0-6)
|
||||||
|
- the 'conditional fields' are currently predicated on 4 compounded boolean states:
|
||||||
|
- `pH_value` represents bit '0'
|
||||||
|
- `pS_value` represents bit '1'
|
||||||
|
- `pN_value` represents bit '2'
|
||||||
|
- `pD_value` represents bit '3'
|
||||||
|
- all other conditional fields are masked based on these 4 predicates
|
||||||
|
- the full conditional field enumeration is as follows:
|
||||||
|
- `nHSND_value` - negative Healer/Slower/Nuker/Doter
|
||||||
|
- `pH_value` - positive Healer
|
||||||
|
- `pS_value` - positive Slower
|
||||||
|
- `pHS_value` - positive Healer/Slower
|
||||||
|
- `pN_value` - positive Nuker
|
||||||
|
- `pHN_value` - positive Healer/Nuker
|
||||||
|
- `pSN_value` - positive Slower/Nuker
|
||||||
|
- `pHSN_value` - positive Healer/Slower/Nuker
|
||||||
|
- `pD_value` - positive Doter
|
||||||
|
- `pHD_value` - positive Healer/Doter
|
||||||
|
- `pSD_value` - positive Slower/Doter
|
||||||
|
- `pHSD_value` - positive Healer/Slower/Doter
|
||||||
|
- `pND_value` - positive Nuker/Doter
|
||||||
|
- `pHND_value` - positive Healer/Nuker/Doter
|
||||||
|
- `pSND_value` - positive Slower/Nuker/Doter
|
||||||
|
- `pHSND_value` - positive Healer/Slower/Nuker/Doter
|
||||||
|
- Single- and mixed-bits fields should be filled-in based on the boolean 'AND' concept
|
||||||
|
- (i.e., if 'healer' then `pH_value`=x; if 'slower' then `pS_value`=y; if 'healer' AND 'slower' then `pHS_value`=z; )
|
||||||
|
- most cases can allow the same value across all fields..but, there are some that shouldn't and this format allows for their discrimination
|
||||||
|
- Valid `##_value` entries are 0-100..though, the field accepts up to 255... Anything above 100 is clamped to 100 upon loading, however...
|
||||||
|
- Not all conditions are currently coded and changing a field may not produce any results
|
||||||
|
- The 'default' database values will be changed and tweaked as bot spell code modifications occur
|
||||||
|
|
||||||
== 02/25/2017 ==
|
== 02/25/2017 ==
|
||||||
Uleat: Implemented rule-based node pathing for bots
|
Uleat: Implemented rule-based node pathing for bots
|
||||||
- This currently applies to out-of-combat following movement and blocked los in-combat movement
|
- This currently applies to out-of-combat following movement and blocked los in-combat movement
|
||||||
@ -13,6 +59,7 @@ Uleat: Implemented rule-based position update packet with movement timer check f
|
|||||||
- This appears to help with/eliminate rubber banding
|
- This appears to help with/eliminate rubber banding
|
||||||
|
|
||||||
== 02/23/2017 ==
|
== 02/23/2017 ==
|
||||||
|
** THIS NOTE HAS BEEN SUPERCEDED ON 02/26/2017 **
|
||||||
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
||||||
- Each entry uses a 4-dimensional identifier: [spell type index][class index][stance index][conditional index]
|
- Each entry uses a 4-dimensional identifier: [spell type index][class index][stance index][conditional index]
|
||||||
- [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead
|
- [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead
|
||||||
|
|||||||
@ -2243,6 +2243,7 @@ struct GroupFollow_Struct { // SoF Follow Struct
|
|||||||
/*0132*/
|
/*0132*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this is generic struct
|
||||||
struct GroupLeaderChange_Struct
|
struct GroupLeaderChange_Struct
|
||||||
{
|
{
|
||||||
/*000*/ char Unknown000[64];
|
/*000*/ char Unknown000[64];
|
||||||
|
|||||||
@ -1182,17 +1182,17 @@ namespace RoF2
|
|||||||
// Leader
|
// Leader
|
||||||
//
|
//
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // index
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname);
|
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname); // name
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // owner name of merc
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
|
||||||
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // Observed 0x41 and 0x46 here
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // level
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||||
|
|
||||||
int MemberNumber = 1;
|
int MemberNumber = 1;
|
||||||
|
|
||||||
@ -1201,17 +1201,17 @@ namespace RoF2
|
|||||||
if (gu2->membername[i][0] == '\0')
|
if (gu2->membername[i][0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++); // index
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]);
|
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]); // name
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // merc flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
|
||||||
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // owner name fo merc
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // Observed 0x41 and 0x46 here
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // level
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Low byte is Main Assist Flag
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||||
|
|||||||
@ -2566,9 +2566,12 @@ struct GroupJoin_Struct_Live { // New for Live
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct GroupJoin_Struct {
|
struct GroupJoin_Struct {
|
||||||
/*000*/ char unknown000[64];
|
/*000*/ char owner_name[64]; // merc
|
||||||
/*064*/ char membername[64];
|
/*064*/ char membername[64];
|
||||||
/*128*/ uint8 unknown128[20]; // Leadership AA ?
|
/*128*/ uint8 merc;
|
||||||
|
/*129*/ uint8 padding129[3];
|
||||||
|
/*132*/ uint32 level;
|
||||||
|
/*136*/ uint8 unknown136[12]; // group ID most likely in here judging from like captures (unused by client)
|
||||||
/*148*/
|
/*148*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -67,9 +67,11 @@ enum SpellTypes : uint32
|
|||||||
SpellType_HateRedux = (1 << 17),
|
SpellType_HateRedux = (1 << 17),
|
||||||
SpellType_InCombatBuffSong = (1 << 18), // bard in-combat group/ae buffs
|
SpellType_InCombatBuffSong = (1 << 18), // bard in-combat group/ae buffs
|
||||||
SpellType_OutOfCombatBuffSong = (1 << 19), // bard out-of-combat group/ae buffs
|
SpellType_OutOfCombatBuffSong = (1 << 19), // bard out-of-combat group/ae buffs
|
||||||
|
SpellType_PreCombatBuff = (1 << 20),
|
||||||
|
SpellType_PreCombatBuffSong = (1 << 21),
|
||||||
|
|
||||||
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
|
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
|
||||||
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong),
|
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong | SpellType_PreCombatBuff | SpellType_PreCombatBuffSong),
|
||||||
|
|
||||||
SpellType_Any = 0xFFFFFFFF
|
SpellType_Any = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,9 +30,9 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9105
|
#define CURRENT_BINARY_DATABASE_VERSION 9106
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9011
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9015
|
||||||
#else
|
#else
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -359,6 +359,7 @@
|
|||||||
9103|2017_01_30_book_languages_fix.sql|SELECT `language` from `books` WHERE `language` IS NULL|not_empty|
|
9103|2017_01_30_book_languages_fix.sql|SELECT `language` from `books` WHERE `language` IS NULL|not_empty|
|
||||||
9104|2017_02_09_npc_spells_entries_type_update.sql|SHOW COLUMNS IN `npc_spells_entries` LIKE `type`|contains|smallint(5) unsigned
|
9104|2017_02_09_npc_spells_entries_type_update.sql|SHOW COLUMNS IN `npc_spells_entries` LIKE `type`|contains|smallint(5) unsigned
|
||||||
9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
||||||
|
9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -10,6 +10,10 @@
|
|||||||
9009|2017_02_15_bots_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
9009|2017_02_15_bots_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
||||||
9010|2017_02_20_bots_bard_spell_update.sql|SELECT * FROM `bot_spells_entries` WHERE `npc_spells_id` = 711 AND (`type` & 0xFFFF0000) = 0xFFFF0000|empty|
|
9010|2017_02_20_bots_bard_spell_update.sql|SELECT * FROM `bot_spells_entries` WHERE `npc_spells_id` = 711 AND (`type` & 0xFFFF0000) = 0xFFFF0000|empty|
|
||||||
9011|2017_02_23_bots_spell_casting_chances.sql|SHOW TABLES LIKE 'bot_spell_casting_chances'|empty|
|
9011|2017_02_23_bots_spell_casting_chances.sql|SHOW TABLES LIKE 'bot_spell_casting_chances'|empty|
|
||||||
|
9012|2017_02_26_bots_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty|
|
||||||
|
9013|2017_02_26_bots_spells_id_update_for_saved_bots.sql|SELECT * FROM `bot_data` WHERE `spells_id` >= '701' AND `spells_id` <= '712'|not_empty|
|
||||||
|
9014|2017_02_26_bots_spells_id_update_for_bot_spells_entries.sql|SELECT * FROM `bot_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712'|not_empty|
|
||||||
|
9015|2017_02_26_bots_spell_casting_chances_update.sql|SHOW COLUMNS FROM `bot_spell_casting_chances` LIKE 'value'|not_empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
-- Re-ordered entries according to actual class values and added melee types (for future expansion)
|
||||||
|
DELETE FROM `npc_spells` WHERE `id` >= '701' AND `id` <= '712';
|
||||||
|
|
||||||
|
INSERT INTO `npc_spells` VALUES (3001, 'Warrior Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3002, 'Cleric Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3003, 'Paladin Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3004, 'Ranger Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3005, 'Shadowknight Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3006, 'Druid Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3007, 'Monk Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3008, 'Bard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3009, 'Rogue Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3010, 'Shaman Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3011, 'Necromancer Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3012, 'Wizard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3013, 'Magician Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3014, 'Enchanter Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3015, 'Beastlord Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3016, 'Berserker Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@
|
|||||||
|
-- Update npc_spells_id to new values
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3002' WHERE `npc_spells_id` = '701';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3012' WHERE `npc_spells_id` = '702';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3011' WHERE `npc_spells_id` = '703';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3013' WHERE `npc_spells_id` = '704';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3014' WHERE `npc_spells_id` = '705';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3010' WHERE `npc_spells_id` = '706';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3006' WHERE `npc_spells_id` = '707';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3003' WHERE `npc_spells_id` = '708';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3005' WHERE `npc_spells_id` = '709';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3004' WHERE `npc_spells_id` = '710';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3008' WHERE `npc_spells_id` = '711';
|
||||||
|
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3015' WHERE `npc_spells_id` = '712';
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
-- Update spells_id to new values
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3001' WHERE `class` = '1';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3002' WHERE `class` = '2';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3003' WHERE `class` = '3';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3004' WHERE `class` = '4';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3005' WHERE `class` = '5';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3006' WHERE `class` = '6';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3007' WHERE `class` = '7';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3008' WHERE `class` = '8';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3009' WHERE `class` = '9';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3010' WHERE `class` = '10';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3011' WHERE `class` = '11';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3012' WHERE `class` = '12';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3013' WHERE `class` = '13';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3014' WHERE `class` = '14';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3015' WHERE `class` = '15';
|
||||||
|
UPDATE `bot_data` SET `spells_id` = '3016' WHERE `class` = '16';
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
-- Re-ordered entries according to actual class values and added melee types (for future expansion)
|
||||||
|
DELETE FROM `npc_spells` WHERE `id` >= '701' AND `id` <= '712';
|
||||||
|
|
||||||
|
INSERT INTO `npc_spells` VALUES (3001, 'Warrior Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3002, 'Cleric Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3003, 'Paladin Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3004, 'Ranger Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3005, 'Shadowknight Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3006, 'Druid Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3007, 'Monk Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3008, 'Bard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3009, 'Rogue Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3010, 'Shaman Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3011, 'Necromancer Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3012, 'Wizard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3013, 'Magician Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3014, 'Enchanter Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3015, 'Beastlord Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
INSERT INTO `npc_spells` VALUES (3016, 'Berserker Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
277
zone/bot.cpp
277
zone/bot.cpp
@ -178,6 +178,8 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
|||||||
|
|
||||||
m_CastingRoles.GroupHealer = false;
|
m_CastingRoles.GroupHealer = false;
|
||||||
m_CastingRoles.GroupSlower = false;
|
m_CastingRoles.GroupSlower = false;
|
||||||
|
m_CastingRoles.GroupNuker = false;
|
||||||
|
m_CastingRoles.GroupDoter = false;
|
||||||
|
|
||||||
GenerateBaseStats();
|
GenerateBaseStats();
|
||||||
|
|
||||||
@ -404,8 +406,10 @@ NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string b
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::GenerateBaseStats() {
|
void Bot::GenerateBaseStats()
|
||||||
|
{
|
||||||
int BotSpellID = 0;
|
int BotSpellID = 0;
|
||||||
|
|
||||||
// base stats
|
// base stats
|
||||||
uint32 Strength = _baseSTR;
|
uint32 Strength = _baseSTR;
|
||||||
uint32 Stamina = _baseSTA;
|
uint32 Stamina = _baseSTA;
|
||||||
@ -421,24 +425,27 @@ void Bot::GenerateBaseStats() {
|
|||||||
int32 PoisonResist = _basePR;
|
int32 PoisonResist = _basePR;
|
||||||
int32 ColdResist = _baseCR;
|
int32 ColdResist = _baseCR;
|
||||||
int32 CorruptionResist = _baseCorrup;
|
int32 CorruptionResist = _baseCorrup;
|
||||||
|
|
||||||
|
// pulling fixed values from an auto-increment field is dangerous...
|
||||||
switch(this->GetClass()) {
|
switch(this->GetClass()) {
|
||||||
case 1: // Warrior (why not just use 'case WARRIOR:'?)
|
case WARRIOR:
|
||||||
|
BotSpellID = 3001;
|
||||||
Strength += 10;
|
Strength += 10;
|
||||||
Stamina += 20;
|
Stamina += 20;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Dexterity += 10;
|
Dexterity += 10;
|
||||||
Attack += 12;
|
Attack += 12;
|
||||||
break;
|
break;
|
||||||
case 2: // Cleric
|
case CLERIC:
|
||||||
BotSpellID = 701;
|
BotSpellID = 3002;
|
||||||
Strength += 5;
|
Strength += 5;
|
||||||
Stamina += 5;
|
Stamina += 5;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Wisdom += 30;
|
Wisdom += 30;
|
||||||
Attack += 8;
|
Attack += 8;
|
||||||
break;
|
break;
|
||||||
case 3: // Paladin
|
case PALADIN:
|
||||||
BotSpellID = 708;
|
BotSpellID = 3003;
|
||||||
Strength += 15;
|
Strength += 15;
|
||||||
Stamina += 5;
|
Stamina += 5;
|
||||||
Wisdom += 15;
|
Wisdom += 15;
|
||||||
@ -446,84 +453,86 @@ void Bot::GenerateBaseStats() {
|
|||||||
Dexterity += 5;
|
Dexterity += 5;
|
||||||
Attack += 17;
|
Attack += 17;
|
||||||
break;
|
break;
|
||||||
case 4: // Ranger
|
case RANGER:
|
||||||
BotSpellID = 710;
|
BotSpellID = 3004;
|
||||||
Strength += 15;
|
Strength += 15;
|
||||||
Stamina += 10;
|
Stamina += 10;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Wisdom += 15;
|
Wisdom += 15;
|
||||||
Attack += 17;
|
Attack += 17;
|
||||||
break;
|
break;
|
||||||
case 5: // Shadowknight
|
case SHADOWKNIGHT:
|
||||||
BotSpellID = 709;
|
BotSpellID = 3004;
|
||||||
Strength += 10;
|
Strength += 10;
|
||||||
Stamina += 15;
|
Stamina += 15;
|
||||||
Intelligence += 20;
|
Intelligence += 20;
|
||||||
Charisma += 5;
|
Charisma += 5;
|
||||||
Attack += 17;
|
Attack += 17;
|
||||||
break;
|
break;
|
||||||
case 6: // Druid
|
case DRUID:
|
||||||
BotSpellID = 707;
|
BotSpellID = 3006;
|
||||||
Stamina += 15;
|
Stamina += 15;
|
||||||
Wisdom += 35;
|
Wisdom += 35;
|
||||||
Attack += 5;
|
Attack += 5;
|
||||||
break;
|
break;
|
||||||
case 7: // Monk
|
case MONK:
|
||||||
|
BotSpellID = 3007;
|
||||||
Strength += 5;
|
Strength += 5;
|
||||||
Stamina += 15;
|
Stamina += 15;
|
||||||
Agility += 15;
|
Agility += 15;
|
||||||
Dexterity += 15;
|
Dexterity += 15;
|
||||||
Attack += 17;
|
Attack += 17;
|
||||||
break;
|
break;
|
||||||
case 8: // Bard
|
case BARD:
|
||||||
BotSpellID = 711;
|
BotSpellID = 3008;
|
||||||
Strength += 15;
|
Strength += 15;
|
||||||
Dexterity += 10;
|
Dexterity += 10;
|
||||||
Charisma += 15;
|
Charisma += 15;
|
||||||
Intelligence += 10;
|
Intelligence += 10;
|
||||||
Attack += 17;
|
Attack += 17;
|
||||||
break;
|
break;
|
||||||
case 9: // Rogue
|
case ROGUE:
|
||||||
|
BotSpellID = 3009;
|
||||||
Strength += 10;
|
Strength += 10;
|
||||||
Stamina += 20;
|
Stamina += 20;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Dexterity += 10;
|
Dexterity += 10;
|
||||||
Attack += 12;
|
Attack += 12;
|
||||||
break;
|
break;
|
||||||
case 10: // Shaman
|
case SHAMAN:
|
||||||
BotSpellID = 706;
|
BotSpellID = 3010;
|
||||||
Stamina += 10;
|
Stamina += 10;
|
||||||
Wisdom += 30;
|
Wisdom += 30;
|
||||||
Charisma += 10;
|
Charisma += 10;
|
||||||
Attack += 28;
|
Attack += 28;
|
||||||
break;
|
break;
|
||||||
case 11: // Necromancer
|
case NECROMANCER:
|
||||||
BotSpellID = 703;
|
BotSpellID = 3011;
|
||||||
Dexterity += 10;
|
Dexterity += 10;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Intelligence += 30;
|
Intelligence += 30;
|
||||||
Attack += 5;
|
Attack += 5;
|
||||||
break;
|
break;
|
||||||
case 12: // Wizard
|
case WIZARD:
|
||||||
BotSpellID = 702;
|
BotSpellID = 3012;
|
||||||
Stamina += 20;
|
Stamina += 20;
|
||||||
Intelligence += 30;
|
Intelligence += 30;
|
||||||
Attack += 5;
|
Attack += 5;
|
||||||
break;
|
break;
|
||||||
case 13: // Magician
|
case MAGICIAN:
|
||||||
BotSpellID = 704;
|
BotSpellID = 3013;
|
||||||
Stamina += 20;
|
Stamina += 20;
|
||||||
Intelligence += 30;
|
Intelligence += 30;
|
||||||
Attack += 5;
|
Attack += 5;
|
||||||
break;
|
break;
|
||||||
case 14: // Enchanter
|
case ENCHANTER:
|
||||||
BotSpellID = 705;
|
BotSpellID = 3014;
|
||||||
Intelligence += 25;
|
Intelligence += 25;
|
||||||
Charisma += 25;
|
Charisma += 25;
|
||||||
Attack += 5;
|
Attack += 5;
|
||||||
break;
|
break;
|
||||||
case 15: // Beastlord
|
case BEASTLORD:
|
||||||
BotSpellID = 712;
|
BotSpellID = 3015;
|
||||||
Stamina += 10;
|
Stamina += 10;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Dexterity += 5;
|
Dexterity += 5;
|
||||||
@ -531,21 +540,24 @@ void Bot::GenerateBaseStats() {
|
|||||||
Charisma += 5;
|
Charisma += 5;
|
||||||
Attack += 31;
|
Attack += 31;
|
||||||
break;
|
break;
|
||||||
case 16: // Berserker
|
case BERSERKER:
|
||||||
|
BotSpellID = 3016;
|
||||||
Strength += 10;
|
Strength += 10;
|
||||||
Stamina += 15;
|
Stamina += 15;
|
||||||
Dexterity += 15;
|
Dexterity += 15;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
Attack += 25;
|
Attack += 25;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float BotSize = GetSize();
|
float BotSize = GetSize();
|
||||||
|
|
||||||
switch(this->GetRace()) {
|
switch(this->GetRace()) {
|
||||||
case 1: // Humans have no race bonus
|
case HUMAN: // Humans have no race bonus
|
||||||
break;
|
break;
|
||||||
case 2: // Barbarian
|
case BARBARIAN:
|
||||||
Strength += 28;
|
Strength += 28;
|
||||||
Stamina += 20;
|
Stamina += 20;
|
||||||
Agility += 7;
|
Agility += 7;
|
||||||
@ -556,7 +568,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
BotSize = 7.0;
|
BotSize = 7.0;
|
||||||
ColdResist += 10;
|
ColdResist += 10;
|
||||||
break;
|
break;
|
||||||
case 3: // Erudite
|
case ERUDITE:
|
||||||
Strength -= 15;
|
Strength -= 15;
|
||||||
Stamina -= 5;
|
Stamina -= 5;
|
||||||
Agility -= 5;
|
Agility -= 5;
|
||||||
@ -567,7 +579,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
MagicResist += 5;
|
MagicResist += 5;
|
||||||
DiseaseResist -= 5;
|
DiseaseResist -= 5;
|
||||||
break;
|
break;
|
||||||
case 4: // Wood Elf
|
case WOOD_ELF:
|
||||||
Strength -= 10;
|
Strength -= 10;
|
||||||
Stamina -= 10;
|
Stamina -= 10;
|
||||||
Agility += 20;
|
Agility += 20;
|
||||||
@ -575,7 +587,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Wisdom += 5;
|
Wisdom += 5;
|
||||||
BotSize = 5.0;
|
BotSize = 5.0;
|
||||||
break;
|
break;
|
||||||
case 5: // High Elf
|
case HIGH_ELF:
|
||||||
Strength -= 20;
|
Strength -= 20;
|
||||||
Stamina -= 10;
|
Stamina -= 10;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
@ -584,7 +596,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Intelligence += 12;
|
Intelligence += 12;
|
||||||
Charisma += 5;
|
Charisma += 5;
|
||||||
break;
|
break;
|
||||||
case 6: // Dark Elf
|
case DARK_ELF:
|
||||||
Strength -= 15;
|
Strength -= 15;
|
||||||
Stamina -= 10;
|
Stamina -= 10;
|
||||||
Agility += 15;
|
Agility += 15;
|
||||||
@ -593,7 +605,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Charisma -= 15;
|
Charisma -= 15;
|
||||||
BotSize = 5.0;
|
BotSize = 5.0;
|
||||||
break;
|
break;
|
||||||
case 7: // Half Elf
|
case HALF_ELF:
|
||||||
Strength -= 5;
|
Strength -= 5;
|
||||||
Stamina -= 5;
|
Stamina -= 5;
|
||||||
Agility += 15;
|
Agility += 15;
|
||||||
@ -601,7 +613,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Wisdom -= 15;
|
Wisdom -= 15;
|
||||||
BotSize = 5.5;
|
BotSize = 5.5;
|
||||||
break;
|
break;
|
||||||
case 8: // Dwarf
|
case DWARF:
|
||||||
Strength += 15;
|
Strength += 15;
|
||||||
Stamina += 15;
|
Stamina += 15;
|
||||||
Agility -= 5;
|
Agility -= 5;
|
||||||
@ -613,7 +625,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
MagicResist -= 5;
|
MagicResist -= 5;
|
||||||
PoisonResist += 5;
|
PoisonResist += 5;
|
||||||
break;
|
break;
|
||||||
case 9: // Troll
|
case TROLL:
|
||||||
Strength += 33;
|
Strength += 33;
|
||||||
Stamina += 34;
|
Stamina += 34;
|
||||||
Agility += 8;
|
Agility += 8;
|
||||||
@ -623,7 +635,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
BotSize = 8.0;
|
BotSize = 8.0;
|
||||||
FireResist -= 20;
|
FireResist -= 20;
|
||||||
break;
|
break;
|
||||||
case 10: // Ogre
|
case OGRE:
|
||||||
Strength += 55;
|
Strength += 55;
|
||||||
Stamina += 77;
|
Stamina += 77;
|
||||||
Agility -= 5;
|
Agility -= 5;
|
||||||
@ -633,7 +645,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Charisma -= 38;
|
Charisma -= 38;
|
||||||
BotSize = 9.0;
|
BotSize = 9.0;
|
||||||
break;
|
break;
|
||||||
case 11: // Halfling
|
case HALFLING:
|
||||||
Strength -= 5;
|
Strength -= 5;
|
||||||
Agility += 20;
|
Agility += 20;
|
||||||
Dexterity += 15;
|
Dexterity += 15;
|
||||||
@ -644,7 +656,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
PoisonResist += 5;
|
PoisonResist += 5;
|
||||||
DiseaseResist += 5;
|
DiseaseResist += 5;
|
||||||
break;
|
break;
|
||||||
case 12: // Gnome
|
case GNOME:
|
||||||
Strength -= 15;
|
Strength -= 15;
|
||||||
Stamina -= 5;
|
Stamina -= 5;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
@ -654,7 +666,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
Charisma -= 15;
|
Charisma -= 15;
|
||||||
BotSize = 3.0;
|
BotSize = 3.0;
|
||||||
break;
|
break;
|
||||||
case 128: // Iksar
|
case IKSAR:
|
||||||
Strength -= 5;
|
Strength -= 5;
|
||||||
Stamina -= 5;
|
Stamina -= 5;
|
||||||
Agility += 15;
|
Agility += 15;
|
||||||
@ -664,7 +676,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
MagicResist -= 5;
|
MagicResist -= 5;
|
||||||
FireResist -= 5;
|
FireResist -= 5;
|
||||||
break;
|
break;
|
||||||
case 130: // Vah Shir
|
case VAHSHIR:
|
||||||
Strength += 15;
|
Strength += 15;
|
||||||
Agility += 15;
|
Agility += 15;
|
||||||
Dexterity -= 5;
|
Dexterity -= 5;
|
||||||
@ -675,7 +687,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
MagicResist -= 5;
|
MagicResist -= 5;
|
||||||
FireResist -= 5;
|
FireResist -= 5;
|
||||||
break;
|
break;
|
||||||
case 330: // Froglok
|
case FROGLOK:
|
||||||
Strength -= 5;
|
Strength -= 5;
|
||||||
Stamina += 5;
|
Stamina += 5;
|
||||||
Agility += 25;
|
Agility += 25;
|
||||||
@ -685,7 +697,7 @@ void Bot::GenerateBaseStats() {
|
|||||||
MagicResist -= 5;
|
MagicResist -= 5;
|
||||||
FireResist -= 5;
|
FireResist -= 5;
|
||||||
break;
|
break;
|
||||||
case 522: // Drakkin
|
case DRAKKIN:
|
||||||
Strength -= 5;
|
Strength -= 5;
|
||||||
Stamina += 5;
|
Stamina += 5;
|
||||||
Agility += 10;
|
Agility += 10;
|
||||||
@ -698,7 +710,10 @@ void Bot::GenerateBaseStats() {
|
|||||||
FireResist += 2;
|
FireResist += 2;
|
||||||
ColdResist += 2;
|
ColdResist += 2;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->STR = Strength;
|
this->STR = Strength;
|
||||||
this->STA = Stamina;
|
this->STA = Stamina;
|
||||||
this->DEX = Dexterity;
|
this->DEX = Dexterity;
|
||||||
@ -2149,7 +2164,7 @@ void Bot::AI_Process() {
|
|||||||
} else if(!IsRooted()) {
|
} else if(!IsRooted()) {
|
||||||
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
|
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
|
||||||
Log.Out(Logs::Detail, Logs::AI, "Returning to location prior to being summoned.");
|
Log.Out(Logs::Detail, Logs::AI, "Returning to location prior to being summoned.");
|
||||||
CalculateNewPosition2(m_PreSummonLocation.x, m_PreSummonLocation.y, m_PreSummonLocation.z, GetRunspeed());
|
CalculateNewPosition2(m_PreSummonLocation.x, m_PreSummonLocation.y, m_PreSummonLocation.z, GetBotRunspeed());
|
||||||
SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.x, m_PreSummonLocation.y));
|
SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.x, m_PreSummonLocation.y));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2224,7 +2239,7 @@ void Bot::AI_Process() {
|
|||||||
if(IsMoving()) {
|
if(IsMoving()) {
|
||||||
SetHeading(0);
|
SetHeading(0);
|
||||||
SetRunAnimSpeed(0);
|
SetRunAnimSpeed(0);
|
||||||
SetCurrentSpeed(GetRunspeed());
|
SetCurrentSpeed(GetBotRunspeed());
|
||||||
if(moved)
|
if(moved)
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
@ -2235,17 +2250,17 @@ void Bot::AI_Process() {
|
|||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||||
GetRunspeed(), WaypointChanged, NodeReached);
|
GetBotRunspeed(), WaypointChanged, NodeReached);
|
||||||
|
|
||||||
if (WaypointChanged)
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetBotRunspeed());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Mob* follow = entity_list.GetMob(GetFollowID());
|
Mob* follow = entity_list.GetMob(GetFollowID());
|
||||||
if (follow)
|
if (follow)
|
||||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetRunspeed());
|
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetBotRunspeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -2335,7 +2350,7 @@ void Bot::AI_Process() {
|
|||||||
float newZ = 0;
|
float newZ = 0;
|
||||||
FaceTarget(GetTarget());
|
FaceTarget(GetTarget());
|
||||||
if (PlotPositionAroundTarget(this, newX, newY, newZ)) {
|
if (PlotPositionAroundTarget(this, newX, newY, newZ)) {
|
||||||
CalculateNewPosition2(newX, newY, newZ, GetRunspeed());
|
CalculateNewPosition2(newX, newY, newZ, GetBotRunspeed());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2347,7 +2362,7 @@ void Bot::AI_Process() {
|
|||||||
float newY = 0;
|
float newY = 0;
|
||||||
float newZ = 0;
|
float newZ = 0;
|
||||||
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ)) {
|
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ)) {
|
||||||
CalculateNewPosition2(newX, newY, newZ, GetRunspeed());
|
CalculateNewPosition2(newX, newY, newZ, GetBotRunspeed());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2358,7 +2373,7 @@ void Bot::AI_Process() {
|
|||||||
float newY = 0;
|
float newY = 0;
|
||||||
float newZ = 0;
|
float newZ = 0;
|
||||||
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) {
|
if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) {
|
||||||
CalculateNewPosition2(newX, newY, newZ, GetRunspeed());
|
CalculateNewPosition2(newX, newY, newZ, GetBotRunspeed());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2483,7 +2498,7 @@ void Bot::AI_Process() {
|
|||||||
if (AI_movement_timer->Check()) {
|
if (AI_movement_timer->Check()) {
|
||||||
if(!IsRooted()) {
|
if(!IsRooted()) {
|
||||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
|
||||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetBotRunspeed());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2503,7 +2518,8 @@ void Bot::AI_Process() {
|
|||||||
else if(GetArchetype() == ARCHETYPE_CASTER)
|
else if(GetArchetype() == ARCHETYPE_CASTER)
|
||||||
BotMeditate(true);
|
BotMeditate(true);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||||
SendRemovePlayerState(PlayerState::Aggressive);
|
SendRemovePlayerState(PlayerState::Aggressive);
|
||||||
@ -2512,77 +2528,44 @@ void Bot::AI_Process() {
|
|||||||
if (!follow)
|
if (!follow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float cur_dist = DistanceSquared(m_Position, follow->GetPosition());
|
if (!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled()) {
|
||||||
|
if (GetBotStance() != BotStancePassive) {
|
||||||
if (!IsMoving() && cur_dist <= GetFollowDistance()) {
|
if (!AI_IdleCastCheck() && !IsCasting() && GetClass() != BARD)
|
||||||
if (AI_think_timer->Check()) {
|
BotMeditate(true);
|
||||||
if (!spellend_timer.Enabled()) {
|
}
|
||||||
if (GetBotStance() != BotStancePassive) {
|
else {
|
||||||
if (!AI_IdleCastCheck() && !IsCasting() && GetClass() != BARD)
|
if (GetClass() != BARD)
|
||||||
BotMeditate(true);
|
BotMeditate(true);
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (GetClass() != BARD)
|
|
||||||
BotMeditate(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(AI_movement_timer->Check()) {
|
|
||||||
// Something is still wrong with bot the follow code...
|
if (AI_movement_timer->Check()) {
|
||||||
// Shows up really bad over long distances when movement bonuses are involved
|
float dist = DistanceSquared(m_Position, follow->GetPosition());
|
||||||
// The flip-side is that too much speed adversely affects node pathing...
|
int speed = GetBotRunspeed();
|
||||||
if (cur_dist > GetFollowDistance()) {
|
|
||||||
|
if (dist < GetFollowDistance() + BOT_FOLLOW_DISTANCE_WALK)
|
||||||
|
speed = GetBotWalkspeed();
|
||||||
|
|
||||||
|
SetRunAnimSpeed(0);
|
||||||
|
|
||||||
|
if (dist > GetFollowDistance()) {
|
||||||
if (RuleB(Bots, UsePathing) && zone->pathing) {
|
if (RuleB(Bots, UsePathing) && zone->pathing) {
|
||||||
if (cur_dist <= BOT_FOLLOW_DISTANCE_WALK) {
|
bool WaypointChanged, NodeReached;
|
||||||
bool WaypointChanged, NodeReached;
|
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(follow->GetX(), follow->GetY(), follow->GetZ(),
|
glm::vec3 Goal = UpdatePath(follow->GetX(), follow->GetY(), follow->GetZ(),
|
||||||
GetWalkspeed(), WaypointChanged, NodeReached);
|
speed, WaypointChanged, NodeReached);
|
||||||
|
|
||||||
if (WaypointChanged)
|
if (WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetWalkspeed());
|
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
||||||
}
|
|
||||||
else {
|
|
||||||
int speed = GetRunspeed();
|
|
||||||
if (cur_dist > BOT_FOLLOW_DISTANCE_CRITICAL)
|
|
||||||
speed = ((float)speed * 1.333f); // sprint mod (1/3 boost)
|
|
||||||
|
|
||||||
bool WaypointChanged, NodeReached;
|
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(follow->GetX(), follow->GetY(), follow->GetZ(),
|
|
||||||
speed, WaypointChanged, NodeReached);
|
|
||||||
|
|
||||||
if (WaypointChanged)
|
|
||||||
tar_ndx = 20;
|
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (cur_dist <= BOT_FOLLOW_DISTANCE_WALK) {
|
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
||||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetWalkspeed());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int speed = GetRunspeed();
|
|
||||||
if (cur_dist > BOT_FOLLOW_DISTANCE_CRITICAL)
|
|
||||||
speed = ((float)speed * 1.333f); // sprint mod (1/3 boost)
|
|
||||||
|
|
||||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rest_timer.Enabled())
|
if (rest_timer.Enabled())
|
||||||
rest_timer.Disable();
|
rest_timer.Disable();
|
||||||
|
|
||||||
if (RuleB(Bots, UpdatePositionWithTimer)) { // this helps with rubber-banding effect
|
|
||||||
if (IsMoving())
|
|
||||||
SendPosUpdate();
|
|
||||||
//else
|
|
||||||
// SendPosition(); // enabled - no discernable difference..disabled - saves on no movement packets
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (moved) {
|
if (moved) {
|
||||||
@ -2590,13 +2573,9 @@ void Bot::AI_Process() {
|
|||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetClass() == BARD && GetBotStance() != BotStancePassive && !spellend_timer.Enabled() && AI_think_timer->Check())
|
|
||||||
AI_IdleCastCheck();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else if (IsMoving()) {
|
|
||||||
|
if (IsMoving()) {
|
||||||
if (GetClass() == BARD && GetBotStance() != BotStancePassive && !spellend_timer.Enabled() && AI_think_timer->Check()) {
|
if (GetClass() == BARD && GetBotStance() != BotStancePassive && !spellend_timer.Enabled() && AI_think_timer->Check()) {
|
||||||
AI_IdleCastCheck();
|
AI_IdleCastCheck();
|
||||||
}
|
}
|
||||||
@ -6905,6 +6884,8 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
|
|||||||
if (iter->IsBot()) {
|
if (iter->IsBot()) {
|
||||||
iter->CastToBot()->SetGroupHealer(false);
|
iter->CastToBot()->SetGroupHealer(false);
|
||||||
iter->CastToBot()->SetGroupSlower(false);
|
iter->CastToBot()->SetGroupSlower(false);
|
||||||
|
iter->CastToBot()->SetGroupNuker(false);
|
||||||
|
iter->CastToBot()->SetGroupDoter(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6913,11 +6894,14 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
|
|||||||
|
|
||||||
Mob* healer = nullptr;
|
Mob* healer = nullptr;
|
||||||
Mob* slower = nullptr;
|
Mob* slower = nullptr;
|
||||||
|
Mob* nuker = nullptr;
|
||||||
|
Mob* doter = nullptr;
|
||||||
|
|
||||||
for (auto iter : group->members) {
|
for (auto iter : group->members) {
|
||||||
if (!iter)
|
if (!iter)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// GroupHealer
|
||||||
switch (iter->GetClass()) {
|
switch (iter->GetClass()) {
|
||||||
case CLERIC:
|
case CLERIC:
|
||||||
if (!healer)
|
if (!healer)
|
||||||
@ -6966,6 +6950,7 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GroupSlower
|
||||||
switch (iter->GetClass()) {
|
switch (iter->GetClass()) {
|
||||||
case SHAMAN:
|
case SHAMAN:
|
||||||
if (!slower)
|
if (!slower)
|
||||||
@ -6997,14 +6982,43 @@ void Bot::UpdateGroupCastingRoles(const Group* group, bool disband)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GroupNuker
|
||||||
|
switch (iter->GetClass()) {
|
||||||
|
// wizard
|
||||||
|
// magician
|
||||||
|
// necromancer
|
||||||
|
// enchanter
|
||||||
|
// druid
|
||||||
|
// cleric
|
||||||
|
// shaman
|
||||||
|
// shadowknight
|
||||||
|
// paladin
|
||||||
|
// ranger
|
||||||
|
// beastlord
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupDoter
|
||||||
|
switch (iter->GetClass()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (healer && healer->IsBot())
|
if (healer && healer->IsBot())
|
||||||
healer->CastToBot()->SetGroupHealer();
|
healer->CastToBot()->SetGroupHealer();
|
||||||
if (slower && slower->IsBot())
|
if (slower && slower->IsBot())
|
||||||
slower->CastToBot()->SetGroupSlower();
|
slower->CastToBot()->SetGroupSlower();
|
||||||
|
if (nuker && nuker->IsBot())
|
||||||
|
nuker->CastToBot()->SetGroupNuker();
|
||||||
|
if (doter && doter->IsBot())
|
||||||
|
doter->CastToBot()->SetGroupDoter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void Bot::UpdateRaidCastingRoles(const Raid* raid, bool disband = false) { }
|
||||||
|
|
||||||
bool Bot::CanHeal() {
|
bool Bot::CanHeal() {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
@ -7024,10 +7038,6 @@ bool Bot::CanHeal() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ) {
|
|
||||||
return MakeNewPositionAndSendUpdate(x, y, z, speed, checkZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, std::string botName) {
|
Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, std::string botName) {
|
||||||
Bot* Result = 0;
|
Bot* Result = 0;
|
||||||
if(c) {
|
if(c) {
|
||||||
@ -7776,6 +7786,23 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iSpellTypes == SpellType_PreCombatBuff) {
|
||||||
|
if (botCasterClass == BARD || caster->IsEngaged())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (caster->HasGroup()) {
|
||||||
|
Group *g = caster->GetGroup();
|
||||||
|
if (g) {
|
||||||
|
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
|
if (g->members[i]) {
|
||||||
|
if (caster->AICastSpell(g->members[i], iChance, SpellType_PreCombatBuff) || caster->AICastSpell(g->members[i]->GetPet(), iChance, SpellType_PreCombatBuff))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
zone/bot.h
61
zone/bot.h
@ -40,8 +40,7 @@
|
|||||||
|
|
||||||
#define BOT_FOLLOW_DISTANCE_DEFAULT 184 // as DSq value (~13.565 units)
|
#define BOT_FOLLOW_DISTANCE_DEFAULT 184 // as DSq value (~13.565 units)
|
||||||
#define BOT_FOLLOW_DISTANCE_DEFAULT_MAX 2500 // as DSq value (50 units)
|
#define BOT_FOLLOW_DISTANCE_DEFAULT_MAX 2500 // as DSq value (50 units)
|
||||||
#define BOT_FOLLOW_DISTANCE_WALK 400 // as DSq value (20 units)
|
#define BOT_FOLLOW_DISTANCE_WALK 1000 // as DSq value (~31.623 units)
|
||||||
#define BOT_FOLLOW_DISTANCE_CRITICAL 22500 // as DSq value (150 units)
|
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
|
||||||
@ -132,11 +131,48 @@ enum SpellTypeIndex {
|
|||||||
SpellType_HateReduxIndex,
|
SpellType_HateReduxIndex,
|
||||||
SpellType_InCombatBuffSongIndex,
|
SpellType_InCombatBuffSongIndex,
|
||||||
SpellType_OutOfCombatBuffSongIndex,
|
SpellType_OutOfCombatBuffSongIndex,
|
||||||
|
SpellType_PreCombatBuffIndex,
|
||||||
|
SpellType_PreCombatBuffSongIndex,
|
||||||
MaxSpellTypes
|
MaxSpellTypes
|
||||||
};
|
};
|
||||||
|
|
||||||
// negative Healer/Slower, positive Healer, postive Slower, positive Healer/Slower
|
// nHSND negative Healer/Slower/Nuker/Doter
|
||||||
enum BotCastingChanceConditional : uint8 { nHS = 0, pH, pS, pHS, cntHS = 4 };
|
// pH positive Healer
|
||||||
|
// pS positive Slower
|
||||||
|
// pHS positive Healer/Slower
|
||||||
|
// pN positive Nuker
|
||||||
|
// pHN positive Healer/Nuker
|
||||||
|
// pSN positive Slower/Nuker
|
||||||
|
// pHSN positive Healer/Slower/Nuker
|
||||||
|
// pD positive Doter
|
||||||
|
// pHD positive Healer/Doter
|
||||||
|
// pSD positive Slower/Doter
|
||||||
|
// pHSD positive Healer/Slower/Doter
|
||||||
|
// pND positive Nuker/Doter
|
||||||
|
// pHND positive Healer/Nuker/Doter
|
||||||
|
// pSND positive Slower/Nuker/Doter
|
||||||
|
// pHSND positive Healer/Slower/Nuker/Doter
|
||||||
|
// cntHSND count Healer/Slower/Nuker/Doter
|
||||||
|
enum BotCastingChanceConditional : uint8
|
||||||
|
{
|
||||||
|
nHSND = 0,
|
||||||
|
pH,
|
||||||
|
pS,
|
||||||
|
pHS,
|
||||||
|
pN,
|
||||||
|
pHN,
|
||||||
|
pSN,
|
||||||
|
pHSN,
|
||||||
|
pD,
|
||||||
|
pHD,
|
||||||
|
pSD,
|
||||||
|
pHSD,
|
||||||
|
pND,
|
||||||
|
pHND,
|
||||||
|
pSND,
|
||||||
|
pHSND,
|
||||||
|
cntHSND = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Bot : public NPC {
|
class Bot : public NPC {
|
||||||
@ -299,8 +335,9 @@ public:
|
|||||||
void Stand();
|
void Stand();
|
||||||
bool IsSitting();
|
bool IsSitting();
|
||||||
bool IsStanding();
|
bool IsStanding();
|
||||||
|
int GetBotWalkspeed() const { return (int)((float)_GetWalkSpeed() * 1.786f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143
|
||||||
|
int GetBotRunspeed() const { return (int)((float)_GetRunSpeed() * 1.786f); }
|
||||||
bool IsBotCasterCombatRange(Mob *target);
|
bool IsBotCasterCombatRange(Mob *target);
|
||||||
bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true) ;
|
|
||||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||||
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets);
|
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets);
|
||||||
bool GetNeedsCured(Mob *tar);
|
bool GetNeedsCured(Mob *tar);
|
||||||
@ -482,8 +519,16 @@ public:
|
|||||||
|
|
||||||
bool IsGroupHealer() { return m_CastingRoles.GroupHealer; }
|
bool IsGroupHealer() { return m_CastingRoles.GroupHealer; }
|
||||||
bool IsGroupSlower() { return m_CastingRoles.GroupSlower; }
|
bool IsGroupSlower() { return m_CastingRoles.GroupSlower; }
|
||||||
|
bool IsGroupNuker() { return m_CastingRoles.GroupNuker; }
|
||||||
|
bool IsGroupDoter() { return m_CastingRoles.GroupDoter; }
|
||||||
static void UpdateGroupCastingRoles(const Group* group, bool disband = false);
|
static void UpdateGroupCastingRoles(const Group* group, bool disband = false);
|
||||||
|
|
||||||
|
//bool IsRaidHealer() { return m_CastingRoles.RaidHealer; }
|
||||||
|
//bool IsRaidSlower() { return m_CastingRoles.RaidSlower; }
|
||||||
|
//bool IsRaidNuker() { return m_CastingRoles.RaidNuker; }
|
||||||
|
//bool IsRaidDoter() { return m_CastingRoles.RaidDoter; }
|
||||||
|
//static void UpdateRaidCastingRoles(const Raid* raid, bool disband = false);
|
||||||
|
|
||||||
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
||||||
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
||||||
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
||||||
@ -650,6 +695,12 @@ protected:
|
|||||||
BotCastingRoles& GetCastingRoles() { return m_CastingRoles; }
|
BotCastingRoles& GetCastingRoles() { return m_CastingRoles; }
|
||||||
void SetGroupHealer(bool flag = true) { m_CastingRoles.GroupHealer = flag; }
|
void SetGroupHealer(bool flag = true) { m_CastingRoles.GroupHealer = flag; }
|
||||||
void SetGroupSlower(bool flag = true) { m_CastingRoles.GroupSlower = flag; }
|
void SetGroupSlower(bool flag = true) { m_CastingRoles.GroupSlower = flag; }
|
||||||
|
void SetGroupNuker(bool flag = true) { m_CastingRoles.GroupNuker = flag; }
|
||||||
|
void SetGroupDoter(bool flag = true) { m_CastingRoles.GroupDoter = flag; }
|
||||||
|
//void SetRaidHealer(bool flag = true) { m_CastingRoles.RaidHealer = flag; }
|
||||||
|
//void SetRaidSlower(bool flag = true) { m_CastingRoles.RaidSlower = flag; }
|
||||||
|
//void SetRaidNuker(bool flag = true) { m_CastingRoles.RaidNuker = flag; }
|
||||||
|
//void SetRaidDoter(bool flag = true) { m_CastingRoles.RaidDoter = flag; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Class Members
|
// Class Members
|
||||||
|
|||||||
@ -5151,6 +5151,7 @@ void bot_subcommand_bot_summon(Client *c, const Seperator *sep)
|
|||||||
bot_iter->WipeHateList();
|
bot_iter->WipeHateList();
|
||||||
bot_iter->SetTarget(bot_iter->GetBotOwner());
|
bot_iter->SetTarget(bot_iter->GetBotOwner());
|
||||||
bot_iter->Warp(glm::vec3(c->GetPosition()));
|
bot_iter->Warp(glm::vec3(c->GetPosition()));
|
||||||
|
bot_iter->DoAnim(0);
|
||||||
|
|
||||||
if (!bot_iter->HasPet())
|
if (!bot_iter->HasPet())
|
||||||
continue;
|
continue;
|
||||||
@ -5399,6 +5400,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
bot_iter->SetPetChooser(false);
|
bot_iter->SetPetChooser(false);
|
||||||
bot_iter->CalcBotStats((sbl.size() == 1));
|
bot_iter->CalcBotStats((sbl.size() == 1));
|
||||||
|
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
||||||
++bot_count;
|
++bot_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ bool BotDatabase::LoadBotCommandSettings(std::map<std::string, std::pair<uint8,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8 spell_casting_chances[MaxSpellTypes][PLAYER_CLASS_COUNT][MaxStances][cntHS];
|
static uint8 spell_casting_chances[MaxSpellTypes][PLAYER_CLASS_COUNT][MaxStances][cntHSND];
|
||||||
|
|
||||||
bool BotDatabase::LoadBotSpellCastingChances()
|
bool BotDatabase::LoadBotSpellCastingChances()
|
||||||
{
|
{
|
||||||
@ -91,17 +91,29 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
|||||||
query =
|
query =
|
||||||
"SELECT"
|
"SELECT"
|
||||||
" `spell_type_index`,"
|
" `spell_type_index`,"
|
||||||
" `class_index`,"
|
" `class_id`,"
|
||||||
" `stance_index`,"
|
" `stance_index`,"
|
||||||
" `conditional_index`,"
|
" `nHSND_value`,"
|
||||||
" `value` "
|
" `pH_value`,"
|
||||||
|
" `pS_value`,"
|
||||||
|
" `pHS_value`,"
|
||||||
|
" `pN_value`,"
|
||||||
|
" `pHN_value`,"
|
||||||
|
" `pSN_value`,"
|
||||||
|
" `pHSN_value`,"
|
||||||
|
" `pD_value`,"
|
||||||
|
" `pHD_value`,"
|
||||||
|
" `pSD_value`,"
|
||||||
|
" `pHSD_value`,"
|
||||||
|
" `pND_value`,"
|
||||||
|
" `pHND_value`,"
|
||||||
|
" `pSND_value`,"
|
||||||
|
" `pHSND_value`"
|
||||||
"FROM"
|
"FROM"
|
||||||
" `bot_spell_casting_chances` "
|
" `bot_spell_casting_chances`";
|
||||||
"WHERE"
|
|
||||||
" `value` != '0'";
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success() || !results.RowCount())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
@ -109,18 +121,22 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
|||||||
if (spell_type_index >= MaxSpellTypes)
|
if (spell_type_index >= MaxSpellTypes)
|
||||||
continue;
|
continue;
|
||||||
uint8 class_index = atoi(row[1]);
|
uint8 class_index = atoi(row[1]);
|
||||||
if (class_index >= PLAYER_CLASS_COUNT)
|
if (class_index < WARRIOR || class_index > BERSERKER)
|
||||||
continue;
|
continue;
|
||||||
|
--class_index;
|
||||||
uint8 stance_index = atoi(row[2]);
|
uint8 stance_index = atoi(row[2]);
|
||||||
if (stance_index >= MaxStances)
|
if (stance_index >= MaxStances)
|
||||||
continue;
|
continue;
|
||||||
uint8 conditional_index = atoi(row[3]);
|
|
||||||
if (conditional_index >= cntHS)
|
for (uint8 conditional_index = nHSND; conditional_index < cntHSND; ++conditional_index) {
|
||||||
continue;
|
uint8 value = atoi(row[3 + conditional_index]);
|
||||||
uint8 value = atoi(row[4]);
|
if (!value)
|
||||||
if (value > 100)
|
continue;
|
||||||
value = 100;
|
if (value > 100)
|
||||||
spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index] = value;
|
value = 100;
|
||||||
|
|
||||||
|
spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2761,7 +2777,7 @@ bool BotDatabase::DeleteAllHealRotations(const uint32 owner_id)
|
|||||||
|
|
||||||
|
|
||||||
/* Bot miscellaneous functions */
|
/* Bot miscellaneous functions */
|
||||||
uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index)
|
uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index) // class_index is 0-based
|
||||||
{
|
{
|
||||||
if (spell_type_index >= MaxSpellTypes)
|
if (spell_type_index >= MaxSpellTypes)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2769,7 +2785,7 @@ uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_ind
|
|||||||
return 0;
|
return 0;
|
||||||
if (stance_index >= MaxStances)
|
if (stance_index >= MaxStances)
|
||||||
return 0;
|
return 0;
|
||||||
if (conditional_index >= cntHS)
|
if (conditional_index >= cntHSND)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index];
|
return spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index];
|
||||||
|
|||||||
@ -63,6 +63,12 @@ struct BotSpell_wPriority : public BotSpell {
|
|||||||
struct BotCastingRoles {
|
struct BotCastingRoles {
|
||||||
bool GroupHealer;
|
bool GroupHealer;
|
||||||
bool GroupSlower;
|
bool GroupSlower;
|
||||||
|
bool GroupNuker;
|
||||||
|
bool GroupDoter;
|
||||||
|
//bool RaidHealer;
|
||||||
|
//bool RaidSlower;
|
||||||
|
//bool RaidNuker;
|
||||||
|
//bool RaidDoter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BotAA {
|
struct BotAA {
|
||||||
|
|||||||
@ -1046,6 +1046,12 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SpellType_PreCombatBuff: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SpellType_PreCombatBuffSong: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1163,16 +1169,28 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
#endif
|
#endif
|
||||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||||
|
|
||||||
//Ok, IdleCastCheck depends of class.
|
bool pre_combat = false;
|
||||||
// Healers WITHOUT pets will check if a heal is needed before buffing.
|
Mob* test_against = nullptr;
|
||||||
uint8 botClass = GetClass();
|
|
||||||
|
|
||||||
if(botClass == CLERIC || botClass == PALADIN || botClass == RANGER) {
|
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient())
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
test_against = GetGroup()->GetLeader();
|
||||||
|
else if (GetOwner() && GetOwner()->IsClient())
|
||||||
|
test_against = GetOwner();
|
||||||
|
|
||||||
|
if (test_against && test_against->GetTarget() && test_against->GetTarget()->IsNPC() && !test_against->GetTarget()->IsPet())
|
||||||
|
pre_combat = true;
|
||||||
|
|
||||||
|
//Ok, IdleCastCheck depends of class.
|
||||||
|
switch (GetClass()) {
|
||||||
|
// Healers WITHOUT pets will check if a heal is needed before buffing.
|
||||||
|
case CLERIC:
|
||||||
|
case PALADIN:
|
||||||
|
case RANGER: {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1181,16 +1199,23 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Pets class will first cast their pet, then buffs
|
// Pets class will first cast their pet, then buffs
|
||||||
else if(botClass == DRUID || botClass == MAGICIAN || botClass == SHADOWKNIGHT || botClass == SHAMAN || botClass == NECROMANCER || botClass == ENCHANTER || botClass == BEASTLORD || botClass == WIZARD) {
|
case DRUID:
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
case MAGICIAN:
|
||||||
|
case SHADOWKNIGHT:
|
||||||
|
case SHAMAN:
|
||||||
|
case NECROMANCER:
|
||||||
|
case ENCHANTER:
|
||||||
|
case BEASTLORD: {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
||||||
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
||||||
if(!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1201,23 +1226,57 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if(botClass == BARD) {
|
case WIZARD: { // This can eventually be move into the BEASTLORD case handler once pre-combat is fully implemented
|
||||||
// bard bots
|
if (pre_combat) {
|
||||||
bool battle_prep = false;
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
Mob* prep_against = nullptr;
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
if (HasGroup() && GetGroup()->GetLeader() && GetGroup()->GetLeader()->IsClient())
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
||||||
prep_against = GetGroup()->GetLeader();
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
else if (GetOwner() && GetOwner()->IsClient())
|
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
||||||
prep_against = GetOwner();
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_PreCombatBuff)) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
if (prep_against && prep_against->GetTarget() && prep_against->GetTarget()->IsNPC() && !prep_against->GetTarget()->IsPet())
|
//
|
||||||
battle_prep = true;
|
}
|
||||||
|
}
|
||||||
if (battle_prep) {
|
}
|
||||||
if (!AICastSpell(this, 100, SpellType_InCombatBuffSong)) {
|
}
|
||||||
//
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Pet)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Heal)) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Heal)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_Buff)) {
|
||||||
|
if (!AICastSpell(GetPet(), 100, SpellType_Heal)) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Buff)) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BARD: {
|
||||||
|
if (pre_combat) {
|
||||||
|
if (!entity_list.Bot_AICheckCloseBeneficialSpells(this, 100, BotAISpellRange, SpellType_Cure)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_PreCombatBuffSong)) {
|
||||||
|
if (!AICastSpell(this, 100, SpellType_InCombatBuffSong)) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1229,6 +1288,10 @@ bool Bot::AI_IdleCastCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!AIautocastspell_timer->Enabled())
|
if(!AIautocastspell_timer->Enabled())
|
||||||
@ -2572,6 +2635,12 @@ uint8 Bot::GetChanceToCastBySpellType(uint32 spellType)
|
|||||||
case SpellType_OutOfCombatBuffSong:
|
case SpellType_OutOfCombatBuffSong:
|
||||||
spell_type_index = SpellType_OutOfCombatBuffSongIndex;
|
spell_type_index = SpellType_OutOfCombatBuffSongIndex;
|
||||||
break;
|
break;
|
||||||
|
case SpellType_PreCombatBuff:
|
||||||
|
spell_type_index = SpellType_PreCombatBuffIndex;
|
||||||
|
break;
|
||||||
|
case SpellType_PreCombatBuffSong:
|
||||||
|
spell_type_index = SpellType_PreCombatBuffSongIndex;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
spell_type_index = MaxSpellTypes;
|
spell_type_index = MaxSpellTypes;
|
||||||
break;
|
break;
|
||||||
@ -2588,12 +2657,16 @@ uint8 Bot::GetChanceToCastBySpellType(uint32 spellType)
|
|||||||
if (stance_index >= MaxStances)
|
if (stance_index >= MaxStances)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint8 type_index = nHS;
|
uint8 type_index = nHSND;
|
||||||
if (HasGroup()) {
|
if (HasGroup()) {
|
||||||
if (IsGroupHealer())
|
if (IsGroupHealer()/* || IsRaidHealer()*/)
|
||||||
type_index |= pH;
|
type_index |= pH;
|
||||||
if (IsGroupSlower())
|
if (IsGroupSlower()/* || IsRaidSlower()*/)
|
||||||
type_index |= pS;
|
type_index |= pS;
|
||||||
|
if (IsGroupNuker()/* || IsRaidNuker()*/)
|
||||||
|
type_index |= pN;
|
||||||
|
if (IsGroupDoter()/* || IsRaidDoter()*/)
|
||||||
|
type_index |= pD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return botdb.GetSpellCastingChance(spell_type_index, class_index, stance_index, type_index);
|
return botdb.GetSpellCastingChance(spell_type_index, class_index, stance_index, type_index);
|
||||||
|
|||||||
@ -5912,20 +5912,20 @@ void Client::SendGroupCreatePacket()
|
|||||||
|
|
||||||
char *Buffer = (char *)outapp->pBuffer;
|
char *Buffer = (char *)outapp->pBuffer;
|
||||||
// Header
|
// Header
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // group ID probably
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); // count of members in packet
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // Null Leader name
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // Null Leader name, shouldn't be null besides this case
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Member 0
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Member 0, index
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, GetName());
|
VARSTRUCT_ENCODE_STRING(Buffer, GetName()); // group member name
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // merc flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // owner name (if merc)
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, GetLevel()); // level
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, GetLevel());
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline flag
|
||||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||||
|
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
@ -8823,7 +8823,7 @@ void Client::ProcessAggroMeter()
|
|||||||
secondary = cur_tar->GetSecondaryHate(this);
|
secondary = cur_tar->GetSecondaryHate(this);
|
||||||
has_aggro = true;
|
has_aggro = true;
|
||||||
} else {
|
} else {
|
||||||
secondary = cur_tar->GetTarget();
|
secondary = cur_tar->CheckAggro(cur_tar->GetTarget()) ? cur_tar->GetTarget() : nullptr; // make sure they are targeting for aggro reasons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -255,6 +255,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
|
|||||||
item->attuned = 0;
|
item->attuned = 0;
|
||||||
item->min_level = minlevel;
|
item->min_level = minlevel;
|
||||||
item->max_level = maxlevel;
|
item->max_level = maxlevel;
|
||||||
|
item->equip_slot = EQEmu::inventory::slotInvalid;
|
||||||
|
|
||||||
if (equipit) {
|
if (equipit) {
|
||||||
uint8 eslot = 0xFF;
|
uint8 eslot = 0xFF;
|
||||||
@ -399,8 +400,8 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
|
|||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
CalcBonuses(); // This is less than ideal for bulk adding of items
|
CalcBonuses(); // This is less than ideal for bulk adding of items
|
||||||
|
item->equip_slot = foundslot;
|
||||||
}
|
}
|
||||||
item->equip_slot = item2->Slots;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(itemlist != nullptr)
|
if(itemlist != nullptr)
|
||||||
|
|||||||
19
zone/mob.cpp
19
zone/mob.cpp
@ -614,7 +614,11 @@ int Mob::_GetWalkSpeed() const {
|
|||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
//runspeed cap.
|
//runspeed cap.
|
||||||
|
#ifdef BOTS
|
||||||
|
if (IsClient() || IsBot())
|
||||||
|
#else
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if(speed_mod > runspeedcap)
|
if(speed_mod > runspeedcap)
|
||||||
speed_mod = runspeedcap;
|
speed_mod = runspeedcap;
|
||||||
@ -673,7 +677,11 @@ int Mob::_GetRunSpeed() const {
|
|||||||
|
|
||||||
if (!has_horse && movemod != 0)
|
if (!has_horse && movemod != 0)
|
||||||
{
|
{
|
||||||
|
#ifdef BOTS
|
||||||
|
if (IsClient() || IsBot())
|
||||||
|
#else
|
||||||
if (IsClient())
|
if (IsClient())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
speed_mod += (speed_mod * movemod / 100);
|
speed_mod += (speed_mod * movemod / 100);
|
||||||
} else {
|
} else {
|
||||||
@ -702,7 +710,11 @@ int Mob::_GetRunSpeed() const {
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
//runspeed cap.
|
//runspeed cap.
|
||||||
|
#ifdef BOTS
|
||||||
|
if (IsClient() || IsBot())
|
||||||
|
#else
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if(speed_mod > runspeedcap)
|
if(speed_mod > runspeedcap)
|
||||||
speed_mod = runspeedcap;
|
speed_mod = runspeedcap;
|
||||||
@ -1459,10 +1471,15 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
|
|||||||
spu->padding0006 =7;
|
spu->padding0006 =7;
|
||||||
spu->padding0014 =0x7f;
|
spu->padding0014 =0x7f;
|
||||||
spu->padding0018 =0x5df27;
|
spu->padding0018 =0x5df27;
|
||||||
|
#ifdef BOTS
|
||||||
|
if (this->IsClient() || this->IsBot())
|
||||||
|
#else
|
||||||
if(this->IsClient())
|
if(this->IsClient())
|
||||||
|
#endif
|
||||||
spu->animation = animation;
|
spu->animation = animation;
|
||||||
else
|
else
|
||||||
spu->animation = pRunAnimSpeed;//animation;
|
spu->animation = pRunAnimSpeed;//animation;
|
||||||
|
|
||||||
spu->delta_heading = NewFloatToEQ13(m_Delta.w);
|
spu->delta_heading = NewFloatToEQ13(m_Delta.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2606,11 +2606,12 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
|
|||||||
uint32 tmpidle_no_sp_recast_max = atoi(row[18]);
|
uint32 tmpidle_no_sp_recast_max = atoi(row[18]);
|
||||||
uint8 tmpidle_b_chance = atoi(row[19]);
|
uint8 tmpidle_b_chance = atoi(row[19]);
|
||||||
|
|
||||||
|
// pulling fixed values from an auto-increment field is dangerous...
|
||||||
query = StringFormat("SELECT spellid, type, minlevel, maxlevel, "
|
query = StringFormat("SELECT spellid, type, minlevel, maxlevel, "
|
||||||
"manacost, recast_delay, priority, resist_adjust "
|
"manacost, recast_delay, priority, resist_adjust "
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
"FROM %s "
|
"FROM %s "
|
||||||
"WHERE npc_spells_id=%d ORDER BY minlevel", (iDBSpellsID >= 701 && iDBSpellsID <= 712 ? "bot_spells_entries" : "npc_spells_entries"), iDBSpellsID);
|
"WHERE npc_spells_id=%d ORDER BY minlevel", (iDBSpellsID >= 3001 && iDBSpellsID <= 3016 ? "bot_spells_entries" : "npc_spells_entries"), iDBSpellsID);
|
||||||
#else
|
#else
|
||||||
"FROM npc_spells_entries "
|
"FROM npc_spells_entries "
|
||||||
"WHERE npc_spells_id=%d ORDER BY minlevel", iDBSpellsID);
|
"WHERE npc_spells_id=%d ORDER BY minlevel", iDBSpellsID);
|
||||||
|
|||||||
@ -567,7 +567,11 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
m_TargetV.z = z - nz;
|
m_TargetV.z = z - nz;
|
||||||
SetCurrentSpeed((int8)speed);
|
SetCurrentSpeed((int8)speed);
|
||||||
pRunAnimSpeed = speed;
|
pRunAnimSpeed = speed;
|
||||||
|
#ifdef BOTS
|
||||||
|
if(IsClient() || IsBot())
|
||||||
|
#else
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
animation = speed / 2;
|
animation = speed / 2;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user