From 93022fe9301bba70a780072db744bffe10132c2e Mon Sep 17 00:00:00 2001 From: Tereneckla Date: Fri, 25 Jul 2025 23:42:30 +0200 Subject: [PATCH] Initial commit --- .editorconfig | 8 + .gitattributes | 105 ++++++++ .github/ISSUE_TEMPLATE/bug_report.yml | 72 ++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 33 +++ .github/README.md | 18 ++ .github/workflows/core-build.yml | 15 ++ .github/workflows/core_codestyle.yml | 15 ++ .gitignore | 48 ++++ LICENSE | 21 ++ apps/.gitkeep | 0 apps/ci/.gitkeep | 0 apps/ci/ci-codestyle.sh | 40 +++ conf/.gitkeep | 0 conf/mod-profession-experience.conf.dist | 91 +++++++ data/.gitkeep | 0 data/sql/db-auth/.gitkeep | 0 data/sql/db-characters/.gitkeep | 0 data/sql/db-world/.gitkeep | 0 include.sh | 0 pull_request_template.md | 25 ++ src/PE_loader.cpp | 13 + src/ProfessionExp.cpp | 277 +++++++++++++++++++++ 22 files changed, 781 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/README.md create mode 100644 .github/workflows/core-build.yml create mode 100644 .github/workflows/core_codestyle.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 apps/.gitkeep create mode 100644 apps/ci/.gitkeep create mode 100644 apps/ci/ci-codestyle.sh create mode 100644 conf/.gitkeep create mode 100644 conf/mod-profession-experience.conf.dist create mode 100644 data/.gitkeep create mode 100644 data/sql/db-auth/.gitkeep create mode 100644 data/sql/db-characters/.gitkeep create mode 100644 data/sql/db-world/.gitkeep create mode 100644 include.sh create mode 100644 pull_request_template.md create mode 100644 src/PE_loader.cpp create mode 100644 src/ProfessionExp.cpp 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/.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/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..5610d2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,72 @@ +name: Bug report +description: Create a bug report to help us improve. +title: "Bug: " +body: + - type: textarea + id: current + attributes: + label: Current Behaviour + description: | + Description of the problem or issue here. + Include entries of affected creatures / items / quests / spells etc. + If this is a crash, post the crashlog (upload to https://gist.github.com/) and include the link here. + Never upload files! Use GIST for text and YouTube for videos! + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected Behaviour + description: | + Tell us what should happen instead. + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce the problem + description: | + What does someone else need to do to encounter the same bug? + placeholder: | + 1. Step 1 + 2. Step 2 + 3. Step 3 + validations: + required: true + - type: textarea + id: extra + attributes: + label: Extra Notes + description: | + Do you have any extra notes that can help solve the issue that does not fit any other field? + placeholder: | + None + validations: + required: false + - type: textarea + id: commit + attributes: + label: AC rev. hash/commit + description: | + Copy the result of the `.server debug` command (if you need to run it from the client get a prat addon) + validations: + required: true + - type: input + id: os + attributes: + label: Operating system + description: | + The Operating System the Server is running on. + i.e. Windows 11 x64, Debian 10 x64, macOS 12, Ubuntu 20.04 + validations: + required: true + - type: textarea + id: custom + attributes: + label: Custom changes or Modules + description: | + List which custom changes or modules you have applied, i.e. Eluna module, etc. + placeholder: | + None + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..58f79dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,33 @@ +name: Feature request +description: Suggest an idea for this project +title: "Feature: " +body: + - type: markdown + attributes: + value: | + Thank you for taking your time to fill out a feature request. Remember to fill out all fields including the title above. + An issue that is not properly filled out will be closed. + - type: textarea + id: description + attributes: + label: Describe your feature request or suggestion in detail + description: | + A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe a possible solution to your feature or suggestion in detail + description: | + A clear and concise description of any alternative solutions or features you've considered. + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: | + Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..b507eef --- /dev/null +++ b/.github/README.md @@ -0,0 +1,18 @@ +# ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) AzerothCore + +## mod-profession-experience + +Module for azerothcore to reward experience when crafting or gathering with professions + +## This module currently requires: +- AzerothCore https://github.com/azerothcore/azerothcore-wotlk/commit/fd262c3ab109afec7d191c97d2b44f58eb4a1477 + +## 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 + +## Usage + +- Enable or disable professions in conf +- Change the experience gained for performing actions in conf diff --git a/.github/workflows/core-build.yml b/.github/workflows/core-build.yml new file mode 100644 index 0000000..aad248b --- /dev/null +++ b/.github/workflows/core-build.yml @@ -0,0 +1,15 @@ +name: core-build +on: + push: + branches: + - 'master' + pull_request: + branches: + - 'master' + workflow_dispatch: + +jobs: + build: + uses: azerothcore/reusable-workflows/.github/workflows/core_build_modules.yml@main + with: + module_repo: ${{ github.event.repository.name }} diff --git a/.github/workflows/core_codestyle.yml b/.github/workflows/core_codestyle.yml new file mode 100644 index 0000000..c6573bb --- /dev/null +++ b/.github/workflows/core_codestyle.yml @@ -0,0 +1,15 @@ +name: Codestyle Checks +on: + push: + pull_request: + +jobs: + check-codestyle: + strategy: + fail-fast: false + runs-on: ubuntu-latest + name: Check Codestyling + steps: + - uses: actions/checkout@v2 + - name: Check Codestyling + run: source ./apps/ci/ci-codestyle.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6e1299 --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +!.gitignore + +# +#Generic +# + +.directory +.mailmap +*.orig +*.rej +*.*~ +.hg/ +*.kdev* +.DS_Store +CMakeLists.txt.user +*.bak +*.patch +*.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/LICENSE b/LICENSE new file mode 100644 index 0000000..d0882e0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AzerothCore + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/apps/.gitkeep b/apps/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/ci/.gitkeep b/apps/ci/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/ci/ci-codestyle.sh b/apps/ci/ci-codestyle.sh new file mode 100644 index 0000000..c96a31d --- /dev/null +++ b/apps/ci/ci-codestyle.sh @@ -0,0 +1,40 @@ +#!/bin/bash +set -e + +echo "Codestyle check script:" +echo + +declare -A singleLineRegexChecks=( + ["LOG_.+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" + ["[[:blank:]]$"]="Remove whitespace at the end of the lines above" + ["\t"]="Replace tabs with 4 spaces in the lines above" +) + +for check in ${!singleLineRegexChecks[@]}; do + echo " Checking RegEx: '${check}'" + + if grep -P -r -I -n ${check} src; then + echo + echo "${singleLineRegexChecks[$check]}" + exit 1 + fi +done + +declare -A multiLineRegexChecks=( + ["LOG_[^;]+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" + ["\n\n\n"]="Multiple blank lines detected, keep only one. Check the files above" +) + +for check in ${!multiLineRegexChecks[@]}; do + echo " Checking RegEx: '${check}'" + + if grep -Pzo -r -I ${check} src; then + echo + echo + echo "${multiLineRegexChecks[$check]}" + exit 1 + fi +done + +echo +echo "Everything looks good" diff --git a/conf/.gitkeep b/conf/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/conf/mod-profession-experience.conf.dist b/conf/mod-profession-experience.conf.dist new file mode 100644 index 0000000..21ce81f --- /dev/null +++ b/conf/mod-profession-experience.conf.dist @@ -0,0 +1,91 @@ +# +# Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 +# + +[worldserver] + +######################################## +# Profession Experience Configuration +######################################## +# +# ProfessionExperience.MultGray +# ProfessionExperience.MultGreen +# ProfessionExperience.MultYellow +# ProfessionExperience.MultOrange +# Description: Multiplicator to experience when using a skill with this difficulty +# Default: 0.0 - (ProfessionExperience.MultGray) +# 0.75 - (ProfessionExperience.MultGreen) +# 1.0 - (ProfessionExperience.MultYellow) +# 1.25 - (ProfessionExperience.MultOrange) + +ProfessionExperience.MultGray = 0.0 +ProfessionExperience.MultGreen = 0.75 +ProfessionExperience.MultYellow = 1.0 +ProfessionExperience.MultOrange = 1.25 + + +# +# ProfessionExperience.*.Enabled +# Description: Enable experience gain when crafting or gathering with this profession. Enchanting governs both Enchanting and Disenchanting +# Default: 0 - (Disabled, ProfessionExperience.Alchemy.Enabled) +# 0 - (Disabled, ProfessionExperience.Blacksmith.Enabled) +# 0 - (Disabled, ProfessionExperience.Cooking.Enabled) +# 0 - (Disabled, ProfessionExperience.Enchanting.Enabled) +# 0 - (Disabled, ProfessionExperience.Engineering.Enabled) +# 1 - (Enabled, ProfessionExperience.Fishing.Enabled) +# 0 - (Disabled, ProfessionExperience.FirstAid.Enabled) +# 1 - (Enabled, ProfessionExperience.Herbalism.Enabled) +# 0 - (Disabled, ProfessionExperience.Inscription.Enabled) +# 0 - (Disabled, ProfessionExperience.Jewelcrafting.Enabled) +# 0 - (Disabled, ProfessionExperience.Leatherworking.Enabled) +# 0 - (Disabled, ProfessionExperience.Lockpick.Enabled) +# 0 - (Disabled, ProfessionExperience.Milling.Enabled) +# 1 - (Enabled, ProfessionExperience.Mining.Enabled) +# 0 - (Disabled, ProfessionExperience.Prospecting.Enabled) +# 0 - (Disabled, ProfessionExperience.Skinning.Enabled) +# 0 - (Disabled, ProfessionExperience.Smelting.Enabled) +# 0 - (Disabled, ProfessionExperience.Tailoring.Enabled) + +ProfessionExperience.Alchemy.Enabled = 0 +ProfessionExperience.Blacksmith.Enabled = 0 +ProfessionExperience.Cooking.Enabled = 0 +ProfessionExperience.Enchanting.Enabled = 0 +ProfessionExperience.Engineering.Enabled = 0 +ProfessionExperience.Fishing.Enabled = 1 +ProfessionExperience.FirstAid.Enabled = 0 +ProfessionExperience.Herbalism.Enabled = 1 +ProfessionExperience.Inscription.Enabled = 0 +ProfessionExperience.Jewelcrafting.Enabled = 0 +ProfessionExperience.Leatherworking.Enabled = 0 +ProfessionExperience.Lockpick.Enabled = 0 +ProfessionExperience.Milling.Enabled = 0 +ProfessionExperience.Mining.Enabled = 1 +ProfessionExperience.Prospecting.Enabled = 0 +ProfessionExperience.Skinning.Enabled = 0 +ProfessionExperience.Smelting.Enabled = 0 +ProfessionExperience.Tailoring.Enabled = 0 + + +# +# ProfessionExperience.*.Experience +# Description: Part of a level gained for performing the action +# Default: 0.01 - (1%, All of them) + +ProfessionExperience.Alchemy.Experience = 0.01 +ProfessionExperience.Blacksmith.Experience = 0.01 +ProfessionExperience.Cooking.Experience = 0.01 +ProfessionExperience.Enchanting.Experience = 0.01 +ProfessionExperience.Engineering.Experience = 0.01 +ProfessionExperience.Fishing.Experience = 0.01 +ProfessionExperience.FirstAid.Experience = 0.01 +ProfessionExperience.Herbalism.Experience = 0.01 +ProfessionExperience.Inscription.Experience = 0.01 +ProfessionExperience.Jewelcrafting.Experience = 0.01 +ProfessionExperience.Leatherworking.Experience = 0.01 +ProfessionExperience.Lockpick.Experience = 0.01 +ProfessionExperience.Milling.Experience = 0.01 +ProfessionExperience.Mining.Experience = 0.01 +ProfessionExperience.Prospecting.Experience = 0.01 +ProfessionExperience.Skinning.Experience = 0.01 +ProfessionExperience.Smelting.Experience = 0.01 +ProfessionExperience.Tailoring.Experience = 0.01 diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/sql/db-auth/.gitkeep b/data/sql/db-auth/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/sql/db-characters/.gitkeep b/data/sql/db-characters/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/sql/db-world/.gitkeep b/data/sql/db-world/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include.sh b/include.sh new file mode 100644 index 0000000..e69de29 diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 0000000..21c9245 --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,25 @@ + + +## Changes Proposed: +- +- + +## Issues Addressed: + +- Closes + +## SOURCE: + + +## Tests Performed: + +- +- + + +## How to Test the Changes: + + +1. +2. +3. diff --git a/src/PE_loader.cpp b/src/PE_loader.cpp new file mode 100644 index 0000000..157d9a7 --- /dev/null +++ b/src/PE_loader.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + */ + +// From SC +void AddProfessionExpScripts(); + +// Add all +void Addmod_profession_experienceScripts() +{ + AddProfessionExpScripts(); +} + diff --git a/src/ProfessionExp.cpp b/src/ProfessionExp.cpp new file mode 100644 index 0000000..3acbbc6 --- /dev/null +++ b/src/ProfessionExp.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + */ + +#include "Chat.h" +#include "Config.h" +#include "ConfigValueCache.h" +#include "Player.h" +#include "ScriptMgr.h" + +enum class PEConfig +{ + ALCHEMY_ENABLED, + ALCHEMY_EXPERIENCE, + BLACKSMITH_ENABLED, + BLACKSMITH_EXPERIENCE, + COOKING_ENABLED, + COOKING_EXPERIENCE, + ENCHANTING_ENABLED, + ENCHANTING_EXPERIENCE, + ENGINEERING_ENABLED, + ENGINEERING_EXPERIENCE, + FISHING_ENABLED, + FISHING_EXPERIENCE, + FIRST_AID_ENABLED, + FIRST_AID_EXPERIENCE, + HERBALISM_ENABLED, + HERBALISM_EXPERIENCE, + INSCRIPTION_ENABLED, + INSCRIPTION_EXPERIENCE, + JEWELCRAFTING_ENABLED, + JEWELCRAFTING_EXPERIENCE, + LEATHERWORKING_ENABLED, + LEATHERWORKING_EXPERIENCE, + LOCKPICK_ENABLED, + LOCKPICK_EXPERIENCE, + MILLING_ENABLED, + MILLING_EXPERIENCE, + MINING_ENABLED, + MINING_EXPERIENCE, + PROSPECTING_ENABLED, + PROSPECTING_EXPERIENCE, + SKINNING_ENABLED, + SKINNING_EXPERIENCE, + SMELTING_ENABLED, + SMELTING_EXPERIENCE, + TAILORING_ENABLED, + TAILORING_EXPERIENCE, + MULT_GREY, + MULT_GREEN, + MULT_YELLOW, + MULT_ORANGE, + + NUM_CONFIGS, +}; + +class PEConfigData : public ConfigValueCache +{ +public: + PEConfigData() : ConfigValueCache(PEConfig::NUM_CONFIGS) { }; + + void BuildConfigCache() override + { + SetConfigValue(PEConfig::ALCHEMY_ENABLED, "ProfessionExperience.Alchemy.Enabled", false); + SetConfigValue(PEConfig::ALCHEMY_EXPERIENCE, "ProfessionExperience.Alchemy.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::BLACKSMITH_ENABLED, "ProfessionExperience.Blacksmith.Enabled", false); + SetConfigValue(PEConfig::BLACKSMITH_EXPERIENCE, "ProfessionExperience.Blacksmith.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::COOKING_ENABLED, "ProfessionExperience.Cooking.Enabled", false); + SetConfigValue(PEConfig::COOKING_EXPERIENCE, "ProfessionExperience.Cooking.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::ENCHANTING_ENABLED, "ProfessionExperience.Enchanting.Enabled", false); + SetConfigValue(PEConfig::ENCHANTING_EXPERIENCE, "ProfessionExperience.Enchanting.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::ENGINEERING_ENABLED, "ProfessionExperience.Engineering.Enabled", false); + SetConfigValue(PEConfig::ENGINEERING_EXPERIENCE, "ProfessionExperience.Engineering.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::FISHING_ENABLED, "ProfessionExperience.Fishing.Enabled", true); + SetConfigValue(PEConfig::FISHING_EXPERIENCE, "ProfessionExperience.Fishing.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::FIRST_AID_ENABLED, "ProfessionExperience.FirstAid.Enabled", false); + SetConfigValue(PEConfig::FIRST_AID_EXPERIENCE, "ProfessionExperience.FirstAid.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::HERBALISM_ENABLED, "ProfessionExperience.Herbalism.Enabled", true); + SetConfigValue(PEConfig::HERBALISM_EXPERIENCE, "ProfessionExperience.Herbalism.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::INSCRIPTION_ENABLED, "ProfessionExperience.Inscription.Enabled", false); + SetConfigValue(PEConfig::INSCRIPTION_EXPERIENCE, "ProfessionExperience.Inscription.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::JEWELCRAFTING_ENABLED, "ProfessionExperience.Jewelcrafting.Enabled", false); + SetConfigValue(PEConfig::JEWELCRAFTING_EXPERIENCE, "ProfessionExperience.Jewelcrafting.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::LEATHERWORKING_ENABLED, "ProfessionExperience.Leatherworking.Enabled", false); + SetConfigValue(PEConfig::LEATHERWORKING_EXPERIENCE, "ProfessionExperience.Leatherworking.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::LOCKPICK_ENABLED, "ProfessionExperience.Lockpick.Enabled", false); + SetConfigValue(PEConfig::LOCKPICK_EXPERIENCE, "ProfessionExperience.Lockpick.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::MILLING_ENABLED, "ProfessionExperience.Milling.Enabled", false); + SetConfigValue(PEConfig::MILLING_EXPERIENCE, "ProfessionExperience.Milling.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::MINING_ENABLED, "ProfessionExperience.Mining.Enabled", true); + SetConfigValue(PEConfig::MINING_EXPERIENCE, "ProfessionExperience.Mining.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::PROSPECTING_ENABLED, "ProfessionExperience.Prospecting.Enabled", false); + SetConfigValue(PEConfig::PROSPECTING_EXPERIENCE, "ProfessionExperience.Prospecting.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::SKINNING_ENABLED, "ProfessionExperience.Skinning.Enabled", false); + SetConfigValue(PEConfig::SKINNING_EXPERIENCE, "ProfessionExperience.Skinning.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::SMELTING_ENABLED, "ProfessionExperience.Smelting.Enabled", false); + SetConfigValue(PEConfig::SMELTING_EXPERIENCE, "ProfessionExperience.Smelting.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::TAILORING_ENABLED, "ProfessionExperience.Tailoring.Enabled", false); + SetConfigValue(PEConfig::TAILORING_EXPERIENCE, "ProfessionExperience.Tailoring.Experience", 0.01, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value > 0.0f; }, "> 0"); + + SetConfigValue(PEConfig::MULT_GREY, "ProfessionExperience.MultGrey", 0.0f, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value >= 0.0f; }, ">= 0"); + SetConfigValue(PEConfig::MULT_GREEN, "ProfessionExperience.MultGreen", 0.75f, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value >= 0.0f; }, ">= 0"); + SetConfigValue(PEConfig::MULT_YELLOW, "ProfessionExperience.MultYellow", 1.0f, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value >= 0.0f; }, ">= 0"); + SetConfigValue(PEConfig::MULT_ORANGE, "ProfessionExperience.MultOrange", 1.25f, ConfigValueCache::Reloadable::Yes, [](float const& value) { return value >= 0.0f; }, ">= 0"); + } +}; +static PEConfigData peConfigData; + +class RewardExperienceScript : public PlayerScript +{ +public: +RewardExperienceScript() : PlayerScript("RewardExperienceScript", { + PLAYERHOOK_ON_UPDATE_CRAFTING_SKILL, + PLAYERHOOK_ON_UPDATE_GATHERING_SKILL, + PLAYERHOOK_ON_UPDATE_FISHING_SKILL, + }) { } + + bool OnPlayerUpdateFishingSkill(Player* player, int32 skill, int32 zone_skill, int32 /*chance*/, int32 /*roll*/) override + { + if (peConfigData.GetConfigValue(PEConfig::FISHING_ENABLED)) + RewardXP(player, skill, zone_skill + 100, zone_skill + 50, zone_skill + 25, peConfigData.GetConfigValue(PEConfig::FISHING_EXPERIENCE)); + + return true; + } + + void OnPlayerUpdateGatheringSkill(Player* player, uint32 skillId, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, uint32& /*gain*/) override + { + PEConfig enabledSetting; + PEConfig experienceSetting; + switch (skillId) + { + case SKILL_HERBALISM: + enabledSetting = PEConfig::HERBALISM_ENABLED; + experienceSetting = PEConfig::HERBALISM_EXPERIENCE; + break; + case SKILL_MINING: + enabledSetting = PEConfig::MINING_ENABLED; + experienceSetting = PEConfig::MINING_EXPERIENCE; + break; + case SKILL_SKINNING: + enabledSetting = PEConfig::SKINNING_ENABLED; + experienceSetting = PEConfig::SKINNING_EXPERIENCE; + break; + case SKILL_LOCKPICKING: + enabledSetting = PEConfig::LOCKPICK_ENABLED; + experienceSetting = PEConfig::LOCKPICK_EXPERIENCE; + break; + case SKILL_JEWELCRAFTING: + enabledSetting = PEConfig::PROSPECTING_ENABLED; + experienceSetting = PEConfig::PROSPECTING_EXPERIENCE; + break; + case SKILL_INSCRIPTION: + enabledSetting = PEConfig::MILLING_ENABLED; + experienceSetting = PEConfig::MILLING_EXPERIENCE; + break; + default: + return; + } + + if (peConfigData.GetConfigValue(enabledSetting)) + RewardXP(player, currentLevel, gray, green, yellow, peConfigData.GetConfigValue(experienceSetting)); + } + + void OnPlayerUpdateCraftingSkill(Player *player, SkillLineAbilityEntry const* skill, uint32 currentLevel, uint32& /*gain*/) override + { + PEConfig enabledSetting; + PEConfig experienceSetting; + switch (skill->SkillLine) + { + case SKILL_ALCHEMY: + enabledSetting = PEConfig::ALCHEMY_ENABLED; + experienceSetting = PEConfig::ALCHEMY_EXPERIENCE; + break; + case SKILL_BLACKSMITHING: + enabledSetting = PEConfig::BLACKSMITH_ENABLED; + experienceSetting = PEConfig::BLACKSMITH_EXPERIENCE; + break; + case SKILL_COOKING: + enabledSetting = PEConfig::COOKING_ENABLED; + experienceSetting = PEConfig::COOKING_EXPERIENCE; + break; + case SKILL_ENCHANTING: + enabledSetting = PEConfig::ENCHANTING_ENABLED; + experienceSetting = PEConfig::ENCHANTING_EXPERIENCE; + break; + case SKILL_ENGINEERING: + enabledSetting = PEConfig::ENGINEERING_ENABLED; + experienceSetting = PEConfig::ENGINEERING_EXPERIENCE; + break; + case SKILL_FIRST_AID: + enabledSetting = PEConfig::FIRST_AID_ENABLED; + experienceSetting = PEConfig::FIRST_AID_EXPERIENCE; + break; + case SKILL_INSCRIPTION: + enabledSetting = PEConfig::INSCRIPTION_ENABLED; + experienceSetting = PEConfig::INSCRIPTION_EXPERIENCE; + break; + case SKILL_JEWELCRAFTING: + enabledSetting = PEConfig::JEWELCRAFTING_ENABLED; + experienceSetting = PEConfig::JEWELCRAFTING_EXPERIENCE; + break; + case SKILL_LEATHERWORKING: + enabledSetting = PEConfig::LEATHERWORKING_ENABLED; + experienceSetting = PEConfig::LEATHERWORKING_EXPERIENCE; + break; + case SKILL_MINING: + enabledSetting = PEConfig::SMELTING_ENABLED; + experienceSetting = PEConfig::SMELTING_EXPERIENCE; + break; + case SKILL_TAILORING: + enabledSetting = PEConfig::TAILORING_ENABLED; + experienceSetting = PEConfig::TAILORING_EXPERIENCE; + break; + default: + return; + } + if (peConfigData.GetConfigValue(enabledSetting)) + { + uint32 gray = skill->TrivialSkillLineRankHigh; + uint32 green = (skill->TrivialSkillLineRankHigh + skill->TrivialSkillLineRankLow) / 2; + uint32 yellow = skill->TrivialSkillLineRankLow; + RewardXP(player, currentLevel, gray, green, yellow, peConfigData.GetConfigValue(experienceSetting)); + } + } + + void RewardXP(Player* player, uint32 currentLevel, uint32 gray, uint32 green, uint32 yellow, float xpFraction) + { + uint32 xp = player->GetUInt32Value(PLAYER_NEXT_LEVEL_XP) * xpFraction; + if (currentLevel >= gray) + xp = xp * peConfigData.GetConfigValue(PEConfig::MULT_GREY); + else if (currentLevel >= green) + xp = xp * peConfigData.GetConfigValue(PEConfig::MULT_GREEN); + else if (currentLevel >= yellow) + xp = xp * peConfigData.GetConfigValue(PEConfig::MULT_YELLOW); + else + xp = xp * peConfigData.GetConfigValue(PEConfig::MULT_ORANGE); + + player->GiveXP(xp, nullptr); + } +}; + +class LoadPEConfigScript : public WorldScript +{ +public: +LoadPEConfigScript() : WorldScript("LoadPEConfigScript", { + WORLDHOOK_ON_BEFORE_CONFIG_LOAD + }) { } + + void OnBeforeConfigLoad(bool reload) override + { + peConfigData.Initialize(reload); + } +}; + +// Add all scripts in one +void AddProfessionExpScripts() +{ + new RewardExperienceScript(); + new LoadPEConfigScript(); +}