public static void GenerateSpellBurst(int x, int y, int width, int height, MagicSprite.MagicAnimation anim) { // Create ~6 spell sprites within bounds randomly and play them // Debug.WriteLine("Generate burst " + x + ", " + y + ", " + width + ", " + height + ", " + anim.ToString()); List <Vector2> posList = new List <Vector2>(); for (int i = 0; i < width / 32; i++) { for (int j = 0; j < height / 32; j++) { int xPos = x + i * 32 + Globals.rnd.Next(4); int yPos = y + j * 32 + Globals.rnd.Next(4); posList.Add(new Vector2(xPos, yPos)); } } foreach (Vector2 pos in posList) { float delay = (float)Globals.rnd.NextDouble() * 100f; MagicSprite mspr = GetMagicSprite(); mspr.SetAnimation(anim, delay); mspr.SetPosition(pos); } }
private bool ExecuteActions() { turn = 0; foreach (Action action in GetSortedActionArray()) { // Update and display turn number turn++; turnTotal++; TextManager.SetTurnText(turn); // If an actor was killed before its turn, ignore the turn if (action.Actor == null || action.Actor.IsDead()) { continue; } // Apply the action to each target foreach (MonoMonster target in action.Targets) { // Ignore invalid target and spells against the dead if (target == null || (action.Spell != null && target.IsDead())) { continue; } TextManager.SetActorText(action.Actor.Name); Thread.Sleep(gameTick); // If the action is nothing, display and bail out if (action.Nothing) { TextManager.SetResultsText("Nothing"); continue; } TextManager.SetTargetText(target.Name); Thread.Sleep(gameTick); if (action.Physical) { // Physical attacks can target the dead, but are ineffective if (target.IsDead()) { TextManager.SetResultsText("Ineffective"); continue; } // Apply the attack and display the results AttackResult atkRes = AttackManager.AttackMonster(action.Actor, target); // On a miss, display and bail out if (string.Equals(atkRes.DamageMessage, "Miss")) { TextManager.SetDamageText("Miss"); continue; } // Flicker sprite // TODO: Different sounds and animations need to play based on the attack type if (gameTick > 30) { SoundManager.PlaySound(SoundManager.Sound.Physical); target.Flicker(16); } TextManager.SetHitsText(atkRes.HitsMessage); Thread.Sleep(gameTick); TextManager.SetDamageText(atkRes.DamageMessage); Thread.Sleep(gameTick); // Fade the monster if dead // TODO: This is awkward here if (target.IsDead()) { target.StartDeath(); Thread.Sleep(30); // 300 } // Display each result, tearing down existing results as needed for (int i = 0; i < atkRes.Results.Count; i++) { string res = atkRes.Results[i]; TextManager.SetResultsText(res); if (i < atkRes.Results.Count - 1) { Thread.Sleep(gameTick * 2); TextManager.TearDownResults(); Thread.Sleep(teardownTick); } } break; } else { // Casting a spell TextManager.SetHitsText(action.Spell.Name + " " + action.SpellLevel); Thread.Sleep(gameTick); // Cast the spell and display the results SpellResult spellRes = SpellManager.CastSpell(action.Actor, target, action.Spell, action.SpellLevel, action.Targets.Count > 1); // Set the spell animation and sound based on the spell's effect (kinda). This is awkward but fine for now. MagicSprite.MagicAnimation magicAnim = MagicSprite.MagicAnimation.Attack; SoundManager.Sound magicSnd = SoundManager.Sound.AttackSpell; if (action.Spell.Effect == "Buff") { magicAnim = MagicSprite.MagicAnimation.Buff; magicSnd = SoundManager.Sound.Buff; } if (action.Spell.Effect == "Debuff" || action.Spell.Effect == "TempStatus" || action.Spell.Effect == "PermStatus") { magicAnim = MagicSprite.MagicAnimation.Debuff; magicSnd = SoundManager.Sound.Debuff; } if (action.Spell.Effect == "Heal" || action.Spell.Effect == "Revive" || action.Spell.Effect == "ItemFullRestore") { magicAnim = MagicSprite.MagicAnimation.Heal; magicSnd = SoundManager.Sound.Heal; } MagicSpriteManager.GenerateSpellBurst((int)target.Position.X, (int)target.Position.Y, target.Width, target.Height, magicAnim); SoundManager.PlaySound(magicSnd); Thread.Sleep(SPELL_ANIMATION_DELAY); if (spellRes.Damage >= 0) { TextManager.SetDamageText(spellRes.Damage.ToString()); Thread.Sleep(gameTick); } // Kill the target if it's dead. // TODO: This is weird here, should be handled by the monster itself? if (target.IsDead()) { target.StartDeath(); Thread.Sleep(300); } // Display each result, tearing down existing results as needed for (int i = 0; i < spellRes.Results.Count; i++) { string res = spellRes.Results[i]; TextManager.SetResultsText(res); if (i < spellRes.Results.Count - 1) { Thread.Sleep(gameTick * 2); TextManager.TearDownResults(); Thread.Sleep(teardownTick); } } // Tear down between each target Thread.Sleep(gameTick * 5); while (TextManager.TearDownText()) { Thread.Sleep(teardownTick); } } // TODO: If both scenes only contain "Soul" enemies, they cannot kill eachother if (!sceneOne.HasLivingMonsters() || !sceneTwo.HasLivingMonsters() || round >= ROUND_LIMIT) { break; } } // Turn end, clean up text display Thread.Sleep(gameTick * 5); while (TextManager.TearDownText()) { Thread.Sleep(teardownTick); } if (!sceneOne.HasLivingMonsters() || !sceneTwo.HasLivingMonsters() || round >= ROUND_LIMIT) { break; } } return(false); }