aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTraesh <traesh@farahlon.com>2018-10-23 16:20:45 +0200
committerShauren <shauren.trinity@gmail.com>2019-08-24 17:13:17 +0200
commit548d79bb06cfba3517347070dfe606748dda55ab (patch)
tree04d48461378ed52a7ac3075b8119e18ab985925b /src
parent11674e2721bf402b6f3b03e9d7dba9a57bbf4c4c (diff)
Core/DataStores: Implemented WorldStateExpression
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp3
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp393
-rw-r--r--src/server/game/Conditions/ConditionMgr.h2
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h14
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp2
-rw-r--r--src/server/game/DataStores/DB2Stores.h2
-rw-r--r--src/server/game/DataStores/DB2Structure.h6
-rw-r--r--src/server/game/DataStores/DBCEnums.h80
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp6
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp69
12 files changed, 574 insertions, 9 deletions
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index e93d72bfb08..5dcc28fd544 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -1090,6 +1090,9 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// WorldSafeLocs.db2
PrepareStatement(HOTFIX_SEL_WORLD_SAFE_LOCS, "SELECT ID, AreaName, LocX, LocY, LocZ, MapID, Facing FROM world_safe_locs ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_WORLD_SAFE_LOCS, "SELECT ID, AreaName_lang FROM world_safe_locs_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // WorldStateExpression.db2
+ PrepareStatement(HOTFIX_SEL_WORLD_STATE_EXPRESSION, "SELECT ID, Expression FROM world_state_expression ORDER BY ID DESC", CONNECTION_SYNCH);
}
HotfixDatabaseConnection::HotfixDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo)
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index e31704bebe7..18aa7c60cf7 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -572,6 +572,8 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_WORLD_SAFE_LOCS,
HOTFIX_SEL_WORLD_SAFE_LOCS_LOCALE,
+ HOTFIX_SEL_WORLD_STATE_EXPRESSION,
+
MAX_HOTFIXDATABASE_STATEMENTS
};
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 37c2e980459..598c1000758 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -23,6 +23,7 @@
#include "DB2Stores.h"
#include "GameEventMgr.h"
#include "GameObject.h"
+#include "GameTime.h"
#include "Group.h"
#include "InstanceScript.h"
#include "Item.h"
@@ -33,12 +34,14 @@
#include "PhasingHandler.h"
#include "Player.h"
#include "Pet.h"
+#include "Realm.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "SpellAuras.h"
#include "SpellMgr.h"
#include "World.h"
#include "WorldSession.h"
+#include <random>
char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
{
@@ -2771,7 +2774,17 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player const* player, PlayerConditio
}
// TODO: time condition
- // TODO (or not): world state expression condition
+
+ if (condition->WorldStateExpressionID)
+ {
+ WorldStateExpressionEntry const* worldStateExpression = sWorldStateExpressionStore.LookupEntry(condition->WorldStateExpressionID);
+ if (!worldStateExpression)
+ return false;
+
+ if (!IsPlayerMeetingExpression(player, worldStateExpression))
+ return false;
+ }
+
// TODO: weather condition
if (condition->Achievement[0])
@@ -2869,3 +2882,381 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player const* player, PlayerConditio
return true;
}
+
+ByteBuffer HexToBytes(const std::string& hex)
+{
+ ByteBuffer buffer;
+ buffer.resize(hex.length() / 2);
+ HexStrToByteArray(hex, buffer.contents());
+ return buffer;
+}
+
+static int32(* const WorldStateExpressionFunctions[WSE_FUNCTION_MAX])(Player const*, uint32, uint32) =
+{
+ // WSE_FUNCTION_NONE
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_RANDOM
+ [](Player const* /*player*/, uint32 arg1, uint32 arg2) -> int32
+ {
+ return irand(std::min(arg1, arg2), std::max(arg1, arg2));
+ },
+
+ // WSE_FUNCTION_MONTH
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return GameTime::GetDateAndTime()->tm_mon + 1;
+ },
+
+ // WSE_FUNCTION_DAY
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return GameTime::GetDateAndTime()->tm_mday + 1;
+ },
+
+ // WSE_FUNCTION_TIME_OF_DAY
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ tm const* localTime = GameTime::GetDateAndTime();
+ return localTime->tm_hour * MINUTE + localTime->tm_min;
+ },
+
+ // WSE_FUNCTION_REGION
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return realm.Id.Region;
+ },
+
+ // WSE_FUNCTION_CLOCK_HOUR
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ uint32 currentHour = GameTime::GetDateAndTime()->tm_hour + 1;
+ return currentHour <= 12 ? (currentHour ? currentHour : 12) : currentHour - 12;
+ },
+
+ // WSE_FUNCTION_OLD_DIFFICULTY_ID
+ [](Player const* player, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(player->GetMap()->GetDifficultyID()))
+ return difficulty->OldEnumValue;
+
+ return -1;
+ },
+
+ // WSE_FUNCTION_HOLIDAY_START
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_HOLIDAY_LEFT
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_HOLIDAY_ACTIVE
+ [](Player const* /*player*/, uint32 arg1, uint32 /*arg2*/) -> int32
+ {
+ return int32(IsHolidayActive(HolidayIds(arg1)));
+ },
+
+ // WSE_FUNCTION_TIMER_CURRENT_TIME
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return GameTime::GetGameTime();
+ },
+
+ // WSE_FUNCTION_WEEK_NUMBER
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ time_t now = GameTime::GetGameTime();
+ uint32 raidOrigin = 1135695600;
+ if (Cfg_RegionsEntry const* region = sCfgRegionsStore.LookupEntry(realm.Id.Region))
+ raidOrigin = region->Raidorigin;
+
+ return (now - raidOrigin) / WEEK;
+ },
+
+ // WSE_FUNCTION_UNK13
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK14
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_DIFFICULTY_ID
+ [](Player const* player, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return player->GetMap()->GetDifficultyID();
+ },
+
+ // WSE_FUNCTION_WAR_MODE_ACTIVE
+ [](Player const* player, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return player->HasPlayerFlag(PLAYER_FLAGS_WAR_MODE_ACTIVE);
+ },
+
+ // WSE_FUNCTION_UNK17
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK18
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK19
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK20
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK21
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_WORLD_STATE_EXPRESSION
+ [](Player const* player, uint32 arg1, uint32 /*arg2*/) -> int32
+ {
+ if (WorldStateExpressionEntry const* worldStateExpression = sWorldStateExpressionStore.LookupEntry(arg1))
+ return ConditionMgr::IsPlayerMeetingExpression(player, worldStateExpression);
+
+ return 0;
+ },
+
+ // WSE_FUNCTION_KEYSTONE_AFFIX
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK24
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK25
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK26
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK27
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_KEYSTONE_LEVEL
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK29
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK30
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK31
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK32
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_MERSENNE_RANDOM
+ [](Player const* /*player*/, uint32 arg1, uint32 arg2) -> int32
+ {
+ if (arg1 == 1)
+ return 1;
+
+ // init with predetermined seed
+ std::mt19937 mt(arg2 ? arg2 : 1);
+ return mt() % arg1 + 1;
+ },
+
+ // WSE_FUNCTION_UNK34
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK35
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UNK36
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+ // WSE_FUNCTION_UI_WIDGET_DATA
+ [](Player const* /*player*/, uint32 /*arg1*/, uint32 /*arg2*/) -> int32
+ {
+ return 0;
+ },
+
+};
+
+int32 EvalSingleValue(ByteBuffer& buffer, Player const* player)
+{
+ WorldStateExpressionValueType valueType = buffer.read<WorldStateExpressionValueType>();
+ int32 value = 0;
+
+ switch (valueType)
+ {
+ case WorldStateExpressionValueType::Constant:
+ {
+ value = buffer.read<int32>();
+ break;
+ }
+ case WorldStateExpressionValueType::WorldState:
+ {
+ uint32 worldStateId = buffer.read<uint32>();
+ value = sWorld->getWorldState(worldStateId);
+ break;
+ }
+ case WorldStateExpressionValueType::Function:
+ {
+ uint32 functionType = buffer.read<uint32>();
+ int32 arg1 = EvalSingleValue(buffer, player);
+ int32 arg2 = EvalSingleValue(buffer, player);
+
+ if (functionType >= WSE_FUNCTION_MAX)
+ return 0;
+
+ value = WorldStateExpressionFunctions[functionType](player, arg1, arg2);
+ }
+ default:
+ break;
+ }
+
+ return value;
+}
+
+int32 EvalValue(ByteBuffer& buffer, Player const* player)
+{
+ int32 leftValue = EvalSingleValue(buffer, player);
+
+ WorldStateExpressionOperatorType operatorType = buffer.read<WorldStateExpressionOperatorType>();
+ if (operatorType == WorldStateExpressionOperatorType::None)
+ return leftValue;
+
+ int32 rightValue = EvalSingleValue(buffer, player);
+
+ switch (operatorType)
+ {
+ case WorldStateExpressionOperatorType::Sum: return leftValue + rightValue;
+ case WorldStateExpressionOperatorType::Substraction: return leftValue - rightValue;
+ case WorldStateExpressionOperatorType::Multiplication: return leftValue * rightValue;
+ case WorldStateExpressionOperatorType::Division: return !rightValue ? 0 : leftValue / rightValue;
+ case WorldStateExpressionOperatorType::Remainder: return !rightValue ? 0 : leftValue % rightValue;
+ default:
+ break;
+ }
+
+ return leftValue;
+}
+
+bool EvalRelOp(ByteBuffer& buffer, Player const* player)
+{
+ int32 leftValue = EvalValue(buffer, player);
+
+ WorldStateExpressionComparisonType compareLogic = buffer.read<WorldStateExpressionComparisonType>();
+ if (compareLogic == WorldStateExpressionComparisonType::None)
+ return leftValue != 0;
+
+ int32 rightValue = EvalValue(buffer, player);
+
+ switch (compareLogic)
+ {
+ case WorldStateExpressionComparisonType::Equal: return leftValue == rightValue;
+ case WorldStateExpressionComparisonType::NotEqual: return leftValue != rightValue;
+ case WorldStateExpressionComparisonType::Less: return leftValue < rightValue;
+ case WorldStateExpressionComparisonType::LessOrEqual: return leftValue <= rightValue;
+ case WorldStateExpressionComparisonType::Greater: return leftValue > rightValue;
+ case WorldStateExpressionComparisonType::GreaterOrEqual: return leftValue >= rightValue;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ConditionMgr::IsPlayerMeetingExpression(Player const* player, WorldStateExpressionEntry const* expression)
+{
+ ByteBuffer buffer = HexToBytes(expression->Expression);
+ if (buffer.empty())
+ return false;
+
+ bool enabled = buffer.read<bool>();
+ if (!enabled)
+ return false;
+
+ bool finalResult = EvalRelOp(buffer, player);
+ WorldStateExpressionLogic resultLogic = buffer.read<WorldStateExpressionLogic>();
+
+ while (resultLogic != WorldStateExpressionLogic::None)
+ {
+ bool secondResult = EvalRelOp(buffer, player);
+
+ switch (resultLogic)
+ {
+ case WorldStateExpressionLogic::And: finalResult = finalResult && secondResult; break;
+ case WorldStateExpressionLogic::Or: finalResult = finalResult || secondResult; break;
+ case WorldStateExpressionLogic::Xor: finalResult = finalResult != secondResult; break;
+ default:
+ break;
+ }
+
+ if (buffer.rpos() < buffer.size())
+ break;
+
+ resultLogic = buffer.read<WorldStateExpressionLogic>();
+ }
+
+ return finalResult;
+}
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 618931fa2cd..eab6c09b16f 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -32,6 +32,7 @@ class WorldObject;
class LootTemplate;
struct Condition;
struct PlayerConditionEntry;
+struct WorldStateExpressionEntry;
/*! Documentation on implementing a new ConditionType:
Step 1: Check for the lowest free ID. Look for CONDITION_UNUSED_XX in the enum.
@@ -286,6 +287,7 @@ class TC_GAME_API ConditionMgr
bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const;
static bool IsPlayerMeetingCondition(Player const* player, PlayerConditionEntry const* condition);
+ static bool IsPlayerMeetingExpression(Player const* player, WorldStateExpressionEntry const* expression);
struct ConditionTypeInfo
{
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index 7e5a4c66c71..63d1f7382ca 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -5558,4 +5558,18 @@ struct WorldSafeLocsLoadInfo
}
};
+struct WorldStateExpressionLoadInfo
+{
+ static DB2LoadInfo const* Instance()
+ {
+ static DB2FieldMeta const fields[] =
+ {
+ { false, FT_INT, "ID" },
+ { false, FT_STRING_NOT_LOCALIZED, "Expression" },
+ };
+ static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, WorldStateExpressionMeta::Instance(), HOTFIX_SEL_WORLD_STATE_EXPRESSION);
+ return &loadInfo;
+ }
+};
+
#endif // DB2LoadInfo_h__
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 6b5731d0bb9..9f933d962c3 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -275,6 +275,7 @@ DB2Storage<WMOAreaTableEntry> sWMOAreaTableStore("WMOAreaTable
DB2Storage<WorldEffectEntry> sWorldEffectStore("WorldEffect.db2", WorldEffectLoadInfo::Instance());
DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore("WorldMapOverlay.db2", WorldMapOverlayLoadInfo::Instance());
DB2Storage<WorldSafeLocsEntry> sWorldSafeLocsStore("WorldSafeLocs.db2", WorldSafeLocsLoadInfo::Instance());
+DB2Storage<WorldStateExpressionEntry> sWorldStateExpressionStore("WorldStateExpression.db2", WorldStateExpressionLoadInfo::Instance());
TaxiMask sTaxiNodesMask;
TaxiMask sOldContinentsNodesMask;
@@ -733,6 +734,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sWorldEffectStore);
LOAD_DB2(sWorldMapOverlayStore);
LOAD_DB2(sWorldSafeLocsStore);
+ LOAD_DB2(sWorldStateExpressionStore);
#undef LOAD_DB2
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 3d224c857cb..5fbe3b0737a 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -58,6 +58,7 @@ TC_GAME_API extern DB2Storage<BattlePetSpeciesEntry> sBattlePetSp
TC_GAME_API extern DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore;
TC_GAME_API extern DB2Storage<BattlemasterListEntry> sBattlemasterListStore;
TC_GAME_API extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore;
+TC_GAME_API extern DB2Storage<Cfg_RegionsEntry> sCfgRegionsStore;
TC_GAME_API extern DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore;
TC_GAME_API extern DB2Storage<CharTitlesEntry> sCharTitlesStore;
TC_GAME_API extern DB2Storage<ChatChannelsEntry> sChatChannelsStore;
@@ -210,6 +211,7 @@ TC_GAME_API extern DB2Storage<VehicleSeatEntry> sVehicleSeat
TC_GAME_API extern DB2Storage<WorldEffectEntry> sWorldEffectStore;
TC_GAME_API extern DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore;
TC_GAME_API extern DB2Storage<WorldSafeLocsEntry> sWorldSafeLocsStore;
+TC_GAME_API extern DB2Storage<WorldStateExpressionEntry> sWorldStateExpressionStore;
struct TaxiPathBySourceAndDestination
{
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 71958a94791..a9dac88860e 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -3272,5 +3272,11 @@ struct WorldSafeLocsEntry
float Facing;
};
+struct WorldStateExpressionEntry
+{
+ uint32 ID;
+ char const* Expression;
+};
+
#pragma pack(pop)
#endif
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index dd180cbdfd6..6bb6b4ebfa1 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -1177,4 +1177,84 @@ enum WorldMapTransformsFlags
WORLD_MAP_TRANSFORMS_FLAG_DUNGEON = 0x04
};
+enum class WorldStateExpressionValueType : uint8
+{
+ Constant = 1,
+ WorldState = 2,
+ Function = 3
+};
+
+enum class WorldStateExpressionLogic : uint8
+{
+ None = 0,
+ And = 1,
+ Or = 2,
+ Xor = 3,
+};
+
+enum class WorldStateExpressionComparisonType : uint8
+{
+ None = 0,
+ Equal = 1,
+ NotEqual = 2,
+ Less = 3,
+ LessOrEqual = 4,
+ Greater = 5,
+ GreaterOrEqual = 6,
+};
+
+enum class WorldStateExpressionOperatorType : uint8
+{
+ None = 0,
+ Sum = 1,
+ Substraction = 2,
+ Multiplication = 3,
+ Division = 4,
+ Remainder = 5,
+};
+
+enum WorldStateExpressionFunctions
+{
+ WSE_FUNCTION_NONE = 0,
+ WSE_FUNCTION_RANDOM,
+ WSE_FUNCTION_MONTH,
+ WSE_FUNCTION_DAY,
+ WSE_FUNCTION_TIME_OF_DAY,
+ WSE_FUNCTION_REGION,
+ WSE_FUNCTION_CLOCK_HOUR,
+ WSE_FUNCTION_OLD_DIFFICULTY_ID,
+ WSE_FUNCTION_HOLIDAY_START,
+ WSE_FUNCTION_HOLIDAY_LEFT,
+ WSE_FUNCTION_HOLIDAY_ACTIVE,
+ WSE_FUNCTION_TIMER_CURRENT_TIME,
+ WSE_FUNCTION_WEEK_NUMBER,
+ WSE_FUNCTION_UNK13,
+ WSE_FUNCTION_UNK14,
+ WSE_FUNCTION_DIFFICULTY_ID,
+ WSE_FUNCTION_WAR_MODE_ACTIVE,
+ WSE_FUNCTION_UNK17,
+ WSE_FUNCTION_UNK18,
+ WSE_FUNCTION_UNK19,
+ WSE_FUNCTION_UNK20,
+ WSE_FUNCTION_UNK21,
+ WSE_FUNCTION_WORLD_STATE_EXPRESSION,
+ WSE_FUNCTION_KEYSTONE_AFFIX,
+ WSE_FUNCTION_UNK24,
+ WSE_FUNCTION_UNK25,
+ WSE_FUNCTION_UNK26,
+ WSE_FUNCTION_UNK27,
+ WSE_FUNCTION_KEYSTONE_LEVEL,
+ WSE_FUNCTION_UNK29,
+ WSE_FUNCTION_UNK30,
+ WSE_FUNCTION_UNK31,
+ WSE_FUNCTION_UNK32,
+ WSE_FUNCTION_MERSENNE_RANDOM,
+ WSE_FUNCTION_UNK34,
+ WSE_FUNCTION_UNK35,
+ WSE_FUNCTION_UNK36,
+ WSE_FUNCTION_UI_WIDGET_DATA,
+
+ WSE_FUNCTION_MAX,
+};
+
#endif
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index ea3dc0021ca..879b7499e10 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -405,8 +405,8 @@ enum PlayerFlags
PLAYER_FLAGS_UNK7 = 0x00000080, // pre-3.0.3 PLAYER_FLAGS_FFA_PVP flag for FFA PVP state
PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards
PLAYER_FLAGS_IN_PVP = 0x00000200,
- PLAYER_FLAGS_HIDE_HELM = 0x00000400,
- PLAYER_FLAGS_HIDE_CLOAK = 0x00000800,
+ PLAYER_FLAGS_WAR_MODE_ACTIVE = 0x00000400,
+ PLAYER_FLAGS_WAR_MODE_DESIRED = 0x00000800,
PLAYER_FLAGS_PLAYED_LONG_TIME = 0x00001000, // played long time
PLAYER_FLAGS_PLAYED_TOO_LONG = 0x00002000, // played too long time
PLAYER_FLAGS_IS_OUT_OF_BOUNDS = 0x00004000,
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index 1739ef13eb9..981ac12d226 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -67,12 +67,6 @@ WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Fiel
if (atLoginFlags & AT_LOGIN_RESURRECT)
playerFlags &= ~PLAYER_FLAGS_GHOST;
- if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
- Flags |= CHARACTER_FLAG_HIDE_HELM;
-
- if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK)
- Flags |= CHARACTER_FLAG_HIDE_CLOAK;
-
if (playerFlags & PLAYER_FLAGS_GHOST)
Flags |= CHARACTER_FLAG_GHOST;
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index edd69688e0e..e7b1db5060f 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -43,6 +43,7 @@ EndScriptData */
#include "RBAC.h"
#include "SpellPackets.h"
#include "Transport.h"
+#include "World.h"
#include "WorldSession.h"
#include <fstream>
#include <limits>
@@ -102,6 +103,8 @@ public:
{ "raidreset", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleDebugRaidResetCommand, "" },
{ "neargraveyard", rbac::RBAC_PERM_COMMAND_NEARGRAVEYARD, false, &HandleDebugNearGraveyard, "" },
{ "conversation" , rbac::RBAC_PERM_COMMAND_DEBUG_CONVERSATION, false, &HandleDebugConversationCommand, "" },
+ { "worldstate" , rbac::RBAC_PERM_COMMAND_DEBUG, false, &HandleDebugWorldStateCommand, "" },
+ { "wsexpression" , rbac::RBAC_PERM_COMMAND_DEBUG, false, &HandleDebugWSExpressionCommand, "" },
};
static std::vector<ChatCommand> commandTable =
{
@@ -1299,6 +1302,72 @@ public:
return Conversation::CreateConversation(conversationEntry, target, *target, { target->GetGUID() }) != nullptr;
}
+
+ static bool HandleDebugWorldStateCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char const* worldStateIdStr = strtok((char*)args, " ");
+ char const* valueStr = args ? strtok(nullptr, " ") : nullptr;
+
+ if (!worldStateIdStr)
+ return false;
+
+ Player* target = handler->getSelectedPlayerOrSelf();
+
+ if (!target)
+ {
+ handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 worldStateId = atoi(worldStateIdStr);
+ uint32 value = valueStr ? atoi(valueStr) : 0;
+
+ if (value)
+ {
+ sWorld->setWorldState(worldStateId, value);
+ target->SendUpdateWorldState(worldStateId, value);
+ }
+ else
+ handler->PSendSysMessage("Worldstate %u actual value : %u", worldStateId, sWorld->getWorldState(worldStateId));
+
+ return true;
+ }
+
+ static bool HandleDebugWSExpressionCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char const* expressionIdStr = strtok((char*)args, " ");
+
+ if (!expressionIdStr)
+ return false;
+
+ uint32 expressionId = atoi(expressionIdStr);
+ Player* target = handler->getSelectedPlayerOrSelf();
+
+ if (!target)
+ {
+ handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ WorldStateExpressionEntry const* wsExpressionEntry = sWorldStateExpressionStore.LookupEntry(expressionId);
+ if (!wsExpressionEntry)
+ return false;
+
+ if (sConditionMgr->IsPlayerMeetingExpression(target, wsExpressionEntry))
+ handler->PSendSysMessage("Expression %u meet", expressionId);
+ else
+ handler->PSendSysMessage("Expression %u not meet", expressionId);
+
+ return true;
+ };
};
void AddSC_debug_commandscript()