/// <summary> /// Initializes a new instance of the <see cref = "MmoObjectAutoSubscription" /> class. /// </summary> public MmoObjectAutoSubscription(MmoObject mmoObject, Vector3 position, Region region, IDisposable subscription) { this.Position = position; this.mmoObject = mmoObject; this.subscription = subscription; this.WorldRegion = region; }
/// <summary> /// Casts the spell on a(n) <see cref="MmoObject"/> /// </summary> public CastResults Cast(MmoObject victim) { if (victim == null) { victim = this.caster; } var result = this.CheckSpell(victim); if (result == CastResults.Ok) { this.target = victim; this.caster.DrainVitalPower(this.powerType, this.powerCost); if (castTime > 0) { this.state = SpellStates.Casting; this.castingTimer = 0; this.spellManager.OnBeginCasting(this); } else { this.state = SpellStates.CastFinished; } this.lastCasterPosition = caster.Position; this.spellManager.AddSpellUpdateEvent(this); } return(result); }
/// <summary> /// Creates a new instance of the <see cref="MmoObjectSnapshot"/> class. /// </summary> public MmoObjectSnapshot(MmoObject source, Vector3 position, Vector3 rotation, int revision, Region region) { this.source = source; this.position = position; this.rotation = rotation; this.revision = revision; this.region = region; this.coordinate = position.ToFloatArray(3); }
/// <summary> /// Applies the spell effect on the casting target /// </summary> void ApplyEffect(MmoObject victim) { if (effects != null) { for (int i = 0; i < this.effects.Length; i++) { var index = (int)this.effects[i]; this.effectHandlers[index](i, victim); } } }
/// <summary> /// Creates a new instance of the <see cref="RandomLootContainer"/> class. /// </summary> public RandomLootContainer(MmoObject owner, short lootGroupId, Func <short, Player, bool> itemFilter, Action <Player> lootAddedCallback = null, Action <Player> lootRemovedCallback = null) { this.owner = owner; this.lootGroupId = lootGroupId; this.itemFilter = itemFilter; this.lootAddedCallback = lootAddedCallback; this.lootRemovedCallback = lootRemovedCallback; this.playerLoots = new Dictionary <MmoGuid, Loot>(); }
/// <summary> /// Unsubscribes an <see cref="MmoObject"/> manually. /// </summary> /// <param name="mmoObject"></param> public void UnsubscribeManually(MmoObject mmoObject) { lock (this.SyncRoot) { MmoObjectAutoSubscription subscription; if (this.autoManagedItemSubscriptions.TryGetValue(mmoObject, out subscription)) { this.AutoUnsubscribeMmoObject(subscription); } } }
/// <summary> /// Removes a(n) <see cref="MmoObject"/> from the <see cref="MmoZone"/>. /// </summary> /// <returns></returns> public bool Remove(MmoObject mmoObject) { while (!objectCache.RemoveItem(mmoObject.Guid)) { MmoObject existingObject; if (!objectCache.TryGetItem(mmoObject.Guid, out existingObject)) { return(false); } } return(true); }
/// <summary> /// Creates a new instance of the <see cref="FixedLootContainer"/> class. /// </summary> public FixedLootContainer(MmoObject owner, short lootGroupId, Func <short, Player, bool> itemFilter, Action <Player> lootAddedCallback = null, Action <Player> lootRemovedCallback = null) { this.owner = owner; this.itemFilter = itemFilter; this.lootAddedCallback = lootAddedCallback; this.lootRemovedCallback = lootRemovedCallback; this.playerLoots = new Dictionary <MmoGuid, Loot>(); // generating the intial loot which will be fixed this.lootItems = GenerateLoot(lootGroupId); }
/// <summary> /// Adds a(n) <see cref="MmoObject"/> to the <see cref="MmoZone"/>. /// </summary> /// <returns></returns> public bool Add(MmoObject mmoObject) { // using a while loop for the lock-timeout while (!objectCache.AddItem(mmoObject)) { MmoObject existingObject; if (objectCache.TryGetItem(mmoObject.Guid, out existingObject)) { return(false); } } return(true); }
/// <summary> /// Interupts the spell casting /// </summary> public void InteruptCast() { if (state == SpellStates.Casting) { this.spellManager.RemoveSpellUpdateEvent(this); this.spellManager.OnEndCasting(this, true); this.castingTimer = 0; this.target = null; this.state = this.isProc ? SpellStates.WaitingForProc : SpellStates.Idle; } }
private void HandleEffectPowerGain(int effectIndex, MmoObject victim) { switch ((ObjectType)victim.Guid.Type) { case ObjectType.Npc: case ObjectType.Player: { var amount = this.effectBaseValues[effectIndex]; var charUnit = (Character)victim; charUnit.GainPower(caster, amount, this); } break; } }
private void HandleEffectSchoolDamage(int effectIndex, MmoObject victim) { // TODO: Compensate dmg for school defense switch ((ObjectType)victim.Guid.Type) { case ObjectType.Npc: case ObjectType.Player: { var amount = this.effectBaseValues[effectIndex]; var charUnit = (Character)victim; charUnit.Damage(caster, amount, this); } break; } }
/// <summary> /// Resets the spell /// </summary> void ResetSpell() { this.target = null; if (cooldown > 0) { this.state = SpellStates.Cooldown; this.cooldownTimer = 0; this.spellManager.OnBeginCooldown(this); } else { this.state = this.isProc ? SpellStates.WaitingForProc : SpellStates.Idle; this.spellManager.RemoveSpellUpdateEvent(this); } }
/// <summary> /// Unsubscribes the player from the item's event channel and notifies the client /// </summary> protected override void OnMmoObjectUnsubscribed(MmoObject mmoObject) { IDisposable messageReceiver = this.eventChannelSubscriptions[mmoObject]; this.eventChannelSubscriptions.Remove(mmoObject); messageReceiver.Dispose(); // when there is no owner there is no need to send an event to client if (Owner == null) { return; } this.receiver.SendEvent(new ObjectUnsubscribed { ObjectId = mmoObject.Guid }, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.Owner.OnUnsubscribe(mmoObject); }
/// <summary> /// Casts a spell /// </summary> public CastResults CastSpell(short id, MmoObject target) { if (IsCasting) { return(CastResults.AlreadyCasting); } Spell spell; if (spells.TryGetValue(id, out spell)) { if (spell.AffectedByGCD && this.inGcd) { return(CastResults.InGcd); } var result = spell.Cast(target); if (result == CastResults.Ok) { if (spell.TriggersGCD) { this.inGcd = true; this.owner.BeginClientCooldown(-1); // SpellId of -1 = GCD this.gcdSubscription = this.owner.CurrentZone.PrimaryFiber.Schedule(() => { this.inGcd = false; this.owner.EndClientCooldown(-1); // SpellId of -1 = GCD } , (long)(GCD * 1000)); // activates gcd } } return(result); } return(CastResults.SpellNotFound); }
/// <summary> /// Called by the <see cref = "MmoObject" /> when received. /// </summary> public abstract void OnMmoObjectReceive(MmoObject gameObject);
/// <summary> /// Casts the use spell on an <see cref="MmoObject"/>. /// </summary> /// <param name="mmoObject"></param> public void CastUse(MmoObject mmoObject) { this.CastSpell(ServerGameSettings.USE_SPELL_ID, mmoObject); }
/// <summary> /// Called by the <see cref = "MmoObject" /> when received. /// Increments <see cref = "MessageCounters.CounterReceive" /> and publishes an <see cref = "MmoObjectPositionMessage" /> in the <paramref name = "item" />'s <see cref = "MmoObject.CurrentRegion" />. /// </summary> public override void OnMmoObjectReceive(MmoObject gameObject) { MmoObjectSnapshot gameObjectSnapshot = gameObject.GetMmoObjectSnapshot(); this.source.ReceiveMmoObjectSnapshot(gameObjectSnapshot); }
/// <summary> /// Checks whether to auto subscribe the <paramref name = "mmoObject" />. /// The default implementation ignores the <see cref = "Owner" />. /// Override to change or extend this behavior. /// </summary> protected virtual bool CanAutoSubscribeMmoObject(MmoObject mmoObject) { return(mmoObject != this.Owner && mmoObject.IsHiddenFor(Owner.Guid) == false); }
/// <summary> /// Creates a new <see cref="MmoObjectPositionMessage"/>. /// </summary> public MmoObjectPositionMessage(MmoObject source, Vector3 position, Region worldRegion) { this.source = source; this.position = position; this.worldRegion = worldRegion; }
/// <summary> /// Does nothing. /// Called after subscribing an <see cref = "MmoObject" />. /// </summary> protected virtual void OnMmoObjectUnsubscribed(MmoObject item) { }
/// <summary> /// Adds an item to the cache /// </summary> public bool AddItem(MmoObject mmoObject) { var guid = mmoObject.Guid; return(objects.Add(guid.Type, guid.Id, mmoObject)); }
private void HandleEffectApplyAura(int effectIndex, MmoObject victim) { Utils.Logger.DebugFormat("Effect: ApplyAura. Value: {0}. Target: {1}", this.effectBaseValues[effectIndex], victim.Guid); }
/// <summary> /// Initializes a new instance of the <see cref = "MmoObjectDisposedMessage" /> class. /// </summary> /// <param name = "source"> /// The source. /// </param> public MmoObjectDisposedMessage(MmoObject source) { this.source = source; }
/// <summary> /// Increments <see cref = "MessageCounters.CounterReceive" />. /// Called by the <see cref = "MmoObject" /> when received. /// </summary> public override void OnMmoObjectReceive(MmoObject gameObject) { }
/// <summary> /// Automatically subscribes an <see cref="MmoObject"/> manually. /// </summary> /// <param name="mmoObject"></param> public void AutoSubscribeManually(MmoObject mmoObject) { this.ReceiveMmoObjectSnapshot(mmoObject.GetMmoObjectSnapshot()); }
/// <summary> /// Called by the <see cref="MmoObject"/> when received. /// </summary> /// <param name="gameObject"></param> public override void OnMmoObjectReceive(MmoObject gameObject) { this.source.ProcessThreat(gameObject); }
/// <summary> /// Initializes a new instance of the <see cref = "MmoObjectEventMessage" /> class. /// </summary> /// <param name = "source"> /// The source. /// </param> /// <param name = "eventData"> /// The event data. /// </param> /// <param name = "parameters"> /// The message parameters /// </param> public MmoObjectEventMessage(MmoObject source, GameEvent eventData, MessageParameters parameters) { this.source = source; this.eventData = eventData; this.parameters = parameters; }
/// <summary> /// Checks to see whether the spell can be casted on a(n) <see cref="MmoObject"/> or not. /// </summary> protected CastResults CheckSpell(MmoObject victim) { if ((flags & SpellFlags.FLAG_SPECIAL_NO_REQ_CHECK) == SpellFlags.FLAG_SPECIAL_NO_REQ_CHECK) { return(CastResults.Ok); } if (victim == null || victim == this.caster) { return(this.CheckSpell()); } if (state != SpellStates.Idle) { return(CastResults.SpellNotReady); } if (targetSelectionMethod == SpellTargetSelectionMethods.AreaOfEffect || targetSelectionMethod == SpellTargetSelectionMethods.Cone) { // TODO: Needs to check to see whether the character is in live or ghost mode return(caster.HaveVitalPower(this.powerType, this.powerCost) ? CastResults.Ok : CastResults.NotEnoughPower); } switch ((ObjectType)victim.Guid.Type) { case ObjectType.Player: case ObjectType.Npc: { var character = (Character)victim; if (character.IsHostileTo(caster)) { if ((!character.IsDead() && requiredTargetType.HasFlag(SpellTargetTypes.HostileUnit)) == false && (character.IsDead() && requiredTargetType.HasFlag(SpellTargetTypes.HostileCorpse)) == false) { return(CastResults.InvalidTarget); } } else { if ((!character.IsDead() && requiredTargetType.HasFlag(SpellTargetTypes.FriendlyUnit)) == false && (character.IsDead() && requiredTargetType.HasFlag(SpellTargetTypes.FriendlyCorpse)) == false) { return(CastResults.InvalidTarget); } } } break; default: return(CastResults.InvalidTarget); } if (!caster.HaveVitalPower(this.powerType, this.powerCost)) { return(CastResults.NotEnoughPower); } var sqrDistance = Vector3.SqrDistance(caster.Position, victim.Position); if (sqrDistance <= this.minCastRadius * this.minCastRadius) { return(CastResults.TargetTooClose); } if (sqrDistance > this.maxCastRadius * this.maxCastRadius) { return(CastResults.OutOfRange); } return(CastResults.Ok); }
/// <summary> /// Tries to retrieve an item /// </summary> public bool TryGetItem(MmoGuid guid, out MmoObject mmoObject) { return(objects.TryGetValue(guid.Type, guid.Id, out mmoObject)); }