/// <summary> /// De-serialize the effect /// </summary> /// <param name="reader">Reader instance</param> public override void Read(BinaryReader reader) { base.Read(reader); mPlayer = reader.ReadEntityID(); mStartPos = reader.ReadVector2(); mLandingPos = reader.ReadVector2(); mFallProgress = reader.ReadSingle(); mStage = reader.ReadByte(); mLanded = reader.ReadBoolean(); }
/// <summary> /// Constructor /// </summary> /// <param name="target">Target entity to place to swoosh on</param> public EffectSwoosh(EntityID target) : base(EffectType.Swoosh) { mFramesTotal = S.ANIM_SWOOSH.Count; mFramesRemaining = mFramesTotal; mTargetEntity = target; mDrawFlags = 0; mDrawFlags |= Random.Range(0, 2) == 0 ? 0 : RB.FLIP_H; }
/// <summary> /// Make this entity attack another entity /// </summary> /// <param name="resultSet">Result</param> /// <param name="target">Target entity</param> public void Attack(ResultSet resultSet, EntityID target) { if (target.isEmpty) { return; } int damage = power - target.e.fighter.defense; if (damage > 0) { target.e.fighter.TakeDamage(resultSet, damage); resultSet.AddMessage( C.FSTR.Clear() .Append(C.STR_COLOR_NAME) .Append(owner.e.name) .Append("@- attacks ") .Append(C.STR_COLOR_NAME) .Append(target.e.name) .Append("@- for ") .Append(C.STR_COLOR_DAMAGE) .Append(damage) .Append("@- hit points.")); } else { if (Random.Range(0, 3) == 0) { resultSet.AddMessage( C.FSTR.Clear() .Append(C.STR_COLOR_NAME) .Append(owner.e.name) .Append("@- attacks ") .Append(C.STR_COLOR_NAME) .Append(target.e.name) .Append("@- but does no damage.")); } else { damage = 1; target.e.fighter.TakeDamage(resultSet, damage); resultSet.AddMessage( C.FSTR.Clear() .Append(C.STR_COLOR_NAME) .Append(owner.e.name) .Append("@- hits ") .Append(C.STR_COLOR_NAME) .Append(target.e.name) .Append("@- with a glancing blow for ") .Append(C.STR_COLOR_DAMAGE) .Append(damage) .Append("@- hit points.")); } } }
/// <summary> /// Constructor /// </summary> /// <param name="portal">Portal</param> public EffectPortal(EntityID portal) : base(EffectType.Portal) { mFramesTotal = 10; mFramesRemaining = mFramesTotal; mPortal = portal; mRiseTime = 0; renderOrder = RenderFunctions.RenderOrder.ACTOR_UNDERLAY_EFFECTS; }
/// <summary> /// Constructor /// </summary> /// <param name="target">Target of confusion effect</param> public EffectConfuse(EntityID target) : base(EffectType.Confuse) { mFramesTotal = 10; mFramesRemaining = mFramesTotal; mTarget = target; mMarks.Add(new Vector2(-6, -(FLOAT_HEIGHT / 2))); mMarks.Add(new Vector2(0, 0)); mMarks.Add(new Vector2(6, -(FLOAT_HEIGHT / 4))); }
/// <summary> /// Get entity by id /// </summary> /// <param name="id">Id</param> /// <returns>Entity</returns> public static Entity Get(EntityID id) { var checkId = Instance.mEntityIDs[id.index]; if (checkId == id) { return(Instance.mEntities[id.index]); } return(null); }
/// <summary> /// Constructor /// </summary> /// <param name="target">Target of confusion effect</param> public EffectPlayerDeath(EntityID target) : base(EffectType.PlayerDeath) { var game = (RetroDungeoneerGame)RB.Game; mFramesTotal = (int)(FLOAT_HEIGHT / FLOAT_SPEED); mFramesRemaining = mFramesTotal; mGhostPos = new Vector2(target.e.pos.x * game.assets.spriteSheet.grid.cellSize.width, target.e.pos.y * game.assets.spriteSheet.grid.cellSize.height); renderOrder = RenderFunctions.RenderOrder.TOP_MOST; }
/// <summary> /// Set position based on entity. This immediately snaps the camera to the given entities position. /// </summary> /// <param name="entity">Entity</param> public void SetPos(EntityID entity) { var e = EntityStore.Get(entity); if (e == null) { return; } mPos = new Vector2(e.pos.x * RB.SpriteSize(0).width, e.pos.y * RB.SpriteSize(0).height); }
/// <summary> /// Make a starting dungeon room /// </summary> /// <param name="player">Player entity</param> /// <param name="room">Room rect</param> public void MakeStartRoom(EntityID player, Rect2i room) { if (dungeonLevel == 1) { var daggerSpawnRect = room; daggerSpawnRect.Expand(-2); EntityFunctions.CreateItem(ItemType.Dagger, RandomUtils.RandomRectPerimeterPos(daggerSpawnRect)); } // Place the player in the middle of the room player.e.pos = room.center; }
/// <summary> /// Take a turn. /// </summary> /// <param name="resultSet">Result of taking a turn</param> /// <param name="target">Target entity being tracked by the Ai</param> public override void TakeTurn(ResultSet resultSet, EntityID target) { var game = (RetroDungeoneerGame)RB.Game; base.TakeTurn(resultSet, target); if (aggroed && !encounteredOnce) { encounteredOnce = true; resultSet.AddBossEncounter(); } }
/// <summary> /// Follow the given entity /// </summary> /// <param name="entity">Entity to follow</param> public void Follow(EntityID entity) { var e = EntityStore.Get(entity); if (e == null) { return; } mPos.x += ((e.pos.x * RB.SpriteSize(0).width) - mPos.x) * mSpeed; mPos.y += ((e.pos.y * RB.SpriteSize(0).height) - mPos.y) * mSpeed; }
/// <summary> /// De-serialize the effect /// </summary> /// <param name="reader">Reader instance</param> public override void Read(BinaryReader reader) { base.Read(reader); mTarget = reader.ReadEntityID(); var count = reader.ReadInt32(); mMarks.Clear(); for (int i = 0; i < count; i++) { mMarks.Add(reader.ReadVector2()); } }
/// <summary> /// Set position based on entity. This immediately snaps the camera to the given entities position. /// </summary> /// <param name="entity">Entity</param> public void SetPos(EntityID entity) { var game = (RetroDungeoneerGame)RB.Game; var e = EntityStore.Get(entity); if (e == null) { return; } mPos = new Vector2(e.pos.x * game.assets.spriteSheet.grid.cellSize.width, e.pos.y * game.assets.spriteSheet.grid.cellSize.height); }
/// <summary> /// De-serialize the effect /// </summary> /// <param name="reader">Reader instance</param> public override void Read(BinaryReader reader) { base.Read(reader); mPortal = reader.ReadEntityID(); var count = reader.ReadInt32(); mParticles.Clear(); for (int i = 0; i < count; i++) { mParticles.Add(reader.ReadVector2()); } }
/// <summary> /// Follow the given entity /// </summary> /// <param name="entity">Entity to follow</param> public void Follow(EntityID entity) { var game = (RetroDungeoneerGame)RB.Game; var e = EntityStore.Get(entity); if (e == null) { return; } mPos.x += ((e.pos.x * game.assets.spriteSheet.grid.cellSize.width) - mPos.x) * mSpeed; mPos.y += ((e.pos.y * game.assets.spriteSheet.grid.cellSize.height) - mPos.y) * mSpeed; }
/// <summary> /// Check if equipment contains the given item /// </summary> /// <param name="item">Item</param> /// <returns>True if item is in equipment</returns> public bool ContainsItem(EntityID item) { if (item.e == null || item.e.equippable == null) { return(false); } if (equipment[(int)item.e.equippable.slot] == item) { return(true); } return(false); }
/// <summary> /// Setup new game variables. This involves creating the player, and generating the game map. /// </summary> /// <param name="player">Player</param> /// <param name="gameMap">Game map</param> public static void SetupGameVariables(ref EntityID player, ref GameMap gameMap) { EntityStore.Clear(); player = EntityFunctions.CreatePlayer(new Vector2i(-1, -1)); gameMap = new GameMap(new Vector2i(C.MAP_WIDTH, C.MAP_HEIGHT)); gameMap.MakeMap(C.MAX_ROOMS, C.ROOM_MIN_SIZE, C.ROOM_MAX_SIZE, C.MAP_WIDTH, C.MAP_HEIGHT, player); if (player.e.moveTrail != null) { player.e.moveTrail.Clear(); } }
/// <summary> /// De-serialize the effect /// </summary> /// <param name="reader">Reader instance</param> public override void Read(BinaryReader reader) { base.Read(reader); mSourcePos = reader.ReadVector2i(); mTargetPos = reader.ReadVector2i(); mTargetEntity = reader.ReadEntityID(); mAlphaFade = reader.ReadInt32(); mProjecticleColor = reader.ReadColor32(); mProjecticleSprite = reader.ReadPackedSpriteID(); mProjecticleSprite45 = reader.ReadPackedSpriteID(); mRotate = reader.ReadBoolean(); mLaunchSound = SoundSerializer.Deserialize(reader.ReadInt32()); mLandSound = SoundSerializer.Deserialize(reader.ReadInt32()); }
private static void RenderTrail(EntityID entity) { var moveTrail = entity.e.moveTrail; RB.TintColorSet(Color.white); for (int i = 0; i < moveTrail.trail.Count; i++) { var t = moveTrail.trail[i]; RB.AlphaSet(t.fade); RB.DrawEllipseFill(t.pos + new Vector2i(RB.SpriteSize(0).width / 2, RB.SpriteSize(0).height / 2), new Vector2i(2, 2), Color.white); } RB.AlphaSet(255); }
/// <summary> /// Cast confuse /// </summary> /// <param name="resultSet">Result set</param> /// <param name="caster">Caster</param> /// <param name="targetPos">Target position</param> /// <returns>True if successful</returns> public static bool CastConfuse(ResultSet resultSet, EntityID caster, Vector2i targetPos) { var game = (RetroDungeoneerGame)RB.Game; if (!CheckTargetPosValid(resultSet, targetPos, caster)) { return(false); } EntityID target = EntityID.empty; for (int i = 0; i < EntityStore.entities.Count; i++) { var eid = EntityStore.entities[i]; var e = eid.e; if (e.pos == targetPos) { target = eid; break; } } if (!target.isEmpty) { var confusedAi = new ConfusedMonster(); confusedAi.previousAi = target.e.ai; confusedAi.numberOfTurns = 10; target.e.ai = confusedAi; resultSet.AddMessage( C.FSTR.Set("The eyes of the ").Append(C.STR_COLOR_NAME).Append(target.e.name).Append("@- look vacant, as it starts to stumble around!")); EffectManager.Instance.AddEffect(new EffectConfuse(target)); RB.SoundPlay(game.assets.soundConfuse); return(true); } else { resultSet.AddMessage( C.FSTR.Set("There is no targetable enemy at that location.")); } return(false); }
/// <summary> /// Take a turn. /// </summary> /// <param name="resultSet">Result of taking a turn</param> /// <param name="target">Target entity being tracked by the Ai</param> public override void TakeTurn(ResultSet resultSet, EntityID target) { var game = (RetroDungeoneerGame)RB.Game; var monster = owner; // No aggro, see if we can aquire aggro if (!aggroed) { if (game.map.IsInFOV(monster.e.pos)) { float dist = monster.e.DistanceTo(target); if (dist <= aggroRange) { aggroed = true; aggroTimeout = AGGRO_MAX_TIMEOUT; resultSet.AddMessage(C.FSTR.Set("The ").Append(C.STR_COLOR_NAME).Append(owner.e.name).Append("@- spots you!")); EffectManager.Instance.AddEffect(new EffectAggro(monster)); int aggroSound = UnityEngine.Random.Range(0, 2) == 0 ? C.SOUND_AGGRO1 : C.SOUND_AGGRO2; SoundBank.Instance.SoundPlayDelayed(aggroSound, 0.66f, RandomUtils.RandomPitch(0.15f), UnityEngine.Random.Range(0, 8)); } } } else { if (aggroTimeout == 0) { resultSet.AddMessage(C.FSTR.Set("The ").Append(C.STR_COLOR_NAME).Append(owner.e.name).Append("@- gives up the chase.")); aggroed = false; } else { if (!game.map.IsInFOV(monster.e.pos) || monster.e.DistanceTo(target) > aggroRange) { aggroTimeout--; } else { aggroTimeout = AGGRO_MAX_TIMEOUT; } DoSkill(resultSet, target); } } }
/// <summary> /// Equality check /// </summary> /// <param name="other">Other object</param> /// <returns>True if equal</returns> public override bool Equals(object other) { bool result; if (!(other is EntityID)) { result = false; } else { EntityID r = (EntityID)other; result = mIndex.Equals(r.mIndex) && mGen.Equals(r.mGen); } return(result); }
private static void RenderTrail(EntityID entity) { var game = (RetroDungeoneerGame)RB.Game; var moveTrail = entity.e.moveTrail; RB.TintColorSet(Color.white); for (int i = 0; i < moveTrail.trail.Count; i++) { var t = moveTrail.trail[i]; RB.AlphaSet(t.fade); RB.DrawEllipseFill(t.pos + new Vector2i(game.assets.spriteSheet.grid.cellSize.width / 2, game.assets.spriteSheet.grid.cellSize.height / 2), new Vector2i(2, 2), Color.white); } RB.AlphaSet(255); }
/// <summary> /// Create the next floor, this also takes care of moving the player to the next floor /// </summary> /// <param name="resultSet">Result</param> /// <param name="player">Player</param> /// <param name="console">Output console</param> public void NextFloor(ResultSet resultSet, EntityID player, Console console) { dungeonLevel++; List <EntityID> playerEntities = player.e.GetSelfAndChildren(); EntityStore.ClearExcept(playerEntities); InitializeTiles(); MakeMap(C.MAX_ROOMS, C.ROOM_MIN_SIZE, C.ROOM_MAX_SIZE, C.MAP_WIDTH, C.MAP_HEIGHT, player); if (player.e.moveTrail != null) { player.e.moveTrail.Clear(); } }
/// <summary> /// Constructor /// </summary> /// <param name="player">Player</param> public EffectPlayerEntrance(EntityID player) : base(EffectType.PlayerEntrance) { mFramesTotal = 1; mFramesRemaining = 1; mStage = 0; mPlayer = player; mLandingPos = new Vector2(player.e.pos.x * RB.SpriteSize(0).width, player.e.pos.y * RB.SpriteSize(0).height); mStartPos = new Vector2(mLandingPos.x, mLandingPos.y - (RB.DisplaySize.height / 1.75f)); mFallProgress = 0.0f; mLanded = false; // Animation blocks player input until it's done mIsBlocking = true; renderOrder = RenderFunctions.RenderOrder.TOP_MOST; }
/// <summary> /// Constructor /// </summary> /// <param name="player">Player</param> public EffectPlayerEntrance(EntityID player) : base(EffectType.PlayerEntrance) { var game = (RetroDungeoneerGame)RB.Game; mFramesTotal = 1; mFramesRemaining = 1; mStage = 0; mPlayer = player; mLandingPos = new Vector2(player.e.pos.x * game.assets.spriteSheet.grid.cellSize.width, player.e.pos.y * game.assets.spriteSheet.grid.cellSize.height); mStartPos = new Vector2(mLandingPos.x, mLandingPos.y - (RB.DisplaySize.height / 1.75f)); mFallProgress = 0.0f; mLanded = false; // Animation blocks player input until it's done mIsBlocking = true; renderOrder = RenderFunctions.RenderOrder.TOP_MOST; }
private void DeleteItemFromList(EntityID item) { for (int i = 0; i < items.Length; i++) { if (items[i] == item) { // Shift following items down int j; for (j = i; j < items.Length - 1; j++) { items[j] = items[j + 1]; } items[j] = EntityID.empty; break; } } }
/// <summary> /// Drop item on the ground from inventory /// </summary> /// <param name="resultSet">Result</param> /// <param name="item">Item to drop</param> public void DropItem(ResultSet resultSet, EntityID item) { DeleteItemFromList(item); item.e.pos = owner.e.pos; // Dequip item first if its currently equipped if (owner.e.equipment != null && item.e.equippable != null) { var slot = item.e.equippable.slot; if (owner.e.equipment.equipment[(int)slot] == item) { owner.e.equipment.ToggleEquip(resultSet, item); } } resultSet.AddItemDropped(item); resultSet.AddMessage(C.FSTR.Set("You dropped the ").Append(C.STR_COLOR_NAME).Append(item.e.name).Append("@-.")); }
/// <summary> /// Kill the player /// </summary> /// <param name="resultSet">Result</param> /// <param name="player">Player entity</param> public static void KillPlayer(ResultSet resultSet, EntityID player) { var pe = player.e; pe.sprite = S.GRAVESTONE; pe.color = new Color32(200, 200, 200, 255); C.FSTR.Set(pe.name); pe.name.Set("grave of ").Append(C.FSTR); pe.renderOrder = RenderFunctions.RenderOrder.CORPSE; // Delete all equipment, this prevents paperDoll rendering on the grave pe.equipment = null; resultSet.AddMessage(C.FSTR.Set("You ").Append(C.STR_COLOR_DEAD).Append("@w145died@w000@-!")); RB.SoundPlay(C.SOUND_PLAYER_DEATH, 1.0f); RB.MusicVolumeSet(1.0f); RB.MusicPlay(C.MUSIC_DEATH); EffectManager.Instance.AddEffect(new EffectPlayerDeath(player)); }
/// <summary> /// Take a turn. /// </summary> /// <param name="resultSet">Result of taking a turn</param> /// <param name="target">Target entity being tracked by the Ai</param> public override void TakeTurn(ResultSet resultSet, EntityID target) { if (numberOfTurns > 0) { var randomPos = owner.e.pos; randomPos.x += Random.Range(-1, 2); randomPos.y += Random.Range(-1, 2); if (randomPos != owner.e.pos) { owner.e.MoveTowards(randomPos); } numberOfTurns--; } else { owner.e.ai = previousAi; resultSet.AddMessage(C.FSTR.Set("The ").Append(C.STR_COLOR_NAME).Append(owner.e.name).Append("@- is no longer confused!")); } }