Compare commits

..

26 Commits

Author SHA1 Message Date
Chris Miles c64a2aec94 [Release] 22.11.0 (#3328)
* [Release] 22.11.0

* Update version.h
2023-04-29 20:37:04 -05:00
Alex King 0e582eda82 [Quest API] Add HasSpellEffect() to Perl/Lua (#3319)
* [Quest API] Add HasSpellEffect() to Perl/Lua

# Perl
- Add `$mob->HasSpellEffect(effect_id)`.

# Lua
- Add `mob:HasSpellEffect(effect_id)`.

# Notes
- Allows operators to see if a Mob has an effect ID from any of their buffs.

* Update mob.cpp
2023-04-29 20:09:00 -05:00
Alex King 7eff6ada87 [Cleanup] Remove unused code in zone/pets.cpp (#3310)
# Notes
- This code is unused.
2023-04-29 20:00:37 -05:00
Alex King 291997d35b [Cleanup] Remove pDontCastBefore_casting_spell from zone/npc.h (#3311)
# Notes
- This is unused.
2023-04-29 20:00:20 -05:00
Alex King ac4572bf79 [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h (#3312)
* [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h

# Notes
- Remove `CheckAccess()` in `zone/client.cpp`.
- Remove `CheckAccess()` in `zone/client.h`.
- Remove `CheckQuests()` in `zone/client.h`.
- Remove `MakeCorpse()` in `zone/client.h`.
- Remove `HPTick()` in `zone/client.h`.
- These methods are unused.

* Update client.h
2023-04-29 20:00:08 -05:00
Alex King f0a9578b6a [Cleanup] Remove GetClassHPFactor() from zone/merc.h (#3314)
# Notes
- This is unused.
2023-04-29 19:59:50 -05:00
Alex King baa824d8fb [Cleanup] Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h (#3313)
# Notes
- This is unused.
2023-04-29 19:59:19 -05:00
Alex King b19d3ac8a2 [Cleanup] Remove unused methods in zone/bot.cpp and zone/bot.h (#3315)
# Notes
- Remove `DoFinishedSpellAETarget()`.
- Remove `SendBotArcheryWearChange()`.
- These are unused.
2023-04-29 19:59:05 -05:00
Alex King 6a393bf0c3 [Quest API] Add GetDefaultRaceSize() overloads to Perl/Lua (#3320)
# Perl
- Add `$mob->GetDefaultRaceSize(race_id)`.
- Add `$mob->GetDefaultRaceSize(race_id, gender_id)`.

# Lua
- Add `mob:GetDefaultRaceSize(race_id)`.
- Add `mob:GetDefaultRaceSize(race_id, gender_id)`.

# Notes
- This allows you to get a default size for a race and gender that isn't the current mob's race and gender.
2023-04-29 19:53:49 -05:00
Alex King 09a5551de1 [Cleanup] quest::setallskill() had always true condition. (#3301)
# Notes
- Remove unnecessary double check of `initiator`.
- Cleanup logic to use `EQ::skills::GetSkillTypeMap()`.
2023-04-29 19:52:30 -05:00
Alex King 6e2e035d66 [Cleanup] Remove unused variable in common/crash.cpp (#3308)
# Notes
- This variable is unused.
2023-04-29 19:51:41 -05:00
Alex King ac5922bb32 [Cleanup] Use default ctor/dtor in oriented_bounding_box.h (#3307)
# Notes
- Use default ctor/dtor instead of empty ones.
2023-04-29 19:51:21 -05:00
Chris Miles ecf2a369cc [Discord] Add Discord webhook callback processing to world (#3322) 2023-04-29 20:49:06 -04:00
Chris Miles 95b306599f [Maps] Update download with faster releases link (#3321) 2023-04-29 19:39:24 -05:00
Chris Miles 497d20512a [Crash] Fix UCS crash that occurs during log reloading (#3324) 2023-04-29 19:39:13 -05:00
Aeadoin db916e946e [Bug Fix] Fix issue with spawning Mercs (#3327) 2023-04-29 18:45:35 -04:00
Alex King 958549b407 [Bug Fix] Possible issues with SummonItem in Client::QuestReward() methods (#3325)
# Notes
- These methods were ignoring the sixth augment slot and could cause item to be summoned attuned being `EQ::invslot::slotCursor` is a non-zero value.
2023-04-26 21:28:24 -04:00
Paul Coene 71ebf1b2d4 [Messages] Remove duplicate you have lost a level message (#3323) 2023-04-25 17:42:31 -04:00
Paul Coene e19b8d3056 [Bug Fix] Fix issue with NPCs no longer using some armor. (#3318)
* [BugFix/NPCs] Fix issue with NPCs no longer using some armor.

* Removed redundant memory clear
2023-04-24 17:05:29 -04:00
Alex King 8b1d64a043 [Cleanup] quest::createBot() unnecessary check against nullptr (#3302)
# Notes
- We initialize this variable, so it can never be a nullptr.
2023-04-23 15:08:50 -04:00
Alex King 576f99f292 [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp (#3306)
* [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp

# Notes
- Add `initiator` check to `quest::permaclass()`.
- Add `initiator` check to `quest::permarace()`.
- Add `initiator` check to `quest::permagender()`.
- Add `initiator` check to `quest::scribespells()`.
- Add `initiator` check to `quest::traindiscs()`.
- Add `initiator` check to `quest::unscribespells()`.
- Add `initiator` check to `quest::untraindiscs()`.
- Cleanup `initiator` check in `quest::pvp()`.
- Cleanup `initiator` check in `quest::movepc()`.
- Cleanup `initiator` check in `quest::gmmove()`.
- Cleanup `initiator` check in `quest::movegrp()`.
- Add `owner` check to `quest::doanim()`.
- Cleanup `initiator` check in `quest::addskill()`.
- Cleanup `initiator` check in `quest::setlanguage()`.
- Cleanup `initiator` check in `quest::setskill()`.

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp
2023-04-23 15:08:32 -04:00
Alex King e3761cf2a3 [Cleanup] Add check for owner in quest::resumetimer() (#3305)
# Notes
- We didn't check for owner before doing `owner->GetName()`.
2023-04-23 15:07:49 -04:00
Alex King ad1764b464 [Cleanup] Add cehck for owner in quest::pausetimer() (#3304)
# Notes
- We didn't check for `owner` before doing `owner->GetName()`.
2023-04-23 15:07:09 -04:00
Alex King 1c9ea57a4e [Cleanup] Fix possible nullptr in quest::addloot() (#3303)
# Notes
- We didn't check for `owner` before calling `owner->IsNPC()`.
2023-04-23 15:06:53 -04:00
Alex King 03c158b674 [Crash] Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() (#3317)
# Notes
- We could possibly not have a `zone` here, causing a crash.
- http://spire.akkadius.com/dev/release/22.9.1?id=3051
- http://spire.akkadius.com/dev/release/22.9.1?id=3052
- http://spire.akkadius.com/dev/release/22.9.1?id=3073
- http://spire.akkadius.com/dev/release/22.9.1?id=3102
- http://spire.akkadius.com/dev/release/22.9.1?id=3103
- http://spire.akkadius.com/dev/release/22.9.1?id=3104
- http://spire.akkadius.com/dev/release/22.9.1?id=3107
- http://spire.akkadius.com/dev/release/22.9.1?id=3108
- http://spire.akkadius.com/dev/release/22.9.1?id=3109
- http://spire.akkadius.com/dev/release/22.9.1?id=3110
- http://spire.akkadius.com/dev/release/22.9.1?id=3111
- http://spire.akkadius.com/dev/release/22.9.1?id=3112
- http://spire.akkadius.com/dev/release/22.9.1?id=3113
- http://spire.akkadius.com/dev/release/22.9.1?id=3114
2023-04-23 15:05:47 -04:00
Aeadoin 39b5374e92 [Crash] Fix possible dereference of nullptr in Client::CalcHPRegen (#3316) 2023-04-23 14:27:43 -04:00
28 changed files with 657 additions and 530 deletions
+48
View File
@@ -1,3 +1,51 @@
## [22.11.0] - 04/29/2023
### Code
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
### Crash
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
### Discord
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
### Fixes
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
### Maps
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
### Messages
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
### Quest API
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
## [22.10.0] - 04/22/2023 ## [22.10.0] - 04/22/2023
### Backups ### Backups
-3
View File
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0); r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0); r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0); r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info // os info
auto os = EQ::GetOS(); auto os = EQ::GetOS();
+1 -1
View File
@@ -25,7 +25,7 @@
// Build variables // Build variables
// these get injected during the build pipeline // these get injected during the build pipeline
#define CURRENT_VERSION "22.10.0-dev" // always append -dev to the current version for custom-builds #define CURRENT_VERSION "22.11.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0" #define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__ #define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__ #define COMPILE_TIME __TIME__
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "eqemu-server", "name": "eqemu-server",
"version": "22.10.0", "version": "22.11.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/EQEmu/Server.git" "url": "https://github.com/EQEmu/Server.git"
+2
View File
@@ -144,6 +144,8 @@ int main() {
->LoadLogDatabaseSettings() ->LoadLogDatabaseSettings()
->StartFileLogs(); ->StartFileLogs();
player_event_logs.SetDatabase(&database)->Init();
char tmp[64]; char tmp[64];
// ucs has no 'reload rules' handler // ucs has no 'reload rules' handler
+1 -15
View File
@@ -1801,23 +1801,9 @@ sub fetch_peq_db_full
sub map_files_fetch_bulk sub map_files_fetch_bulk
{ {
print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n"; print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n";
get_remote_file("http://analytics.akkadius.com/maps.zip", "maps/maps.zip", 1); get_remote_file("https://github.com/Akkadius/eqemu-maps/releases/latest/download/maps.zip", "maps/maps.zip", 1);
unzip('maps/maps.zip', 'maps/'); unzip('maps/maps.zip', 'maps/');
my @files;
my $start_dir = "maps/EQEmuMaps-master/";
find(
sub { push @files, $File::Find::name unless -d; },
$start_dir
);
for my $file (@files) {
$destination_file = $file;
$destination_file =~ s/maps\/EQEmuMaps-master\///g;
print "[Install] Installing [" . $destination_file . "]\n";
copy_file($file, "maps/" . $destination_file);
}
print "[Install] Fetched Latest Maps\n"; print "[Install] Fetched Latest Maps\n";
rmtree('maps/EQEmuMaps-master');
unlink('maps/maps.zip'); unlink('maps/maps.zip');
} }
+1
View File
@@ -17,6 +17,7 @@ public:
void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); } void Disconnect() { if(connection && connection->Handle()) connection->Handle()->Disconnect(); }
void SendMessage(const char *From, const char *Message); void SendMessage(const char *From, const char *Message);
const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const; const std::shared_ptr<EQ::Net::ServertalkServerConnection> &GetConnection() const;
inline bool IsConnected() const { return connection->Handle() ? connection->Handle()->IsConnected() : false; }
private: private:
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; } inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
+17
View File
@@ -300,6 +300,8 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
->SetLogPath(path.GetLogPath()) ->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings(); ->LoadLogDatabaseSettings();
LogSys.SetDiscordHandler(&WorldBoot::DiscordWebhookMessageHandler);
if (!ignore_db) { if (!ignore_db) {
LogInfo("Checking Database Conversions"); LogInfo("Checking Database Conversions");
database.CheckDatabaseConversions(); database.CheckDatabaseConversions();
@@ -662,3 +664,18 @@ void WorldBoot::Shutdown()
safe_delete(mutex); safe_delete(mutex);
} }
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
{
if (UCSLink.IsConnected()) {
auto pack = new ServerPacket(ServerOP_DiscordWebhookMessage, sizeof(DiscordWebhookMessage_Struct) + 1);
auto *q = (DiscordWebhookMessage_Struct *) pack->pBuffer;
strn0cpy(q->message, message.c_str(), 2000);
q->webhook_id = webhook_id;
UCSLink.SendPacket(pack);
safe_delete(pack);
}
}
+13
View File
@@ -3,6 +3,9 @@
#include <string> #include <string>
#include "../common/types.h" #include "../common/types.h"
#include "../common/discord/discord.h"
extern UCSConnection UCSLink;
class WorldBoot { class WorldBoot {
public: public:
@@ -16,6 +19,16 @@ public:
static bool DatabaseLoadRoutines(int argc, char **argv); static bool DatabaseLoadRoutines(int argc, char **argv);
static void CheckForPossibleConfigurationIssues(); static void CheckForPossibleConfigurationIssues();
static void Shutdown(); static void Shutdown();
static void SendDiscordMessage(int webhook_id, const std::string& message);
static void DiscordWebhookMessageHandler(uint16 log_category, int webhook_id, const std::string &message)
{
std::string message_prefix = fmt::format(
"[**{}**] **World** ",
Logs::LogCategoryName[log_category]
);
SendDiscordMessage(webhook_id, message_prefix + Discord::FormatDiscordMessage(log_category, message));
};
}; };
+5 -11
View File
@@ -58,16 +58,10 @@ void Mob::CalcBonuses()
void NPC::CalcBonuses() void NPC::CalcBonuses()
{ {
memset(&itembonuses, 0, sizeof(StatBonuses)); memset(&itembonuses, 0, sizeof(StatBonuses));
if (RuleB(NPC, UseItemBonusesForNonPets)) {
memset(&itembonuses, 0, sizeof(StatBonuses)); if (GetOwner() || RuleB(NPC, UseItemBonusesForNonPets)) {
CalcItemBonuses(&itembonuses); CalcItemBonuses(&itembonuses);
} }
else {
if (GetOwner()) {
memset(&itembonuses, 0, sizeof(StatBonuses));
CalcItemBonuses(&itembonuses);
}
}
// This has to happen last, so we actually take the item bonuses into account. // This has to happen last, so we actually take the item bonuses into account.
Mob::CalcBonuses(); Mob::CalcBonuses();
@@ -268,7 +262,7 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
return; return;
} }
if (!is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) { if (IsClient() && !is_tribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) { if (item->ItemType != EQ::item::ItemTypeFood && item->ItemType != EQ::item::ItemTypeDrink) {
return; return;
} }
@@ -276,14 +270,14 @@ void Mob::AddItemBonuses(const EQ::ItemInstance* inst, StatBonuses* b, bool is_a
const auto current_level = GetLevel(); const auto current_level = GetLevel();
if (current_level < inst->GetItemRequiredLevel(true)) { if (IsClient() && current_level < inst->GetItemRequiredLevel(true)) {
return; return;
} }
if (!is_ammo_item) { if (!is_ammo_item) {
const auto recommended_level = is_augment ? recommended_level_override : inst->GetItemRecommendedLevel(true); const auto recommended_level = is_augment ? recommended_level_override : inst->GetItemRecommendedLevel(true);
if (current_level >= recommended_level) { if (IsNPC() || current_level >= recommended_level) {
b->HP += item->HP; b->HP += item->HP;
b->Mana += item->Mana; b->Mana += item->Mana;
b->Endurance += item->Endur; b->Endurance += item->Endur;
-23
View File
@@ -3605,19 +3605,6 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
} }
} }
void Bot::SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color) {
auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
auto wc = (WearChange_Struct*)outapp->pBuffer;
wc->spawn_id = GetID();
wc->material = material;
wc->color.Color = color;
wc->wear_slot_id = material_slot;
entity_list.QueueClients(this, outapp);
safe_delete(outapp);
}
// Returns the item id that is in the bot inventory collection for the specified slot. // Returns the item id that is in the bot inventory collection for the specified slot.
EQ::ItemInstance* Bot::GetBotItem(uint16 slot_id) { EQ::ItemInstance* Bot::GetBotItem(uint16 slot_id) {
EQ::ItemInstance* item = m_inv.GetItem(slot_id); EQ::ItemInstance* item = m_inv.GetItem(slot_id);
@@ -5867,16 +5854,6 @@ void Bot::GenerateSpecialAttacks() {
SetSpecialAbility(SPECATK_TRIPLE, 1); SetSpecialAbility(SPECATK_TRIPLE, 1);
} }
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
if (GetClass() == BARD) {
if (!ApplyBardPulse(bardsong, this, bardsong_slot))
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
stopLogic = true;
}
return true;
}
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) { bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
if ( if (
-2
View File
@@ -196,10 +196,8 @@ public:
void SetAttackTimer() override; void SetAttackTimer() override;
uint64 GetClassHPFactor(); uint64 GetClassHPFactor();
int64 CalcMaxHP() override; int64 CalcMaxHP() override;
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic); bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic); bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool &stopLogic);
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
void Camp(bool save_to_database = true); void Camp(bool save_to_database = true);
void SetTarget(Mob* mob) override; void SetTarget(Mob* mob) override;
void Zone(); void Zone();
+2 -9
View File
@@ -2783,13 +2783,6 @@ void Client::GMKill() {
safe_delete(outapp); safe_delete(outapp);
} }
bool Client::CheckAccess(int16 iDBLevel, int16 iDefaultLevel) {
if ((admin >= iDBLevel) || (iDBLevel == AccountStatus::Max && admin >= iDefaultLevel))
return true;
else
return false;
}
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing, uint32 reduction){ void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing, uint32 reduction){
if (slot < 0 || slot >= EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize) if (slot < 0 || slot >= EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
return; return;
@@ -8545,7 +8538,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold,
AddMoneyToPP(copper, silver, gold, platinum); AddMoneyToPP(copper, silver, gold, platinum);
if (itemid > 0) if (itemid > 0)
SummonItem(itemid, -1, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor); SummonItem(itemid, -1, 0, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
if (faction) if (faction)
{ {
@@ -8581,7 +8574,7 @@ void Client::QuestReward(Mob* target, const QuestReward_Struct &reward, bool fac
for (int i = 0; i < QUESTREWARD_COUNT; ++i) for (int i = 0; i < QUESTREWARD_COUNT; ++i)
if (reward.item_id[i] > 0) if (reward.item_id[i] > 0)
SummonItem(reward.item_id[i], -1, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor); SummonItem(reward.item_id[i], -1, 0, 0, 0, 0, 0, 0, false, EQ::invslot::slotCursor);
// only process if both are valid // only process if both are valid
// if we don't have a target here, we want to just reward, but if there is a target, need to check charm // if we don't have a target here, we want to just reward, but if there is a target, need to check charm
-7
View File
@@ -322,7 +322,6 @@ public:
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); } bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); }
virtual bool Process(); virtual bool Process();
void ProcessPackets();
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone); void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL); void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false); void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
@@ -379,12 +378,8 @@ public:
void SetPetCommandState(int button, int state); void SetPetCommandState(int button, int state);
bool CheckAccess(int16 iDBLevel, int16 iDefaultLevel);
void CheckQuests(const char* zonename, const char* message, uint32 npc_id, uint32 item_id, Mob* other);
bool AutoAttackEnabled() const { return auto_attack; } bool AutoAttackEnabled() const { return auto_attack; }
bool AutoFireEnabled() const { return auto_fire; } bool AutoFireEnabled() const { return auto_fire; }
void MakeCorpse(uint32 exploss);
bool ChangeFirstName(const char* in_firstname,const char* gmname); bool ChangeFirstName(const char* in_firstname,const char* gmname);
@@ -394,7 +389,6 @@ public:
virtual void SetMaxHP(); virtual void SetMaxHP();
int32 LevelRegen(); int32 LevelRegen();
void HPTick();
void SetGM(bool toggle); void SetGM(bool toggle);
void SetPVP(bool toggle, bool message = true); void SetPVP(bool toggle, bool message = true);
@@ -1719,7 +1713,6 @@ private:
int64 CalcHPRegen(bool bCombat = false); int64 CalcHPRegen(bool bCombat = false);
int64 CalcManaRegen(bool bCombat = false); int64 CalcManaRegen(bool bCombat = false);
int64 CalcBaseManaRegen(); int64 CalcBaseManaRegen();
uint64 GetClassHPFactor();
void DoHPRegen(); void DoHPRegen();
void DoManaRegen(); void DoManaRegen();
void DoStaminaHungerUpdate(); void DoStaminaHungerUpdate();
+1 -45
View File
@@ -288,7 +288,7 @@ int64 Client::CalcHPRegen(bool bCombat)
if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) {
auto max_hp = GetMaxHP(); auto max_hp = GetMaxHP();
int fast_regen = 6 * (max_hp / zone->newzone_data.fast_regen_hp); int64 fast_regen = 6 * (max_hp / (zone ? zone->newzone_data.fast_regen_hp : 180));
if (base < fast_regen) // weird, but what the client is doing if (base < fast_regen) // weird, but what the client is doing
base = fast_regen; base = fast_regen;
} }
@@ -506,50 +506,6 @@ int64 Client::CalcBaseHP()
return base_hp; return base_hp;
} }
// This is for calculating Base HPs + STA bonus for SoD or later clients.
uint64 Client::GetClassHPFactor()
{
int factor;
// Note: Base HP factor under level 41 is equal to factor / 12, and from level 41 to 80 is factor / 6.
// Base HP over level 80 is factor / 10
// HP per STA point per level is factor / 30 for level 80+
// HP per STA under level 40 is the level 80 HP Per STA / 120, and for over 40 it is / 60.
switch (GetClass()) {
case DRUID:
case ENCHANTER:
case NECROMANCER:
case MAGICIAN:
case WIZARD:
factor = 240;
break;
case BEASTLORD:
case BERSERKER:
case MONK:
case ROGUE:
case SHAMAN:
factor = 255;
break;
case BARD:
case CLERIC:
factor = 264;
break;
case SHADOWKNIGHT:
case PALADIN:
factor = 288;
break;
case RANGER:
factor = 276;
break;
case WARRIOR:
factor = 300;
break;
default:
factor = 240;
break;
}
return factor;
}
// This should return the combined AC of all the items the player is wearing. // This should return the combined AC of all the items the player is wearing.
int32 Client::GetRawItemAC() int32 Client::GetRawItemAC()
{ {
+3 -3
View File
@@ -783,8 +783,6 @@ void Client::SetEXP(uint64 set_exp, uint64 set_aaxp, bool isrezzexp) {
if (check_level == RuleI(Character, DeathExpLossLevel)) if (check_level == RuleI(Character, DeathExpLossLevel))
MessageString(Chat::Yellow, CORPSE_EXP_LOST); MessageString(Chat::Yellow, CORPSE_EXP_LOST);
} }
else
MessageString(Chat::Experience, LOSE_LEVEL, ConvertArray(check_level, val1));
uint8 myoldlevel = GetLevel(); uint8 myoldlevel = GetLevel();
@@ -1256,8 +1254,10 @@ uint8 Client::GetCharMaxLevelFromQGlobal() {
std::list<QGlobal> global_map; std::list<QGlobal> global_map;
const uint32 zone_id = zone ? zone->GetZoneID() : 0;
if (char_cache) { if (char_cache) {
QGlobalCache::Combine(global_map, char_cache->GetBucket(), 0, CharacterID(), zone->GetZoneID()); QGlobalCache::Combine(global_map, char_cache->GetBucket(), 0, CharacterID(), zone_id);
} }
for (const auto& global : global_map) { for (const auto& global : global_map) {
+6 -2
View File
@@ -361,11 +361,12 @@ void NPC::AddLootDrop(
SetArrowEquipped(true); SetArrowEquipped(true);
} }
bool found = false; // track if we found an empty slot we fit into
if (loot_drop.equip_item > 0) { if (loot_drop.equip_item > 0) {
uint8 eslot = 0xFF; uint8 eslot = 0xFF;
char newid[20]; char newid[20];
const EQ::ItemData* compitem = nullptr; const EQ::ItemData* compitem = nullptr;
bool found = false; // track if we found an empty slot we fit into
int32 foundslot = -1; // for multi-slot items int32 foundslot = -1; // for multi-slot items
// Equip rules are as follows: // Equip rules are as follows:
@@ -500,7 +501,6 @@ void NPC::AddLootDrop(
} }
if (found) { if (found) {
CalcBonuses(); // This is less than ideal for bulk adding of items
item->equip_slot = foundslot; item->equip_slot = foundslot;
} }
} }
@@ -510,6 +510,10 @@ void NPC::AddLootDrop(
} }
else safe_delete(item); else safe_delete(item);
if (found) {
CalcBonuses();
}
if (IsRecordLootStats()) { if (IsRecordLootStats()) {
m_rolled_items.emplace_back(item->item_id); m_rolled_items.emplace_back(item->item_id);
} }
+19 -1
View File
@@ -2875,6 +2875,16 @@ float Lua_Mob::GetDefaultRaceSize() {
return self->GetDefaultRaceSize(); return self->GetDefaultRaceSize();
} }
float Lua_Mob::GetDefaultRaceSize(int race_id) {
Lua_Safe_Call_Real();
return self->GetDefaultRaceSize(race_id);
}
float Lua_Mob::GetDefaultRaceSize(int race_id, int gender_id) {
Lua_Safe_Call_Real();
return self->GetDefaultRaceSize(race_id, gender_id);
}
float Lua_Mob::GetActSpellRange(uint16 spell_id, float range) { float Lua_Mob::GetActSpellRange(uint16 spell_id, float range) {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetActSpellRange(spell_id, range); return self->GetActSpellRange(spell_id, range);
@@ -3000,6 +3010,11 @@ luabind::object Lua_Mob::GetBuffSpellIDs(lua_State* L) {
return t; return t;
} }
bool Lua_Mob::HasSpellEffect(int effect_id) {
Lua_Safe_Call_Bool();
return self->HasSpellEffect(effect_id);
}
luabind::scope lua_register_mob() { luabind::scope lua_register_mob() {
return luabind::class_<Lua_Mob, Lua_Entity>("Mob") return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
@@ -3212,7 +3227,9 @@ luabind::scope lua_register_mob() {
.def("GetDEX", &Lua_Mob::GetDEX) .def("GetDEX", &Lua_Mob::GetDEX)
.def("GetDR", &Lua_Mob::GetDR) .def("GetDR", &Lua_Mob::GetDR)
.def("GetDamageAmount", (uint32(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetDamageAmount) .def("GetDamageAmount", (uint32(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetDamageAmount)
.def("GetDefaultRaceSize", &Lua_Mob::GetDefaultRaceSize) .def("GetDefaultRaceSize", (float(Lua_Mob::*)(void))&Lua_Mob::GetDefaultRaceSize)
.def("GetDefaultRaceSize", (float(Lua_Mob::*)(int))&Lua_Mob::GetDefaultRaceSize)
.def("GetDefaultRaceSize", (float(Lua_Mob::*)(int,int))&Lua_Mob::GetDefaultRaceSize)
.def("GetDeity", &Lua_Mob::GetDeity) .def("GetDeity", &Lua_Mob::GetDeity)
.def("GetDisplayAC", &Lua_Mob::GetDisplayAC) .def("GetDisplayAC", &Lua_Mob::GetDisplayAC)
.def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails) .def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails)
@@ -3338,6 +3355,7 @@ luabind::scope lua_register_mob() {
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet) .def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
.def("HasProcs", &Lua_Mob::HasProcs) .def("HasProcs", &Lua_Mob::HasProcs)
.def("HasShieldEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquipped) .def("HasShieldEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquipped)
.def("HasSpellEffect", &Lua_Mob::HasSpellEffect)
.def("HasTimer", &Lua_Mob::HasTimer) .def("HasTimer", &Lua_Mob::HasTimer)
.def("HasTwoHandBluntEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquipped) .def("HasTwoHandBluntEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquipped)
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped) .def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
+3
View File
@@ -516,6 +516,8 @@ public:
bool IsFindable(); bool IsFindable();
bool IsTrackable(); bool IsTrackable();
float GetDefaultRaceSize(); float GetDefaultRaceSize();
float GetDefaultRaceSize(int race_id);
float GetDefaultRaceSize(int race_id, int gender_id);
int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target); int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target);
int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target, bool from_buff_tic); int64 GetActDoTDamage(uint16 spell_id, int64 value, Lua_Mob target, bool from_buff_tic);
int64 GetActReflectedSpellDamage(uint16 spell_id, int64 value, int effectiveness); int64 GetActReflectedSpellDamage(uint16 spell_id, int64 value, int effectiveness);
@@ -539,6 +541,7 @@ public:
void StopAllTimers(); void StopAllTimers();
void StopTimer(const char* timer_name); void StopTimer(const char* timer_name);
luabind::object GetBuffSpellIDs(lua_State* L); luabind::object GetBuffSpellIDs(lua_State* L);
bool HasSpellEffect(int effect_id);
}; };
#endif #endif
+1 -1
View File
@@ -4302,7 +4302,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
const NPCType* npc_type_to_copy = nullptr; const NPCType* npc_type_to_copy = nullptr;
if (c) { if (c) {
const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel()); npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
} }
if(npc_type_to_copy != nullptr) if(npc_type_to_copy != nullptr)
-1
View File
@@ -307,7 +307,6 @@ private:
int32 CalcCorrup(); int32 CalcCorrup();
int64 CalcMaxHP(); int64 CalcMaxHP();
int64 CalcBaseHP(); int64 CalcBaseHP();
int64 GetClassHPFactor();
int64 CalcHPRegen(); int64 CalcHPRegen();
int64 CalcHPRegenCap(); int64 CalcHPRegenCap();
int64 CalcMaxMana(); int64 CalcMaxMana();
+13 -10
View File
@@ -6227,20 +6227,20 @@ FACTION_VALUE Mob::GetSpecialFactionCon(Mob* iOther) {
bool Mob::HasSpellEffect(int effect_id) bool Mob::HasSpellEffect(int effect_id)
{ {
int i; const auto buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; i++) {
const auto spell_id = buffs[i].spellid;
int buff_count = GetMaxTotalSlots(); if (!IsValidSpell(spell_id)) {
for(i = 0; i < buff_count; i++)
{
if (!IsValidSpell(buffs[i].spellid)) {
continue; continue;
} }
if (IsEffectInSpell(buffs[i].spellid, effect_id)) { if (IsEffectInSpell(spell_id, effect_id)) {
return(1); return true;
} }
} }
return(0);
return false;
} }
int Mob::GetSpecialAbility(int ability) int Mob::GetSpecialAbility(int ability)
@@ -6724,8 +6724,11 @@ void Mob::CommonBreakInvisible()
CancelSneakHide(); CancelSneakHide();
} }
float Mob::GetDefaultRaceSize() const { float Mob::GetDefaultRaceSize(int race_id, int gender_id) const {
return GetRaceGenderDefaultHeight(race, gender); return GetRaceGenderDefaultHeight(
race_id > 0 ? race_id : race,
gender_id >= 0 ? gender_id : gender
);
} }
bool Mob::ShieldAbility(uint32 target_id, int shielder_max_distance, int shield_duration, int shield_target_mitigation, int shielder_mitigation, bool use_aa, bool can_shield_npc) bool Mob::ShieldAbility(uint32 target_id, int shielder_max_distance, int shield_duration, int shield_target_mitigation, int shielder_mitigation, bool use_aa, bool can_shield_npc)
+1 -1
View File
@@ -1205,7 +1205,7 @@ public:
void SendTo(float new_x, float new_y, float new_z); void SendTo(float new_x, float new_y, float new_z);
void SendToFixZ(float new_x, float new_y, float new_z); void SendToFixZ(float new_x, float new_y, float new_z);
float GetZOffset() const; float GetZOffset() const;
float GetDefaultRaceSize() const; float GetDefaultRaceSize(int race_id = -1, int gender_id = -1) const;
void FixZ(int32 z_find_offset = 5, bool fix_client_z = false); void FixZ(int32 z_find_offset = 5, bool fix_client_z = false);
float GetFixedZ(const glm::vec3 &destination, int32 z_find_offset = 5); float GetFixedZ(const glm::vec3 &destination, int32 z_find_offset = 5);
virtual int GetStuckBehavior() const { return 0; } virtual int GetStuckBehavior() const { return 0; }
-1
View File
@@ -584,7 +584,6 @@ protected:
uint32 npc_spells_id; uint32 npc_spells_id;
uint8 casting_spell_AIindex; uint8 casting_spell_AIindex;
uint32* pDontCastBefore_casting_spell;
std::vector<AISpells_Struct> AIspells; std::vector<AISpells_Struct> AIspells;
bool HasAISpell; bool HasAISpell;
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates = false); virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes, bool bInnates = false);
+2 -2
View File
@@ -7,9 +7,9 @@
class OrientedBoundingBox class OrientedBoundingBox
{ {
public: public:
OrientedBoundingBox() { } OrientedBoundingBox() = default;
OrientedBoundingBox(const glm::vec3 &pos, const glm::vec3 &rot, const glm::vec3 &scale, const glm::vec3 &extents); OrientedBoundingBox(const glm::vec3 &pos, const glm::vec3 &rot, const glm::vec3 &scale, const glm::vec3 &extents);
~OrientedBoundingBox() { } ~OrientedBoundingBox() = default;
bool ContainsPoint(const glm::vec3 &p) const; bool ContainsPoint(const glm::vec3 &p) const;
private: private:
+19 -1
View File
@@ -2887,6 +2887,16 @@ float Perl_Mob_GetDefaultRaceSize(Mob* self) // @categories Script Utility
return self->GetDefaultRaceSize(); return self->GetDefaultRaceSize();
} }
float Perl_Mob_GetDefaultRaceSize(Mob* self, int race_id) // @categories Script Utility
{
return self->GetDefaultRaceSize(race_id);
}
float Perl_Mob_GetDefaultRaceSize(Mob* self, int race_id, int gender_id) // @categories Script Utility
{
return self->GetDefaultRaceSize(race_id, gender_id);
}
uint32 Perl_Mob_GetRemainingTimeMS(Mob* self, const char* timer_name) uint32 Perl_Mob_GetRemainingTimeMS(Mob* self, const char* timer_name)
{ {
return quest_manager.getremainingtimeMS(timer_name, self); return quest_manager.getremainingtimeMS(timer_name, self);
@@ -2950,6 +2960,11 @@ perl::array Perl_Mob_GetBuffSpellIDs(Mob* self)
return l; return l;
} }
bool Perl_Mob_HasSpellEffect(Mob* self, int effect_id)
{
return self->HasSpellEffect(effect_id);
}
void perl_register_mob() void perl_register_mob()
{ {
perl::interpreter perl(PERL_GET_THX); perl::interpreter perl(PERL_GET_THX);
@@ -3141,7 +3156,9 @@ void perl_register_mob()
package.add("GetClassName", &Perl_Mob_GetClassName); package.add("GetClassName", &Perl_Mob_GetClassName);
package.add("GetCleanName", &Perl_Mob_GetCleanName); package.add("GetCleanName", &Perl_Mob_GetCleanName);
package.add("GetCorruption", &Perl_Mob_GetCorruption); package.add("GetCorruption", &Perl_Mob_GetCorruption);
package.add("GetDefaultRaceSize", &Perl_Mob_GetDefaultRaceSize); package.add("GetDefaultRaceSize", (float(*)(Mob*))&Perl_Mob_GetDefaultRaceSize);
package.add("GetDefaultRaceSize", (float(*)(Mob*, int))&Perl_Mob_GetDefaultRaceSize);
package.add("GetDefaultRaceSize", (float(*)(Mob*, int, int))&Perl_Mob_GetDefaultRaceSize);
package.add("GetDEX", &Perl_Mob_GetDEX); package.add("GetDEX", &Perl_Mob_GetDEX);
package.add("GetDR", &Perl_Mob_GetDR); package.add("GetDR", &Perl_Mob_GetDR);
package.add("GetDamageAmount", &Perl_Mob_GetDamageAmount); package.add("GetDamageAmount", &Perl_Mob_GetDamageAmount);
@@ -3272,6 +3289,7 @@ void perl_register_mob()
package.add("HasPet", &Perl_Mob_HasPet); package.add("HasPet", &Perl_Mob_HasPet);
package.add("HasProcs", &Perl_Mob_HasProcs); package.add("HasProcs", &Perl_Mob_HasProcs);
package.add("HasShieldEquipped", &Perl_Mob_HasShieldEquipped); package.add("HasShieldEquipped", &Perl_Mob_HasShieldEquipped);
package.add("HasSpellEffect", &Perl_Mob_HasSpellEffect);
package.add("HasTimer", &Perl_Mob_HasTimer); package.add("HasTimer", &Perl_Mob_HasTimer);
package.add("HasTwoHandBluntEquipped", &Perl_Mob_HasTwoHandBluntEquipped); package.add("HasTwoHandBluntEquipped", &Perl_Mob_HasTwoHandBluntEquipped);
package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped); package.add("HasTwoHanderEquipped", &Perl_Mob_HasTwoHanderEquipped);
-97
View File
@@ -75,103 +75,6 @@ void GetRandPetName(char *name)
strn0cpy(name, temp.c_str(), 64); strn0cpy(name, temp.c_str(), 64);
} }
//not used anymore
/*int CalcPetHp(int levelb, int classb, int STA)
{
int multiplier = 0;
int base_hp = 0;
switch(classb) {
case WARRIOR:{
if (levelb < 20)
multiplier = 22;
else if (levelb < 30)
multiplier = 23;
else if (levelb < 40)
multiplier = 25;
else if (levelb < 53)
multiplier = 27;
else if (levelb < 57)
multiplier = 28;
else
multiplier = 30;
break;
}
case DRUID:
case CLERIC:
case SHAMAN:{
multiplier = 15;
break;
}
case PALADIN:
case SHADOWKNIGHT:{
if (levelb < 35)
multiplier = 21;
else if (levelb < 45)
multiplier = 22;
else if (levelb < 51)
multiplier = 23;
else if (levelb < 56)
multiplier = 24;
else if (levelb < 60)
multiplier = 25;
else
multiplier = 26;
break;
}
case MONK:
case BARD:
case ROGUE:
case BEASTLORD:{
if (levelb < 51)
multiplier = 18;
else if (levelb < 58)
multiplier = 19;
else
multiplier = 20;
break;
}
case RANGER:{
if (levelb < 58)
multiplier = 20;
else
multiplier = 21;
break;
}
case MAGICIAN:
case WIZARD:
case NECROMANCER:
case ENCHANTER:{
multiplier = 12;
break;
}
default:{
if (levelb < 35)
multiplier = 21;
else if (levelb < 45)
multiplier = 22;
else if (levelb < 51)
multiplier = 23;
else if (levelb < 56)
multiplier = 24;
else if (levelb < 60)
multiplier = 25;
else
multiplier = 26;
break;
}
}
if (multiplier == 0)
{
LogFile->write(EQEMuLog::Error, "Multiplier == 0 in CalcPetHp,using Generic....");;
multiplier=12;
}
base_hp = 5 + (multiplier*levelb) + ((multiplier*levelb*STA) + 1)/300;
return base_hp;
}
*/
void Mob::MakePet(uint16 spell_id, const char* pettype, const char *petname) { void Mob::MakePet(uint16 spell_id, const char* pettype, const char *petname) {
// petpower of -1 is used to get the petpower based on whichever focus is currently // petpower of -1 is used to get the petpower based on whichever focus is currently
// equipped. This should replicate the old functionality for the most part. // equipped. This should replicate the old functionality for the most part.
+367 -162
View File
@@ -17,6 +17,7 @@
*/ */
#include "../common/classes.h" #include "../common/classes.h"
#include "../common/data_verification.h"
#include "../common/global_define.h" #include "../common/global_define.h"
#include "../common/rulesys.h" #include "../common/rulesys.h"
#include "../common/skills.h" #include "../common/skills.h"
@@ -405,13 +406,28 @@ void QuestManager::selfcast(int spell_id) {
initiator->SpellFinished(spell_id, initiator, EQ::spells::CastingSlot::Item, 0, -1, spells[spell_id].resist_difficulty); initiator->SpellFinished(spell_id, initiator, EQ::spells::CastingSlot::Item, 0, -1, spells[spell_id].resist_difficulty);
} }
void QuestManager::addloot(int item_id, int charges, bool equipitem, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) { void QuestManager::addloot(
int item_id,
int charges,
bool equipitem,
int aug1,
int aug2,
int aug3,
int aug4,
int aug5,
int aug6
) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
if (item_id != 0) { if (item_id != 0) {
if(owner->IsNPC()) if (owner->IsNPC()) {
owner->CastToNPC()->AddItem(item_id, charges, equipitem, aug1, aug2, aug3, aug4, aug5, aug6); owner->CastToNPC()->AddItem(item_id, charges, equipitem, aug1, aug2, aug3, aug4, aug5, aug6);
} }
} }
}
void QuestManager::Zone(const char *zone_name) { void QuestManager::Zone(const char *zone_name) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
@@ -611,6 +627,10 @@ void QuestManager::stopalltimers(Mob *mob) {
void QuestManager::pausetimer(const char* timer_name, Mob* mob) { void QuestManager::pausetimer(const char* timer_name, Mob* mob) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!mob && !owner) {
return;
}
std::list<QuestTimer>::iterator cur = QTimerList.begin(), end; std::list<QuestTimer>::iterator cur = QTimerList.begin(), end;
std::list<PausedTimer>::iterator pcur = PTimerList.begin(), pend; std::list<PausedTimer>::iterator pcur = PTimerList.begin(), pend;
PausedTimer pt; PausedTimer pt;
@@ -648,6 +668,10 @@ void QuestManager::pausetimer(const char* timer_name, Mob* mob) {
void QuestManager::resumetimer(const char* timer_name, Mob* mob) { void QuestManager::resumetimer(const char* timer_name, Mob* mob) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!mob && !owner) {
return;
}
std::list<QuestTimer>::iterator cur = QTimerList.begin(), end; std::list<QuestTimer>::iterator cur = QTimerList.begin(), end;
std::list<PausedTimer>::iterator pcur = PTimerList.begin(), pend; std::list<PausedTimer>::iterator pcur = PTimerList.begin(), pend;
PausedTimer pt; PausedTimer pt;
@@ -1133,7 +1157,11 @@ void QuestManager::surname(std::string last_name) {
void QuestManager::permaclass(int class_id) { void QuestManager::permaclass(int class_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
//Makes the client the class specified
if (!initiator) {
return;
}
initiator->SetBaseClass(class_id); initiator->SetBaseClass(class_id);
initiator->Save(2); initiator->Save(2);
initiator->Kick("Base class change by QuestManager"); initiator->Kick("Base class change by QuestManager");
@@ -1141,7 +1169,11 @@ void QuestManager::permaclass(int class_id) {
void QuestManager::permarace(int race_id) { void QuestManager::permarace(int race_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
//Makes the client the race specified
if (!initiator) {
return;
}
initiator->SetBaseRace(race_id); initiator->SetBaseRace(race_id);
initiator->Save(2); initiator->Save(2);
initiator->Kick("Base race change by QuestManager"); initiator->Kick("Base race change by QuestManager");
@@ -1149,7 +1181,11 @@ void QuestManager::permarace(int race_id) {
void QuestManager::permagender(int gender_id) { void QuestManager::permagender(int gender_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
//Makes the client the gender specified
if (!initiator) {
return;
}
initiator->SetBaseGender(gender_id); initiator->SetBaseGender(gender_id);
initiator->Save(2); initiator->Save(2);
initiator->Kick("Base gender change by QuestManager"); initiator->Kick("Base gender change by QuestManager");
@@ -1157,21 +1193,41 @@ void QuestManager::permagender(int gender_id) {
uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return 0;
}
return initiator->ScribeSpells(min_level, max_level); return initiator->ScribeSpells(min_level, max_level);
} }
uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return 0;
}
return initiator->LearnDisciplines(min_level, max_level); return initiator->LearnDisciplines(min_level, max_level);
} }
void QuestManager::unscribespells() { void QuestManager::unscribespells() {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->UnscribeSpellAll(); initiator->UnscribeSpellAll();
} }
void QuestManager::untraindiscs() { void QuestManager::untraindiscs() {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->UntrainDiscAll(); initiator->UntrainDiscAll();
} }
@@ -1179,7 +1235,6 @@ void QuestManager::givecash(uint32 copper, uint32 silver, uint32 gold, uint32 pl
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if ( if (
initiator && initiator &&
initiator->IsClient() &&
( (
copper || copper ||
silver || silver ||
@@ -1198,90 +1253,113 @@ void QuestManager::givecash(uint32 copper, uint32 silver, uint32 gold, uint32 pl
void QuestManager::pvp(const char *mode) { void QuestManager::pvp(const char *mode) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!strcasecmp(mode,"on"))
{ if (!initiator) {
if (initiator) return;
initiator->SetPVP(true);
} }
else
if (initiator) initiator->SetPVP(Strings::ToBool(mode));
initiator->SetPVP(false);
} }
void QuestManager::movepc(int zone_id, float x, float y, float z, float heading) { void QuestManager::movepc(int zone_id, float x, float y, float z, float heading) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (initiator)
if (!initiator) {
return;
}
initiator->MovePC(zone_id, x, y, z, heading); initiator->MovePC(zone_id, x, y, z, heading);
} }
void QuestManager::gmmove(float x, float y, float z) { void QuestManager::gmmove(float x, float y, float z) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (initiator)
if (!initiator) {
return;
}
initiator->GMMove(x, y, z); initiator->GMMove(x, y, z);
} }
void QuestManager::movegrp(int zoneid, float x, float y, float z) { void QuestManager::movegrp(int zoneid, float x, float y, float z) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (initiator)
{ if (!initiator) {
Group *g = entity_list.GetGroupByClient(initiator); return;
if (g != nullptr) { }
if (Group *g = entity_list.GetGroupByClient(initiator)) {
g->TeleportGroup(owner, zoneid, 0, x, y, z, 0.0f); g->TeleportGroup(owner, zoneid, 0, x, y, z, 0.0f);
} } else {
else { if (Raid *r = entity_list.GetRaidByClient(initiator)) {
Raid *r = entity_list.GetRaidByClient(initiator); const auto group_id = r->GetGroup(initiator);
if (r != nullptr) { if (EQ::ValueWithin(group_id, 0, MAX_RAID_GROUPS)) {
uint32 gid = r->GetGroup(initiator); r->TeleportGroup(owner, zoneid, 0, x, y, z, 0.0f, group_id);
if (gid >= 0 && gid < 12) { } else {
r->TeleportGroup(owner, zoneid, 0, x, y, z, 0.0f, gid);
}
else {
initiator->MovePC(zoneid, x, y, z, 0.0f); initiator->MovePC(zoneid, x, y, z, 0.0f);
} }
} } else {
else {
initiator->MovePC(zoneid, x, y, z, 0.0f); initiator->MovePC(zoneid, x, y, z, 0.0f);
} }
} }
} }
}
void QuestManager::doanim(int animation_id, int animation_speed, bool ackreq, eqFilterType filter) { void QuestManager::doanim(int animation_id, int animation_speed, bool ackreq, eqFilterType filter) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
owner->DoAnim(animation_id, animation_speed, ackreq, filter); owner->DoAnim(animation_id, animation_speed, ackreq, filter);
} }
void QuestManager::addskill(int skill_id, int value) { void QuestManager::addskill(int skill_id, int value) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (skill_id < 0 || skill_id > EQ::skills::HIGHEST_SKILL)
if (!initiator) {
return; return;
if (initiator) }
if (!EQ::ValueWithin(skill_id, EQ::skills::Skill1HBlunt, EQ::skills::HIGHEST_SKILL)) {
return;
}
initiator->AddSkill((EQ::skills::SkillType) skill_id, value); initiator->AddSkill((EQ::skills::SkillType) skill_id, value);
} }
void QuestManager::setlanguage(int skill_id, int value) { void QuestManager::setlanguage(int skill_id, int value) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (initiator)
if (!initiator) {
return;
}
initiator->SetLanguageSkill(skill_id, value); initiator->SetLanguageSkill(skill_id, value);
} }
void QuestManager::setskill(int skill_id, int value) { void QuestManager::setskill(int skill_id, int value) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (skill_id < 0 || skill_id > EQ::skills::HIGHEST_SKILL)
if (!initiator) {
return; return;
if (initiator) }
if (!EQ::ValueWithin(skill_id, EQ::skills::Skill1HBlunt, EQ::skills::HIGHEST_SKILL)) {
return;
}
initiator->SetSkill((EQ::skills::SkillType) skill_id, value); initiator->SetSkill((EQ::skills::SkillType) skill_id, value);
} }
void QuestManager::setallskill(int value) { void QuestManager::setallskill(int value) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) if (!initiator) {
return; return;
if (initiator) {
EQ::skills::SkillType sk;
for (sk = EQ::skills::Skill1HBlunt; sk <= EQ::skills::HIGHEST_SKILL; sk = (EQ::skills::SkillType)(sk + 1)) {
initiator->SetSkill(sk, value);
} }
for (const auto& s : EQ::skills::GetSkillTypeMap()) {
initiator->SetSkill(s.first, value);
} }
} }
@@ -1957,21 +2035,41 @@ void QuestManager::toggle_spawn_event(int event_id, bool enable, bool strict, bo
bool QuestManager::has_zone_flag(int zone_id) { bool QuestManager::has_zone_flag(int zone_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
return initiator ? initiator->HasZoneFlag(zone_id) : false;
if (!initiator) {
return false;
}
return initiator->HasZoneFlag(zone_id);
} }
void QuestManager::set_zone_flag(int zone_id) { void QuestManager::set_zone_flag(int zone_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->SetZoneFlag(zone_id); initiator->SetZoneFlag(zone_id);
} }
void QuestManager::clear_zone_flag(int zone_id) { void QuestManager::clear_zone_flag(int zone_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->ClearZoneFlag(zone_id); initiator->ClearZoneFlag(zone_id);
} }
void QuestManager::sethp(int64 hpperc) { void QuestManager::sethp(int64 hpperc) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
int64 newhp = (owner->GetMaxHP() * (100 - hpperc)) / 100; int64 newhp = (owner->GetMaxHP() * (100 - hpperc)) / 100;
owner->Damage(owner, newhp, SPELL_UNKNOWN, EQ::skills::SkillHandtoHand, false, 0, false); owner->Damage(owner, newhp, SPELL_UNKNOWN, EQ::skills::SkillHandtoHand, false, 0, false);
} }
@@ -2088,55 +2186,103 @@ bool QuestManager::isdooropen(uint32 doorid) {
} }
return false; return false;
} }
void QuestManager::npcrace(int race_id) void QuestManager::npcrace(int race_id)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
owner->SendIllusionPacket(race_id); owner->SendIllusionPacket(race_id);
} }
void QuestManager::npcgender(int gender_id) void QuestManager::npcgender(int gender_id)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
owner->SendIllusionPacket(owner->GetRace(), gender_id); owner->SendIllusionPacket(owner->GetRace(), gender_id);
} }
void QuestManager::npcsize(int newsize) void QuestManager::npcsize(int newsize)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
owner->ChangeSize(newsize, true); owner->ChangeSize(newsize, true);
} }
void QuestManager::npctexture(int newtexture) void QuestManager::npctexture(int newtexture)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
owner->SendIllusionPacket(owner->GetRace(), 0xFF, newtexture); owner->SendIllusionPacket(owner->GetRace(), 0xFF, newtexture);
} }
void QuestManager::playerrace(int race_id) void QuestManager::playerrace(int race_id)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->SendIllusionPacket(race_id); initiator->SendIllusionPacket(race_id);
} }
void QuestManager::playergender(int gender_id) void QuestManager::playergender(int gender_id)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->SendIllusionPacket(initiator->GetRace(), gender_id); initiator->SendIllusionPacket(initiator->GetRace(), gender_id);
} }
void QuestManager::playersize(int newsize) void QuestManager::playersize(int newsize)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->ChangeSize(newsize, true); initiator->ChangeSize(newsize, true);
} }
void QuestManager::playertexture(int newtexture) void QuestManager::playertexture(int newtexture)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture); initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture);
} }
void QuestManager::playerfeature(const char* feature, int setting) void QuestManager::playerfeature(const char* feature, int setting)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
uint16 Race = initiator->GetRace(); uint16 Race = initiator->GetRace();
uint8 Gender = initiator->GetGender(); uint8 Gender = initiator->GetGender();
uint8 Texture = 0xFF; uint8 Texture = 0xFF;
@@ -2153,47 +2299,68 @@ void QuestManager::playerfeature(const char* feature, int setting)
uint32 DrakkinDetails = initiator->GetDrakkinDetails(); uint32 DrakkinDetails = initiator->GetDrakkinDetails();
float Size = initiator->GetSize(); float Size = initiator->GetSize();
if (!strcasecmp(feature,"race")) if (!strcasecmp(feature, "race")) {
Race = setting; Race = setting;
else if (!strcasecmp(feature,"gender")) } else if (!strcasecmp(feature, "gender")) {
Gender = setting; Gender = setting;
else if (!strcasecmp(feature,"texture")) } else if (!strcasecmp(feature, "texture")) {
Texture = setting; Texture = setting;
else if (!strcasecmp(feature,"helm")) } else if (!strcasecmp(feature, "helm")) {
HelmTexture = setting; HelmTexture = setting;
else if (!strcasecmp(feature,"haircolor")) } else if (!strcasecmp(feature, "haircolor")) {
HairColor = setting; HairColor = setting;
else if (!strcasecmp(feature,"beardcolor")) } else if (!strcasecmp(feature, "beardcolor")) {
BeardColor = setting; BeardColor = setting;
else if (!strcasecmp(feature,"eyecolor1")) } else if (!strcasecmp(feature, "eyecolor1")) {
EyeColor1 = setting; EyeColor1 = setting;
else if (!strcasecmp(feature,"eyecolor2")) } else if (!strcasecmp(feature, "eyecolor2")) {
EyeColor2 = setting; EyeColor2 = setting;
else if (!strcasecmp(feature,"hair")) } else if (!strcasecmp(feature, "hair")) {
HairStyle = setting; HairStyle = setting;
else if (!strcasecmp(feature,"face")) } else if (!strcasecmp(feature, "face")) {
LuclinFace = setting; LuclinFace = setting;
else if (!strcasecmp(feature,"beard")) } else if (!strcasecmp(feature, "beard")) {
Beard = setting; Beard = setting;
else if (!strcasecmp(feature,"heritage")) } else if (!strcasecmp(feature, "heritage")) {
DrakkinHeritage = setting; DrakkinHeritage = setting;
else if (!strcasecmp(feature,"tattoo")) } else if (!strcasecmp(feature, "tattoo")) {
DrakkinTattoo = setting; DrakkinTattoo = setting;
else if (!strcasecmp(feature,"details")) } else if (!strcasecmp(feature, "details")) {
DrakkinDetails = setting; DrakkinDetails = setting;
else if (!strcasecmp(feature,"size")) } else if (!strcasecmp(feature, "size")) {
Size = (float) setting / 10; //dividing by 10 to allow 1 decimal place for adjusting size Size = (float) setting / 10; //dividing by 10 to allow 1 decimal place for adjusting size
else } else {
return; return;
}
initiator->SendIllusionPacket(Race, Gender, Texture, HelmTexture, HairColor, BeardColor, initiator->SendIllusionPacket(
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, Race,
DrakkinHeritage, DrakkinTattoo, DrakkinDetails, Size); Gender,
Texture,
HelmTexture,
HairColor,
BeardColor,
EyeColor1,
EyeColor2,
HairStyle,
LuclinFace,
Beard,
0xFF,
DrakkinHeritage,
DrakkinTattoo,
DrakkinDetails,
Size
);
} }
void QuestManager::npcfeature(const char* feature, int setting) void QuestManager::npcfeature(const char* feature, int setting)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner) {
return;
}
uint16 Race = owner->GetRace(); uint16 Race = owner->GetRace();
uint8 Gender = owner->GetGender(); uint8 Gender = owner->GetGender();
uint8 Texture = owner->GetTexture(); uint8 Texture = owner->GetTexture();
@@ -2210,48 +2377,68 @@ void QuestManager::npcfeature(const char* feature, int setting)
uint32 DrakkinDetails = owner->GetDrakkinDetails(); uint32 DrakkinDetails = owner->GetDrakkinDetails();
float Size = owner->GetSize(); float Size = owner->GetSize();
if (!strcasecmp(feature,"race")) if (!strcasecmp(feature, "race")) {
Race = setting; Race = setting;
else if (!strcasecmp(feature,"gender")) } else if (!strcasecmp(feature, "gender")) {
Gender = setting; Gender = setting;
else if (!strcasecmp(feature,"texture")) } else if (!strcasecmp(feature, "texture")) {
Texture = setting; Texture = setting;
else if (!strcasecmp(feature,"helm")) } else if (!strcasecmp(feature, "helm")) {
HelmTexture = setting; HelmTexture = setting;
else if (!strcasecmp(feature,"haircolor")) } else if (!strcasecmp(feature, "haircolor")) {
HairColor = setting; HairColor = setting;
else if (!strcasecmp(feature,"beardcolor")) } else if (!strcasecmp(feature, "beardcolor")) {
BeardColor = setting; BeardColor = setting;
else if (!strcasecmp(feature,"eyecolor1")) } else if (!strcasecmp(feature, "eyecolor1")) {
EyeColor1 = setting; EyeColor1 = setting;
else if (!strcasecmp(feature,"eyecolor2")) } else if (!strcasecmp(feature, "eyecolor2")) {
EyeColor2 = setting; EyeColor2 = setting;
else if (!strcasecmp(feature,"hair")) } else if (!strcasecmp(feature, "hair")) {
HairStyle = setting; HairStyle = setting;
else if (!strcasecmp(feature,"face")) } else if (!strcasecmp(feature, "face")) {
LuclinFace = setting; LuclinFace = setting;
else if (!strcasecmp(feature,"beard")) } else if (!strcasecmp(feature, "beard")) {
Beard = setting; Beard = setting;
else if (!strcasecmp(feature,"heritage")) } else if (!strcasecmp(feature, "heritage")) {
DrakkinHeritage = setting; DrakkinHeritage = setting;
else if (!strcasecmp(feature,"tattoo")) } else if (!strcasecmp(feature, "tattoo")) {
DrakkinTattoo = setting; DrakkinTattoo = setting;
else if (!strcasecmp(feature,"details")) } else if (!strcasecmp(feature, "details")) {
DrakkinDetails = setting; DrakkinDetails = setting;
else if (!strcasecmp(feature,"size")) } else if (!strcasecmp(feature, "size")) {
Size = (float) setting / 10; //dividing by 10 to allow 1 decimal place for adjusting size Size = (float) setting / 10; //dividing by 10 to allow 1 decimal place for adjusting size
else } else {
return; return;
}
owner->SendIllusionPacket(Race, Gender, Texture, HelmTexture, HairColor, BeardColor, owner->SendIllusionPacket(
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, Race,
DrakkinHeritage, DrakkinTattoo, DrakkinDetails, Size); Gender,
Texture,
HelmTexture,
HairColor,
BeardColor,
EyeColor1,
EyeColor2,
HairStyle,
LuclinFace,
Beard,
0xFF,
DrakkinHeritage,
DrakkinTattoo,
DrakkinDetails,
Size
);
} }
void QuestManager::popup(const char *title, const char *text, uint32 popupid, uint32 buttons, uint32 Duration) void QuestManager::popup(const char *title, const char *text, uint32 popupid, uint32 buttons, uint32 Duration)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if(initiator)
if (!initiator) {
return;
}
initiator->SendPopupToClient(title, text, popupid, buttons, Duration); initiator->SendPopupToClient(title, text, popupid, buttons, Duration);
} }
@@ -2407,7 +2594,6 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level
Bot* new_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender), initiator); Bot* new_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender), initiator);
if (new_bot) {
if (!new_bot->IsValidRaceClassCombo()) { if (!new_bot->IsValidRaceClassCombo()) {
initiator->Message(Chat::White, "That Race/Class combination cannot be created."); initiator->Message(Chat::White, "That Race/Class combination cannot be created.");
return false; return false;
@@ -2459,7 +2645,6 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level
return true; return true;
} }
} }
}
return false; return false;
} }
@@ -2730,48 +2915,41 @@ void QuestManager::whisper(const char *message) {
int QuestManager::getlevel(uint8 type) int QuestManager::getlevel(uint8 type)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (type == 0)
{ if (!initiator) {
return (initiator->GetLevel());
}
else if(type == 1)
{
Group *g = entity_list.GetGroupByClient(initiator);
if (g != nullptr)
return (g->GetAvgLevel());
else
return 0; return 0;
} }
else if(type == 2)
{ if (type == 0) {
Raid *r = entity_list.GetRaidByClient(initiator); return initiator->GetLevel();
if (r != nullptr) } else if (type == 1) {
return (r->GetAvgLevel()); if (Group *g = entity_list.GetGroupByClient(initiator)) {
else return g->GetAvgLevel();
} else {
return 0; return 0;
} }
else if(type == 3) } else if (type == 2) {
{ if (Raid *r = entity_list.GetRaidByClient(initiator)) {
Raid *r = entity_list.GetRaidByClient(initiator); return r->GetAvgLevel();
if(r != nullptr) } else {
{
return (r->GetAvgLevel());
}
Group *g = entity_list.GetGroupByClient(initiator);
if(g != nullptr)
{
return (g->GetAvgLevel());
}
else
return (initiator->GetLevel());
}
else if(type == 4)
{
return (initiator->CastToClient()->GetLevel2());
}
else
return 0; return 0;
} }
} else if (type == 3) {
if (Raid *r = entity_list.GetRaidByClient(initiator)) {
return r->GetAvgLevel();
}
if (Group *g = entity_list.GetGroupByClient(initiator)) {
return g->GetAvgLevel();
} else {
return initiator->GetLevel();
}
} else if (type == 4) {
return initiator->CastToClient()->GetLevel2();
} else {
return 0;
}
}
uint16 QuestManager::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time) uint16 QuestManager::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
{ {
@@ -2795,38 +2973,35 @@ void QuestManager::ModifyNPCStat(std::string stat, std::string value)
} }
} }
int QuestManager::collectitems_processSlot(int16 slot_id, uint32 item_id, int QuestManager::collectitems_processSlot(
bool remove) int16 slot_id,
{ uint32 item_id,
bool remove
) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
EQ::ItemInstance *item = nullptr;
int quantity = 0;
item = initiator->GetInv().GetItem(slot_id); if (!initiator) {
return 0;
}
const auto item = initiator->GetInv().GetItem(slot_id);
// If we have found matching item, add quantity // If we have found matching item, add quantity
if (item && item->GetID() == item_id) if (item && item->GetID() == item_id) {
{
// If item is stackable, add its charges (quantity) // If item is stackable, add its charges (quantity)
if (item->IsStackable()) const auto quantity = item->IsStackable() ? item->GetCharges() : 1;
{
quantity = item->GetCharges();
}
else
{
quantity = 1;
}
// Remove item from inventory // Remove item from inventory
if (remove) if (remove) {
{
initiator->DeleteItemInInventory(slot_id, 0, true); initiator->DeleteItemInInventory(slot_id, 0, true);
} }
}
return quantity; return quantity;
} }
return 0;
}
// Returns number of item_id that exist in inventory // Returns number of item_id that exist in inventory
// If remove is true, items are removed as they are counted. // If remove is true, items are removed as they are counted.
int QuestManager::collectitems(uint32 item_id, bool remove) int QuestManager::collectitems(uint32 item_id, bool remove)
@@ -2834,13 +3009,11 @@ int QuestManager::collectitems(uint32 item_id, bool remove)
int quantity = 0; int quantity = 0;
int slot_id; int slot_id;
for (slot_id = EQ::invslot::GENERAL_BEGIN; slot_id <= EQ::invslot::GENERAL_END; ++slot_id) for (slot_id = EQ::invslot::GENERAL_BEGIN; slot_id <= EQ::invslot::GENERAL_END; ++slot_id) {
{
quantity += collectitems_processSlot(slot_id, item_id, remove); quantity += collectitems_processSlot(slot_id, item_id, remove);
} }
for (slot_id = EQ::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQ::invbag::GENERAL_BAGS_END; ++slot_id) for (slot_id = EQ::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQ::invbag::GENERAL_BAGS_END; ++slot_id) {
{
quantity += collectitems_processSlot(slot_id, item_id, remove); quantity += collectitems_processSlot(slot_id, item_id, remove);
} }
@@ -2849,11 +3022,21 @@ int QuestManager::collectitems(uint32 item_id, bool remove)
int QuestManager::countitem(uint32 item_id) { int QuestManager::countitem(uint32 item_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return 0;
}
return initiator->CountItem(item_id); return initiator->CountItem(item_id);
} }
void QuestManager::removeitem(uint32 item_id, uint32 quantity) { void QuestManager::removeitem(uint32 item_id, uint32 quantity) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->RemoveItem(item_id, quantity); initiator->RemoveItem(item_id, quantity);
} }
@@ -3299,8 +3482,16 @@ uint8 QuestManager::FactionValue()
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
FACTION_VALUE oldfac; FACTION_VALUE oldfac;
uint8 newfac = 0; uint8 newfac = 0;
if(initiator && owner->IsNPC()) { if (initiator && owner && owner->IsNPC()) {
oldfac = initiator->GetFactionLevel(initiator->GetID(), owner->GetID(), initiator->GetFactionRace(), initiator->GetClass(), initiator->GetDeity(), owner->GetPrimaryFaction(), owner); oldfac = initiator->GetFactionLevel(
initiator->GetID(),
owner->GetID(),
initiator->GetFactionRace(),
initiator->GetClass(),
initiator->GetDeity(),
owner->GetPrimaryFaction(),
owner
);
// now, reorder the faction to have it make sense (higher values are better) // now, reorder the faction to have it make sense (higher values are better)
switch (oldfac) { switch (oldfac) {
@@ -3339,62 +3530,76 @@ uint8 QuestManager::FactionValue()
void QuestManager::enabletitle(int titleset) { void QuestManager::enabletitle(int titleset) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->EnableTitle(titleset); initiator->EnableTitle(titleset);
} }
bool QuestManager::checktitle(int titleset) { bool QuestManager::checktitle(int titleset) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
return initiator ? initiator->CheckTitle(titleset) : false;
if (!initiator) {
return false;
}
return initiator->CheckTitle(titleset);
} }
void QuestManager::removetitle(int titleset) { void QuestManager::removetitle(int titleset) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!initiator) {
return;
}
initiator->RemoveTitle(titleset); initiator->RemoveTitle(titleset);
} }
void QuestManager::wearchange(uint8 slot, uint16 texture, uint32 hero_forge_model /*= 0*/, uint32 elite_material /*= 0*/) void QuestManager::wearchange(uint8 slot, uint16 texture, uint32 hero_forge_model /*= 0*/, uint32 elite_material /*= 0*/)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if(owner){
if (!owner) {
return;
}
owner->SendTextureWC(slot, texture, hero_forge_model, elite_material); owner->SendTextureWC(slot, texture, hero_forge_model, elite_material);
if (owner->IsNPC()) { if (owner->IsNPC()) {
owner->CastToNPC()->NPCSlotTexture(slot, texture); owner->CastToNPC()->NPCSlotTexture(slot, texture);
} }
} }
}
void QuestManager::voicetell(const char *str, int macronum, int racenum, int gendernum) void QuestManager::voicetell(const char *str, int macronum, int racenum, int gendernum)
{ {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if(owner && str)
{ if (!owner) {
return;
}
if (str) {
Client *c = entity_list.GetClientByName(str); Client *c = entity_list.GetClientByName(str);
if(c) if (c) {
{
auto outapp = new EQApplicationPacket(OP_VoiceMacroOut, sizeof(VoiceMacroOut_Struct)); auto outapp = new EQApplicationPacket(OP_VoiceMacroOut, sizeof(VoiceMacroOut_Struct));
auto* vmo = (VoiceMacroOut_Struct *) outapp->pBuffer;
VoiceMacroOut_Struct* vmo = (VoiceMacroOut_Struct*)outapp->pBuffer;
strn0cpy(vmo->From, owner->GetCleanName(), sizeof(vmo->From)); strn0cpy(vmo->From, owner->GetCleanName(), sizeof(vmo->From));
vmo->Type = 1; vmo->Type = 1;
vmo->Voice = (racenum * 2) + gendernum; vmo->Voice = (racenum * 2) + gendernum;
vmo->MacroNumber = macronum; vmo->MacroNumber = macronum;
c->QueuePacket(outapp); c->QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
} } else {
else
LogQuests("from [{}]. Client [{}] not found", owner->GetName(), str); LogQuests("from [{}]. Client [{}] not found", owner->GetName(), str);
} }
} }
}
void QuestManager::SendMail(const char *to, const char *from, const char *subject, const char *message) { void QuestManager::SendMail(const char *to, const char *from, const char *subject, const char *message) {
if(to == nullptr || from == nullptr || subject == nullptr || message == nullptr) { if (!to || !from || !subject || !message) {
return; return;
} }