mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/DataStores: Implemented WorldStateExpression
This commit is contained in:
10
sql/updates/hotfixes/master/2019_08_24_00_hotfixes.sql
Normal file
10
sql/updates/hotfixes/master/2019_08_24_00_hotfixes.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
--
|
||||
-- Table structure for table `world_state_expression`
|
||||
--
|
||||
DROP TABLE IF EXISTS `world_state_expression`;
|
||||
CREATE TABLE `world_state_expression` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Expression` text,
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -3272,5 +3272,11 @@ struct WorldSafeLocsEntry
|
||||
float Facing;
|
||||
};
|
||||
|
||||
struct WorldStateExpressionEntry
|
||||
{
|
||||
uint32 ID;
|
||||
char const* Expression;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user