private void IceSpikeCollisionHandler(SimulationTime simTime, Contact contact) { Entity iceSpike = contact.EntityA; Entity other = contact.EntityB; // ignore collision with island player is standing on during warmup phase if (simTime.At < createdAt + constants.GetInt("ice_spike_rising_time") && shootingPlayer.HasAttribute("active_island") && other.Name == shootingPlayer.GetString("active_island")) { return; } // remove spike if (other != shootingPlayer && // dont collide with shooter !other.HasAttribute("dynamic") // don't collide with moving other spikes, explosions, etc. ) // don't collide with other explosions { if (other.GetString(CommonNames.Kind) == "player") { IceSpikePlayerCollisionHandler(simTime, iceSpike, other); } SetDead(iceSpike, simTime); } }
public void Update(SimulationTime simTime) { if (OnUpdate != null) { OnUpdate(this, simTime); } }
private void SetDead(Entity iceSpike, SimulationTime simTime) { iceSpike.SetBool(CommonNames.Dead, true); iceSpike.GetProperty <CollisionProperty>("collision").OnContact -= IceSpikeCollisionHandler; // make boom Game.Instance.AudioPlayer.Play(Game.Instance.Simulation.SoundRegistry.IceSpikeExplosionOnEnvironment); // add explosion Entity iceSpikeExplosion = new Entity(iceSpike.Name + "_explosion"); iceSpikeExplosion.AddStringAttribute("player", iceSpike.GetString("player")); // only do damage when in targeting mode if (state == IceSpikeState.Targeting) { iceSpikeExplosion.AddFloatAttribute("damage", constants.GetFloat("ice_spike_damage")); iceSpikeExplosion.AddIntAttribute("freeze_time", constants.GetInt("ice_spike_freeze_time")); } iceSpikeExplosion.AddVector3Attribute(CommonNames.Position, iceSpike.GetVector3(CommonNames.Position)); Game.Instance.Simulation.EntityManager.AddDeferred(iceSpikeExplosion, "ice_spike_explosion_base", templates); explodedAt = simTime.At; state = IceSpikeState.Exploded; }
private void OnUpdate(Entity entity, SimulationTime simTime) { if (entity.GetFloat(CommonNames.Health) <= 0) { Game.Instance.Simulation.EntityManager.RemoveDeferred(entity); return; } }
private void FlamethrowerCollisionHandler(SimulationTime simTime, Contact contact) { Entity other = contact.EntityB; if (other.HasProperty("burnable") && other != player) // don't burn self { other.SetFloat("burnt_at", simTime.At); } }
protected override void OnUpdate(Entity player, SimulationTime simTime) { // stop vibration if (simTime.At > player.GetFloat("vibrateStartetAt") + 330) // todo: extract constant { ResetVibration(); } OnPlaying(player, simTime); CheckPlayerAttributeRanges(player); }
protected virtual void CheckScheduledEvents(Entity entity, SimulationTime simTime) { for (int i = timeouts.Count - 1; i >= 0; --i) { Timeout timeout = timeouts[i]; if (timeout.timeoutAt <= simTime.At) { timeout.handler.Invoke(entity, simTime); timeouts.RemoveAt(i); } } }
private void OnUpdate(Entity explosion, SimulationTime simTime) { if (hadCollision) { explosion.GetProperty <CollisionProperty>("collision").OnContact -= ExplosionCollisionHandler; } if (simTime.At > liveTo) { Game.Instance.Simulation.EntityManager.RemoveDeferred(explosion); } }
private void OnUpdate(Entity powerupEntity, SimulationTime simTime) { if (island != null) { // take position centers Vector3 playerPos = player.GetVector3(CommonNames.Position) + Vector3.UnitY * player.GetVector3(CommonNames.Scale).Y / 2; Vector3 islandPos = island.GetVector3(CommonNames.Position) + Vector3.UnitY * island.GetVector3(CommonNames.Scale).Y / 2; Vector3 aimVector = islandPos - playerPos; if (aimVector != Vector3.Zero) { aimVector.Normalize(); } // also adapt playerpos with radius away playerPos += aimVector * (player.GetVector3(CommonNames.Scale)).Length(); // get intersection Ray3 ray = new Ray3(playerPos, aimVector); Vector3 surfacePos; if (Game.Instance.Simulation.CollisionManager.GetIntersectionPoint(ref ray, island, out surfacePos)) { Vector3 delta = (surfacePos - playerPos) * relPos; arrow.SetVector3(CommonNames.Position, playerPos + delta); } // rotate arrow from player -> island Vector3 tminusp = -aimVector; Vector3 ominusp = Vector3.Up; if (tminusp != Vector3.Zero) { tminusp.Normalize(); } float theta = (float)System.Math.Acos(Vector3.Dot(tminusp, ominusp)); Vector3 cross = Vector3.Cross(ominusp, tminusp); if (cross != Vector3.Zero) { cross.Normalize(); } Quaternion targetQ = Quaternion.CreateFromAxisAngle(cross, theta); arrow.SetQuaternion(CommonNames.Rotation, targetQ); relPos += simTime.Dt * constants.GetFloat("arrows_per_second"); if (relPos > constants.GetFloat("arrow_island_max_distance_factor")) { relPos = constants.GetFloat("arrow_island_min_distance_factor"); } } }
private void OnUpdate(Entity entity, SimulationTime simTime) { float burntAt = entity.GetFloat("burnt_at"); if (simTime.At < burntAt + entity.GetInt("burn_time")) { entity.SetFloat(CommonNames.Health, entity.GetFloat(CommonNames.Health) - simTime.Dt * constants.GetFloat("flamethrower_damage_per_second")); if (entity.GetString(CommonNames.Kind) == "player") { entity.SetInt(CommonNames.Frozen, 0); entity.GetProperty <PlayerControllerProperty>("controller").CheckPlayerAttributeRanges(entity); } } }
private void PerformSpawnMovement(Entity player, SimulationTime simTime) { if (landedAt > -1) { if (simTime.At > landedAt + ((respawn)?1500:2500)) // extract constant { player.SetBool("ready", true); ready = true; } else if (simTime.At > landedAt + 1000 && spawnLight != null && spawnLight.GetBool(CommonNames.Hide) == false) // todo: extract constant { spawnLight.SetBool(CommonNames.Hide, true); } } Vector3 velocity = -Vector3.UnitY * constants.GetFloat("max_gravity_speed"); Vector3 position = player.GetVector3(CommonNames.Position) + velocity * simTime.Dt; Vector3 surfacePos; if (Simulation.GetPositionOnSurface(ref position, destinationIsland, out surfacePos)) { if (position.Y < surfacePos.Y || player.GetBool("abortRespawning")) { position = surfacePos; if (landedAt == -1) { player.GetProperty <RobotRenderProperty>("render").NextOnceState = "jump_end"; destinationIsland.GetProperty <IslandRenderProperty>("render").Squash(); landedAt = simTime.At; } } } else { Debug.WriteLine("island's gone :("); position = GetLandingPosition(destinationIsland); } player.SetVector3(CommonNames.Position, position); }
private void OnUpdate(Entity entity, SimulationTime simTime) { #region update view matrix // preconditions Debug.Assert(entity.HasAttribute(CommonNames.Position)); Debug.Assert(entity.HasAttribute("target")); Debug.Assert(entity.HasAttribute("up")); Vector3 movingPosition = entity.GetVector3(CommonNames.Position) + //entity.GetVector3("up") * (float)Math.Sin(simTime.At * 0.002f) * 10.0f; entity.GetVector3("up") * (float)Math.Sin(1 * 0.002f) * 10.0f; // compute matrix view = Matrix.CreateLookAt( movingPosition, entity.GetVector3("target"), entity.GetVector3("up") ); #endregion #region update projection matrix // preconditions Debug.Assert(entity.HasAttribute("fov")); Debug.Assert(entity.HasAttribute("near_clip")); Debug.Assert(entity.HasAttribute("far_clip")); // get aspect ratio Viewport viewport = Game.Instance.GraphicsDevice.Viewport; float aspectRatio = (float)viewport.Width / (float)viewport.Height; // compute matrix projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(entity.GetFloat("fov")), aspectRatio, entity.GetFloat("near_clip"), entity.GetFloat("far_clip") ); entity.SetMatrix("view", view); entity.SetMatrix("projection", projection); #endregion }
protected override void OnUpdate(Entity player, SimulationTime simTime) { if (ready && landedAt > -1) { if (Game.Instance.Simulation.Phase != SimulationPhase.Intro) { SetActiveIsland(destinationIsland); Deactivate(); } return; } PerformSpawnMovement(player, simTime); if (controllerInput.jumpButtonPressed) { player.SetBool("abortRespawning", true); } }
protected override bool HandleCollision(SimulationTime simTime, Entity island, Entity other, Contact co, ref Vector3 normal) { // change dir if (other.HasAttribute(CommonNames.Kind) && other.GetString(CommonNames.Kind) != "island" && // we don't change direction for other islands other.GetString(CommonNames.Kind) != "player" && // or players simTime.At > dirChangedAt + 1000) // todo: extract constant { dir = -dir; dirChangedAt = simTime.At; // collision handled return(true); } else { return(false); } }
private void OnUpdate(Entity powerup, SimulationTime simTime) { if (powerUsed && respawnAt == 0) { powerup.GetProperty <CollisionProperty>("collision").OnContact -= PowerupCollisionHandler; powerup.RemoveProperty("collision"); powerup.RemoveProperty("render"); powerup.RemoveProperty("shadow_cast"); island.GetVector3Attribute(CommonNames.Position).ValueChanged -= OnIslandPositionChanged; respawnAt = (float)(simTime.At + rand.NextDouble() * powerup.GetFloat("respawn_random_time") + powerup.GetFloat("respawn_min_time")); } else if (powerUsed && simTime.At > respawnAt) { if (!powerup.GetBool("fixed")) { if (!SelectNewIsland()) { // if we cannot find a suitable island: wait return; } } else { Vector3 pos = island.GetVector3(CommonNames.Position); PositionOnIsland(ref pos); } powerup.AddProperty("collision", new CollisionProperty(), true); powerup.AddProperty("render", new PowerupRenderProperty(), true); //powerup.AddProperty("shadow_cast", new ShadowCastProperty()); this.island.GetVector3Attribute(CommonNames.Position).ValueChanged += OnIslandPositionChanged; powerup.GetProperty <CollisionProperty>("collision").OnContact += PowerupCollisionHandler; respawnAt = 0; powerUsed = false; } }
private void ExplosionCollisionHandler(SimulationTime simTime, Contact contact) { Entity explosion = contact.EntityA; Entity other = contact.EntityB; if (other.HasAttribute(CommonNames.Kind) && other.GetString(CommonNames.Kind) == "player") { // apply damage to player if (explosion.HasAttribute("damage")) { other.SetFloat(CommonNames.Health, other.GetFloat(CommonNames.Health) - explosion.GetFloat("damage")); } if (explosion.HasAttribute("freeze_time")) { other.SetInt(CommonNames.Frozen, explosion.GetInt("freeze_time")); } other.GetProperty <PlayerControllerProperty>("controller").CheckPlayerAttributeRanges(other); } hadCollision = true; }
protected override bool HandleCollision(SimulationTime simTime, Entity island, Entity other, Contact co, ref Vector3 normal) { if (simTime.At > directionChangedAt + 1000) { if (other.HasAttribute(CommonNames.Kind) && other.GetString(CommonNames.Kind) != "island" && // we don't change direction for other islands other.GetString(CommonNames.Kind) != "player") // or players { direction = -direction; directionChangedAt = simTime.At; return(true); } else { return(false); // handle collision at base } } else { return(false); // no collision reaction right now } }
public void Update(SimulationTime simTime) { Random rand = new Random(); if (simTime.At < iceSpikeShotAt + 2000 + rand.Next(500)) { iceSpikeButtonPressed = true; iceSpikeShotAt = simTime.At; } if (simTime.At < flameThrowerActivatedAt + 200 + rand.Next(100)) { flamethrowerButtonHold = true; flameThrowerActivatedAt = simTime.At; } if (simTime.At < jumpButtonPressedAt + 1000 + rand.Next(1000)) { jumpButtonPressed = true; jumpButtonPressedAt = simTime.At; } moveStickMoved = true; leftStickX = (float)rand.NextDouble(); leftStickY = (float)rand.NextDouble(); }
public RendererUpdateQueue Initialize( WrappedContentManager wrappedContent, string simulationLevel, string rendererLevel, double startTime ) { try { simTime = new SimulationTime(startTime); StartOperation(); // needs a valid simTime! paused = false; currentUpdateQueue.AddUpdate(new Renderer.Renderer.ChangeLevelUpdate(rendererLevel)); SetPhase(SimulationPhase.Intro, "", null); // load level data levelData = wrappedContent.Load <LevelData>(simulationLevel); entityManager.Load(levelData); soundRegistry.Load(); LevelLoaded(); // start to play sounds MusicSettingsLoaded(); Game.Instance.AudioPlayer.Play(soundRegistry.CaveBackgroundLoop, true); Game.Instance.AudioPlayer.Play(soundRegistry.LavaBackgroundLoop, true); return(EndOperation()); } finally { currentUpdateQueue = null; } }
private void PowerupCollisionHandler(SimulationTime simTime, Contact contact) { Entity other = contact.EntityB; if (other.HasAttribute(CommonNames.Kind) && "player".Equals(other.GetString(CommonNames.Kind)) && !powerUsed) { // use the power GivePower(other); // notify hud if (other.HasProperty("hud")) { other.GetProperty <HUDProperty>("hud").NotifyPowerupPickup(powerup.GetVector3(CommonNames.Position), NotificationString); } // check ranges other.GetProperty <PlayerControllerProperty>("controller").CheckPlayerAttributeRanges(other); // set to used powerUsed = true; } }
public void Update(SimulationTime simTime) { keyboardState = Keyboard.GetState(playerIndex); if (keyboardState.IsKeyDown(Keys.A)) { leftStickX = gamepadEmulationValue; } else if (keyboardState.IsKeyDown(Keys.D)) { leftStickX = -gamepadEmulationValue; } if (keyboardState.IsKeyDown(Keys.W)) { leftStickY = gamepadEmulationValue; } else if (keyboardState.IsKeyDown(Keys.S)) { leftStickY = -gamepadEmulationValue; } if (keyboardState.IsKeyDown(Keys.Left)) { rightStickX = gamepadEmulationValue; } else if (keyboardState.IsKeyDown(Keys.Right)) { rightStickX = -gamepadEmulationValue; } if (keyboardState.IsKeyDown(Keys.Up)) { rightStickY = -gamepadEmulationValue; } else if (keyboardState.IsKeyDown(Keys.Down)) { rightStickY = gamepadEmulationValue; } moveStickMoved = leftStickX > StickMovementEps || leftStickX <-StickMovementEps || leftStickY> StickMovementEps || leftStickY < -StickMovementEps; rightStickMoved = rightStickX > StickMovementEps || rightStickX <-StickMovementEps || rightStickY> StickMovementEps || rightStickY < -StickMovementEps; flameStickMoved = flameStickX > StickMovementEps || flameStickX <-StickMovementEps || flameStickY> StickMovementEps || flameStickY < -StickMovementEps; SetStates(JetpackKey, out repulsionButtonPressed, out repulsionButtonHold, out repulsionButtonReleased); SetStates(JetpackKey, out jumpButtonPressed, out jumpButtonHold, out jumpButtonReleased); SetStates(IceSpikeKey, out iceSpikeButtonPressed, out iceSpikeButtonHold, out iceSpikeButtonReleased); SetStates(HitKey, out hitButtonPressed, out hitButtonHold, out hitButtonReleased); SetStates(FlamethrowerKey, out flamethrowerButtonPressed, out flamethrowerButtonHold, out flamethrowerButtonReleased); SetStates(RunKey, out runButtonPressed, out runButtonHold, out runButtonReleased); if (hitButtonPressed) { // filter pressed events if (simTime.At < hitButtonPressedAt + HitButtonTimeout) { hitButtonPressed = false; } else { hitButtonPressedAt = simTime.At; } } oldKBState = keyboardState; }
protected virtual void OnUpdate(Entity island, SimulationTime simTime) { if (Game.Instance.Simulation.Phase == SimulationPhase.Intro) { return; } float dt = simTime.Dt; int playersOnIsland = island.GetInt("players_on_island"); Vector3 position = island.GetVector3(CommonNames.Position); // check if any player can interact with this island to provide an attribute so dominik is happy bool interactable; if (Game.Instance.Simulation.Phase == SimulationPhase.Game) { interactable = playersOnIsland > 0; if (!interactable) { foreach (Entity player in Game.Instance.Simulation.PlayerManager) { float dist = (position - player.GetVector3(CommonNames.Position)).Length(); if (dist < playerConstants.GetFloat("island_jump_free_range")) { interactable = true; } } } } else { // islands are interactable only during game phase interactable = false; } island.SetBool(CommonNames.Interactable, interactable); // implement sinking islands if (!HadCollision(simTime) && Game.Instance.Simulation.Phase == SimulationPhase.Game) // only sink in game-phase { if (playersOnIsland > 0) { position -= dt * island.GetFloat("sinking_speed") * playersOnIsland * (Vector3.UnitY); } } // set repositioning on players left if (playersOnIsland == 0) { if (simTime.At > lastPlayerLeftAt + constants.GetInt("rising_delay")) { // rising using normal repositioning state = IslandState.Repositioning; lastPlayerLeftAt = double.MaxValue; } } // apply repulsion from players Vector3 repulsionVelocity = island.GetVector3("repulsion_velocity"); if (repulsionVelocity.Length() > island.GetFloat("repulsion_speed")) { repulsionVelocity = Vector3.Normalize(repulsionVelocity) * island.GetFloat("repulsion_speed"); } Simulation.ApplyPushback(ref position, ref repulsionVelocity, constants.GetFloat("repulsion_deacceleration")); island.SetVector3("repulsion_velocity", repulsionVelocity); // apply pushback from other objects as long as there is a collision if (HadCollision(simTime)) { Vector3 pushbackVelocity = island.GetVector3("pushback_velocity"); if (pushbackVelocity.Length() > constants.GetFloat("collision_max_speed")) { pushbackVelocity.Normalize(); pushbackVelocity *= constants.GetFloat("collision_max_speed"); island.SetVector3("pushback_velocity", pushbackVelocity); } Simulation.ApplyPushback(ref position, ref pushbackVelocity, constants.GetFloat("collision_deacceleration"), CheckDistance); } else { if (island.GetVector3("pushback_velocity") != Vector3.Zero) { island.SetVector3("pushback_velocity", Vector3.Zero); CheckDistance(); } } // perform repositioning if (state == IslandState.Repositioning) { if (lastState != IslandState.Repositioning) { if (hasFixedMovementPath) { repositioningPosition = GetNearestPointOnPath(ref position); } else { repositioningPosition = position; repositioningPosition.Y = originalPosition.Y; // ensure we still maintian y position } island.SetVector3("repositioning_velocity", Vector3.Zero); } Vector3 desiredPosition = repositioningPosition; // if players are standing on island, we only reposition in xz if (playersOnIsland > 0 || (simTime.At < lastPlayerLeftAt + constants.GetInt("rising_delay") && // also wait for the delay lastPlayerLeftAt < float.MaxValue)) { // stay on y desiredPosition.Y = position.Y; } // get direction of new repositioning effort Vector3 dir = desiredPosition - position; float dist = dir.Length(); if (dir != Vector3.Zero) { dir.Normalize(); } Vector3 oldVelocity = island.GetVector3("repositioning_velocity"); if (oldVelocity.Length() > island.GetFloat("repositioning_speed")) { oldVelocity = Vector3.Normalize(oldVelocity) * island.GetFloat("repositioning_speed"); } if (dist < 80 && oldVelocity != Vector3.Zero) // todo: extract constant { oldVelocity -= oldVelocity * 0.6f * simTime.Dt * 25; } Vector3 velocity = oldVelocity; // acceleration Vector3 acc = dir * constants.GetFloat("repositioning_acceleraton"); velocity += acc * dt; // calculate new position Vector3 newPosition = position; newPosition += velocity * dt; // if acceleration takes us further away from object we stop if ((newPosition - desiredPosition).Length() > (position - desiredPosition).Length() && (newPosition - desiredPosition).Length() < 40) { // position = desiredPosition; state = IslandState.Normal; island.SetVector3("repositioning_velocity", Vector3.Zero); OnRepositioningEnded(dir); } else { position = newPosition; island.SetVector3("repositioning_velocity", velocity); } } else { Vector3 velocity = island.GetVector3(CommonNames.Velocity); // apply movement only if no collision if (!HadCollision(simTime)) { // normal movement if (state != IslandState.Repulsed) { // calculate acceleration direction in subclass Vector3 dir = CalculateAccelerationDirection(island, ref position, ref velocity, constants.GetFloat("movement_acceleration"), dt); velocity += dir * constants.GetFloat("movement_acceleration") * dt; if (velocity.Length() > island.GetFloat("movement_speed")) { velocity.Normalize(); velocity *= island.GetFloat("movement_speed"); } island.SetVector3(CommonNames.Velocity, velocity); } } position += velocity * dt; } island.SetVector3(CommonNames.Position, position); lastState = state; }
private void OnUpdate(Entity player, SimulationTime simTime) { controllerInput.Update(simTime); }
protected virtual bool HandleCollision(SimulationTime simTime, Entity island, Entity other, Contact co, ref Vector3 normal) { return(false); }
protected bool HadCollision(SimulationTime simTime) { return(simTime.At < collisionAt + CollisionTimeout); }
private void CollisionHandler(SimulationTime simTime, Contact contact) { Entity island = contact.EntityA; Entity other = contact.EntityB; if (other.HasString(CommonNames.Kind)) { String kind = other.GetString(CommonNames.Kind); if (// never do collision response with player who is standing or jumping on island (other.HasString("active_island") && other.GetString("active_island") == island.Name) || (other.HasString("jump_island") && other.GetString("jump_island") == island.Name) || (kind == "player" && other.GetString("active_island") == "") || // don't react on flying players kind == "powerup" || // with powerup neather other.HasBool("dynamic") // neither with dynamic entities ) { // do nothing } else { if (kind == "island" && simTime.At > collisionAt + 250 && // don't make to much noise state == IslandState.Repulsed) // and only if island influenced by player { // play sound Game.Instance.AudioPlayer.Play(Game.Instance.Simulation.SoundRegistry.IslandHitsIsland); } // other objects Vector3 normal = CalculatePseudoNormalIsland(island, other); // change direction of repulsion Vector3 repulsionVelocity = island.GetVector3("repulsion_velocity"); if (repulsionVelocity.Length() > 0) { // only if collision normal is in opposite direction of current repulsion Vector3 xznormal = normal; xznormal.Y = 0; if (Vector3.Dot(Vector3.Normalize(repulsionVelocity), xznormal) > 0) { island.SetVector3("repulsion_velocity", Vector3.Reflect(repulsionVelocity, xznormal) * constants.GetFloat("collision_damping")); } island.SetVector3("pushback_velocity", island.GetVector3("pushback_velocity") - xznormal * constants.GetFloat("collision_acceleration") * simTime.Dt); // todo: extract constant } if (state == IslandState.Repositioning) { Vector3 repositioningVelocity = island.GetVector3("repositioning_velocity"); if (Vector3.Dot(Vector3.Normalize(repositioningVelocity), normal) > 0) { island.SetVector3("repositioning_velocity", Vector3.Reflect(repositioningVelocity, normal) * constants.GetFloat("collision_damping")); } } else if (state == IslandState.Normal) { // pusbhack a bit island.SetVector3("pushback_velocity", island.GetVector3("pushback_velocity") - normal * constants.GetFloat("collision_acceleration") * simTime.Dt); // todo: extract constant // call handler of child class if (!HandleCollision(simTime, island, other, contact, ref normal)) { // do simple reflection if no special collision handler provided by subclass // or explicitly return of false Vector3 xznormal = normal; xznormal.Y = 0; if (xznormal != Vector3.Zero) { xznormal.Normalize(); } // reflect velocity Vector3 velocity = island.GetVector3(CommonNames.Velocity); if (velocity != Vector3.Zero) { if (Vector3.Dot(Vector3.Normalize(velocity), xznormal) > 0) { island.SetVector3(CommonNames.Velocity, Vector3.Reflect(velocity, xznormal) * constants.GetFloat("collision_damping")); } } } } collisionAt = simTime.At; } } }
private void OnUpdate(Entity iceSpike, SimulationTime simTime) { if (state == IceSpikeState.Exploded) { if (simTime.At > explodedAt + constants.GetInt("ice_spike_death_timeout")) { Game.Instance.Simulation.EntityManager.RemoveDeferred(iceSpike); } return; } // fetch required values Vector3 pos = iceSpike.GetVector3(CommonNames.Position); Vector3 v = iceSpike.GetVector3(CommonNames.Velocity); float dt = simTime.Dt; // accumulate forces Vector3 a = constants.GetVector3("ice_spike_gravity_acceleration"); // in targeting mode (yet)? if (state == IceSpikeState.Rising && simTime.At > createdAt + constants.GetInt("ice_spike_rising_time")) { state = IceSpikeState.Targeting; } // perform targetting logic if (state == IceSpikeState.Targeting) { if (targetPlayer != null && targetPlayer.GetFloat(CommonNames.Health) <= 0) { AbortPlayerTargeting(); } Vector3 dir; if (targetPlayer != null) { // incorporate homing effect towards targeted player Vector3 targetPlayerPos = targetPlayer.GetVector3(CommonNames.Position); dir = Vector3.Normalize(targetPlayerPos - pos); } else { // just accelerate in targeting direction dir = iceSpike.GetVector3("target_direction"); } // deaccelerate a bit if too fast if (v.Length() > constants.GetFloat("ice_spike_max_speed")) { a = -Vector3.Normalize(v) * constants.GetFloat("ice_spike_homing_acceleration"); } else { // get acceleration to direction float acc = constants.GetFloat("ice_spike_homing_acceleration"); a += dir * acc; a.Y *= 0.6f; // don't accelerate as fast on y axis // and add forces for islands float islandForceRadius = constants.GetFloat("ice_spike_island_force_radius"); foreach (Entity island in Game.Instance.Simulation.IslandManager) { // island target player is standing on has no force if (targetPlayer != null && targetPlayer.GetString("active_island") == island.Name) { continue; } Vector3 idir = island.GetVector3(CommonNames.Position) - pos; float dist = idir.Length(); idir.Normalize(); Vector3 ia = -idir * acc * (islandForceRadius * islandForceRadius / dist / dist); a += ia; } // and pillars float pillarForceRadius = constants.GetFloat("ice_spike_pillar_force_radius"); foreach (Entity island in Game.Instance.Simulation.PillarManager) { Vector3 idir = island.GetVector3(CommonNames.Position) - pos; idir.Y = 0; float dist = idir.Length(); idir.Normalize(); Vector3 ia = -idir * acc * (pillarForceRadius * pillarForceRadius / dist / dist); a += ia; } } } // integrate v += a * dt; pos += v * dt; // check lifetime if (state == IceSpikeState.Targeting && iceSpike.GetInt("creation_time") + constants.GetInt("ice_spike_lifetime") < simTime.At) { SetDead(iceSpike, simTime); return; } // remove if in lava if (pos.Y < Game.Instance.Simulation.EntityManager["lava"].GetVector3(CommonNames.Position).Y - 20) { SetDead(iceSpike, simTime); return; } // store computed values; iceSpike.SetVector3(CommonNames.Position, pos); iceSpike.SetVector3(CommonNames.Velocity, v); }
private void IceSpikePlayerCollisionHandler(SimulationTime simTime, Entity iceSpike, Entity player) { // indicate hit Game.Instance.AudioPlayer.Play(Game.Instance.Simulation.SoundRegistry.IceSpikeExplosionOnPlayer); }
protected abstract void OnUpdate(Entity entity, SimulationTime simTime);
private void OnUpdate(Entity flame, SimulationTime simTime) { float dt = simTime.Dt; at = simTime.At; if (flameThrowerState == FlameThrowerState.InActive) { flameThrowerStateChangedAt = at; flameThrowerState = FlameThrowerState.Warmup; } if (flameThrowerState == FlameThrowerState.Warmup) { int warmupTime = constants.GetInt("flamethrower_warmup_time"); int warmupCost = constants.GetInt("flamethrower_warmup_energy_cost"); if (at < flameThrowerStateChangedAt + warmupTime) { flame.SetVector3(CommonNames.Scale, flame.GetVector3("full_scale") * ((float)((at - flameThrowerStateChangedAt) / warmupTime))); if (at >= flameThrowerStateChangedAt + flameThrowerWarmupDeducted * (warmupTime / warmupCost)) { player.SetFloat(CommonNames.Energy, player.GetFloat(CommonNames.Energy) - 1); flameThrowerWarmupDeducted++; } } else { player.SetFloat(CommonNames.Energy, player.GetFloat(CommonNames.Energy) - (warmupCost - flameThrowerWarmupDeducted)); flameThrowerState = FlameThrowerState.Active; flameThrowerStateChangedAt = at; } } else if (flameThrowerState == FlameThrowerState.Active) { player.SetFloat(CommonNames.Energy, player.GetFloat(CommonNames.Energy) - Game.Instance.Simulation.Time.Dt * constants.GetFloat("flamethrower_energy_per_second")); } // else cooldown -> do nothing if (flameThrowerState == FlameThrowerState.Cooldown) { // cooldown int cooldownTime = constants.GetInt("flamethrower_cooldown_time"); if (at < flameThrowerStateChangedAt + constants.GetInt("flamethrower_cooldown_time")) { flame.SetVector3(CommonNames.Scale, flame.GetVector3("full_scale") * ((float)(1 - (at - flameThrowerStateChangedAt) / cooldownTime))); } else { flameThrowerState = FlameThrowerState.InActive; Game.Instance.Simulation.EntityManager.RemoveDeferred(flame); } } if (flameThrowerState == FlameThrowerState.Active) { flame.SetVector3(CommonNames.Scale, flame.GetVector3("full_scale") * scaleFactor); if (scaleFactor < 1) { scaleFactor += constants.GetFloat("flamethrower_turn_flame_increase") * dt; } else { scaleFactor = 1; } } }