/// <summary> /// Constructor. /// </summary> /// <param name="unit"></param> /// <param name="direction"></param> /// <param name="linkedAnimProcess"></param> /// <param name="delay"></param> public MovementProcess(Unit unit, CompassDirection direction, AnimProcess linkedAnimProcess, Isometry iso, float delay = .015f) : base() { _unit = unit; _direction = direction; _linkedAnimProcess = linkedAnimProcess; _speed = delay; _iso = iso; }
public void AddModifierObstacle(Modifier mod, Unit unit) { var position = unit.Position; modifierAdded = true; AbilityDrawer.Dispose(AbilityDrawer.Type.Rectangle); AbilityDrawer.DrawCircle(position, GetRadius()); if (Obstacle == null) { StartCast = Game.RawGameTime; EndCast = StartCast + GetDuration(); fowCast = true; } Obstacle = Pathfinder.AddObstacle(position, GetRadius(), Obstacle); }
public void Init(Game game) { Tiles=new List<Tile> { new Tile(game.Content, "Images\\Tiles\\Land", true), new Tile(game.Content, "Images\\Tiles\\Water",false), new Tile(game.Content, "Images\\Tiles\\Brick",true) }; UnitTypes = new List<UnitType> { new UnitType { Name = "Воин", Code = "WARRIOR", MaxHealth = 100, Sizes = new Vector2(50f,100f), Offset = new Vector2(25f,100f), Speed = 50f, FacesNum = 4, Standing = game.Content.Load<Texture2D>("Images\\Units\\Warrior\\Standing") }, new UnitType { Name = "Дерево", Code = "TREE", MaxHealth = 1000, Sizes = new Vector2(680f,601f), Offset = new Vector2(340f,601f), Speed = 0f, FacesNum = 1, Standing = game.Content.Load<Texture2D>("Images\\Units\\Tree\\Standing") } }; foreach (Unit unit in Units) { unit.Map = this; } Player = Units[0]; SpriteBatch=new SpriteBatch(game.GraphicsDevice); Game = game; }
/// <summary> /// Returns the sprite for the given unit. /// </summary> /// <param name="unit"></param> /// <returns></returns> private ZSprite GetSprite(Unit unit) { if (unit.Sprite != null) return unit.Sprite; // Lazy load unit.Body = BodyType.LeatherMale; unit.Weapon = WeaponType.SMG; unit.Facing = CompassDirection.East; ZSprite sprite = new ZSprite(_game.GraphicsDevice, "D:\\workspace\\BaseGame\\sprites\\characters\\" + Enum.GetName(typeof(BodyType), unit.Body) + ".spr"); sprite._baseSprite.ReadAnimation(sprite.Sequences["StandBreathe"].AnimCollection); sprite.CurrentSequence = "StandBreathe"; unit.Sprite = sprite; ClientGame._processManager.ProcessList.Add(new AnimProcess(unit, AnimAction.Breathe, true)); // Test some anims! //var anim = new AnimatedMoveProcess(unit, _iso, CompassDirection.NorthWest, CompassDirection.NorthWest, CompassDirection.North); //var wait = new WaitProcess(1000); //anim.Next = wait; //var anim2 = new AnimatedMoveProcess(unit, _iso, CompassDirection.East, CompassDirection.East, CompassDirection.East, CompassDirection.East, CompassDirection.SouthEast, CompassDirection.SouthEast, CompassDirection.SouthEast, CompassDirection.SouthEast); //wait.Next = anim2; //ClientGame._processManager.ProcessList.Add(anim); return sprite; }
/// <summary> /// /// </summary> /// <param name="input"></param> private void HandleInput(InputState input) { // LMB Mouse clicks if (input.CurrentMouseState.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed && input.LastMouseState.LeftButton != Microsoft.Xna.Framework.Input.ButtonState.Pressed) { // Check for click on unit foreach (Unit u in _module.Roster) { if (GetSprite(u).HitTest(input.CurrentMouseState.X, input.CurrentMouseState.Y)) { if (u.OwnerID == _game.PlayerID) { // Own unit - select SelectedUnit = u; } else { // Enemy unit - Handle attack order } return; } } // Check for move order if (SelectedUnit != null && characterAvailable) { var destination = _iso.MouseMapper(new System.Drawing.Point( input.CurrentMouseState.X + _screenAnchor.X, input.CurrentMouseState.Y + _screenAnchor.Y)); // Check destination is valid if (_module.Map.IsOnGrid(destination) && _module.Map.Cells[destination.X, destination.Y].IsWalkable() && destination != new System.Drawing.Point(SelectedUnit.X, SelectedUnit.Y)) { // Get the path if one exists Path<MapCell> path = AStar.FindPath<MapCell> (_module.Map.Cells[SelectedUnit.X, SelectedUnit.Y], _module.Map.Cells[destination.X, destination.Y], MapCell.Distance, MapCell.DiagonalHeuristic); if (path == null) return; // Do it MapCell prev = null; List<CompassDirection> dirs = new List<CompassDirection>(); foreach (MapCell cell in path.Reverse()) { if (prev != null) { dirs.Add(_iso.DirectionOfNeighbour(prev.MapCoordinate, cell.MapCoordinate)); } prev = cell; } AnimatedMoveProcess proc = new AnimatedMoveProcess(SelectedUnit, _iso, dirs.ToArray()); ClientGame._processManager.ProcessList.Add(proc); } } } }
/// <summary> /// Reads a Unit from the given stream. /// </summary> /// <param name="stream"></param> /// <returns></returns> public static Unit ReadUnit(TextReader stream) { var unit = new Unit(0, BodyType.MetalMale, WeaponType.Rifle, Stance.Stand, 1, 1, 1, 1, 1, 1, 1, "Biff"); if (stream == null) return unit; stream.ReadLine(); // <Unit> unit.OwnerID = byte.Parse(stream.ReadLine()); unit.Body = (BodyType)Enum.Parse(typeof(BodyType), stream.ReadLine()); unit.Weapon = (WeaponType)Enum.Parse(typeof(WeaponType), stream.ReadLine()); unit.Stance = (Stance)Enum.Parse(typeof(Stance), stream.ReadLine()); unit.Facing = (CompassDirection)Enum.Parse(typeof(CompassDirection), stream.ReadLine()); unit.InitialHitPoints = byte.Parse(stream.ReadLine()); unit.CurrentHitPoints = byte.Parse(stream.ReadLine()); unit.InitialActionPoints = byte.Parse(stream.ReadLine()); unit.CurrentActionPoints = byte.Parse(stream.ReadLine()); unit.Expertise = byte.Parse(stream.ReadLine()); unit.X = short.Parse(stream.ReadLine()); unit.Y = short.Parse(stream.ReadLine()); unit.Name = stream.ReadLine(); string s; while ((s = stream.ReadLine()) != "</Unit>") { unit.Effects.Add((StatusEffect)Enum.Parse(typeof(StatusEffect), s)); }// </Unit> return unit; }
private void SelectImplicitTargets() { // select explicit potentially redirected target SelectRedirectedTargets(); // also select targets based on spell effects int processedAreaEffectsMask = 0; for (var effectIndex = 0; effectIndex < SpellInfo.Effects.Count; effectIndex++) { if (processedAreaEffectsMask.HasBit(effectIndex)) { continue; } SpellEffectInfo effect = SpellInfo.Effects[effectIndex]; // avoid recalculating similar effects int effectMask = 1 << effectIndex; for (int otherEffectIndex = 0; otherEffectIndex < SpellInfo.Effects.Count; otherEffectIndex++) { if (effect.Targeting == SpellInfo.Effects[otherEffectIndex].Targeting) { effectMask |= 1 << otherEffectIndex; } } processedAreaEffectsMask |= effectMask; effect.Targeting.SelectTargets(this, effectMask); } void SelectRedirectedTargets() { Unit target = ExplicitTargets.Target; if (target == null) { return; } if (SpellInfo.ExplicitCastTargets.HasAnyFlag(SpellCastTargetFlags.UnitEnemy) && Caster.IsHostileTo(target)) { Unit redirectTarget; switch (SpellInfo.DamageClass) { case SpellDamageClass.Magic: redirectTarget = Caster.Spells.GetMagicHitRedirectTarget(target, SpellInfo); break; case SpellDamageClass.Melee: case SpellDamageClass.Ranged: redirectTarget = Caster.Spells.GetMeleeHitRedirectTarget(target, SpellInfo); break; default: redirectTarget = null; break; } if (redirectTarget != null && redirectTarget != target) { ExplicitTargets.Target = redirectTarget; } } } }
private void ProcessTarget(SpellTargetEntry targetEntry) { if (targetEntry.Processed) { return; } targetEntry.Processed = true; if (targetEntry.Target.IsAlive != targetEntry.Alive) { return; } Unit caster = OriginalCaster ?? Caster; if (caster == null) { return; } SpellMissType missType = targetEntry.MissCondition; EffectDamage = 0; EffectHealing = 0; Unit hitTarget = targetEntry.Target; if (missType == SpellMissType.Reflect && targetEntry.ReflectResult == SpellMissType.None) { hitTarget = Caster; } missType = ProcessSpellHit(targetEntry); if (missType != SpellMissType.None) { EffectDamage = 0; } EventHandler.ExecuteEvent(EventHandler.GlobalDispatcher, GameEvents.ServerSpellHit, Caster, hitTarget, SpellInfo, missType); Caster.Spells.ApplySpellTriggers(SpellTriggerFlags.DoneSpellHit, hitTarget, this); if (EffectHealing > 0) { caster.Spells.HealBySpell(new SpellHealInfo(caster, targetEntry.Target, SpellInfo, (uint)EffectHealing, targetEntry.Crit)); } else if (EffectDamage > 0) { caster.Spells.DamageBySpell(new SpellDamageInfo(caster, targetEntry.Target, SpellInfo, (uint)EffectDamage, targetEntry.Crit, SpellDamageType.Direct), this); } if (missType == SpellMissType.None) { for (int effectIndex = 0; effectIndex < SpellInfo.Effects.Count; effectIndex++) { if (targetEntry.EffectMask.HasBit(effectIndex)) { SpellInfo.Effects[effectIndex].Handle(this, effectIndex, hitTarget, SpellEffectHandleMode.HitFinal); } } } if (missType != SpellMissType.Evade && !caster.IsFriendlyTo(hitTarget) && !SpellInfo.IsPositive) { caster.Combat.StartCombatWith(hitTarget); } }
private SpellCastResult ValidateRange() { if (spellValue.CastFlags.HasTargetFlag(SpellCastFlags.IgnoreRangeCheck)) { return(SpellCastResult.Success); } switch (SpellInfo.ExplicitTargetType) { case SpellExplicitTargetType.None: return(SpellCastResult.Success); case SpellExplicitTargetType.Caster: return(SpellCastResult.Success); case SpellExplicitTargetType.Target: return(ValidateTargetRange()); case SpellExplicitTargetType.Destination: return(ValidateDestinationRange()); default: throw new ArgumentOutOfRangeException(); } SpellCastResult ValidateTargetRange() { if (ExplicitTargets.Target == null || ExplicitTargets.Target == Caster) { return(SpellCastResult.Success); } Unit target = ExplicitTargets.Target; float minRange = 0.0f; float maxRange = 0.0f; float rangeMod = 0.0f; if (SpellInfo.RangedFlags.HasTargetFlag(SpellRangeFlags.Melee)) { rangeMod = StatUtils.NominalMeleeRange; } else { float meleeRange = 0.0f; if (SpellInfo.RangedFlags.HasTargetFlag(SpellRangeFlags.Ranged)) { meleeRange = StatUtils.MinMeleeReach; } minRange = Caster.Spells.GetSpellMinRangeForTarget(target, SpellInfo) + meleeRange; maxRange = Caster.Spells.GetSpellMaxRangeForTarget(target, SpellInfo); } maxRange += rangeMod; if (!Caster.IsWithinDistance(target, maxRange, true)) { return(SpellCastResult.OutOfRange); } if (minRange > 0.0f && Caster.IsWithinDistance(target, minRange, true)) { return(SpellCastResult.OutOfRange); } return(SpellCastResult.Success); } SpellCastResult ValidateDestinationRange() { if (!ExplicitTargets.Destination.HasValue) { return(SpellCastResult.BadTargets); } Vector3 targetPosition = ExplicitTargets.Destination.Value; float minRange = SpellInfo.GetMinRange(false); float maxRange = SpellInfo.GetMaxRange(false); if (Caster.ExactDistanceTo(targetPosition) > maxRange) { return(SpellCastResult.OutOfRange); } if (minRange > 0.0f && Caster.ExactDistanceTo(targetPosition) < minRange) { return(SpellCastResult.OutOfRange); } return(SpellCastResult.Success); } }
internal void HandleUnappliedModifers(Unit unit, SpellModifierType modifierType, SpellModifierApplicationType applicationType, ref float value) { switch (applicationType) { case SpellModifierApplicationType.Flat: for (int i = unappliedModifiers.Count - 1; i >= 0; i--) { if (unappliedModifiers[i].Kind != (modifierType, applicationType)) { continue; } if (!unit.Spells.IsAffectedBySpellModifier(this, unappliedModifiers[i])) { continue; } value += unappliedModifiers[i].Value; appliedModifiers.Add(unappliedModifiers[i]); unappliedModifiers.RemoveAt(i); } break; case SpellModifierApplicationType.Percent: for (int i = unappliedModifiers.Count - 1; i >= 0; i--) { if (unappliedModifiers[i].Kind != (modifierType, applicationType)) { continue; } if (!unit.Spells.IsAffectedBySpellModifier(this, unappliedModifiers[i])) { continue; } value *= 1.0f + 1.0f.ApplyPercentage(unappliedModifiers[i].Value); appliedModifiers.Add(unappliedModifiers[i]); unappliedModifiers.RemoveAt(i); } break; case SpellModifierApplicationType.SpellValue: for (int i = unappliedModifiers.Count - 1; i >= 0; i--) { if (unappliedModifiers[i].Kind != (modifierType, applicationType)) { continue; } if (!unit.Spells.IsAffectedBySpellModifier(this, unappliedModifiers[i])) { continue; } if (unappliedModifiers[i].AuraModifier.SpellValueModifier != null) { ApplySpellValueModifier(unappliedModifiers[i].AuraModifier.SpellValueModifier); } appliedModifiers.Add(unappliedModifiers[i]); unappliedModifiers.RemoveAt(i); } break; default: throw new ArgumentOutOfRangeException(nameof(applicationType), applicationType, null); } }
/// <summary> /// Constructor. /// </summary> /// <param name="unit"></param> /// <param name="iso"></param> /// <param name="path"></param> public AnimatedMoveProcess(Unit unit, Isometry iso, params CompassDirection[] path) { this.unit = unit; this.iso = iso; this.path = path; }