protected ProjectileWeapon(ProjectileWeaponData data, PhysicalUnit owner) : base(TimeSpan.FromSeconds(1.0 / data.FireRate), owner) { _name = data.Name; _projectilesPerFire = data.ProjectilesPerFire; _projectileInfo = data.ProjectileInfo; _spread = data.Spread; _contactEffect = _projectileInfo.ContactEffect == null ? ProjectileEffect.NullEffect : new ProjectileEffect(_projectileInfo.ContactEffect); _proximityEffect = _projectileInfo.ProximityEffect == null ? ProjectileEffect.NullEffect : new ProjectileEffect(_projectileInfo.ProximityEffect); _destinationEffect = _projectileInfo.DestinationEffect == null ? ProjectileEffect.NullEffect : new ProjectileEffect(_projectileInfo.DestinationEffect); _fireParticleEffect = data.FireParticleEffectName == null ? null : new ParticleEffect(data.FireParticleEffectName); float maxProjLife = data.ProjectileInfo.SecondsToLive + Math.Max((float)_contactEffect.Duration.TotalSeconds, (float)_destinationEffect.Duration.TotalSeconds); float maxProjectiles = data.FireRate * maxProjLife * data.ProjectilesPerFire; maxProjectiles = Math.Max(maxProjectiles, _projectilesPerFire); _projectiles = new Projectile[(int)maxProjectiles + 1]; for (int i = 0; i < _projectiles.Length; i++) { _projectiles[i] = new Projectile(data.ProjectileInfo.SpriteName); } }
/// <summary> /// Apply Gravity on a unit and eat it if close enough /// call on each unit during unit update loop /// </summary> /// <param name="unit">unit to affect. Should be called after updating unit</param> public void ApplyToUnit(PhysicalUnit unit, GameTime gameTime) { float massEaten; if (_state != BlackHoleState.Pulling && _state != BlackHoleState.Overdrive) { return; } if (_state == BlackHoleState.Pulling) { unit.ApplyGravity(Gravity, gameTime); } else if (_state == BlackHoleState.Overdrive) { unit.FlyToPoint(Position, _overdriveTimer, 2.0f); } if ((massEaten = unit.EatByBlackHole(Position, _radius)) > 0) { _capacityUsed += massEaten; _particleEffect.IntensityFactor = 1.0f + _capacityUsed / _totalCapacity; Gravity.MagnitudeFactor = (1.0f + _capacityUsed / _totalCapacity); if (_capacityUsed > _totalCapacity) { goOverdrive(); } } }
public void CheckAndApplyWeaponCollision(PhysicalUnit unit, TimeSpan time) { if (_meleeWeapon != null) { _meleeWeapon.CheckAndApplyCollision(unit, time); } }
/// <summary> /// Create a new weapon /// </summary> /// <param name="fireDelay">Time between successive shots</param> /// <param name="maxAmmo">Total ammo capacity. Set to 1 for infinite ammo.</param> /// <param name="ammoConsumption">Ammo used per shot. Set to 0 for infinite ammo.</param> /// <param name="levelWidth">Width of the level in which this weapon is instantiated.</param> /// <param name="levelHeight">Height of the level in which this weapon is instantiated.</param> public Weapon(TimeSpan fireDelay, int maxAmmo, int ammoConsumption, PhysicalUnit owner) { _fireDelay = fireDelay; _maxAmmo = maxAmmo; _currentAmmo = maxAmmo; _ammoConsumption = ammoConsumption; _owner = owner; }
public HookShot(PhysicalUnit owner) : base(TimeSpan.FromSeconds(FIRE_DELAY), 1, 0, owner) { _hookState = HookState.Idle; _hookSprite = new Sprite("HookClaw"); _chainSprite = new Sprite("HookChain"); _hookHitRect = new Rectangle(0, 0, (int)_hookSprite.Width, (int)_hookSprite.Height); }
public void CheckAndApplyUnitCollision(PhysicalUnit other) { if (!Collides) { return; //don't check collision if unit shouldn't collide } //special shattered collision detection if (_lifeState == LifeState.Shattered) { tempRec.Width = _hitRect.Width / ICE_DIVISIONS; tempRec.Height = _hitRect.Height / ICE_DIVISIONS; for (int i = 0; i < ICE_DIVISIONS; i++) { for (int j = 0; j < ICE_DIVISIONS; j++) { tempRec.X = (int)(_fragments[i, j].Position.X - tempRec.Width / 2); tempRec.Y = (int)(_fragments[i, j].Position.Y - tempRec.Height / 2); if (tempRec.Intersects(other.HitRect)) { Vector2 fVel = _fragments[i, j].Velocity; float fMass = (float)Mass / (ICE_DIVISIONS * ICE_DIVISIONS); temp = other.Velocity; other._velocity = (other._velocity * (other.Mass - fMass) + 2 * fMass * fVel) / (fMass + other.Mass); _fragments[i, j].Velocity = (fVel * (fMass - other.Mass) + 2 * other.Mass * temp) / (fMass + other.Mass); } } } return; //ignore normal collision detection } //check if fire should be transferred float dist = XnaHelper.DistanceBetweenRects(HitRect, other.HitRect); if (dist < FIRE_SPREAD_DISTANCE) { if (_statusEffects.Fire > other._statusEffects.Fire) { StatEffect transfer = new StatEffect() { Fire = FIRE_SPREAD_FACTOR * dist / FIRE_SPREAD_DISTANCE * _statusEffects.Fire }; other.ApplyStatus(transfer); ApplyStatus(transfer * -FIRE_SPREAD_LOSS); } } if (XnaHelper.RectsCollide(HitRect, other.HitRect)) { temp = other._velocity; //temp is a static reusable vector other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) / (this.Mass + other.Mass); this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) / (this.Mass + other.Mass); } }
/// <summary> /// Create a new weapon /// </summary> /// <param name="fireDelay">Time between successive shots</param> /// <param name="maxAmmo">Total ammo capacity. Set to 1 for infinite ammo.</param> /// <param name="ammoConsumption">Ammo used per shot. Set to 0 for infinite ammo.</param> /// <param name="levelWidth">Width of the level in which this weapon is instantiated.</param> /// <param name="levelHeight">Height of the level in which this weapon is instantiated.</param> public Weapon(WeaponData data, PhysicalUnit owner, string spriteName = null) { _fireDelay = TimeSpan.FromSeconds(1.0 / data.FireRate); _owner = owner; if (spriteName != null) { Sprite = new WeaponSprite(spriteName); } }
public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time) { if (!unit.Collides) return; foreach (Projectile p in _projectiles) { p.CheckAndApplyCollision(unit, time); } }
public void CheckCollisions(GameTime gameTime, PhysicalUnit unit) { foreach (IConsumable item in _slots) { if (item is ProjectileWeapon) { (item as ProjectileWeapon).CheckAndApplyCollision(unit, gameTime.ElapsedGameTime); } } }
public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time) { if (_hookState == HookState.Fired || _hookState == HookState.Retracting) { if (XnaHelper.RectsCollide(_hookHitRect, unit.HitRect)) { _hookedUnit = unit; _hookState = HookState.Attached; } } }
protected MeleeWeapon(MeleeWeaponData data, PhysicalUnit owner) : base(data, owner, data.Name) { _damage = data.Damage; _force = data.Impact; _recoil = data.Recoil; _hitArc = data.HitArc; _range = data.Range; _attackParticleEffect = (data.AttackParticleEffect == null) ? null : new ParticleEffect(data.AttackParticleEffect); _hitParticleEffect = (data.HitParticleEffect == null) ? null : new ParticleEffect(data.HitParticleEffect); }
protected MeleeWeapon(MeleeWeaponData data, PhysicalUnit owner) : base(TimeSpan.FromSeconds(1.0 / data.FireRate), owner) { _damage = data.Damage; _force = data.Impact; _recoil = data.Recoil; _hitArc = data.HitArc; _range = data.Range; _attackParticleEffect = (data.AttackParticleEffect == null) ? null : new ParticleEffect(data.AttackParticleEffect); _hitParticleEffect = (data.HitParticleEffect == null) ? null : new ParticleEffect(data.HitParticleEffect); }
public HookShot(PhysicalUnit owner) : base(new WeaponData { Name = "Hookshot", FireRate = c_fireRate, }, owner) { _hookState = HookState.Idle; _hookSprite = new Sprite("HookClaw", SpaceGame.graphics.Sprite.SpriteType.Projectile); _chainSprite = new Sprite("HookChain", SpaceGame.graphics.Sprite.SpriteType.Projectile); _hookHitRect = new Rectangle(0, 0, (int)_hookSprite.Width, (int)_hookSprite.Height); }
public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time) { if (!_firing || !unit.Collides) return; //don't check collisions if not firing float fireAngle = XnaHelper.RadiansFromVector(_fireDirection); if (XnaHelper.RectangleIntersectsArc(unit.HitRect, _owner.Center, _range, fireAngle, _hitArc)) { _tempVector = unit.Center - _owner.Center; _tempVector.Normalize(); unit.ApplyImpact(_force * _tempVector, 1); unit.ApplyDamage(_damage); } }
protected ProjectileWeapon(ProjectileWeaponData data, PhysicalUnit owner) : base(TimeSpan.FromSeconds(1.0 / data.FireRate), data.MaxAmmo, data.AmmoConsumption, owner) { _maxProjectiles = data.MaxProjectiles; _projectiles = new Projectile[_maxProjectiles]; for (int i = 0; i < _maxProjectiles; i++) { _projectiles[i] = new Projectile(); _projectiles[i].ProjectileSprite = new Sprite(data.ProjectileSpriteName); } _projectileDamage = data.Damage; _projectileForce = data.ProjectileForce; _recoilForce = data.Recoil; _projectileSpeed = data.ProjectileSpeed; _projectileAcceleration = data.ProjectileAcceleration; _dissipateOnHit = data.DissipateOnHit; _projectileSpread = MathHelper.ToRadians(data.ProjectileSpread); _projectilesPerFire = data.ProjectilesPerFire; _projectileLife = data.ProjectileLife; _splashDamage = data.SplashDamage; _splashRadius = data.SplashRadius; _splashForce = data.SplashForce; Sprite projectileSprite = _projectiles[0].ProjectileSprite; if (projectileSprite.Width <= _splashRadius * 2) { _splashScaleRate = (projectileSprite.Width / _splashRadius); _splashScaleRate /= (float)projectileSprite.FullAnimationTime.TotalSeconds; } _hitDetectionRect = new Rectangle(0,0, (int)(projectileSprite.Width), (int)projectileSprite.Height); if (data.MovementParticleEffect != null) _movementParticleEffect = new ParticleEffect(data.MovementParticleEffect); if (data.SplashParticleEffect != null) _splashParticleEffect = new ParticleEffect(data.SplashParticleEffect); }
public void CheckAndApplyCollision(PhysicalUnit unit, GameTime gameTime) { switch (_state) { case State.Dormant: break; case State.Appearing: case State.Scanning: unit.ApplyGravity(_gravity, gameTime); break; case State.Charging: unit.ApplyGravity(_gravity, gameTime); if (willCollide(unit.Top, unit.Bottom, unit.Left, unit.Right, gameTime.ElapsedGameTime)) { unit.ApplyImpact(_velocity, IMPACT_IMPULSE); unit.ApplyDamage(IMPACT_DAMAGE); break; } break; } }
protected UnitSprite(UnitSpriteData data, PhysicalUnit unit) : base(data, SpriteType.Unit) { _unit = unit; if (_numStates % 2 == 0) { throw new Exception(String.Format("UnitSprite {0} has an even number of states along the horizontal axis", data.Name)); } //shoulder positioning _unitShoulderOffset = new Vector2(data.ShoulderX, data.ShoulderY); _flippedUnitShoulderOffset = new Vector2(-data.ShoulderX, data.ShoulderY); _armTexture = Content.Load<Texture2D>(c_armSpritePath + data.SpriteArmData.Name); //hand/weapon positioning _armShoulderPos = new Vector2(data.SpriteArmData.ShoulderX, data.SpriteArmData.ShoulderY); _shoulderToHand = new Vector2(data.SpriteArmData.HandX, data.SpriteArmData.HandY); //leg positioning _legTexture = Content.Load<Texture2D>(c_legSpritePath + data.SpriteLegData.Name); _unitHipOffset = new Vector2(data.HipX, data.HipY); _flippedUnitHipOffset = new Vector2(-data.HipX, data.HipY); _legOrigin = new Vector2(data.SpriteLegData.HipX, data.SpriteLegData.HipY); _flippedLegOrigin = new Vector2(_legTexture.Width - data.SpriteLegData.HipX, data.SpriteLegData.HipY); _exhaustOffset = new Vector2(data.ExhaustX, data.ExhaustY); }
public void CheckAndApplyUnitCollision(PhysicalUnit other) { if (!Collides) return; //don't check collision if unit shouldn't collide //special shattered collision detection if (_lifeState == LifeState.Shattered) { tempRec.Width = _hitRect.Width / ICE_DIVISIONS; tempRec.Height = _hitRect.Height / ICE_DIVISIONS; for (int i = 0; i < ICE_DIVISIONS ; i++) for (int j = 0; j < ICE_DIVISIONS; j++) { tempRec.X = (int)(_fragments[i,j].Position.X - tempRec.Width / 2); tempRec.Y = (int)(_fragments[i,j].Position.Y - tempRec.Height / 2); if (tempRec.Intersects(other.HitRect)) { Vector2 fVel = _fragments[i, j].Velocity; float fMass = (float)Mass / (ICE_DIVISIONS * ICE_DIVISIONS); temp = other.Velocity; other._velocity = (other._velocity * (other.Mass - fMass) + 2 * fMass * fVel) / (fMass + other.Mass); _fragments[i,j].Velocity = (fVel * (fMass - other.Mass) + 2 * other.Mass * temp) / (fMass + other.Mass); } } return; //ignore normal collision detection } //check if fire should be transferred float dist = XnaHelper.DistanceBetweenRects(HitRect, other.HitRect); if (dist < FIRE_SPREAD_DISTANCE) { if (_statusEffects.Fire > other._statusEffects.Fire) { StatEffect transfer = new StatEffect() { Fire = FIRE_SPREAD_FACTOR * dist / FIRE_SPREAD_DISTANCE * _statusEffects.Fire }; other.ApplyStatus(transfer); ApplyStatus(transfer * -FIRE_SPREAD_LOSS); } } if (XnaHelper.RectsCollide(HitRect, other.HitRect)) { temp = other._velocity; //temp is a static reusable vector other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) / (this.Mass + other.Mass); this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) / (this.Mass + other.Mass); } }
public void CheckAndApplyUnitCollision(PhysicalUnit other) { if (!Collides) return; //don't check collision if unit shouldn't collide if (XnaHelper.RectsCollide(HitRect, other.HitRect)) { temp = other._velocity; //temp is a static reusable vector other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) / (this.Mass + other.Mass); this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) / (this.Mass + other.Mass); } }
public void CheckAndApplyWeaponCollision(PhysicalUnit unit, TimeSpan time) { if (CurrentWeapon != null) CurrentWeapon.CheckAndApplyCollision(unit, time); }
public MeleeWeapon(string weaponName, PhysicalUnit owner) : this(DataManager.GetData<MeleeWeaponData>(weaponName), owner) { }
public ProjectileWeapon(string weaponName, PhysicalUnit owner) : this(ProjectileWeaponData[weaponName], owner) { }
public ThrowableWeapon(string name, PhysicalUnit owner) : base(DataDict[name], owner) { _maxAmmo = DataDict[name].UsesPerStack; NumUses = _maxAmmo; }
/// <summary> /// Check if weapon is hitting a target, and apply its affects if so /// Call during the update loop on each unit /// </summary> /// <param name="unit"></param> public abstract void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time);
public ProjectileWeapon(string name, PhysicalUnit owner) : this(DataDict[name], owner) { }
public ThrowableWeapon(string name, PhysicalUnit owner) : base(DataManager.GetData<ThrowableWeaponData>(name), owner, null) { _maxAmmo = DataManager.GetData<ThrowableWeaponData>(name).UsesPerStack; NumUses = _maxAmmo; }
/// <summary> /// Check if target unit is in range. If so, apply force and damage /// </summary> /// <param name="effectPos">origin of effect</param> /// <param name="target">target unit</param> public void TryApply(Vector2 effectPos, PhysicalUnit target, TimeSpan time) { if (utility.XnaHelper.RectangleIntersectsCircle(target.HitRect, effectPos, _radius)) { tempVec.X = target.Position.X - effectPos.X; tempVec.Y = target.Position.Y - effectPos.Y; Vector2.Normalize(tempVec); float factor = Duration == TimeSpan.Zero ? 1 : (float)time.TotalSeconds / (float)Duration.TotalSeconds; target.ApplyForce(_force * factor * tempVec); target.ApplyDamage((_damage * factor)); target.ApplyStatus(_statEffects); } }
Vector2 _weaponOrigin; //weapon vectors #endregion Fields #region Constructors public UnitSprite(string name, PhysicalUnit unit) : this(DataManager.GetData<UnitSpriteData>(name), unit) { }
public void CheckAndApplyCollision(PhysicalUnit u, TimeSpan time) { if (!u.Collides) return; switch (_state) { case State.Dormant: break; case State.Moving: if (u.HitRect.Intersects(_hitRect)) { if (_penetration != -1) { _penetration -= 1; if (_penetration <= 0) _state = State.JustHit; } u.ApplyImpact(_velocity, _mass); } _proximityEffect.TryApply(_position, u, time); break; case State.JustHit: break; case State.ApplyContactEffect: _contactEffect.TryApply(_position, u, time); break; case State.ReachedDestination: _destinationEffect.TryApply(_position, u, time); break; default: break; } }
public MeleeWeapon(string weaponName, PhysicalUnit owner) : this(MeleeWeaponDataDict[weaponName], owner) { }
/// <summary> /// Check if weapon is hitting a target, and apply its affects if so /// Call during the update loop on each unit /// </summary> /// <param name="unit"></param> public abstract void CheckAndApplyCollision(PhysicalUnit unit);
protected virtual void applyProjectileHit(Projectile p, PhysicalUnit unit) { unit.ApplyForce(p.Velocity / p.Velocity.Length() * _projectileForce); unit.ApplyDamage(_projectileDamage); if (_dissipateOnHit) p.Active = false; if (_splashRadius > 0) { p.ReadyToSplash = true; p.Velocity = Vector2.Zero; p.ProjectileSprite.PlayAnimation(1); } }
/// <summary> /// Apply Gravity on a unit and eat it if close enough /// call on each unit during unit update loop /// </summary> /// <param name="unit">unit to affect. Should be called after updating unit</param> public void ApplyToUnit(PhysicalUnit unit, GameTime gameTime) { float massEaten; if (_state != BlackHoleState.Pulling && _state != BlackHoleState.Overdrive) return; if (_state == BlackHoleState.Pulling) { unit.ApplyGravity(Gravity, gameTime); } else if (_state == BlackHoleState.Overdrive) { unit.FlyToPoint(Position, _overdriveTimer, 2.0f); } if ((massEaten = unit.EatByBlackHole(Position, _radius)) > 0) { _capacityUsed += massEaten; _particleEffect.IntensityFactor = 1.0f + _capacityUsed / _totalCapacity; Gravity.MagnitudeFactor = (1.0f + _capacityUsed / _totalCapacity); if (_capacityUsed > _totalCapacity) { goOverdrive(); } } }