/// <summary> /// Begins the capturing process. A base will turn if not taken back /// </summary> /// <param name="chr"></param> public void BeginCapture(Character chr) { Capturer = chr; CaptureTimer.Start(CapturePointConversionDelayMillis, 0); SpawnContested(); ABSounds sound; if (_side == BattlegroundSide.End) { sound = ABSounds.NodeContested; Instance.WorldStates.SetInt32(showIconNeutral, 0); } else if (_side == BattlegroundSide.Alliance) { sound = ABSounds.NodeAssaultedHorde; } else { sound = ABSounds.NodeAssaultedAlliance; } if (chr.Battlegrounds.Team.Side == BattlegroundSide.Alliance) { State = BaseState.ContestedAlliance; Instance.WorldStates.SetInt32(showIconAllianceContested, 1); Instance.WorldStates.SetInt32(showIconHordeControlled, 0); } else { State = BaseState.ContestedHorde; Instance.WorldStates.SetInt32(showIconHordeContested, 1); Instance.WorldStates.SetInt32(showIconAllianceControlled, 0); } var time = RealmLocalizer.FormatTimeSecondsMinutes(CapturePointConversionDelayMillis / 1000); foreach (Character character in Instance.Characters) { character.SendSystemMessage(DefaultAddonLocalizer.Instance.Translate(character.Locale, AddonMsgKey.ABBaseClaimed, chr.Name, Names[(int)character.Locale], chr.Battlegrounds.Team.Side, time)); } MiscHandler.SendPlaySoundToMap(Instance, (uint)sound); var evt = BaseChallenged; if (evt != null) { evt(chr); } }
protected bool Start() { try { IsCached = AuthServerConfiguration.CacheAccounts; //I would have liked this to be a readonly field but it must be //initialised here otherwise in the ctor AccountReloadIntervalMs //wont have been init'd which would mean we cant customise the timer easily _accountsReloadTimer = new TimerEntry(0, AccountReloadIntervalMs, delay => { if (Instance.IsCached) { Instance.Resync(); } }); _accountsReloadTimer.Start(); AuthenticationServer.IOQueue.RegisterUpdatable(_accountsReloadTimer); if (Count == 0) { log.Info("Detected empty Account-database."); //if (!DoesAccountExist("Administrator")) //{ // CreateAccount("Administrator", DefaultAdminPW, null, RoleGroupInfo.HighestRole.Name, ClientId.Wotlk); // log.Warn("Created new Account \"Administrator\" with same password."); //} } } catch (Exception e) { AuthDBMgr.OnDBError(e); } return(true); }
/// <summary> /// Restarts the spawn timer with the given delay /// </summary> public void SpawnAfter(int delay) { if (Pool.IsActive && !m_timer.IsRunning) { m_nextRespawn = Environment.TickCount + delay; m_timer.Start(delay); Map.RegisterUpdatableLater(m_timer); } }
/// <summary> /// Starts the shutdown timer with the given delay /// </summary> protected virtual void StartShutdown(int millis) { _shutdownTimer.Start(millis); foreach (var chr in m_characters) { chr.Auras.Remove(_preparationSpell); } }
protected override void OnLeave(Character chr) { if (PlayerCount > 1) { return; } if (TimeoutDelay > 0) { m_timeoutTimer.Start(TimeoutDelay, 0); } s_log.Debug("{0} #{1} timeout timer started.", Name, m_InstanceId); }
/// <summary> /// Opens this SpellChannel. /// Will be called by SpellCast class. /// Requires an active Caster. /// </summary> internal void Open(List <SpellEffectHandler> channelHandlers, List <IAura> auras) { if (!m_channeling && m_cast != null) { m_channeling = true; m_auras = auras; var spell = m_cast.Spell; var caster = m_cast.CasterUnit; m_duration = spell.Durations.Max; m_amplitude = spell.ChannelAmplitude; if (m_amplitude < 1) { // only one tick m_amplitude = m_duration; } caster.ChannelSpell = spell.SpellId; var now = Environment.TickCount; m_ticks = 0; m_maxTicks = m_duration / m_amplitude; m_channelHandlers = channelHandlers; // get duration again, this time with modifiers m_duration = spell.GetDuration(caster.SharedReference); if (m_amplitude < 1) { // only one tick m_amplitude = m_duration; } m_until = now + m_duration; SpellHandler.SendChannelStart(m_cast, spell.SpellId, m_duration); if (m_channeling) { m_timer.Start(m_amplitude, m_amplitude); } // Send Initial Tick? // Keep in mind: Aura is not initialized at this point! } else { log.Warn(this + " was opened more than once or after disposal!"); } }
/// <summary> /// Finalizes a capture (Flag changes colour (de/respawns, casts spells, etc) /// </summary> public void Capture() { var stats = (ArathiStats)Capturer.Battlegrounds.Stats; stats.BasesAssaulted++; FlagStand.Delete(); ActualAura.Delete(); ABSounds sound; if (Capturer.Battlegrounds.Team.Side == BattlegroundSide.Horde) { BaseOwner = BattlegroundSide.Horde; State = BaseState.CapturedHorde; SpawnHorde(); sound = ABSounds.NodeCapturedHorde; Instance.WorldStates.SetInt32(showIconHordeControlled, 1); Instance.WorldStates.SetInt32(showIconHordeContested, 0); } else { BaseOwner = BattlegroundSide.Alliance; State = BaseState.CapturedAlliance; SpawnAlliance(); sound = ABSounds.NodeCapturedAlliance; Instance.WorldStates.SetInt32(showIconAllianceControlled, 1); Instance.WorldStates.SetInt32(showIconAllianceContested, 0); } // It takes a few minutes before a captured flag begins to give score. StartScoreTimer.Start(ScoreDelayMillis, 0); foreach (Character character in Instance.Characters) { character.SendSystemMessage(DefaultAddonLocalizer.Instance.Translate(character.Locale, AddonMsgKey.ABBaseTaken, BaseOwner, Names[(int)character.Locale])); } MiscHandler.SendPlaySoundToMap(Instance, (uint)sound); var evt = BaseCaptured; if (evt != null) { evt(Capturer); } }
/// <summary> /// Forces the server to shutdown after the given delay. /// </summary> /// <param name="delayMillis">the time to wait before shutting down</param> public virtual void ShutdownIn(uint delayMillis) { m_shutdownTimer = new TimerEntry((int)delayMillis, 0, upd => { AppUtil.UnhookAll(); if (IsRunning) { _OnShutdown(); } }); m_shutdownTimer.Start(); if (!IsPreparingShutdown) { ioQueue.RegisterUpdatable(m_shutdownTimer); IsPreparingShutdown = true; } }
private void LoadDeathState() { if (m_record.CorpseX != null) { // we were dead and released the corpse var map = World.GetNonInstancedMap(m_record.CorpseMap); if (map != null) { m_corpse = SpawnCorpse(false, false, map, new Vector3(m_record.CorpseX.Value, m_record.CorpseY, m_record.CorpseZ), m_record.CorpseO); BecomeGhost(); } else { // can't spawn corpse -> revive if (log.IsWarnEnabled) { log.Warn("Player {0}'s Corpse was spawned in invalid map: {1}", this, m_record.CorpseMap); } } } else if (m_record.Health == 0) { // we were dead and did not release yet var diff = DateTime.Now.Subtract(m_record.LastDeathTime).ToMilliSecondsInt() + Corpse.AutoReleaseDelay; m_corpseReleaseTimer = new TimerEntry(dt => ReleaseCorpse()); if (diff > 0) { // mark dead and start release timer MarkDead(); m_corpseReleaseTimer.Start(diff, 0); } else { // auto release ReleaseCorpse(); } } else { // we are alive and kicking } }
/// <summary> /// 延迟指定时间后关闭 /// </summary> /// <param name="delayMillis"></param> public virtual void ShutdownIn(uint delayMillis) { IsShuttingDown = true; m_shutdownTimer = new TimerEntry(delayMillis / 1000f, 0f, upd => { //AppUtil.UnhookAll(); if (IsRunning) { _OnShutdown(); } }); m_shutdownTimer.Start(); if (!IsPreparingShutdown) { RegisterUpdatable(m_shutdownTimer); IsPreparingShutdown = true; } }
protected internal override void InitMap() { base.InitMap(); BattlegroundMgr.Instances.AddInstance(Template.Id, this); _preparationSpell = SpellHandler.Get(PreparationSpellId); _healingReductionSpell = SpellHandler.Get(HealingReductionSpellId); if (HasQueue) { _instanceQueue = new InstanceBattlegroundQueue(this); _queueTimer.Start(0, UpdateQueueMillis); } _teams[(int)BattlegroundSide.Alliance] = CreateAllianceTeam(); _teams[(int)BattlegroundSide.Horde] = CreateHordeTeam(); ProcessPendingPlayers(); }
/// <summary> /// 注册心跳 /// </summary> /// <param name="func"></param> /// <param name="delay"> </param> /// <param name="intervalMS"></param> /// <param name="count"></param> /// <param name="tag"></param> /// <param name="rsv"></param> /// <param name="type"> </param> /// <returns></returns> public int Reg(Action <float> func, int delay, int intervalMS, int count = -1, object tag = null, object rsv = null, TimerType type = TimerType.Important) { TimerEntry timer; int tId; if (count == -1) { timer = new TimerEntry(delay, intervalMS, func); timer.Start(); tId = timer.Id; } else { timer = new TimerEntry(delay, intervalMS, func, count); timer.Start(); tId = timer.Id; } RegisterUpdatable(timer); return(tId); }
/// <summary> /// Opens this SpellChannel. /// Will be called by SpellCast class. /// Requires an active Caster. /// </summary> internal void Open(List <SpellEffectHandler> channelHandlers, List <IAura> auras) { if (!m_channeling && m_cast != null) { m_channeling = true; m_auras = auras; Spell spell = m_cast.Spell; Unit casterUnit = m_cast.CasterUnit; m_duration = spell.Durations.Max; m_amplitude = spell.ChannelAmplitude; if (m_amplitude < 1) { m_amplitude = m_duration; } casterUnit.ChannelSpell = spell.SpellId; int tickCount = Environment.TickCount; m_ticks = 0; m_maxTicks = m_duration / m_amplitude; m_channelHandlers = channelHandlers; m_duration = spell.GetDuration(casterUnit.SharedReference); if (m_amplitude < 1) { m_amplitude = m_duration; } m_until = tickCount + m_duration; SpellHandler.SendChannelStart(m_cast, spell.SpellId, m_duration); if (!m_channeling) { return; } m_timer.Start(m_amplitude, m_amplitude); } else { log.Warn(ToString() + " was opened more than once or after disposal!"); } }
/// <summary> /// Tries to land a mainhand hit + maybe offhand hit on the current Target /// </summary> protected virtual void CombatTick(int timeElapsed) { // if currently casting a spell, skip this if (IsUsingSpell && !m_spellCast.IsPending) { m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); return; } if (!CheckCombatState()) { if (m_isInCombat) { // if still in combat - check soon again m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); } return; } if (!CanDoHarm || !CanMelee) { m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); return; } var target = m_target; if (target == null || target.IsDead) { IsFighting = false; if (this is NPC) { Movement.MayMove = true; } return; } var now = Environment.TickCount; var isRanged = IsUsingRangedWeapon; var mainHandDelay = m_lastStrike + (isRanged ? RangedAttackTime : MainHandAttackTime) - now; var strikeReady = mainHandDelay <= 0; // try to strike if (strikeReady) { if (this is NPC) { Movement.MayMove = true; } var distanceSq = GetDistanceSq(target); var mainWeapon = isRanged ? m_RangedWeapon : m_mainWeapon; if (mainWeapon != null) { if (IsInAttackRangeSq(mainWeapon, target, distanceSq)) { // close enough if (m_AutorepeatSpell != null) { // Auto-shot (only when not running) if (!IsMoving) { SpellCast.TargetFlags = SpellTargetFlags.Unit; SpellCast.SelectedTarget = target; SpellCast.Start(m_AutorepeatSpell, false); m_lastStrike = now; mainHandDelay += RangedAttackTime; } } else { var chr = this as Character; if (chr != null) { chr.IsMoving = false; } Strike(mainWeapon); m_lastStrike = now; mainHandDelay += MainHandAttackTime; if (this is NPC) { Movement.MayMove = false; } } } else { // too far away if (UsesPendingAbility(mainWeapon)) { // ability is pending -> Need to cancel m_spellCast.Cancel(SpellFailedReason.OutOfRange); } // no pending ability if (this is Character) { CombatHandler.SendAttackSwingNotInRange(this as Character); } else if (this is NPC) { Brain.OnCombatTargetOutOfRange(); } } } } m_attackTimer.Start(mainHandDelay <= 0 ? 1000 : mainHandDelay); }
/// <summary> /// Tries to land a mainhand hit + maybe offhand hit on the current Target /// </summary> protected virtual void CombatTick(int timeElapsed) { // if currently casting a spell, skip this if (IsUsingSpell && !m_spellCast.IsPending) { m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); return; } if (!CheckCombatState()) { if (m_isInCombat) { // if still in combat - check soon again m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); } return; } if (!CanDoHarm || !CanMelee) { m_attackTimer.Start(DamageAction.DefaultCombatTickDelay); return; } var target = m_target; var now = Environment.TickCount; var usesOffHand = UsesDualWield; var isRanged = IsUsingRangedWeapon; var mainHandDelay = m_lastStrike + (isRanged ? RangedAttackTime : MainHandAttackTime) - now; int offhandDelay; var strikeReady = mainHandDelay <= 0; bool offHandReady; if (usesOffHand) { offhandDelay = m_lastOffhandStrike + OffHandAttackTime - now; offHandReady = true; } else { offhandDelay = int.MaxValue; offHandReady = false; } // try to strike if (strikeReady || offHandReady) { if (this is Character && !target.IsInFrontOf(this)) { CombatHandler.SendAttackSwingBadFacing(this as Character); } else { var distanceSq = GetDistanceSq(target); if (strikeReady) { var mainWeapon = isRanged ? m_RangedWeapon : m_mainWeapon; if (mainWeapon != null) { if (IsInAttackRangeSq(mainWeapon, target, distanceSq)) { // close enough if (m_AutorepeatSpell != null) { // Auto-shot (only when not running) if (!IsMoving) { SpellCast.TargetFlags = SpellTargetFlags.Unit; SpellCast.SelectedTarget = target; SpellCast.Start(m_AutorepeatSpell, false); m_lastStrike = now; mainHandDelay += RangedAttackTime; } } else { Strike(mainWeapon); m_lastStrike = now; mainHandDelay += MainHandAttackTime; } } else { // too far away if (UsesPendingAbility(mainWeapon)) { // ability is pending -> Need to cancel m_spellCast.Cancel(SpellFailedReason.OutOfRange); } // no pending ability if (this is Character) { CombatHandler.SendAttackSwingNotInRange(this as Character); } else if (this is NPC) { Brain.OnCombatTargetOutOfRange(); } } } } if (offHandReady) { if (IsInAttackRangeSq(m_offhandWeapon, target, distanceSq)) { // in range for a strike Strike(m_offhandWeapon); m_lastOffhandStrike = now; offhandDelay += OffHandAttackTime; } else { // too far away if (UsesPendingAbility(m_offhandWeapon)) { // ability is pending -> Need to cancel m_spellCast.Cancel(SpellFailedReason.OutOfRange); } } } } } // determine the next strike int delay; strikeReady = mainHandDelay <= 0; offHandReady = usesOffHand && offhandDelay <= 0; if (strikeReady) { // mainhand is ready but not in reach if (offHandReady || !usesOffHand) { // mainhand is ready and offhand is either also ready or not present delay = DamageAction.DefaultCombatTickDelay; } else { // mainhand is ready and offhand is still waiting delay = Math.Min(DamageAction.DefaultCombatTickDelay, offhandDelay); } } else { // mainhand is not ready if (offHandReady) { // mainhand is not ready but offhand is ready delay = Math.Min(DamageAction.DefaultCombatTickDelay, mainHandDelay); } else { if (usesOffHand) { // mainhand and offhand are both not ready delay = Math.Min(offhandDelay, mainHandDelay); } else { // mainhand is not ready and there is no offhand delay = mainHandDelay; } } } m_attackTimer.Start(delay); }
internal void StartTimer() { m_timer = new TimerEntry(AuthenticationStoreMillis, 0, dl => Remove()); m_timer.Start(); AuthenticationServer.IOQueue.RegisterUpdatable(m_timer); }