diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..eb64e2f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +tab_width = 4 +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 80 diff --git a/.git_commit_template.txt b/.git_commit_template.txt new file mode 100644 index 0000000..708b551 --- /dev/null +++ b/.git_commit_template.txt @@ -0,0 +1,49 @@ +### TITLE +## Type(Scope/Subscope): Commit ultra short explanation +## |---- Write below the examples with a maximum of 50 characters ----| +## Example 1: fix(DB/SAI): Missing spell to NPC Hogger +## Example 2: fix(CORE/Raid): Phase 2 of Ragnaros +## Example 3: feat(CORE/Commands): New GM command to do something + + +### DESCRIPTION +## Explain why this change is being made, what does it fix etc... +## |---- Write below the examples with a maximum of 72 characters per lines ----| +## Example: Hogger (id: 492) was not charging player when being engaged. + + +## Provide links to any issue, commit, pull request or other resource +## Example 1: Closes issue #23 +## Example 2: Ported from other project's commit (link) +## Example 3: References taken from wowpedia / wowhead / wowwiki / https://wowgaming.altervista.org/aowow/ + + + +## ======================================================= +## EXTRA INFOS +## ======================================================= +## "Type" can be: +## feat (new feature) +## fix (bug fix) +## refactor (refactoring production code) +## style (formatting, missing semi colons, etc; no code change) +## docs (changes to documentation) +## test (adding or refactoring tests; no production code change) +## chore (updating bash scripts, git files etc; no production code change) +## -------------------- +## Remember to +## Capitalize the subject line +## Use the imperative mood in the subject line +## Do not end the subject line with a period +## Separate subject from body with a blank line +## Use the body to explain what and why rather than how +## Can use multiple lines with "-" for bullet points in body +## -------------------- +## More info here https://www.conventionalcommits.org/en/v1.0.0-beta.2/ +## ======================================================= +## "Scope" can be: +## CORE (core related, c++) +## DB (database related, sql) +## ======================================================= +## "Subscope" is optional and depends on the nature of the commit. +## ======================================================= diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7ef9001 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,105 @@ +## AUTO-DETECT +## Handle line endings automatically for files detected as +## text and leave all files detected as binary untouched. +## This will handle all files NOT defined below. +* text=auto eol=lf + +# Text +*.conf text +*.conf.dist text +*.cmake text + +## Scripts +*.sh text +*.fish text +*.lua text + +## SQL +*.sql text + +## C++ +*.c text +*.cc text +*.cxx text +*.cpp text +*.c++ text +*.hpp text +*.h text +*.h++ text +*.hh text + + +## For documentation + +# Documents +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +## DOCUMENTATION +*.markdown text +*.md text +*.mdwn text +*.mdown text +*.mkd text +*.mkdn text +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text + +## GRAPHICS +*.ai binary +*.bmp binary +*.eps binary +*.gif binary +*.ico binary +*.jng binary +*.jp2 binary +*.jpg binary +*.jpeg binary +*.jpx binary +*.jxr binary +*.pdf binary +*.png binary +*.psb binary +*.psd binary +*.svg text +*.svgz binary +*.tif binary +*.tiff binary +*.wbmp binary +*.webp binary + + +## ARCHIVES +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary + +## EXECUTABLES +*.exe binary +*.pyc binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..923a1b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +!.gitignore + +# +#Generic +# + +.directory +.mailmap +*.orig +*.rej +*.*~ +.hg/ +*.kdev* +.DS_Store +CMakeLists.txt.user +*.bak +*.diff +*.REMOTE.* +*.BACKUP.* +*.BASE.* +*.LOCAL.* + +# +# IDE & other softwares +# +/.settings/ +/.externalToolBuilders/* +# exclude in all levels +nbproject/ +.sync.ffs_db +*.kate-swp + +# +# Eclipse +# +*.pydevproject +.metadata +.gradle +tmp/ +*.tmp +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.project +.cproject diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c1538c7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,77 @@ +sudo: required +dist: xenial # (16.04) +# bionic (18.04) is not yet available in travis + +language: cpp + +cache: ccache + +addons: + apt: + update: true + +services: + - mysql + +git: + depth: 10 + +stages: + - prepare_cache + - run + +jobs: + include: + - stage: prepare_cache + env: TRAVIS_BUILD_ID="1" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh OFF + script: + - source ./apps/ci/ci-compile.sh + + - stage: run + env: TRAVIS_BUILD_ID="1" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh ON + - source ./apps/ci/ci-import-db.sh + script: + - source ./apps/ci/ci-compile.sh + - source ./apps/ci/ci-worldserver-dry-run.sh + + - stage: prepare_cache + env: TRAVIS_BUILD_ID="2" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh OFF + script: + - source ./apps/ci/ci-compile.sh + + - stage: run + env: TRAVIS_BUILD_ID="2" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh ON + script: + - source ./apps/ci/ci-compile.sh diff --git a/README.md b/README.md index 5b536bf..c41317d 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,21 @@ - ############################################################################################################# - - ____ __ ______ __ ____ __ - /\ _`\ /\ \__ __ /\__ _\/\ \ /\ _`\ /\ \__ - \ \,\L\_\ \ ,_\ __ __ __ /\_\ __ ___\/_/\ \/\ \ \___ __\ \ \L\ \ __ ____\ \ ,_\ - \/_\__ \\ \ \/ /\ \/\ \ /'_ `\/\ \ /'__`\ /' _ `\ \ \ \ \ \ _ `\ /'__`\ \ _ <' /'__`\ /',__\\ \ \/ - /\ \L\ \ \ \_\ \ \_\ \/\ \L\ \ \ \/\ \L\.\_/\ \/\ \ \ \ \ \ \ \ \ \/\ __/\ \ \L\ \/\ __//\__, `\\ \ \_ - \ `\____\ \__\\/`____ \ \____ \ \_\ \__/.\_\ \_\ \_\ \ \_\ \ \_\ \_\ \____\\ \____/\ \____\/\____/ \ \__\ - \/_____/\/__/ `/___/> \/___L\ \/_/\/__/\/_/\/_/\/_/ \/_/ \/_/\/_/\/____/ \/___/ \/____/\/___/ \/__/ - /\___/ /\____/ - \/__/ \_/__/ http://stygianthebest.github.io - - ############################################################################################################# - - Modules, Scripts, and other resources for use with AzerothCore and the World of Warcraft v3.3.5a game client - - ############################################################################################################# \ No newline at end of file +# ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) AzerothCore +## mod-money-for-kills +### This is a module for [AzerothCore](http://www.azerothcore.org) +- Latest build status with azerothcore: [![Build Status](https://travis-ci.org/azerothcore/mod-money-for-kills.svg?branch=master)](https://travis-ci.org/azerothcore/mod-money-for-kills) +#### Features: +- Money for Kills for Azerothcore + +### This module currently requires: +- AzerothCore v1.0.1+ + +### How to install +1. Simply place the module under the `modules` folder of your AzerothCore source folder. +2. Re-run cmake and launch a clean build of AzerothCore +3. Copy 'mod_moneyforkills.conf.dist' to 'mod_moneyforkills.conf' +4. Start Server login and enjoy + + +## Credits +* [stygiancore]( http://stygianthebest.github.io ): (Author of the module): + +* AzerothCore: [repository](https://github.com/azerothcore) - [website](http://azerothcore.org/) - [discord chat community](https://discord.gg/PaqQRkd) diff --git a/conf/mod_moneyforkills.conf.dist b/conf/mod_moneyforkills.conf.dist index 470bc61..8ca69b3 100644 --- a/conf/mod_moneyforkills.conf.dist +++ b/conf/mod_moneyforkills.conf.dist @@ -12,7 +12,7 @@ MFK.Enable = 1 # Announce the module when the player logs in? # Default: 1 -MFK.Announce = 1 +MFK.Announce = 0 # Enable announcements to notify the server of a world boss kill # Default 1 @@ -74,7 +74,7 @@ MFK.PVP.CorpseLootPercent = 5 # NOTE: There are many dungeon bosses per dungeon, so set accordingly! # NOTE: A value of 0 will disable the payment type -MFK.Bounty.Kill.Multiplier = 100 -MFK.PVP.Kill.Multiplier = 200 +MFK.Bounty.Kill.Multiplier = 10 +MFK.PVP.Kill.Multiplier = 20 MFK.Bounty.DungeonBoss.Multiplier = 25 -MFK.Bounty.WorldBoss.Multiplier = 200 \ No newline at end of file +MFK.Bounty.WorldBoss.Multiplier = 20 \ No newline at end of file diff --git a/setup_git_commit_template.sh b/setup_git_commit_template.sh new file mode 100644 index 0000000..7b52062 --- /dev/null +++ b/setup_git_commit_template.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +## Set a local git commit template +git config --local commit.template ".git_commit_template.txt" ; diff --git a/src/mod_moneyforkills.cpp b/src/mod_moneyforkills.cpp index bc5c51d..fe91769 100644 --- a/src/mod_moneyforkills.cpp +++ b/src/mod_moneyforkills.cpp @@ -79,12 +79,12 @@ reward range of the group and an option to only reward the player that got the k enum KillType { - KILLTYPE_LOOT, - KILLTYPE_PVP, - KILLTYPE_DUNGEONBOSS, - KILLTYPE_WORLDBOSS, - KILLTYPE_MOB, - KILLTYPE_SUICIDE + KILLTYPE_LOOT, + KILLTYPE_PVP, + KILLTYPE_DUNGEONBOSS, + KILLTYPE_WORLDBOSS, + KILLTYPE_MOB, + KILLTYPE_SUICIDE }; static constexpr const char* MFKEnable = "MFK.Enable"; @@ -106,304 +106,300 @@ static constexpr const char* MFKBountyKillWBMult = "MFK.Bounty.WorldBoss.Multipl class MoneyForKills : public PlayerScript { public: - MoneyForKills() : PlayerScript("MoneyForKills") { } + MoneyForKills() : PlayerScript("MoneyForKills") { } - // Announce Module - void OnLogin(Player *player) { - if (sConfigMgr->GetBoolDefault(MFKEnable, true)) - { - if (sConfigMgr->GetBoolDefault(MFKAnnounce, true)) - { - ChatHandler(player->GetSession()).SendSysMessage("This server is running the |cff4CFF00MoneyForKills |rmodule."); - } - } - } + // Announce Module + void OnLogin(Player *player) { + if (sConfigMgr->GetBoolDefault(MFKEnable, true)) + { + if (sConfigMgr->GetBoolDefault(MFKAnnounce, true)) + { + ChatHandler(player->GetSession()).SendSysMessage("This server is running the |cff4CFF00MoneyForKills |rmodule."); + } + } + } - // Player Kill Reward - void OnPVPKill(Player* killer, Player* victim) - { - // If enabled... - if (sConfigMgr->GetBoolDefault(MFKEnable, true)) - { - const uint32 PVPMultiplier = sConfigMgr->GetIntDefault(MFKPVPKillMult, 0); - const uint32 VictimLevel = victim->getLevel(); + // Player Kill Reward + void OnPVPKill(Player* killer, Player* victim) + { + // If enabled... + if (sConfigMgr->GetBoolDefault(MFKEnable, true)) + { + const uint32 PVPMultiplier = sConfigMgr->GetIntDefault(MFKPVPKillMult, 0); + const uint32 VictimLevel = victim->getLevel(); - // If enabled... - if (PVPMultiplier > 0) - { - // No reward for killing yourself - if (killer->GetGUID() == victim->GetGUID()) - { - Notify(killer, victim, nullptr, KILLTYPE_SUICIDE, 0); - return; - } + // If enabled... + if (PVPMultiplier > 0) + { + // No reward for killing yourself + if (killer->GetGUID() == victim->GetGUID()) + { + Notify(killer, victim, nullptr, KILLTYPE_SUICIDE, 0); + return; + } - const int BountyAmount = ((VictimLevel * PVPMultiplier) / 3); + const int BountyAmount = ((VictimLevel * PVPMultiplier) / 3); - // Pay the player the additional PVP bounty - killer->ModifyMoney(BountyAmount); - // Inform the player of the bounty amount - Notify(killer, victim, nullptr, KILLTYPE_PVP, BountyAmount); - } + // Pay the player the additional PVP bounty + killer->ModifyMoney(BountyAmount); + // Inform the player of the bounty amount + Notify(killer, victim, nullptr, KILLTYPE_PVP, BountyAmount); + } - // Calculate the amount of gold to give to the victor - const uint32 PVPCorpseLootPercent = sConfigMgr->GetIntDefault(MFKPVPCorpseLootPercent, 5); - const int VictimLoot = (victim->GetMoney() * PVPCorpseLootPercent) / 100; - - // Rifle the victim's corpse for loot - if (victim->GetMoney() >= 10000 && VictimLoot > 0) - { - // Player loots a percentage of the victim's gold - killer->ModifyMoney(VictimLoot); - victim->ModifyMoney(-VictimLoot); + // Calculate the amount of gold to give to the victor + const uint32 PVPCorpseLootPercent = sConfigMgr->GetIntDefault(MFKPVPCorpseLootPercent, 5); + const int VictimLoot = (victim->GetMoney() * PVPCorpseLootPercent) / 100; - // Inform the player of the corpse loot - Notify(killer, victim, nullptr, KILLTYPE_LOOT, VictimLoot); - } - - return; - } - } + // Rifle the victim's corpse for loot + if (victim->GetMoney() >= 10000 && VictimLoot > 0) + { + // Player loots a percentage of the victim's gold + killer->ModifyMoney(VictimLoot); + victim->ModifyMoney(-VictimLoot); - // Creature Kill Reward - void OnCreatureKill(Player* player, Creature* killed) - { - // If enabled... - if (sConfigMgr->GetBoolDefault(MFKEnable, true)) - { - // Get the creature level - const uint32 CreatureLevel = killed->getLevel(); - uint32 BossMultiplier = 0; - uint32 KillMultiplier = 0; - KillType CreatureType; + // Inform the player of the corpse loot + Notify(killer, victim, nullptr, KILLTYPE_LOOT, VictimLoot); + } - if (killed->IsDungeonBoss()) { - BossMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillDBMult, 0); - CreatureType = KILLTYPE_DUNGEONBOSS; - } - else if (killed->isWorldBoss()) { - BossMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillWBMult, 0); - CreatureType = KILLTYPE_WORLDBOSS; - } - else - { - KillMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillMult, 0); - CreatureType = KILLTYPE_MOB; - } + return; + } + } - if (BossMultiplier > 0) - { - // Reward based on creature level - const int BountyAmount = ((CreatureLevel * BossMultiplier) * 100); - - if (CreatureType == KILLTYPE_WORLDBOSS) - { - Notify(player, nullptr, killed, KILLTYPE_WORLDBOSS, BountyAmount); - CreatureBounty(player, killed, KILLTYPE_MOB, BountyAmount); - } - else - { - CreatureBounty(player, killed, CreatureType, BountyAmount); - } + // Creature Kill Reward + void OnCreatureKill(Player* player, Creature* killed) + { + // If enabled... + if (sConfigMgr->GetBoolDefault(MFKEnable, true)) + { + // Get the creature level + const uint32 CreatureLevel = killed->getLevel(); + uint32 BossMultiplier = 0; + uint32 KillMultiplier = 0; + KillType CreatureType; - } + if (killed->IsDungeonBoss()) { + BossMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillDBMult, 0); + CreatureType = KILLTYPE_DUNGEONBOSS; + } + else if (killed->isWorldBoss()) { + BossMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillWBMult, 0); + CreatureType = KILLTYPE_WORLDBOSS; + } + else + { + KillMultiplier = sConfigMgr->GetIntDefault(MFKBountyKillMult, 0); + CreatureType = KILLTYPE_MOB; + } - if (KillMultiplier > 0) - { - // Reward based on creature level - const int BountyAmount = ((CreatureLevel * KillMultiplier) / 3); + if (BossMultiplier > 0) + { + // Reward based on creature level + const int BountyAmount = ((CreatureLevel * BossMultiplier) * 100); - // Pay the bounty amount - CreatureBounty(player, killed, CreatureType, BountyAmount); - } - } - } + if (CreatureType == KILLTYPE_WORLDBOSS) + { + Notify(player, nullptr, killed, KILLTYPE_WORLDBOSS, BountyAmount); + CreatureBounty(player, killed, KILLTYPE_MOB, BountyAmount); + } + else + { + CreatureBounty(player, killed, CreatureType, BountyAmount); + } - // Pay Creature Bounty - void CreatureBounty(Player* player, Creature* killed, KillType kType, int bounty) - { - Group* group = player->GetGroup(); - const uint32 KillingBlowOnly = sConfigMgr->GetIntDefault(MFKBountyKillingBlow, 0); + } - // Determine who receives the bounty - if (!group || KillingBlowOnly == 1) - { - // Pay a specific player bounty amount - player->ModifyMoney(bounty); + if (KillMultiplier > 0) + { + // Reward based on creature level + const int BountyAmount = ((CreatureLevel * KillMultiplier) / 3); - // Inform the player of the bounty amount - Notify(player, nullptr, killed, kType, bounty); - } - else - { - const uint32 MoneyForNothing = sConfigMgr->GetIntDefault(MFKBountyMoneyForNothing, 0); - Group::MemberSlotList const& members = group->GetMemberSlots(); + // Pay the bounty amount + CreatureBounty(player, killed, CreatureType, BountyAmount); + } + } + } - // Pay the group (OnCreatureKill only rewards the player that got the killing blow) - for (auto itr = members.begin(); itr != members.end(); ++itr) - { - Player* playerInGroup = ObjectAccessor::FindPlayer((*itr).guid); + // Pay Creature Bounty + void CreatureBounty(Player* player, Creature* killed, KillType kType, int bounty) + { + Group* group = player->GetGroup(); + const uint32 KillingBlowOnly = sConfigMgr->GetIntDefault(MFKBountyKillingBlow, 0); - // Pay each player in the group - if (playerInGroup && playerInGroup->GetSession()) - { - // Money for nothing and the kills for free.. - if (MoneyForNothing == 1) - { - // Pay the bounty - playerInGroup->ModifyMoney(bounty); + // Determine who receives the bounty + if (!group || KillingBlowOnly == 1) + { + // Pay a specific player bounty amount + player->ModifyMoney(bounty); - // Inform the player of the bounty amount - Notify(playerInGroup, nullptr, killed, kType, bounty); - } - else - { - // Only pay players that are in reward distance - if (playerInGroup->IsAtGroupRewardDistance(killed)) - { - // Pay the bounty - playerInGroup->ModifyMoney(bounty); + // Inform the player of the bounty amount + Notify(player, nullptr, killed, kType, bounty); + } + else + { + const uint32 MoneyForNothing = sConfigMgr->GetIntDefault(MFKBountyMoneyForNothing, 0); + Group::MemberSlotList const& members = group->GetMemberSlots(); - // Inform the player of the bounty amount - Notify(playerInGroup, nullptr, killed, kType, bounty); - } - } - } - } - } - } + // Pay the group (OnCreatureKill only rewards the player that got the killing blow) + for (auto itr = members.begin(); itr != members.end(); ++itr) + { + Player* playerInGroup = ObjectAccessor::FindPlayer((*itr).guid); - void Notify(Player * killer, Player * victim, Creature * killed, KillType kType, int reward) - { - int rewardBreakdown[3]; - rewardBreakdown[0] = reward / 10000; - reward = reward - rewardBreakdown[0] * 10000; - rewardBreakdown[1] = reward / 100; - rewardBreakdown[2] = reward - (rewardBreakdown[1] * 100); + // Pay each player in the group + if (playerInGroup && playerInGroup->GetSession()) + { + // Money for nothing and the kills for free.. + if (MoneyForNothing == 1) + { + // Pay the bounty + playerInGroup->ModifyMoney(bounty); - std::string rewardMsg = ""; - std::string victimMsg = ""; - std::string rewardVal = BuildRewardString(&rewardBreakdown[0]); - switch (kType) - { - case KILLTYPE_LOOT: - rewardMsg.append("You loot").append(rewardVal).append(" from the corpse."); - victimMsg.append(killer->GetName()).append(" rifles through your corpse and takes").append(rewardVal).append("."); - ChatHandler(victim->GetSession()).SendSysMessage(victimMsg.c_str()); - ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); - break; - case KILLTYPE_PVP: - if (sConfigMgr->GetBoolDefault(MFKAnnouncePvP, true)) - { - rewardMsg.append("|cff676767[ |cffFFFF00World |cff676767]|r:|cff4CFF00 ").append(killer->GetName()).append(" |cffFF0000has slain "); - rewardMsg.append(victim->GetName()).append(" earning a bounty of").append(rewardVal).append("."); - sWorld->SendServerMessage(SERVER_MSG_STRING, rewardMsg.c_str()); - } - break; - case KILLTYPE_DUNGEONBOSS: - if (sConfigMgr->GetBoolDefault(MFKAnnounceDungeonBoss, true)) - { - rewardMsg.append("|cffFF8000Your group has defeated |cffFF0000").append(killed->GetName()).append("|cffFF8000."); - ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); - rewardMsg.clear(); - } - break; - case KILLTYPE_WORLDBOSS: - if (sConfigMgr->GetBoolDefault(MFKAnnounceWorldBoss, true)) - { - rewardMsg.append("|cffFF0000[ |cffFFFF00World |cffFF0000]|r:|cff4CFF00 ").append(killer->GetName()); - rewardMsg.append("'s|r group triumphed victoriously over |CFF18BE00[").append(killed->GetName()).append("]|r !"); - sWorld->SendServerMessage(SERVER_MSG_STRING, rewardMsg.c_str()); - rewardMsg.clear(); - } - break; - case KILLTYPE_MOB: - break; - case KILLTYPE_SUICIDE: - std::string message = "|cff4CFF00 "; - message.append(killer->GetName()); - message.append(" met an untimely demise!"); + // Inform the player of the bounty amount + Notify(playerInGroup, nullptr, killed, kType, bounty); + } + else + { + // Only pay players that are in reward distance + if (playerInGroup->IsAtGroupRewardDistance(killed)) + { + // Pay the bounty + playerInGroup->ModifyMoney(bounty); - if (sConfigMgr->GetBoolDefault(MFKAnnounceWorldSuicide, true)) - sWorld->SendServerMessage(SERVER_MSG_STRING, message.c_str()); + // Inform the player of the bounty amount + Notify(playerInGroup, nullptr, killed, kType, bounty); + } + } + } + } + } + } - if (sConfigMgr->GetBoolDefault(MFKAnnounceGuildSuicide, false)) - { - Guild* guild = killer->GetGuild(); - if (guild) - guild->BroadcastToGuild(killer->GetSession(), false, message, LANG_UNIVERSAL); - } - + void Notify(Player * killer, Player * victim, Creature * killed, KillType kType, int reward) + { + int rewardBreakdown[3]; + rewardBreakdown[0] = reward / 10000; + reward = reward - rewardBreakdown[0] * 10000; + rewardBreakdown[1] = reward / 100; + rewardBreakdown[2] = reward - (rewardBreakdown[1] * 100); - if (sConfigMgr->GetBoolDefault(MFKAnnounceGroupSuicide, false)) - { - Group* group = killer->GetGroup(); - if (group) - { - Group::MemberSlotList const& members = group->GetMemberSlots(); + std::string rewardMsg = ""; + std::string victimMsg = ""; + std::string rewardVal = BuildRewardString(&rewardBreakdown[0]); + switch (kType) + { + case KILLTYPE_LOOT: + rewardMsg.append("You loot").append(rewardVal).append(" from the corpse."); + victimMsg.append(killer->GetName()).append(" rifles through your corpse and takes").append(rewardVal).append("."); + ChatHandler(victim->GetSession()).SendSysMessage(victimMsg.c_str()); + ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); + break; + case KILLTYPE_PVP: + if (sConfigMgr->GetBoolDefault(MFKAnnouncePvP, true)) + { + rewardMsg.append("|cff676767[ |cffFFFF00World |cff676767]|r:|cff4CFF00 ").append(killer->GetName()).append(" |cffFF0000has slain "); + rewardMsg.append(victim->GetName()).append(" earning a bounty of").append(rewardVal).append("."); + sWorld->SendServerMessage(SERVER_MSG_STRING, rewardMsg.c_str()); + } + break; + case KILLTYPE_DUNGEONBOSS: + if (sConfigMgr->GetBoolDefault(MFKAnnounceDungeonBoss, true)) + { + rewardMsg.append("|cffFF8000Your group has defeated |cffFF0000").append(killed->GetName()).append("|cffFF8000."); + ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); + rewardMsg.clear(); + } + break; + case KILLTYPE_WORLDBOSS: + if (sConfigMgr->GetBoolDefault(MFKAnnounceWorldBoss, true)) + { + rewardMsg.append("|cffFF0000[ |cffFFFF00World |cffFF0000]|r:|cff4CFF00 ").append(killer->GetName()); + rewardMsg.append("'s|r group triumphed victoriously over |CFF18BE00[").append(killed->GetName()).append("]|r !"); + sWorld->SendServerMessage(SERVER_MSG_STRING, rewardMsg.c_str()); + rewardMsg.clear(); + } + break; + case KILLTYPE_MOB: + break; + case KILLTYPE_SUICIDE: + std::string message = "|cff4CFF00 "; + message.append(killer->GetName()); + message.append(" met an untimely demise!"); - for (auto itr = members.begin(); itr != members.end(); ++itr) - { - Player* playerInGroup = ObjectAccessor::FindPlayer((*itr).guid); - if (playerInGroup) - ChatHandler(playerInGroup->GetSession()).SendSysMessage(message.c_str()); - } - } - } + if (sConfigMgr->GetBoolDefault(MFKAnnounceWorldSuicide, true)) + sWorld->SendServerMessage(SERVER_MSG_STRING, message.c_str()); - } + if (sConfigMgr->GetBoolDefault(MFKAnnounceGuildSuicide, false)) + { + Guild* guild = killer->GetGuild(); + if (guild) + guild->BroadcastToGuild(killer->GetSession(), false, message, LANG_UNIVERSAL); + } - if (kType != KILLTYPE_LOOT && kType != KILLTYPE_WORLDBOSS && kType != KILLTYPE_SUICIDE) - { - rewardMsg.clear(); - rewardMsg.append("You receive a bounty of"); - rewardMsg.append(rewardVal); - rewardMsg.append(" for the kill."); - ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); - } - } - std::string BuildRewardString(int * reward) - { - std::string currSymbol[3] = { " gold", " silver", " copper" }; - std::string rewardMsg = ""; - for (int i = 0; i < 3; i++) - { - if (reward[i] > 0) - { - rewardMsg.append(" ").append(std::to_string(reward[i])); - rewardMsg.append(currSymbol[i]); - } - } + if (sConfigMgr->GetBoolDefault(MFKAnnounceGroupSuicide, false)) + { + Group* group = killer->GetGroup(); + if (group) + { + Group::MemberSlotList const& members = group->GetMemberSlots(); - return rewardMsg; - } + for (auto itr = members.begin(); itr != members.end(); ++itr) + { + Player* playerInGroup = ObjectAccessor::FindPlayer((*itr).guid); + if (playerInGroup) + ChatHandler(playerInGroup->GetSession()).SendSysMessage(message.c_str()); + } + } + } + + } + + if (kType != KILLTYPE_LOOT && kType != KILLTYPE_WORLDBOSS && kType != KILLTYPE_SUICIDE) + { + rewardMsg.clear(); + rewardMsg.append("You receive a bounty of"); + rewardMsg.append(rewardVal); + rewardMsg.append(" for the kill."); + ChatHandler(killer->GetSession()).SendSysMessage(rewardMsg.c_str()); + } + } + + std::string BuildRewardString(int * reward) + { + std::string currSymbol[3] = { " gold", " silver", " copper" }; + std::string rewardMsg = ""; + for (int i = 0; i < 3; i++) + { + if (reward[i] > 0) + { + rewardMsg.append(" ").append(std::to_string(reward[i])); + rewardMsg.append(currSymbol[i]); + } + } + + return rewardMsg; + } }; class MoneyForKillsWorld : public WorldScript { public: - MoneyForKillsWorld() : WorldScript("MoneyForKillsWorld") { } + MoneyForKillsWorld() : WorldScript("MoneyForKillsWorld") { } - void OnBeforeConfigLoad(bool reload) override - { - if (!reload) { - std::string conf_path = _CONF_DIR; - std::string cfg_file = conf_path + "/mod_moneyforkills.conf"; + void OnBeforeConfigLoad(bool reload) override + { + if (!reload) { + std::string conf_path = _CONF_DIR; + std::string cfg_file = conf_path + "/mod_moneyforkills.conf"; -#ifdef WIN32 - cfg_file = "mod_moneyforkills.conf"; -#endif - - std::string cfg_def_file = cfg_file + ".dist"; - sConfigMgr->LoadMore(cfg_def_file.c_str()); - sConfigMgr->LoadMore(cfg_file.c_str()); - } - } + std::string cfg_def_file = cfg_file + ".dist"; + sConfigMgr->LoadMore(cfg_def_file.c_str()); + sConfigMgr->LoadMore(cfg_file.c_str()); + } + } }; void AddMoneyForKillsScripts() { - new MoneyForKills(); - new MoneyForKillsWorld(); -} + new MoneyForKills(); + new MoneyForKillsWorld(); +} \ No newline at end of file