// returns cost to walk to a node. // 1.5 = 150% cost, 0.5 = 50% cost. does not always relate to speed (may be related to spell effects being present) public float GetNodeCostFactor(int x, int y, bool staticOnly) { float nodeFactor = 0; int nodeCount = 0; for (int ly = y; ly < y + Unit.Height; ly++) { for (int lx = x; lx < x + Unit.Width; lx++) { MapNode node = MapLogic.Instance.Nodes[lx, ly]; // for walking units, take base node speed as factor float baseNodeFactor = 1f; if (Unit.IsWalking) { baseNodeFactor = Math.Max((byte)1, node.BaseWalkCost) / 8f; // reverse formula for cost compared to speed } // it would be strange if long-term path included spells and other temporary effects if (!staticOnly) { foreach (MapObject mobj in node.Objects) { if (!(mobj is MapProjectile)) { continue; } MapProjectile proj = (MapProjectile)mobj; // now some magic ;) if (proj.Class == null) { continue; } // logic: the more elemental protection unit has, the more likely it is that it will try to walk right through a spell // we are multiplying it *2 because just "firefac" and "waterfac" don't seem to be powerful enough do make the unit go around with 50 protection switch ((AllodsProjectile)proj.Class.ID) { case AllodsProjectile.FireWall: float firefac = (100 - Unit.Stats.ProtectionFire) / 100f; baseNodeFactor *= 1f + firefac * 2; break; case AllodsProjectile.PoisonCloud: case AllodsProjectile.Blizzard: float waterfac = (100 - Unit.Stats.ProtectionWater) / 100f; baseNodeFactor *= 1f + waterfac * 2; break; // could check for SpecLight, SpecDarkness here. however ROM2 does not seem to do this default: break; } } } nodeFactor += baseNodeFactor; nodeCount++; } } return(nodeFactor / nodeCount); }
public override void Process() { int meanWh = (Unit.Width + Unit.Height) / 2; for (int i = 0; i < meanWh * 2; i++) { float rX = Unit.Width / 2f; float rY = Unit.Height / 4f; float randRad = UnityEngine.Random.Range(0.0f, 1.0f) * Mathf.PI * 2; float pX = -(Mathf.Cos(randRad) * rX); float pY = -(Mathf.Sin(randRad) * rY); float cZ = -(meanWh / 2f); MapProjectile item = new MapProjectile(AllodsProjectile.Healing, Unit, new HealingProjectileLogic((Unit.Width + Unit.Height) / 2f, pX, pY, cZ, Unit)); item.ZOffset = -64; if (Unit.IsFlying) { item.ZOffset += 128; } item.SetPosition(pX, pY, 0); item.ZAbsolute = true; MapLogic.Instance.AddObject(item, true); } }
public void SetProjectile(MapProjectile proj) { Projectile = proj; if (Start == 0 && End == 0) { End = Projectile.Class.Phases - 1; } }
private void CreateProjectile(AllodsProjectile proj) { MapProjectile p = new MapProjectile(proj, Unit); p.ZOffset = 64; MapLogic.Instance.AddObject(p, true); Indicators.Add(p); }
public static void SpawnProjectileEOT(int id, IPlayerPawn source, float x, float y, float z, int duration, int frequency, int startframes = 0, int endframes = 0, int zoffs = -128, MapProjectileCallback cb = null) { MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicEOT(duration, frequency, startframes, endframes), cb); proj.ZOffset = zoffs; proj.SetPosition(x, y, z); MapLogic.Instance.Objects.Add(proj); if (NetworkManager.IsServer) { foreach (ServerClient client in ServerManager.Clients) { if (client.State != ClientState.Playing) { continue; } Player p = MapLogic.Instance.GetNetPlayer(client); MapObject sourceObj = (MapObject)source; if (sourceObj != null) { if (!sourceObj.IsVisibleForNetPlayer(p)) { ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit } } ClientCommands.AddProjectileEOT app; app.X = x; app.Y = y; app.Z = z; app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object; if (app.SourceType == MapObjectType.Human || app.SourceType == MapObjectType.Monster) { app.SourceTag = ((MapUnit)sourceObj).Tag; } else if (app.SourceType == MapObjectType.Structure) { app.SourceTag = ((MapStructure)sourceObj).Tag; } else { app.SourceTag = -1; } app.TypeID = id; app.Duration = duration; app.StartFrames = startframes; app.EndFrames = endframes; app.ZOffset = zoffs; client.SendCommand(app); } } }
public static void SpawnProjectileDirectional(int id, IPlayerPawn source, float x, float y, float z, float tgx, float tgy, float tgz, float speed, MapProjectileCallback cb = null) { MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicDirectional(tgx, tgy, tgz, speed), cb); proj.SetPosition(x, y, z); MapLogic.Instance.Objects.Add(proj); // todo notify clients if (NetworkManager.IsServer) { foreach (ServerClient client in ServerManager.Clients) { if (client.State != ClientState.Playing) { continue; } Player p = MapLogic.Instance.GetNetPlayer(client); MapObject sourceObj = (MapObject)source; if (sourceObj != null) { if (!sourceObj.IsVisibleForNetPlayer(p)) { ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit } } ClientCommands.AddProjectileDirectional app; app.X = x; app.Y = y; app.Z = z; app.TargetX = tgx; app.TargetY = tgy; app.TargetZ = tgz; app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object; if (app.SourceType == MapObjectType.Human || app.SourceType == MapObjectType.Monster) { app.SourceTag = ((MapUnit)sourceObj).Tag; } else if (app.SourceType == MapObjectType.Structure) { app.SourceTag = ((MapStructure)sourceObj).Tag; } else { app.SourceTag = -1; } app.Speed = speed; app.TypeID = id; client.SendCommand(app); } } }
public static void SpawnProjectileSimple(int id, IPlayerPawn source, float x, float y, float z, float animspeed = 0.5f, float scale = 1f, int start = 0, int end = 0) { MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicSimple(animspeed, scale, start, end), null); // this is usually SFX like stuff. projectile plays animation based on typeid and stops. proj.SetPosition(x, y, z); MapLogic.Instance.Objects.Add(proj); if (NetworkManager.IsServer) { foreach (ServerClient client in ServerManager.Clients) { if (client.State != ClientState.Playing) { continue; } Player p = MapLogic.Instance.GetNetPlayer(client); MapObject sourceObj = (MapObject)source; if (sourceObj != null) { if (!sourceObj.IsVisibleForNetPlayer(p)) { ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit } } ClientCommands.AddProjectileSimple app; app.X = x; app.Y = y; app.Z = z; app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object; if (app.SourceType == MapObjectType.Human || app.SourceType == MapObjectType.Monster) { app.SourceTag = ((MapUnit)sourceObj).Tag; } else if (app.SourceType == MapObjectType.Structure) { app.SourceTag = ((MapStructure)sourceObj).Tag; } else { app.SourceTag = -1; } app.TypeID = id; app.AnimSpeed = animspeed; app.Scale = scale; app.Start = start; app.End = end; client.SendCommand(app); } } }
public static void SpawnProjectileLightning(IPlayerPawn source, float x, float y, float z, MapUnit target, int color, MapProjectileCallback cb = null) { MapProjectile proj = new MapProjectile(AllodsProjectile.Lightning, source, new MapProjectileLogicLightning(target, color), cb); proj.SetPosition(x, y, z); MapLogic.Instance.Objects.Add(proj); if (NetworkManager.IsServer) { foreach (ServerClient client in ServerManager.Clients) { if (client.State != ClientState.Playing) { continue; } Player p = MapLogic.Instance.GetNetPlayer(client); MapObject sourceObj = (MapObject)source; if (sourceObj != null) { if (!sourceObj.IsVisibleForNetPlayer(p)) { ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit } } ClientCommands.AddProjectileLightning app; app.X = x; app.Y = y; app.Z = z; app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object; if (app.SourceType == MapObjectType.Human || app.SourceType == MapObjectType.Monster) { app.SourceTag = ((MapUnit)sourceObj).Tag; } else if (app.SourceType == MapObjectType.Structure) { app.SourceTag = ((MapStructure)sourceObj).Tag; } else { app.SourceTag = -1; } app.TargetTag = target.Tag; app.Color = color; client.SendCommand(app); } } }
public void SetProjectile(MapProjectile proj) { if (Projectile != null && Target != null) { Target.TargetedBy.Remove(Projectile); } Projectile = proj; if (Target != null) { Target.TargetedBy.Add(proj); } }
public void AddMapProjectile(MapProjectile projectile, bool addToMap = true) { Entity entity = Entity.CreateInstance(GameState.Instance.EntityManager); entity.GetTransform().Parent = this.Parent.GetTransform(); new ProjectileComponent(entity, projectile); ProjectileEntites.Add(entity); if (addToMap) { _mapInstance.AddMapProjectile(projectile); } }
public override void Process() { Timer++; float zatUnit = MapLogic.Instance.GetHeightAt(Unit.X + Unit.FracX + (float)Unit.Width / 2, Unit.Y + Unit.FracY + (float)Unit.Height / 2, Unit.Width, Unit.Height) / 32; float heightOffset = Mathf.Max(1, ((Unit.Width + Unit.Height) / 4f)); float shieldRadius = 0.5f * Mathf.Max(1, ((Unit.Width + Unit.Height) / 2f)); float shieldHeight = 0.6f * heightOffset; Vector3 initialPos = new Vector3(Unit.X + Unit.FracX + Unit.Width / 2f, Unit.Y + Unit.FracY + Unit.Height / 2f, 0.1f * heightOffset + zatUnit); for (int j = 0; j < 2; j++) { for (int i = 0; i < Scalar * 16; i++) { MapProjectile item = Grid[i + Scalar * 16 * j]; Vector3 particlePos = new Vector3(0, 0, 1); Vector3 pos = Quaternion.Euler(0, 0, Timer * 2 + 90 * j) * Quaternion.Euler(0, i * 360 / (Scalar * 16), 0) * particlePos; item.SetPosition(pos.x * shieldRadius + initialPos.x, pos.y * shieldRadius + initialPos.y, pos.z * shieldHeight + initialPos.z); item.ZOffset = -64; if (Unit.IsFlying) { item.ZOffset += 128; } item.CurrentFrame = 2 + Mathf.RoundToInt((1f - Mathf.Abs(pos.z)) * 2); item.ZAbsolute = true; item.DoUpdateView = true; } } for (int j = 0; j < 2; j++) { for (int i = 0; i < Scalar * 16; i++) { MapProjectile item = Circles[i + Scalar * 16 * j]; Vector3 particlePos = new Vector3(0, 1, 0); Vector3 pos = Quaternion.Euler(0, 0, i * 360 / (Scalar * 16)) * Quaternion.Euler(Timer * 2 + 180 * j, 0, 0) * particlePos; item.SetPosition(pos.x * shieldRadius + initialPos.x, pos.y * shieldRadius + initialPos.y, pos.z * shieldHeight + initialPos.z); item.ZOffset = -64; if (Unit.IsFlying) { item.ZOffset += 128; } item.CurrentFrame = 2 + Mathf.RoundToInt((1f - Mathf.Abs(pos.z)) * 2); item.ZAbsolute = true; item.DoUpdateView = true; } } }
public void OnUpdateMapProjectile(MapProjectile mapProjectile, int index) { if (mapProjectile.Changed) { ServerCommand serverCommand = new ServerCommand(ServerCommand.CommandType.UpdateProjectile); serverCommand.SetParameter("MapID", _mapID); serverCommand.SetParameter("ProjectileID", index); serverCommand.SetParameter("RealX", mapProjectile.Position.X); serverCommand.SetParameter("RealY", mapProjectile.Position.Y); serverCommand.SetParameter("OnBridge", mapProjectile.OnBridge); serverCommand.SetParameter("Destroyed", mapProjectile.Destroyed); for (int i = 0; i < _clients.Count; i++) { _clients[i].AddServerCommand(serverCommand); } } }
public void OnAddMapProjectile(MapProjectile mapProjectile, int index) { ServerCommand command = new ServerCommand(ServerCommand.CommandType.AddProjectile); command.SetParameter("MapID", _mapID); command.SetParameter("DataID", mapProjectile.ProjectileID); command.SetParameter("RealX", mapProjectile.Position.X); command.SetParameter("RealY", mapProjectile.Position.Y); command.SetParameter("VelocityX", mapProjectile.Velocity.X); command.SetParameter("VelocityY", mapProjectile.Velocity.Y); command.SetParameter("Direction", (int)mapProjectile.Direction); command.SetParameter("OnBridge", mapProjectile.OnBridge); for (int i = 0; i < _clients.Count; i++) { _clients[i].AddServerCommand(command); } }
// check if next node is dangerous. used in step-by-step pathfinding to detect that we need to recheck with dynamic mode public bool CheckDangerous(int x, int y) { for (int ly = y; ly < y + Unit.Height; ly++) { for (int lx = x; lx < x + Unit.Width; lx++) { MapNode node = MapLogic.Instance.Nodes[lx, ly]; foreach (MapObject mobj in node.Objects) { if (!(mobj is MapProjectile)) { continue; } MapProjectile proj = (MapProjectile)mobj; // now some magic ;) if (proj.Class == null) { continue; } switch ((AllodsProjectile)proj.Class.ID) { case AllodsProjectile.FireWall: if (Unit.Stats.ProtectionFire != 100) { return(true); } break; case AllodsProjectile.PoisonCloud: case AllodsProjectile.Blizzard: if (Unit.Stats.ProtectionWater != 100) { return(true); } break; } } } } return(false); }
public override void OnEnable() { Scalar = (Unit.Width + Unit.Height) / 2; if (Scalar < 1) { Scalar = 1; } for (int i = 0; i < Scalar * 16 * 2; i++) { MapProjectile item = new MapProjectile(AllodsProjectile.Shield, Unit); MapLogic.Instance.AddObject(item, true); Grid.Add(item); } for (int i = 0; i < Scalar * 16 * 2; i++) { MapProjectile item = new MapProjectile(AllodsProjectile.Shield, Unit); MapLogic.Instance.AddObject(item, true); Circles.Add(item); } }
public ProjectileComponent(Entity entity, MapProjectile projectile) : base(entity) { SetProjectile(projectile); }
public static MapPacket FromBytes(byte[] bytes) { using (MemoryStream stream = new MemoryStream(bytes)) { byte[] tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int mapID = BitConverter.ToInt32(tempBytes, 0); stream.Read(tempBytes, 0, sizeof(int)); int dataSize = BitConverter.ToInt32(tempBytes, 0); tempBytes = new byte[dataSize]; stream.Read(tempBytes, 0, dataSize); MapPacket mapPacket = new MapPacket(mapID, MapData.FromBytes(tempBytes)); //add in the map players here tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int enemiesCount = BitConverter.ToInt32(tempBytes, 0); for (int i = 0; i < enemiesCount; i++) { tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int size = BitConverter.ToInt32(tempBytes, 0); tempBytes = new byte[size]; stream.Read(tempBytes, 0, size); MapEnemy enemy = MapEnemy.FromBytes(tempBytes); mapPacket.Enemies.Add(enemy); } tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int projectilesCount = BitConverter.ToInt32(tempBytes, 0); for (int i = 0; i < projectilesCount; i++) { tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int size = BitConverter.ToInt32(tempBytes, 0); tempBytes = new byte[size]; stream.Read(tempBytes, 0, size); MapProjectile projectile = MapProjectile.FromBytes(tempBytes); mapPacket.Projectiles.Add(projectile); } tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int itemsCount = BitConverter.ToInt32(tempBytes, 0); for (int i = 0; i < itemsCount; i++) { tempBytes = new byte[sizeof(int)]; stream.Read(tempBytes, 0, sizeof(int)); int size = BitConverter.ToInt32(tempBytes, 0); tempBytes = new byte[size]; stream.Read(tempBytes, 0, size); MapItem item = MapItem.FromBytes(tempBytes); mapPacket.Items.Add(item); } return(mapPacket); } }
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); } int ballDamage = Spell.GetDamage(); // here SpawnProjectile is basically duplicated. except some functions that aren't needed. // following offsets are based on unit's width, height and center float tX, tY; tX = TargetX + 0.5f; tY = TargetY + 0.5f; float cX, cY; if (Spell.User != null) { cX = Spell.User.X + Spell.User.Width * 0.5f + Spell.User.FracX; cY = Spell.User.Y + Spell.User.Height * 0.5f + Spell.User.FracY; Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Spell.User.Width + Spell.User.Height) / 2) / 1.5f; cX += dir.x; cY += dir.y; } else { cX = tX; cY = tY; } Server.SpawnProjectileDirectional(AllodsProjectile.FireBall, Spell.User, cX, cY, 0, tX, tY, 0, 10, (MapProjectile fproj) => { //Debug.LogFormat("spell projectile hit!"); // done, make damage DamageFlags spdf = SphereToDamageFlags(Spell); if (Spell.Item == null) { spdf |= DamageFlags.AllowExp; } // spawn explosion. serverside, since projectile hit callback is serverside as well. Server.SpawnProjectileSimple(AllodsProjectile.Explosion, null, fproj.ProjectileX, fproj.ProjectileY, fproj.ProjectileZ); // apply damage over 3x3 cells around the fireball for (int y = fproj.Y - 1; y <= fproj.Y + 1; y++) { for (int x = fproj.X - 1; x <= fproj.X + 1; x++) { if (x < 0 || y < 0 || x >= MapLogic.Instance.Width || y >= MapLogic.Instance.Height) { continue; } int dmg = (int)((2f - (new Vector2(x - fproj.X, y - fproj.Y).magnitude)) * ballDamage); // damage in the center is approximately 1.4 or 1.6 MapNode node = MapLogic.Instance.Nodes[x, y]; 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 - fproj.ProjectileX, mp.ProjectileY - fproj.ProjectileY).magnitude > 1.5f) { continue; } mp.Dispose(); i--; continue; } else { IVulnerable mov = (IVulnerable)mo; mov.TakeDamage(spdf, Spell.User, dmg); } } } } fproj.Dispose(); }); return(false); }
public void SetProjectile(MapProjectile proj) { Projectile = proj; }
public override void Process() { if (Unit.Flags != LastFlags) { UnitFlags leftFlags = Unit.Flags; // remove unused projectiles for (int i = 0; i < Indicators.Count; i++) { UnitFlags flag = 0; switch (Indicators[i].ClassID) { case AllodsProjectile.ProtectionFire: flag = UnitFlags.ProtectionFire; break; case AllodsProjectile.ProtectionWater: flag = UnitFlags.ProtectionWater; break; case AllodsProjectile.ProtectionAir: flag = UnitFlags.ProtectionAir; break; case AllodsProjectile.ProtectionEarth: flag = UnitFlags.ProtectionEarth; break; } if ((Unit.Flags & flag) == 0) { Indicators[i].Dispose(); i--; continue; } else { leftFlags &= ~flag; } } if (leftFlags.HasFlag(UnitFlags.ProtectionAir)) { CreateProjectile(AllodsProjectile.ProtectionAir); } if (leftFlags.HasFlag(UnitFlags.ProtectionWater)) { CreateProjectile(AllodsProjectile.ProtectionWater); } if (leftFlags.HasFlag(UnitFlags.ProtectionEarth)) { CreateProjectile(AllodsProjectile.ProtectionEarth); } if (leftFlags.HasFlag(UnitFlags.ProtectionFire)) { CreateProjectile(AllodsProjectile.ProtectionFire); } LastFlags = Unit.Flags; } for (int i = 0; i < Indicators.Count; i++) { float indicatorAngle = (Mathf.PI * 2) / Indicators.Count * i + Mathf.PI * 0.5f; MapProjectile p = Indicators[i]; float pX = -Mathf.Cos(indicatorAngle) * 0.25f; float pY = Mathf.Sin(indicatorAngle) * 0.25f; if (Indicators.Count == 1) { pY = -pY; } float pZ = MapLogic.Instance.GetHeightAt(Unit.X + Unit.FracX, Unit.Y + Unit.FracY, Unit.Width, Unit.Height) / 32 + (1f + (((Unit.Width + Unit.Height) / 2f) - 1f) / 2f); p.Alpha = (Unit.GetVisibility() == 2) ? 1f : 0; p.SetPosition(Unit.X + Unit.FracX + Unit.Width / 2f + pX, Unit.Y + Unit.FracY + Unit.Height / 2f + pY, pZ); p.ZAbsolute = true; p.ZOffset = -32; if (Unit.IsFlying) { p.ZOffset += 128; } p.CurrentFrame = (p.CurrentFrame + 1) % p.Class.Phases; p.DoUpdateView = true; } }
public virtual bool Update() { // calculate target direction! // check if target is gone if (Target != null && (!Target.IsAlive || !Target.IsLinked)) { Target = null; } Projectile.Alpha = 0; if (Target != null && SubProjectiles.Count <= 0) { // special magic for lightning Projectile.LightLevel = 256; TargetCenter = new Vector2(Target.X + (float)Target.Width / 2 + Target.FracX, Target.Y + (float)Target.Height / 2 + Target.FracY); TargetAngle = Projectile.Angle = MapObject.FaceVector(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY); TargetDir = new Vector2(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY); TargetDst = TargetDir.magnitude; TargetDir.Normalize(); // spawn projectiles along the way Density = 0.2f; for (float i = 0; i < TargetDst; i += Density) { MapProjectile visProj = new MapProjectile(Color == 0 ? AllodsProjectile.Lightning : AllodsProjectile.ChainLightning); visProj.LightLevel = 0; visProj.CurrentFrame = Color == 0 ? 0 : (5 * (Color - 1)); visProj.SetPosition(Projectile.ProjectileX + TargetDir.x * i, Projectile.ProjectileY + TargetDir.y * i, 0); // for now MapLogic.Instance.Objects.Add(visProj); SubProjectiles.Add(visProj); } Projectile.CallCallback(); } AnimTime += 0.08f; float hUDiff = MapLogic.Instance.GetHeightAt(TargetCenter.x, TargetCenter.y, 1, 1) / 32f; float htOrig = MapLogic.Instance.GetHeightAt(Projectile.ProjectileX, Projectile.ProjectileY, 1, 1) / 32f; float angleToDst = Mathf.Atan2(TargetDir.y, TargetDir.x); float sinScale = TargetDst / 8 * Mathf.Sin((float)MapLogic.Instance.LevelTime / 2 * TargetDst); Vector2 offs = new Vector2(0, 1); float sinX = Mathf.Cos(angleToDst) * offs.x - Mathf.Sin(angleToDst) * offs.y; float sinY = Mathf.Cos(angleToDst) * offs.y + Mathf.Sin(angleToDst) * offs.x; for (int i = 0; i < SubProjectiles.Count; i++) { float idst = Density * i; // get angle from first to second. calculate sin wave float baseX = Projectile.ProjectileX + TargetDir.x * idst; float baseY = Projectile.ProjectileY + TargetDir.y * idst; float sscale = (Sin10(idst / TargetDst) * sinScale); MapProjectile sub = SubProjectiles[i]; int cframe = (Color == 0 ? 0 : (5 * (Color - 1))); sub.CurrentFrame = (int)(cframe + 4 * AnimTime); sub.LightLevel = 0; if (i % 12 == 0) { sub.LightLevel = (int)(512 * (1f - AnimTime)); } float htDiff = MapLogic.Instance.GetHeightAt(baseX + sinX * sscale, baseY + sinY * sscale, 1, 1) / 32f; float lval = (float)i / SubProjectiles.Count; float htLerp = hUDiff * lval + htOrig * (1f - lval); sub.SetPosition(baseX + sinX * sscale, baseY + sinY * sscale, -htDiff + htLerp); } if (AnimTime > 1) { foreach (MapProjectile sub in SubProjectiles) { sub.Dispose(); } Projectile.Dispose(); return(false); } return(true); }
public void OnRemoveMapProjectile(MapProjectile mapProjectile, int index) { }
private void RecieveServerCommand() { byte[] bytes = ReadData(sizeof(int), _networkStream); int packetSize = BitConverter.ToInt32(bytes, 0); bytes = ReadData(packetSize, _networkStream); ServerCommand command = ServerCommand.FromBytes(bytes); int eventID; int enemyID; int enemyIndex; int mapID; int mapX; int mapY; float realX; float realY; FacingDirection direction; MapData map; int projectileID; int playerID; string playerName; int itemIndex; int itemID; int count; switch (command.GetCommandType()) { case ServerCommand.CommandType.Disconnect: this.Disconnect(); Console.WriteLine("Server Disconnected"); break; case ServerCommand.CommandType.ShowMessage: if (_messageBox == null) { _messageBox = new MessageBox((string)command.GetParameter("Message"), _gameState, false); _gameState.AddControl(_messageBox); } break; case ServerCommand.CommandType.ShowOptions: if (_messageBox == null) { string message = (string)command.GetParameter("Message"); _messageBox = new MessageBox(message, _gameState, false); string[] options = ((string)command.GetParameter("Options")).Split(','); for (int i = 0; i < options.Length; i++) { _messageBox.AddOption(options[i]); } _messageBox.SetSelectedOption(0); _gameState.AddControl(_messageBox); } break; case ServerCommand.CommandType.AddMapEnemy: enemyID = (int)command.GetParameter("EnemyID"); mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { mapX = (int)command.GetParameter("MapX"); mapY = (int)command.GetParameter("MapY"); bool onBridge = (bool)command.GetParameter("OnBridge"); MapEnemy mapEnemy = new MapEnemy(enemyID, mapX, mapY, onBridge); MapComponent.Instance.AddMapEnemy(mapEnemy); } break; case ServerCommand.CommandType.UpdateMapEnemy: enemyIndex = (int)command.GetParameter("EnemyIndex"); mapID = (int)command.GetParameter("MapID"); if ((_gameState.MapEntity.FindComponent <MapComponent>()).GetMapInstance().GetMapPacket().MapID == mapID) { int HP = (int)command.GetParameter("HP"); mapX = (int)command.GetParameter("MapX"); mapY = (int)command.GetParameter("MapY"); realX = (float)command.GetParameter("RealX"); realY = (float)command.GetParameter("RealY"); direction = (FacingDirection)command.GetParameter("Direction"); bool onBridge = (bool)command.GetParameter("OnBridge"); bool dead = (bool)command.GetParameter("Dead"); MapEnemyComponent enemyComponent = MapComponent.Instance.EnemyEntites[enemyIndex].FindComponent <MapEnemyComponent>(); enemyComponent.UpdateMapEnemy(HP, mapX, mapY, realX, realY, direction, onBridge, dead); if (dead) { MapComponent.Instance.EnemyEntites[enemyIndex].Destroy(); MapComponent.Instance.EnemyEntites.RemoveAt(enemyIndex); MapComponent.Instance.GetMapInstance().RemoveMapEnemy(enemyIndex); } } break; case ServerCommand.CommandType.UpdateMapEvent: eventID = (int)command.GetParameter("EventID"); mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { mapX = (int)command.GetParameter("MapX"); mapY = (int)command.GetParameter("MapY"); realX = (float)command.GetParameter("RealX"); realY = (float)command.GetParameter("RealY"); direction = (FacingDirection)command.GetParameter("Direction"); bool onBridge = (bool)command.GetParameter("OnBridge"); map = _gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapData(); if (map != null) { map.GetMapEvent(eventID).MapX = mapX; map.GetMapEvent(eventID).MapY = mapY; map.GetMapEvent(eventID).RealX = realX; map.GetMapEvent(eventID).RealY = realY; map.GetMapEvent(eventID).EventDirection = direction; map.GetMapEvent(eventID).OnBridge = onBridge; } } break; case ServerCommand.CommandType.ChangeMapEventDirection: eventID = (int)command.GetParameter("EventID"); mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { direction = (FacingDirection)command.GetParameter("Direction"); map = _gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapData(); if (map != null) { map.GetMapEvent(eventID).EventDirection = direction; } } break; case ServerCommand.CommandType.ChangeMapEventSprite: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { eventID = (int)command.GetParameter("EventID"); int spriteID = (int)command.GetParameter("SpriteID"); _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventSprite(eventID, spriteID); } break; case ServerCommand.CommandType.ChangeMapEventRenderPriority: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { eventID = (int)command.GetParameter("EventID"); RenderPriority priority = (RenderPriority)command.GetParameter("RenderPriority"); _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventRenderPriority(eventID, priority); } break; case ServerCommand.CommandType.ChangeMapEventEnabled: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { eventID = (int)command.GetParameter("EventID"); bool enabled = (bool)command.GetParameter("Enabled"); _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventEnabled(eventID, enabled); } break; case ServerCommand.CommandType.AddProjectile: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { { int dataID = (int)command.GetParameter("DataID"); realX = (float)command.GetParameter("RealX"); realY = (float)command.GetParameter("RealY"); direction = (FacingDirection)command.GetParameter("Direction"); bool onBridge = (bool)command.GetParameter("OnBridge"); MapProjectile projectile = new MapProjectile(dataID, CharacterType.Player, -1, new Vector2(realX, realY), direction); projectile.OnBridge = onBridge; MapComponent.Instance.AddMapProjectile(projectile); } } break; case ServerCommand.CommandType.UpdateProjectile: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { projectileID = (int)command.GetParameter("ProjectileID"); if (projectileID < MapComponent.Instance.ProjectileEntites.Count) { realX = (float)command.GetParameter("RealX"); realY = (float)command.GetParameter("RealY"); bool onBridge = (bool)command.GetParameter("OnBridge"); bool destroyed = (bool)command.GetParameter("Destroyed"); ProjectileComponent component = MapComponent.Instance.ProjectileEntites[projectileID].FindComponent <ProjectileComponent>(); component.SetRealPosition(realX, realY); component.SetOnBridge(onBridge); if (destroyed) { MapComponent.Instance.ProjectileEntites[projectileID].Destroy(); MapComponent.Instance.ProjectileEntites.RemoveAt(projectileID); MapComponent.Instance.GetMapInstance().RemoveMapProjectile(projectileID); } } } break; case ServerCommand.CommandType.AddMapItem: mapID = (int)command.GetParameter("MapID"); MapComponent mapComponent = _gameState.MapEntity.FindComponent <MapComponent>(); if (mapComponent.GetMapInstance().GetMapPacket().MapID == mapID) { itemID = (int)command.GetParameter("ItemID"); count = (int)command.GetParameter("Count"); mapX = (int)command.GetParameter("MapX"); mapY = (int)command.GetParameter("MapY"); playerID = (int)command.GetParameter("PlayerID"); bool onBridge = (bool)command.GetParameter("OnBridge"); MapItem mapItem = new MapItem(itemID, count, mapX, mapY, playerID, onBridge); MapComponent.Instance.AddMapItem(mapItem); } break; case ServerCommand.CommandType.RemoveMapItem: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { itemIndex = (int)command.GetParameter("ItemIndex"); if (itemIndex < MapComponent.Instance.MapItemEntities.Count) { MapComponent.Instance.MapItemEntities[itemIndex].Destroy(); MapComponent.Instance.MapItemEntities.RemoveAt(itemIndex); MapComponent.Instance.GetMapInstance().RemoveMapItem(itemIndex); } } break; case ServerCommand.CommandType.UpdateMapItem: mapID = (int)command.GetParameter("MapID"); if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID) { itemIndex = (int)command.GetParameter("ItemIndex"); if (itemIndex < MapComponent.Instance.MapItemEntities.Count) { playerID = (int)command.GetParameter("PlayerID"); count = (int)command.GetParameter("Count"); MapComponent.Instance.MapItemEntities[itemIndex].FindComponent <MapItemComponent>().GetMapItem().PlayerID = playerID; MapComponent.Instance.MapItemEntities[itemIndex].FindComponent <MapItemComponent>().GetMapItem().Count = count; } } break; case ServerCommand.CommandType.ShowShop: int shopID = (int)command.GetParameter("ShopID"); ShopData data = ShopData.GetData(shopID); if (data != null) { if (InventoryPanel.Instance == null) { GameState.Instance.ToggleInventory(); } _gameState.AddControl(new GUI.ShopPanel(_gameState, data)); } else { AddClientCommand(new ClientCommand(ClientCommand.CommandType.CloseShop)); } break; case ServerCommand.CommandType.TradeRequest: playerID = (int)command.GetParameter("PlayerID"); playerName = (string)command.GetParameter("PlayerName"); MessagePanel.Instance.AddMessage(playerName + " would like to trade."); break; case ServerCommand.CommandType.StartTrade: playerID = (int)command.GetParameter("PlayerID"); playerName = (string)command.GetParameter("PlayerName"); if (InventoryPanel.Instance == null) { GameState.Instance.ToggleInventory(); } _gameState.AddControl(new GUI.TradePanel(_gameState, playerID, playerName)); break; case ServerCommand.CommandType.AcceptTrade: if (TradePanel.Instance != null) { TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = true; } break; case ServerCommand.CommandType.EndTrade: if (TradePanel.Instance != null) { TradePanel.Instance.Close(); } break; case ServerCommand.CommandType.AddTradeItem: itemID = (int)command.GetParameter("ItemID"); count = (int)command.GetParameter("Count"); if (TradePanel.Instance != null) { TradePanel.Instance.TradeRequest.TradeOffer2.AddItem(itemID, count); TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false; TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false; } break; case ServerCommand.CommandType.RemoveTradeItem: itemIndex = (int)command.GetParameter("ItemIndex"); count = (int)command.GetParameter("Count"); if (TradePanel.Instance != null) { TradePanel.Instance.TradeRequest.TradeOffer2.RemoveItem(itemIndex, count); TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false; TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false; } break; case ServerCommand.CommandType.CantTrade: if (TradePanel.Instance != null) { TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false; TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false; } break; case ServerCommand.CommandType.OpenBank: if (InventoryPanel.Instance == null) { GameState.Instance.ToggleInventory(); } _gameState.AddControl(new BankPanel(_gameState)); break; case ServerCommand.CommandType.ShowWorkbench: int workbenchID = (int)command.GetParameter("WorkbenchID"); if (InventoryPanel.Instance == null) { GameState.Instance.ToggleInventory(); } _gameState.AddControl(new GUI.WorkbenchPanel(_gameState, workbenchID)); break; } }
private void SetProjectile(MapProjectile projectile) { _projectile = projectile; _data = ProjectileData.GetProjectileData(projectile.ProjectileID); SetRealPosition(_projectile.Position.X, _projectile.Position.Y); }
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 void OnEnable() { Indicator = new MapProjectile(AllodsProjectile.PoisonSign, Unit); Indicator.ZOffset = 64; MapLogic.Instance.Objects.Add(Indicator); }