public static void Heal(IVulnerable target, float amount) { target.Health += amount; if (target.Health < target.HealthMax) { target.Health = target.HealthMax; } }
//IVulnerable Functions //See IVulnerable.cs public static void Injure(IVulnerable target, float amount) { target.Health -= amount; if (target.Health <= 0) { target.Kill(); } }
//When the Seeker collides with another physics object, if that object has the Player tag it injures the target and destroys itself. //Uses IVulnerable mechanics void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.tag == "Player") { IVulnerable target = other.GetComponent("IVulnerable") as IVulnerable; target.Injure(damage); Kill(); } }
//When the spikes detect a collision, it attempts to exectute the target's Kill method. //If the target is not an IVulnerable object, the script does nothing. private void OnCollisionEnter2D(Collision2D collision) { IVulnerable target = collision.gameObject.GetComponent("IVulnerable") as IVulnerable; if (target != null) { target.Kill(); } }
public virtual void OnTriggerEnter(Collider other) { print(other.name); IDamager dmg = other.GetComponent <IDamager>(); if (dmg != null) { BeDamaged(dmg); } IVulnerable v = other.GetComponent <IVulnerable>(); if (v != null) { v.BeDamaged(this); } }
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()); }
protected override void OnEntityEnteredRange(IVulnerable e) { var spirit = e as SpiritSystem; var spiritAttackSpeed = spirit.Data.Get(Enums.Spirit.AttackSpeed); var removedAttackSpeedMod = (int)spiritAttackSpeed.Sum.GetPercent(effect.SlowPercent); if (spirit.CountOf(EffectData) <= 0) { spiritAttackSpeed.AppliedValue -= removedAttackSpeedMod; } else { removedAttackSpeedMod = (int)(spiritAttackSpeed.Sum - effect.SlowPercent).GetPercent(effect.SlowPercent); } spirit.AddEffect(EffectData); removedAttackSpeedMods.Add(spirit, removedAttackSpeedMod); }
//OnTriggerEnter2D //Handles collision event, checking for a valid collision //Only interacts with specified target type. Used IVulnerable and ISpeedMod for effects. //Effect depends on chosen Effect enum. //Will destroy the missile after impact if destroyOnImpact is true. void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.tag == hitTag) { //Applies effect based on selected effect type. //Note: Incompatable effects (hitting a non-ISpeedMod target with a slow) will still trigger here, but will fail. switch (effect) { case EffectType.None: Debug.Log("Hit " + other); break; case EffectType.Damage: IVulnerable damageTarget = other.GetComponent("IVulnerable") as IVulnerable; damageTarget.Injure(effectAmount); break; case EffectType.Slow: ISpeedMod speedTarget = other.GetComponent("ISpeedMod") as ISpeedMod; speedTarget.SpeedDecrease(effectAmount); break; default: Debug.Log("Effeect not found " + effect); break; } //Destroys the target if set to destroyOnImpact. Otherwise projectile will destroy after missileLifespan. if (destroyedOnImpact == true) { Destroy(gameObject); if (deathEmission != null) { Instantiate(deathEmission, transform.position, transform.rotation); } } } }
public override bool Process() { if (NetworkManager.IsClient) { return(false); } int ballDamage = 16; // 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); // 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)) { continue; } IVulnerable mov = (IVulnerable)mo; mov.TakeDamage(spdf, Spell.User, dmg); mo.DoUpdateInfo = true; mo.DoUpdateView = true; //Debug.LogFormat("{0} <- {1}", mo, dmg); } } } fproj.Dispose(); MapLogic.Instance.Objects.Remove(fproj); }); return(false); }
/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { // trackers for statically drawn sprites as we move through draw order bool showCraftingMenu = false; bool showStorageMenu = false; ICraftingObject craftObj = null; Storage invStorage = null; Ship playerShip = gameState.player.playerOnShip; List <InventoryItem> invItemsPlayer = gameState.player.inventory; List <InventoryItem> invItemsShip = (gameState.player.playerOnShip == null) ? null : gameState.player.playerOnShip.actionInventory; if (gameState.player.onShip) { invItemsShip = gameState.player.playerOnShip.actionInventory; } // game menu before everything if (startingMenu.showMenu) { startingMenu.DrawInventory(spriteBatchStatic); return; } // draw the interior view if in interior if (gameState.player.playerInInterior != null) { gameState.player.playerInInterior.interiorObjects.Add(gameState.player); GraphicsDevice.SetRenderTarget(lightsTarget); GraphicsDevice.Clear(Color.Black); DrawUtility.DrawSpotLighting(spriteBatchView, this.camera, lightsTarget, gameState.player.playerInInterior.interiorObjects.ToList()); gameState.player.playerInInterior.Draw(spriteBatchView, this.camera, interiorScene); // lighting shader - for ambient day/night light and lanterns GraphicsDevice.SetRenderTarget(null); GraphicsDevice.Clear(Color.White); dayLight.Draw(spriteBatchStatic, interiorScene, lightsTarget); showCraftingMenu = gameState.player.playerInInterior.showCraftingMenu; showStorageMenu = gameState.player.playerInInterior.showStorageMenu; craftObj = gameState.player.playerInInterior.craftObj; invStorage = gameState.player.playerInInterior.invStorage; } // not in interior so draw the game scene else { // setup lightTarget for spot lights GraphicsDevice.SetRenderTarget(lightsTarget); GraphicsDevice.Clear(Color.Black); DrawUtility.DrawSpotLighting(spriteBatchView, this.camera, lightsTarget, DrawOrder); // draw map map.DrawMap(spriteBatchView, spriteBatchStatic, worldScene); // draw treasure locations if any spriteBatchView.Begin(this.camera); foreach (var map in BoundingBoxLocations.treasureLocationsList) { spriteBatchView.Draw(treasureXMark, map.digTileLoc, Color.White); } spriteBatchView.End(); // draw shadows and wakes foreach (var sprite in DrawOrder) { if (sprite is IShadowCaster) { sprite.DrawShadow(spriteBatchView, camera, WeatherState.sunAngleX, WeatherState.shadowTransparency); if (sprite.GetType().BaseType == typeof(Gusto.Models.Animated.Ship)) { Ship ship = (Ship)sprite; ship.shipSail.DrawShadow(spriteBatchView, this.camera, WeatherState.sunAngleX, WeatherState.shadowTransparency); } } if (sprite is IWakes) { IWakes waker = (IWakes)sprite; WakeParticleEngine wpe = waker.GetWakeEngine(); wpe.Draw(spriteBatchView, camera); } } List <Sprite> fliers = new List <Sprite>(); // draw any flyers on top of everything // sort sprites by y cord asc and draw DrawOrder.Sort((a, b) => a.GetBoundingBox().Bottom.CompareTo(b.GetBoundingBox().Bottom)); int i = 0; foreach (var sprite in DrawOrder) { if (sprite is IVulnerable) { IVulnerable v = (IVulnerable)sprite; v.DrawHealthBar(spriteBatchView, camera); } if (sprite is IInventoryItem) { InventoryItem item = (InventoryItem)sprite; if (!item.inInventory) { item.DrawPickUp(spriteBatchView, camera); } } if (sprite is ICraftingObject) { ICraftingObject tcraftObj = (ICraftingObject)sprite; tcraftObj.DrawCanCraft(spriteBatchView, camera); if (tcraftObj.GetShowMenu()) { showCraftingMenu = true; craftObj = tcraftObj; } } if (sprite is IPlaceable) { IPlaceable placeObj = (IPlaceable)sprite; placeObj.DrawCanPickUp(spriteBatchView, camera); } if (sprite is IStructure) { IStructure structure = (IStructure)sprite; structure.DrawNearInterior(spriteBatchView, camera); } if (sprite is IStorage) { Storage storage = (Storage)sprite; storage.DrawOpenStorage(spriteBatchView, camera); if (storage.storageOpen) { showStorageMenu = true; invStorage = storage; } } if (sprite.GetType().BaseType == typeof(Gusto.Models.Animated.Ship)) { Ship ship = (Ship)sprite; if (ship.sinking) { ship.DrawSinking(spriteBatchView, this.camera); ship.shipSail.DrawSinking(spriteBatchView, this.camera); } else { // Draw a ship before its sail and mount ship.Draw(spriteBatchView, this.camera); if (ship.mountedOnShip != null) { foreach (var shot in ship.mountedOnShip.Shots) { shot.Draw(spriteBatchView, this.camera); } if (ship.mountedOnShip.aiming) { ship.mountedOnShip.Draw(spriteBatchView, this.camera); if (ship.teamType == TeamType.Player) { ship.mountedOnShip.DrawAimLine(spriteBatchView, this.camera); } } } ship.shipSail.Draw(spriteBatchView, this.camera); } continue; } else if (sprite.GetType() == typeof(Gusto.AnimatedSprite.PiratePlayer)) { DrawUtility.DrawPlayer(spriteBatchView, this.camera, gameState.player); continue; } else if (sprite.GetType().BaseType == typeof(Gusto.Models.Animated.Npc)) { Npc npc = (Npc)sprite; // flying drawn after everything else if (npc.flying) { fliers.Add(npc); continue; } if (npc.swimming && !npc.onShip) { npc.DrawSwimming(spriteBatchView, this.camera); } else if (!npc.onShip) { npc.Draw(spriteBatchView, this.camera); } if (npc.dying) { npc.DrawDying(spriteBatchView, this.camera); } continue; } else if (sprite.GetType() == typeof(Gusto.AnimatedSprite.BaseTower)) { Tower tower = (Tower)sprite; sprite.Draw(spriteBatchView, this.camera); // draw any shots this tower has in motion foreach (var shot in tower.Shots) { shot.Draw(spriteBatchView, this.camera); } continue; } if (sprite.GetType() == typeof(Gusto.Models.Menus.Inventory) || sprite.GetType() == typeof(Gusto.Models.Menus.CraftingMenu)) { continue; // we handle this after everthing else } sprite.Draw(spriteBatchView, this.camera); } // draw fliers foreach (var flier in fliers) { flier.Draw(spriteBatchView, this.camera); } // draw weather weather.DrawWeather(spriteBatchStatic); // lighting shader - for ambient day/night light and lanterns GraphicsDevice.SetRenderTarget(null); GraphicsDevice.Clear(Color.White); dayLight.Draw(spriteBatchStatic, worldScene, lightsTarget); } // lightning is drawn after ambient light if (WeatherState.lightning) { weather.DrawLightning(spriteBatchStatic); } // draw static and menu sprites windArrows.Draw(spriteBatchStatic, null); if (gameState.player.onShip) { playerShip.DrawAnchorMeter(spriteBatchStatic, new Vector2(1660, 30), anchorIcon); playerShip.DrawRepairHammer(spriteBatchStatic, new Vector2(1600, 30), repairIcon); if (playerShip.msBoarding > 0) { playerShip.DrawBeingBoarded(spriteBatchStatic, new Vector2(1540, 30), boardingIcon); } if (gameState.player.playerInInterior != null) { invItemsShip = null; } } else { invItemsShip = null; } if (gameState.player.showInventory) { inventoryMenu.Draw(spriteBatchStatic, null); inventoryMenu.DrawInventory(spriteBatchStatic, invItemsPlayer, invItemsShip, null); } else if (showCraftingMenu) { craftingMenu.Draw(spriteBatchStatic, null); craftingMenu.DrawInventory(spriteBatchStatic, invItemsPlayer, craftObj); } else if (showStorageMenu) { inventoryMenu.Draw(spriteBatchStatic, null); inventoryMenu.DrawInventory(spriteBatchStatic, invItemsPlayer, invItemsShip, invStorage); } // fps var deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds; _frameCounter.Update(deltaTime); var fps = string.Format("FPS: {0}", _frameCounter.AverageFramesPerSecond); spriteBatchStatic.Begin(); spriteBatchStatic.DrawString(font, fps, new Vector2(10, 10), Color.Green); spriteBatchStatic.End(); base.Draw(gameTime); }
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); }
protected abstract void OnEntityExitRange(IVulnerable entity);
public void Draw(SpriteBatch sb, Camera cam, RenderTarget2D interiorScene) { // Draw the tileset Vector2 minCorner = new Vector2(cam.Position.X - (GameOptions.PrefferedBackBufferWidth / 2), cam.Position.Y - (GameOptions.PrefferedBackBufferHeight / 2)); Vector2 maxCorner = new Vector2(cam.Position.X + (GameOptions.PrefferedBackBufferWidth / 2), cam.Position.Y + (GameOptions.PrefferedBackBufferHeight / 2)); // setup drawing for interior on backbuffer _graphics.SetRenderTarget(interiorScene); _graphics.Clear(Color.Black); startDrawPoint = new Vector2(interiorForObj.location.X - (width / 2), interiorForObj.location.Y - (height / 2)); Vector2 drawPoint = startDrawPoint; interiorTiles.Clear(); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { TilePiece tile = interiorMap[((cols) * i) + j]; if (tile == null) { drawPoint.X += GameOptions.tileWidth * 2; continue; } tile.location = drawPoint; var loc = tile.location; tile.location += speed; tile.inInteriorId = interiorId; // TODO: need to move setting of InteriorId to constructor, but this screws up serialization interiorTiles.Add(tile); if (tile.groundObjects != null) { foreach (var groundObject in tile.groundObjects) { groundObject.location = loc; } } // draw if in viewporit if ((loc.X >= minCorner.X && loc.X <= maxCorner.X) && (loc.Y >= minCorner.Y && loc.Y <= maxCorner.Y)) { tile.Draw(sb, cam); } drawPoint.X += GameOptions.tileWidth * 2; } drawPoint.Y += GameOptions.tileHeight * 2; drawPoint.X = startDrawPoint.X; } // reset these menu trackers showCraftingMenu = false; showStorageMenu = false; craftObj = null; invStorage = null; List <Sprite> drawOrder = interiorObjects.ToList(); drawOrder.Sort((a, b) => a.GetBoundingBox().Bottom.CompareTo(b.GetBoundingBox().Bottom)); // Draw any interior objs foreach (var obj in drawOrder) { // npcs always have random loc set when entering interior, other objects are randomly set initially, unless coming from a save if ((!tilesSet && !(obj is IPlayer) && !interiorWasLoaded) || (obj is INPC && !showingInterior)) { obj.location = RandomInteriorTile().location; } // special draw for player if (obj is IPlayer) { DrawUtility.DrawPlayer(sb, cam, (PiratePlayer)obj); continue; } obj.Draw(sb, cam); if (obj is IVulnerable) { IVulnerable v = (IVulnerable)obj; v.DrawHealthBar(sb, cam); } if (obj is IInventoryItem) { InventoryItem item = (InventoryItem)obj; if (!item.inInventory) { item.DrawPickUp(sb, cam); } } if (obj is IPlaceable) { IPlaceable placeObj = (IPlaceable)obj; placeObj.DrawCanPickUp(sb, cam); } if (obj is ICraftingObject) { ICraftingObject tcraftObj = (ICraftingObject)obj; tcraftObj.DrawCanCraft(sb, cam); if (tcraftObj.GetShowMenu()) { showCraftingMenu = true; craftObj = tcraftObj; } } if (obj is IStorage) { Storage storage = (Storage)obj; storage.DrawOpenStorage(sb, cam); if (storage.storageOpen) { showStorageMenu = true; invStorage = storage; } } } tilesSet = true; showingInterior = true; }
protected override void OnEntityExitRange(IVulnerable e) => RemoveEffect(e as IAppliedEffectsComponent);
private void Awake() { _owner = GetComponent <IVulnerable>(); _model = GetComponent <Model>(); }