public static bool Wraith(Entity e, TileMap map) { int r = ScreenManager.Rand.Next(500); if (e.State == EntityState.Standing && e.getSpeedX() <= 0) e.setXSpeedPerMs(Entity.SPEED_PER_MS); if (r < 35) { Entity nEntity = map.getNearestEntity(e, e.Rect.Center).Entity; if (nEntity.Rect.Center.X > e.Rect.Center.X) e.setXSpeedPerMs(Entity.SPEED_PER_MS); else e.setXSpeedPerMs(-Entity.SPEED_PER_MS); } else if (r < 60) { e.attack(map, EntityPart.Body, AttackFactory.Iceball); } else if (r < 80) { Entity nEntity = map.getNearestEntity(e, e.Rect.Center).Entity; if (nEntity.Rect.Center.X > e.Rect.Center.X) e.setXSpeedPerMs(Entity.SPEED_PER_MS); else e.setXSpeedPerMs(-Entity.SPEED_PER_MS); } else if (r < 90) { e.setXSpeedPerMs(-e.getSpeedX()); } else if (r < 100) { e.block(); } else if (r < 110) { e.jump(); } else if (r < 120) { e.duck(); } return true; }
public static Attack Raise_Death(Entity e, EntityPart part, TileMap map) { // Static int width = AttackFactory.RAISE_DEATH_WIDTH, height = 8; // Changes based on entity state int x; int y = e.EBounds.Top - (height * 2); float speed = 0.175f; if (e.isFacingForward()) { x = e.EBounds.Right + (AttackFactory.RAISE_DEATH_WIDTH * 5); } else { x = e.EBounds.Left - (AttackFactory.RAISE_DEATH_WIDTH * 5); } return new Attack(map, e, map.GScreen.SprAttack[AttackSpriteId.Raise_Death], new Rectangle(x, y - (height / 2), width, height), (int) (8 * e.Stats.AttackPower), speed, TileMap.SPRITE_SIZE, false); }
public Attack(TileMap map, Entity owner, Texture2D sprite, Rectangle rect, int dmg, float msSpeed, int maxdist, bool horizontal=true) { Owner = owner; this.xp = 0; this.alive = true; this.sprite = sprite; this.drawRect = rect; this.msSpeed = msSpeed; this.horizontal = horizontal; this.dmg = dmg; if (horizontal) { if (msSpeed > 0) { this.collRect = new Rectangle(rect.X, rect.Y, rect.Width - (int) (rect.Width * 0.2), rect.Height); } else { this.collRect = new Rectangle(rect.X + (int) (rect.Width * 0.2), rect.Y, rect.Width - (int) (rect.Width * 0.2), rect.Height); } } else { if (msSpeed > 0) { this.collRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height - (int) (rect.Height * 0.2)); } else { this.collRect = new Rectangle(rect.X, rect.Y + (int) (rect.Height * 0.2), rect.Width, rect.Height - (int) (rect.Height * 0.2)); } } this.maxdist = maxdist; this.distTraveled = 0; // Initial bounds text with all containing tiles int maxX = map.shrinkX(rect.Right, true); int maxY = map.shrinkY(rect.Bottom, true); for (int x = map.shrinkX(rect.Left, false); x <= maxX; x++) { for (int y = map.shrinkY(rect.Top, false); y <= maxY; y++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(rect, wallRect)) { alive = false; break; } } if (!alive) break; } }
public static Attack Scurge_Shot(Entity e, EntityPart part, TileMap map) { // Static int width = 20, height = 8; // Changes based on entity state int x; int y = e.EBounds.getFireFrom(part); float speed = 0.15f; if (e.isFacingForward()) { x = e.EBounds.Right + 1; } else { speed *= -1; x = e.EBounds.Left - width - 1; } return new Attack(map, e, map.GScreen.SprAttack[AttackSpriteId.Scurge_Shot], new Rectangle(x, y - (height / 2), width, height), (int) (8 * e.Stats.AttackPower), speed, 200); }
public static bool Skeleton_King(Entity e, TileMap map) { int r = ScreenManager.Rand.Next(500); if (e.State == EntityState.Standing && e.getSpeedX() <= 0) e.setXSpeedPerMs(Entity.SPEED_PER_MS); if (r < 15) { e["run"] = false; e.setXSpeedPerMs(Math.Sign(e.getSpeedX()) * -1 * Entity.SPEED_PER_MS); } else if (!e.DidMove && e["run"] != null && (bool) e["run"] == true) { // If running and hit wall try to jump over e.jump(); e.setXSpeedPerMs(Math.Sign(e.getSpeedX()) * Entity.SPEED_PER_MS); } else if (r < 150) { NearEntity nEntity = map.getNearestEntity(e, e.Rect.Center); if (nEntity.Distance < AttackFactory.RAISE_DEATH_WIDTH * 3.75) { e["run"] = true; // Too close, run if (nEntity.Entity.Rect.Center.X > e.Rect.Center.X) e.setXSpeedPerMs(-Entity.SPEED_PER_MS); else e.setXSpeedPerMs(Entity.SPEED_PER_MS); } else if (nEntity.Distance < AttackFactory.RAISE_DEATH_WIDTH * 7.25) { e["run"] = false; // Right range, attack if (nEntity.Entity.Rect.Center.X > e.Rect.Center.X) e.setXSpeedPerMs(0.05f); else e.setXSpeedPerMs(-0.05f); e.attack(map, EntityPart.Body, AttackFactory.Raise_Death); } } return true; }
public static bool Basic(Entity e, TileMap map) { // Basic random AI int r = ScreenManager.Rand.Next(500); if (e.State == EntityState.Standing && e.getSpeedX() <= 0) e.setXSpeedPerMs(Entity.SPEED_PER_MS); if (r < 10) { e.setXSpeedPerMs(-e.getSpeedX()); } else if (r < 75) { if (r < 25) e.attack(map, EntityPart.Head, AttackFactory.Scurge_Shot); else if (r < 40) e.attack(map, EntityPart.Body, AttackFactory.Scurge_Shot); else e.attack(map, EntityPart.Legs, AttackFactory.Scurge_Shot); } else if (r < 85) { e.jump(); } else if (r < 95) { e.duck(); } else if (r < 105) { e.block(); } return true; }
private void updateBoundsX(TileMap map, int newX) { if (!isOnFloor && State != EntityState.Jumping) { fallWithGravity(); } else if (newX != bounds.X) { EBounds.moveX(newX - bounds.X); // msVel.X = 0; } }
protected virtual void runAI(TileMap map) { EntityAIs.Basic(this, map); }
public override void update(TileMap map, TimeSpan elapsed) { if (SlatedToRemove) return; tElapsed = elapsed; isOnFloor = map.isRectOnFloor(EBounds.StandRect); if (attackDelay > 0) attackDelay -= elapsed.Milliseconds; if (showHpTicks > 0) showHpTicks -= elapsed.Milliseconds; // ### Update entity State if (!Alive) { DidMove = false; if (State == EntityState.Dead) return; else if (State != EntityState.Dying) die(); else if (!isOnFloor) EBounds.moveY(2); else { setState(EntityState.Dead); dropItems(); } return; } isOnFloor = map.isRectOnFloor(EBounds.StandRect); // ### Run the entities customizable AI if (ai != null) ai(this, map); else runAI(map); // ### Update movement State based on movement if (msVel.X != 0 && State != EntityState.Jumping) { setState(EntityState.Moving); if (msVel.X < 0) facing = Direction.Left; else facing = Direction.Right; } else if (State == EntityState.Moving) { // If State still 'Moving' but not moving, change State setState(EntityState.Standing); } // ### Update X position int currXSpeed = (int) (getRealXSpeed() * speedMultiplier); if (attackDelay > ATTACK_DELAY_MS * 0.625f && speedMultiplier > 0.25f) // If attacked recently while jumping, move slower speedMultiplier *= 0.93f; else if (speedMultiplier < MAX_SPEED) speedMultiplier += 0.033f; else speedMultiplier = MAX_SPEED; // Don't overshoot int oldX = EBounds.X; EBounds.moveX(currXSpeed); if (bounds.Right > map.getPixelWidth()) { EBounds.moveX((map.getPixelWidth() - bounds.Width) - bounds.X); // msVel.X = 0; } else if (bounds.Left <= 0) { EBounds.moveX(-bounds.X); // msVel.X = 0; } else if (msVel.X > 0) { int newX = map.checkBoundsXRight(bounds.Rect); updateBoundsX(map, newX); } else if (msVel.X < 0) { int newX = map.checkBoundsXLeft(bounds.Rect); updateBoundsX(map, newX); } if (oldX != EBounds.X) DidMove = true; else DidMove = false; // ### Update Y Position if (State == EntityState.Jumping) { // Gravity msVel.Y -= GRAVITY_PER_MS; } else if(jumpDelay > 0) { // Tick jump delay jumpDelay -= elapsed.Milliseconds; } // Subtract so everything else doesn't have to be switched (0 is top) EBounds.moveY((int) -getRealYSpeed()); if (bounds.Top >= map.getPixelHeight() - bounds.Height / 2) { EBounds.moveY((int) getRealYSpeed()); // Undo the move fallWithGravity(); } else if (bounds.Bottom <= 0) { EBounds.moveY((int) getRealYSpeed()); // Undo the move hitGround(); } else if (getRealYSpeed() > 0) { int newY = map.checkBoundsYUp(bounds.Rect); if (newY != bounds.Y) { // Hit something EBounds.moveY(newY - bounds.Y); // Move down correct amount (+) fallWithGravity(); } } else if (getRealYSpeed() < 0) { int newY = map.checkBoundsYDown(bounds.Rect); if (newY != bounds.Y) { // Hit something EBounds.moveY(newY - bounds.Y); // Move up correct amount (-) hitGround(); } } }
public Attack attack(TileMap map, EntityPart part, Func<Entity, EntityPart, TileMap, Attack> factoryFunc) { if (canAttack()) { Attack a = factoryFunc(this, part, map); map.addAttack(a); attackDelay = ATTACK_DELAY_MS; return a; } return null; }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; if (horizontal) { drawRect.X += getRealSpeed(); collRect.X += getRealSpeed(); } else { drawRect.Y += getRealSpeed(); collRect.Y += getRealSpeed(); } distTraveled += Math.Abs(getRealSpeed()); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int x; if (msSpeed > 0) x = map.shrinkX(collRect.Right, false); else x = map.shrinkX(collRect.Left, false); int maxY = map.shrinkY(collRect.Bottom, true); for (int y = map.shrinkY(collRect.Top, false); y <= maxY; y++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } else { int y; if (msSpeed > 0) y = map.shrinkX(collRect.Bottom, false); else y = map.shrinkX(collRect.Top, false); int maxX = map.shrinkX(collRect.Left, true); for (int x = map.shrinkX(collRect.Right, false); x <= maxX; x++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) continue; EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(collRect.Right, collRect.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) eHit = e.EBounds.collide(new Point(collRect.Left, collRect.Center.Y)); } else { int y; if (msSpeed > 0) y = collRect.Bottom; else y = collRect.Top; eHit = e.EBounds.collide(new Point(collRect.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) eHit = e.EBounds.collide(new Point(collRect.Right, y)); } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = ((eHit.PercFromCenter < 0.6) ? 1 - eHit.PercFromCenter : 0.4f); int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); map.addHitText(e, realDmg); if (!e.Alive) xp += e.XPValue; } return; } } } } }
public TileMap(int width, int height, MapType type, GameScreen screen, TileMap oldMap) { this.GScreen = screen; this.Width = width; this.Height = height; this.OldMap = oldMap; // Init numEntities = 0; DeadEntities = new List<Entity>(); Map = new List<TileBlock>(); Entities = new List<Entity>(); GameObjects = new List<GameObject>(); Attacks = new List<Attack>(); HitTexts = new List<HitText>(); switch (type) { case MapType.Treasure: setBackground(GameScreen.Backgrounds[BackgroundId.Cave1]); for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { if (h == height - 2 && w == 0) { Map.Add(TileBlock.IRON_DOOR.Clone().addEvent(TileBlockEvent.MapGoBack)); } else if (h == 0 || h == height - 1) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 2 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(width / 3) == 0) { Map.Add(TileBlock.CLOSED_CHEST.Clone()); } else { Map.Add(TileBlock.NONE.Clone()); } } } break; case MapType.Hall: default: // Hall Way setBackground(GameScreen.Backgrounds[BackgroundId.Cave1]); int specialCount = 0; for (int w = 0; w < width; w++) for (int h = 0; h < height; h++) { if (h == height - 2 && w == width - 1) { Map.Add(TileBlock.DOOR.Clone()); addRandomEntity(w * SPRITE_SIZE, h * SPRITE_SIZE, screen); } else if (h == 0 || h == height - 1) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 3 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(25) == 0) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 3 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(25) == 0) { Map.Add(TileBlock.STONE2_WALL.Clone()); } else if (specialCount == 0 && w > 2 && h == height - 2 && ScreenManager.Rand.Next(150) == 0) { specialCount++; Map.Add(TileBlock.HPPOOL.Clone()); } else if (specialCount == 0 && w > 2 && h == height - 2 && ScreenManager.Rand.Next(200) == 0) { specialCount++; Map.Add(TileBlock.IRON_DOOR.Clone().addEvent(TileBlockEvent.NewTreasureRoom)); } else { Map.Add(TileBlock.NONE.Clone()); if (h == height - 2 && w > 4 && ScreenManager.Rand.Next(12) == 0) addRandomEntity(w * SPRITE_SIZE, h * SPRITE_SIZE, screen); } } break; } }
protected override void runAI(TileMap map) { foreach (Attack a in myAttacks) xp += a.getXP(); // Level up if (xp > lvlXp) { xp = 0; lvlXp = (int) (lvlXp * 1.5f); Stats.levelUp(); } myAttacks.RemoveAll(new Predicate<Attack>(AttackXpAdded)); }
public static Attack None(Entity e, EntityPart part, TileMap map) { return(null); }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; int vel = getRealSpeed(); if (horizontal) { drawRect.X += vel; bounds.moveX(vel); } else { drawRect.Y += vel; bounds.moveY(vel); } distTraveled += Math.Abs(vel); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int oldX = bounds.X, newX; if (vel > 0) { newX = map.checkBoundsXRight(bounds, Direction.Right); } else { newX = map.checkBoundsXLeft(bounds, Direction.Left); } if (newX != oldX || bounds.Y != drawRect.Y) { alive = false; return; } } else { int oldY = bounds.Y, newY; if (vel > 0) { newY = map.checkBoundsYDown(bounds, Direction.Right); } else { newY = map.checkBoundsYUp(bounds, Direction.Right); } if (newY != oldY) { alive = false; return; } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) { continue; } EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(bounds.Right, bounds.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(bounds.Left, bounds.Center.Y)); } } else { int y; if (msSpeed > 0) { y = bounds.Bottom; } else { y = bounds.Top; } eHit = e.EBounds.collide(new Point(bounds.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(bounds.Right, y)); } } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = 0; if (eHit.PercFromCenter >= 0.75) { dmgReducer = 0.25f; } else if (eHit.PercFromCenter >= 0) { dmgReducer = 1 - eHit.PercFromCenter; } int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); realDmg += e.slide(eHit.KnockBack); map.addHitText(e, realDmg); if (!e.Alive) { xp += e.XPValue; } } return; } } } } }
public void doAttack(TileMap map, EntityPart part) { if (Alive) { Attack attack = base.attack(map, part, AttackFactory.FireBall); if (attack != null) { myAttacks.Add(attack); } } }
public void setRoom(TileMap map) { if (TileMap != null) TileMap.LeavePoint = Player.Location; TileMap = map; for(int i=0; i<10; i++) TileMap.update(ScreenManager.TargElapsedTime); TileMap.addEntity(Player); transitionMs = TRANSITION_MS; }
public TileMap(int width, int height, MapType type, GameScreen screen, TileMap oldMap) { this.GScreen = screen; this.Width = width; this.Height = height; this.OldMap = oldMap; // Init numEntities = 0; DeadEntities = new List <Entity>(); Map = new List <TileBlock>(); Entities = new List <Entity>(); GameObjects = new List <GameObject>(); Attacks = new List <Attack>(); HitTexts = new List <HitText>(); switch (type) { case MapType.Treasure: setBackground(GameScreen.Backgrounds[BackgroundId.Cave1]); for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { if (h == height - 2 && w == 0) { Map.Add(TileBlock.IRON_DOOR.Clone().addEvent(TileBlockEvent.MapGoBack)); } else if (h == 0 || h == height - 1) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 2 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(width / 3) == 0) { Map.Add(TileBlock.CLOSED_CHEST.Clone()); } else { Map.Add(TileBlock.NONE.Clone()); } } } break; case MapType.Hall: default: // Hall Way setBackground(GameScreen.Backgrounds[BackgroundId.Cave1]); int specialCount = 0; for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { if (h == height - 2 && w == width - 1) { Map.Add(TileBlock.DOOR.Clone()); addRandomEntity(w * SPRITE_SIZE, h * SPRITE_SIZE, screen); } else if (h == 0 || h == height - 1) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 3 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(25) == 0) { Map.Add(TileBlock.STONE_WALL.Clone()); } else if (w > 3 && w < width - 2 && h == height - 2 && ScreenManager.Rand.Next(25) == 0) { Map.Add(TileBlock.STONE2_WALL.Clone()); } else if (specialCount == 0 && w > 2 && h == height - 2 && ScreenManager.Rand.Next(150) == 0) { specialCount++; Map.Add(TileBlock.HPPOOL.Clone()); } else if (specialCount == 0 && w > 2 && h == height - 2 && ScreenManager.Rand.Next(200) == 0) { specialCount++; Map.Add(TileBlock.IRON_DOOR.Clone().addEvent(TileBlockEvent.NewTreasureRoom)); } else { Map.Add(TileBlock.NONE.Clone()); if (h == height - 2 && w > 4 && ScreenManager.Rand.Next(12) == 0) { addRandomEntity(w * SPRITE_SIZE, h * SPRITE_SIZE, screen); } } } } break; } }
public virtual void update(TileMap map, TimeSpan elapsed) { if (SlatedToRemove) return; isOnFloor = map.isRectOnFloor(bounds.Rect); if (!isOnFloor) bounds.moveY(2); }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; if (horizontal) { drawRect.X += getRealSpeed(); collRect.X += getRealSpeed(); } else { drawRect.Y += getRealSpeed(); collRect.Y += getRealSpeed(); } distTraveled += Math.Abs(getRealSpeed()); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int x; if (msSpeed > 0) { x = map.shrinkX(collRect.Right, false); } else { x = map.shrinkX(collRect.Left, false); } int maxY = map.shrinkY(collRect.Bottom, true); for (int y = map.shrinkY(collRect.Top, false); y <= maxY; y++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } else { int y; if (msSpeed > 0) { y = map.shrinkX(collRect.Bottom, false); } else { y = map.shrinkX(collRect.Top, false); } int maxX = map.shrinkX(collRect.Left, true); for (int x = map.shrinkX(collRect.Right, false); x <= maxX; x++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) { continue; } EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(collRect.Right, collRect.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(collRect.Left, collRect.Center.Y)); } } else { int y; if (msSpeed > 0) { y = collRect.Bottom; } else { y = collRect.Top; } eHit = e.EBounds.collide(new Point(collRect.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(collRect.Right, y)); } } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = ((eHit.PercFromCenter < 0.6) ? 1 - eHit.PercFromCenter : 0.4f); int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); map.addHitText(e, realDmg); if (!e.Alive) { xp += e.XPValue; } } return; } } } } }