Core/Battlegrounds: Move to scripts And a lot of misc commits i couldn't recover.
Port From (https://github.com/TrinityCore/TrinityCore/commit/d0d5d309bb5877dc2fcb27f6cb123707a31ec1e8)
This commit is contained in:
@@ -64,6 +64,11 @@ namespace BNetServer
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public bool UsesDevWildcardCertificate()
|
||||
{
|
||||
return certificate.Subject.Contains("*.*");
|
||||
}
|
||||
}
|
||||
|
||||
public class BnetServiceHandler
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace BNetServer.Networking
|
||||
|
||||
ChallengeExternalRequest externalChallenge = new();
|
||||
externalChallenge.PayloadType = "web_auth_url";
|
||||
externalChallenge.Payload = ByteString.CopyFromUtf8($"https://{Global.LoginService.GetHostnameForClient(GetRemoteIpAddress())}:{Global.LoginService.GetPort()}/bnetserver/login/");
|
||||
externalChallenge.Payload = ByteString.CopyFromUtf8($"http{(!Global.LoginServiceMgr.UsesDevWildcardCertificate() ? "s" : "")}://{Global.LoginService.GetHostnameForClient(GetRemoteIpAddress())}:{Global.LoginService.GetPort()}/bnetserver/login/");
|
||||
|
||||
SendRequest((uint)OriginalHash.ChallengeListener, 3, externalChallenge);
|
||||
return BattlenetRpcErrorCode.Ok;
|
||||
|
||||
@@ -16,7 +16,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BNetServer.Networking
|
||||
{
|
||||
public partial class Session : SSLSocket
|
||||
public partial class Session : SocketBase
|
||||
{
|
||||
AccountInfo accountInfo;
|
||||
GameAccountInfo gameAccountInfo;
|
||||
@@ -34,7 +34,7 @@ namespace BNetServer.Networking
|
||||
AsyncCallbackProcessor<QueryCallback> queryProcessor;
|
||||
Dictionary<uint, Action<CodedInputStream>> responseCallbacks;
|
||||
|
||||
public Session(Socket socket) : base(socket)
|
||||
public Session(Socket socket) : base(socket, true)
|
||||
{
|
||||
clientSecret = new byte[32];
|
||||
queryProcessor = new AsyncCallbackProcessor<QueryCallback>();
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace BNetServer.REST
|
||||
public BnetSRP6Base Srp;
|
||||
}
|
||||
|
||||
public class LoginHttpSession : SslSocket<LoginHttpSession>
|
||||
public class LoginHttpSession : BaseHttpSocket
|
||||
{
|
||||
public static string SESSION_ID_COOKIE = "JSESSIONID";
|
||||
|
||||
public LoginHttpSession(Socket socket) : base(socket) { }
|
||||
public LoginHttpSession(Socket socket) : base(socket, !Global.LoginServiceMgr.UsesDevWildcardCertificate()) { }
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
@@ -56,7 +56,10 @@ namespace BNetServer.REST
|
||||
}
|
||||
}
|
||||
|
||||
if (!Global.LoginServiceMgr.UsesDevWildcardCertificate())
|
||||
await AsyncHandshake(Global.LoginServiceMgr.GetCertificate());
|
||||
else
|
||||
await AsyncRead();
|
||||
}
|
||||
|
||||
public override RequestHandlerResult RequestHandler(RequestContext context)
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace BNetServer.REST
|
||||
RequestHandlerResult HandleGetForm(LoginHttpSession session, RequestContext context)
|
||||
{
|
||||
FormInputs form = _formInputs;
|
||||
form.SrpUrl = $"https://{GetHostnameForClient(session.GetRemoteIpAddress())}:{_port}/bnetserver/login/srp/";
|
||||
form.SrpUrl = $"http{(!Global.LoginServiceMgr.UsesDevWildcardCertificate() ? "s" : "")}://{GetHostnameForClient(session.GetRemoteIpAddress())}:{_port}/bnetserver/login/srp/";
|
||||
|
||||
context.response.ContentType = "application/json;charset=utf-8";
|
||||
context.response.Content = JsonSerializer.Serialize(form);
|
||||
|
||||
@@ -13,44 +13,28 @@ namespace Framework.Constants
|
||||
NotStarted = 0x00000005,
|
||||
InProgress = 0x00000006,
|
||||
InvalidArgs = 0x00000007,
|
||||
InvalidSubscriber = 0x00000008,
|
||||
WaitingForDependency = 0x00000009,
|
||||
NoAuth = 0x0000000a,
|
||||
ParentalControlRestriction = 0x0000000b,
|
||||
NoGameAccount = 0x0000000c,
|
||||
NotImplemented = 0x0000000d,
|
||||
ObjectRemoved = 0x0000000e,
|
||||
InvalidEntityId = 0x0000000f,
|
||||
InvalidEntityAccountId = 0x00000010,
|
||||
InvalidEntityGameAccountId = 0x00000011,
|
||||
InvalidAgentId = 0x00000013,
|
||||
InvalidTargetId = 0x00000014,
|
||||
ModuleNotLoaded = 0x00000015,
|
||||
ModuleNoEntryPoint = 0x00000016,
|
||||
ModuleSignatureIncorrect = 0x00000017,
|
||||
ModuleCreateFailed = 0x00000018,
|
||||
NoProgram = 0x00000019,
|
||||
ApiNotReady = 0x0000001b,
|
||||
BadVersion = 0x0000001c,
|
||||
AttributeTooManyAttributesSet = 0x0000001d,
|
||||
AttributeMaxSizeExceeded = 0x0000001e,
|
||||
AttributeQuotaExceeded = 0x0000001f,
|
||||
ServerPoolServerDisappeared = 0x00000020,
|
||||
ServerIsPrivate = 0x00000021,
|
||||
Disabled = 0x00000022,
|
||||
ModuleNotFound = 0x00000024,
|
||||
ServerBusy = 0x00000025,
|
||||
NoBattletag = 0x00000026,
|
||||
IncompleteProfanityFilters = 0x00000027,
|
||||
InvalidRegion = 0x00000028,
|
||||
ExistsAlready = 0x00000029,
|
||||
InvalidServerThumbprint = 0x0000002a,
|
||||
PhoneLock = 0x0000002b,
|
||||
Squelched = 0x0000002c,
|
||||
TargetOffline = 0x0000002d,
|
||||
BadServer = 0x0000002e,
|
||||
NoCookie = 0x0000002f,
|
||||
ExpiredCookie = 0x00000030,
|
||||
TokenNotFound = 0x00000031,
|
||||
GameAccountNoTime = 0x00000032,
|
||||
GameAccountNoPlan = 0x00000033,
|
||||
@@ -60,13 +44,17 @@ namespace Framework.Constants
|
||||
GameAccountCancelled = 0x00000037,
|
||||
GameAccountCreationDisabled = 0x00000038,
|
||||
GameAccountLocked = 0x00000039,
|
||||
|
||||
GameAccountPhoneLock = 0x0000003a,
|
||||
GameAccountBillingLock = 0x0000003b,
|
||||
SessionDuplicate = 0x0000003c,
|
||||
SessionDisconnected = 0x0000003d,
|
||||
SessionDataChanged = 0x0000003e,
|
||||
SessionUpdateFailed = 0x0000003f,
|
||||
SessionNotFound = 0x00000040,
|
||||
|
||||
SessionFreePlayNotSupported = 0x00000041,
|
||||
SessionSubscriptionAdded = 0x00000042,
|
||||
SessionConsumptionTimeAdded = 0x00000043,
|
||||
SessionTokenNotFound = 0x00000044,
|
||||
AdminKick = 0x00000046,
|
||||
UnplannedMaintenance = 0x00000047,
|
||||
PlannedMaintenance = 0x00000048,
|
||||
@@ -82,42 +70,29 @@ namespace Framework.Constants
|
||||
LocaleRestrictedKo = 0x00000053,
|
||||
LocaleRestrictedTw = 0x00000054,
|
||||
LocaleRestricted = 0x00000055,
|
||||
AccountNeedsMaintenance = 0x00000056,
|
||||
ModuleApiError = 0x00000057,
|
||||
ModuleBadCacheHandle = 0x00000058,
|
||||
ModuleAlreadyLoaded = 0x00000059,
|
||||
NetworkBlacklisted = 0x0000005a,
|
||||
NetworkBlocklisted = 0x0000005a,
|
||||
EventProcessorSlow = 0x0000005b,
|
||||
ServerShuttingDown = 0x0000005c,
|
||||
NetworkNotPrivileged = 0x0000005d,
|
||||
TooManyOutstandingRequests = 0x0000005e,
|
||||
NoAccountRegistered = 0x0000005f,
|
||||
BattlenetAccountBanned = 0x00000060,
|
||||
|
||||
OkDeprecated = 0x00000064,
|
||||
ServerInModeZombie = 0x00000065,
|
||||
AgentIsBlockingTarget = 0x00000066,
|
||||
TargetIsBlockingAgent = 0x00000067,
|
||||
FeatureUnavailable = 0x00000068,
|
||||
BrokenPromise = 0x00000069,
|
||||
UninitializedExpected = 0x0000006a,
|
||||
NoSslConnection = 0x0000006b,
|
||||
ServiceNotReady = 0x0000006e,
|
||||
|
||||
LogonModuleRequired = 0x000001f4,
|
||||
LogonModuleNotConfigured = 0x000001f5,
|
||||
LogonModuleTimeout = 0x000001f6,
|
||||
LogonAgreementRequired = 0x000001fe,
|
||||
LogonAgreementNotConfigured = 0x000001ff,
|
||||
|
||||
LogonInvalidServerProof = 0x00000208,
|
||||
LogonWebVerifyTimeout = 0x00000209,
|
||||
LogonInvalidAuthToken = 0x0000020a,
|
||||
|
||||
ChallengeSmsTooSoon = 0x00000258,
|
||||
ChallengeSmsThrottled = 0x00000259,
|
||||
ChallengeSmsTempOutage = 0x0000025a,
|
||||
ChallengeNoChallenge = 0x0000025b,
|
||||
ChallengeNotPicked = 0x0000025c,
|
||||
ChallengeAlreadyPicked = 0x0000025d,
|
||||
ChallengeInProgress = 0x0000025e,
|
||||
LogonTassadarRequestFailed = 0x0000020b,
|
||||
|
||||
ConfigFormatInvalid = 0x000002bc,
|
||||
ConfigNotFound = 0x000002bd,
|
||||
ConfigRetrieveFailed = 0x000002be,
|
||||
ConfigDumpFailed = 0x000002bf,
|
||||
|
||||
NetworkModuleBusy = 0x000003e8,
|
||||
NetworkModuleCantResolveAddress = 0x000003e9,
|
||||
@@ -136,12 +111,10 @@ namespace Framework.Constants
|
||||
NetworkModuleNoSslCommonNameForCertificate = 0x000003f6,
|
||||
NetworkModuleSslCommonNameDoesNotMatchRemoteEndpoint = 0x000003f7,
|
||||
NetworkModuleSocketClosed = 0x000003f8,
|
||||
NetworkModuleSslPeerIsNotRegisteredInCertbundle = 0x000003f9,
|
||||
NetworkModuleSslInitializeLowFirst = 0x000003fa,
|
||||
NetworkModuleSslCertBundleReadError = 0x000003fb,
|
||||
NetworkModuleNoCertBundle = 0x000003fc,
|
||||
NetworkModuleFailedToDownloadCertBundle = 0x000003fd,
|
||||
NetworkModuleNotReadyToRead = 0x000003fe,
|
||||
NetworkModuleSslCertChainValidationFailed = 0x000003ff,
|
||||
NetworkModuleNetworkDown = 0x00000401,
|
||||
NetworkModuleSslInitializationFailed = 0x00000402,
|
||||
|
||||
NetworkModuleOpensslX509Ok = 0x000004b0,
|
||||
NetworkModuleOpensslX509UnableToGetIssuerCert = 0x000004b1,
|
||||
@@ -183,6 +156,7 @@ namespace Framework.Constants
|
||||
NetworkModuleSchannelCannotFindInterface = 0x00000517,
|
||||
NetworkModuleSchannelInitFail = 0x00000518,
|
||||
NetworkModuleSchannelFunctionCallFail = 0x00000519,
|
||||
NetworkModuleSchannelHandshakeFailure = 0x0000051a,
|
||||
NetworkModuleSchannelX509UnableToGetIssuerCert = 0x00000546,
|
||||
NetworkModuleSchannelX509TimeInvalid = 0x00000547,
|
||||
NetworkModuleSchannelX509SignatureInvalid = 0x00000548,
|
||||
@@ -190,24 +164,31 @@ namespace Framework.Constants
|
||||
NetworkModuleSchannelX509SelfSignedLeafCertificate = 0x0000054a,
|
||||
NetworkModuleSchannelX509UnhandledError = 0x0000054b,
|
||||
NetworkModuleSchannelX509SelfSignedCertInChain = 0x0000054c,
|
||||
|
||||
WebsocketHandshake = 0x00000578,
|
||||
|
||||
NetworkModuleDurangoUnknown = 0x000005dc,
|
||||
NetworkModuleDurangoMalformedHostName = 0x000005dd,
|
||||
NetworkModuleDurangoInvalidConnectionResponse = 0x000005de,
|
||||
NetworkModuleDurangoInvalidCaCert = 0x000005df,
|
||||
NetworkModuleDarwinsslFunctionCallFail = 0x00000640,
|
||||
NetworkModuleDarwinsslX509NeverTrust = 0x00000672,
|
||||
NetworkModuleDarwinsslX509UnknownError = 0x00000676,
|
||||
NetworkModuleSceSslContextAllocateFailed = 0x000006a4,
|
||||
NetworkModuleSceSslConnectionAllocateFailed = 0x000006a5,
|
||||
NetworkModuleSceSslSetVerifyOptionFailed = 0x000006a6,
|
||||
NetworkModuleSceSslHandshakeFailed = 0x000006a7,
|
||||
|
||||
SdkMessageHandlerNotFound = 0x0000076c,
|
||||
SdkTassadarClientInvalidInput = 0x00000776,
|
||||
SdkTassadarServerError = 0x00000777,
|
||||
SdkTassadarServerMaintenance = 0x00000778,
|
||||
|
||||
RpcWriteFailed = 0x00000bb8,
|
||||
RpcServiceNotBound = 0x00000bb9,
|
||||
RpcTooManyRequests = 0x00000bba,
|
||||
RpcPeerUnknown = 0x00000bbb,
|
||||
RpcPeerUnavailable = 0x00000bbc,
|
||||
RpcPeerDisconnected = 0x00000bbd,
|
||||
RpcRequestTimedOut = 0x00000bbe,
|
||||
RpcConnectionTimedOut = 0x00000bbf,
|
||||
RpcMalformedResponse = 0x00000bc0,
|
||||
RpcAccessDenied = 0x00000bc1,
|
||||
RpcInvalidService = 0x00000bc2,
|
||||
RpcInvalidMethod = 0x00000bc3,
|
||||
RpcInvalidObject = 0x00000bc4,
|
||||
@@ -217,30 +198,25 @@ namespace Framework.Constants
|
||||
RpcServerError = 0x00000bc8,
|
||||
RpcShutdown = 0x00000bc9,
|
||||
RpcDisconnect = 0x00000bca,
|
||||
RpcDisconnectIdle = 0x00000bcb,
|
||||
RpcProtocolError = 0x00000bcc,
|
||||
RpcNotReady = 0x00000bcd,
|
||||
RpcForwardFailed = 0x00000bce,
|
||||
RpcEncryptionFailed = 0x00000bcf,
|
||||
RpcInvalidAddress = 0x00000bd0,
|
||||
RpcMethodDisabled = 0x00000bd1,
|
||||
RpcShardNotFound = 0x00000bd2,
|
||||
RpcInvalidConnectionId = 0x00000bd3,
|
||||
RpcNotConnected = 0x00000bd4,
|
||||
RpcInvalidConnectionState = 0x00000bd5,
|
||||
RpcServiceAlreadyRegistered = 0x00000bd6,
|
||||
RpcConnectionUnreachable = 0x00000bd7,
|
||||
RpcNoBufferSpace = 0x00000bd8,
|
||||
RpcHttpProbe = 0x00000bd9,
|
||||
RpcClientIdRequired = 0x00000bda,
|
||||
RpcConnectionReplaced = 0x00000bdb,
|
||||
RpcInvalidRoute = 0x00000bdc,
|
||||
|
||||
PresenceInvalidFieldId = 0x00000fa0,
|
||||
PresenceNoValidSubscribers = 0x00000fa1,
|
||||
PresenceAlreadySubscribed = 0x00000fa2,
|
||||
PresenceConsumerNotFound = 0x00000fa3,
|
||||
PresenceConsumerIsNull = 0x00000fa4,
|
||||
PresenceTemporaryOutage = 0x00000fa5,
|
||||
PresenceTooManySubscriptions = 0x00000fa6,
|
||||
PresenceSubscriptionCancelled = 0x00000fa7,
|
||||
PresenceRichPresenceParseError = 0x00000fa8,
|
||||
PresenceRichPresenceXmlError = 0x00000fa9,
|
||||
PresenceRichPresenceLoadError = 0x00000faa,
|
||||
PresenceNoRecord = 0x00000fab,
|
||||
PresenceNoChange = 0x00000fac,
|
||||
|
||||
FriendsTooManySentInvitations = 0x00001389,
|
||||
FriendsTooManyReceivedInvitations = 0x0000138a,
|
||||
@@ -248,7 +224,6 @@ namespace Framework.Constants
|
||||
FriendsFriendshipDoesNotExist = 0x0000138c,
|
||||
FriendsInvitationAlreadyExists = 0x0000138d,
|
||||
FriendsInvalidInvitation = 0x0000138e,
|
||||
FriendsAlreadySubscribed = 0x0000138f,
|
||||
FriendsAccountBlocked = 0x00001391,
|
||||
FriendsNotSubscribed = 0x00001392,
|
||||
FriendsInvalidRoleId = 0x00001393,
|
||||
@@ -257,11 +232,20 @@ namespace Framework.Constants
|
||||
FriendsUpdateFriendStateFailed = 0x00001396,
|
||||
FriendsInviteeAtMaxFriends = 0x00001397,
|
||||
FriendsInviterAtMaxFriends = 0x00001398,
|
||||
FriendsInviterIsBlockedByInvitee = 0x00001399,
|
||||
FriendsReceivedInvitationUndeliverable = 0x0000139a,
|
||||
FriendsMuted = 0x0000139b,
|
||||
FriendsReceivedInvitationIgnored = 0x0000139c,
|
||||
FriendsTransactionAlreadyExists = 0x0000139d,
|
||||
FriendsMergedFriendsAboveLimit = 0x0000139e,
|
||||
|
||||
PlatformStorageFileWriteDenied = 0x00001770,
|
||||
|
||||
WhisperUndeliverable = 0x00001b58,
|
||||
WhisperMaxSizeExceeded = 0x00001b59,
|
||||
WhisperAlreadyRegistered = 0x00001b5a,
|
||||
WhisperDropped = 0x00001b5b,
|
||||
WhisperQuotaExceeded = 0x00001b5c,
|
||||
|
||||
UserManagerAlreadyBlocked = 0x00001f40,
|
||||
UserManagerNotBlocked = 0x00001f41,
|
||||
@@ -275,73 +259,88 @@ namespace Framework.Constants
|
||||
UserManagerUnblockEntityFailed = 0x00001f51,
|
||||
UserManagerCannotBlockFriend = 0x00001f53,
|
||||
|
||||
SocialNetworkDbException = 0x00002328,
|
||||
SocialNetworkDenialFromProvider = 0x00002329,
|
||||
SocialNetworkInvalidSnsId = 0x0000232a,
|
||||
SocialNetworkCantSendToProvider = 0x0000232b,
|
||||
SocialNetworkExCommFailed = 0x0000232c,
|
||||
SocialNetworkDisabled = 0x0000232d,
|
||||
SocialNetworkMissingRequestParam = 0x0000232e,
|
||||
SocialNetworkUnsupportedOauthVersion = 0x0000232f,
|
||||
SocialNetworkOauthException = 0x00002328,
|
||||
SocialNetworkInvalidSnsId = 0x00002329,
|
||||
SocialNetworkCantSendToProvider = 0x0000232a,
|
||||
SocialNetworkDisabled = 0x0000232b,
|
||||
SocialNetworkMissingRequestParam = 0x0000232c,
|
||||
SocialNetworkNoAccountData = 0x0000232d,
|
||||
SocialNetworkNoToken = 0x0000232e,
|
||||
SocialNetworkMissingDataFromProvider = 0x0000232f,
|
||||
SocialNetworkResponseNotParsable = 0x00002330,
|
||||
SocialNetworkTokenPermissionDenied = 0x00002331,
|
||||
SocialNetworkDenialFromProvider = 0x00002332,
|
||||
|
||||
ChannelFull = 0x00002710,
|
||||
ChannelNoChannel = 0x00002711,
|
||||
ChannelNotMember = 0x00002712,
|
||||
ChannelAlreadyMember = 0x00002713,
|
||||
ChannelNoSuchMember = 0x00002714,
|
||||
ChannelInvalidChannelId = 0x00002716,
|
||||
ChannelNoSuchInvitation = 0x00002718,
|
||||
ChannelTooManyInvitations = 0x00002719,
|
||||
ChannelInvitationAlreadyExists = 0x0000271a,
|
||||
ChannelInvalidChannelSize = 0x0000271b,
|
||||
ChannelInvalidRoleId = 0x0000271c,
|
||||
ChannelRoleNotAssignable = 0x0000271d,
|
||||
ChannelInsufficientPrivileges = 0x0000271e,
|
||||
ChannelInsufficientPrivacyLevel = 0x0000271f,
|
||||
ChannelInvalidPrivacyLevel = 0x00002720,
|
||||
ChannelTooManyChannelsJoined = 0x00002721,
|
||||
ChannelInvitationAlreadySubscribed = 0x00002722,
|
||||
ChannelInvalidChannelDelegate = 0x00002723,
|
||||
ChannelSlotAlreadyReserved = 0x00002724,
|
||||
ChannelSlotNotReserved = 0x00002725,
|
||||
ChannelNoReservedSlotsAvailable = 0x00002726,
|
||||
ChannelInvalidRoleSet = 0x00002727,
|
||||
ChannelRequireFriendValidation = 0x00002728,
|
||||
ChannelMemberOffline = 0x00002729,
|
||||
ChannelReceivedTooManyInvitations = 0x0000272a,
|
||||
ChannelInvitationInvalidGameAccountSelected = 0x0000272b,
|
||||
ChannelUnreachable = 0x0000272c,
|
||||
ChannelInvitationNotSubscribed = 0x0000272d,
|
||||
ChannelInvalidMessageSize = 0x0000272e,
|
||||
ChannelMaxMessageSizeExceeded = 0x0000272f,
|
||||
ChannelConfigNotFound = 0x00002730,
|
||||
ChannelInvalidChannelType = 0x00002731,
|
||||
ChannelInvalidIndex = 0x00002732,
|
||||
ChannelMembershipNotSubscribed = 0x00002733,
|
||||
ChannelAlreadySubscribed = 0x00002734,
|
||||
|
||||
LocalStorageFileOpenError = 0x00002af8,
|
||||
LocalStorageFileCreateError = 0x00002af9,
|
||||
LocalStorageFileReadError = 0x00002afa,
|
||||
LocalStorageFileWriteError = 0x00002afb,
|
||||
LocalStorageFileDeleteError = 0x00002afc,
|
||||
LocalStorageFileCopyError = 0x00002afd,
|
||||
LocalStorageFileDecompressError = 0x00002afe,
|
||||
LocalStorageFileHashMismatch = 0x00002aff,
|
||||
LocalStorageFileUsageMismatch = 0x00002b00,
|
||||
LocalStorageDatabaseInitError = 0x00002b01,
|
||||
LocalStorageDatabaseNeedsRebuild = 0x00002b02,
|
||||
LocalStorageDatabaseInsertError = 0x00002b03,
|
||||
LocalStorageDatabaseLookupError = 0x00002b04,
|
||||
LocalStorageDatabaseUpdateError = 0x00002b05,
|
||||
LocalStorageDatabaseDeleteError = 0x00002b06,
|
||||
LocalStorageDatabaseShrinkError = 0x00002b07,
|
||||
LocalStorageCacheCrawlError = 0x00002b08,
|
||||
LocalStorageDatabaseIndexTriggerError = 0x00002b09,
|
||||
LocalStorageDatabaseRebuildInProgress = 0x00002b0a,
|
||||
LocalStorageOkButNotInCache = 0x00002b0b,
|
||||
LocalStorageDatabaseRebuildInterrupted = 0x00002b0d,
|
||||
LocalStorageDatabaseNotInitialized = 0x00002b0e,
|
||||
LocalStorageDirectoryCreateError = 0x00002b0f,
|
||||
LocalStorageFilekeyNotFound = 0x00002b10,
|
||||
LocalStorageNotAvailableOnServer = 0x00002b11,
|
||||
ClubFull = 0x00002af8,
|
||||
ClubNoClub = 0x00002af9,
|
||||
ClubNotMember = 0x00002afa,
|
||||
ClubAlreadyMember = 0x00002afb,
|
||||
ClubNoSuchMember = 0x00002afc,
|
||||
ClubNoSuchInvitation = 0x00002b00,
|
||||
ClubInvitationAlreadyExists = 0x00002b02,
|
||||
ClubInvalidRoleId = 0x00002b04,
|
||||
ClubInsufficientPrivileges = 0x00002b06,
|
||||
ClubInsufficientPrivacyLevel = 0x00002b07,
|
||||
ClubInvalidPrivacyLevel = 0x00002b08,
|
||||
ClubTooManyClubsJoined = 0x00002b09,
|
||||
ClubInvalidRoleSet = 0x00002b0f,
|
||||
ClubNotSubscribed = 0x00002b15,
|
||||
ClubInvalidClubType = 0x00002b19,
|
||||
ClubVoiceFull = 0x00002b1a,
|
||||
ClubMemberSubscriptionsAtMax = 0x00002b1b,
|
||||
ClubSuggestionAlreadyExists = 0x00002b20,
|
||||
ClubSuggestionCountAtMax = 0x00002b21,
|
||||
ClubNoSuchSuggestion = 0x00002b22,
|
||||
ClubStreamNoStream = 0x00002b5c,
|
||||
ClubStreamInvalidName = 0x00002b5d,
|
||||
ClubStreamCountAtMin = 0x00002b5e,
|
||||
ClubStreamCountAtMax = 0x00002b5f,
|
||||
ClubStreamInvalidVoiceLevel = 0x00002b60,
|
||||
ClubStreamNoSuchMessage = 0x00002b61,
|
||||
ClubInvalidAvatar = 0x00002b75,
|
||||
ClubMemberHasRequiredRole = 0x00002b76,
|
||||
ClubInvalidRoleChangeRequest = 0x00002b77,
|
||||
ClubSentInvitationCountAtMax = 0x00002b8e,
|
||||
ClubReceivedInvitationCountAtMax = 0x00002b8f,
|
||||
ClubTargetIsBanned = 0x00002b90,
|
||||
ClubNoSuchBannedTarget = 0x00002b91,
|
||||
ClubBanAlreadyExists = 0x00002b92,
|
||||
ClubBanCountAtMax = 0x00002b93,
|
||||
ClubTicketCountAtMax = 0x00002ba2,
|
||||
ClubTicketNoSuchTicket = 0x00002ba3,
|
||||
ClubTicketHasConsumedAllowedRedeemCount = 0x00002ba4,
|
||||
|
||||
ClubMembershipSubscriptionsAtMax = 0x00002e19,
|
||||
ClubMembershipPushNotificationRegistrationsAtMax = 0x00002e1a,
|
||||
ClubTagAlreadyExists = 0x00002e1b,
|
||||
ClubTagNoSuchTag = 0x00002e1c,
|
||||
ClubTagTooManyTags = 0x00002e1d,
|
||||
|
||||
RegistryCreateKeyError = 0x00002ee0,
|
||||
RegistryOpenKeyError = 0x00002ee1,
|
||||
@@ -351,18 +350,10 @@ namespace Framework.Constants
|
||||
RegistryDeleteError = 0x00002ee5,
|
||||
RegistryEncryptError = 0x00002ee6,
|
||||
RegistryDecryptError = 0x00002ee7,
|
||||
RegistryKeySizeError = 0x00002ee8,
|
||||
RegistryValueSizeError = 0x00002ee9,
|
||||
RegistryNotFound = 0x00002eeb,
|
||||
RegistryMalformedString = 0x00002eec,
|
||||
|
||||
InterfaceAlreadyConnected = 0x000032c8,
|
||||
InterfaceNotReady = 0x000032c9,
|
||||
InterfaceOptionKeyTooLarge = 0x000032ca,
|
||||
InterfaceOptionValueTooLarge = 0x000032cb,
|
||||
InterfaceOptionKeyInvalidUtf8String = 0x000032cc,
|
||||
InterfaceOptionValueInvalidUtf8String = 0x000032cd,
|
||||
|
||||
HttpCouldntResolve = 0x000036b0,
|
||||
HttpCouldntConnect = 0x000036b1,
|
||||
HttpTimeout = 0x000036b2,
|
||||
@@ -373,21 +364,55 @@ namespace Framework.Constants
|
||||
HttpTooManyRedirects = 0x000036b7,
|
||||
HttpCouldntOpenFile = 0x000036b8,
|
||||
HttpCouldntCreateFile = 0x000036b9,
|
||||
HttpCouldntReadFile = 0x000036ba,
|
||||
HttpCouldntRenameFile = 0x000036bb,
|
||||
HttpCouldntCreateDirectory = 0x000036bc,
|
||||
HttpCurlIsNotReady = 0x000036bd,
|
||||
HttpCancelled = 0x000036be,
|
||||
HttpCanceled = 0x000036be,
|
||||
HttpSendFailed = 0x000036bf,
|
||||
HttpRecvFailed = 0x000036c0,
|
||||
HttpMalformedReply = 0x000036c1,
|
||||
HttpAccessDenied = 0x000036c2,
|
||||
HttpMalformedPost = 0x000036c3,
|
||||
HttpInvalidCert = 0x000036c4,
|
||||
HttpInvalidCaCert = 0x000036c5,
|
||||
HttpSslConnectFailed = 0x000036c6,
|
||||
HttpProtocolFailed = 0x000036c7,
|
||||
|
||||
HttpFileNotFound = 0x00003844,
|
||||
|
||||
HttpOauth2DiscoveryFailed = 0x000038a5,
|
||||
HttpOauth2TokenRefreshFailed = 0x000038a6,
|
||||
HttpOauth2TokenStorageFailed = 0x000038a7,
|
||||
HttpOauth2TokenExchangeFailed = 0x000038a8,
|
||||
HttpOauth2InvalidContext = 0x000038a9,
|
||||
|
||||
AsterionGeneralRuntime = 0x00003a98,
|
||||
AsterionThrottled = 0x00003a99,
|
||||
AsterionShardNotFound = 0x00003a9a,
|
||||
AsterionInvalidParameter = 0x00003a9b,
|
||||
AsterionRemoteRegionUnavailable = 0x00003a9d,
|
||||
AsterionDeductRecordDuplicated = 0x00003a9f,
|
||||
AsterionDeductRecordMinimumGametime = 0x00003aa0,
|
||||
AsterionDeductRecordInvalidStopTime = 0x00003aa1,
|
||||
AsterionTimedOut = 0x00003aa2,
|
||||
AsterionTooManyOutstandingRequests = 0x00003aa3,
|
||||
AsterionDeductRecordAnotherInProgress = 0x00003aa4,
|
||||
|
||||
AsterionUnavailable = 0x00003e7f,
|
||||
|
||||
EventViewIsFull = 0x00003e80,
|
||||
|
||||
VoiceAccountNotFound = 0x00004268,
|
||||
VoiceTokenAlreadyUsed = 0x00004269,
|
||||
VoiceVersionNotSupported = 0x0000426a,
|
||||
VoiceInvalidVersion = 0x0000426b,
|
||||
VoiceSecretKeyStorageFailure = 0x0000426c,
|
||||
|
||||
AccountMissingConfig = 0x00004650,
|
||||
AccountDataNotFound = 0x00004651,
|
||||
AccountAlreadySubscribed = 0x00004652,
|
||||
AccountNotSubscribed = 0x00004653,
|
||||
AccountFailedToParseTimezoneData = 0x00004654,
|
||||
AccountLoadFailed = 0x00004655,
|
||||
AccountLoadCancelled = 0x00004656,
|
||||
AccountDatabaseInvalidateFailed = 0x00004657,
|
||||
AccountCacheInvalidateFailed = 0x00004658,
|
||||
AccountSubscriptionPending = 0x00004659,
|
||||
@@ -396,40 +421,20 @@ namespace Framework.Constants
|
||||
AccountUnderage = 0x0000465c,
|
||||
AccountIdentityCheckPending = 0x0000465d,
|
||||
AccountIdentityUnverified = 0x0000465e,
|
||||
|
||||
DatabaseBindingCountMismatch = 0x00004a38,
|
||||
DatabaseBindingParseFail = 0x00004a39,
|
||||
DatabaseResultsetColumnsMismatch = 0x00004a3a,
|
||||
DatabaseDeadlock = 0x00004a3b,
|
||||
DatabaseDuplicateKey = 0x00004a3c,
|
||||
DatabaseCannotConnect = 0x00004a3d,
|
||||
DatabaseStatementFailed = 0x00004a3e,
|
||||
DatabaseTransactionNotStarted = 0x00004a3f,
|
||||
DatabaseTransactionNotEnded = 0x00004a40,
|
||||
DatabaseTransactionLeak = 0x00004a41,
|
||||
DatabaseTransactionStateBad = 0x00004a42,
|
||||
DatabaseServerGone = 0x00004a43,
|
||||
DatabaseQueryTimeout = 0x00004a44,
|
||||
DatabaseBindingNotNullable = 0x00004a9c,
|
||||
DatabaseBindingInvalidInteger = 0x00004a9d,
|
||||
DatabaseBindingInvalidFloat = 0x00004a9e,
|
||||
DatabaseBindingInvalidTemporal = 0x00004a9f,
|
||||
DatabaseBindingInvalidProtobuf = 0x00004aa0,
|
||||
|
||||
PartyInvalidPartyId = 0x00004e20,
|
||||
PartyAlreadyInParty = 0x00004e21,
|
||||
PartyNotInParty = 0x00004e22,
|
||||
PartyInvitationUndeliverable = 0x00004e23,
|
||||
PartyInvitationAlreadyExists = 0x00004e24,
|
||||
PartyTooManyPartyInvitations = 0x00004e25,
|
||||
PartyTooManyReceivedInvitations = 0x00004e26,
|
||||
PartyNoSuchType = 0x00004e27,
|
||||
AccountIgr = 0x0000465f,
|
||||
GameAccountCreateNeedNationalId = 0x00004660,
|
||||
GameAccountCreateBlocked = 0x00004661,
|
||||
GameAccountDetached = 0x00004662,
|
||||
GameAccountCreateTooManyGameAccount = 0x00004663,
|
||||
SubscriberNoNeedToUpdate = 0x00004664,
|
||||
AccountMobileNumberRequired = 0x00004665,
|
||||
AccountMobileNumberAlreadyUsed = 0x00004666,
|
||||
AccountDataNotExistsInCache = 0x00004667,
|
||||
AccountInvalidIdentityData = 0x00004668,
|
||||
|
||||
GamesNoSuchFactory = 0x000055f0,
|
||||
GamesNoSuchGame = 0x000055f1,
|
||||
GamesNoSuchRequest = 0x000055f2,
|
||||
GamesNoSuchPartyMember = 0x000055f3,
|
||||
|
||||
ResourcesOffline = 0x000059d8,
|
||||
|
||||
GameServerCreateGameRefused = 0x00005dc0,
|
||||
@@ -453,11 +458,8 @@ namespace Framework.Constants
|
||||
GameMasterRegisterFailed = 0x000061ab,
|
||||
GameMasterNoGameServer = 0x000061ac,
|
||||
GameMasterNoUtilityServer = 0x000061ad,
|
||||
GameMasterNoGameVersion = 0x000061ae,
|
||||
GameMasterGameJoinFailed = 0x000061af,
|
||||
GameMasterAlreadyRegistered = 0x000061b0,
|
||||
GameMasterNoFactory = 0x000061b1,
|
||||
GameMasterMultipleGameVersions = 0x000061b2,
|
||||
GameMasterInvalidPlayer = 0x000061b3,
|
||||
GameMasterInvalidGameRequest = 0x000061b4,
|
||||
GameMasterInsufficientPrivileges = 0x000061b5,
|
||||
@@ -471,43 +473,50 @@ namespace Framework.Constants
|
||||
GameMasterInvalidTeamId = 0x000061bd,
|
||||
GameMasterCreationInProgress = 0x000061be,
|
||||
|
||||
NotificationInvalidClientId = 0x00006590,
|
||||
NotificationDuplicateName = 0x00006591,
|
||||
NotificationNameNotFound = 0x00006592,
|
||||
NotificationInvalidServer = 0x00006593,
|
||||
NotificationQuotaExceeded = 0x00006594,
|
||||
NotificationInvalidNotificationType = 0x00006595,
|
||||
NotificationUndeliverable = 0x00006596,
|
||||
NotificationUndeliverableTemporary = 0x00006597,
|
||||
|
||||
AchievementsNothingToUpdate = 0x00006d60,
|
||||
AchievementsInvalidParams = 0x00006d61,
|
||||
AchievementsNotRegistered = 0x00006d62,
|
||||
AchievementsNotReady = 0x00006d63,
|
||||
AchievementsFailedToParseStaticData = 0x00006d64,
|
||||
AchievementsUnknownId = 0x00006d65,
|
||||
AchievementsMissingSnapshot = 0x00006d66,
|
||||
AchievementsAlreadyRegistered = 0x00006d67,
|
||||
AchievementsTooManyRegistrations = 0x00006d68,
|
||||
AchievementsAlreadyInProgress = 0x00006d69,
|
||||
AchievementsTemporaryOutage = 0x00006d6a,
|
||||
AchievementsInvalidProgramid = 0x00006d6b,
|
||||
AchievementsMissingRecord = 0x00006d6c,
|
||||
AchievementsRegistrationPending = 0x00006d6d,
|
||||
AchievementsEntityIdNotFound = 0x00006d6e,
|
||||
AchievementsAchievementIdNotFound = 0x00006d6f,
|
||||
AchievementsCriteriaIdNotFound = 0x00006d70,
|
||||
AchievementsStaticDataMismatch = 0x00006d71,
|
||||
AchievementsWrongThread = 0x00006d72,
|
||||
AchievementsCallbackIsNull = 0x00006d73,
|
||||
AchievementsAutoRegisterPending = 0x00006d74,
|
||||
AchievementsNotInitialized = 0x00006d75,
|
||||
AchievementsAchievementIdAlreadyExists = 0x00006d76,
|
||||
AchievementsFailedToDownloadStaticData = 0x00006d77,
|
||||
AchievementsStaticDataNotFound = 0x00006d78,
|
||||
LeaderboardRuleNotFound = 0x00006d61,
|
||||
LeaderboardNotFound = 0x00006d62,
|
||||
LeaderboardInvalidEntityId = 0x00006d64,
|
||||
LeaderboardInvalidGameAccount = 0x00006d65,
|
||||
LeaderboardInvalidTimestamp = 0x00006d66,
|
||||
LeaderboardInvalidTags = 0x00006d67,
|
||||
LeaderboardInvalidPayload = 0x00006d69,
|
||||
LeaderboardInvalidTitleId = 0x00006d6a,
|
||||
LeaderboardInvalidRuleName = 0x00006d6b,
|
||||
LeaderboardInvalidRequest = 0x00006d6c,
|
||||
LeaderboardInvalidScores = 0x00006d6d,
|
||||
LeaderboardInvalidFieldFormat = 0x00006d6e,
|
||||
LeaderboardAccountNotFound = 0x00006d6f,
|
||||
LeaderboardRanksNotFound = 0x00006d70,
|
||||
LeaderboardInvalidBatchSubmitRanksRequest = 0x00006d71,
|
||||
|
||||
MatchmakingMatchmakerNotFound = 0x00007530,
|
||||
MatchmakingMatchmakerDecommissioned = 0x00007531,
|
||||
MatchmakingGameserverNotFound = 0x00007532,
|
||||
Matchmaking30003 = 0x00007533,
|
||||
MatchmakingMatchmakerAlreadyRegistered = 0x00007534,
|
||||
MatchmakingGameserverAlreadyRegistered = 0x00007535,
|
||||
MatchmakingRequestIdNotFound = 0x00007536,
|
||||
MatchmakingInsufficientPartyPrivileges = 0x00007537,
|
||||
MatchmakingEventQueueFull = 0x00007538,
|
||||
MatchmakingCancelNotAllowed = 0x00007539,
|
||||
MatchmakingPlayerNotConnected = 0x0000753a,
|
||||
MatchmakingEventCanceled = 0x0000753b,
|
||||
MatchmakingGameserverFull = 0x0000753c,
|
||||
MatchmakingInvalidResponse = 0x0000753d,
|
||||
MatchmakingMatchmakerInvalidConnection = 0x0000753e,
|
||||
|
||||
MatchmakingServerAlreadyInGame = 0x00007918,
|
||||
MatchmakingServerInvalidGame = 0x00007919,
|
||||
MatchmakingServerInvalidPlayer = 0x0000791a,
|
||||
MatchmakingServerGameFull = 0x0000791b,
|
||||
MatchmakingServerUnknownRequestId = 0x0000791c,
|
||||
|
||||
GameUtilityServerVariableRequestRefused = 0x000084d1,
|
||||
GameUtilityServerWrongNumberOfVariablesReturned = 0x000084d2,
|
||||
GameUtilityServerClientRequestRefused = 0x000084d3,
|
||||
GameUtilityServerPresenceChannelCreatedRefused = 0x000084d4,
|
||||
GameUtilityServerVariableRequestRefusedTransient = 0x00008502,
|
||||
@@ -518,31 +527,34 @@ namespace Framework.Constants
|
||||
GameUtilityServerClientRequestRefusedBusy = 0x00008535,
|
||||
GameUtilityServerPresenceChannelCreatedRefusedBusy = 0x00008536,
|
||||
GameUtilityServerServerRequestRefusedBusy = 0x00008537,
|
||||
|
||||
GameUtilityServerRequestRefused = 0x00008567,
|
||||
GameUtilityServerRequestRefusedBusy = 0x00008568,
|
||||
GameUtilityServerRequestRefusedTransient = 0x00008569,
|
||||
GameUtilityServerNoServer = 0x00008598,
|
||||
GameUtilityServerVersionMismatch = 0x0000859a,
|
||||
GameUtilityServerTimedOut = 0x0000859b,
|
||||
|
||||
IdentityInsufficientData = 0x0000a028,
|
||||
IdentityTooManyResults = 0x0000a029,
|
||||
IdentityBadId = 0x0000a02a,
|
||||
IdentityNoAccountBlob = 0x0000a02b,
|
||||
SessionAdminKick = 0x00009c44,
|
||||
SessionAbandoned = 0x00009c48,
|
||||
SessionCaisPlaytimeExceeded = 0x00009c4b,
|
||||
SessionCaisCurfew = 0x00009c4c,
|
||||
SessionInvalidNid = 0x00009c4e,
|
||||
SessionQueueDuplicated = 0x00009c4f,
|
||||
SessionQueueAdminKick = 0x00009c51,
|
||||
SessionKeyExpired = 0x00009c52,
|
||||
SessionTokenExpired = 0x00009c53,
|
||||
|
||||
RiskChallengeAction = 0x0000a410,
|
||||
RiskDelayAction = 0x0000a411,
|
||||
RiskThrottleAction = 0x0000a412,
|
||||
RiskAccountLocked = 0x0000a413,
|
||||
RiskCsDenied = 0x0000a414,
|
||||
RiskDisconnectAccount = 0x0000a415,
|
||||
RiskCheckSkipped = 0x0000a416,
|
||||
|
||||
ReportUnavailable = 0x0000afc8,
|
||||
ReportTooLarge = 0x0000afc9,
|
||||
ReportUnknownProgram = 0x0000afc9,
|
||||
ReportUnknownType = 0x0000afca,
|
||||
ReportAttributeInvalid = 0x0000afcb,
|
||||
ReportAttributeQuotaExceeded = 0x0000afcc,
|
||||
ReportUnconfirmed = 0x0000afcd,
|
||||
ReportNotConnected = 0x0000afce,
|
||||
ReportRejected = 0x0000afcf,
|
||||
ReportTooManyRequests = 0x0000afd0,
|
||||
|
||||
AccountAlreadyRegisterd = 0x0000bb80,
|
||||
AccountNotRegistered = 0x0000bb81,
|
||||
AccountRegistrationPending = 0x0000bb82,
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace Framework.Constants
|
||||
TrainerSpell = 31,
|
||||
ObjectIdVisibility = 32,
|
||||
SpawnGroup = 33,
|
||||
PlayerCondition = 34,
|
||||
|
||||
MaxDbAllowed,
|
||||
ReferenceCondition = MaxDbAllowed,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -369,16 +369,19 @@ namespace Framework.Constants
|
||||
RaceToRecipient = 29, // "%s's attempt to share quest "%s" failed. You are the wrong race for that quest."
|
||||
LowFaction = 30, // "%s's reputation is too low for that quest."
|
||||
LowFactionToRecipient = 31, // "%s's attempt to share quest "%s" failed. Your reputation is too low for that quest."
|
||||
Expansion = 32, // "%s doesn't own the required expansion for that quest."
|
||||
ExpansionToRecipient = 33, // "%s's attempt to share quest "%s" failed. You do not own the required expansion for that quest."
|
||||
NotGarrisonOwner = 34, // "%s must own a garrison to accept that quest."
|
||||
NotGarrisonOwnerToRecipient = 35, // "%s's attempt to share quest "%s" failed. You must own a garrison to accept that quest."
|
||||
WrongCovenant = 36, // "%s is in the wrong covenant for that quest."
|
||||
WrongCovenantToRecipient = 37, // "%s's attempt to share quest "%s" failed. You are in the wrong covenant for that quest."
|
||||
NewPlayerExperience = 38, // "%s must complete Exile's Reach to accept that quest."
|
||||
NewPlayerExperienceToRecipient = 39, // "%s's attempt to share quest "%s" failed. You must complete Exile's Reach to accept that quest."
|
||||
WrongFaction = 40, // "%s is the wrong faction for that quest."
|
||||
WrongFactionToRecipient = 41 // "%s's attempt to share quest "%s" failed. You are the wrong faction for that quest."
|
||||
HighFaction = 32, // "%s's reputation is too high for that quest."
|
||||
HighFactionToRecipient = 33, // "%s's attempt to share quest "%s" failed. Your reputation is too high for that quest."
|
||||
Expansion = 34, // "%s doesn't own the required expansion for that quest."
|
||||
ExpansionToRecipient = 35, // "%s's attempt to share quest "%s" failed. You do not own the required expansion for that quest."
|
||||
NotGarrisonOwner = 36, // "%s must own a garrison to accept that quest."
|
||||
NotGarrisonOwnerToRecipient = 37, // "%s's attempt to share quest "%s" failed. You must own a garrison to accept that quest."
|
||||
WrongCovenant = 38, // "%s is in the wrong covenant for that quest."
|
||||
WrongCovenantToRecipient = 39, // "%s's attempt to share quest "%s" failed. You are in the wrong covenant for that quest."
|
||||
NewPlayerExperience = 40, // "%s must complete Exile's Reach to accept that quest."
|
||||
NewPlayerExperienceToRecipient = 41, // "%s's attempt to share quest "%s" failed. You must complete Exile's Reach to accept that quest."
|
||||
WrongFaction = 42, // "%s is the wrong faction for that quest."
|
||||
WrongFactionToRecipient = 43, // "%s's attempt to share quest "%s" failed. You are the wrong faction for that quest."
|
||||
CrossFactionRestricted = 44, // "Quests can't be shared in cross-faction groups."
|
||||
}
|
||||
|
||||
public enum QuestTradeSkill
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,8 @@ namespace Framework.Database
|
||||
{
|
||||
// Achievement.db2
|
||||
PrepareStatement(HotfixStatements.SEL_ACHIEVEMENT, "SELECT Description, Title, Reward, ID, InstanceID, Faction, Supercedes, Category, MinimumCriteria, " +
|
||||
"Points, Flags, UiOrder, IconFileID, RewardItemID, CriteriaTree, SharesCriteria, CovenantID FROM achievement WHERE (`VerifiedBuild` > 0) = ?");
|
||||
"Points, Flags, UiOrder, IconFileID, RewardItemID, CriteriaTree, SharesCriteria, CovenantID, HiddenBeforeDisplaySeason, LegacyAfterTimeEvent" +
|
||||
" FROM achievement WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_ACHIEVEMENT_LOCALE, "SELECT ID, Description_lang, Title_lang, Reward_lang FROM achievement_locale" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
@@ -20,9 +21,9 @@ namespace Framework.Database
|
||||
|
||||
// AdventureJournal.db2
|
||||
PrepareStatement(HotfixStatements.SEL_ADVENTURE_JOURNAL, "SELECT ID, Name, Description, ButtonText, RewardDescription, ContinueDescription, Type, " +
|
||||
"PlayerConditionID, Flags, ButtonActionType, TextureFileDataID, LfgDungeonID, QuestID, BattleMasterListID, PriorityMin, PriorityMax, ItemID, " +
|
||||
"ItemQuantity, CurrencyType, CurrencyQuantity, UiMapID, BonusPlayerConditionID1, BonusPlayerConditionID2, BonusValue1, BonusValue2" +
|
||||
" FROM adventure_journal WHERE (`VerifiedBuild` > 0) = ?");
|
||||
"PlayerConditionID, Flags, ButtonActionType, TextureFileDataID, LfgDungeonID, QuestID, BattleMasterListID, PriorityMin, PriorityMax, " +
|
||||
"CurrencyType, CurrencyQuantity, UiMapID, BonusPlayerConditionID1, BonusPlayerConditionID2, BonusValue1, BonusValue2 FROM adventure_journal" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_ADVENTURE_JOURNAL_LOCALE, "SELECT ID, Name_lang, Description_lang, ButtonText_lang, RewardDescription_lang, " +
|
||||
"ContinueDescription_lang FROM adventure_journal_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
|
||||
@@ -296,6 +296,14 @@ namespace Framework.GameMath
|
||||
return v;
|
||||
}
|
||||
|
||||
public Vector3 extent()
|
||||
{
|
||||
if (Lo.IsEmpty())
|
||||
return Vector3.Zero;
|
||||
|
||||
return Hi - Lo;
|
||||
}
|
||||
|
||||
public static AxisAlignedBox operator +(AxisAlignedBox box, Vector3 v)
|
||||
{
|
||||
AxisAlignedBox outt = new();
|
||||
|
||||
@@ -210,6 +210,11 @@ namespace Framework.GameMath
|
||||
{
|
||||
return Vector3.Divide(Vector3.One, Direction);
|
||||
}
|
||||
|
||||
public Ray bumpedRay(float distance)
|
||||
{
|
||||
return new Ray(Origin + Direction * distance, Direction);
|
||||
}
|
||||
}
|
||||
|
||||
#region RayConverter class
|
||||
|
||||
@@ -618,8 +618,7 @@ namespace Framework.IO
|
||||
|
||||
if(strm==null||strm.state==null||dictionary==null) return Z_STREAM_ERROR;
|
||||
|
||||
deflate_state s=strm.state as deflate_state;
|
||||
if(s==null||s.wrap==2||(s.wrap==1&&s.status!=INIT_STATE))
|
||||
if (strm.state is not deflate_state s || s.wrap == 2 || (s.wrap == 1 && s.status != INIT_STATE))
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
if (s.wrap!=0) strm.adler=adler32(strm.adler, dictionary, dictLength);
|
||||
|
||||
@@ -6,6 +6,7 @@ using Framework.Database;
|
||||
using Framework.Web;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Framework.Networking.Http
|
||||
{
|
||||
@@ -20,9 +21,21 @@ namespace Framework.Networking.Http
|
||||
public Guid? GetSessionId();
|
||||
}
|
||||
|
||||
public abstract class BaseSocket<Derived> : SSLSocket, IAbstractSocket
|
||||
public abstract class BaseHttpSocket : SocketBase, IAbstractSocket
|
||||
{
|
||||
public BaseSocket(Socket socket) : base(socket) { }
|
||||
public BaseHttpSocket(Socket socket, bool useSSL = false) : base(socket, useSSL) { }
|
||||
|
||||
public async override Task HandshakeHandler(Exception exception = null)
|
||||
{
|
||||
if (exception != null)
|
||||
{
|
||||
Log.outError(LogFilter.Http, $"{GetClientInfo()} SSL Handshake failed {exception.Message}");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
await AsyncRead();
|
||||
}
|
||||
|
||||
public async override void ReadHandler(byte[] data, int receivedLength)
|
||||
{
|
||||
@@ -114,5 +127,6 @@ namespace Framework.Networking.Http
|
||||
|
||||
protected AsyncCallbackProcessor<QueryCallback> _queryProcessor = new();
|
||||
protected SessionState _state;
|
||||
protected ISocket socket;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Framework.Configuration;
|
||||
|
||||
namespace Framework.Networking.Http
|
||||
{
|
||||
public class SslSocket<Derived> : BaseSocket<Derived>
|
||||
{
|
||||
X509Certificate2 _certificate;
|
||||
|
||||
public SslSocket(Socket socket) : base(socket)
|
||||
{
|
||||
_certificate = new X509Certificate2(ConfigMgr.GetDefaultValue("CertificatesFile", "./BNetServer.pfx"));
|
||||
}
|
||||
|
||||
public async override void Start()
|
||||
{
|
||||
await AsyncHandshake(_certificate);
|
||||
}
|
||||
|
||||
public async override Task HandshakeHandler(Exception exception = null)
|
||||
{
|
||||
if (exception != null)
|
||||
{
|
||||
Log.outError(LogFilter.Http, $"{GetClientInfo()} SSL Handshake failed {exception.Message}");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
await AsyncRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Framework.Networking
|
||||
{
|
||||
public abstract class SSLSocket : ISocket, IDisposable
|
||||
{
|
||||
Socket _socket;
|
||||
internal SslStream _stream;
|
||||
IPEndPoint _remoteEndPoint;
|
||||
byte[] _receiveBuffer;
|
||||
|
||||
protected SSLSocket(Socket socket)
|
||||
{
|
||||
_socket = socket;
|
||||
_remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
|
||||
_receiveBuffer = new byte[ushort.MaxValue];
|
||||
|
||||
_stream = new SslStream(new NetworkStream(socket), false);
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_receiveBuffer = null;
|
||||
_stream.Dispose();
|
||||
}
|
||||
|
||||
public abstract void Start();
|
||||
|
||||
public virtual bool Update()
|
||||
{
|
||||
return _socket.Connected;
|
||||
}
|
||||
|
||||
public IPAddress GetRemoteIpAddress()
|
||||
{
|
||||
return _remoteEndPoint.Address;
|
||||
}
|
||||
|
||||
public async Task AsyncRead()
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length);
|
||||
if (result == 0)
|
||||
{
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadHandler(_receiveBuffer, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AsyncHandshake(X509Certificate2 certificate)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _stream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls12, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await HandshakeHandler(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
await HandshakeHandler();
|
||||
}
|
||||
|
||||
public abstract Task HandshakeHandler(Exception ex = null);
|
||||
|
||||
public abstract void ReadHandler(byte[] data, int receivedLength);
|
||||
|
||||
public async Task AsyncWrite(byte[] data)
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await _stream.WriteAsync(data, 0, data.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
_socket.Shutdown(SocketShutdown.Both);
|
||||
_socket.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WorldSocket.CloseSocket: {GetRemoteIpAddress()} errored when shutting down socket: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnClose() { Dispose(); }
|
||||
|
||||
public bool IsOpen() { return _socket.Connected; }
|
||||
|
||||
public void SetNoDelay(bool enable)
|
||||
{
|
||||
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, enable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,13 @@
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Framework.Networking
|
||||
{
|
||||
@@ -15,92 +20,126 @@ namespace Framework.Networking
|
||||
void CloseSocket();
|
||||
}
|
||||
|
||||
public delegate Task SocketReadCallback(byte[] data, int receivedLength);
|
||||
|
||||
public abstract class SocketBase : ISocket, IDisposable
|
||||
{
|
||||
Socket _socket;
|
||||
IPEndPoint _remoteIPEndPoint;
|
||||
Stream _stream;
|
||||
IPEndPoint _remoteEndPoint;
|
||||
byte[] _receiveBuffer;
|
||||
|
||||
SocketAsyncEventArgs receiveSocketAsyncEventArgsWithCallback;
|
||||
SocketAsyncEventArgs receiveSocketAsyncEventArgs;
|
||||
|
||||
public delegate void SocketReadCallback(SocketAsyncEventArgs args);
|
||||
|
||||
protected SocketBase(Socket socket)
|
||||
protected SocketBase(Socket socket, bool useSSL = false)
|
||||
{
|
||||
_socket = socket;
|
||||
_remoteIPEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
|
||||
_remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
|
||||
_receiveBuffer = new byte[ushort.MaxValue];
|
||||
|
||||
receiveSocketAsyncEventArgsWithCallback = new SocketAsyncEventArgs();
|
||||
receiveSocketAsyncEventArgsWithCallback.SetBuffer(new byte[0x4000], 0, 0x4000);
|
||||
|
||||
receiveSocketAsyncEventArgs = new SocketAsyncEventArgs();
|
||||
receiveSocketAsyncEventArgs.SetBuffer(new byte[0x4000], 0, 0x4000);
|
||||
receiveSocketAsyncEventArgs.Completed += (sender, args) => ProcessReadAsync(args);
|
||||
if (useSSL)
|
||||
_stream = new SslStream(new NetworkStream(socket), false);
|
||||
else
|
||||
_stream = new NetworkStream(socket);
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_socket.Dispose();
|
||||
_receiveBuffer = null;
|
||||
_stream.Dispose();
|
||||
}
|
||||
|
||||
public virtual void Start() { }
|
||||
public abstract void Start();
|
||||
|
||||
public virtual bool Update()
|
||||
{
|
||||
return IsOpen();
|
||||
}
|
||||
|
||||
public IPEndPoint GetRemoteIpAddress()
|
||||
public IPAddress GetRemoteIpAddress()
|
||||
{
|
||||
return _remoteIPEndPoint;
|
||||
return _remoteEndPoint.Address;
|
||||
}
|
||||
|
||||
public void AsyncReadWithCallback(SocketReadCallback callback)
|
||||
public IPEndPoint GetRemoteIpEndPoint()
|
||||
{
|
||||
return _remoteEndPoint;
|
||||
}
|
||||
|
||||
public async void AsyncReadWithCallback(SocketReadCallback callback)
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
receiveSocketAsyncEventArgsWithCallback.Completed += (sender, args) => callback(args);
|
||||
receiveSocketAsyncEventArgsWithCallback.SetBuffer(0, 0x4000);
|
||||
if (!_socket.ReceiveAsync(receiveSocketAsyncEventArgsWithCallback))
|
||||
callback(receiveSocketAsyncEventArgsWithCallback);
|
||||
}
|
||||
|
||||
public void AsyncRead()
|
||||
try
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
receiveSocketAsyncEventArgs.SetBuffer(0, 0x4000);
|
||||
if (!_socket.ReceiveAsync(receiveSocketAsyncEventArgs))
|
||||
ProcessReadAsync(receiveSocketAsyncEventArgs);
|
||||
}
|
||||
|
||||
void ProcessReadAsync(SocketAsyncEventArgs args)
|
||||
{
|
||||
if (args.SocketError != SocketError.Success)
|
||||
var result = await _stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length);
|
||||
if (result == 0)
|
||||
{
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.BytesTransferred == 0)
|
||||
await callback(_receiveBuffer, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AsyncRead()
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length);
|
||||
if (result == 0)
|
||||
{
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadHandler(args);
|
||||
ReadHandler(_receiveBuffer, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ReadHandler(SocketAsyncEventArgs args);
|
||||
public async Task AsyncHandshake(X509Certificate2 certificate)
|
||||
{
|
||||
try
|
||||
{
|
||||
await (_stream as SslStream).AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls12, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await HandshakeHandler(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
public void AsyncWrite(byte[] data)
|
||||
await HandshakeHandler();
|
||||
}
|
||||
|
||||
public virtual Task HandshakeHandler(Exception exception = null) { return null; }
|
||||
|
||||
public abstract void ReadHandler(byte[] data, int receivedLength);
|
||||
|
||||
public async Task AsyncWrite(byte[] data)
|
||||
{
|
||||
if (!IsOpen())
|
||||
return;
|
||||
|
||||
_socket.Send(data);
|
||||
try
|
||||
{
|
||||
await _stream.WriteAsync(data, 0, data.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.outException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseSocket()
|
||||
|
||||
@@ -300,6 +300,11 @@ namespace System
|
||||
return kZMat * (kYMat * kXMat);
|
||||
}
|
||||
|
||||
public static bool IsEmpty(this Vector3 vector3)
|
||||
{
|
||||
return float.IsNaN(vector3.X) || float.IsNaN(vector3.Y) || float.IsNaN(vector3.Z);
|
||||
}
|
||||
|
||||
#region Strings
|
||||
public static bool IsEmpty(this string str)
|
||||
{
|
||||
|
||||
@@ -506,13 +506,25 @@ namespace Game.Achievements
|
||||
//! Since no common attributes were found, (not even in titleRewardFlags field)
|
||||
//! we explicitly check by ID. Maybe in the future we could move the achievement_reward
|
||||
//! condition fields to the condition system.
|
||||
uint titleId = reward.TitleId[achievement.Id == 1793 ? (int)_owner.GetNativeGender() : (_owner.GetTeam() == Team.Alliance ? 0 : 1)];
|
||||
if (titleId != 0)
|
||||
uint titleId = 0;
|
||||
if (achievement.Id == 1793)
|
||||
titleId = reward.TitleId[(int)_owner.GetNativeGender()];
|
||||
else
|
||||
{
|
||||
CharTitlesRecord titleEntry = CliDB.CharTitlesStorage.LookupByKey(titleId);
|
||||
switch (_owner.GetTeam())
|
||||
{
|
||||
case Team.Alliance:
|
||||
titleId = reward.TitleId[0];
|
||||
break;
|
||||
case Team.Horde:
|
||||
titleId = reward.TitleId[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var titleEntry = CliDB.CharTitlesStorage.LookupByKey(titleId);
|
||||
if (titleEntry != null)
|
||||
_owner.SetTitle(titleEntry);
|
||||
}
|
||||
|
||||
// mail
|
||||
if (reward.SenderCreatureId != 0)
|
||||
|
||||
@@ -1254,8 +1254,7 @@ namespace Game.Achievements
|
||||
}
|
||||
case ModifierTreeType.PlayerMeetsCondition: // 2
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(reqValue);
|
||||
if (playerCondition == null || !ConditionManager.IsPlayerMeetingCondition(referencePlayer, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(referencePlayer, reqValue))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -1520,8 +1519,7 @@ namespace Game.Achievements
|
||||
if (refe == null || !refe.IsPlayer())
|
||||
return false;
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(reqValue);
|
||||
if (playerCondition == null || !ConditionManager.IsPlayerMeetingCondition(refe.ToPlayer(), playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(refe.ToPlayer(), reqValue))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Game.Arenas
|
||||
{
|
||||
// if the player was a match participant, calculate rating
|
||||
|
||||
ArenaTeam winnerArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(bgPlayer.Team)));
|
||||
ArenaTeam winnerArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(SharedConst.GetOtherTeam(bgPlayer.Team)));
|
||||
ArenaTeam loserArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(bgPlayer.Team));
|
||||
|
||||
// left a rated match while the encounter was in progress, consider as loser
|
||||
@@ -110,9 +110,9 @@ namespace Game.Arenas
|
||||
{
|
||||
Player player = _GetPlayer(guid, bgPlayer.OfflineRemoveTime != 0, "Arena.RemovePlayerAtLeave");
|
||||
if (player != null)
|
||||
loserArenaTeam.MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(bgPlayer.Team)));
|
||||
loserArenaTeam.MemberLost(player, GetArenaMatchmakerRating(SharedConst.GetOtherTeam(bgPlayer.Team)));
|
||||
else
|
||||
loserArenaTeam.OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(bgPlayer.Team)));
|
||||
loserArenaTeam.OfflineMemberLost(guid, GetArenaMatchmakerRating(SharedConst.GetOtherTeam(bgPlayer.Team)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,14 +147,14 @@ namespace Game.Arenas
|
||||
// In case of arena draw, follow this logic:
|
||||
// winnerArenaTeam => ALLIANCE, loserArenaTeam => HORDE
|
||||
ArenaTeam winnerArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(winner == Team.Other ? Team.Alliance : winner));
|
||||
ArenaTeam loserArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(winner == Team.Other ? Team.Horde : GetOtherTeam(winner)));
|
||||
ArenaTeam loserArenaTeam = Global.ArenaTeamMgr.GetArenaTeamById(GetArenaTeamIdForTeam(winner == Team.Other ? Team.Horde : SharedConst.GetOtherTeam(winner)));
|
||||
|
||||
if (winnerArenaTeam != null && loserArenaTeam != null && winnerArenaTeam != loserArenaTeam)
|
||||
{
|
||||
// In case of arena draw, follow this logic:
|
||||
// winnerMatchmakerRating => ALLIANCE, loserMatchmakerRating => HORDE
|
||||
loserTeamRating = loserArenaTeam.GetRating();
|
||||
loserMatchmakerRating = GetArenaMatchmakerRating(winner == Team.Other ? Team.Horde : GetOtherTeam(winner));
|
||||
loserMatchmakerRating = GetArenaMatchmakerRating(winner == Team.Other ? Team.Horde : SharedConst.GetOtherTeam(winner));
|
||||
winnerTeamRating = winnerArenaTeam.GetRating();
|
||||
winnerMatchmakerRating = GetArenaMatchmakerRating(winner == Team.Other ? Team.Alliance : winner);
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Game.Arenas
|
||||
loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange);
|
||||
|
||||
SetArenaMatchmakerRating(winner, (uint)(winnerMatchmakerRating + winnerMatchmakerChange));
|
||||
SetArenaMatchmakerRating(GetOtherTeam(winner), (uint)(loserMatchmakerRating + loserMatchmakerChange));
|
||||
SetArenaMatchmakerRating(SharedConst.GetOtherTeam(winner), (uint)(loserMatchmakerRating + loserMatchmakerChange));
|
||||
|
||||
// bg team that the client expects is different to TeamId
|
||||
// alliance 1, horde 0
|
||||
@@ -176,7 +176,7 @@ namespace Game.Arenas
|
||||
byte loserTeam = (byte)(winner == Team.Alliance ? PvPTeamId.Horde : PvPTeamId.Alliance);
|
||||
|
||||
_arenaTeamScores[winnerTeam].Assign(winnerTeamRating, (uint)(winnerTeamRating + winnerChange), winnerMatchmakerRating, GetArenaMatchmakerRating(winner));
|
||||
_arenaTeamScores[loserTeam].Assign(loserTeamRating, (uint)(loserTeamRating + loserChange), loserMatchmakerRating, GetArenaMatchmakerRating(GetOtherTeam(winner)));
|
||||
_arenaTeamScores[loserTeam].Assign(loserTeamRating, (uint)(loserTeamRating + loserChange), loserMatchmakerRating, GetArenaMatchmakerRating(SharedConst.GetOtherTeam(winner)));
|
||||
|
||||
Log.outDebug(LogFilter.Arena, "Arena match Type: {0} for Team1Id: {1} - Team2Id: {2} ended. WinnerTeamId: {3}. Winner rating: +{4}, Loser rating: {5}",
|
||||
GetArenaType(), GetArenaTeamIdByIndex(BattleGroundTeamId.Alliance), GetArenaTeamIdByIndex(BattleGroundTeamId.Horde), winnerArenaTeam.GetId(), winnerChange, loserChange);
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.BattleGrounds;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
public class BladesEdgeArena : Arena
|
||||
{
|
||||
public BladesEdgeArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
taskScheduler.Update(diff);
|
||||
}
|
||||
|
||||
public override void StartingEventCloseDoors()
|
||||
{
|
||||
for (int i = BladeEdgeObjectTypes.Door1; i <= BladeEdgeObjectTypes.Door4; ++i)
|
||||
SpawnBGObject(i, BattlegroundConst.RespawnImmediately);
|
||||
|
||||
for (int i = BladeEdgeObjectTypes.Buff1; i <= BladeEdgeObjectTypes.Buff2; ++i)
|
||||
SpawnBGObject(i, BattlegroundConst.RespawnOneDay);
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
for (int i = BladeEdgeObjectTypes.Door1; i <= BladeEdgeObjectTypes.Door4; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
taskScheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
for (int i = BladeEdgeObjectTypes.Door1; i <= BladeEdgeObjectTypes.Door2; ++i)
|
||||
DelObject(i);
|
||||
});
|
||||
|
||||
for (int i = BladeEdgeObjectTypes.Buff1; i <= BladeEdgeObjectTypes.Buff2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
bool result = true;
|
||||
result &= AddObject(BladeEdgeObjectTypes.Door1, BladeEfgeGameObjects.Door1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(BladeEdgeObjectTypes.Door2, BladeEfgeGameObjects.Door2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(BladeEdgeObjectTypes.Door3, BladeEfgeGameObjects.Door3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(BladeEdgeObjectTypes.Door4, BladeEfgeGameObjects.Door4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, BattlegroundConst.RespawnImmediately);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "BatteGroundBE: Failed to spawn door object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(BladeEdgeObjectTypes.Buff1, BladeEfgeGameObjects.Buff1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120);
|
||||
result &= AddObject(BladeEdgeObjectTypes.Buff2, BladeEfgeGameObjects.Buff2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "BladesEdgeArena: Failed to spawn buff object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct BladeEdgeObjectTypes
|
||||
{
|
||||
public const int Door1 = 0;
|
||||
public const int Door2 = 1;
|
||||
public const int Door3 = 2;
|
||||
public const int Door4 = 3;
|
||||
public const int Buff1 = 4;
|
||||
public const int Buff2 = 5;
|
||||
public const int Max = 6;
|
||||
}
|
||||
|
||||
struct BladeEfgeGameObjects
|
||||
{
|
||||
public const uint Door1 = 183971;
|
||||
public const uint Door2 = 183973;
|
||||
public const uint Door3 = 183970;
|
||||
public const uint Door4 = 183972;
|
||||
public const uint Buff1 = 184663;
|
||||
public const uint Buff2 = 184664;
|
||||
}
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.Dynamic;
|
||||
using Game.BattleGrounds;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
class DalaranSewersArena : Arena
|
||||
{
|
||||
uint _pipeKnockBackTimer;
|
||||
uint _pipeKnockBackCount;
|
||||
|
||||
public DalaranSewersArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate)
|
||||
{
|
||||
_events = new EventMap();
|
||||
}
|
||||
|
||||
public override void StartingEventCloseDoors()
|
||||
{
|
||||
for (int i = DalaranSewersObjectTypes.Door1; i <= DalaranSewersObjectTypes.Door2; ++i)
|
||||
SpawnBGObject(i, BattlegroundConst.RespawnImmediately);
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
for (int i = DalaranSewersObjectTypes.Door1; i <= DalaranSewersObjectTypes.Door2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (int i = DalaranSewersObjectTypes.Buff1; i <= DalaranSewersObjectTypes.Buff2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
_events.ScheduleEvent(DalaranSewersEvents.WaterfallWarning, DalaranSewersData.WaterfallTimerMin, DalaranSewersData.WaterfallTimerMax);
|
||||
//_events.ScheduleEvent(DalaranSewersEvents.PipeKnockback, DalaranSewersData.PipeKnockbackFirstDelay);
|
||||
|
||||
_pipeKnockBackCount = 0;
|
||||
_pipeKnockBackTimer = DalaranSewersData.PipeKnockbackFirstDelay;
|
||||
|
||||
SpawnBGObject(DalaranSewersObjectTypes.Water2, BattlegroundConst.RespawnImmediately);
|
||||
|
||||
DoorOpen(DalaranSewersObjectTypes.Water1); // Turn off collision
|
||||
DoorOpen(DalaranSewersObjectTypes.Water2);
|
||||
|
||||
// Remove effects of Demonic Circle Summon
|
||||
foreach (var pair in GetPlayers())
|
||||
{
|
||||
Player player = _GetPlayer(pair, "BattlegroundDS::StartingEventOpenDoors");
|
||||
if (player != null)
|
||||
player.RemoveAurasDueToSpell(DalaranSewersSpells.DemonicCircle);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
bool result = true;
|
||||
result &= AddObject(DalaranSewersObjectTypes.Door1, DalaranSewersGameObjects.Door1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(DalaranSewersObjectTypes.Door2, DalaranSewersGameObjects.Door2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, BattlegroundConst.RespawnImmediately);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "DalaranSewersArena: Failed to spawn door object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// buffs
|
||||
result &= AddObject(DalaranSewersObjectTypes.Buff1, DalaranSewersGameObjects.Buff1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f, 120);
|
||||
result &= AddObject(DalaranSewersObjectTypes.Buff2, DalaranSewersGameObjects.Buff2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f, 120);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "DalaranSewersArena: Failed to spawn buff object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(DalaranSewersObjectTypes.Water1, DalaranSewersGameObjects.Water1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120);
|
||||
result &= AddObject(DalaranSewersObjectTypes.Water2, DalaranSewersGameObjects.Water2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120);
|
||||
result &= AddCreature(DalaranSewersData.NpcWaterSpout, DalaranSewersCreatureTypes.WaterfallKnockback, 1292.587f, 790.2205f, 7.19796f, 3.054326f, BattleGroundTeamId.Neutral, BattlegroundConst.RespawnImmediately) != null;
|
||||
result &= AddCreature(DalaranSewersData.NpcWaterSpout, DalaranSewersCreatureTypes.PipeKnockback1, 1369.977f, 817.2882f, 16.08718f, 3.106686f, BattleGroundTeamId.Neutral, BattlegroundConst.RespawnImmediately) != null;
|
||||
result &= AddCreature(DalaranSewersData.NpcWaterSpout, DalaranSewersCreatureTypes.PipeKnockback2, 1212.833f, 765.3871f, 16.09484f, 0.0f, BattleGroundTeamId.Neutral, BattlegroundConst.RespawnImmediately) != null;
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "DalaranSewersArena: Failed to spawn collision object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case DalaranSewersEvents.WaterfallWarning:
|
||||
// Add the water
|
||||
DoorClose(DalaranSewersObjectTypes.Water2);
|
||||
_events.ScheduleEvent(DalaranSewersEvents.WaterfallOn, DalaranSewersData.WaterWarningDuration);
|
||||
break;
|
||||
case DalaranSewersEvents.WaterfallOn:
|
||||
// Active collision and start knockback timer
|
||||
DoorClose(DalaranSewersObjectTypes.Water1);
|
||||
_events.ScheduleEvent(DalaranSewersEvents.WaterfallOff, DalaranSewersData.WaterfallDuration);
|
||||
_events.ScheduleEvent(DalaranSewersEvents.WaterfallKnockback, DalaranSewersData.WaterfallKnockbackTimer);
|
||||
break;
|
||||
case DalaranSewersEvents.WaterfallOff:
|
||||
// Remove collision and water
|
||||
DoorOpen(DalaranSewersObjectTypes.Water1);
|
||||
DoorOpen(DalaranSewersObjectTypes.Water2);
|
||||
_events.CancelEvent(DalaranSewersEvents.WaterfallKnockback);
|
||||
_events.ScheduleEvent(DalaranSewersEvents.WaterfallWarning, DalaranSewersData.WaterfallTimerMin, DalaranSewersData.WaterfallTimerMax);
|
||||
break;
|
||||
case DalaranSewersEvents.WaterfallKnockback:
|
||||
{
|
||||
// Repeat knockback while the waterfall still active
|
||||
Creature waterSpout = GetBGCreature(DalaranSewersCreatureTypes.WaterfallKnockback);
|
||||
if (waterSpout != null)
|
||||
waterSpout.CastSpell(waterSpout, DalaranSewersSpells.WaterSpout, true);
|
||||
_events.ScheduleEvent(eventId, DalaranSewersData.WaterfallKnockbackTimer);
|
||||
}
|
||||
break;
|
||||
case DalaranSewersEvents.PipeKnockback:
|
||||
{
|
||||
for (uint i = DalaranSewersCreatureTypes.PipeKnockback1; i <= DalaranSewersCreatureTypes.PipeKnockback2; ++i)
|
||||
{
|
||||
Creature waterSpout = GetBGCreature(i);
|
||||
if (waterSpout != null)
|
||||
waterSpout.CastSpell(waterSpout, DalaranSewersSpells.Flush, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (_pipeKnockBackCount < DalaranSewersData.PipeKnockbackTotalCount)
|
||||
{
|
||||
if (_pipeKnockBackTimer < diff)
|
||||
{
|
||||
for (uint i = DalaranSewersCreatureTypes.PipeKnockback1; i <= DalaranSewersCreatureTypes.PipeKnockback2; ++i)
|
||||
{
|
||||
Creature waterSpout = GetBGCreature(i);
|
||||
if (waterSpout != null)
|
||||
waterSpout.CastSpell(waterSpout, DalaranSewersSpells.Flush, true);
|
||||
}
|
||||
|
||||
++_pipeKnockBackCount;
|
||||
_pipeKnockBackTimer = DalaranSewersData.PipeKnockbackDelay;
|
||||
}
|
||||
else
|
||||
_pipeKnockBackTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint dataId, uint value)
|
||||
{
|
||||
base.SetData(dataId, value);
|
||||
if (dataId == DalaranSewersData.PipeKnockbackCount)
|
||||
_pipeKnockBackCount = value;
|
||||
}
|
||||
|
||||
public override uint GetData(uint dataId)
|
||||
{
|
||||
if (dataId == DalaranSewersData.PipeKnockbackCount)
|
||||
return _pipeKnockBackCount;
|
||||
|
||||
return base.GetData(dataId);
|
||||
}
|
||||
}
|
||||
|
||||
struct DalaranSewersEvents
|
||||
{
|
||||
public const int WaterfallWarning = 1; // Water starting to fall, but no LoS Blocking nor movement blocking
|
||||
public const uint WaterfallOn = 2; // LoS and Movement blocking active
|
||||
public const uint WaterfallOff = 3;
|
||||
public const uint WaterfallKnockback = 4;
|
||||
|
||||
public const uint PipeKnockback = 5;
|
||||
}
|
||||
|
||||
struct DalaranSewersObjectTypes
|
||||
{
|
||||
public const int Door1 = 0;
|
||||
public const int Door2 = 1;
|
||||
public const int Water1 = 2; // Collision
|
||||
public const int Water2 = 3;
|
||||
public const int Buff1 = 4;
|
||||
public const int Buff2 = 5;
|
||||
public const int Max = 6;
|
||||
}
|
||||
|
||||
struct DalaranSewersGameObjects
|
||||
{
|
||||
public const uint Door1 = 192642;
|
||||
public const uint Door2 = 192643;
|
||||
public const uint Water1 = 194395; // Collision
|
||||
public const uint Water2 = 191877;
|
||||
public const uint Buff1 = 184663;
|
||||
public const uint Buff2 = 184664;
|
||||
}
|
||||
|
||||
struct DalaranSewersCreatureTypes
|
||||
{
|
||||
public const int WaterfallKnockback = 0;
|
||||
public const int PipeKnockback1 = 1;
|
||||
public const int PipeKnockback2 = 2;
|
||||
public const int Max = 3;
|
||||
}
|
||||
|
||||
struct DalaranSewersData
|
||||
{
|
||||
// These values are NOT blizzlike... need the correct data!
|
||||
public static TimeSpan WaterfallTimerMin = TimeSpan.FromSeconds(30);
|
||||
public static TimeSpan WaterfallTimerMax = TimeSpan.FromSeconds(60);
|
||||
public static TimeSpan WaterWarningDuration = TimeSpan.FromSeconds(5);
|
||||
public static TimeSpan WaterfallDuration = TimeSpan.FromSeconds(30);
|
||||
public static TimeSpan WaterfallKnockbackTimer = TimeSpan.FromSeconds(1.5);
|
||||
|
||||
public static uint PipeKnockbackFirstDelay = 5000;
|
||||
public static uint PipeKnockbackDelay = 3000;
|
||||
public const uint PipeKnockbackTotalCount = 2;
|
||||
public const uint PipeKnockbackCount = 1;
|
||||
|
||||
public const uint NpcWaterSpout = 28567;
|
||||
}
|
||||
|
||||
struct DalaranSewersSpells
|
||||
{
|
||||
public const uint Flush = 57405; // Visual And Target Selector For The Starting Knockback From The Pipe
|
||||
public const uint FlushKnockback = 61698; // Knockback Effect For Previous Spell (Triggered, Not Needed To Be Cast)
|
||||
public const uint WaterSpout = 58873; // Knockback Effect Of The Central Waterfall
|
||||
|
||||
public const uint DemonicCircle = 48018; // Demonic Circle Summon
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.BattleGrounds;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
public class NagrandArena : Arena
|
||||
{
|
||||
public NagrandArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
taskScheduler.Update(diff);
|
||||
}
|
||||
|
||||
public override void StartingEventCloseDoors()
|
||||
{
|
||||
for (int i = NagrandArenaObjectTypes.Door1; i <= NagrandArenaObjectTypes.Door4; ++i)
|
||||
SpawnBGObject(i, BattlegroundConst.RespawnImmediately);
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
for (int i = NagrandArenaObjectTypes.Door1; i <= NagrandArenaObjectTypes.Door4; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
taskScheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
for (int i = NagrandArenaObjectTypes.Door1; i <= NagrandArenaObjectTypes.Door2; ++i)
|
||||
DelObject(i);
|
||||
});
|
||||
|
||||
for (int i = NagrandArenaObjectTypes.Buff1; i <= NagrandArenaObjectTypes.Buff2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
bool result = true;
|
||||
result &= AddObject(NagrandArenaObjectTypes.Door1, NagrandArenaObjects.Door1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(NagrandArenaObjectTypes.Door2, NagrandArenaObjects.Door2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(NagrandArenaObjectTypes.Door3, NagrandArenaObjects.Door3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, BattlegroundConst.RespawnImmediately);
|
||||
result &= AddObject(NagrandArenaObjectTypes.Door4, NagrandArenaObjects.Door4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, BattlegroundConst.RespawnImmediately);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "NagrandArena: Failed to spawn door object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(NagrandArenaObjectTypes.Buff1, NagrandArenaObjects.Buff1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120);
|
||||
result &= AddObject(NagrandArenaObjectTypes.Buff2, NagrandArenaObjects.Buff2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "NagrandArena: Failed to spawn buff object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct NagrandArenaObjectTypes
|
||||
{
|
||||
public const int Door1 = 0;
|
||||
public const int Door2 = 1;
|
||||
public const int Door3 = 2;
|
||||
public const int Door4 = 3;
|
||||
public const int Buff1 = 4;
|
||||
public const int Buff2 = 5;
|
||||
public const int Max = 6;
|
||||
}
|
||||
|
||||
struct NagrandArenaObjects
|
||||
{
|
||||
public const uint Door1 = 183978;
|
||||
public const uint Door2 = 183980;
|
||||
public const uint Door3 = 183977;
|
||||
public const uint Door4 = 183979;
|
||||
public const uint Buff1 = 184663;
|
||||
public const uint Buff2 = 184664;
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.Dynamic;
|
||||
using Game.BattleGrounds;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
class RingofValorArena : Arena
|
||||
{
|
||||
public RingofValorArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate)
|
||||
{
|
||||
_events = new EventMap();
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
bool result = true;
|
||||
result &= AddObject(RingofValorObjectTypes.Elevator1, RingofValorGameObjects.Elevator1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Elevator2, RingofValorGameObjects.Elevator2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0, 0, 0, 0);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RingofValorArena: Failed to spawn elevator object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(RingofValorObjectTypes.Buff1, RingofValorGameObjects.Buff1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Buff2, RingofValorGameObjects.Buff2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0, 0, 0, 0);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RingofValorArena: Failed to spawn buff object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(RingofValorObjectTypes.Fire1, RingofValorGameObjects.Fire1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Fire2, RingofValorGameObjects.Fire2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Firedoor1, RingofValorGameObjects.Firedoor1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Firedoor2, RingofValorGameObjects.Firedoor2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0, 0, 0, 0);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RingofValorArena: Failed to spawn fire/firedoor object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(RingofValorObjectTypes.Gear1, RingofValorGameObjects.Gear1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Gear2, RingofValorGameObjects.Gear2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Pulley1, RingofValorGameObjects.Pulley1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Pulley2, RingofValorGameObjects.Pulley2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0, 0, 0, 0);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RingofValorArena: Failed to spawn gear/pully object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(RingofValorObjectTypes.Pilar1, RingofValorGameObjects.Pilar1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Pilar2, RingofValorGameObjects.Pilar2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Pilar3, RingofValorGameObjects.Pilar3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.Pilar4, RingofValorGameObjects.Pilar4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.PilarCollision1, RingofValorGameObjects.PilarCollision1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.PilarCollision2, RingofValorGameObjects.PilarCollision2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.PilarCollision3, RingofValorGameObjects.PilarCollision3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0, 0, 0, 0);
|
||||
result &= AddObject(RingofValorObjectTypes.PilarCollision4, RingofValorGameObjects.PilarCollision4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, 0);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RingofValorArena: Failed to spawn pilar object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
// Buff respawn
|
||||
SpawnBGObject(RingofValorObjectTypes.Buff1, 90);
|
||||
SpawnBGObject(RingofValorObjectTypes.Buff2, 90);
|
||||
// Elevators
|
||||
DoorOpen(RingofValorObjectTypes.Elevator1);
|
||||
DoorOpen(RingofValorObjectTypes.Elevator2);
|
||||
|
||||
_events.ScheduleEvent(RingofValorEvents.OpenFences, TimeSpan.FromSeconds(20));
|
||||
|
||||
// Should be false at first, TogglePillarCollision will do it.
|
||||
TogglePillarCollision(true);
|
||||
}
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case RingofValorEvents.OpenFences:
|
||||
// Open fire (only at game start)
|
||||
for (byte i = RingofValorObjectTypes.Fire1; i <= RingofValorObjectTypes.Firedoor2; ++i)
|
||||
DoorOpen(i);
|
||||
_events.ScheduleEvent(RingofValorEvents.CloseFire, TimeSpan.FromSeconds(5));
|
||||
break;
|
||||
case RingofValorEvents.CloseFire:
|
||||
for (byte i = RingofValorObjectTypes.Fire1; i <= RingofValorObjectTypes.Firedoor2; ++i)
|
||||
DoorClose(i);
|
||||
// Fire got closed after five seconds, leaves twenty seconds before toggling pillars
|
||||
_events.ScheduleEvent(RingofValorEvents.SwitchPillars, TimeSpan.FromSeconds(20));
|
||||
break;
|
||||
case RingofValorEvents.SwitchPillars:
|
||||
TogglePillarCollision(true);
|
||||
_events.Repeat(TimeSpan.FromSeconds(25));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void TogglePillarCollision(bool enable)
|
||||
{
|
||||
// Toggle visual pillars, pulley, gear, and collision based on previous state
|
||||
for (int i = RingofValorObjectTypes.Pilar1; i <= RingofValorObjectTypes.Gear2; ++i)
|
||||
{
|
||||
if (enable)
|
||||
DoorOpen(i);
|
||||
else
|
||||
DoorClose(i);
|
||||
}
|
||||
|
||||
for (byte i = RingofValorObjectTypes.Pilar2; i <= RingofValorObjectTypes.Pulley2; ++i)
|
||||
{
|
||||
if (enable)
|
||||
DoorClose(i);
|
||||
else
|
||||
DoorOpen(i);
|
||||
}
|
||||
|
||||
for (byte i = RingofValorObjectTypes.Pilar1; i <= RingofValorObjectTypes.PilarCollision4; ++i)
|
||||
{
|
||||
GameObject go = GetBGObject(i);
|
||||
if (go != null)
|
||||
{
|
||||
if (i >= RingofValorObjectTypes.PilarCollision1)
|
||||
{
|
||||
GameObjectState state = ((go.GetGoInfo().Door.startOpen != 0) == enable) ? GameObjectState.Active : GameObjectState.Ready;
|
||||
go.SetGoState(state);
|
||||
}
|
||||
|
||||
foreach (var guid in GetPlayers().Keys)
|
||||
{
|
||||
Player player = Global.ObjAccessor.FindPlayer(guid);
|
||||
if (player != null)
|
||||
go.SendUpdateToPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RingofValorEvents
|
||||
{
|
||||
public const int OpenFences = 0;
|
||||
public const int SwitchPillars = 1;
|
||||
public const int CloseFire = 2;
|
||||
}
|
||||
|
||||
struct RingofValorObjectTypes
|
||||
{
|
||||
public const int Buff1 = 1;
|
||||
public const int Buff2 = 2;
|
||||
public const int Fire1 = 3;
|
||||
public const int Fire2 = 4;
|
||||
public const int Firedoor1 = 5;
|
||||
public const int Firedoor2 = 6;
|
||||
|
||||
public const int Pilar1 = 7;
|
||||
public const int Pilar3 = 8;
|
||||
public const int Gear1 = 9;
|
||||
public const int Gear2 = 10;
|
||||
|
||||
public const int Pilar2 = 11;
|
||||
public const int Pilar4 = 12;
|
||||
public const int Pulley1 = 13;
|
||||
public const int Pulley2 = 14;
|
||||
|
||||
public const int PilarCollision1 = 15;
|
||||
public const int PilarCollision2 = 16;
|
||||
public const int PilarCollision3 = 17;
|
||||
public const int PilarCollision4 = 18;
|
||||
|
||||
public const int Elevator1 = 19;
|
||||
public const int Elevator2= 20;
|
||||
public const int Max = 21;
|
||||
}
|
||||
|
||||
struct RingofValorGameObjects
|
||||
{
|
||||
public const uint Buff1 = 184663;
|
||||
public const uint Buff2 = 184664;
|
||||
public const uint Fire1 = 192704;
|
||||
public const uint Fire2 = 192705;
|
||||
|
||||
public const uint Firedoor2 = 192387;
|
||||
public const uint Firedoor1 = 192388;
|
||||
public const uint Pulley1 = 192389;
|
||||
public const uint Pulley2 = 192390;
|
||||
public const uint Gear1 = 192393;
|
||||
public const uint Gear2 = 192394;
|
||||
public const uint Elevator1 = 194582;
|
||||
public const uint Elevator2 = 194586;
|
||||
|
||||
public const uint PilarCollision1 = 194580; // Axe
|
||||
public const uint PilarCollision2 = 194579; // Arena
|
||||
public const uint PilarCollision3 = 194581; // Lightning
|
||||
public const uint PilarCollision4 = 194578; // Ivory
|
||||
|
||||
public const uint Pilar1 = 194583; // Axe
|
||||
public const uint Pilar2 = 194584; // Arena
|
||||
public const uint Pilar3 = 194585; // Lightning
|
||||
public const uint Pilar4 = 194587; // Ivory
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.BattleGrounds;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
class RuinsofLordaeronArena : Arena
|
||||
{
|
||||
public RuinsofLordaeronArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
taskScheduler.Update(diff);
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
bool result = true;
|
||||
result &= AddObject(RuinsofLordaeronObjectTypes.Door1, RuinsofLordaeronObjectTypes.Door1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f);
|
||||
result &= AddObject(RuinsofLordaeronObjectTypes.Door2, RuinsofLordaeronObjectTypes.Door2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RuinsofLordaeronArena: Failed to spawn door object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
result &= AddObject(RuinsofLordaeronObjectTypes.Buff1, RuinsofLordaeronObjectTypes.Buff1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120);
|
||||
result &= AddObject(RuinsofLordaeronObjectTypes.Buff2, RuinsofLordaeronObjectTypes.Buff2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120);
|
||||
if (!result)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "RuinsofLordaeronArena: Failed to spawn buff object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void StartingEventCloseDoors()
|
||||
{
|
||||
for (int i = RuinsofLordaeronObjectTypes.Door1; i <= RuinsofLordaeronObjectTypes.Door2; ++i)
|
||||
SpawnBGObject(i, BattlegroundConst.RespawnImmediately);
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
for (int i = RuinsofLordaeronObjectTypes.Door1; i <= RuinsofLordaeronObjectTypes.Door2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
taskScheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
for (int i = RuinsofLordaeronObjectTypes.Door1; i <= RuinsofLordaeronObjectTypes.Door2; ++i)
|
||||
DelObject(i);
|
||||
});
|
||||
|
||||
for (int i = RuinsofLordaeronObjectTypes.Buff1; i <= RuinsofLordaeronObjectTypes.Buff2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
}
|
||||
|
||||
struct RuinsofLordaeronObjectTypes
|
||||
{
|
||||
public const int Door1 = 0;
|
||||
public const int Door2 = 1;
|
||||
public const int Buff1 = 2;
|
||||
public const int Buff2 = 3;
|
||||
public const int Max = 4;
|
||||
}
|
||||
|
||||
struct RuinsofLordaeronGameObjects
|
||||
{
|
||||
public const uint Door1 = 185918;
|
||||
public const uint Door2 = 185917;
|
||||
public const uint Buff1 = 184663;
|
||||
public const uint Buff2 = 184664;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
class TigersPeak
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.Arenas
|
||||
{
|
||||
class TolvironArena
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,7 @@ namespace Game.BattleFields
|
||||
if (m_PlayersInQueue[player.GetTeamId()].Contains(player.GetGUID()))
|
||||
return;
|
||||
|
||||
if (m_PlayersInQueue[player.GetTeamId()].Count <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player.GetTeamId())].Count >= m_MinPlayer)
|
||||
if (m_PlayersInQueue[player.GetTeamId()].Count <= m_MinPlayer || m_PlayersInQueue[SharedConst.GetOtherTeam(player.GetTeamId())].Count >= m_MinPlayer)
|
||||
PlayerAcceptInviteToQueue(player);
|
||||
}
|
||||
|
||||
@@ -705,7 +705,6 @@ namespace Game.BattleFields
|
||||
// Battlefield - generic methods
|
||||
public uint GetDefenderTeam() { return m_DefenderTeam; }
|
||||
public uint GetAttackerTeam() { return 1 - m_DefenderTeam; }
|
||||
public int GetOtherTeam(int teamIndex) { return (teamIndex == BattleGroundTeamId.Horde ? BattleGroundTeamId.Alliance : BattleGroundTeamId.Horde); }
|
||||
void SetDefenderTeam(uint team) { m_DefenderTeam = team; }
|
||||
|
||||
// Called on start
|
||||
|
||||
@@ -40,15 +40,8 @@ namespace Game.BattleGrounds
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// remove objects and creatures
|
||||
// (this is done automatically in mapmanager update, when the instance is reset after the reset time)
|
||||
for (uint i = 0; i < BgCreatures.Length; ++i)
|
||||
DelCreature(i);
|
||||
|
||||
for (var i = 0; i < BgObjects.Length; ++i)
|
||||
DelObject(i);
|
||||
|
||||
Global.BattlegroundMgr.RemoveBattleground(GetTypeID(), GetInstanceID());
|
||||
|
||||
// unload map
|
||||
if (m_Map != null)
|
||||
{
|
||||
@@ -207,7 +200,7 @@ namespace Game.BattleGrounds
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Team GetPrematureWinner()
|
||||
public Team GetPrematureWinner()
|
||||
{
|
||||
Team winner = Team.Other;
|
||||
if (GetPlayersCountByTeam(Team.Alliance) >= GetMinPlayersPerTeam())
|
||||
@@ -286,19 +279,12 @@ namespace Game.BattleGrounds
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup here, only when at least one player has ported to the map
|
||||
if (!SetupBattleground())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
_preparationStartTime = GameTime.GetGameTime();
|
||||
foreach (Group group in m_BgRaids)
|
||||
if (group != null)
|
||||
group.StartCountdown(CountdownTimerType.Pvp, TimeSpan.FromSeconds((int)StartDelayTimes[BattlegroundConst.EventIdFirst] / 1000), _preparationStartTime);
|
||||
|
||||
StartingEventCloseDoors();
|
||||
GetBgMap().GetBattlegroundScript().OnPrepareStage1();
|
||||
SetStartDelayTime(StartDelayTimes[BattlegroundConst.EventIdFirst]);
|
||||
// First start warning - 2 or 1 Minute
|
||||
if (StartMessageIds[BattlegroundConst.EventIdFirst] != 0)
|
||||
@@ -308,6 +294,7 @@ namespace Game.BattleGrounds
|
||||
else if (GetStartDelayTime() <= (int)StartDelayTimes[BattlegroundConst.EventIdSecond] && !m_Events.HasAnyFlag(BattlegroundEventFlags.Event2))
|
||||
{
|
||||
m_Events |= BattlegroundEventFlags.Event2;
|
||||
GetBgMap().GetBattlegroundScript().OnPrepareStage2();
|
||||
if (StartMessageIds[BattlegroundConst.EventIdSecond] != 0)
|
||||
SendBroadcastText(StartMessageIds[BattlegroundConst.EventIdSecond], ChatMsg.BgSystemNeutral);
|
||||
}
|
||||
@@ -315,6 +302,7 @@ namespace Game.BattleGrounds
|
||||
else if (GetStartDelayTime() <= (int)StartDelayTimes[BattlegroundConst.EventIdThird] && !m_Events.HasAnyFlag(BattlegroundEventFlags.Event3))
|
||||
{
|
||||
m_Events |= BattlegroundEventFlags.Event3;
|
||||
GetBgMap().GetBattlegroundScript().OnPrepareStage3();
|
||||
if (StartMessageIds[BattlegroundConst.EventIdThird] != 0)
|
||||
SendBroadcastText(StartMessageIds[BattlegroundConst.EventIdThird], ChatMsg.BgSystemNeutral);
|
||||
}
|
||||
@@ -323,7 +311,7 @@ namespace Game.BattleGrounds
|
||||
{
|
||||
m_Events |= BattlegroundEventFlags.Event4;
|
||||
|
||||
StartingEventOpenDoors();
|
||||
GetBgMap().GetBattlegroundScript().OnStart();
|
||||
|
||||
if (StartMessageIds[BattlegroundConst.EventIdFourth] != 0)
|
||||
SendBroadcastText(StartMessageIds[BattlegroundConst.EventIdFourth], ChatMsg.RaidBossEmote);
|
||||
@@ -740,6 +728,8 @@ namespace Game.BattleGrounds
|
||||
player.SendPacket(pvpMatchComplete);
|
||||
|
||||
player.UpdateCriteria(CriteriaType.ParticipateInBattleground, player.GetMapId());
|
||||
|
||||
GetBgMap().GetBattlegroundScript().OnEnd(winner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1027,6 +1017,8 @@ namespace Game.BattleGrounds
|
||||
// setup BG group membership
|
||||
PlayerAddedToBGCheckIfBGIsRunning(player);
|
||||
AddOrSetPlayerToCorrectBgGroup(player, team);
|
||||
|
||||
GetBgMap().GetBattlegroundScript().OnPlayerJoined(player, isInBattleground);
|
||||
}
|
||||
|
||||
// this method adds player to his team's bg group, or sets his correct group if player is already in bg group
|
||||
@@ -1104,8 +1096,8 @@ namespace Game.BattleGrounds
|
||||
|
||||
// 1 player is logging out, if it is the last alive, then end arena!
|
||||
if (IsArena() && player.IsAlive())
|
||||
if (GetAlivePlayersCountByTeam(player.GetBGTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player.GetBGTeam())) != 0)
|
||||
EndBattleground(GetOtherTeam(player.GetBGTeam()));
|
||||
if (GetAlivePlayersCountByTeam(player.GetBGTeam()) <= 1 && GetPlayersCountByTeam(SharedConst.GetOtherTeam(player.GetBGTeam())) != 0)
|
||||
EndBattleground(SharedConst.GetOtherTeam(player.GetBGTeam()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,7 +1233,7 @@ namespace Game.BattleGrounds
|
||||
return PlayerScores.LookupByKey(player.GetGUID());
|
||||
}
|
||||
|
||||
public virtual bool UpdatePlayerScore(Player player, ScoreType type, uint value, bool doAddHonor = true)
|
||||
public bool UpdatePlayerScore(Player player, ScoreType type, uint value, bool doAddHonor = true)
|
||||
{
|
||||
var bgScore = PlayerScores.LookupByKey(player.GetGUID());
|
||||
if (bgScore == null) // player not found...
|
||||
@@ -1262,99 +1254,6 @@ namespace Game.BattleGrounds
|
||||
score.UpdatePvpStat(pvpStatId, value);
|
||||
}
|
||||
|
||||
public bool AddObject(int type, uint entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint respawnTime = 0, GameObjectState goState = GameObjectState.Ready)
|
||||
{
|
||||
Map map = FindBgMap();
|
||||
if (map == null)
|
||||
return false;
|
||||
|
||||
Quaternion rotation = new(rotation0, rotation1, rotation2, rotation3);
|
||||
// Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff)
|
||||
if (rotation0 == 0 && rotation1 == 0 && rotation2 == 0 && rotation3 == 0)
|
||||
{
|
||||
Log.outDebug(LogFilter.Battleground, $"Battleground.AddObject: gameoobject [entry: {entry}, object type: {type}] for BG (map: {GetMapId()}) has zeroed rotation fields, " +
|
||||
"orientation used temporally, but please fix the spawn");
|
||||
|
||||
rotation = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(o, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
// Must be created this way, adding to godatamap would add it to the base map of the instance
|
||||
// and when loading it (in go.LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
|
||||
// So we must create it specific for this instance
|
||||
GameObject go = GameObject.CreateGameObject(entry, GetBgMap(), new Position(x, y, z, o), rotation, 255, goState);
|
||||
if (go == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.AddObject: cannot create gameobject (entry: {entry}) for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to world, so it can be later looked up from HashMapHolder
|
||||
if (!map.AddToMap(go))
|
||||
return false;
|
||||
|
||||
BgObjects[type] = go.GetGUID();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddObject(int type, uint entry, Position pos, float rotation0, float rotation1, float rotation2, float rotation3, uint respawnTime = 0, GameObjectState goState = GameObjectState.Ready)
|
||||
{
|
||||
return AddObject(type, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), rotation0, rotation1, rotation2, rotation3, respawnTime, goState);
|
||||
}
|
||||
|
||||
// Some doors aren't despawned so we cannot handle their closing in gameobject.update()
|
||||
// It would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code
|
||||
public void DoorClose(int type)
|
||||
{
|
||||
GameObject obj = GetBgMap().GetGameObject(BgObjects[type]);
|
||||
if (obj != null)
|
||||
{
|
||||
// If doors are open, close it
|
||||
if (obj.GetLootState() == LootState.Activated && obj.GetGoState() != GameObjectState.Ready)
|
||||
{
|
||||
obj.SetLootState(LootState.Ready);
|
||||
obj.SetGoState(GameObjectState.Ready);
|
||||
}
|
||||
}
|
||||
else
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.DoorClose: door gameobject (type: {type}, {BgObjects[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
}
|
||||
|
||||
public void DoorOpen(int type)
|
||||
{
|
||||
GameObject obj = GetBgMap().GetGameObject(BgObjects[type]);
|
||||
if (obj != null)
|
||||
{
|
||||
obj.SetLootState(LootState.Activated);
|
||||
obj.SetGoState(GameObjectState.Active);
|
||||
}
|
||||
else
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.DoorOpen: door gameobject (type: {type}, {BgObjects[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
}
|
||||
|
||||
public GameObject GetBGObject(int type)
|
||||
{
|
||||
if (BgObjects[type].IsEmpty())
|
||||
return null;
|
||||
|
||||
GameObject obj = GetBgMap().GetGameObject(BgObjects[type]);
|
||||
if (obj == null)
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.GetBGObject: gameobject (type: {type}, {BgObjects[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Creature GetBGCreature(uint type)
|
||||
{
|
||||
if (BgCreatures[type].IsEmpty())
|
||||
return null;
|
||||
|
||||
Creature creature = GetBgMap().GetCreature(BgCreatures[type]);
|
||||
if (creature == null)
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.GetBGCreature: creature (type: {type}, {BgCreatures[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
|
||||
return creature;
|
||||
}
|
||||
|
||||
public uint GetMapId()
|
||||
{
|
||||
return (uint)_battlegroundTemplate.BattlemasterEntry.MapId[0];
|
||||
@@ -1364,168 +1263,11 @@ namespace Game.BattleGrounds
|
||||
{
|
||||
m_Map = map;
|
||||
if (map != null)
|
||||
{
|
||||
_pvpStatIds = Global.DB2Mgr.GetPVPStatIDsForMap(map.GetId());
|
||||
OnMapSet(map);
|
||||
}
|
||||
else
|
||||
_pvpStatIds = null;
|
||||
}
|
||||
|
||||
public void SpawnBGObject(int type, uint respawntime)
|
||||
{
|
||||
Map map = FindBgMap();
|
||||
if (map != null)
|
||||
{
|
||||
GameObject obj = map.GetGameObject(BgObjects[type]);
|
||||
if (obj != null)
|
||||
{
|
||||
if (respawntime != 0)
|
||||
{
|
||||
obj.SetLootState(LootState.JustDeactivated);
|
||||
{
|
||||
GameObjectOverride goOverride = obj.GetGameObjectOverride();
|
||||
if (goOverride != null)
|
||||
if (goOverride.Flags.HasFlag(GameObjectFlags.NoDespawn))
|
||||
{
|
||||
// This function should be called in GameObject::Update() but in case of
|
||||
// GO_FLAG_NODESPAWN flag the function is never called, so we call it here
|
||||
obj.SendGameObjectDespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (obj.GetLootState() == LootState.JustDeactivated)
|
||||
{
|
||||
// Change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again
|
||||
obj.SetLootState(LootState.Ready);
|
||||
}
|
||||
obj.SetRespawnTime((int)respawntime);
|
||||
map.AddToMap(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Creature AddCreature(uint entry, uint type, float x, float y, float z, float o, int teamIndex = BattleGroundTeamId.Neutral, uint respawntime = 0, Transport transport = null)
|
||||
{
|
||||
Map map = FindBgMap();
|
||||
if (map == null)
|
||||
return null;
|
||||
|
||||
if (Global.ObjectMgr.GetCreatureTemplate(entry) == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.AddCreature: creature template (entry: {entry}) does not exist for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (transport != null)
|
||||
{
|
||||
Creature transCreature = transport.SummonPassenger(entry, new Position(x, y, z, o), TempSummonType.ManualDespawn);
|
||||
if (transCreature != null)
|
||||
{
|
||||
BgCreatures[type] = transCreature.GetGUID();
|
||||
return transCreature;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Position pos = new(x, y, z, o);
|
||||
|
||||
Creature creature = Creature.CreateCreature(entry, map, pos);
|
||||
if (creature == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.AddCreature: cannot create creature (entry: {entry}) for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
return null;
|
||||
}
|
||||
|
||||
creature.SetHomePosition(pos);
|
||||
|
||||
if (!map.AddToMap(creature))
|
||||
return null;
|
||||
|
||||
BgCreatures[type] = creature.GetGUID();
|
||||
|
||||
if (respawntime != 0)
|
||||
creature.SetRespawnDelay(respawntime);
|
||||
|
||||
return creature;
|
||||
}
|
||||
|
||||
public Creature AddCreature(uint entry, uint type, Position pos, int teamIndex = BattleGroundTeamId.Neutral, uint respawntime = 0, Transport transport = null)
|
||||
{
|
||||
return AddCreature(entry, type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamIndex, respawntime, transport);
|
||||
}
|
||||
|
||||
public bool DelCreature(uint type)
|
||||
{
|
||||
if (BgCreatures[type].IsEmpty())
|
||||
return true;
|
||||
|
||||
Creature creature = GetBgMap().GetCreature(BgCreatures[type]);
|
||||
if (creature != null)
|
||||
{
|
||||
creature.AddObjectToRemoveList();
|
||||
BgCreatures[type].Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.DelCreature: creature (type: {type}, {BgCreatures[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
BgCreatures[type].Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DelObject(int type)
|
||||
{
|
||||
if (BgObjects[type].IsEmpty())
|
||||
return true;
|
||||
|
||||
GameObject obj = GetBgMap().GetGameObject(BgObjects[type]);
|
||||
if (obj != null)
|
||||
{
|
||||
obj.SetRespawnTime(0); // not save respawn time
|
||||
obj.Delete();
|
||||
BgObjects[type].Clear();
|
||||
return true;
|
||||
}
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.DelObject: gameobject (type: {type}, {BgObjects[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
BgObjects[type].Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RemoveObjectFromWorld(uint type)
|
||||
{
|
||||
if (BgObjects[type].IsEmpty())
|
||||
return true;
|
||||
|
||||
GameObject obj = GetBgMap().GetGameObject(BgObjects[type]);
|
||||
if (obj != null)
|
||||
{
|
||||
obj.RemoveFromWorld();
|
||||
BgObjects[type].Clear();
|
||||
return true;
|
||||
}
|
||||
Log.outInfo(LogFilter.Battleground, $"Battleground::RemoveObjectFromWorld: gameobject (type: {type}, {BgObjects[type]}) not found for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AddSpiritGuide(uint type, float x, float y, float z, float o, int teamIndex)
|
||||
{
|
||||
uint entry = (uint)(teamIndex == BattleGroundTeamId.Alliance ? BattlegroundCreatures.A_SpiritGuide : BattlegroundCreatures.H_SpiritGuide);
|
||||
|
||||
if (AddCreature(entry, type, x, y, z, o) != null)
|
||||
return true;
|
||||
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.AddSpiritGuide: cannot create spirit guide (type: {type}, entry: {entry}) for BG (map: {GetMapId()}, instance id: {m_InstanceID})!");
|
||||
EndNow();
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AddSpiritGuide(uint type, Position pos, int teamIndex = BattleGroundTeamId.Neutral)
|
||||
{
|
||||
return AddSpiritGuide(type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamIndex);
|
||||
}
|
||||
|
||||
public void SendMessageToAll(CypherStrings entry, ChatMsg msgType, Player source = null)
|
||||
{
|
||||
if (entry == 0)
|
||||
@@ -1598,9 +1340,18 @@ namespace Game.BattleGrounds
|
||||
victim.SetUnitFlag(UnitFlags.Skinnable);
|
||||
RewardXPAtKill(killer, victim);
|
||||
}
|
||||
|
||||
BattlegroundScript script = GetBgMap().GetBattlegroundScript();
|
||||
if (script != null)
|
||||
script.OnPlayerKilled(victim, killer);
|
||||
}
|
||||
|
||||
public virtual void HandleKillUnit(Creature creature, Unit killer) { }
|
||||
public virtual void HandleKillUnit(Creature victim, Unit killer)
|
||||
{
|
||||
BattlegroundScript script = GetBgMap().GetBattlegroundScript();
|
||||
if (script != null)
|
||||
script.OnUnitKilled(victim, killer);
|
||||
}
|
||||
|
||||
// Return the player's team based on Battlegroundplayer info
|
||||
// Used in same faction arena matches mainly
|
||||
@@ -1612,11 +1363,6 @@ namespace Game.BattleGrounds
|
||||
return Team.Other;
|
||||
}
|
||||
|
||||
public Team GetOtherTeam(Team team)
|
||||
{
|
||||
return team != 0 ? ((team == Team.Alliance) ? Team.Horde : Team.Alliance) : Team.Other;
|
||||
}
|
||||
|
||||
public bool IsPlayerInBattleground(ObjectGuid guid)
|
||||
{
|
||||
return m_Players.ContainsKey(guid);
|
||||
@@ -1658,15 +1404,6 @@ namespace Game.BattleGrounds
|
||||
return count;
|
||||
}
|
||||
|
||||
public int GetObjectType(ObjectGuid guid)
|
||||
{
|
||||
for (int i = 0; i < BgObjects.Length; ++i)
|
||||
if (BgObjects[i] == guid)
|
||||
return i;
|
||||
Log.outError(LogFilter.Battleground, $"Battleground.GetObjectType: player used gameobject ({guid}) which is not in internal data for BG (map: {GetMapId()}, instance id: {m_InstanceID}), cheating?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void SetBgRaid(Team team, Group bg_raid)
|
||||
{
|
||||
Group old_raid = m_BgRaids[GetTeamIndexByTeamId(team)];
|
||||
@@ -1677,23 +1414,6 @@ namespace Game.BattleGrounds
|
||||
m_BgRaids[GetTeamIndexByTeamId(team)] = bg_raid;
|
||||
}
|
||||
|
||||
public virtual WorldSafeLocsEntry GetClosestGraveyard(Player player)
|
||||
{
|
||||
return Global.ObjectMgr.GetClosestGraveyard(player, GetPlayerTeam(player.GetGUID()), player);
|
||||
}
|
||||
|
||||
public override void TriggerGameEvent(uint gameEventId, WorldObject source = null, WorldObject target = null)
|
||||
{
|
||||
ProcessEvent(target, gameEventId, source);
|
||||
GameEvents.TriggerForMap(gameEventId, GetBgMap(), source, target);
|
||||
foreach (var guid in GetPlayers().Keys)
|
||||
{
|
||||
Player player = Global.ObjAccessor.FindPlayer(guid);
|
||||
if (player != null)
|
||||
GameEvents.TriggerForPlayer(gameEventId, player);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBracket(PvpDifficultyRecord bracketEntry)
|
||||
{
|
||||
_pvpDifficultyEntry = bracketEntry;
|
||||
@@ -1714,17 +1434,6 @@ namespace Game.BattleGrounds
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void HandleAreaTrigger(Player player, uint trigger, bool entered)
|
||||
{
|
||||
Log.outDebug(LogFilter.Battleground, "Unhandled AreaTrigger {0} in Battleground {1}. Player coords (x: {2}, y: {3}, z: {4})",
|
||||
trigger, player.GetMapId(), player.GetPositionX(), player.GetPositionY(), player.GetPositionZ());
|
||||
}
|
||||
|
||||
public virtual bool SetupBattleground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return _battlegroundTemplate.BattlemasterEntry.Name[Global.WorldMgr.GetDefaultDbcLocale()];
|
||||
@@ -1801,13 +1510,9 @@ namespace Game.BattleGrounds
|
||||
return m_Players.LookupByKey(playerGuid);
|
||||
}
|
||||
|
||||
// Called when valid BattlegroundMap is assigned to the battleground
|
||||
public virtual void OnMapSet(BattlegroundMap map) { }
|
||||
|
||||
public virtual void StartingEventCloseDoors() { }
|
||||
public virtual void StartingEventOpenDoors() { }
|
||||
|
||||
public virtual void DestroyGate(Player player, GameObject go) { }
|
||||
public void AddPoint(Team team, uint points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] += points; }
|
||||
public void SetTeamPoint(Team team, uint points = 0) { m_TeamScores[GetTeamIndexByTeamId(team)] = points; }
|
||||
void RemovePoint(Team team, uint points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] -= points; }
|
||||
|
||||
public uint GetInstanceID() { return m_InstanceID; }
|
||||
public BattlegroundStatus GetStatus() { return m_Status; }
|
||||
@@ -1878,14 +1583,6 @@ namespace Game.BattleGrounds
|
||||
public void SetArenaMatchmakerRating(Team team, uint MMR) { m_ArenaTeamMMR[GetTeamIndexByTeamId(team)] = MMR; }
|
||||
public uint GetArenaMatchmakerRating(Team team) { return m_ArenaTeamMMR[GetTeamIndexByTeamId(team)]; }
|
||||
|
||||
// Battleground events
|
||||
public virtual void EventPlayerDroppedFlag(Player player) { }
|
||||
public virtual void EventPlayerClickedOnFlag(Player player, GameObject target_obj) { }
|
||||
|
||||
public override void ProcessEvent(WorldObject obj, uint eventId, WorldObject invoker = null) { }
|
||||
|
||||
public virtual void HandlePlayerResurrect(Player player) { }
|
||||
|
||||
public virtual WorldSafeLocsEntry GetExploitTeleportLocation(Team team) { return null; }
|
||||
|
||||
public virtual bool HandlePlayerUnderMap(Player player) { return false; }
|
||||
@@ -1895,12 +1592,6 @@ namespace Game.BattleGrounds
|
||||
|
||||
bool CanAwardArenaPoints() { return GetMinLevel() >= 71; }
|
||||
|
||||
public virtual ObjectGuid GetFlagPickerGUID(int teamIndex = -1) { return ObjectGuid.Empty; }
|
||||
public virtual void SetDroppedFlagGUID(ObjectGuid guid, int teamIndex = -1) { }
|
||||
public virtual void HandleQuestComplete(uint questid, Player player) { }
|
||||
public virtual bool CanActivateGO(int entry, uint team) { return true; }
|
||||
public virtual bool IsSpellAllowed(uint spellId, Player player) { return true; }
|
||||
|
||||
public virtual void RemovePlayer(Player player, ObjectGuid guid, Team team) { }
|
||||
|
||||
public virtual bool PreUpdateImpl(uint diff) { return true; }
|
||||
@@ -1930,9 +1621,6 @@ namespace Game.BattleGrounds
|
||||
|
||||
public uint[] m_TeamScores = new uint[SharedConst.PvpTeamsCount];
|
||||
|
||||
protected ObjectGuid[] BgObjects;// = new Dictionary<int, ObjectGuid>();
|
||||
protected ObjectGuid[] BgCreatures;// = new Dictionary<int, ObjectGuid>();
|
||||
|
||||
public uint[] Buff_Entries = { BattlegroundConst.SpeedBuff, BattlegroundConst.RegenBuff, BattlegroundConst.BerserkerBuff };
|
||||
|
||||
// Battleground
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.Database;
|
||||
using Game.BattleGrounds.Zones;
|
||||
using Game.BattleGrounds.Zones.AlteracValley;
|
||||
using Game.BattleGrounds.Zones.ArathisBasin;
|
||||
using Game.BattleGrounds.Zones.EyeofStorm;
|
||||
using Game.BattleGrounds.Zones.IsleOfConquest;
|
||||
using Game.BattleGrounds.Zones.StrandOfAncients;
|
||||
using Game.BattleGrounds.Zones.WarsongGluch;
|
||||
using Game.Arenas;
|
||||
using Game.DataStorage;
|
||||
using Game.Entities;
|
||||
using Game.Networking.Packets;
|
||||
@@ -201,6 +195,60 @@ namespace Game.BattleGrounds
|
||||
return null;
|
||||
}
|
||||
|
||||
public void LoadBattlegroundScriptTemplate()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
|
||||
// 0 1 2
|
||||
SQLResult result = DB.World.Query("SELECT MapId, BattlemasterListId, ScriptName FROM battleground_scripts");
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 battleground scripts. DB table `battleground_scripts` is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint count = 0;
|
||||
do
|
||||
{
|
||||
uint mapID = result.Read<uint>(0);
|
||||
|
||||
var mapEntry = CliDB.MapStorage.LookupByKey(mapID);
|
||||
if (mapEntry == null || !mapEntry.IsBattlegroundOrArena())
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad mapid {mapID}! Map doesn't exist or is not a battleground/arena!");
|
||||
continue;
|
||||
}
|
||||
|
||||
BattlegroundTypeId bgTypeId = (BattlegroundTypeId)result.Read<uint>(1);
|
||||
if (bgTypeId != BattlegroundTypeId.None && !_battlegroundTemplates.ContainsKey(bgTypeId))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad battlemasterlist id {bgTypeId}! Battleground doesn't exist or is not supported in battleground_template!");
|
||||
continue;
|
||||
}
|
||||
|
||||
BattlegroundScriptTemplate scriptTemplate = new();
|
||||
scriptTemplate.MapId = mapID;
|
||||
scriptTemplate.Id = bgTypeId;
|
||||
scriptTemplate.ScriptId = Global.ObjectMgr.GetScriptId(result.Read<string>(2));
|
||||
|
||||
_battlegroundScriptTemplates[(mapID, bgTypeId)] = scriptTemplate;
|
||||
|
||||
++count;
|
||||
} while (result.NextRow());
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} battleground scripts in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
public BattlegroundScriptTemplate FindBattlegroundScriptTemplate(uint mapId, BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
BattlegroundScriptTemplate scriptTemplate = _battlegroundScriptTemplates.LookupByKey((mapId, bgTypeId));
|
||||
if (scriptTemplate != null)
|
||||
return scriptTemplate;
|
||||
|
||||
// fall back to 0 for no specific battleground type id
|
||||
return _battlegroundScriptTemplates.LookupByKey((mapId, BattlegroundTypeId.None));
|
||||
}
|
||||
|
||||
uint CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
|
||||
{
|
||||
if (IsArenaType(bgTypeId))
|
||||
@@ -250,56 +298,10 @@ namespace Game.BattleGrounds
|
||||
}
|
||||
|
||||
Battleground bg = null;
|
||||
// create a copy of the BG template
|
||||
switch (bgTypeId)
|
||||
{
|
||||
case BattlegroundTypeId.AV:
|
||||
bg = new BgAlteracValley(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.WS:
|
||||
case BattlegroundTypeId.WgCtf:
|
||||
bg = new BgWarsongGluch(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.AB:
|
||||
case BattlegroundTypeId.DomAb:
|
||||
bg = new BgArathiBasin(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.NA:
|
||||
bg = new BgNagrandArena(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.BE:
|
||||
bg = new BgBladesEdgeArena(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.EY:
|
||||
bg = new BgEyeofStorm(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.RL:
|
||||
bg = new BgRuinsOfLordaernon(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.SA:
|
||||
bg = new BgStrandOfAncients(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.DS:
|
||||
bg = new BgDalaranSewers(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.RV:
|
||||
bg = new BgTheRingOfValor(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.IC:
|
||||
bg = new BgIsleofConquest(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.TP:
|
||||
bg = new BgTwinPeaks(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.BFG:
|
||||
bg = new BgBattleforGilneas(bg_template);
|
||||
break;
|
||||
case BattlegroundTypeId.RB:
|
||||
case BattlegroundTypeId.AA:
|
||||
case BattlegroundTypeId.RandomEpic:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
if (bg_template.IsArena())
|
||||
bg = new Arena(bg_template);
|
||||
else
|
||||
bg = new Battleground(bg_template);
|
||||
|
||||
bg.SetBracket(bracketEntry);
|
||||
bg.SetInstanceID(Global.MapMgr.GenerateInstanceId());
|
||||
@@ -723,6 +725,7 @@ namespace Game.BattleGrounds
|
||||
Dictionary<uint, BattlegroundTypeId> mBattleMastersMap = new();
|
||||
Dictionary<BattlegroundTypeId, BattlegroundTemplate> _battlegroundTemplates = new();
|
||||
Dictionary<uint, BattlegroundTemplate> _battlegroundMapTemplates = new();
|
||||
Dictionary<(uint, BattlegroundTypeId), BattlegroundScriptTemplate> _battlegroundScriptTemplates = new();
|
||||
|
||||
struct ScheduledQueueUpdate
|
||||
{
|
||||
@@ -808,4 +811,11 @@ namespace Game.BattleGrounds
|
||||
return BattlemasterEntry.MaxLevel;
|
||||
}
|
||||
}
|
||||
|
||||
public class BattlegroundScriptTemplate
|
||||
{
|
||||
public uint MapId;
|
||||
public BattlegroundTypeId Id;
|
||||
public uint ScriptId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Game.Maps;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Game.BattleGrounds
|
||||
{
|
||||
public class BattlegroundScript : ZoneScript
|
||||
{
|
||||
protected BattlegroundMap battlegroundMap;
|
||||
protected Battleground battleground;
|
||||
|
||||
public BattlegroundScript(BattlegroundMap map)
|
||||
{
|
||||
battlegroundMap = map;
|
||||
battleground = map.GetBG();
|
||||
}
|
||||
|
||||
public virtual Team GetPrematureWinner()
|
||||
{
|
||||
Team winner = Team.Other;
|
||||
if (battleground.GetPlayersCountByTeam(Team.Alliance) >= battleground.GetMinPlayersPerTeam())
|
||||
winner = Team.Alliance;
|
||||
else if (battleground.GetPlayersCountByTeam(Team.Horde) >= battleground.GetMinPlayersPerTeam())
|
||||
winner = Team.Horde;
|
||||
|
||||
return winner;
|
||||
}
|
||||
|
||||
public override void TriggerGameEvent(uint gameEventId, WorldObject source = null, WorldObject target = null)
|
||||
{
|
||||
ProcessEvent(target, gameEventId, source);
|
||||
GameEvents.TriggerForMap(gameEventId, battlegroundMap, source, target);
|
||||
foreach (var (playerGuid, _) in battleground.GetPlayers())
|
||||
{
|
||||
Player player = Global.ObjAccessor.FindPlayer(playerGuid);
|
||||
if (player != null)
|
||||
GameEvents.TriggerForPlayer(gameEventId, player);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateWorldState(int worldStateId, int value, bool hidden = false)
|
||||
{
|
||||
Global.WorldStateMgr.SetValue(worldStateId, value, hidden, battlegroundMap);
|
||||
}
|
||||
|
||||
public void UpdateWorldState(int worldStateId, bool value, bool hidden = false)
|
||||
{
|
||||
Global.WorldStateMgr.SetValue(worldStateId, value ? 1 : 0, hidden, battlegroundMap);
|
||||
}
|
||||
|
||||
public virtual void OnInit() { }
|
||||
public virtual void OnUpdate(uint diff) { }
|
||||
public virtual void OnPrepareStage1() { }
|
||||
public virtual void OnPrepareStage2() { }
|
||||
public virtual void OnPrepareStage3() { }
|
||||
public virtual void OnStart() { }
|
||||
public virtual void OnEnd(Team winner) { }
|
||||
public virtual void OnPlayerJoined(Player player, bool inBattleground) { }
|
||||
public virtual void OnPlayerLeft(Player player) { }
|
||||
public virtual void OnPlayerKilled(Player victim, Player killer) { }
|
||||
public virtual void OnUnitKilled(Creature victim, Unit killer) { }
|
||||
}
|
||||
|
||||
public class ArenaScript : BattlegroundScript
|
||||
{
|
||||
public ArenaScript(BattlegroundMap map) : base(map) { }
|
||||
|
||||
public GameObject CreateObject(uint entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GameObjectState goState = GameObjectState.Ready)
|
||||
{
|
||||
Quaternion rot = new(rotation0, rotation1, rotation2, rotation3);
|
||||
// Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff)
|
||||
if (rotation0 == 0 && rotation1 == 0 && rotation2 == 0 && rotation3 == 0)
|
||||
{
|
||||
Log.outDebug(LogFilter.Battleground, $"Battleground::AddObject: gameoobject [entry: {entry}] for BG (map: {battlegroundMap.GetId()}) has zeroed rotation fields, " +
|
||||
"orientation used temporally, but please fix the spawn");
|
||||
|
||||
rot = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(o, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
// Must be created this way, adding to godatamap would add it to the base map of the instance
|
||||
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
|
||||
// So we must create it specific for this instance
|
||||
GameObject go = GameObject.CreateGameObject(entry, battlegroundMap, new Position(x, y, z, o), rot, 255, goState);
|
||||
if (go == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground::AddObject: cannot create gameobject (entry: {entry}) for BG (map: {battlegroundMap.GetId()}, instance id: {battleground.GetInstanceID()})!");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!battlegroundMap.AddToMap(go))
|
||||
{
|
||||
go.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
public Creature CreateCreature(uint entry, float x, float y, float z, float o)
|
||||
{
|
||||
if (Global.ObjectMgr.GetCreatureTemplate(entry) == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground::AddCreature: creature template (entry: {entry}) does not exist for BG (map: {battlegroundMap.GetId()}, instance id: {battleground.GetInstanceID()})!");
|
||||
return null;
|
||||
}
|
||||
|
||||
Position pos = new(x, y, z, o);
|
||||
|
||||
Creature creature = Creature.CreateCreature(entry, battlegroundMap, pos);
|
||||
if (creature == null)
|
||||
{
|
||||
Log.outError(LogFilter.Battleground, $"Battleground::AddCreature: cannot create creature (entry: {entry}) for BG (map: {battlegroundMap.GetId()}, instance id: {battleground.GetInstanceID()})!");
|
||||
return null;
|
||||
}
|
||||
|
||||
creature.SetHomePosition(pos);
|
||||
|
||||
if (!battlegroundMap.AddToMap(creature))
|
||||
{
|
||||
creature.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
return creature;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,658 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using Game.Maps;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Game.BattleGrounds.Zones.ArathisBasin
|
||||
{
|
||||
class BgArathiBasin : Battleground
|
||||
{
|
||||
TimeTracker _pointsTimer;
|
||||
uint[] m_HonorScoreTics = new uint[SharedConst.PvpTeamsCount];
|
||||
uint[] m_ReputationScoreTics = new uint[SharedConst.PvpTeamsCount];
|
||||
bool m_IsInformedNearVictory;
|
||||
uint m_HonorTics;
|
||||
uint m_ReputationTics;
|
||||
|
||||
List<ObjectGuid> _gameobjectsToRemoveOnMatchStart = new();
|
||||
List<ObjectGuid> _creaturesToRemoveOnMatchStart = new();
|
||||
List<ObjectGuid> _doors = new();
|
||||
List<ObjectGuid> _capturePoints = new();
|
||||
|
||||
public BgArathiBasin(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate)
|
||||
{
|
||||
m_IsInformedNearVictory = false;
|
||||
_pointsTimer = new TimeTracker(MiscConst.TickInterval);
|
||||
|
||||
for (byte i = 0; i < SharedConst.PvpTeamsCount; ++i)
|
||||
{
|
||||
m_HonorScoreTics[i] = 0;
|
||||
m_ReputationScoreTics[i] = 0;
|
||||
}
|
||||
|
||||
m_HonorTics = 0;
|
||||
m_ReputationTics = 0;
|
||||
}
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() == BattlegroundStatus.InProgress)
|
||||
{
|
||||
// Accumulate points
|
||||
_pointsTimer.Update(diff);
|
||||
if (_pointsTimer.Passed())
|
||||
{
|
||||
_pointsTimer.Reset(MiscConst.TickInterval);
|
||||
|
||||
_CalculateTeamNodes(out var ally, out var horde);
|
||||
int[] points = [ally, horde];
|
||||
|
||||
for (int team = 0; team < SharedConst.PvpTeamsCount; ++team)
|
||||
{
|
||||
if (points[team] == 0)
|
||||
continue;
|
||||
|
||||
m_TeamScores[team] += MiscConst.TickPoints[points[team]];
|
||||
m_HonorScoreTics[team] += MiscConst.TickPoints[points[team]];
|
||||
m_ReputationScoreTics[team] += MiscConst.TickPoints[points[team]];
|
||||
|
||||
if (m_ReputationScoreTics[team] >= m_ReputationTics)
|
||||
{
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
RewardReputationToTeam(509, 10, Team.Alliance);
|
||||
else
|
||||
RewardReputationToTeam(510, 10, Team.Horde);
|
||||
|
||||
m_ReputationScoreTics[team] -= m_ReputationTics;
|
||||
}
|
||||
|
||||
if (m_HonorScoreTics[team] >= m_HonorTics)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == BattleGroundTeamId.Alliance) ? Team.Alliance : Team.Horde);
|
||||
m_HonorScoreTics[team] -= m_HonorTics;
|
||||
}
|
||||
|
||||
if (!m_IsInformedNearVictory && m_TeamScores[team] > MiscConst.WarningNearVictoryScore)
|
||||
{
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
{
|
||||
SendBroadcastText((uint)ABBattlegroundBroadcastTexts.AllianceNearVictory, ChatMsg.BgSystemNeutral);
|
||||
PlaySoundToAll((uint)SoundIds.NearVictoryAlliance);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendBroadcastText((uint)ABBattlegroundBroadcastTexts.HordeNearVictory, ChatMsg.BgSystemNeutral);
|
||||
PlaySoundToAll((uint)SoundIds.NearVictoryHorde);
|
||||
}
|
||||
m_IsInformedNearVictory = true;
|
||||
}
|
||||
|
||||
if (m_TeamScores[team] > MiscConst.MaxTeamScore)
|
||||
m_TeamScores[team] = MiscConst.MaxTeamScore;
|
||||
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
UpdateWorldState(WorldStateIds.ResourcesAlly, (int)m_TeamScores[team]);
|
||||
else
|
||||
UpdateWorldState(WorldStateIds.ResourcesHorde, (int)m_TeamScores[team]);
|
||||
// update achievement flags
|
||||
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
||||
int otherTeam = (team + 1) % SharedConst.PvpTeamsCount;
|
||||
if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
|
||||
{
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
UpdateWorldState(WorldStateIds.Had500DisadvantageHorde, 1);
|
||||
else
|
||||
UpdateWorldState(WorldStateIds.Had500DisadvantageAlliance, 1);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateWorldState(WorldStateIds.OccupiedBasesAlly, ally);
|
||||
UpdateWorldState(WorldStateIds.OccupiedBasesHorde, horde);
|
||||
}
|
||||
|
||||
// Test win condition
|
||||
if (m_TeamScores[BattleGroundTeamId.Alliance] >= MiscConst.MaxTeamScore)
|
||||
EndBattleground(Team.Alliance);
|
||||
else if (m_TeamScores[BattleGroundTeamId.Horde] >= MiscConst.MaxTeamScore)
|
||||
EndBattleground(Team.Horde);
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
// Achievement: Let's Get This Done
|
||||
TriggerGameEvent((uint)ABEventIds.StartBattle);
|
||||
}
|
||||
|
||||
void _CalculateTeamNodes(out int alliance, out int horde)
|
||||
{
|
||||
alliance = 0;
|
||||
horde = 0;
|
||||
|
||||
BattlegroundMap map = FindBgMap();
|
||||
if (map != null)
|
||||
{
|
||||
foreach (ObjectGuid guid in _capturePoints)
|
||||
{
|
||||
GameObject capturePoint = map.GetGameObject(guid);
|
||||
if (capturePoint != null)
|
||||
{
|
||||
int wsValue = map.GetWorldStateValue((int)capturePoint.GetGoInfo().CapturePoint.worldState1);
|
||||
switch ((BattlegroundCapturePointState)wsValue)
|
||||
{
|
||||
case BattlegroundCapturePointState.AllianceCaptured:
|
||||
++alliance;
|
||||
break;
|
||||
case BattlegroundCapturePointState.HordeCaptured:
|
||||
++horde;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Team GetPrematureWinner()
|
||||
{
|
||||
// How many bases each team owns
|
||||
_CalculateTeamNodes(out var ally, out var horde);
|
||||
|
||||
if (ally > horde)
|
||||
return Team.Alliance;
|
||||
else if (horde > ally)
|
||||
return Team.Horde;
|
||||
|
||||
// If the values are equal, fall back to the original result (based on number of players on each team)
|
||||
return base.GetPrematureWinner();
|
||||
}
|
||||
|
||||
public override void ProcessEvent(WorldObject source, uint eventId, WorldObject invoker)
|
||||
{
|
||||
Player player = invoker.ToPlayer();
|
||||
|
||||
switch ((ABEventIds)eventId)
|
||||
{
|
||||
case ABEventIds.StartBattle:
|
||||
{
|
||||
foreach (ObjectGuid guid in _creaturesToRemoveOnMatchStart)
|
||||
{
|
||||
Creature creature = GetBgMap().GetCreature(guid);
|
||||
if (creature != null)
|
||||
creature.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
foreach (ObjectGuid guid in _gameobjectsToRemoveOnMatchStart)
|
||||
{
|
||||
GameObject gameObject = GetBgMap().GetGameObject(guid);
|
||||
if (gameObject != null)
|
||||
gameObject.DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
foreach (ObjectGuid guid in _doors)
|
||||
{
|
||||
GameObject gameObject = GetBgMap().GetGameObject(guid);
|
||||
if (gameObject != null)
|
||||
{
|
||||
gameObject.UseDoorOrButton();
|
||||
gameObject.DespawnOrUnsummon(TimeSpan.FromSeconds(3));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ABEventIds.ContestedBlacksmithAlliance:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithAllianceControlState, 1);
|
||||
UpdateWorldState(WorldStateIds.BlacksmithHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedBlacksmithAlliance:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithAllianceControlState, 2);
|
||||
UpdateWorldState(WorldStateIds.BlacksmithHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureBlacksmithAlliance:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithAllianceControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
break;
|
||||
case ABEventIds.ContestedBlacksmithHorde:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.BlacksmithHordeControlState, 1);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedBlacksmithHorde:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.BlacksmithHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureBlacksmithHorde:
|
||||
UpdateWorldState(WorldStateIds.BlacksmithHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
break;
|
||||
case ABEventIds.ContestedFarmAlliance:
|
||||
UpdateWorldState(WorldStateIds.FarmAllianceControlState, 1);
|
||||
UpdateWorldState(WorldStateIds.FarmHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedFarmAlliance:
|
||||
UpdateWorldState(WorldStateIds.FarmAllianceControlState, 2);
|
||||
UpdateWorldState(WorldStateIds.FarmHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureFarmAlliance:
|
||||
UpdateWorldState(WorldStateIds.FarmAllianceControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
break;
|
||||
case ABEventIds.ContestedFarmHorde:
|
||||
UpdateWorldState(WorldStateIds.FarmAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.FarmHordeControlState, 1);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedFarmHorde:
|
||||
UpdateWorldState(WorldStateIds.FarmAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.FarmHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureFarmHorde:
|
||||
UpdateWorldState(WorldStateIds.FarmHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
break;
|
||||
case ABEventIds.ContestedGoldMineAlliance:
|
||||
UpdateWorldState(WorldStateIds.GoldMineAllianceControlState, 1);
|
||||
UpdateWorldState(WorldStateIds.GoldMineHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedGoldMineAlliance:
|
||||
UpdateWorldState(WorldStateIds.GoldMineAllianceControlState, 2);
|
||||
UpdateWorldState(WorldStateIds.GoldMineHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureGoldMineAlliance:
|
||||
UpdateWorldState(WorldStateIds.GoldMineAllianceControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
break;
|
||||
case ABEventIds.ContestedGoldMineHorde:
|
||||
UpdateWorldState(WorldStateIds.GoldMineAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.GoldMineHordeControlState, 1);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedGoldMineHorde:
|
||||
UpdateWorldState(WorldStateIds.GoldMineAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.GoldMineHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureGoldMineHorde:
|
||||
UpdateWorldState(WorldStateIds.GoldMineHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
break;
|
||||
case ABEventIds.ContestedLumberMillAlliance:
|
||||
UpdateWorldState(WorldStateIds.LumberMillAllianceControlState, 1);
|
||||
UpdateWorldState(WorldStateIds.LumberMillHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedLumberMillAlliance:
|
||||
UpdateWorldState(WorldStateIds.LumberMillAllianceControlState, 2);
|
||||
UpdateWorldState(WorldStateIds.LumberMillHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureLumberMillAlliance:
|
||||
UpdateWorldState(WorldStateIds.LumberMillAllianceControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
break;
|
||||
case ABEventIds.ContestedLumberMillHorde:
|
||||
UpdateWorldState(WorldStateIds.LumberMillAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.LumberMillHordeControlState, 1);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedLumberMillHorde:
|
||||
UpdateWorldState(WorldStateIds.LumberMillAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.LumberMillHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureLumberMillHorde:
|
||||
UpdateWorldState(WorldStateIds.LumberMillHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
break;
|
||||
case ABEventIds.ContestedStablesAlliance:
|
||||
UpdateWorldState(WorldStateIds.StablesAllianceControlState, 1);
|
||||
UpdateWorldState(WorldStateIds.StablesHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedStablesAlliance:
|
||||
UpdateWorldState(WorldStateIds.StablesAllianceControlState, 2);
|
||||
UpdateWorldState(WorldStateIds.StablesHordeControlState, 0);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureStablesAlliance:
|
||||
UpdateWorldState(WorldStateIds.StablesAllianceControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
|
||||
break;
|
||||
case ABEventIds.ContestedStablesHorde:
|
||||
UpdateWorldState(WorldStateIds.StablesAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.StablesHordeControlState, 1);
|
||||
PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesAssaulted, 1);
|
||||
break;
|
||||
case ABEventIds.DefendedStablesHorde:
|
||||
UpdateWorldState(WorldStateIds.StablesAllianceControlState, 0);
|
||||
UpdateWorldState(WorldStateIds.StablesHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
if (player != null)
|
||||
UpdatePvpStat(player, (uint)ArathiBasinPvpStats.BasesDefended, 1);
|
||||
break;
|
||||
case ABEventIds.CaptureStablesHorde:
|
||||
UpdateWorldState(WorldStateIds.StablesHordeControlState, 2);
|
||||
PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
|
||||
break;
|
||||
default:
|
||||
Log.outWarn(LogFilter.Battleground, $"BattlegroundAB::ProcessEvent: Unhandled event {eventId}.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch ((CreatureIds)creature.GetEntry())
|
||||
{
|
||||
case CreatureIds.TheBlackBride:
|
||||
case CreatureIds.RadulfLeder:
|
||||
_creaturesToRemoveOnMatchStart.Add(creature.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject gameObject)
|
||||
{
|
||||
if (gameObject.GetGoInfo().type == GameObjectTypes.CapturePoint)
|
||||
_capturePoints.Add(gameObject.GetGUID());
|
||||
|
||||
switch ((GameobjectIds)gameObject.GetEntry())
|
||||
{
|
||||
case GameobjectIds.GhostGate:
|
||||
_gameobjectsToRemoveOnMatchStart.Add(gameObject.GetGUID());
|
||||
break;
|
||||
case GameobjectIds.AllianceDoor:
|
||||
case GameobjectIds.HordeDoor:
|
||||
_doors.Add(gameObject.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
UpdateWorldState(WorldStateIds.ResourcesMax, MiscConst.MaxTeamScore);
|
||||
UpdateWorldState(WorldStateIds.ResourcesWarning, MiscConst.WarningNearVictoryScore);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
base.Reset();
|
||||
|
||||
for (var i = 0; i < SharedConst.PvpTeamsCount; ++i)
|
||||
{
|
||||
m_TeamScores[i] = 0;
|
||||
m_HonorScoreTics[i] = 0;
|
||||
m_ReputationScoreTics[i] = 0;
|
||||
}
|
||||
|
||||
_pointsTimer.Reset(MiscConst.TickInterval);
|
||||
|
||||
m_IsInformedNearVictory = false;
|
||||
bool isBGWeekend = Global.BattlegroundMgr.IsBGWeekend(GetTypeID());
|
||||
m_HonorTics = isBGWeekend ? MiscConst.ABBGWeekendHonorTicks : MiscConst.NotABBGWeekendHonorTicks;
|
||||
m_ReputationTics = isBGWeekend ? MiscConst.ABBGWeekendReputationTicks : MiscConst.NotABBGWeekendReputationTicks;
|
||||
|
||||
_creaturesToRemoveOnMatchStart.Clear();
|
||||
_gameobjectsToRemoveOnMatchStart.Clear();
|
||||
_doors.Clear();
|
||||
_capturePoints.Clear();
|
||||
}
|
||||
|
||||
public override void EndBattleground(Team winner)
|
||||
{
|
||||
// Win reward
|
||||
if (winner == Team.Alliance)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
||||
if (winner == Team.Horde)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
||||
// Complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
||||
|
||||
base.EndBattleground(winner);
|
||||
}
|
||||
|
||||
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
|
||||
{
|
||||
return Global.ObjectMgr.GetClosestGraveyard(player.GetWorldLocation(), player.GetTeam(), player);
|
||||
}
|
||||
|
||||
public override WorldSafeLocsEntry GetExploitTeleportLocation(Team team)
|
||||
{
|
||||
return Global.ObjectMgr.GetWorldSafeLoc(team == Team.Alliance ? MiscConst.ExploitTeleportLocationAlliance : MiscConst.ExploitTeleportLocationHorde);
|
||||
}
|
||||
}
|
||||
|
||||
#region Constants
|
||||
struct MiscConst
|
||||
{
|
||||
public const uint NotABBGWeekendHonorTicks = 260;
|
||||
public const uint ABBGWeekendHonorTicks = 160;
|
||||
public const uint NotABBGWeekendReputationTicks = 160;
|
||||
public const uint ABBGWeekendReputationTicks = 120;
|
||||
|
||||
public const int WarningNearVictoryScore = 1400;
|
||||
public const int MaxTeamScore = 1500;
|
||||
|
||||
public const uint ExploitTeleportLocationAlliance = 3705;
|
||||
public const uint ExploitTeleportLocationHorde = 3706;
|
||||
|
||||
// Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
|
||||
public static TimeSpan TickInterval = TimeSpan.FromSeconds(2);
|
||||
public static uint[] TickPoints = { 0, 10, 10, 10, 10, 30 };
|
||||
}
|
||||
|
||||
enum ABEventIds
|
||||
{
|
||||
StartBattle = 9158, // Achievement: Let'S Get This Done
|
||||
|
||||
ContestedStablesHorde = 28523,
|
||||
CaptureStablesHorde = 28527,
|
||||
DefendedStablesHorde = 28525,
|
||||
ContestedStablesAlliance = 28522,
|
||||
CaptureStablesAlliance = 28526,
|
||||
DefendedStablesAlliance = 28524,
|
||||
|
||||
ContestedBlacksmithHorde = 8876,
|
||||
CaptureBlacksmithHorde = 8773,
|
||||
DefendedBlacksmithHorde = 8770,
|
||||
ContestedBlacksmithAlliance = 8874,
|
||||
CaptureBlacksmithAlliance = 8769,
|
||||
DefendedBlacksmithAlliance = 8774,
|
||||
|
||||
ContestedFarmHorde = 39398,
|
||||
CaptureFarmHorde = 39399,
|
||||
DefendedFarmHorde = 39400,
|
||||
ContestedFarmAlliance = 39401,
|
||||
CaptureFarmAlliance = 39402,
|
||||
DefendedFarmAlliance = 39403,
|
||||
|
||||
ContestedGoldMineHorde = 39404,
|
||||
CaptureGoldMineHorde = 39405,
|
||||
DefendedGoldMineHorde = 39406,
|
||||
ContestedGoldMineAlliance = 39407,
|
||||
CaptureGoldMineAlliance = 39408,
|
||||
DefendedGoldMineAlliance = 39409,
|
||||
|
||||
ContestedLumberMillHorde = 39387,
|
||||
CaptureLumberMillHorde = 39388,
|
||||
DefendedLumberMillHorde = 39389,
|
||||
ContestedLumberMillAlliance = 39390,
|
||||
CaptureLumberMillAlliance = 39391,
|
||||
DefendedLumberMillAlliance = 39392
|
||||
}
|
||||
|
||||
struct WorldStateIds
|
||||
{
|
||||
public const int OccupiedBasesHorde = 1778;
|
||||
public const int OccupiedBasesAlly = 1779;
|
||||
public const int ResourcesAlly = 1776;
|
||||
public const int ResourcesHorde = 1777;
|
||||
public const int ResourcesMax = 1780;
|
||||
public const int ResourcesWarning = 1955;
|
||||
|
||||
public const int StableIcon = 1842; // Stable Map Icon (None)
|
||||
public const int StableStateAlience = 1767; // Stable Map State (Alience)
|
||||
public const int StableStateHorde = 1768; // Stable Map State (Horde)
|
||||
public const int StableStateConAli = 1769; // Stable Map State (Con Alience)
|
||||
public const int StableStateConHor = 1770; // Stable Map State (Con Horde)
|
||||
public const int FarmIcon = 1845; // Farm Map Icon (None)
|
||||
public const int FarmStateAlience = 1772; // Farm State (Alience)
|
||||
public const int FarmStateHorde = 1773; // Farm State (Horde)
|
||||
public const int FarmStateConAli = 1774; // Farm State (Con Alience)
|
||||
public const int FarmStateConHor = 1775; // Farm State (Con Horde)
|
||||
public const int BlacksmithIcon = 1846; // Blacksmith Map Icon (None)
|
||||
public const int BlacksmithStateAlience = 1782; // Blacksmith Map State (Alience)
|
||||
public const int BlacksmithStateHorde = 1783; // Blacksmith Map State (Horde)
|
||||
public const int BlacksmithStateConAli = 1784; // Blacksmith Map State (Con Alience)
|
||||
public const int BlacksmithStateConHor = 1785; // Blacksmith Map State (Con Horde)
|
||||
public const int LumbermillIcon = 1844; // Lumber Mill Map Icon (None)
|
||||
public const int LumbermillStateAlience = 1792; // Lumber Mill Map State (Alience)
|
||||
public const int LumbermillStateHorde = 1793; // Lumber Mill Map State (Horde)
|
||||
public const int LumbermillStateConAli = 1794; // Lumber Mill Map State (Con Alience)
|
||||
public const int LumbermillStateConHor = 1795; // Lumber Mill Map State (Con Horde)
|
||||
public const int GoldmineIcon = 1843; // Gold Mine Map Icon (None)
|
||||
public const int GoldmineStateAlience = 1787; // Gold Mine Map State (Alience)
|
||||
public const int GoldmineStateHorde = 1788; // Gold Mine Map State (Horde)
|
||||
public const int GoldmineStateConAli = 1789; // Gold Mine Map State (Con Alience
|
||||
public const int GoldmineStateConHor = 1790; // Gold Mine Map State (Con Horde)
|
||||
|
||||
public const int Had500DisadvantageAlliance = 3644;
|
||||
public const int Had500DisadvantageHorde = 3645;
|
||||
|
||||
public const int FarmIconNew = 8808; // Farm Map Icon
|
||||
public const int LumberMillIconNew = 8805; // Lumber Mill Map Icon
|
||||
public const int BlacksmithIconNew = 8799; // Blacksmith Map Icon
|
||||
public const int GoldMineIconNew = 8809; // Gold Mine Map Icon
|
||||
public const int StablesIconNew = 5834; // Stable Map Icon
|
||||
|
||||
public const int FarmHordeControlState = 17328;
|
||||
public const int FarmAllianceControlState = 17325;
|
||||
public const int LumberMillHordeControlState = 17330;
|
||||
public const int LumberMillAllianceControlState = 17326;
|
||||
public const int BlacksmithHordeControlState = 17327;
|
||||
public const int BlacksmithAllianceControlState = 17324;
|
||||
public const int GoldMineHordeControlState = 17329;
|
||||
public const int GoldMineAllianceControlState = 17323;
|
||||
public const int StablesHordeControlState = 17331;
|
||||
public const int StablesAllianceControlState = 17322;
|
||||
}
|
||||
|
||||
// Object id templates from DB
|
||||
enum GameobjectIds
|
||||
{
|
||||
CapturePointStables = 227420,
|
||||
CapturePointBlacksmith = 227522,
|
||||
CapturePointFarm = 227536,
|
||||
CapturePointGoldMine = 227538,
|
||||
CapturePointLumberMill = 227544,
|
||||
|
||||
GhostGate = 180322,
|
||||
AllianceDoor = 322273,
|
||||
HordeDoor = 322274
|
||||
}
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
TheBlackBride = 150501,
|
||||
RadulfLeder = 150505
|
||||
}
|
||||
|
||||
struct ABBattlegroundNodes
|
||||
{
|
||||
public const int NodeStables = 0;
|
||||
public const int NodeBlacksmith = 1;
|
||||
public const int NodeFarm = 2;
|
||||
public const int NodeLumberMill = 3;
|
||||
public const int NodeGoldMine = 4;
|
||||
|
||||
public const int DynamicNodesCount = 5; // Dynamic Nodes That Can Be Captured
|
||||
|
||||
public const int SpiritAliance = 5;
|
||||
public const int SpiritHorde = 6;
|
||||
|
||||
public const int AllCount = 7; // All Nodes (Dynamic And Static)
|
||||
}
|
||||
|
||||
enum ABBattlegroundBroadcastTexts
|
||||
{
|
||||
AllianceNearVictory = 10598,
|
||||
HordeNearVictory = 10599
|
||||
}
|
||||
|
||||
enum SoundIds
|
||||
{
|
||||
NodeClaimed = 8192,
|
||||
NodeCapturedAlliance = 8173,
|
||||
NodeCapturedHorde = 8213,
|
||||
NodeAssaultedAlliance = 8212,
|
||||
NodeAssaultedHorde = 8174,
|
||||
NearVictoryAlliance = 8456,
|
||||
NearVictoryHorde = 8457
|
||||
}
|
||||
|
||||
enum ArathiBasinPvpStats
|
||||
{
|
||||
BasesAssaulted = 926,
|
||||
BasesDefended = 927,
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgBattleforGilneas : Battleground
|
||||
{
|
||||
public BgBattleforGilneas(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgBladesEdgeArena : Battleground
|
||||
{
|
||||
public BgBladesEdgeArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgDalaranSewers : Battleground
|
||||
{
|
||||
public BgDalaranSewers(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgDeepwindGorge : Battleground
|
||||
{
|
||||
public BgDeepwindGorge(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,803 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using Game.Entities.GameObjectType;
|
||||
using Game.Maps;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Game.BattleGrounds.Zones.EyeofStorm
|
||||
{
|
||||
class BgEyeofStorm : Battleground
|
||||
{
|
||||
uint[] m_HonorScoreTics = new uint[SharedConst.PvpTeamsCount];
|
||||
uint m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured
|
||||
|
||||
TimeTracker _pointsTimer;
|
||||
uint m_HonorTics;
|
||||
|
||||
Dictionary<uint, BgEyeOfStormControlZoneHandler> _controlZoneHandlers = new();
|
||||
List<ObjectGuid> _doorGUIDs = new();
|
||||
ObjectGuid _flagGUID;
|
||||
|
||||
// Focused/Brutal Assault
|
||||
bool _assaultEnabled;
|
||||
TimeTracker _flagAssaultTimer;
|
||||
byte _assaultStackCount;
|
||||
|
||||
public BgEyeofStorm(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate)
|
||||
{
|
||||
m_HonorScoreTics = [0, 0];
|
||||
m_FlagCapturedBgObjectType = 0;
|
||||
m_HonorTics = 0;
|
||||
_pointsTimer = new(MiscConst.PointsTickTime);
|
||||
_assaultEnabled = false;
|
||||
_assaultStackCount = 0;
|
||||
_flagAssaultTimer = new(MiscConst.FlagAssaultTimer);
|
||||
}
|
||||
|
||||
public override void PostUpdateImpl(uint diff)
|
||||
{
|
||||
if (GetStatus() == BattlegroundStatus.InProgress)
|
||||
{
|
||||
_pointsTimer.Update(diff);
|
||||
if (_pointsTimer.Passed())
|
||||
{
|
||||
_pointsTimer.Reset(MiscConst.PointsTickTime);
|
||||
|
||||
byte baseCountAlliance = GetControlledBaseCount(BattleGroundTeamId.Alliance);
|
||||
byte baseCountHorde = GetControlledBaseCount(BattleGroundTeamId.Horde);
|
||||
if (baseCountAlliance > 0)
|
||||
AddPoints(Team.Alliance, MiscConst.TickPoints[baseCountAlliance - 1]);
|
||||
if (baseCountHorde > 0)
|
||||
AddPoints(Team.Horde, MiscConst.TickPoints[baseCountHorde - 1]);
|
||||
}
|
||||
|
||||
if (_assaultEnabled)
|
||||
{
|
||||
_flagAssaultTimer.Update(diff);
|
||||
if (_flagAssaultTimer.Passed())
|
||||
{
|
||||
_flagAssaultTimer.Reset(MiscConst.FlagAssaultTimer);
|
||||
_assaultStackCount++;
|
||||
|
||||
// update assault debuff stacks
|
||||
DoForFlagKeepers(player => ApplyAssaultDebuffToPlayer(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartingEventOpenDoors()
|
||||
{
|
||||
foreach (ObjectGuid door in _doorGUIDs)
|
||||
{
|
||||
GameObject gameObject = GetBgMap().GetGameObject(door);
|
||||
if (gameObject != null)
|
||||
{
|
||||
gameObject.UseDoorOrButton();
|
||||
gameObject.DespawnOrUnsummon(TimeSpan.FromSeconds(3));
|
||||
}
|
||||
}
|
||||
|
||||
// Achievement: Flurry
|
||||
TriggerGameEvent(MiscConst.EventStartBattle);
|
||||
}
|
||||
|
||||
void AddPoints(Team Team, uint Points)
|
||||
{
|
||||
int team_index = GetTeamIndexByTeamId(Team);
|
||||
m_TeamScores[team_index] += Points;
|
||||
m_HonorScoreTics[team_index] += Points;
|
||||
if (m_HonorScoreTics[team_index] >= m_HonorTics)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
|
||||
m_HonorScoreTics[team_index] -= m_HonorTics;
|
||||
}
|
||||
UpdateTeamScore(team_index);
|
||||
}
|
||||
|
||||
byte GetControlledBaseCount(int teamId)
|
||||
{
|
||||
byte baseCount = 0;
|
||||
foreach (var controlZoneHandler in _controlZoneHandlers)
|
||||
{
|
||||
uint point = controlZoneHandler.Value.GetPoint();
|
||||
switch (teamId)
|
||||
{
|
||||
case BattleGroundTeamId.Alliance:
|
||||
if (GetBgMap().GetWorldStateValue(MiscConst.m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
|
||||
baseCount++;
|
||||
break;
|
||||
case BattleGroundTeamId.Horde:
|
||||
if (GetBgMap().GetWorldStateValue(MiscConst.m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
|
||||
baseCount++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return baseCount;
|
||||
}
|
||||
|
||||
void DoForFlagKeepers(Action<Player> action)
|
||||
{
|
||||
GameObject flag = GetBgMap().GetGameObject(_flagGUID);
|
||||
if (flag != null)
|
||||
{
|
||||
Player carrier = Global.ObjAccessor.FindPlayer(flag.GetFlagCarrierGUID());
|
||||
if (carrier != null)
|
||||
action(carrier);
|
||||
}
|
||||
}
|
||||
|
||||
void ResetAssaultDebuff()
|
||||
{
|
||||
_assaultEnabled = false;
|
||||
_assaultStackCount = 0;
|
||||
_flagAssaultTimer.Reset(MiscConst.FlagAssaultTimer);
|
||||
DoForFlagKeepers(RemoveAssaultDebuffFromPlayer);
|
||||
}
|
||||
|
||||
void ApplyAssaultDebuffToPlayer(Player player)
|
||||
{
|
||||
if (_assaultStackCount == 0)
|
||||
return;
|
||||
|
||||
uint spellId = MiscConst.SpellFocusedAssault;
|
||||
if (_assaultStackCount >= MiscConst.FlagBrutalAssaultStackCount)
|
||||
{
|
||||
player.RemoveAurasDueToSpell(MiscConst.SpellFocusedAssault);
|
||||
spellId = MiscConst.SpellBrutalAssault;
|
||||
}
|
||||
|
||||
Aura aura = player.GetAura(spellId);
|
||||
if (aura == null)
|
||||
{
|
||||
player.CastSpell(player, spellId, true);
|
||||
aura = player.GetAura(spellId);
|
||||
}
|
||||
|
||||
if (aura != null)
|
||||
aura.SetStackAmount(_assaultStackCount);
|
||||
}
|
||||
|
||||
void RemoveAssaultDebuffFromPlayer(Player player)
|
||||
{
|
||||
player.RemoveAurasDueToSpell(MiscConst.SpellFocusedAssault);
|
||||
player.RemoveAurasDueToSpell(MiscConst.SpellBrutalAssault);
|
||||
}
|
||||
|
||||
void UpdateTeamScore(int team)
|
||||
{
|
||||
uint score = GetTeamScore(team);
|
||||
if (score >= ScoreIds.MaxTeamScore)
|
||||
{
|
||||
score = ScoreIds.MaxTeamScore;
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
EndBattleground(Team.Alliance);
|
||||
else
|
||||
EndBattleground(Team.Horde);
|
||||
}
|
||||
|
||||
if (team == BattleGroundTeamId.Alliance)
|
||||
UpdateWorldState(WorldStateIds.AllianceResources, (int)score);
|
||||
else
|
||||
UpdateWorldState(WorldStateIds.HordeResources, (int)score);
|
||||
}
|
||||
|
||||
public override void EndBattleground(Team winner)
|
||||
{
|
||||
// Win reward
|
||||
if (winner == Team.Alliance)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
||||
if (winner == Team.Horde)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
||||
|
||||
// Complete map reward
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
||||
|
||||
base.EndBattleground(winner);
|
||||
}
|
||||
|
||||
void UpdatePointsCount(uint teamId)
|
||||
{
|
||||
if (teamId == BattleGroundTeamId.Alliance)
|
||||
UpdateWorldState(WorldStateIds.AllianceBase, GetControlledBaseCount(BattleGroundTeamId.Alliance));
|
||||
else
|
||||
UpdateWorldState(WorldStateIds.HordeBase, GetControlledBaseCount(BattleGroundTeamId.Horde));
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject gameobject)
|
||||
{
|
||||
switch (gameobject.GetEntry())
|
||||
{
|
||||
case GameobjectIds.ADoorEyEntry:
|
||||
case GameobjectIds.HDoorEyEntry:
|
||||
_doorGUIDs.Add(gameobject.GetGUID());
|
||||
break;
|
||||
case GameobjectIds.Flag2EyEntry:
|
||||
_flagGUID = gameobject.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanCaptureFlag(AreaTrigger areaTrigger, Player player)
|
||||
{
|
||||
if (areaTrigger.GetEntry() != MiscConst.AreatriggerCaptureFlag)
|
||||
return false;
|
||||
|
||||
GameObject flag = GetBgMap().GetGameObject(_flagGUID);
|
||||
if (flag != null)
|
||||
{
|
||||
if (flag.GetFlagCarrierGUID() != player.GetGUID())
|
||||
return false;
|
||||
}
|
||||
|
||||
GameObject controlzone = player.FindNearestGameObjectWithOptions(40.0f, new FindGameObjectOptions() { StringId = "bg_eye_of_the_storm_control_zone" });
|
||||
if (controlzone != null)
|
||||
{
|
||||
uint point = _controlZoneHandlers[controlzone.GetEntry()].GetPoint();
|
||||
switch (GetPlayerTeam(player.GetGUID()))
|
||||
{
|
||||
case Team.Alliance:
|
||||
return GetBgMap().GetWorldStateValue(MiscConst.m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
|
||||
case Team.Horde:
|
||||
return GetBgMap().GetWorldStateValue(MiscConst.m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnCaptureFlag(AreaTrigger areaTrigger, Player player)
|
||||
{
|
||||
if (areaTrigger.GetEntry() != MiscConst.AreatriggerCaptureFlag)
|
||||
return;
|
||||
|
||||
uint baseCount = GetControlledBaseCount(GetTeamIndexByTeamId(GetPlayerTeam(player.GetGUID())));
|
||||
|
||||
GameObject gameObject = GetBgMap().GetGameObject(_flagGUID);
|
||||
if (gameObject != null)
|
||||
gameObject.HandleCustomTypeCommand(new SetNewFlagState(FlagState.Respawning, player));
|
||||
|
||||
Team team = GetPlayerTeam(player.GetGUID());
|
||||
if (team == Team.Alliance)
|
||||
{
|
||||
SendBroadcastText(BroadcastTextIds.AllianceCapturedFlag, ChatMsg.BgSystemAlliance, player);
|
||||
PlaySoundToAll(SoundIds.FlagCapturedAlliance);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendBroadcastText(BroadcastTextIds.HordeCapturedFlag, ChatMsg.BgSystemHorde, player);
|
||||
PlaySoundToAll(SoundIds.FlagCapturedHorde);
|
||||
}
|
||||
|
||||
if (baseCount > 0)
|
||||
AddPoints(team, MiscConst.FlagPoints[baseCount - 1]);
|
||||
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateHorde, (int)EYFlagState.OnBase);
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateAlliance, (int)EYFlagState.OnBase);
|
||||
|
||||
UpdatePvpStat(player, MiscConst.PvpStatFlagCaptures, 1);
|
||||
|
||||
player.RemoveAurasDueToSpell(MiscConst.SpellNetherstormFlag);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
}
|
||||
|
||||
public override void OnFlagStateChange(GameObject flagInBase, FlagState oldValue, FlagState newValue, Player player)
|
||||
{
|
||||
switch (newValue)
|
||||
{
|
||||
case FlagState.InBase:
|
||||
ResetAssaultDebuff();
|
||||
break;
|
||||
case FlagState.Dropped:
|
||||
player.CastSpell(player, BattlegroundConst.SpellRecentlyDroppedNeutralFlag, true);
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateHorde, (int)EYFlagState.WaitRespawn);
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateAlliance, (int)EYFlagState.WaitRespawn);
|
||||
|
||||
if (GetPlayerTeam(player.GetGUID()) == Team.Alliance)
|
||||
SendBroadcastText(BroadcastTextIds.FlagDropped, ChatMsg.BgSystemAlliance);
|
||||
else
|
||||
SendBroadcastText(BroadcastTextIds.FlagDropped, ChatMsg.BgSystemHorde);
|
||||
break;
|
||||
case FlagState.Taken:
|
||||
if (GetPlayerTeam(player.GetGUID()) == Team.Alliance)
|
||||
{
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateAlliance, (int)EYFlagState.OnPlayer);
|
||||
PlaySoundToAll(SoundIds.FlagPickedUpAlliance);
|
||||
SendBroadcastText(BroadcastTextIds.TakenFlag, ChatMsg.BgSystemAlliance, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlagStateHorde, (int)EYFlagState.OnPlayer);
|
||||
PlaySoundToAll(SoundIds.FlagPickedUpHorde);
|
||||
SendBroadcastText(BroadcastTextIds.TakenFlag, ChatMsg.BgSystemHorde, player);
|
||||
}
|
||||
|
||||
ApplyAssaultDebuffToPlayer(player);
|
||||
_assaultEnabled = true;
|
||||
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
break;
|
||||
case FlagState.Respawning:
|
||||
ResetAssaultDebuff();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateWorldState(WorldStateIds.NetherstormFlag, (int)newValue);
|
||||
}
|
||||
|
||||
public override bool SetupBattleground()
|
||||
{
|
||||
UpdateWorldState(WorldStateIds.MaxResources, (int)ScoreIds.MaxTeamScore);
|
||||
|
||||
_controlZoneHandlers[GameobjectIds.FrTowerCapEyEntry] = new BgEyeOfStormControlZoneHandler(this, Points.FelReaver);
|
||||
_controlZoneHandlers[GameobjectIds.BeTowerCapEyEntry] = new BgEyeOfStormControlZoneHandler(this, Points.BloodElf);
|
||||
_controlZoneHandlers[GameobjectIds.DrTowerCapEyEntry] = new BgEyeOfStormControlZoneHandler(this, Points.DraeneiRuins);
|
||||
_controlZoneHandlers[GameobjectIds.HuTowerCapEyEntry] = new BgEyeOfStormControlZoneHandler(this, Points.MageTower);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
base.Reset();
|
||||
|
||||
m_TeamScores[BattleGroundTeamId.Alliance] = 0;
|
||||
m_TeamScores[BattleGroundTeamId.Horde] = 0;
|
||||
m_HonorScoreTics = [0, 0];
|
||||
m_FlagCapturedBgObjectType = 0;
|
||||
bool isBGWeekend = Global.BattlegroundMgr.IsBGWeekend(GetTypeID());
|
||||
m_HonorTics = isBGWeekend ? MiscConst.EYWeekendHonorTicks : MiscConst.NotEYWeekendHonorTicks;
|
||||
}
|
||||
|
||||
public override void HandleKillPlayer(Player player, Player killer)
|
||||
{
|
||||
if (GetStatus() != BattlegroundStatus.InProgress)
|
||||
return;
|
||||
|
||||
base.HandleKillPlayer(player, killer);
|
||||
EventPlayerDroppedFlag(player);
|
||||
}
|
||||
|
||||
public void EventTeamLostPoint(uint teamId, uint point, WorldObject controlZone)
|
||||
{
|
||||
if (teamId == BattleGroundTeamId.Alliance)
|
||||
{
|
||||
SendBroadcastText(MiscConst.m_LosingPointTypes[point].MessageIdAlliance, ChatMsg.BgSystemAlliance, controlZone);
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
|
||||
}
|
||||
else if (teamId == BattleGroundTeamId.Horde)
|
||||
{
|
||||
SendBroadcastText(MiscConst.m_LosingPointTypes[point].MessageIdHorde, ChatMsg.BgSystemHorde, controlZone);
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
|
||||
}
|
||||
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateControlIndex, 1);
|
||||
UpdatePointsCount(teamId);
|
||||
}
|
||||
|
||||
public void EventTeamCapturedPoint(uint teamId, uint point, WorldObject controlZone)
|
||||
{
|
||||
if (teamId == BattleGroundTeamId.Alliance)
|
||||
{
|
||||
SendBroadcastText(MiscConst.m_CapturingPointTypes[point].MessageIdAlliance, ChatMsg.BgSystemAlliance, controlZone);
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
|
||||
}
|
||||
else if (teamId == BattleGroundTeamId.Horde)
|
||||
{
|
||||
SendBroadcastText(MiscConst.m_CapturingPointTypes[point].MessageIdHorde, ChatMsg.BgSystemHorde, controlZone);
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
|
||||
}
|
||||
|
||||
UpdateWorldState(MiscConst.m_PointsIconStruct[point].WorldStateControlIndex, 0);
|
||||
UpdatePointsCount(teamId);
|
||||
}
|
||||
|
||||
public override WorldSafeLocsEntry GetExploitTeleportLocation(Team team)
|
||||
{
|
||||
return Global.ObjectMgr.GetWorldSafeLoc(team == Team.Alliance ? MiscConst.ExploitTeleportLocationAlliance : MiscConst.ExploitTeleportLocationHorde);
|
||||
}
|
||||
|
||||
public override Team GetPrematureWinner()
|
||||
{
|
||||
if (GetTeamScore(BattleGroundTeamId.Alliance) > GetTeamScore(BattleGroundTeamId.Horde))
|
||||
return Team.Alliance;
|
||||
else if (GetTeamScore(BattleGroundTeamId.Horde) > GetTeamScore(BattleGroundTeamId.Alliance))
|
||||
return Team.Horde;
|
||||
|
||||
return base.GetPrematureWinner();
|
||||
}
|
||||
|
||||
public override void ProcessEvent(WorldObject target, uint eventId, WorldObject invoker)
|
||||
{
|
||||
base.ProcessEvent(target, eventId, invoker);
|
||||
|
||||
if (invoker != null)
|
||||
{
|
||||
GameObject gameobject = invoker.ToGameObject();
|
||||
if (gameobject != null)
|
||||
{
|
||||
if (gameobject.GetGoType() == GameObjectTypes.ControlZone)
|
||||
{
|
||||
if (!_controlZoneHandlers.TryGetValue(gameobject.GetEntry(), out BgEyeOfStormControlZoneHandler handler))
|
||||
return;
|
||||
|
||||
var controlzone = gameobject.GetGoInfo().ControlZone;
|
||||
if (eventId == controlzone.NeutralEventAlliance)
|
||||
handler.HandleNeutralEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventHorde)
|
||||
handler.HandleNeutralEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventAlliance)
|
||||
handler.HandleProgressEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventHorde)
|
||||
handler.HandleProgressEventHorde(gameobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePoint(Team team, uint Points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] -= Points; }
|
||||
|
||||
void SetTeamPoint(Team team, uint Points = 0) { m_TeamScores[GetTeamIndexByTeamId(team)] = Points; }
|
||||
}
|
||||
|
||||
struct BgEyeOfStormPointIconsStruct
|
||||
{
|
||||
public BgEyeOfStormPointIconsStruct(uint worldStateControlIndex, int worldStateAllianceControlledIndex, int worldStateHordeControlledIndex, uint worldStateAllianceStatusBarIcon, uint worldStateHordeStatusBarIcon)
|
||||
{
|
||||
WorldStateControlIndex = worldStateControlIndex;
|
||||
WorldStateAllianceControlledIndex = worldStateAllianceControlledIndex;
|
||||
WorldStateHordeControlledIndex = worldStateHordeControlledIndex;
|
||||
WorldStateAllianceStatusBarIcon = worldStateAllianceStatusBarIcon;
|
||||
WorldStateHordeStatusBarIcon = worldStateHordeStatusBarIcon;
|
||||
}
|
||||
|
||||
public uint WorldStateControlIndex;
|
||||
public int WorldStateAllianceControlledIndex;
|
||||
public int WorldStateHordeControlledIndex;
|
||||
public uint WorldStateAllianceStatusBarIcon;
|
||||
public uint WorldStateHordeStatusBarIcon;
|
||||
}
|
||||
|
||||
struct BgEyeOfStormLosingPointStruct
|
||||
{
|
||||
public BgEyeOfStormLosingPointStruct(int _SpawnNeutralObjectType, int _DespawnObjectTypeAlliance, uint _MessageIdAlliance, int _DespawnObjectTypeHorde, uint _MessageIdHorde)
|
||||
{
|
||||
SpawnNeutralObjectType = _SpawnNeutralObjectType;
|
||||
DespawnObjectTypeAlliance = _DespawnObjectTypeAlliance;
|
||||
MessageIdAlliance = _MessageIdAlliance;
|
||||
DespawnObjectTypeHorde = _DespawnObjectTypeHorde;
|
||||
MessageIdHorde = _MessageIdHorde;
|
||||
}
|
||||
|
||||
public int SpawnNeutralObjectType;
|
||||
public int DespawnObjectTypeAlliance;
|
||||
public uint MessageIdAlliance;
|
||||
public int DespawnObjectTypeHorde;
|
||||
public uint MessageIdHorde;
|
||||
}
|
||||
|
||||
struct BgEyeOfStormCapturingPointStruct
|
||||
{
|
||||
public BgEyeOfStormCapturingPointStruct(int _DespawnNeutralObjectType, int _SpawnObjectTypeAlliance, uint _MessageIdAlliance, int _SpawnObjectTypeHorde, uint _MessageIdHorde, uint _GraveyardId)
|
||||
{
|
||||
DespawnNeutralObjectType = _DespawnNeutralObjectType;
|
||||
SpawnObjectTypeAlliance = _SpawnObjectTypeAlliance;
|
||||
MessageIdAlliance = _MessageIdAlliance;
|
||||
SpawnObjectTypeHorde = _SpawnObjectTypeHorde;
|
||||
MessageIdHorde = _MessageIdHorde;
|
||||
GraveyardId = _GraveyardId;
|
||||
}
|
||||
|
||||
public int DespawnNeutralObjectType;
|
||||
public int SpawnObjectTypeAlliance;
|
||||
public uint MessageIdAlliance;
|
||||
public int SpawnObjectTypeHorde;
|
||||
public uint MessageIdHorde;
|
||||
public uint GraveyardId;
|
||||
}
|
||||
|
||||
class BgEyeOfStormControlZoneHandler : ControlZoneHandler
|
||||
{
|
||||
BgEyeofStorm _battleground;
|
||||
uint _point;
|
||||
|
||||
public BgEyeOfStormControlZoneHandler(BgEyeofStorm bg, uint point)
|
||||
{
|
||||
_battleground = bg;
|
||||
_point = point;
|
||||
}
|
||||
|
||||
public override void HandleProgressEventHorde(GameObject controlZone)
|
||||
{
|
||||
_battleground.EventTeamCapturedPoint(BattleGroundTeamId.Horde, _point, controlZone);
|
||||
}
|
||||
|
||||
public override void HandleProgressEventAlliance(GameObject controlZone)
|
||||
{
|
||||
_battleground.EventTeamCapturedPoint(BattleGroundTeamId.Alliance, _point, controlZone);
|
||||
}
|
||||
|
||||
public override void HandleNeutralEventHorde(GameObject controlZone)
|
||||
{
|
||||
_battleground.EventTeamLostPoint(BattleGroundTeamId.Horde, _point, controlZone);
|
||||
}
|
||||
|
||||
public override void HandleNeutralEventAlliance(GameObject controlZone)
|
||||
{
|
||||
_battleground.EventTeamLostPoint(BattleGroundTeamId.Alliance, _point, controlZone);
|
||||
}
|
||||
|
||||
public uint GetPoint() { return _point; }
|
||||
}
|
||||
|
||||
#region Constants
|
||||
struct MiscConst
|
||||
{
|
||||
public static TimeSpan PointsTickTime = TimeSpan.FromSeconds(2);
|
||||
public static TimeSpan FlagAssaultTimer = TimeSpan.FromSeconds(30);
|
||||
public static ushort FlagBrutalAssaultStackCount = 5;
|
||||
|
||||
public const uint EventStartBattle = 13180; // Achievement: Flurry
|
||||
|
||||
public const uint NotEYWeekendHonorTicks = 260;
|
||||
public const uint EYWeekendHonorTicks = 160;
|
||||
|
||||
public const uint SpellNetherstormFlag = 34976;
|
||||
// Focused/Brutal Assault
|
||||
public const uint SpellFocusedAssault = 46392;
|
||||
public const uint SpellBrutalAssault = 46393;
|
||||
|
||||
public const uint ExploitTeleportLocationAlliance = 3773;
|
||||
public const uint ExploitTeleportLocationHorde = 3772;
|
||||
|
||||
public static byte[] TickPoints = { 1, 2, 5, 10 };
|
||||
public static uint[] FlagPoints = { 75, 85, 100, 500 };
|
||||
|
||||
public const uint AreatriggerCaptureFlag = 33;
|
||||
|
||||
public const uint PvpStatFlagCaptures = 183;
|
||||
|
||||
public static BgEyeOfStormPointIconsStruct[] m_PointsIconStruct =
|
||||
{
|
||||
new BgEyeOfStormPointIconsStruct(WorldStateIds.FelReaverUncontrol, WorldStateIds.FelReaverAllianceControl, WorldStateIds.FelReaverHordeControl, WorldStateIds.FelReaverAllianceControlState, WorldStateIds.FelReaverHordeControlState),
|
||||
new BgEyeOfStormPointIconsStruct(WorldStateIds.BloodElfUncontrol, WorldStateIds.BloodElfAllianceControl, WorldStateIds.BloodElfHordeControl, WorldStateIds.BloodElfAllianceControlState, WorldStateIds.BloodElfHordeControlState),
|
||||
new BgEyeOfStormPointIconsStruct(WorldStateIds.DraeneiRuinsUncontrol, WorldStateIds.DraeneiRuinsAllianceControl, WorldStateIds.DraeneiRuinsHordeControl, WorldStateIds.DraeneiRuinsAllianceControlState, WorldStateIds.DraeneiRuinsHordeControlState),
|
||||
new BgEyeOfStormPointIconsStruct(WorldStateIds.MageTowerUncontrol, WorldStateIds.MageTowerAllianceControl, WorldStateIds.MageTowerHordeControl, WorldStateIds.MageTowerAllianceControlState, WorldStateIds.MageTowerHordeControlState)
|
||||
};
|
||||
public static BgEyeOfStormLosingPointStruct[] m_LosingPointTypes =
|
||||
{
|
||||
new BgEyeOfStormLosingPointStruct(ObjectTypes.NBannerFelReaverCenter, ObjectTypes.ABannerFelReaverCenter, BroadcastTextIds.AllianceLostFelReaverRuins, ObjectTypes.HBannerFelReaverCenter, BroadcastTextIds.HordeLostFelReaverRuins),
|
||||
new BgEyeOfStormLosingPointStruct(ObjectTypes.NBannerBloodElfCenter, ObjectTypes.ABannerBloodElfCenter, BroadcastTextIds.AllianceLostBloodElfTower, ObjectTypes.HBannerBloodElfCenter, BroadcastTextIds.HordeLostBloodElfTower),
|
||||
new BgEyeOfStormLosingPointStruct(ObjectTypes.NBannerDraeneiRuinsCenter, ObjectTypes.ABannerDraeneiRuinsCenter, BroadcastTextIds.AllianceLostDraeneiRuins, ObjectTypes.HBannerDraeneiRuinsCenter, BroadcastTextIds.HordeLostDraeneiRuins),
|
||||
new BgEyeOfStormLosingPointStruct(ObjectTypes.NBannerMageTowerCenter, ObjectTypes.ABannerMageTowerCenter, BroadcastTextIds.AllianceLostMageTower, ObjectTypes.HBannerMageTowerCenter, BroadcastTextIds.HordeLostMageTower)
|
||||
};
|
||||
public static BgEyeOfStormCapturingPointStruct[] m_CapturingPointTypes =
|
||||
{
|
||||
new BgEyeOfStormCapturingPointStruct(ObjectTypes.NBannerFelReaverCenter, ObjectTypes.ABannerFelReaverCenter, BroadcastTextIds.AllianceTakenFelReaverRuins, ObjectTypes.HBannerFelReaverCenter, BroadcastTextIds.HordeTakenFelReaverRuins, GaveyardIds.FelReaver),
|
||||
new BgEyeOfStormCapturingPointStruct(ObjectTypes.NBannerBloodElfCenter, ObjectTypes.ABannerBloodElfCenter, BroadcastTextIds.AllianceTakenBloodElfTower, ObjectTypes.HBannerBloodElfCenter, BroadcastTextIds.HordeTakenBloodElfTower, GaveyardIds.BloodElf),
|
||||
new BgEyeOfStormCapturingPointStruct(ObjectTypes.NBannerDraeneiRuinsCenter, ObjectTypes.ABannerDraeneiRuinsCenter, BroadcastTextIds.AllianceTakenDraeneiRuins, ObjectTypes.HBannerDraeneiRuinsCenter, BroadcastTextIds.HordeTakenDraeneiRuins, GaveyardIds.DraeneiRuins),
|
||||
new BgEyeOfStormCapturingPointStruct(ObjectTypes.NBannerMageTowerCenter, ObjectTypes.ABannerMageTowerCenter, BroadcastTextIds.AllianceTakenMageTower, ObjectTypes.HBannerMageTowerCenter, BroadcastTextIds.HordeTakenMageTower, GaveyardIds.MageTower)
|
||||
};
|
||||
}
|
||||
|
||||
struct BroadcastTextIds
|
||||
{
|
||||
public const uint AllianceTakenFelReaverRuins = 17828;
|
||||
public const uint HordeTakenFelReaverRuins = 17829;
|
||||
public const uint AllianceLostFelReaverRuins = 17835;
|
||||
public const uint HordeLostFelReaverRuins = 17836;
|
||||
|
||||
public const uint AllianceTakenBloodElfTower = 17819;
|
||||
public const uint HordeTakenBloodElfTower = 17823;
|
||||
public const uint AllianceLostBloodElfTower = 17831;
|
||||
public const uint HordeLostBloodElfTower = 17832;
|
||||
|
||||
public const uint AllianceTakenDraeneiRuins = 17827;
|
||||
public const uint HordeTakenDraeneiRuins = 17826;
|
||||
public const uint AllianceLostDraeneiRuins = 17833;
|
||||
public const uint HordeLostDraeneiRuins = 17834;
|
||||
|
||||
public const uint AllianceTakenMageTower = 17824;
|
||||
public const uint HordeTakenMageTower = 17825;
|
||||
public const uint AllianceLostMageTower = 17837;
|
||||
public const uint HordeLostMageTower = 17838;
|
||||
|
||||
public const uint TakenFlag = 18359;
|
||||
public const uint FlagDropped = 18361;
|
||||
public const uint FlagReset = 18364;
|
||||
public const uint AllianceCapturedFlag = 18375;
|
||||
public const uint HordeCapturedFlag = 18384;
|
||||
}
|
||||
|
||||
struct WorldStateIds
|
||||
{
|
||||
public const int AllianceResources = 1776;
|
||||
public const int HordeResources = 1777;
|
||||
public const int MaxResources = 1780;
|
||||
public const int AllianceBase = 2752;
|
||||
public const int HordeBase = 2753;
|
||||
public const int DraeneiRuinsHordeControl = 2733;
|
||||
public const int DraeneiRuinsAllianceControl = 2732;
|
||||
public const int DraeneiRuinsUncontrol = 2731;
|
||||
public const int MageTowerAllianceControl = 2730;
|
||||
public const int MageTowerHordeControl = 2729;
|
||||
public const int MageTowerUncontrol = 2728;
|
||||
public const int FelReaverHordeControl = 2727;
|
||||
public const int FelReaverAllianceControl = 2726;
|
||||
public const int FelReaverUncontrol = 2725;
|
||||
public const int BloodElfHordeControl = 2724;
|
||||
public const int BloodElfAllianceControl = 2723;
|
||||
public const int BloodElfUncontrol = 2722;
|
||||
public const int ProgressBarPercentGrey = 2720; //100 = Empty (Only Grey); 0 = Blue|Red (No Grey)
|
||||
public const int ProgressBarStatus = 2719; //50 Init!; 48 ... Hordak Bere .. 33 .. 0 = Full 100% Hordacky; 100 = Full Alliance
|
||||
public const int ProgressBarShow = 2718; //1 Init; 0 Druhy Send - Bez Messagu; 1 = Controlled Aliance
|
||||
public const int NetherstormFlag = 8863;
|
||||
//Set To 2 When Flag Is Picked Up; And To 1 If It Is Dropped
|
||||
public const int NetherstormFlagStateAlliance = 9808;
|
||||
public const int NetherstormFlagStateHorde = 9809;
|
||||
|
||||
public const int DraeneiRuinsHordeControlState = 17362;
|
||||
public const int DraeneiRuinsAllianceControlState = 17366;
|
||||
public const int MageTowerHordeControlState = 17361;
|
||||
public const int MageTowerAllianceControlState = 17368;
|
||||
public const int FelReaverHordeControlState = 17364;
|
||||
public const int FelReaverAllianceControlState = 17367;
|
||||
public const int BloodElfHordeControlState = 17363;
|
||||
public const int BloodElfAllianceControlState = 17365;
|
||||
}
|
||||
|
||||
struct SoundIds
|
||||
{
|
||||
//strange ids, but sure about them
|
||||
public const uint FlagPickedUpAlliance = 8212;
|
||||
public const uint FlagCapturedHorde = 8213;
|
||||
public const uint FlagPickedUpHorde = 8174;
|
||||
public const uint FlagCapturedAlliance = 8173;
|
||||
public const uint FlagReset = 8192;
|
||||
}
|
||||
|
||||
struct GameobjectIds
|
||||
{
|
||||
public const uint ADoorEyEntry = 184719; //Alliance Door
|
||||
public const uint HDoorEyEntry = 184720; //Horde Door
|
||||
public const uint Flag1EyEntry = 184493; //Netherstorm Flag (Generic)
|
||||
public const uint Flag2EyEntry = 208977; //Netherstorm Flag (Flagstand)
|
||||
public const uint ABannerEyEntry = 184381; //Visual Banner (Alliance)
|
||||
public const uint HBannerEyEntry = 184380; //Visual Banner (Horde)
|
||||
public const uint NBannerEyEntry = 184382; //Visual Banner (Neutral)
|
||||
public const uint BeTowerCapEyEntry = 184080; //Be Tower Cap Pt
|
||||
public const uint FrTowerCapEyEntry = 184081; //Fel Reaver Cap Pt
|
||||
public const uint HuTowerCapEyEntry = 184082; //Human Tower Cap Pt
|
||||
public const uint DrTowerCapEyEntry = 184083; //Draenei Tower Cap Pt
|
||||
public const uint SpeedBuffFelReaverEyEntry = 184970;
|
||||
public const uint RestorationBuffFelReaverEyEntry = 184971;
|
||||
public const uint BerserkBuffFelReaverEyEntry = 184972;
|
||||
public const uint SpeedBuffBloodElfEyEntry = 184964;
|
||||
public const uint RestorationBuffBloodElfEyEntry = 184965;
|
||||
public const uint BerserkBuffBloodElfEyEntry = 184966;
|
||||
public const uint SpeedBuffDraeneiRuinsEyEntry = 184976;
|
||||
public const uint RestorationBuffDraeneiRuinsEyEntry = 184977;
|
||||
public const uint BerserkBuffDraeneiRuinsEyEntry = 184978;
|
||||
public const uint SpeedBuffMageTowerEyEntry = 184973;
|
||||
public const uint RestorationBuffMageTowerEyEntry = 184974;
|
||||
public const uint BerserkBuffMageTowerEyEntry = 184975;
|
||||
}
|
||||
|
||||
struct GaveyardIds
|
||||
{
|
||||
public const int MainAlliance = 1103;
|
||||
public const uint MainHorde = 1104;
|
||||
public const uint FelReaver = 1105;
|
||||
public const uint BloodElf = 1106;
|
||||
public const uint DraeneiRuins = 1107;
|
||||
public const uint MageTower = 1108;
|
||||
}
|
||||
|
||||
struct Points
|
||||
{
|
||||
public const int FelReaver = 0;
|
||||
public const int BloodElf = 1;
|
||||
public const int DraeneiRuins = 2;
|
||||
public const int MageTower = 3;
|
||||
|
||||
public const int PlayersOutOfPoints = 4;
|
||||
public const int PointsMax = 4;
|
||||
}
|
||||
|
||||
struct ObjectTypes
|
||||
{
|
||||
public const int DoorA = 0;
|
||||
public const int DoorH = 1;
|
||||
public const int ABannerFelReaverCenter = 2;
|
||||
public const int ABannerFelReaverLeft = 3;
|
||||
public const int ABannerFelReaverRight = 4;
|
||||
public const int ABannerBloodElfCenter = 5;
|
||||
public const int ABannerBloodElfLeft = 6;
|
||||
public const int ABannerBloodElfRight = 7;
|
||||
public const int ABannerDraeneiRuinsCenter = 8;
|
||||
public const int ABannerDraeneiRuinsLeft = 9;
|
||||
public const int ABannerDraeneiRuinsRight = 10;
|
||||
public const int ABannerMageTowerCenter = 11;
|
||||
public const int ABannerMageTowerLeft = 12;
|
||||
public const int ABannerMageTowerRight = 13;
|
||||
public const int HBannerFelReaverCenter = 14;
|
||||
public const int HBannerFelReaverLeft = 15;
|
||||
public const int HBannerFelReaverRight = 16;
|
||||
public const int HBannerBloodElfCenter = 17;
|
||||
public const int HBannerBloodElfLeft = 18;
|
||||
public const int HBannerBloodElfRight = 19;
|
||||
public const int HBannerDraeneiRuinsCenter = 20;
|
||||
public const int HBannerDraeneiRuinsLeft = 21;
|
||||
public const int HBannerDraeneiRuinsRight = 22;
|
||||
public const int HBannerMageTowerCenter = 23;
|
||||
public const int HBannerMageTowerLeft = 24;
|
||||
public const int HBannerMageTowerRight = 25;
|
||||
public const int NBannerFelReaverCenter = 26;
|
||||
public const int NBannerFelReaverLeft = 27;
|
||||
public const int NBannerFelReaverRight = 28;
|
||||
public const int NBannerBloodElfCenter = 29;
|
||||
public const int NBannerBloodElfLeft = 30;
|
||||
public const int NBannerBloodElfRight = 31;
|
||||
public const int NBannerDraeneiRuinsCenter = 32;
|
||||
public const int NBannerDraeneiRuinsLeft = 33;
|
||||
public const int NBannerDraeneiRuinsRight = 34;
|
||||
public const int NBannerMageTowerCenter = 35;
|
||||
public const int NBannerMageTowerLeft = 36;
|
||||
public const int NBannerMageTowerRight = 37;
|
||||
public const int TowerCapFelReaver = 38;
|
||||
public const int TowerCapBloodElf = 39;
|
||||
public const int TowerCapDraeneiRuins = 40;
|
||||
public const int TowerCapMageTower = 41;
|
||||
public const int FlagNetherstorm = 42;
|
||||
public const int FlagFelReaver = 43;
|
||||
public const int FlagBloodElf = 44;
|
||||
public const int FlagDraeneiRuins = 45;
|
||||
public const int FlagMageTower = 46;
|
||||
//Buffs
|
||||
public const int SpeedbuffFelReaver = 47;
|
||||
public const int RegenbuffFelReaver = 48;
|
||||
public const int BerserkbuffFelReaver = 49;
|
||||
public const int SpeedbuffBloodElf = 50;
|
||||
public const int RegenbuffBloodElf = 51;
|
||||
public const int BerserkbuffBloodElf = 52;
|
||||
public const int SpeedbuffDraeneiRuins = 53;
|
||||
public const int RegenbuffDraeneiRuins = 54;
|
||||
public const int BerserkbuffDraeneiRuins = 55;
|
||||
public const int SpeedbuffMageTower = 56;
|
||||
public const int RegenbuffMageTower = 57;
|
||||
public const int BerserkbuffMageTower = 58;
|
||||
public const int Max = 59;
|
||||
}
|
||||
|
||||
struct ScoreIds
|
||||
{
|
||||
public const uint WarningNearVictoryScore = 1400;
|
||||
public const uint MaxTeamScore = 1500;
|
||||
}
|
||||
|
||||
enum EYFlagState
|
||||
{
|
||||
OnBase = 0,
|
||||
WaitRespawn = 1,
|
||||
OnPlayer = 2,
|
||||
OnGround = 3
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgNagrandArena : Battleground
|
||||
{
|
||||
public BgNagrandArena(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgRuinsOfLordaernon : Battleground
|
||||
{
|
||||
public BgRuinsOfLordaernon(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgSilvershardMines : Battleground
|
||||
{
|
||||
public BgSilvershardMines(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgTempleofKotmogu : Battleground
|
||||
{
|
||||
public BgTempleofKotmogu(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgTheRingOfValor : Battleground
|
||||
{
|
||||
public BgTheRingOfValor(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Game.BattleGrounds.Zones
|
||||
{
|
||||
class BgTwinPeaks : Battleground
|
||||
{
|
||||
public BgTwinPeaks(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate) { }
|
||||
}
|
||||
}
|
||||
@@ -90,15 +90,15 @@ namespace Game.Chat
|
||||
public static ChannelManager ForTeam(Team team)
|
||||
{
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionChannel))
|
||||
return allianceChannelMgr; // cross-faction
|
||||
return neutralChannelMgr; // cross-faction
|
||||
|
||||
if (team == Team.Alliance)
|
||||
return allianceChannelMgr;
|
||||
|
||||
if (team == Team.Horde)
|
||||
return hordeChannelMgr;
|
||||
|
||||
return null;
|
||||
return team switch
|
||||
{
|
||||
Team.Alliance => allianceChannelMgr,
|
||||
Team.Horde => hordeChannelMgr,
|
||||
Team.PandariaNeutral => neutralChannelMgr,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
public static Channel GetChannelForPlayerByNamePart(string namePart, Player playerSearcher)
|
||||
@@ -239,5 +239,6 @@ namespace Game.Chat
|
||||
|
||||
static ChannelManager allianceChannelMgr = new(Team.Alliance);
|
||||
static ChannelManager hordeChannelMgr = new(Team.Horde);
|
||||
static ChannelManager neutralChannelMgr = new(Team.PandariaNeutral);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,11 +682,6 @@ namespace Game.Chat
|
||||
WorldSafeLocsEntry nearestLoc = null;
|
||||
|
||||
if (linked == "linked")
|
||||
{
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg != null)
|
||||
nearestLoc = bg.GetClosestGraveyard(player);
|
||||
else
|
||||
{
|
||||
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(player.GetMap(), player.GetZoneId());
|
||||
if (bf != null)
|
||||
@@ -694,7 +689,6 @@ namespace Game.Chat
|
||||
else
|
||||
nearestLoc = Global.ObjectMgr.GetClosestGraveyard(player, player.GetTeam(), player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = player.GetPositionX();
|
||||
@@ -788,11 +782,7 @@ namespace Game.Chat
|
||||
return false;
|
||||
}
|
||||
|
||||
var playerConditionEntry = CliDB.PlayerConditionStorage.LookupByKey(playerConditionId);
|
||||
if (playerConditionEntry == null)
|
||||
return false;
|
||||
|
||||
if (ConditionManager.IsPlayerMeetingCondition(target, playerConditionEntry))
|
||||
if (ConditionManager.IsPlayerMeetingCondition(target, playerConditionId))
|
||||
handler.SendSysMessage($"PlayerCondition {playerConditionId} met");
|
||||
else
|
||||
handler.SendSysMessage($"PlayerCondition {playerConditionId} not met");
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Game.Chat
|
||||
|
||||
if (normalizePlayerName(*playerNameArg))
|
||||
{
|
||||
if (Player * player = ObjectAccessor::FindPlayerByName(*playerNameArg))
|
||||
if (Player * player = Global.ObjAccessor.FindPlayerByName(*playerNameArg))
|
||||
{
|
||||
handler->GetSession()->GetPlayer()->RemoveFromWhisperWhiteList(player->GetGUID());
|
||||
handler->PSendSysMessage(LANG_COMMAND_WHISPEROFFPLAYER, playerNameArg->c_str());
|
||||
|
||||
@@ -839,8 +839,7 @@ namespace Game.Chat
|
||||
{
|
||||
if (a.GetMovementGeneratorType() == MovementGeneratorType.Follow)
|
||||
{
|
||||
FollowMovementGenerator followMovement = a as FollowMovementGenerator;
|
||||
return followMovement != null && followMovement.GetTarget() == player;
|
||||
return a is FollowMovementGenerator followMovement && followMovement.GetTarget() == player;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -17,35 +17,10 @@ namespace Game.Chat
|
||||
if (info == null)
|
||||
return default;
|
||||
|
||||
ChatCommandResult errorResult = ChatCommandResult.FromErrorMessage(handler.GetCypherString(CypherStrings.CmdparserLinkdataInvalid));
|
||||
|
||||
// store value
|
||||
switch (Type.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.UInt32:
|
||||
{
|
||||
if (!uint.TryParse(info.Data, out uint tempValue))
|
||||
return errorResult;
|
||||
|
||||
value = tempValue;
|
||||
break;
|
||||
}
|
||||
case TypeCode.UInt64:
|
||||
{
|
||||
if (!ulong.TryParse(info.Data, out ulong tempValue))
|
||||
return errorResult;
|
||||
|
||||
value = tempValue;
|
||||
break;
|
||||
}
|
||||
case TypeCode.String:
|
||||
{
|
||||
value = info.Data;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return errorResult;
|
||||
}
|
||||
HyperlinkDataTokenizer t = new(info.Data, true);
|
||||
if (!t.TryConsumeTo(out value, type))
|
||||
return new ChatCommandResult(handler.GetCypherString(CypherStrings.CmdparserLinkdataInvalid));
|
||||
|
||||
// finally, skip any potential delimiters
|
||||
var (token, next) = info.Tail.Tokenize();
|
||||
@@ -101,7 +76,6 @@ namespace Game.Chat
|
||||
|
||||
static byte toHex(char c) { return (byte)((c >= '0' && c <= '9') ? c - '0' + 0x10 : (c >= 'a' && c <= 'f') ? c - 'a' + 0x1a : 0x00); }
|
||||
|
||||
//|color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r
|
||||
public static HyperlinkInfo ParseHyperlink(string currentString)
|
||||
{
|
||||
if (currentString.IsEmpty())
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.IO;
|
||||
using Game.DataStorage;
|
||||
using Game.Entities;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Game.Chat
|
||||
{
|
||||
@@ -14,136 +18,95 @@ namespace Game.Chat
|
||||
_allowEmptyTokens = allowEmptyTokens;
|
||||
}
|
||||
|
||||
public bool TryConsumeTo(out byte val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
public bool TryConsumeTo(out dynamic val, Type type)
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
if (IsEmpty())
|
||||
return _allowEmptyTokens;
|
||||
|
||||
switch (Type.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.SByte:
|
||||
val = _arg.NextByte(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out ushort val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
case TypeCode.Int16:
|
||||
val = _arg.NextUInt16(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out uint val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
case TypeCode.Int32:
|
||||
val = _arg.NextUInt32(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out ulong val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
case TypeCode.Int64:
|
||||
val = _arg.NextUInt64(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out sbyte val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = _arg.NextSByte(":");
|
||||
case TypeCode.Byte:
|
||||
val = _arg.NextByte(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out short val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = _arg.NextInt16(":");
|
||||
case TypeCode.UInt16:
|
||||
val = _arg.NextUInt16(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out int val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = _arg.NextInt32(":");
|
||||
case TypeCode.UInt32:
|
||||
val = _arg.NextUInt32(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out long val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = _arg.NextInt64(":");
|
||||
case TypeCode.UInt64:
|
||||
val = _arg.NextUInt64(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out float val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
case TypeCode.Single:
|
||||
val = _arg.NextSingle(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out ObjectGuid val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = ObjectGuid.FromString(_arg.NextString(":"));
|
||||
case TypeCode.Double:
|
||||
val = _arg.NextDouble(":");
|
||||
return true;
|
||||
}
|
||||
public bool TryConsumeTo(out string val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
case TypeCode.String:
|
||||
val = _arg.NextString(":");
|
||||
return true;
|
||||
case TypeCode.Object:
|
||||
{
|
||||
switch (type.Name)
|
||||
{
|
||||
case nameof(AchievementRecord):
|
||||
val = CliDB.AchievementStorage.LookupByKey(_arg.NextUInt32(":"));
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(CurrencyTypesRecord):
|
||||
val = CliDB.CurrencyTypesStorage.LookupByKey(_arg.NextUInt32(":"));
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(GameTele):
|
||||
val = Global.ObjectMgr.GetGameTele(_arg.NextUInt32(":"));
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(ItemTemplate):
|
||||
val = Global.ObjectMgr.GetItemTemplate(_arg.NextUInt32(":"));
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(Quest):
|
||||
val = Global.ObjectMgr.GetQuestTemplate(_arg.NextUInt32(":"));
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(SpellInfo):
|
||||
val = Global.SpellMgr.GetSpellInfo(_arg.NextUInt32(":"), Framework.Constants.Difficulty.None);
|
||||
if (val != null)
|
||||
return true;
|
||||
break;
|
||||
case nameof(ObjectGuid):
|
||||
val = ObjectGuid.FromString(_arg.NextString(":"));
|
||||
if (val != ObjectGuid.FromStringFailed)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
public bool TryConsumeTo(out bool val)
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
val = default;
|
||||
return _allowEmptyTokens;
|
||||
}
|
||||
|
||||
val = _arg.NextBoolean(":");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsEmpty() { return _arg.Empty(); }
|
||||
|
||||
@@ -306,6 +306,7 @@ namespace Game.Collision
|
||||
}
|
||||
|
||||
public uint PrimCount() { return (uint)objects.Length; }
|
||||
public AxisAlignedBox bound() { return bounds; }
|
||||
|
||||
public void IntersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
||||
{
|
||||
|
||||
@@ -40,34 +40,41 @@ namespace Game.Collision
|
||||
|
||||
public class WModelAreaCallback : WorkerCallback
|
||||
{
|
||||
public WModelAreaCallback(List<GroupModel> vals, Vector3 down)
|
||||
List<GroupModel> prims;
|
||||
public GroupModel[] hit = new GroupModel[3];
|
||||
|
||||
public WModelAreaCallback(List<GroupModel> vals)
|
||||
{
|
||||
prims = vals;
|
||||
hit = null;
|
||||
zDist = float.PositiveInfinity;
|
||||
zVec = down;
|
||||
}
|
||||
|
||||
List<GroupModel> prims;
|
||||
public GroupModel hit;
|
||||
public float zDist;
|
||||
Vector3 zVec;
|
||||
public override void Invoke(Vector3 point, uint entry)
|
||||
public override bool Invoke(Ray ray, uint entry, ref float distance, bool stopAtFirstHit)
|
||||
{
|
||||
float group_Z;
|
||||
if (prims[(int)entry].IsInsideObject(point, zVec, out group_Z))
|
||||
GroupModel.InsideResult result = prims[(int)entry].IsInsideObject(ray, out float group_Z);
|
||||
if ( result != GroupModel.InsideResult.OutOfBounds)
|
||||
{
|
||||
if (group_Z < zDist)
|
||||
if (result != GroupModel.InsideResult.MaybeInside)
|
||||
{
|
||||
zDist = group_Z;
|
||||
hit = prims[(int)entry];
|
||||
if (group_Z < distance)
|
||||
{
|
||||
distance = group_Z;
|
||||
hit[(int)result] = prims[(int)entry];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
hit[(int)result] = prims[(int)entry];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class WModelRayCallBack : WorkerCallback
|
||||
{
|
||||
List<GroupModel> models;
|
||||
public bool hit;
|
||||
|
||||
public WModelRayCallBack(List<GroupModel> mod)
|
||||
{
|
||||
models = mod;
|
||||
@@ -79,8 +86,6 @@ namespace Game.Collision
|
||||
if (result) hit = true;
|
||||
return hit;
|
||||
}
|
||||
List<GroupModel> models;
|
||||
public bool hit;
|
||||
}
|
||||
|
||||
public class GModelRayCallback : WorkerCallback
|
||||
|
||||
@@ -251,19 +251,56 @@ namespace Game.Collision
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
public bool IsInsideObject(Vector3 pos, Vector3 down, out float z_dist)
|
||||
bool IsInsideOrAboveBound(AxisAlignedBox bounds, Vector3 point)
|
||||
{
|
||||
z_dist = 0f;
|
||||
if (triangles.Empty() || !iBound.contains(pos))
|
||||
return false;
|
||||
return point.X >= bounds.Lo.X
|
||||
&& point.Y >= bounds.Lo.Y
|
||||
&& point.Z >= bounds.Lo.Z
|
||||
&& point.X <= bounds.Hi.X
|
||||
&& point.Y <= bounds.Hi.Y;
|
||||
}
|
||||
|
||||
Vector3 rPos = pos - 0.1f * down;
|
||||
public enum InsideResult
|
||||
{
|
||||
Inside = 0,
|
||||
MaybeInside = 1,
|
||||
Above = 2,
|
||||
OutOfBounds = -1
|
||||
}
|
||||
|
||||
public InsideResult IsInsideObject(Ray ray, out float z_dist)
|
||||
{
|
||||
z_dist = 0;
|
||||
|
||||
if (triangles.Empty() || !IsInsideOrAboveBound(iBound, ray.Origin))
|
||||
return InsideResult.OutOfBounds;
|
||||
|
||||
if (meshTree.bound().Hi.Z >= ray.Origin.Z)
|
||||
{
|
||||
float dist = float.PositiveInfinity;
|
||||
Ray ray = new(rPos, down);
|
||||
bool hit = IntersectRay(ray, ref dist, false);
|
||||
if (hit)
|
||||
if (IntersectRay(ray, ref dist, false))
|
||||
{
|
||||
z_dist = dist - 0.1f;
|
||||
return hit;
|
||||
return InsideResult.Inside;
|
||||
}
|
||||
if (meshTree.bound().contains(ray.Origin))
|
||||
return InsideResult.MaybeInside;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some group models don't have any floor to intersect with
|
||||
// so we should attempt to intersect with a model part below this group
|
||||
// then find back where we originated from (in WorldModel::GetLocationInfo)
|
||||
float dist = float.PositiveInfinity;
|
||||
float delta = ray.Origin.Z - meshTree.bound().Hi.Z;
|
||||
if (IntersectRay(ray.bumpedRay(delta), ref dist, false))
|
||||
{
|
||||
z_dist = dist - 0.1f + delta;
|
||||
return InsideResult.Above;
|
||||
}
|
||||
}
|
||||
|
||||
return InsideResult.OutOfBounds;
|
||||
}
|
||||
|
||||
public bool GetLiquidLevel(Vector3 pos, out float liqHeight)
|
||||
@@ -321,13 +358,26 @@ namespace Game.Collision
|
||||
if (groupModels.Empty())
|
||||
return false;
|
||||
|
||||
WModelAreaCallback callback = new(groupModels, down);
|
||||
groupTree.IntersectPoint(p, callback);
|
||||
if (callback.hit != null)
|
||||
WModelAreaCallback callback = new(groupModels);
|
||||
Ray r = new(p - down * 0.1f, down);
|
||||
float zDist = groupTree.bound().extent().Length();
|
||||
groupTree.IntersectRay(r, callback, ref zDist, false);
|
||||
if (callback.hit[(int)GroupModel.InsideResult.Inside] != null)
|
||||
{
|
||||
info.rootId = (int)RootWMOID;
|
||||
info.hitModel = callback.hit;
|
||||
dist = callback.zDist;
|
||||
info.hitModel = callback.hit[(int)GroupModel.InsideResult.Inside];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
|
||||
// some group models don't have any floor to intersect with
|
||||
// so we should attempt to intersect with a model part below the group `p` is in (stored in GroupModel::ABOVE)
|
||||
// then find back where we originated from (GroupModel::MAYBE_INSIDE)
|
||||
if (callback.hit[(int)GroupModel.InsideResult.MaybeInside] != null && callback.hit[(int)GroupModel.InsideResult.Above] != null)
|
||||
{
|
||||
info.rootId = (int)RootWMOID;
|
||||
info.hitModel = callback.hit[(int)GroupModel.InsideResult.MaybeInside];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Game.Conditions
|
||||
BattlegroundMap bgMap = map.ToBattlegroundMap();
|
||||
if (bgMap != null)
|
||||
{
|
||||
ZoneScript zoneScript = bgMap.GetBG();
|
||||
ZoneScript zoneScript = bgMap.GetBattlegroundScript();
|
||||
switch ((InstanceInfo)ConditionValue3)
|
||||
{
|
||||
case InstanceInfo.Data:
|
||||
@@ -446,11 +446,7 @@ namespace Game.Conditions
|
||||
case ConditionTypes.PlayerCondition:
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(ConditionValue1);
|
||||
if (playerCondition != null)
|
||||
condMeets = ConditionManager.IsPlayerMeetingCondition(player, playerCondition);
|
||||
}
|
||||
condMeets = ConditionManager.IsPlayerMeetingCondition(player, ConditionValue1);
|
||||
break;
|
||||
}
|
||||
case ConditionTypes.PrivateObject:
|
||||
|
||||
@@ -505,6 +505,41 @@ namespace Game
|
||||
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.Graveyard])
|
||||
AddToGraveyardData(id, conditions);
|
||||
|
||||
bool isPlayerConditionIdUsedByCondition(int playerConditionId, List<Condition> conditions, Dictionary<ConditionSourceType, Dictionary<ConditionId, List<Condition>>> store)
|
||||
{
|
||||
return conditions.Any(condition =>
|
||||
{
|
||||
if (condition.ConditionType == ConditionTypes.PlayerCondition)
|
||||
{
|
||||
if (condition.ConditionValue1 == playerConditionId)
|
||||
return true;
|
||||
|
||||
var playerCondList = store[ConditionSourceType.PlayerCondition].LookupByKey(new ConditionId(0, (int)condition.ConditionValue1, 0));
|
||||
if (playerCondList != null)
|
||||
if (isPlayerConditionIdUsedByCondition(playerConditionId, playerCondList, store))
|
||||
return true;
|
||||
}
|
||||
else if (condition.ReferenceId != 0)
|
||||
{
|
||||
var refList = store[ConditionSourceType.ReferenceCondition].LookupByKey(new ConditionId(condition.ReferenceId, 0, 0));
|
||||
if (refList != null)
|
||||
if (isPlayerConditionIdUsedByCondition(playerConditionId, refList, store))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.PlayerCondition])
|
||||
{
|
||||
if (isPlayerConditionIdUsedByCondition(id.SourceEntry, conditions, ConditionStorage))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"[Condition SourceType: CONDITION_SOURCE_TYPE_PLAYER_CONDITION, SourceGroup: {id.SourceGroup}, SourceEntry: {id.SourceEntry}, SourceId: {id.SourceId}] " +
|
||||
$"has a circular reference to player condition id {id.SourceEntry}, removed all conditions for this SourceEntry!");
|
||||
conditions.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} conditions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
@@ -1086,10 +1121,6 @@ namespace Game
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case ConditionSourceType.GossipMenu:
|
||||
case ConditionSourceType.GossipMenuOption:
|
||||
case ConditionSourceType.SmartEvent:
|
||||
break;
|
||||
case ConditionSourceType.Graveyard:
|
||||
if (Global.ObjectMgr.FindGraveyardData((uint)cond.SourceEntry, cond.SourceGroup) == null)
|
||||
{
|
||||
@@ -1183,6 +1214,11 @@ namespace Game
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConditionSourceType.GossipMenu:
|
||||
case ConditionSourceType.GossipMenuOption:
|
||||
case ConditionSourceType.SmartEvent:
|
||||
case ConditionSourceType.PlayerCondition:
|
||||
break;
|
||||
default:
|
||||
Log.outError(LogFilter.Sql, $"{cond.ToString()} Invalid ConditionSourceType in `condition` table, ignoring.");
|
||||
return false;
|
||||
@@ -1892,6 +1928,21 @@ namespace Game
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool IsPlayerMeetingCondition(Player player, uint conditionId)
|
||||
{
|
||||
if (conditionId == 0)
|
||||
return true;
|
||||
|
||||
if (!Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.PlayerCondition, conditionId, player))
|
||||
return false;
|
||||
|
||||
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(conditionId);
|
||||
if (playerCondition != null)
|
||||
return IsPlayerMeetingCondition(player, playerCondition);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsPlayerMeetingCondition(Player player, PlayerConditionRecord condition)
|
||||
{
|
||||
ContentTuningLevels? levels = Global.DB2Mgr.GetContentTuningData(condition.ContentTuningID, player.m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
|
||||
@@ -2957,7 +3008,8 @@ namespace Game
|
||||
"AreaTrigger Client Triggered",
|
||||
"Trainer Spell",
|
||||
"Object Visibility (by ID)",
|
||||
"Spawn Group"
|
||||
"Spawn Group",
|
||||
"Player Condition"
|
||||
};
|
||||
|
||||
public ConditionTypeInfo[] StaticConditionTypeData =
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Game.DataStorage
|
||||
public uint CriteriaTree;
|
||||
public ushort SharesCriteria;
|
||||
public int CovenantID;
|
||||
public int HiddenBeforeDisplaySeason; // hidden in UI before this DisplaySeason is active
|
||||
public int LegacyAfterTimeEvent; // category changes clientside to Legacy after this TimeEvent is passed
|
||||
}
|
||||
|
||||
public sealed class AchievementCategoryRecord
|
||||
@@ -54,8 +56,6 @@ namespace Game.DataStorage
|
||||
public ushort BattleMasterListID;
|
||||
public byte PriorityMin;
|
||||
public byte PriorityMax;
|
||||
public int ItemID;
|
||||
public uint ItemQuantity;
|
||||
public ushort CurrencyType;
|
||||
public uint CurrencyQuantity;
|
||||
public ushort UiMapID;
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace Game.Entities
|
||||
|
||||
public class AreaTriggerSpawn : SpawnData
|
||||
{
|
||||
public AreaTriggerId Id;
|
||||
public new AreaTriggerId Id;
|
||||
public uint? SpellForVisuals;
|
||||
|
||||
public AreaTriggerSpawn() : base(SpawnObjectType.AreaTrigger) { }
|
||||
|
||||
@@ -2588,11 +2588,15 @@ namespace Game.Entities
|
||||
// Send a message to LocalDefense channel for players opposition team in the zone
|
||||
public void SendZoneUnderAttackMessage(Player attacker)
|
||||
{
|
||||
Team enemy_team = attacker.GetTeam();
|
||||
|
||||
ZoneUnderAttack packet = new();
|
||||
packet.AreaID = (int)GetAreaId();
|
||||
Global.WorldMgr.SendGlobalMessage(packet, null, (enemy_team == Team.Alliance ? Team.Horde : Team.Alliance));
|
||||
packet.Write();
|
||||
|
||||
Team enemyTeam = attacker.GetTeam();
|
||||
if (enemyTeam != Team.Alliance)
|
||||
Global.WorldMgr.SendGlobalMessage(packet, null, Team.Alliance);
|
||||
if (enemyTeam != Team.Horde)
|
||||
Global.WorldMgr.SendGlobalMessage(packet, null, Team.Horde);
|
||||
}
|
||||
|
||||
public void SetCanMelee(bool canMelee, bool fleeFromMelee = false)
|
||||
|
||||
@@ -290,9 +290,10 @@ namespace Game.Entities
|
||||
m_goValue.FishingHole.MaxOpens = RandomHelper.URand(GetGoInfo().FishingHole.minRestock, GetGoInfo().FishingHole.maxRestock);
|
||||
break;
|
||||
case GameObjectTypes.DestructibleBuilding:
|
||||
m_goValue.Building.Health = 20000;//goinfo.DestructibleBuilding.intactNumHits + goinfo.DestructibleBuilding.damagedNumHits;
|
||||
m_goValue.Building.MaxHealth = m_goValue.Building.Health;
|
||||
m_goValue.Building.DestructibleHitpoint = Global.ObjectMgr.GetDestructibleHitpoint(GetGoInfo().DestructibleBuilding.HealthRec);
|
||||
m_goValue.Building.Health = m_goValue.Building.DestructibleHitpoint != null ? m_goValue.Building.DestructibleHitpoint.GetMaxHealth() : 0;
|
||||
SetGoAnimProgress(255);
|
||||
|
||||
// yes, even after the updatefield rewrite this garbage hack is still in client
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ParentRotation), new Quaternion(goInfo.DestructibleBuilding.DestructibleModelRec, 0f, 0f, 0f));
|
||||
break;
|
||||
@@ -1366,13 +1367,24 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanActivateForPlayer(Player target)
|
||||
{
|
||||
if (!MeetsInteractCondition(target))
|
||||
return false;
|
||||
|
||||
if (!ActivateToQuest(target))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ActivateToQuest(Player target)
|
||||
{
|
||||
if (target.HasQuestForGO((int)GetEntry()))
|
||||
return true;
|
||||
|
||||
if (!Global.ObjectMgr.IsGameObjectForQuests(GetEntry()))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
switch (GetGoType())
|
||||
{
|
||||
@@ -1393,9 +1405,6 @@ namespace Game.Entities
|
||||
|| LootStorage.Gameobject.HaveQuestLootForPlayer(GetGoInfo().Chest.chestPersonalLoot, target)
|
||||
|| LootStorage.Gameobject.HaveQuestLootForPlayer(GetGoInfo().Chest.chestPushLoot, target))
|
||||
{
|
||||
Battleground bg = target.GetBattleground();
|
||||
if (bg != null)
|
||||
return bg.CanActivateGO((int)GetEntry(), (uint)bg.GetPlayerTeam(target.GetGUID()));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -1406,6 +1415,12 @@ namespace Game.Entities
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case GameObjectTypes.SpellFocus:
|
||||
{
|
||||
if (target.GetQuestStatus(GetGoInfo().SpellFocus.questID) == QuestStatus.Incomplete)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case GameObjectTypes.Goober:
|
||||
{
|
||||
if (target.GetQuestStatus(GetGoInfo().Goober.questID) == QuestStatus.Incomplete)
|
||||
@@ -1701,10 +1716,6 @@ namespace Game.Entities
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg != null && !bg.CanActivateGO((int)GetEntry(), (uint)bg.GetPlayerTeam(user.GetGUID())))
|
||||
return;
|
||||
|
||||
GameObjectTemplate info = GetGoInfo();
|
||||
if (loot == null && info.GetLootId() != 0)
|
||||
{
|
||||
@@ -2250,7 +2261,6 @@ namespace Game.Entities
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GameObjectTypes.FlagStand: // 24
|
||||
{
|
||||
if (!user.IsTypeId(TypeId.Player))
|
||||
@@ -2260,29 +2270,15 @@ namespace Game.Entities
|
||||
|
||||
if (player.CanUseBattlegroundObject(this))
|
||||
{
|
||||
// in Battlegroundcheck
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg == null)
|
||||
return;
|
||||
|
||||
if (player.GetVehicle() != null)
|
||||
return;
|
||||
|
||||
player.RemoveAurasByType(AuraType.ModStealth);
|
||||
player.RemoveAurasByType(AuraType.ModInvisibility);
|
||||
// BG flag click
|
||||
// AB:
|
||||
// 15001
|
||||
// 15002
|
||||
// 15003
|
||||
// 15004
|
||||
// 15005
|
||||
bg.EventPlayerClickedOnFlag(player, this);
|
||||
return; //we don;t need to delete flag ... it is despawned!
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GameObjectTypes.FishingHole: // 25
|
||||
{
|
||||
if (!user.IsTypeId(TypeId.Player))
|
||||
@@ -2290,7 +2286,7 @@ namespace Game.Entities
|
||||
|
||||
Player player = user.ToPlayer();
|
||||
|
||||
Loot loot = new Loot(GetMap(), GetGUID(), LootType.Fishinghole, null);
|
||||
Loot loot = new(GetMap(), GetGUID(), LootType.Fishinghole, null);
|
||||
loot.FillLoot(GetGoInfo().GetLootId(), LootStorage.Gameobject, player, true, false, LootModes.Default, ItemBonusMgr.GetContextForPlayer(GetMap().GetMapDifficulty(), player));
|
||||
m_personalLoot[player.GetGUID()] = loot;
|
||||
|
||||
@@ -2298,7 +2294,6 @@ namespace Game.Entities
|
||||
player.UpdateCriteria(CriteriaType.CatchFishInFishingHole, GetGoInfo().entry);
|
||||
return;
|
||||
}
|
||||
|
||||
case GameObjectTypes.FlagDrop: // 26
|
||||
{
|
||||
if (!user.IsTypeId(TypeId.Player))
|
||||
@@ -2308,11 +2303,6 @@ namespace Game.Entities
|
||||
|
||||
if (player.CanUseBattlegroundObject(this))
|
||||
{
|
||||
// in Battlegroundcheck
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg == null)
|
||||
return;
|
||||
|
||||
if (player.GetVehicle() != null)
|
||||
return;
|
||||
|
||||
@@ -2325,24 +2315,8 @@ namespace Game.Entities
|
||||
// EotS:
|
||||
// 184142 - Netherstorm Flag
|
||||
GameObjectTemplate info = GetGoInfo();
|
||||
if (info != null)
|
||||
{
|
||||
switch (info.entry)
|
||||
{
|
||||
case 179785: // Silverwing Flag
|
||||
case 179786: // Warsong Flag
|
||||
if (bg.GetTypeID() == BattlegroundTypeId.WS)
|
||||
bg.EventPlayerClickedOnFlag(player, this);
|
||||
break;
|
||||
case 184142: // Netherstorm Flag
|
||||
if (bg.GetTypeID() == BattlegroundTypeId.EY)
|
||||
bg.EventPlayerClickedOnFlag(player, this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.FlagDrop.eventID != 0)
|
||||
if (info != null && info.FlagDrop.eventID != 0)
|
||||
GameEvents.Trigger(info.FlagDrop.eventID, player, this);
|
||||
}
|
||||
//this cause to call return, all flags must be deleted here!!
|
||||
spellId = 0;
|
||||
Delete();
|
||||
@@ -2462,9 +2436,8 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
Player player = user.ToPlayer();
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(info.ItemForge.conditionID1);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, playerCondition))
|
||||
|
||||
if (!MeetsInteractCondition(player))
|
||||
return;
|
||||
|
||||
switch (info.ItemForge.ForgeType)
|
||||
@@ -2743,7 +2716,7 @@ namespace Game.Entities
|
||||
|
||||
public void SetLocalRotation(float qx, float qy, float qz, float qw)
|
||||
{
|
||||
Quaternion rotation = new Quaternion(qx, qy, qz, qw);
|
||||
Quaternion rotation = new(qx, qy, qz, qw);
|
||||
rotation = Quaternion.Multiply(rotation, 1.0f / MathF.Sqrt(Quaternion.Dot(rotation, rotation)));
|
||||
|
||||
m_localRotation.X = rotation.X;
|
||||
@@ -2880,7 +2853,7 @@ namespace Game.Entities
|
||||
|
||||
public void ModifyHealth(int change, WorldObject attackerOrHealer = null, uint spellId = 0)
|
||||
{
|
||||
if (m_goValue.Building.MaxHealth == 0 || change == 0)
|
||||
if (m_goValue.Building.DestructibleHitpoint == null || change == 0)
|
||||
return;
|
||||
|
||||
// prevent double destructions of the same object
|
||||
@@ -2889,13 +2862,13 @@ namespace Game.Entities
|
||||
|
||||
if (m_goValue.Building.Health + change <= 0)
|
||||
m_goValue.Building.Health = 0;
|
||||
else if (m_goValue.Building.Health + change >= m_goValue.Building.MaxHealth)
|
||||
m_goValue.Building.Health = m_goValue.Building.MaxHealth;
|
||||
else if (m_goValue.Building.Health + change >= m_goValue.Building.DestructibleHitpoint.GetMaxHealth())
|
||||
m_goValue.Building.Health = m_goValue.Building.DestructibleHitpoint.GetMaxHealth();
|
||||
else
|
||||
m_goValue.Building.Health += (uint)change;
|
||||
|
||||
// Set the health bar, value = 255 * healthPct;
|
||||
SetGoAnimProgress(m_goValue.Building.Health * 255 / m_goValue.Building.MaxHealth);
|
||||
SetGoAnimProgress(m_goValue.Building.Health * 255 / m_goValue.Building.DestructibleHitpoint.GetMaxHealth());
|
||||
|
||||
// dealing damage, send packet
|
||||
Player player = attackerOrHealer != null ? attackerOrHealer.GetCharmerOrOwnerPlayerOrPlayerItself() : null;
|
||||
@@ -2917,9 +2890,9 @@ namespace Game.Entities
|
||||
|
||||
if (m_goValue.Building.Health == 0)
|
||||
newState = GameObjectDestructibleState.Destroyed;
|
||||
else if (m_goValue.Building.Health < m_goValue.Building.MaxHealth / 2)
|
||||
else if (m_goValue.Building.Health < m_goValue.Building.DestructibleHitpoint.DamagedNumHits)
|
||||
newState = GameObjectDestructibleState.Damaged;
|
||||
else if (m_goValue.Building.Health == m_goValue.Building.MaxHealth)
|
||||
else if (m_goValue.Building.Health == m_goValue.Building.DestructibleHitpoint.GetMaxHealth())
|
||||
newState = GameObjectDestructibleState.Intact;
|
||||
|
||||
if (newState == GetDestructibleState())
|
||||
@@ -2938,9 +2911,9 @@ namespace Game.Entities
|
||||
case GameObjectDestructibleState.Intact:
|
||||
RemoveFlag(GameObjectFlags.Damaged | GameObjectFlags.Destroyed);
|
||||
SetDisplayId(m_goInfo.displayId);
|
||||
if (setHealth)
|
||||
if (setHealth && m_goValue.Building.DestructibleHitpoint != null)
|
||||
{
|
||||
m_goValue.Building.Health = m_goValue.Building.MaxHealth;
|
||||
m_goValue.Building.Health = m_goValue.Building.DestructibleHitpoint.GetMaxHealth();
|
||||
SetGoAnimProgress(255);
|
||||
}
|
||||
EnableCollision(true);
|
||||
@@ -2959,12 +2932,13 @@ namespace Game.Entities
|
||||
if (modelData != null)
|
||||
if (modelData.State1Wmo != 0)
|
||||
modelId = modelData.State1Wmo;
|
||||
|
||||
SetDisplayId(modelId);
|
||||
|
||||
if (setHealth)
|
||||
if (setHealth && m_goValue.Building.DestructibleHitpoint != null)
|
||||
{
|
||||
m_goValue.Building.Health = 10000;//m_goInfo.DestructibleBuilding.damagedNumHits;
|
||||
uint maxHealth = m_goValue.Building.MaxHealth;
|
||||
m_goValue.Building.Health = m_goValue.Building.DestructibleHitpoint.DamagedNumHits;
|
||||
uint maxHealth = m_goValue.Building.DestructibleHitpoint.GetMaxHealth();
|
||||
// in this case current health is 0 anyway so just prevent crashing here
|
||||
if (maxHealth == 0)
|
||||
maxHealth = 1;
|
||||
@@ -2978,14 +2952,6 @@ namespace Game.Entities
|
||||
GameEvents.Trigger(GetGoInfo().DestructibleBuilding.DestroyedEvent, attackerOrHealer, this);
|
||||
GetAI().Destroyed(attackerOrHealer, m_goInfo.DestructibleBuilding.DestroyedEvent);
|
||||
|
||||
Player player = attackerOrHealer != null ? attackerOrHealer.GetCharmerOrOwnerPlayerOrPlayerItself() : null;
|
||||
if (player != null)
|
||||
{
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg != null)
|
||||
bg.DestroyGate(player, this);
|
||||
}
|
||||
|
||||
RemoveFlag(GameObjectFlags.Damaged);
|
||||
SetFlag(GameObjectFlags.Destroyed);
|
||||
|
||||
@@ -2994,6 +2960,7 @@ namespace Game.Entities
|
||||
if (modelData != null)
|
||||
if (modelData.State2Wmo != 0)
|
||||
modelId = modelData.State2Wmo;
|
||||
|
||||
SetDisplayId(modelId);
|
||||
|
||||
if (setHealth)
|
||||
@@ -3018,9 +2985,9 @@ namespace Game.Entities
|
||||
SetDisplayId(modelId);
|
||||
|
||||
// restores to full health
|
||||
if (setHealth)
|
||||
if (setHealth & m_goValue.Building.DestructibleHitpoint != null)
|
||||
{
|
||||
m_goValue.Building.Health = m_goValue.Building.MaxHealth;
|
||||
m_goValue.Building.Health = m_goValue.Building.DestructibleHitpoint.GetMaxHealth();
|
||||
SetGoAnimProgress(255);
|
||||
}
|
||||
EnableCollision(true);
|
||||
@@ -3318,8 +3285,7 @@ namespace Game.Entities
|
||||
|
||||
public List<uint> GetPauseTimes()
|
||||
{
|
||||
GameObjectType.Transport transport = m_goTypeImpl as GameObjectType.Transport;
|
||||
if (transport != null)
|
||||
if (m_goTypeImpl is GameObjectType.Transport transport)
|
||||
return transport.GetPauseTimes();
|
||||
|
||||
return null;
|
||||
@@ -3655,8 +3621,7 @@ namespace Game.Entities
|
||||
if (GetGoType() != GameObjectTypes.NewFlag)
|
||||
return 0;
|
||||
|
||||
GameObjectType.NewFlag newFlag = m_goTypeImpl as GameObjectType.NewFlag;
|
||||
if (newFlag == null)
|
||||
if (m_goTypeImpl is not GameObjectType.NewFlag newFlag)
|
||||
return 0;
|
||||
|
||||
return newFlag.GetState();
|
||||
@@ -3667,8 +3632,7 @@ namespace Game.Entities
|
||||
if (GetGoType() != GameObjectTypes.NewFlag)
|
||||
return ObjectGuid.Empty;
|
||||
|
||||
GameObjectType.NewFlag newFlag = m_goTypeImpl as GameObjectType.NewFlag;
|
||||
if (newFlag == null)
|
||||
if (m_goTypeImpl is not GameObjectType.NewFlag newFlag)
|
||||
return ObjectGuid.Empty;
|
||||
|
||||
return newFlag.GetCarrierGUID();
|
||||
@@ -3679,8 +3643,7 @@ namespace Game.Entities
|
||||
if (GetGoType() != GameObjectTypes.NewFlag)
|
||||
return 0;
|
||||
|
||||
GameObjectType.NewFlag newFlag = m_goTypeImpl as GameObjectType.NewFlag;
|
||||
if (newFlag == null)
|
||||
if (m_goTypeImpl is not GameObjectType.NewFlag newFlag)
|
||||
return 0;
|
||||
|
||||
return newFlag.GetTakenFromBaseTime();
|
||||
@@ -3688,8 +3651,7 @@ namespace Game.Entities
|
||||
|
||||
public List<ObjectGuid> GetInsidePlayers()
|
||||
{
|
||||
ControlZone controlZone = m_goTypeImpl as ControlZone;
|
||||
if (controlZone != null)
|
||||
if (m_goTypeImpl is ControlZone controlZone)
|
||||
return controlZone.GetInsidePlayers();
|
||||
|
||||
return null;
|
||||
@@ -3697,15 +3659,7 @@ namespace Game.Entities
|
||||
|
||||
public bool MeetsInteractCondition(Player user)
|
||||
{
|
||||
if (m_goInfo.GetConditionID1() == 0)
|
||||
return true;
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(m_goInfo.GetConditionID1());
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(user, playerCondition))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return ConditionManager.IsPlayerMeetingCondition(user, m_goInfo.GetConditionID1());
|
||||
}
|
||||
|
||||
PerPlayerState GetOrCreatePerPlayerStates(ObjectGuid guid)
|
||||
@@ -3797,17 +3751,17 @@ namespace Game.Entities
|
||||
public GameObjectTypes GetGoType() { return (GameObjectTypes)(sbyte)m_gameObjectData.TypeID; }
|
||||
public void SetGoType(GameObjectTypes type) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.TypeID), (sbyte)type); }
|
||||
public GameObjectState GetGoState() { return (GameObjectState)(sbyte)m_gameObjectData.State; }
|
||||
uint GetGoArtKit() { return m_gameObjectData.ArtKit; }
|
||||
byte GetGoAnimProgress() { return m_gameObjectData.PercentHealth; }
|
||||
public uint GetGoArtKit() { return m_gameObjectData.ArtKit; }
|
||||
public byte GetGoAnimProgress() { return m_gameObjectData.PercentHealth; }
|
||||
public void SetGoAnimProgress(uint animprogress) { SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.PercentHealth), (byte)animprogress); }
|
||||
|
||||
public LootState GetLootState() { return m_lootState; }
|
||||
public LootModes GetLootMode() { return m_LootMode; }
|
||||
bool HasLootMode(LootModes lootMode) { return Convert.ToBoolean(m_LootMode & lootMode); }
|
||||
void SetLootMode(LootModes lootMode) { m_LootMode = lootMode; }
|
||||
void AddLootMode(LootModes lootMode) { m_LootMode |= lootMode; }
|
||||
void RemoveLootMode(LootModes lootMode) { m_LootMode &= ~lootMode; }
|
||||
void ResetLootMode() { m_LootMode = LootModes.Default; }
|
||||
public bool HasLootMode(LootModes lootMode) { return Convert.ToBoolean(m_LootMode & lootMode); }
|
||||
public void SetLootMode(LootModes lootMode) { m_LootMode = lootMode; }
|
||||
public void AddLootMode(LootModes lootMode) { m_LootMode |= lootMode; }
|
||||
public void RemoveLootMode(LootModes lootMode) { m_LootMode &= ~lootMode; }
|
||||
public void ResetLootMode() { m_LootMode = LootModes.Default; }
|
||||
|
||||
public void AddToSkillupList(ObjectGuid PlayerGuid) { m_SkillupList.Add(PlayerGuid); }
|
||||
public bool IsInSkillupList(ObjectGuid PlayerGuid)
|
||||
@@ -3818,17 +3772,17 @@ namespace Game.Entities
|
||||
|
||||
return false;
|
||||
}
|
||||
void ClearSkillupList() { m_SkillupList.Clear(); }
|
||||
public void ClearSkillupList() { m_SkillupList.Clear(); }
|
||||
|
||||
public void AddUse() { ++m_usetimes; }
|
||||
|
||||
public uint GetUseCount() { return m_usetimes; }
|
||||
uint GetUniqueUseCount() { return (uint)m_unique_users.Count; }
|
||||
public uint GetUniqueUseCount() { return (uint)m_unique_users.Count; }
|
||||
|
||||
List<ObjectGuid> GetTapList() { return m_tapList; }
|
||||
void SetTapList(List<ObjectGuid> tapList) { m_tapList = tapList; }
|
||||
public List<ObjectGuid> GetTapList() { return m_tapList; }
|
||||
public void SetTapList(List<ObjectGuid> tapList) { m_tapList = tapList; }
|
||||
|
||||
bool HasLootRecipient() { return !m_tapList.Empty(); }
|
||||
public bool HasLootRecipient() { return !m_tapList.Empty(); }
|
||||
|
||||
public override uint GetLevelForTarget(WorldObject target)
|
||||
{
|
||||
@@ -4006,14 +3960,9 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// Base class for GameObject type specific implementations
|
||||
public class GameObjectTypeBase
|
||||
public class GameObjectTypeBase(GameObject owner)
|
||||
{
|
||||
protected GameObject _owner;
|
||||
|
||||
public GameObjectTypeBase(GameObject owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
protected GameObject _owner = owner;
|
||||
|
||||
public virtual void Update(uint diff) { }
|
||||
public virtual void OnStateChanged(GameObjectState oldState, GameObjectState newState) { }
|
||||
@@ -4057,7 +4006,7 @@ namespace Game.Entities
|
||||
public struct building
|
||||
{
|
||||
public uint Health;
|
||||
public uint MaxHealth;
|
||||
public DestructibleHitpoint DestructibleHitpoint;
|
||||
}
|
||||
//42 GAMEOBJECT_TYPE_CAPTURE_POINT
|
||||
public struct capturePoint
|
||||
@@ -4149,12 +4098,12 @@ namespace Game.Entities
|
||||
|
||||
uint now = GameTime.GetGameTimeMS();
|
||||
uint period = GetTransportPeriod();
|
||||
uint newProgress = 0;
|
||||
uint newProgress;
|
||||
if (_stopFrames.Empty())
|
||||
newProgress = now % period;
|
||||
else
|
||||
{
|
||||
int stopTargetTime = 0;
|
||||
int stopTargetTime;
|
||||
if (_owner.GetGoState() == GameObjectState.TransportActive)
|
||||
stopTargetTime = 0;
|
||||
else
|
||||
@@ -4179,7 +4128,7 @@ namespace Game.Entities
|
||||
|
||||
progressPct = pathPctBetweenStops * timeSinceStopProgressPct + stopSourcePathPct;
|
||||
if (progressPct > 1.0f)
|
||||
progressPct = progressPct - 1.0f;
|
||||
progressPct = -1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4379,8 +4328,7 @@ namespace Game.Entities
|
||||
{
|
||||
foreach (WorldObject passenger in _passengers)
|
||||
{
|
||||
float x, y, z, o;
|
||||
passenger.m_movementInfo.transport.pos.GetPosition(out x, out y, out z, out o);
|
||||
passenger.m_movementInfo.transport.pos.GetPosition(out float x, out float y, out float z, out float o);
|
||||
CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
ITransport.UpdatePassengerPosition(this, _owner.GetMap(), passenger, x, y, z, o, true);
|
||||
}
|
||||
@@ -4529,7 +4477,7 @@ namespace Game.Entities
|
||||
public long GetTakenFromBaseTime() { return _takenFromBaseTime; }
|
||||
}
|
||||
|
||||
class SetNewFlagState : GameObjectTypeBase.CustomCommand
|
||||
public class SetNewFlagState : GameObjectTypeBase.CustomCommand
|
||||
{
|
||||
FlagState _state;
|
||||
Player _player;
|
||||
@@ -4542,8 +4490,7 @@ namespace Game.Entities
|
||||
|
||||
public override void Execute(GameObjectTypeBase type)
|
||||
{
|
||||
NewFlag newFlag = type as NewFlag;
|
||||
if (newFlag != null)
|
||||
if (type is NewFlag newFlag)
|
||||
newFlag.SetState(_state, _player);
|
||||
}
|
||||
}
|
||||
@@ -4793,8 +4740,7 @@ namespace Game.Entities
|
||||
|
||||
public override void Execute(GameObjectTypeBase type)
|
||||
{
|
||||
ControlZone controlZone = type as ControlZone;
|
||||
if (controlZone != null)
|
||||
if (type is ControlZone controlZone)
|
||||
{
|
||||
uint value = controlZone.GetStartingValue();
|
||||
if (_value.HasValue)
|
||||
|
||||
@@ -267,6 +267,15 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetQuestID() => type switch
|
||||
{
|
||||
GameObjectTypes.Chest => Chest.questID,
|
||||
GameObjectTypes.Generic => Generic.questID,
|
||||
GameObjectTypes.SpellFocus => SpellFocus.questID,
|
||||
GameObjectTypes.Goober => Goober.questID,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
public uint GetConditionID1() => type switch
|
||||
{
|
||||
GameObjectTypes.Door => Door.conditionID1,
|
||||
@@ -1648,4 +1657,13 @@ namespace Game.Entities
|
||||
|
||||
public GameObjectData() : base(SpawnObjectType.GameObject) { }
|
||||
}
|
||||
|
||||
public class DestructibleHitpoint
|
||||
{
|
||||
public uint Id;
|
||||
public uint IntactNumHits;
|
||||
public uint DamagedNumHits;
|
||||
|
||||
public uint GetMaxHealth() { return IntactNumHits + DamagedNumHits; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,11 +296,7 @@ namespace Game.Entities
|
||||
|
||||
public bool CanUseEssences()
|
||||
{
|
||||
PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(PlayerConst.PlayerConditionIdUnlockedAzeriteEssences);
|
||||
if (condition != null)
|
||||
return ConditionManager.IsPlayerMeetingCondition(GetOwner(), condition);
|
||||
|
||||
return false;
|
||||
return ConditionManager.IsPlayerMeetingCondition(GetOwner(), PlayerConst.PlayerConditionIdUnlockedAzeriteEssences);
|
||||
}
|
||||
|
||||
public bool HasUnlockedEssenceSlot(byte slot)
|
||||
|
||||
@@ -72,9 +72,7 @@ namespace Game.Entities
|
||||
if (itemProto.GetArtifactID() != artifactAppearanceSet.ArtifactID)
|
||||
continue;
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(artifactAppearance.UnlockPlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
if (owner == null || !ConditionManager.IsPlayerMeetingCondition(owner, playerCondition))
|
||||
if (owner == null || !ConditionManager.IsPlayerMeetingCondition(owner, artifactAppearance.UnlockPlayerConditionID))
|
||||
continue;
|
||||
|
||||
SetModifier(ItemModifier.ArtifactAppearanceId, artifactAppearance.Id);
|
||||
@@ -591,14 +589,10 @@ namespace Game.Entities
|
||||
if (_bonusData.GemRelicType[e - EnchantmentSlot.Sock1] != -1)
|
||||
{
|
||||
ArtifactPowerPickerRecord artifactPowerPicker = CliDB.ArtifactPowerPickerStorage.LookupByKey(enchant.EffectArg[i]);
|
||||
if (artifactPowerPicker != null)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(artifactPowerPicker.PlayerConditionID);
|
||||
if (playerCondition == null || (owner != null && ConditionManager.IsPlayerMeetingCondition(owner, playerCondition)))
|
||||
if (artifactPowerPicker != null && owner != null && ConditionManager.IsPlayerMeetingCondition(owner, artifactPowerPicker.PlayerConditionID))
|
||||
if (artifactPower.Label == _bonusData.GemRelicType[e - EnchantmentSlot.Sock1])
|
||||
power.CurrentRankWithBonus += (byte)enchant.EffectPointsMin[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2290,8 +2284,7 @@ namespace Game.Entities
|
||||
ArtifactPowerPickerRecord artifactPowerPicker = CliDB.ArtifactPowerPickerStorage.LookupByKey(enchant.EffectArg[i]);
|
||||
if (artifactPowerPicker != null)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(artifactPowerPicker.PlayerConditionID);
|
||||
if (playerCondition == null || ConditionManager.IsPlayerMeetingCondition(owner, playerCondition))
|
||||
if (ConditionManager.IsPlayerMeetingCondition(owner, artifactPowerPicker.PlayerConditionID))
|
||||
{
|
||||
for (int artifactPowerIndex = 0; artifactPowerIndex < m_itemData.ArtifactPowers.Size(); ++artifactPowerIndex)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,9 @@ namespace Game.Entities
|
||||
|
||||
public static ItemContext GetContextForPlayer(MapDifficultyRecord mapDifficulty, Player player)
|
||||
{
|
||||
if (mapDifficulty == null)
|
||||
return ItemContext.None;
|
||||
|
||||
ItemContext evalContext(ItemContext currentContext, ItemContext newContext)
|
||||
{
|
||||
if (newContext == ItemContext.None)
|
||||
@@ -81,11 +84,7 @@ namespace Game.Entities
|
||||
|
||||
bool meetsPlayerCondition = false;
|
||||
if (player != null)
|
||||
{
|
||||
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(itemContextPickerEntry.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
meetsPlayerCondition = ConditionManager.IsPlayerMeetingCondition(player, playerCondition);
|
||||
}
|
||||
meetsPlayerCondition = ConditionManager.IsPlayerMeetingCondition(player, itemContextPickerEntry.PlayerConditionID);
|
||||
|
||||
if ((itemContextPickerEntry.Flags & 0x1) != 0)
|
||||
meetsPlayerCondition = !meetsPlayerCondition;
|
||||
|
||||
@@ -112,28 +112,32 @@ namespace Game.Entities
|
||||
ushort pathProgress = 0xFFFF;
|
||||
switch (gameObject.GetGoType())
|
||||
{
|
||||
case GameObjectTypes.QuestGiver:
|
||||
if (gameObject.ActivateToQuest(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate;
|
||||
break;
|
||||
case GameObjectTypes.Chest:
|
||||
if (gameObject.ActivateToQuest(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle | GameObjectDynamicLowFlags.Highlight;
|
||||
else if (receiver.IsGameMaster())
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate;
|
||||
break;
|
||||
case GameObjectTypes.Button:
|
||||
case GameObjectTypes.Goober:
|
||||
if (gameObject.ActivateToQuest(receiver))
|
||||
if (gameObject.GetGoInfo().GetQuestID() != 0 || gameObject.GetGoInfo().GetConditionID1() != 0)
|
||||
{
|
||||
if (gameObject.CanActivateForPlayer(receiver))
|
||||
{
|
||||
dynFlags |= GameObjectDynamicLowFlags.Highlight;
|
||||
if (gameObject.GetGoStateFor(receiver.GetGUID()) != GameObjectState.Active)
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate;
|
||||
}
|
||||
else if (receiver.IsGameMaster())
|
||||
}
|
||||
break;
|
||||
case GameObjectTypes.QuestGiver:
|
||||
if (gameObject.CanActivateForPlayer(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate;
|
||||
break;
|
||||
case GameObjectTypes.Chest:
|
||||
if (gameObject.CanActivateForPlayer(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle | GameObjectDynamicLowFlags.Highlight;
|
||||
else if (receiver.IsGameMaster())
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle;
|
||||
break;
|
||||
case GameObjectTypes.Generic:
|
||||
if (gameObject.ActivateToQuest(receiver))
|
||||
case GameObjectTypes.SpellFocus:
|
||||
if (gameObject.GetGoInfo().GetQuestID() != 0 || gameObject.GetGoInfo().GetConditionID1() != 0)
|
||||
if (gameObject.CanActivateForPlayer(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Sparkle | GameObjectDynamicLowFlags.Highlight;
|
||||
break;
|
||||
case GameObjectTypes.Transport:
|
||||
@@ -150,7 +154,7 @@ namespace Game.Entities
|
||||
dynFlags &= ~GameObjectDynamicLowFlags.NoInterract;
|
||||
break;
|
||||
case GameObjectTypes.GatheringNode:
|
||||
if (gameObject.ActivateToQuest(receiver))
|
||||
if (gameObject.CanActivateForPlayer(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.Activate | GameObjectDynamicLowFlags.Sparkle | GameObjectDynamicLowFlags.Highlight;
|
||||
if (gameObject.GetGoStateFor(receiver.GetGUID()) == GameObjectState.Active)
|
||||
dynFlags |= GameObjectDynamicLowFlags.Depleted;
|
||||
@@ -159,7 +163,7 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gameObject.MeetsInteractCondition(receiver))
|
||||
if (!receiver.IsGameMaster() && !gameObject.MeetsInteractCondition(receiver))
|
||||
dynFlags |= GameObjectDynamicLowFlags.NoInterract;
|
||||
|
||||
unitDynFlags = ((uint)pathProgress << 16) | (uint)dynFlags;
|
||||
@@ -2789,22 +2793,25 @@ namespace Game.Entities
|
||||
public UpdateField<uint> HonorLevel = new(0, 30);
|
||||
public UpdateField<long> LogoutTime = new(0, 31);
|
||||
public UpdateFieldString Name = new(32, 33);
|
||||
public UpdateField<int> Field_B0 = new(32, 34);
|
||||
public UpdateField<int> Field_B4 = new(32, 35);
|
||||
public UpdateField<int> Field_1AC = new(32, 34);
|
||||
public UpdateField<int> Field_1B0 = new(32, 35);
|
||||
public UpdateField<int> CurrentBattlePetSpeciesID = new(32, 36);
|
||||
public UpdateField<CTROptions> CtrOptions = new(32, 37);
|
||||
public UpdateField<int> CovenantID = new(32, 38);
|
||||
public UpdateField<int> SoulbindID = new(32, 39);
|
||||
public UpdateField<DungeonScoreSummary> DungeonScore = new(32, 40);
|
||||
public OptionalUpdateField<DeclinedNames> DeclinedNames = new(32, 41);
|
||||
public UpdateField<CustomTabardInfo> PersonalTabard = new(32, 42);
|
||||
public UpdateFieldArray<byte> PartyType = new(2, 43, 44);
|
||||
public UpdateFieldArray<QuestLog> QuestLog = new(175, 46, 47);
|
||||
public UpdateFieldArray<VisibleItem> VisibleItems = new(19, 222, 223);
|
||||
public UpdateFieldArray<float> AvgItemLevel = new(6, 242, 243);
|
||||
public UpdateFieldArray<uint> Field_3120 = new(19, 249, 250);
|
||||
public UpdateField<ObjectGuid> SpectateTarget = new(32, 41);
|
||||
public UpdateField<int> Field_200 = new(32, 42);
|
||||
public OptionalUpdateField<DeclinedNames> DeclinedNames = new(32, 43);
|
||||
public UpdateField<CustomTabardInfo> PersonalTabard = new(32, 44);
|
||||
public UpdateFieldArray<byte> PartyType = new(2, 45, 46);
|
||||
public UpdateFieldArray<QuestLog> QuestLog = new(175, 48, 49);
|
||||
public UpdateFieldArray<VisibleItem> VisibleItems = new(19, 224, 225);
|
||||
public UpdateFieldArray<float> AvgItemLevel = new(6, 244, 245);
|
||||
public UpdateFieldArray<ItemInstance> VisibleEquipableSpells = new(16, 251, 252);
|
||||
public UpdateFieldArray<uint> Field_3120 = new(19, 268, 269);
|
||||
|
||||
public PlayerData() : base(0, TypeId.Player, 269) { }
|
||||
public PlayerData() : base(0, TypeId.Player, 288) { }
|
||||
|
||||
public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver)
|
||||
{
|
||||
@@ -2854,12 +2861,14 @@ namespace Game.Entities
|
||||
data.WriteUInt32(HonorLevel);
|
||||
data.WriteInt64(LogoutTime);
|
||||
data.WriteInt32(ArenaCooldowns.Size());
|
||||
data.WriteInt32(Field_B0);
|
||||
data.WriteInt32(Field_B4);
|
||||
data.WriteInt32(Field_1AC);
|
||||
data.WriteInt32(Field_1B0);
|
||||
data.WriteInt32(CurrentBattlePetSpeciesID);
|
||||
((CTROptions)CtrOptions).WriteCreate(data, owner, receiver);
|
||||
data.WriteInt32(CovenantID);
|
||||
data.WriteInt32(SoulbindID);
|
||||
data.WritePackedGuid(SpectateTarget);
|
||||
data.WriteInt32(Field_200);
|
||||
data.WriteInt32(VisualItemReplacements.Size());
|
||||
for (int i = 0; i < 19; ++i)
|
||||
{
|
||||
@@ -2899,6 +2908,10 @@ namespace Game.Entities
|
||||
data.WriteBits(DeclinedNames.HasValue(), 1);
|
||||
DungeonScore._value.Write(data);
|
||||
data.WriteString(Name);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
VisibleEquipableSpells[i].Write(data);
|
||||
}
|
||||
if (DeclinedNames.HasValue())
|
||||
{
|
||||
DeclinedNames.GetValue().WriteCreate(data, owner, receiver);
|
||||
@@ -2908,7 +2921,7 @@ namespace Game.Entities
|
||||
|
||||
public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver)
|
||||
{
|
||||
UpdateMask allowedMaskForTarget = new(269, [0xFFFFFFDDu, 0x00003FFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xC0000000u, 0xFFFFFFFFu, 0x00001FFFu]);
|
||||
UpdateMask allowedMaskForTarget = new(288, [0xFFFFFFDDu, 0x0000FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFFu, 0xFFFFFFFFu]);
|
||||
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
|
||||
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
|
||||
}
|
||||
@@ -2916,12 +2929,12 @@ namespace Game.Entities
|
||||
public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags)
|
||||
{
|
||||
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.PartyMember))
|
||||
allowedMaskForTarget.OR(new UpdateMask(269, new[] { 0x00000022u, 0xFFFFC000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x3FFFFFFFu, 0x00000000u, 0x00000000u }));
|
||||
allowedMaskForTarget.OR(new UpdateMask(288, [0x00000022u, 0xFFFF0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000000u, 0x00000000u]));
|
||||
}
|
||||
|
||||
public void FilterDisallowedFieldsMaskForFlag(UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags)
|
||||
{
|
||||
UpdateMask allowedMaskForTarget = new(269, new[] { 0xFFFFFFDDu, 0x00003FFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xC0000000u, 0xFFFFFFFFu, 0x00001FFFu });
|
||||
UpdateMask allowedMaskForTarget = new(288, [0xFFFFFFDDu, 0x0000FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFFu, 0xFFFFFFFFu]);
|
||||
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
|
||||
changesMask.AND(allowedMaskForTarget);
|
||||
}
|
||||
@@ -3137,11 +3150,11 @@ namespace Game.Entities
|
||||
{
|
||||
if (changesMask[34])
|
||||
{
|
||||
data.WriteInt32(Field_B0);
|
||||
data.WriteInt32(Field_1AC);
|
||||
}
|
||||
if (changesMask[35])
|
||||
{
|
||||
data.WriteInt32(Field_B4);
|
||||
data.WriteInt32(Field_1B0);
|
||||
}
|
||||
if (changesMask[36])
|
||||
{
|
||||
@@ -3159,13 +3172,21 @@ namespace Game.Entities
|
||||
{
|
||||
data.WriteInt32(SoulbindID);
|
||||
}
|
||||
if (changesMask[41])
|
||||
{
|
||||
data.WritePackedGuid(SpectateTarget);
|
||||
}
|
||||
if (changesMask[42])
|
||||
{
|
||||
data.WriteInt32(Field_200);
|
||||
}
|
||||
if (changesMask[44])
|
||||
{
|
||||
PersonalTabard.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
|
||||
}
|
||||
if (changesMask[33])
|
||||
{
|
||||
data.WriteBits(Name.GetValue().GetByteCount(), 32);
|
||||
data.WriteBits(Name.GetValue().GetByteCount(), 6);
|
||||
}
|
||||
data.WriteBits(DeclinedNames.HasValue(), 1);
|
||||
data.FlushBits();
|
||||
@@ -3177,7 +3198,7 @@ namespace Game.Entities
|
||||
{
|
||||
data.WriteString(Name);
|
||||
}
|
||||
if (changesMask[41])
|
||||
if (changesMask[43])
|
||||
{
|
||||
if (DeclinedNames.HasValue())
|
||||
{
|
||||
@@ -3185,21 +3206,21 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[43])
|
||||
if (changesMask[45])
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (changesMask[44 + i])
|
||||
if (changesMask[46 + i])
|
||||
{
|
||||
data.WriteUInt8(PartyType[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[46])
|
||||
if (changesMask[48])
|
||||
{
|
||||
for (int i = 0; i < 175; ++i)
|
||||
{
|
||||
if (changesMask[47 + i])
|
||||
if (changesMask[49 + i])
|
||||
{
|
||||
if (noQuestLogChangesMask)
|
||||
QuestLog[i].WriteCreate(data, owner, receiver);
|
||||
@@ -3208,36 +3229,46 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[222])
|
||||
if (changesMask[224])
|
||||
{
|
||||
for (int i = 0; i < 19; ++i)
|
||||
{
|
||||
if (changesMask[223 + i])
|
||||
if (changesMask[225 + i])
|
||||
{
|
||||
VisibleItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[242])
|
||||
if (changesMask[244])
|
||||
{
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (changesMask[243 + i])
|
||||
if (changesMask[245 + i])
|
||||
{
|
||||
data.WriteFloat(AvgItemLevel[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[249])
|
||||
if (changesMask[268])
|
||||
{
|
||||
for (int i = 0; i < 19; ++i)
|
||||
{
|
||||
if (changesMask[250 + i])
|
||||
if (changesMask[269 + i])
|
||||
{
|
||||
data.WriteUInt32(Field_3120[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changesMask[251])
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
if (changesMask[252 + i])
|
||||
{
|
||||
VisibleEquipableSpells[i].Write(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
data.FlushBits();
|
||||
}
|
||||
|
||||
@@ -3275,19 +3306,22 @@ namespace Game.Entities
|
||||
ClearChangesMask(HonorLevel);
|
||||
ClearChangesMask(LogoutTime);
|
||||
ClearChangesMask(Name);
|
||||
ClearChangesMask(Field_B0);
|
||||
ClearChangesMask(Field_B4);
|
||||
ClearChangesMask(Field_1AC);
|
||||
ClearChangesMask(Field_1B0);
|
||||
ClearChangesMask(CurrentBattlePetSpeciesID);
|
||||
ClearChangesMask(CtrOptions);
|
||||
ClearChangesMask(CovenantID);
|
||||
ClearChangesMask(SoulbindID);
|
||||
ClearChangesMask(DungeonScore);
|
||||
ClearChangesMask(SpectateTarget);
|
||||
ClearChangesMask(Field_200);
|
||||
ClearChangesMask(DeclinedNames);
|
||||
ClearChangesMask(PersonalTabard);
|
||||
ClearChangesMask(PartyType);
|
||||
ClearChangesMask(QuestLog);
|
||||
ClearChangesMask(VisibleItems);
|
||||
ClearChangesMask(AvgItemLevel);
|
||||
ClearChangesMask(VisibleEquipableSpells);
|
||||
ClearChangesMask(Field_3120);
|
||||
_changesMask.ResetAll();
|
||||
}
|
||||
|
||||
@@ -451,13 +451,14 @@ namespace Game.Entities
|
||||
bool hasMoveCurveID = createProperties != null && createProperties.MoveCurveId != 0;
|
||||
bool hasAreaTriggerSphere = shape.IsSphere();
|
||||
bool hasAreaTriggerBox = shape.IsBox();
|
||||
bool hasAreaTriggerPolygon = createProperties != null && shape.IsPolygon();
|
||||
bool hasAreaTriggerPolygon = shape.IsPolygon();
|
||||
bool hasAreaTriggerCylinder = shape.IsCylinder();
|
||||
bool hasDisk = shape.IsDisk();
|
||||
bool hasBoundedPlane = shape.IsBoundedPlane();
|
||||
bool hasAreaTriggerSpline = areaTrigger.HasSplines();
|
||||
bool hasOrbit = areaTrigger.HasOrbit();
|
||||
bool hasMovementScript = false;
|
||||
bool hasPositionalSoundKitID = false;
|
||||
|
||||
data.WriteBit(hasAbsoluteOrientation);
|
||||
data.WriteBit(hasDynamicShape);
|
||||
@@ -471,6 +472,7 @@ namespace Game.Entities
|
||||
data.WriteBit(hasMorphCurveID);
|
||||
data.WriteBit(hasFacingCurveID);
|
||||
data.WriteBit(hasMoveCurveID);
|
||||
data.WriteBit(hasPositionalSoundKitID);
|
||||
data.WriteBit(hasAreaTriggerSphere);
|
||||
data.WriteBit(hasAreaTriggerBox);
|
||||
data.WriteBit(hasAreaTriggerPolygon);
|
||||
@@ -506,6 +508,9 @@ namespace Game.Entities
|
||||
if (hasMoveCurveID)
|
||||
data.WriteUInt32(createProperties.MoveCurveId);
|
||||
|
||||
if (hasPositionalSoundKitID)
|
||||
data.WriteUInt32(0);
|
||||
|
||||
if (hasAreaTriggerSphere)
|
||||
{
|
||||
data.WriteFloat(shape.SphereDatas.Radius);
|
||||
@@ -1522,7 +1527,7 @@ namespace Game.Entities
|
||||
|
||||
BattlegroundMap bgMap = map.ToBattlegroundMap();
|
||||
if (bgMap != null)
|
||||
return (ZoneScript)bgMap.GetBG();
|
||||
return (ZoneScript)bgMap.GetBattlegroundScript();
|
||||
|
||||
if (!map.IsBattlegroundOrArena())
|
||||
{
|
||||
|
||||
@@ -386,12 +386,8 @@ namespace Game.Entities
|
||||
_mounts[spellId] = flags;
|
||||
|
||||
// Mount condition only applies to using it, should still learn it.
|
||||
if (mount.PlayerConditionID != 0)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(mount.PlayerConditionID);
|
||||
if (playerCondition != null && !ConditionManager.IsPlayerMeetingCondition(player, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, mount.PlayerConditionID))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!learned)
|
||||
{
|
||||
|
||||
@@ -457,7 +457,7 @@ namespace Game.Entities
|
||||
case DuelCompleteType.Fled:
|
||||
// if initiator and opponent are on the same team
|
||||
// or initiator and opponent are not PvP enabled, forcibly stop attacking
|
||||
if (GetTeam() == opponent.GetTeam())
|
||||
if (GetEffectiveTeam() == opponent.GetEffectiveTeam())
|
||||
{
|
||||
AttackStop();
|
||||
opponent.AttackStop();
|
||||
|
||||
@@ -3612,9 +3612,7 @@ namespace Game.Entities
|
||||
if (GetSession().GetCollectionMgr().HasTransmogIllusion(transmogIllusion.Id))
|
||||
continue;
|
||||
|
||||
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(transmogIllusion.UnlockConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, (uint)transmogIllusion.UnlockConditionID))
|
||||
continue;
|
||||
|
||||
GetSession().GetCollectionMgr().AddTransmogIllusion(transmogIllusion.Id);
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace Game.Entities
|
||||
case 1:
|
||||
return IsInSameRaidWith(p);
|
||||
case 2:
|
||||
return GetTeam() == p.GetTeam();
|
||||
return GetEffectiveTeam() == p.GetEffectiveTeam();
|
||||
case 3:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2865,8 +2865,7 @@ namespace Game.Entities
|
||||
var limitConditions = Global.DB2Mgr.GetItemLimitCategoryConditions(limitEntry.Id);
|
||||
foreach (ItemLimitCategoryConditionRecord limitCondition in limitConditions)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(limitCondition.PlayerConditionID);
|
||||
if (playerCondition == null || ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (ConditionManager.IsPlayerMeetingCondition(this, limitCondition.PlayerConditionID))
|
||||
limit += (byte)limitCondition.AddQuantity;
|
||||
}
|
||||
|
||||
@@ -3273,15 +3272,11 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(crItem.PlayerConditionId);
|
||||
if (playerCondition != null)
|
||||
{
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, crItem.PlayerConditionId))
|
||||
{
|
||||
SendEquipError(InventoryResult.ItemLocked);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check current item amount if it limited
|
||||
if (crItem.maxcount != 0)
|
||||
|
||||
@@ -370,7 +370,7 @@ namespace Game.Entities
|
||||
var mapDifficultyConditions = Global.DB2Mgr.GetMapDifficultyConditions(mapDiff.Id);
|
||||
foreach (var pair in mapDifficultyConditions)
|
||||
{
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, pair.Item2))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, pair.Item2.Id))
|
||||
{
|
||||
failedMapDifficultyXCondition = pair.Item1;
|
||||
break;
|
||||
|
||||
@@ -1174,9 +1174,7 @@ namespace Game.Entities
|
||||
{
|
||||
foreach (QuestRewardDisplaySpell displaySpell in quest.RewardDisplaySpell)
|
||||
{
|
||||
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(displaySpell.PlayerConditionId);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, displaySpell.PlayerConditionId))
|
||||
continue;
|
||||
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(displaySpell.SpellId, GetMap().GetDifficultyID());
|
||||
@@ -1588,7 +1586,7 @@ namespace Game.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SatisfyQuestReputation(Quest qInfo, bool msg)
|
||||
public bool SatisfyQuestMinReputation(Quest qInfo, bool msg)
|
||||
{
|
||||
uint fIdMin = qInfo.RequiredMinRepFaction; //Min required rep
|
||||
if (fIdMin != 0 && GetReputationMgr().GetReputation(fIdMin) < qInfo.RequiredMinRepValue)
|
||||
@@ -1601,6 +1599,11 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SatisfyQuestMaxReputation(Quest qInfo, bool msg)
|
||||
{
|
||||
uint fIdMax = qInfo.RequiredMaxRepFaction; //Max required rep
|
||||
if (fIdMax != 0 && GetReputationMgr().GetReputation(fIdMax) >= qInfo.RequiredMaxRepValue)
|
||||
{
|
||||
@@ -1615,6 +1618,11 @@ namespace Game.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SatisfyQuestReputation(Quest qInfo, bool msg)
|
||||
{
|
||||
return SatisfyQuestMinReputation(qInfo, msg) && SatisfyQuestMaxReputation(qInfo, msg);
|
||||
}
|
||||
|
||||
public bool SatisfyQuestStatus(Quest qInfo, bool msg)
|
||||
{
|
||||
if (GetQuestStatus(qInfo.Id) == QuestStatus.Rewarded)
|
||||
@@ -3297,15 +3305,17 @@ namespace Game.Entities
|
||||
ObjectFieldData objMask = new();
|
||||
GameObjectFieldData goMask = new();
|
||||
|
||||
if (m_questObjectiveStatus.ContainsKey((QuestObjectiveType.GameObject, (int)gameObject.GetEntry())))
|
||||
if (m_questObjectiveStatus.ContainsKey((QuestObjectiveType.GameObject, (int)gameObject.GetEntry())) || gameObject.GetGoInfo().GetConditionID1() != 0)
|
||||
objMask.MarkChanged(gameObject.m_objectData.DynamicFlags);
|
||||
|
||||
else
|
||||
{
|
||||
switch (gameObject.GetGoType())
|
||||
{
|
||||
case GameObjectTypes.QuestGiver:
|
||||
case GameObjectTypes.Chest:
|
||||
case GameObjectTypes.Goober:
|
||||
case GameObjectTypes.Generic:
|
||||
case GameObjectTypes.SpellFocus:
|
||||
case GameObjectTypes.Goober:
|
||||
case GameObjectTypes.GatheringNode:
|
||||
if (Global.ObjectMgr.IsGameObjectForQuests(gameObject.GetEntry()))
|
||||
objMask.MarkChanged(gameObject.m_objectData.DynamicFlags);
|
||||
@@ -3313,6 +3323,7 @@ namespace Game.Entities
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (objMask.GetUpdateMask().IsAnySet() || goMask.GetUpdateMask().IsAnySet())
|
||||
gameObject.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), goMask.GetUpdateMask(), this);
|
||||
|
||||
@@ -742,9 +742,7 @@ namespace Game.Entities
|
||||
if (HasPvpTalent(talentID, GetActiveTalentGroup()))
|
||||
return TalentLearnResult.FailedUnknown;
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(talentInfo.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, (uint)talentInfo.PlayerConditionID))
|
||||
return TalentLearnResult.FailedCantDoThatRightNow;
|
||||
|
||||
PvpTalentRecord talent = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]);
|
||||
|
||||
@@ -1327,11 +1327,8 @@ namespace Game.Entities
|
||||
|
||||
// Check award condition
|
||||
if (currency.AwardConditionID != 0)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(currency.AwardConditionID);
|
||||
if (playerCondition != null && !ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, (uint)currency.AwardConditionID))
|
||||
return;
|
||||
}
|
||||
|
||||
bool isGainOnRefund = false;
|
||||
|
||||
@@ -2446,12 +2443,6 @@ namespace Game.Entities
|
||||
// stop taxi flight at summon
|
||||
FinishTaxiFlight();
|
||||
|
||||
// drop flag at summon
|
||||
// this code can be reached only when GM is summoning player who carries flag, because player should be immune to summoning spells when he carries flag
|
||||
Battleground bg = GetBattleground();
|
||||
if (bg != null)
|
||||
bg.EventPlayerDroppedFlag(this);
|
||||
|
||||
m_summon_expire = 0;
|
||||
|
||||
UpdateCriteria(CriteriaType.AcceptSummon, 1);
|
||||
@@ -4250,13 +4241,6 @@ namespace Game.Entities
|
||||
UpdateZone(newzone, newarea);
|
||||
OutdoorPvPMgr.HandlePlayerResurrects(this, newzone);
|
||||
|
||||
if (InBattleground())
|
||||
{
|
||||
Battleground bg = GetBattleground();
|
||||
if (bg != null)
|
||||
bg.HandlePlayerResurrect(this);
|
||||
}
|
||||
|
||||
// update visibility
|
||||
UpdateObjectVisibility();
|
||||
|
||||
@@ -4454,13 +4438,6 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry closestGrave = null;
|
||||
|
||||
// Special handle for Battlegroundmaps
|
||||
Battleground bg = GetBattleground();
|
||||
if (bg != null)
|
||||
closestGrave = bg.GetClosestGraveyard(this);
|
||||
else
|
||||
{
|
||||
var bf = BattleFieldMgr.GetBattlefieldToZoneId(GetMap(), GetZoneId());
|
||||
if (bf != null)
|
||||
closestGrave = bf.GetClosestGraveyard(this);
|
||||
@@ -4470,7 +4447,6 @@ namespace Game.Entities
|
||||
if (instance != null)
|
||||
closestGrave = ObjectMgr.GetWorldSafeLoc(instance.GetEntranceLocation());
|
||||
}
|
||||
}
|
||||
|
||||
if (closestGrave == null)
|
||||
closestGrave = ObjectMgr.GetClosestGraveyard(this, GetTeam(), this);
|
||||
@@ -4985,12 +4961,7 @@ namespace Game.Entities
|
||||
|
||||
public bool MeetPlayerCondition(uint conditionId)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(conditionId);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return ConditionManager.IsPlayerMeetingCondition(this, conditionId);
|
||||
}
|
||||
|
||||
bool IsInFriendlyArea()
|
||||
@@ -5143,6 +5114,8 @@ namespace Game.Entities
|
||||
return Team.Alliance;
|
||||
case 1:
|
||||
return Team.Horde;
|
||||
case 2:
|
||||
return Team.PandariaNeutral;
|
||||
}
|
||||
|
||||
return Team.Alliance;
|
||||
@@ -5157,10 +5130,10 @@ namespace Game.Entities
|
||||
return BattleGroundTeamId.Neutral;
|
||||
}
|
||||
public Team GetTeam() { return m_team; }
|
||||
public int GetTeamId() { return m_team == Team.Alliance ? BattleGroundTeamId.Alliance : BattleGroundTeamId.Horde; }
|
||||
public int GetTeamId() { return SharedConst.GetTeamIdForTeam(m_team); }
|
||||
|
||||
public Team GetEffectiveTeam() { return HasPlayerFlagEx(PlayerFlagsEx.MercenaryMode) ? (GetTeam() == Team.Alliance ? Team.Horde : Team.Alliance) : GetTeam(); }
|
||||
public int GetEffectiveTeamId() { return GetEffectiveTeam() == Team.Alliance ? BattleGroundTeamId.Alliance : BattleGroundTeamId.Horde; }
|
||||
public Team GetEffectiveTeam() { return HasPlayerFlagEx(PlayerFlagsEx.MercenaryMode) ? SharedConst.GetOtherTeam(GetTeam()) : GetTeam(); }
|
||||
public int GetEffectiveTeamId() { return SharedConst.GetTeamIdForTeam(GetEffectiveTeam()); }
|
||||
|
||||
//Money
|
||||
public ulong GetMoney() { return m_activePlayerData.Coinage; }
|
||||
@@ -6318,11 +6291,8 @@ namespace Game.Entities
|
||||
|
||||
// Check award condition
|
||||
if (currencyRecord.AwardConditionID != 0)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(currencyRecord.AwardConditionID);
|
||||
if (playerCondition != null && !ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, (uint)currencyRecord.AwardConditionID))
|
||||
continue;
|
||||
}
|
||||
|
||||
SetupCurrency.Record record = new();
|
||||
record.Type = currencyRecord.Id;
|
||||
|
||||
@@ -1667,15 +1667,11 @@ namespace Game.Entities
|
||||
continue;
|
||||
}
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(corruptionEffect.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
{
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(this, (uint)corruptionEffect.PlayerConditionID))
|
||||
{
|
||||
RemoveAura(corruptionEffect.Aura);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CastSpell(this, corruptionEffect.Aura, true);
|
||||
}
|
||||
|
||||
@@ -154,13 +154,17 @@ namespace Game.Entities
|
||||
foreach (var edge in path)
|
||||
{
|
||||
var To = m_nodesByVertex[(int)edge.To];
|
||||
TaxiNodeFlags requireFlag = (player.GetTeam() == Team.Alliance) ? TaxiNodeFlags.ShowOnAllianceMap : TaxiNodeFlags.ShowOnHordeMap;
|
||||
if (!To.HasFlag(requireFlag))
|
||||
bool isVisibleForFaction = player.GetTeam() switch
|
||||
{
|
||||
Team.Horde => To.HasFlag(TaxiNodeFlags.ShowOnHordeMap),
|
||||
Team.Alliance => To.HasFlag(TaxiNodeFlags.ShowOnAllianceMap),
|
||||
_ => false
|
||||
};
|
||||
|
||||
if (!isVisibleForFaction)
|
||||
continue;
|
||||
|
||||
PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(To.ConditionID);
|
||||
if (condition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, condition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, To.ConditionID))
|
||||
continue;
|
||||
|
||||
shortestPath.Add(GetNodeIDFromVertexID(edge.To));
|
||||
|
||||
@@ -868,13 +868,8 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
Player thisPlayer = ToPlayer();
|
||||
if (thisPlayer != null)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(mountCapability.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(thisPlayer, playerCondition))
|
||||
if (thisPlayer != null && !ConditionManager.IsPlayerMeetingCondition(thisPlayer, (uint)mountCapability.PlayerConditionID))
|
||||
continue;
|
||||
}
|
||||
|
||||
return mountCapability;
|
||||
}
|
||||
|
||||
@@ -110,8 +110,7 @@ namespace Game.Entities
|
||||
if (player.IsQuestRewarded(vignette.Data.VisibleTrackingQuestID))
|
||||
return false;
|
||||
|
||||
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vignette.Data.PlayerConditionID);
|
||||
if (playerCondition != null && !ConditionManager.IsPlayerMeetingCondition(player, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, vignette.Data.PlayerConditionID))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -672,11 +672,6 @@ namespace Game.Entities
|
||||
Player player = Passenger.ToPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
// drop flag
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg != null)
|
||||
bg.EventPlayerDroppedFlag(player);
|
||||
|
||||
player.StopCastingCharm();
|
||||
player.StopCastingBindSight();
|
||||
player.SendOnCancelExpectedVehicleRideAura();
|
||||
|
||||
@@ -4118,6 +4118,10 @@ namespace Game
|
||||
got.BarberChair.SitAnimKit = 0;
|
||||
}
|
||||
break;
|
||||
case GameObjectTypes.DestructibleBuilding:
|
||||
if (got.DestructibleBuilding.HealthRec != 0 && GetDestructibleHitpoint(got.DestructibleBuilding.HealthRec) == null)
|
||||
Log.outError(LogFilter.Sql, $"GameObject (Entry: {entry}) Has non existing Destructible Hitpoint Record {got.DestructibleBuilding.HealthRec}.");
|
||||
break;
|
||||
case GameObjectTypes.GarrisonBuilding:
|
||||
{
|
||||
int transportMap = got.GarrisonBuilding.SpawnMap;
|
||||
@@ -4647,6 +4651,12 @@ namespace Game
|
||||
|
||||
continue;
|
||||
}
|
||||
case GameObjectTypes.SpellFocus:
|
||||
{
|
||||
if (pair.Value.SpellFocus.questID > 0) //quests objects
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
case GameObjectTypes.Goober:
|
||||
{
|
||||
if (pair.Value.Goober.questID > 0) //quests objects
|
||||
@@ -4673,6 +4683,33 @@ namespace Game
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} GameObjects for quests in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
public void LoadDestructibleHitpoints()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
|
||||
_destructibleHitpointStorage.Clear(); // need for reload case
|
||||
|
||||
// 0 1 2
|
||||
SQLResult result = DB.World.Query("SELECT Id, IntactNumHits, DamagedNumHits FROM destructible_hitpoint");
|
||||
if (result.IsEmpty())
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
uint id = result.Read<uint>(0);
|
||||
|
||||
DestructibleHitpoint data = new();
|
||||
data.Id = id;
|
||||
data.IntactNumHits = result.Read<uint>(1);
|
||||
data.DamagedNumHits = result.Read<uint>(2);
|
||||
|
||||
_destructibleHitpointStorage.Add(id, data);
|
||||
|
||||
} while (result.NextRow());
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_destructibleHitpointStorage.Count} destructible_hitpoint records in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
public void AddGameObjectToGrid(GameObjectData data)
|
||||
{
|
||||
AddSpawnDataToGrid(data);
|
||||
@@ -4833,6 +4870,11 @@ namespace Game
|
||||
return difficulties;
|
||||
}
|
||||
|
||||
public DestructibleHitpoint GetDestructibleHitpoint(uint entry)
|
||||
{
|
||||
return _destructibleHitpointStorage.LookupByKey(entry);
|
||||
}
|
||||
|
||||
//Items
|
||||
public void LoadItemTemplates()
|
||||
{
|
||||
@@ -5172,9 +5214,12 @@ namespace Game
|
||||
|
||||
if (vItem.PlayerConditionId != 0 && !CliDB.PlayerConditionStorage.ContainsKey(vItem.PlayerConditionId))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Table `(game_event_)npc_vendor` has Item (Entry: {0}) with invalid PlayerConditionId ({1}) for vendor ({2}), ignore", vItem.item, vItem.PlayerConditionId, vendorentry);
|
||||
if (!Global.ConditionMgr.HasConditionsForNotGroupedEntry(ConditionSourceType.PlayerCondition, vItem.PlayerConditionId))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Table `(game_event_)npc_vendor` has Item (Entry: {0}) with serverside PlayerConditionId ({1}) for vendor ({2}) without conditions, ignore", vItem.item, vItem.PlayerConditionId, vendorentry);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (vItem.ExtendedCost != 0 && !CliDB.ItemExtendedCostStorage.ContainsKey(vItem.ExtendedCost))
|
||||
{
|
||||
@@ -10426,10 +10471,19 @@ namespace Game
|
||||
float dist = 10000;
|
||||
uint id = 0;
|
||||
|
||||
TaxiNodeFlags requireFlag = (team == Team.Alliance) ? TaxiNodeFlags.ShowOnAllianceMap : TaxiNodeFlags.ShowOnHordeMap;
|
||||
var isVisibleForFaction = (TaxiNodesRecord node) =>
|
||||
{
|
||||
return team switch
|
||||
{
|
||||
Team.Horde => node.HasFlag(TaxiNodeFlags.ShowOnHordeMap),
|
||||
Team.Alliance => node.HasFlag(TaxiNodeFlags.ShowOnAllianceMap),
|
||||
_ => false
|
||||
};
|
||||
};
|
||||
|
||||
foreach (var node in CliDB.TaxiNodesStorage.Values)
|
||||
{
|
||||
if (node.ContinentID != mapid || !node.HasFlag(requireFlag) || node.HasFlag(TaxiNodeFlags.IgnoreForFindNearest))
|
||||
if (node.ContinentID != mapid || !isVisibleForFaction(node) || node.HasFlag(TaxiNodeFlags.IgnoreForFindNearest))
|
||||
continue;
|
||||
|
||||
uint field = (node.Id - 1) / 8;
|
||||
@@ -10890,6 +10944,7 @@ namespace Game
|
||||
Dictionary<ulong, GameObjectAddon> _gameObjectAddonStorage = new();
|
||||
MultiMap<uint, uint> _gameObjectQuestItemStorage = new();
|
||||
List<uint> _gameObjectForQuestStorage = new();
|
||||
Dictionary<uint, DestructibleHitpoint> _destructibleHitpointStorage = new();
|
||||
|
||||
//Item
|
||||
Dictionary<uint, ItemTemplate> ItemTemplateStorage = new();
|
||||
|
||||
@@ -672,15 +672,13 @@ namespace Game.Guilds
|
||||
SendCommandResult(session, GuildCommandType.RemovePlayer, GuildCommandError.RankTooHigh_S, name);
|
||||
else
|
||||
{
|
||||
DeleteMember(null, guid, false, true);
|
||||
_LogEvent(GuildEventLogTypes.UninvitePlayer, player.GetGUID().GetCounter(), guid.GetCounter());
|
||||
|
||||
Player pMember = Global.ObjAccessor.FindConnectedPlayer(guid);
|
||||
SendEventPlayerLeft(pMember, player, true);
|
||||
|
||||
SendCommandResult(session, GuildCommandType.RemovePlayer, GuildCommandError.Success, name);
|
||||
|
||||
// After call to DeleteMember pointer to member becomes invalid
|
||||
DeleteMember(null, guid, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,9 +161,7 @@ namespace Game
|
||||
if (artifactAppearanceSet == null || artifactAppearanceSet.ArtifactID != artifact.GetTemplate().GetArtifactID())
|
||||
return;
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(artifactAppearance.UnlockPlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, artifactAppearance.UnlockPlayerConditionID))
|
||||
return;
|
||||
|
||||
artifact.SetAppearanceModId(artifactAppearance.ItemAppearanceModifierID);
|
||||
|
||||
@@ -63,16 +63,35 @@ namespace Game
|
||||
SendPacket(bnetResponse);
|
||||
}
|
||||
|
||||
public void SendBattlenetRequest(uint serviceHash, uint methodId, IMessage request, Action<CodedInputStream> callback)
|
||||
public void SendBattlenetRequest(OriginalHash serviceHash, uint methodId, IMessage request, bool client, bool server, Action<CodedInputStream> callback)
|
||||
{
|
||||
_battlenetResponseCallbacks[_battlenetRequestToken] = callback;
|
||||
SendBattlenetRequest(serviceHash, methodId, request);
|
||||
SendBattlenetRequest(serviceHash, methodId, request, client, server);
|
||||
}
|
||||
|
||||
public void SendBattlenetRequest(uint serviceHash, uint methodId, IMessage request)
|
||||
public void SendBattlenetRequest(NameHash serviceHash, uint methodId, IMessage request, bool client, bool server, Action<CodedInputStream> callback)
|
||||
{
|
||||
_battlenetResponseCallbacks[_battlenetRequestToken] = callback;
|
||||
SendBattlenetRequest(serviceHash, methodId, request, client, server);
|
||||
}
|
||||
|
||||
public void SendBattlenetRequest(OriginalHash serviceHash, uint methodId, IMessage request, bool client = true, bool server = true)
|
||||
{
|
||||
Notification notification = new();
|
||||
notification.Method.Type = MathFunctions.MakePair64(methodId, serviceHash);
|
||||
notification.Method.Type = MathFunctions.MakePair64(methodId | (client ? 0x40000000 : 0u) | (server ? 0x80000000 : 0u), (uint)serviceHash);
|
||||
notification.Method.ObjectId = 1;
|
||||
notification.Method.Token = _battlenetRequestToken++;
|
||||
|
||||
if (request.CalculateSize() != 0)
|
||||
notification.Data.WriteBytes(request.ToByteArray());
|
||||
|
||||
SendPacket(notification);
|
||||
}
|
||||
|
||||
public void SendBattlenetRequest(NameHash serviceHash, uint methodId, IMessage request, bool client = true, bool server = true)
|
||||
{
|
||||
Notification notification = new();
|
||||
notification.Method.Type = MathFunctions.MakePair64(methodId | (client ? 0x40000000 : 0u) | (server ? 0x80000000 : 0u), (uint)serviceHash);
|
||||
notification.Method.ObjectId = 1;
|
||||
notification.Method.Token = _battlenetRequestToken++;
|
||||
|
||||
|
||||
@@ -1394,9 +1394,7 @@ namespace Game
|
||||
if (!MeetsChrCustomizationReq(req, (Race)packet.CustomizedRace, _player.GetClass(), false, packet.Customizations))
|
||||
return;
|
||||
|
||||
var condition = CliDB.PlayerConditionStorage.LookupByKey(conditionalChrModel.PlayerConditionID);
|
||||
if (condition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, condition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, (uint)conditionalChrModel.PlayerConditionID))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1632,9 +1630,7 @@ namespace Game
|
||||
if (illusion.ItemVisual == 0 || !illusion.HasFlag(SpellItemEnchantmentFlags.AllowTransmog))
|
||||
return false;
|
||||
|
||||
PlayerConditionRecord condition = CliDB.PlayerConditionStorage.LookupByKey(illusion.TransmogUseConditionID);
|
||||
if (condition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, condition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, illusion.TransmogUseConditionID))
|
||||
return false;
|
||||
|
||||
if (illusion.ScalingClassRestricted > 0 && illusion.ScalingClassRestricted != (byte)_player.GetClass())
|
||||
|
||||
@@ -251,9 +251,6 @@ namespace Game
|
||||
|
||||
return;
|
||||
}
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg != null)
|
||||
bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
|
||||
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null)
|
||||
@@ -452,9 +449,7 @@ namespace Game
|
||||
UISplashScreenRecord splashScreen = null;
|
||||
foreach (var itr in CliDB.UISplashScreenStorage.Values)
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(itr.CharLevelConditionID);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, (uint)itr.CharLevelConditionID))
|
||||
continue;
|
||||
|
||||
splashScreen = itr;
|
||||
|
||||
@@ -756,8 +756,7 @@ namespace Game
|
||||
// far teleport case
|
||||
if (GetPlayer().GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Flight)
|
||||
{
|
||||
FlightPathMovementGenerator flight = GetPlayer().GetMotionMaster().GetCurrentMovementGenerator() as FlightPathMovementGenerator;
|
||||
if (flight != null)
|
||||
if (GetPlayer().GetMotionMaster().GetCurrentMovementGenerator() is FlightPathMovementGenerator flight)
|
||||
{
|
||||
bool shouldTeleport = curDestNode != null && curDestNode.ContinentID != GetPlayer().GetMapId();
|
||||
if (!shouldTeleport)
|
||||
|
||||
@@ -440,10 +440,8 @@ namespace Game
|
||||
|
||||
VendorItemPkt item = new();
|
||||
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vendorItem.PlayerConditionId);
|
||||
if (playerCondition != null)
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
|
||||
item.PlayerConditionFailed = (int)playerCondition.Id;
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(_player, vendorItem.PlayerConditionId))
|
||||
item.PlayerConditionFailed = (int)vendorItem.PlayerConditionId;
|
||||
|
||||
if (vendorItem.Type == ItemVendorType.Item)
|
||||
{
|
||||
|
||||
@@ -348,10 +348,6 @@ namespace Game
|
||||
{
|
||||
if (GetPlayer().CanRewardQuest(quest, packet.Choice.LootItemType, packet.Choice.Item.ItemID, true)) // Then check if player can receive the reward item (if inventory is not full, if player doesn't have too many unique items, and so on). If not, the client will close the gossip window
|
||||
{
|
||||
Battleground bg = _player.GetBattleground();
|
||||
if (bg != null)
|
||||
bg.HandleQuestComplete(packet.QuestID, _player);
|
||||
|
||||
GetPlayer().RewardQuest(quest, packet.Choice.LootItemType, packet.Choice.Item.ItemID, obj);
|
||||
}
|
||||
}
|
||||
@@ -650,13 +646,20 @@ namespace Game
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!receiver.SatisfyQuestReputation(quest, false))
|
||||
if (!receiver.SatisfyQuestMinReputation(quest, false))
|
||||
{
|
||||
sender.SendPushToPartyResponse(receiver, QuestPushReason.LowFaction);
|
||||
receiver.SendPushToPartyResponse(sender, QuestPushReason.LowFactionToRecipient, quest);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!receiver.SatisfyQuestMaxReputation(quest, false))
|
||||
{
|
||||
sender.SendPushToPartyResponse(receiver, QuestPushReason.HighFaction);
|
||||
receiver.SendPushToPartyResponse(sender, QuestPushReason.HighFactionToRecipient, quest);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!receiver.SatisfyQuestDependentQuests(quest, false))
|
||||
{
|
||||
sender.SendPushToPartyResponse(receiver, QuestPushReason.Prerequisite);
|
||||
|
||||
@@ -191,15 +191,7 @@ namespace Game
|
||||
var mountDisplays = Global.DB2Mgr.GetMountDisplays(mount.Id);
|
||||
if (mountDisplays != null)
|
||||
{
|
||||
List<MountXDisplayRecord> usableDisplays = mountDisplays.Where(mountDisplay =>
|
||||
{
|
||||
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(mountDisplay.PlayerConditionID);
|
||||
if (playerCondition != null)
|
||||
return ConditionManager.IsPlayerMeetingCondition(GetPlayer(), playerCondition);
|
||||
|
||||
return true;
|
||||
}).ToList();
|
||||
|
||||
List<MountXDisplayRecord> usableDisplays = mountDisplays.Where(mountDisplay => ConditionManager.IsPlayerMeetingCondition(GetPlayer(), mountDisplay.PlayerConditionID)).ToList();
|
||||
if (!usableDisplays.Empty())
|
||||
preferredMountDisplay = usableDisplays.SelectRandom().CreatureDisplayInfoID;
|
||||
}
|
||||
@@ -221,8 +213,7 @@ namespace Game
|
||||
[WorldPacketHandler(ClientOpcodes.TaxiRequestEarlyLanding, Processing = PacketProcessing.ThreadSafe)]
|
||||
void HandleTaxiRequestEarlyLanding(TaxiRequestEarlyLanding taxiRequestEarlyLanding)
|
||||
{
|
||||
FlightPathMovementGenerator flight = GetPlayer().GetMotionMaster().GetCurrentMovementGenerator() as FlightPathMovementGenerator;
|
||||
if (flight != null)
|
||||
if (GetPlayer().GetMotionMaster().GetCurrentMovementGenerator() is FlightPathMovementGenerator flight)
|
||||
{
|
||||
if (GetPlayer().m_taxi.RequestEarlyLanding())
|
||||
{
|
||||
|
||||
@@ -129,15 +129,11 @@ namespace Game
|
||||
return;
|
||||
}
|
||||
|
||||
var condition = CliDB.PlayerConditionStorage.LookupByKey(illusion.UnlockConditionID);
|
||||
if (condition != null)
|
||||
{
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, condition))
|
||||
if (!ConditionManager.IsPlayerMeetingCondition(player, (uint)illusion.UnlockConditionID))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleTransmogrifyItems - {0}, Name: {1} tried to transmogrify illusion using not allowed enchant ({2}).", player.GetGUID().ToString(), player.GetName(), transmogItem.SpellItemEnchantmentID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
illusionItems[itemTransmogrified] = (uint)transmogItem.SpellItemEnchantmentID;
|
||||
cost += illusion.TransmogCost;
|
||||
|
||||
+45
-12
@@ -60,17 +60,10 @@ namespace Game.Maps
|
||||
m_terrain.LoadMMapInstance(GetId(), GetInstanceId());
|
||||
|
||||
_worldStateValues = Global.WorldStateMgr.GetInitialWorldStatesForMap(this);
|
||||
|
||||
Global.OutdoorPvPMgr.CreateOutdoorPvPForMap(this);
|
||||
Global.BattleFieldMgr.CreateBattlefieldsForMap(this);
|
||||
|
||||
Global.ScriptMgr.OnCreateMap(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Global.ScriptMgr.OnDestroyMap(this);
|
||||
|
||||
// Delete all waiting spawns
|
||||
// This doesn't delete from database.
|
||||
UnloadAllRespawnInfos();
|
||||
@@ -86,9 +79,6 @@ namespace Game.Maps
|
||||
if (!m_scriptSchedule.Empty())
|
||||
Global.MapMgr.DecreaseScheduledScriptCount((uint)m_scriptSchedule.Count);
|
||||
|
||||
Global.OutdoorPvPMgr.DestroyOutdoorPvPForMap(this);
|
||||
Global.BattleFieldMgr.DestroyBattlefieldsForMap(this);
|
||||
|
||||
m_terrain.UnloadMMapInstance(GetId(), GetInstanceId());
|
||||
}
|
||||
|
||||
@@ -5273,6 +5263,10 @@ namespace Game.Maps
|
||||
|
||||
public class BattlegroundMap : Map
|
||||
{
|
||||
Battleground m_bg;
|
||||
BattlegroundScript _battlegroundScript;
|
||||
uint _scriptId;
|
||||
|
||||
public BattlegroundMap(uint id, uint expiry, uint InstanceId, Difficulty spawnMode)
|
||||
: base(id, expiry, InstanceId, spawnMode)
|
||||
{
|
||||
@@ -5285,6 +5279,37 @@ namespace Game.Maps
|
||||
m_VisibilityNotifyPeriod = IsBattleArena() ? Global.WorldMgr.GetVisibilityNotifyPeriodInArenas() : Global.WorldMgr.GetVisibilityNotifyPeriodInBG();
|
||||
}
|
||||
|
||||
string GetScriptName()
|
||||
{
|
||||
return Global.ObjectMgr.GetScriptName(_scriptId);
|
||||
}
|
||||
|
||||
public void InitScriptData()
|
||||
{
|
||||
if (_battlegroundScript != null)
|
||||
return;
|
||||
|
||||
Cypher.Assert(GetBG() != null, "Battleground not set yet!");
|
||||
|
||||
BattlegroundScriptTemplate scriptTemplate = Global.BattlegroundMgr.FindBattlegroundScriptTemplate(GetId(), GetBG().GetTypeID());
|
||||
if (scriptTemplate != null)
|
||||
{
|
||||
_scriptId = scriptTemplate.ScriptId;
|
||||
_battlegroundScript = Global.ScriptMgr.CreateBattlegroundData(this);
|
||||
}
|
||||
|
||||
// Make sure every battleground has a default script
|
||||
if (_battlegroundScript == null)
|
||||
{
|
||||
if (IsBattleArena())
|
||||
_battlegroundScript = new ArenaScript(this);
|
||||
else
|
||||
_battlegroundScript = new BattlegroundScript(this);
|
||||
}
|
||||
|
||||
_battlegroundScript.OnInit();
|
||||
}
|
||||
|
||||
public override TransferAbortParams CannotEnter(Player player)
|
||||
{
|
||||
if (player.GetMap() == this)
|
||||
@@ -5327,10 +5352,18 @@ namespace Game.Maps
|
||||
player.TeleportTo(player.GetBattlegroundEntryPoint());
|
||||
}
|
||||
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
base.Update(diff);
|
||||
_battlegroundScript.OnUpdate(diff);
|
||||
}
|
||||
|
||||
public Battleground GetBG() { return m_bg; }
|
||||
public void SetBG(Battleground bg) { m_bg = bg; }
|
||||
|
||||
Battleground m_bg;
|
||||
public uint GetScriptId() { return _scriptId; }
|
||||
|
||||
public BattlegroundScript GetBattlegroundScript() { return _battlegroundScript; }
|
||||
}
|
||||
|
||||
public class TransferAbortParams
|
||||
@@ -5396,7 +5429,7 @@ namespace Game.Maps
|
||||
public float FloorZ;
|
||||
public bool outdoors = true;
|
||||
public ZLiquidStatus LiquidStatus;
|
||||
public WmoLocation? wmoLocation;
|
||||
public WmoLocation wmoLocation;
|
||||
public LiquidData LiquidInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ namespace Game.Entities
|
||||
Cypher.Assert(map.IsBattlegroundOrArena());
|
||||
map.SetBG(bg);
|
||||
bg.SetBgMap(map);
|
||||
map.InitScriptData();
|
||||
map.InitSpawnGroupState();
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.BattlegroundMapLoadGrids))
|
||||
@@ -198,7 +199,7 @@ namespace Game.Entities
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
map = CreateInstance(mapId, newInstanceId, instanceLock, difficulty, player.GetTeamId(), group);
|
||||
map = CreateInstance(mapId, newInstanceId, instanceLock, difficulty, SharedConst.GetTeamIdForTeam(Global.CharacterCacheStorage.GetCharacterTeamByGuid(instanceOwnerGuid)), group);
|
||||
if (group != null)
|
||||
group.SetRecentInstance(mapId, instanceOwnerGuid, newInstanceId);
|
||||
else
|
||||
@@ -224,8 +225,14 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
i_maps[(map.GetId(), map.GetInstanceId())] = map;
|
||||
|
||||
Global.ScriptMgr.OnCreateMap(map);
|
||||
Global.OutdoorPvPMgr.CreateOutdoorPvPForMap(map);
|
||||
Global.BattleFieldMgr.CreateBattlefieldsForMap(map);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -320,6 +327,10 @@ namespace Game.Entities
|
||||
|
||||
map.UnloadAll();
|
||||
|
||||
Global.OutdoorPvPMgr.DestroyOutdoorPvPForMap(map);
|
||||
Global.BattleFieldMgr.DestroyBattlefieldsForMap(map);
|
||||
Global.ScriptMgr.OnDestroyMap(map);
|
||||
|
||||
// Free up the instance id and allow it to be reused for normal dungeons, bgs and arenas
|
||||
if (map.IsBattlegroundOrArena() || (map.IsDungeon() && !map.GetMapDifficulty().HasResetSchedule()))
|
||||
FreeInstanceId(map.GetInstanceId());
|
||||
@@ -337,11 +348,17 @@ namespace Game.Entities
|
||||
public void UnloadAll()
|
||||
{
|
||||
// first unload maps
|
||||
foreach (var pair in i_maps)
|
||||
pair.Value.UnloadAll();
|
||||
foreach (var (_, map) in i_maps)
|
||||
{
|
||||
map.UnloadAll();
|
||||
|
||||
foreach (var pair in i_maps)
|
||||
pair.Value.Dispose();
|
||||
Global.OutdoorPvPMgr.DestroyOutdoorPvPForMap(map);
|
||||
Global.BattleFieldMgr.DestroyBattlefieldsForMap(map);
|
||||
Global.ScriptMgr.OnDestroyMap(map);
|
||||
}
|
||||
|
||||
foreach (var (_, map) in i_maps)
|
||||
map.Dispose();
|
||||
|
||||
i_maps.Clear();
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ namespace Game.Maps
|
||||
{
|
||||
public class ZoneScript
|
||||
{
|
||||
protected EventMap _events = new();
|
||||
protected TaskScheduler _scheduler = new();
|
||||
|
||||
public virtual void TriggerGameEvent(uint gameEventId, WorldObject source = null, WorldObject target = null)
|
||||
{
|
||||
if (source != null)
|
||||
@@ -48,8 +51,6 @@ namespace Game.Maps
|
||||
|
||||
public virtual bool CanCaptureFlag(AreaTrigger areaTrigger, Player player) { return false; }
|
||||
public virtual void OnCaptureFlag(AreaTrigger areaTrigger, Player player) { }
|
||||
|
||||
protected EventMap _events = new();
|
||||
}
|
||||
|
||||
public class ControlZoneHandler
|
||||
|
||||
@@ -243,8 +243,7 @@ namespace Game.Movement
|
||||
if (target.GetMotionMaster().GetCurrentMovementGeneratorType() != MovementGeneratorType.Chase)
|
||||
return false;
|
||||
|
||||
ChaseMovementGenerator movement = target.GetMotionMaster().GetCurrentMovementGenerator() as ChaseMovementGenerator;
|
||||
if (movement != null)
|
||||
if (target.GetMotionMaster().GetCurrentMovementGenerator() is ChaseMovementGenerator movement)
|
||||
return movement.GetTarget() == owner;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -148,8 +148,7 @@ namespace Game.Movement
|
||||
{
|
||||
case MovementGeneratorType.Chase:
|
||||
case MovementGeneratorType.Follow:
|
||||
var followInformation = movement as FollowMovementGenerator;
|
||||
if (followInformation != null)
|
||||
if (movement is FollowMovementGenerator followInformation)
|
||||
{
|
||||
Unit target = followInformation.GetTarget();
|
||||
if (target != null)
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Game.Networking.Packets
|
||||
public AuctionHouseFilterMask Filters;
|
||||
public byte[] KnownPets;
|
||||
public sbyte MaxPetLevel;
|
||||
public uint Unused1026;
|
||||
public AddOnInfo? TaintedBy;
|
||||
public string Name;
|
||||
public Array<AuctionListFilterClass> ItemClassFilters = new(7);
|
||||
@@ -37,6 +38,7 @@ namespace Game.Networking.Packets
|
||||
Filters = (AuctionHouseFilterMask)_worldPacket.ReadUInt32();
|
||||
uint knownPetSize = _worldPacket.ReadUInt32();
|
||||
MaxPetLevel = _worldPacket.ReadInt8();
|
||||
Unused1026 = _worldPacket.ReadUInt32();
|
||||
|
||||
uint sizeLimit = CliDB.BattlePetSpeciesStorage.GetNumRows() / 8 + 1;
|
||||
if (knownPetSize >= sizeLimit)
|
||||
|
||||
@@ -326,12 +326,6 @@ namespace Game.Networking.Packets
|
||||
|
||||
public struct RaceLimitDisableInfo
|
||||
{
|
||||
enum blah
|
||||
{
|
||||
Server,
|
||||
Level
|
||||
}
|
||||
|
||||
public int RaceID;
|
||||
public int BlockReason;
|
||||
|
||||
@@ -386,6 +380,7 @@ namespace Game.Networking.Packets
|
||||
bool hasTemplateSet = _worldPacket.HasBit();
|
||||
CreateInfo.IsTrialBoost = _worldPacket.HasBit();
|
||||
CreateInfo.UseNPE = _worldPacket.HasBit();
|
||||
CreateInfo.Unused1026 = _worldPacket.HasBit();
|
||||
|
||||
CreateInfo.RaceId = (Race)_worldPacket.ReadUInt8();
|
||||
CreateInfo.ClassId = (Class)_worldPacket.ReadUInt8();
|
||||
@@ -1144,6 +1139,7 @@ namespace Game.Networking.Packets
|
||||
public uint? TemplateSet;
|
||||
public bool IsTrialBoost;
|
||||
public bool UseNPE;
|
||||
public bool Unused1026;
|
||||
public string Name;
|
||||
|
||||
// Server side data
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Game.Networking.Packets
|
||||
public override void Read()
|
||||
{
|
||||
PlayerGuid = _worldPacket.ReadPackedGuid();
|
||||
DataType = (AccountDataTypes)_worldPacket.ReadBits<uint>(4);
|
||||
DataType = (AccountDataTypes)_worldPacket.ReadInt32();
|
||||
}
|
||||
|
||||
public ObjectGuid PlayerGuid;
|
||||
@@ -56,10 +56,10 @@ namespace Game.Networking.Packets
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WritePackedGuid(Player);
|
||||
_worldPacket.WriteInt64(Time);
|
||||
_worldPacket.WriteUInt32(Size);
|
||||
_worldPacket.WriteBits(DataType, 4);
|
||||
_worldPacket.WritePackedGuid(Player);
|
||||
_worldPacket.WriteInt32((int)DataType);
|
||||
|
||||
if (CompressedData == null)
|
||||
_worldPacket.WriteUInt32(0);
|
||||
@@ -84,10 +84,10 @@ namespace Game.Networking.Packets
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
PlayerGuid = _worldPacket.ReadPackedGuid();
|
||||
Time = _worldPacket.ReadInt64();
|
||||
Size = _worldPacket.ReadUInt32();
|
||||
DataType = (AccountDataTypes)_worldPacket.ReadBits<uint>(4);
|
||||
PlayerGuid = _worldPacket.ReadPackedGuid();
|
||||
DataType = (AccountDataTypes)_worldPacket.ReadInt32();
|
||||
|
||||
uint compressedSize = _worldPacket.ReadUInt32();
|
||||
if (compressedSize != 0)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user