public override bool Process() { if (NetworkManager.IsClient) { return(false); } if (TicsSinceLastDrop < 0 || TicsSinceLastDrop > 6) { TicsSinceLastDrop = 0; // spawn random blizzard projectile in 4x4 grid (center at 1,1) float rndX = UnityEngine.Random.Range(-1, 3) + TargetX; float rndY = UnityEngine.Random.Range(-1, 3) + TargetY; if (rndX >= 0 && rndY >= 0 && rndX < MapLogic.Instance.Width && rndY < MapLogic.Instance.Height) { Server.SpawnProjectileDirectional(AllodsProjectile.Blizzard, Spell.User, rndX + 0.5f, rndY + 0.5f, 4f, rndX + 0.5f, rndY + 0.5f, 0f, 3f, proj => { Server.SpawnProjectileSimple(AllodsProjectile.Blizzard, Spell.User, rndX + 0.5f, rndY + 0.5f, 0f, 1f, 1f, 0, 7); // find something to damage in this cell MapNode node = MapLogic.Instance.Nodes[proj.X, proj.Y]; for (int i = 0; i < node.Objects.Count; i++) { MapObject mo = node.Objects[i]; if (!(mo is IVulnerable)) { continue; } IVulnerable vul = (IVulnerable)mo; int dmg = Spell.GetDamage(); vul.TakeDamage(DamageFlags.Water | (Spell.Item == null?DamageFlags.AllowExp:0), Spell.User, dmg); } }); } } TicsSinceLastDrop++; TicsTotal++; return(TicsTotal < MapLogic.TICRATE * Spell.GetDuration()); }
public override bool Process() { if (NetworkManager.IsClient) { return(false); } // 5x5, but remove corners for (int y = TargetY - 2; y <= TargetY + 2; y++) { for (int x = TargetX - 2; x <= TargetX + 2; x++) { // check for corner tiles :) if ((x == TargetX - 2 || x == TargetX + 2) && (y == TargetY - 2 || y == TargetY + 2)) { continue; } if (x < 0 || y < 0 || x >= MapLogic.Instance.Width || y >= MapLogic.Instance.Height) { continue; } // check if there are FIRE effects on this cell, don't spawn fog bool spawnblocked = false; foreach (MapObject mo in MapLogic.Instance.Nodes[x, y].Objects) { if (!(mo is MapProjectile)) { continue; } MapProjectile mp = (MapProjectile)mo; if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud) { continue; } // don't remove if on edge of fire wall if (new Vector2(mp.ProjectileX - x + 0.5f, mp.ProjectileY - y + 0.5f).magnitude > 0.8f) { continue; } spawnblocked = true; break; } if (spawnblocked) { continue; } Server.SpawnProjectileEOT(AllodsProjectile.PoisonCloud, Spell.User, x + 0.5f, y + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 40, 0, 0, 16, proj => { DamageFlags spdf = SphereToDamageFlags(Spell); // get projectile cells int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX)); int axTo = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX)); int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY)); int ayTo = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY)); for (int py = ayFrom; py <= ayTo; py++) { for (int px = axFrom; px <= axTo; px++) { // check how much projectile is on this cell float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude); // 0..1 effect power MapNode node = MapLogic.Instance.Nodes[px, py]; for (int i = 0; i < node.Objects.Count; i++) { MapObject mo = node.Objects[i]; if (!(mo is MapUnit)) { continue; } MapUnit mov = (MapUnit)mo; int dmg = (int)(Spell.GetIndirectPower() * pdst); if (dmg <= 0) { continue; // don't add null effects } SpellEffects.Effect eff = new SpellEffects.Poison(this, dmg, MapLogic.TICRATE * 8); // originally 8 seconds mov.AddSpellEffects(eff); } } } }); } } return(false); }
public override bool Process() { if (TargetUnit == null) { return(false); } SpellEffects.Effect eff = new SpellEffects.ProtectionWater((int)(MapLogic.TICRATE * Spell.GetDuration()), Spell.GetProtection()); TargetUnit.AddSpellEffects(eff); return(false); }
public override bool Process() { if (NetworkManager.IsClient) { return(false); } // we need to spawn several EoT projectiles at the destination // 5x2 float sourceX = Spell.User.X + Spell.User.FracX + Spell.User.Width / 2f; float sourceY = Spell.User.Y + Spell.User.FracY + Spell.User.Height / 2f; Vector2 direction = new Vector2(TargetX + 0.5f - sourceX, TargetY + 0.5f - sourceY); float angle = Mathf.Atan2(direction.y, direction.x) - (Mathf.PI / 180) * 90; for (int x = -2; x <= 2; x++) { for (int y = 0; y < 2; y++) { // rotate x and y float fx = x; float fy = y; float rx = Mathf.Cos(angle) * x - Mathf.Sin(angle) * y; float ry = Mathf.Cos(angle) * y + Mathf.Sin(angle) * x; Server.SpawnProjectileEOT(AllodsProjectile.FireWall, Spell.User, TargetX + rx + 0.5f, TargetY + ry + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 10, 4, 4, 16, proj => { DamageFlags spdf = SphereToDamageFlags(Spell); if (Spell.Item == null) { spdf |= DamageFlags.AllowExp; } // get projectile cells int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX)); int axTo = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX)); int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY)); int ayTo = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY)); for (int py = ayFrom; py <= ayTo; py++) { for (int px = axFrom; px <= axTo; px++) { // check how much projectile is on this cell float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude); // 0..1 effect power MapNode node = MapLogic.Instance.Nodes[px, py]; for (int i = 0; i < node.Objects.Count; i++) { MapObject mo = node.Objects[i]; if (!(mo is IVulnerable)) { // aoe fire effect: remove cloud effects if any if (!(mo is MapProjectile)) { continue; } MapProjectile mp = (MapProjectile)mo; if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud) { continue; } // don't remove if on edge of fire wall if (new Vector2(mp.ProjectileX - proj.ProjectileX, mp.ProjectileY - proj.ProjectileY).magnitude > 0.8f) { continue; } mp.Dispose(); i--; continue; } else { IVulnerable mov = (IVulnerable)mo; int dmg = (int)(Spell.GetDamage() * pdst); mov.TakeDamage(spdf, Spell.User, dmg); } } } } }); } } return(false); }
public override bool Process() { if (NetworkManager.IsClient) { return(false); } // 11x11, but remove corners for (int y = TargetY - 5; y <= TargetY + 5; y++) { for (int x = TargetX - 5; x <= TargetX + 5; x++) { // check for corner tiles :) if (new Vector2(x - TargetX, y - TargetY).magnitude > 5.5f) { continue; } if (x < 0 || y < 0 || x >= MapLogic.Instance.Width || y >= MapLogic.Instance.Height) { continue; } // remove light effects MapNode node = MapLogic.Instance.Nodes[x, y]; for (int i = 0; i < node.Objects.Count; i++) { MapObject mo = node.Objects[i]; if (mo is MapProjectile && ((((MapProjectile)mo).ClassID == AllodsProjectile.SpecDarkness) || (((MapProjectile)mo).ClassID == AllodsProjectile.SpecLight))) { mo.Dispose(); i--; continue; } } float power = Spell.GetScanRange(); int lightlevel = (int)(-(power * 32)); Server.SpawnProjectileEOT(AllodsProjectile.SpecDarkness, Spell.User, x + 0.5f, y + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), MapLogic.TICRATE / 2, 0, 0, 16, proj => { MapNode pnode = MapLogic.Instance.Nodes[proj.X, proj.Y]; for (int i = 0; i < pnode.Objects.Count; i++) { MapObject mo = pnode.Objects[i]; if (!(mo is MapUnit)) { continue; } MapUnit mov = (MapUnit)mo; // don't affect AI units if (mov.Player == null || mov.Player.DoFullAI) { continue; } SpellEffects.Effect eff = new SpellEffects.Darkness(MapLogic.TICRATE / 2, Spell.GetScanRange()); // 1 second mov.AddSpellEffects(eff); } }, lightlevel); } } return(false); }