private void finishTurn() { world.cameraManager.saveView(team); selectedAnimalActor = null; enterButtonReleased = false; world.endTurn(); }
public Boolean canAttackActor(AnimalActor target) { if (!canAct || target == null) { return(false); } return(true); }
private void ProduceOffspring(AnimalActor parent) { GameTile spawnLocation = FindOpenTile(parent, (world.getTileAt(parent.position) as GameTile)); AnimalActor offspring = (AnimalActor)world.actorFactory.createActor(world.actorFactory.getActorId(parent.actorName), new Vector2(spawnLocation.x, spawnLocation.y)); offspring.teamColor = parent.teamColor; offspring.changeTeam(parent.team); offspring.changeActorSprite(true); world.addActor(offspring); }
/* * Apply any extra effects to the actor from the attacking animal */ public void applyStatusEffect(AnimalActor attacker) { if (attacker.actorName == "Rat") { this.attackDamage = this.poisonAttack; this.defense = this.poisonDefense; this.poisonCount = 4; this.isPoisoned = true; } }
/** * Called when another animalActor fights this animal actor. We are defending. * * Damage Calculation, each AnimalActor attack each other in a fight. * * Damage is attack multiplied by the percent of health we have left of the attacker; * then we subtract the defense of the defender from the damage. * * * TODO: Ranged Attacks? * TODO: Do Checks for what we can attack here. */ private void fight(AnimalActor attacker) { // Get a random number to check if the attack is a critical hit double criticalValue = MirrorEngine.randGen.NextDouble(); double modifiedAttack = attacker.attackDamage; // Check random value against if (criticalValue >= attacker.criticalRange) { modifiedAttack = attacker.attackDamage * 2; applyStatusEffect(attacker); } // Apply damage to defender GameTile currentTile = (GameTile)world.getTileAt(this.position.x, this.position.y); Life.damage(this, (int)Math.Max((modifiedAttack - (this.defense + currentTile.defense)), 0)); // Add explosion to show damage GameActor explosion = new Explosion(world, new Vector2(position.x, position.y + 2), new Vector2(0, 0), 1, new Vector2(2, 2), new Vector2(0, 0), 0); world.addActor(explosion); if (life.dead) { attacker.expPoints += this.spawnCost; checkLevelUp(attacker, this); die(); return; } // Apply retaliation damage to attacker if defender can hit attacker GameTile AttackerTile = (GameTile)world.getTileAt(attacker.position.x, attacker.position.y); if (this.findAttackTiles().Contains(AttackerTile)) { Life.damage(attacker, (int)Math.Max((attackDamage - (attacker.defense + AttackerTile.defense)), 0)); if (attacker.life.dead) { // Add explosion to show damage this.expPoints += attacker.spawnCost; GameActor attackerExplosion = new Explosion(world, new Vector2(attacker.position.x, attacker.position.y + 2), new Vector2(0, 0), 1, new Vector2(2, 2), new Vector2(0, 0), 0); world.addActor(attackerExplosion); checkLevelUp(this, attacker); attacker.die(); return; } } }
public FlyingBehavior(GameWorld world, GameActor actor, AnimalActor carry) : base(world, actor) { sprite = (FlyingSprite)actor; this.carry = carry; if (sprite.plannedPath != null) { path = sprite.plannedPath.GetEnumerator(); path.MoveNext(); sprite.to = new Vector2(path.Current.x, path.Current.y); } }
public void updateStatusEffects(AnimalActor actor) { if (actor.isPoisoned) { if (actor.poisonCount == 0) { actor.attackDamage = actor.baseAttack; actor.defense = actor.baseDefense; actor.isPoisoned = false; return; } actor.poisonCount--; } }
/** * Level up an actor if experience threshold met. Add up to 2 stat points to attack and defense. */ public void checkLevelUp(AnimalActor killer, AnimalActor victim) { if (killer.level == maxLevel) { return; } if (killer.expPoints >= expLevel[killer.level + 1]) { killer.level++; killer.attackDamage += MirrorEngine.randGen.Next(3); killer.defense += MirrorEngine.randGen.Next(3); ProduceOffspring(killer); } }
public override void run() { if (transformReady) { Tile current = world.getTileAt(actor.position); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { Tile checkTile = world.getTile(current.xIndex + i, current.yIndex + j); if (TeamDictionary.TeamDict[team].IsActive && teamValue >= 0 && SPAWN_RANDOM_ACTORS) { AnimalActor newActor = ((GameActorFactory)world.actorFactory).createRandomAnimalActor(new Vector2(checkTile.x, checkTile.y)); GameTile realTile = (GameTile)newActor.FindOpenTile(newActor, checkTile as GameTile); if (realTile != null) { // Move animal to valid position newActor.position.x = realTile.x; newActor.position.y = realTile.y; // Update old position so if a move is cancelled the animal doesn't go back to the invalid position newActor.oldPosition = newActor.position; // Avoid animals flying off of map when moved newActor.velocity = Vector2.Zero; if (newActor != null) { world.addActor(newActor); newActor.teamColor = teamColor; newActor.changeTeam(team); teamValue -= newActor.spawnCost; } } } } } transformReady = false; actor.removeMe = true; } }
public override void startTurn() { movedUnits = new LinkedList <AnimalActor>(); currentUnitCount = units.Count; if (currentUnitCount > 0) { world.cameraManager.moveCamera(units.First().position); } foreach (AnimalActor actor in units) { updateStatusEffects(actor); } System.Console.WriteLine("Number of units for player " + team + ": " + units.Count + "\n"); selectedAnimalActor = null; //world.cameraManager.loadView(team, true); }
public void expandUnits() { IEnumerator <AnimalActor> enu = storage.GetEnumerator(); Tile current = world.getTileAt(units.First.Value.position); LinkedList <Tile> tiles = new LinkedList <Tile>(); tiles.AddFirst(current); AnimalActor currentActor = null; while (tiles.Count != 0 && (currentActor != null || enu.MoveNext())) { if (currentActor == null) { currentActor = enu.Current; } current = tiles.First.Value; tiles.RemoveFirst(); IEnumerator <Tile> tileEnu = current.adjacent.GetEnumerator(); while (tileEnu.MoveNext()) { if (tileEnu.Current != null) { tiles.AddLast(tileEnu.Current); } } AnimalActor a = world.getAnimalOnTile(current); if (a == null && current != null) { enu.Current.position = new Vector2(current.x, current.y); FlyingSprite sprite = new FlyingSprite(world, units.First.Value.position, new Vector2(0, 0), 1, new Vector2(1, 1), Vector2.Zero, 0, enu.Current.position, enu.Current); sprite.anim = enu.Current.anim; world.addActor(enu.Current); enu.Current.removeMe = false; enu.Current.changeTeam(team); world.addActor(sprite); //enu.Current.customDraw = AnimalActor.drawInvisible; currentActor = null; } } }
/* TODO: * What do these functions do? Why do they exist? * It would be very helpful if whoever wrote them also wrote comments. */ public void collapseUnits() { IEnumerator <AnimalActor> enu = units.GetEnumerator(); enu.MoveNext(); AnimalActor first = enu.Current; storage = new LinkedList <AnimalActor>(); while (enu.MoveNext()) { storage.AddFirst(enu.Current); } enu = storage.GetEnumerator(); while (enu.MoveNext()) { enu.Current.die(); FlyingSprite sprite = new FlyingSprite(world, enu.Current.position, new Vector2(0, 0), 1, new Vector2(1, 1), Vector2.Zero, 0, first.position, null); sprite.anim = enu.Current.anim; world.addActor(sprite); } }
/*************************************** Graphics Functions ***************************************/ //Custom draw method for animal actors with health bars. public static void drawWithHealthBar(Actor a) { //Readability vars... AnimalActor aa = (AnimalActor)a; Handle tex = aa.sprite; Vector2 spritePos = aa.position + aa.world2model; Color actorTint = aa.tint * aa.color; GraphicsComponent gcomp = aa.world.engine.graphicsComponent; //Draw the animal's sprite gcomp.drawTex(tex, (int)(spritePos.x + aa.xoffset), (int)(spritePos.y + aa.yoffset), actorTint); //Draw the health bar int hBarW = 32; //TODO: Grab the width of the sprite programmatically int hBarH = hBarW / 8; //Draw the border of the health bar gcomp.drawRect((int)(spritePos.x + aa.xoffset), (int)(spritePos.y + aa.yoffset), hBarW, hBarH, Color.BLACK); //Draw the health hBarW = (int)(hBarW * (aa.life.health / aa.life.maxlife)); gcomp.drawRect((int)(spritePos.x + aa.xoffset + 1), (int)(spritePos.y + aa.yoffset + 1), hBarW - 2, hBarH - 2, aa.teamColor); }
/** * Attacks the target tile, if there is an actor on that tile fight it. */ public Boolean attackTile(Tile target) { AnimalActor animalTarget = world.getAnimalOnTile(target); if (canAttackActor(animalTarget)) { //If adjacent tiles contain the target tile if (findAttackTiles().Contains(target)) { if (this.attackRange > 1) { FlyingSprite sprite = new FlyingSprite(world, this.position, new Vector2(0, 0), 1, new Vector2(1, 1), Vector2.Zero, 0, new Vector2(target.x, target.y)); sprite.anim = new Animation(world.engine.resourceComponent, "Sprites/011_blob/"); world.addActor(sprite); animalTarget.fight(this); } else if (this.movementType.Equals(animalTarget.movementType) || this.movementType.Equals(TileCost.Air)) { List <Tile> hittingAnim = new List <Tile>(); hittingAnim.Add(target); hittingAnim.Add(curTile); FlyingSprite sprite = new FlyingSprite(world, this.position, new Vector2(0, 0), 1, new Vector2(1, 1), Vector2.Zero, 0, new Vector2(curTile.x, curTile.y), this, hittingAnim); sprite.anim = this.anim; world.addActor(sprite); this.customDraw = AnimalActor.drawInvisible; animalTarget.fight(this); } canAct = false; return(true); } } return(false); }
public AnimalActor createRandomAnimalActor(Vector2 position, Vector2 velocity = null, double color = -1) { ResourceComponent rc = this.world.engine.resourceComponent; AnimalActor a = null; int numberOfAnimals = 6; if ((position.x >= 0 && position.x < world.width * Tile.size && position.y >= 0 && position.y < world.height * Tile.size)) { int id = MirrorEngine.randGen.Next(numberOfAnimals); switch (id) { case 0: a = new Rat(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); case 1: a = new TRex(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); case 2: a = new Turtle(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); case 3: a = new Robin(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); case 4: a = new Llama(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); case 5: a = new Penguin(world, position, new Vector2(0, 0), 2, new Vector2(2, 2), new Vector2(0, 0), 0); return(a); } } return(a); }
/* * Searches for available tile to spawn and actor */ public GameTile FindOpenTile(AnimalActor actor, GameTile initialTile) { if (world.getActorOnTile(initialTile) == null && actor.movementType[initialTile.type] != 999) { return(initialTile); } GameTile possibleTile; int yOffset = 0; // Increase the radius of the search square for (int radius = 1; radius < Math.Max(world.width, world.height); radius++) { // Check each tile in the top row of the square if (initialTile.yIndex - radius > 0) { for (int i = -radius; i < radius; i++) { if (initialTile.xIndex + i > 0) { if (initialTile.xIndex + i > world.width) { break; } possibleTile = (world.getTile(initialTile.xIndex + i, initialTile.yIndex - radius) as GameTile); if (world.getActorOnTile(possibleTile) == null && actor.movementType[possibleTile.type] != 999) { return(possibleTile); } } } } else { yOffset = -(initialTile.yIndex - radius); } // Check each tile in the sides of the square for (int sideY = -radius + yOffset; sideY < radius; sideY++) { if (initialTile.xIndex - radius > 0) { possibleTile = (world.getTile(initialTile.xIndex - radius, initialTile.yIndex + sideY) as GameTile); if (possibleTile != null && world.getActorOnTile(possibleTile) == null && actor.movementType[possibleTile.type] != 999) { return(possibleTile); } } if (initialTile.xIndex + radius < world.width) { possibleTile = (world.getTile(initialTile.xIndex + radius, initialTile.yIndex + sideY) as GameTile); if (possibleTile != null && world.getActorOnTile(possibleTile) == null && actor.movementType[possibleTile.type] != 999) { return(possibleTile); } } } // Check each tile in the bottom row of the square if (initialTile.yIndex + radius < world.height) { for (int i = -radius; i < radius; i++) { if (initialTile.xIndex + i < world.width) { break; } possibleTile = (world.getTile(initialTile.xIndex + i, initialTile.yIndex + radius) as GameTile); if (world.getActorOnTile(possibleTile) == null && actor.movementType[possibleTile.type] != 999) { return(possibleTile); } } } } return(null); }
public FlyingSprite(GameWorld world, Vector2 position, Vector2 velocity, float diameter, Vector2 size, Vector2 world2model, int imgIndex, Vector2 to, AnimalActor carry = null, List <Tile> plannedPath = null) : base(world, new Vector2(position.x - (position.x % 32), position.y - (position.y % 32)), velocity, diameter, size, world2model, imgIndex, 10) { this.plannedPath = plannedPath; this.to = to; this.myBehavior = new FlyingBehavior(world, this, carry); }
/*************************************** Team Functions ***************************************/ public void addToTeam(AnimalActor recruit, team_t newTeam) { TeamDictionary.TeamDict[newTeam].ActorList.AddLast(recruit); }
public void poison(AnimalActor victim) { victim.isPoisoned = true; }
public override void Update() { //if (!stashed && world.collapse.isPressed) //{ // collapseUnits(); // stashed = true; //} //if (stashed && world.uncollapse.isPressed) //{ // expandUnits(); // stashed = false; //} CalculateTileFlash(); //System.Console.WriteLine("Number of units in thing " + units.Count + " movedUnits" + movedUnits.Count +"\n"); // End current turn if every animal has moved if (movedUnits.Count == currentUnitCount) { finishTurn(); return; } if (selectedAnimalActor != null) { if (moveRange == null && selectedAnimalActor.canMove) { moveRange = selectedAnimalActor.findPaths(); } IEnumerator <Tile> adjacent = null; if (selectedAnimalActor.canMove) { adjacent = moveRange.GetEnumerator(); while (adjacent.MoveNext()) { if (adjacent.Current != null) { // Change color of ambient light on tiles adjacent.Current.color = moveColor; } } // Don't light up tile that actor is on so player can tell which unit is selected world.getTileAt(selectedAnimalActor.position).color = selectedColor; } if (selectedAnimalActor.canAct && !selectedAnimalActor.canMove) { adjacent = attackRange.GetEnumerator(); while (adjacent.MoveNext()) { if (adjacent.Current != null) { // Change color of ambient light on tiles adjacent.Current.color = atkColor; } } // Don't light up tile that actor is on so player can tell which unit is selected world.getTileAt(selectedAnimalActor.position).color = selectedColor; } } // Reset the move and attack color values else { moveColor = new Color(0, 0, 1); atkColor = new Color(1, 0, 0); } // Handle end turn command if (enter.isPressed) { if (enterButtonReleased) { finishTurn(); return; } } else { enterButtonReleased = true; } if (rightClick.isPressed) { // Animal has moved, return to the old position and cancel attack phase if (selectedAnimalActor != null) { if (selectedAnimalActor.canMove == false) { selectedAnimalActor.position = selectedAnimalActor.oldPosition; selectedAnimalActor.canMove = true; } selectedAnimalActor.anim.ticksPerFrame *= 2; } selectedAnimalActor = null; moveRange = null; } // Handle unit selection through clicks if (click.isPressed) { if (mouseButtonReleased) { mouseButtonReleased = false; // Get position of the mouseclick in pixels Vector2 position = world.engine.graphicsComponent.camera.screen2World(world.engine.inputComponent.getMousePosition()); // Convert position to a multiple of 32 position = new Vector2(position.x - (position.x % 32), position.y - (position.y % 32)); Tile clickedTile = world.getTileAt(position); AnimalActor animalOnTile = world.getAnimalOnTile(clickedTile); if (selectedAnimalActor == null) { if (animalOnTile != null && animalOnTile.canMove == true) { selectedAnimalActor = animalOnTile; selectedAnimalActor.anim.ticksPerFrame /= 2; } } else if (moveRange != null && moveRange.Contains(world.getTileAt(position)) && (animalOnTile == null || animalOnTile == selectedAnimalActor) && selectedAnimalActor.canMove) { selectedAnimalActor.moveTile(world.getTileAt(position)); attackRange = selectedAnimalActor.findAttackTiles(); moveRange = null; //selected = null; } else if (!selectedAnimalActor.canMove && attackRange.Contains(world.getTileAt(position))) { // If an animal is on the attacked tile, attack it (don't allow an animal to attack itself) if (animalOnTile != null && clickedTile != world.getTileAt(selectedAnimalActor.position)) { selectedAnimalActor.attackTile(clickedTile); } // Update all of the attacking animal's variables and add to moved unit list selectedAnimalActor.canAct = false; movedUnits.AddFirst(selectedAnimalActor); selectedAnimalActor.anim.ticksPerFrame *= 2; selectedAnimalActor.changeActorSprite(true); attackRange = null; selectedAnimalActor.oldPosition = selectedAnimalActor.position; selectedAnimalActor = null; } } } else { mouseButtonReleased = true; } if (world.selectLeft.isPressed && (selectedAnimalActor == null || selectedAnimalActor.canMove == true)) { if (selectLeftReleased) { currentAutoselect = (currentAutoselect + 1) % units.Count; while (movedUnits.Contains(units.ElementAt(currentAutoselect))) { currentAutoselect = (currentAutoselect + 1) % units.Count; } moveRange = null; if (selectedAnimalActor != null) { selectedAnimalActor.anim.ticksPerFrame *= 2; } selectedAnimalActor = units.ElementAt(currentAutoselect); selectedAnimalActor.anim.ticksPerFrame /= 2; selectLeftReleased = false; } } else { selectLeftReleased = true; } if (world.selectRight.isPressed && (selectedAnimalActor == null || selectedAnimalActor.canMove == true)) { if (selectRightReleased) { currentAutoselect = (currentAutoselect - 1); if (currentAutoselect < 0) { currentAutoselect = units.Count - 1; } while (movedUnits.Contains(units.ElementAt(currentAutoselect))) { currentAutoselect = (currentAutoselect - 1); if (currentAutoselect < 0) { currentAutoselect = units.Count - 1; } } moveRange = null; if (selectedAnimalActor != null) { selectedAnimalActor.anim.ticksPerFrame *= 2; } selectedAnimalActor = units.ElementAt(currentAutoselect); selectedAnimalActor.anim.ticksPerFrame /= 2; selectRightReleased = false; } } else { selectRightReleased = true; } }