public ProjectileEffect(ProjectileEffectData data) { _radius = data.Radius; _damage = data.Damage; _particleEffect = data.ParticleEffectName == null ? null : new ParticleEffect(data.ParticleEffectName); _force = data.Force; _statEffects = new StatEffect(data.FireEffect, data.CryoEffect, data.ShockEffect); Duration = TimeSpan.FromSeconds(data.Duration); }
public StatEffect ApplyResist(StatEffect resist) { return new StatEffect(Fire * (1 - resist.Fire / MaxEffect), Cryo * (1 - resist.Cryo / MaxEffect), Shock * (1 - resist.Shock / MaxEffect)); }
public virtual void Update(GameTime gameTime, Rectangle levelBounds) { switch(_lifeState) { case LifeState.Living: case LifeState.Ghost: { if (Panicked) { _panicTimer -= gameTime.ElapsedGameTime; if (_panicTimer <= TimeSpan.Zero) { _panicTimer = TimeSpan.FromSeconds(PANIC_DIRECTION_CHANGE_FREQUENCY); XnaHelper.RandomizeVector(ref _moveDirection, -1, 1, -1, 1); _lookDirection = _moveDirection; } } lookThisWay(LookDirection); if (MoveDirection.Length() > 0) moveThisWay(MoveDirection, gameTime); //handle burning ApplyDamage(_statusEffects.Fire * (float)gameTime.ElapsedGameTime.TotalSeconds * FIRE_DPS); break; } case LifeState.Disabled: case LifeState.Frozen: { if (_statusEffects.Cryo <= 0) { _lifeState = LifeState.Living; //still cold after defrosting _statusEffects.Cryo = MAX_STAT_EFFECT / 2; } break; } case LifeState.Shattered: { for (int y = 0; y < ICE_DIVISIONS; y++) for (int x = 0; x < ICE_DIVISIONS; x++) { _fragments[x, y].Angle += _fragments[x, y].AngularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Position += _fragments[x, y].Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Velocity += _fragments[x, y].Acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Acceleration = Vector2.Zero; _fragments[x, y].Health -= FRAGMENT_MELT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].ScaleFactor = _fragments[x,y].Health / FRAGMENT_HEALTH * FRAGMENT_SCALE_FACTOR; XnaHelper.ClampVector(ref _fragments[x, y].Velocity, FRAGMENT_MAX_VELOCITY, out _fragments[x, y].Velocity); if (_fragments[x, y].BeingEaten) { _fragments[x, y].Health -= FRAGMENT_EAT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds; } } return; } case LifeState.BeingEaten: { _sprite.ScaleFactor -= BLACK_HOLE_EAT_SCALE_FACTOR * (float)gameTime.ElapsedGameTime.TotalSeconds; if (_sprite.ScaleFactor <= 0) _lifeState = LifeState.Destroyed; break; } case LifeState.Destroyed: default: { return; //don't update anything } } stayInBounds(levelBounds.Width, levelBounds.Height); _velocity += _acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; Position += _velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; controlVelocity(_maxSpeed, gameTime.ElapsedGameTime); _sprite.Angle += _angularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds; LookDirection = Vector2.Zero; MoveDirection = Vector2.Zero; _acceleration = Vector2.Zero; if (_movementParticleEffect != null) _movementParticleEffect.Update(gameTime); //burning visual effect _burningParticleEffect.Spawn(Position, 0.0f, gameTime.ElapsedGameTime, _velocity); _burningParticleEffect.IntensityFactor = _statusEffects.Fire / MAX_STAT_EFFECT; _burningParticleEffect.Update(gameTime); //cryo visual effect if (_statusEffects.Cryo > 0 && _lifeState != LifeState.Disabled) { _sprite.Shade = Color.Lerp(Color.White, Color.Blue, _statusEffects.Cryo / MAX_STAT_EFFECT); } _hitRect.X = (int)Position.X - _hitRect.Width / 2; _hitRect.Y = (int)Position.Y - _hitRect.Height / 2; //manage stat effects if (_statusEffects.Cryo >= MAX_STAT_EFFECT && _lifeState != LifeState.Frozen) { _lifeState = LifeState.Frozen; _iceIntegrity = maxHealth * ICE_INTEGRITY_FACTOR; _statusEffects.Fire = 0; //stop burning if frozen } //decrement every stat effect based on status resist _statusEffects -= _statusResist * (float)gameTime.ElapsedGameTime.TotalSeconds; _statusEffects.Clamp(0, MAX_STAT_EFFECT); _sprite.Update(gameTime); }
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 ApplyStatus(StatEffect effects) { _statusEffects += effects; }
/// <summary> /// Create a new physical sprite from data /// </summary> /// <param name="pd">data from which to construct unit</param> protected PhysicalUnit(PhysicalData pd) { _unitName = pd.Name; _sprite = new Sprite(_unitName); if (pd.MovementParticleEffectName != null) _movementParticleEffect = new ParticleEffect(pd.MovementParticleEffectName); _burningParticleEffect = new ParticleEffect("Burning"); _mass = pd.Mass; _moveForce = pd.MoveForce; _maxSpeed = pd.MaxSpeed; _maxHealth = pd.Health; _health = _maxHealth; _decelerationFactor = pd.DecelerationFactor; _lifeState = LifeState.Dormant; //not yet spawned _hitRect = new Rectangle(0, 0, (int)_sprite.Width, (int)_sprite.Height); Position = Vector2.Zero; MoveDirection = Vector2.Zero; LookDirection = Vector2.Zero; _statusEffects = new StatEffect(0, 0, 0); _statusResist = new StatEffect(pd.FireResist, pd.CryoResist, pd.ShockResist); _fragments = new IceFragment[ICE_DIVISIONS, ICE_DIVISIONS]; }
public virtual void Update(GameTime gameTime, Rectangle levelBounds) { switch(_lifeState) { case LifeState.Living: case LifeState.Ghost: { //handle burning ApplyDamage(_statusEffects.Fire * (float)gameTime.ElapsedGameTime.TotalSeconds * FIRE_DPS); break; } case LifeState.Frozen: { if (_statusEffects.Cryo <= 0) { _lifeState = Health > 0 ? LifeState.Living : LifeState.Destroyed; //still cold after defrosting _statusEffects.Cryo = StatEffect.MaxEffect / 2; } break; } case LifeState.Shattered: { bool allDestroyed = true; for (int y = 0; y < c_shatterDivisions; y++) for (int x = 0; x < c_shatterDivisions; x++) { allDestroyed = (_fragments[x, y].Health < 0) && allDestroyed; _fragments[x, y].Angle += _fragments[x, y].AngularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Position += _fragments[x, y].Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Velocity += _fragments[x, y].Acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; _fragments[x, y].Acceleration = Vector2.Zero; if (_freezeShatter) { _fragments[x, y].Health -= FRAGMENT_MELT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds; } _fragments[x, y].ScaleFactor = _fragments[x, y].Health / FRAGMENT_HEALTH * FRAGMENT_SCALE_FACTOR; XnaHelper.ClampVector(ref _fragments[x, y].Velocity, FRAGMENT_MAX_VELOCITY, out _fragments[x, y].Velocity); if (_fragments[x, y].BeingEaten) { _fragments[x, y].Health -= FRAGMENT_EAT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds; } } if (allDestroyed) { _lifeState = LifeState.Destroyed; } return; } case LifeState.BeingEaten: { _sprite.ScaleFactor -= BLACK_HOLE_EAT_SCALE_FACTOR * (float)gameTime.ElapsedGameTime.TotalSeconds; if (_sprite.ScaleFactor <= 0) _lifeState = LifeState.Destroyed; break; } case LifeState.Destroyed: { return; } default: break; //don't update anything } stayInBounds(levelBounds.Width, levelBounds.Height); _velocity += _acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; Position += _velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; controlVelocity(_maxSpeed, gameTime.ElapsedGameTime); _sprite.Angle += _angularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds; _acceleration = Vector2.Zero; //burning visual effect _burningParticleEffect.Spawn(Position, 0.0f, gameTime.ElapsedGameTime, _velocity); _burningParticleEffect.IntensityFactor = _statusEffects.Fire / StatEffect.MaxEffect; _burningParticleEffect.Update(gameTime); //cryo visual effect if (_statusEffects.Cryo > 0 && _lifeState != LifeState.Disabled) { _sprite.Shade = Color.Lerp(Color.White, Color.Blue, _statusEffects.Cryo / StatEffect.MaxEffect); } _hitRect.X = (int)Position.X - _hitRect.Width / 2; _hitRect.Y = (int)Position.Y - _hitRect.Height / 2; //manage stat effects if (_statusEffects.Cryo >= StatEffect.MaxEffect && _lifeState != LifeState.Frozen) { _lifeState = LifeState.Frozen; _iceIntegrity = MaxHealth * ICE_INTEGRITY_FACTOR; _statusEffects.Fire = 0; //stop burning if frozen } //decrement every stat effect based on status resist _statusEffects -= _statusResist * (float)gameTime.ElapsedGameTime.TotalSeconds; _statusEffects.Clamp(0, StatEffect.MaxEffect); _sprite.Update(gameTime); }
public void ApplyStatus(StatEffect effects) { _statusEffects += effects.ApplyResist(_statusResist); }
/// <summary> /// Create a new physical sprite from data /// </summary> /// <param name="pd">data from which to construct unit</param> protected PhysicalBody(PhysicalData pd, Sprite.SpriteType spriteType) { _unitName = pd.Name; if (spriteType == Sprite.SpriteType.Unit) { _sprite = new UnitSprite(pd.Name, (PhysicalUnit)this); } else { _sprite = new Sprite(pd.Name, spriteType); } _burningParticleEffect = new ParticleEffect("Burning"); _mass = pd.Mass; _gravitySensitivity = pd.GravitySensitivity; _moveForce = pd.MoveForce; _maxSpeed = pd.MaxSpeed; _maxHealth = pd.Health; _health = _maxHealth; _decelerationFactor = pd.DecelerationFactor; _lifeState = LifeState.Dormant; //not yet spawned _hitRect = new Rectangle(0, 0, (int)_sprite.Width, (int)_sprite.Height); Position = Vector2.Zero; _statusEffects = new StatEffect(0, 0, 0); _statusResist = new StatEffect(pd.FireResist, pd.CryoResist, pd.ShockResist); _fragments = new IceFragment[c_shatterDivisions, c_shatterDivisions]; }