package scalevalapokalypsi.Model import scala.collection.mutable.Map import scalevalapokalypsi.Model.Entities.* import scalevalapokalypsi.Model.Entities.NPCs.* /** The class `Adventure` holds data of the game world and provides methods * for implementing a user interface for it. * * Data about the game world includes remote players, other entities and areas. * The methods are documented below. * * @param playerNames a vector of the names of players to create and add * to the adventure straight away */ class Adventure(val playerNames: Vector[String]): private val middle = Area("Forest", "Olet keskellä metsää. Metsä on täynnä puita.\nLintua laulaa.") private val northForest = Area("Forest", "Olet keskellä metsää. Tiheä pensaikko estää sinua kulkemasta pohjoiseen. \nLintua laulaa.") private val southForest = Area("Forest", "The forest just goes on and on.") private val clearing = Area("Forest Clearing", "You are at a small clearing in the middle of forest.\nNearly invisible, twisted paths lead in many directions.") private val tangle = Area("Tangle of Bushes", "You are in a dense tangle of bushes. It's hard to see exactly where you're going.") private val home = Area("Home", "Home sweet home! Now the only thing you need is a working remote control.") middle.setNeighbors(Vector("north" -> northForest, "east" -> tangle, "south" -> southForest, "west" -> clearing)) northForest.setNeighbors(Vector("east" -> tangle, "south" -> middle, "west" -> clearing)) southForest.setNeighbors(Vector("north" -> middle, "east" -> tangle, "south" -> southForest, "west" -> clearing)) clearing.setNeighbors(Vector("north" -> northForest, "east" -> middle, "south" -> southForest, "west" -> northForest)) tangle.setNeighbors(Vector("north" -> northForest, "east" -> home, "south" -> southForest, "west" -> northForest)) home.setNeighbors(Vector("west" -> tangle)) clearing.addItem(Item("battery", "It's a small battery cell. Looks new.", 1)) southForest.addItem(Item( "laulukäärö", "Jukranpujut, löysit laulukäärön!\n" + "Et vielä voi tehdä sillä mitään, koska et edes osaa laula.", 1 )) val entities: Map[String, Entity] = Map() val npcs: Map[String, NPC] = Map() private val zombieAttrs = Vector( ("Weary zombie", clearing, 20), ("Smelly zombie", home, 20), ("Rotten zombie", tangle, 10) ) zombieAttrs.foreach(z => val zombie = Zombie(this, z(0), z(1), z(2)) npcs += z(0) -> zombie z(1).addEntity(zombie) ) def takeNpcTurns(): Unit = npcs.values.foreach(_.act()) private val gruu = Entity(this, "Gruu", northForest) northForest.addEntity(gruu) this.entities += gruu.name -> gruu val players: Map[String, Player] = Map() playerNames.foreach(this.addPlayer(_)) /** Adds a player entity with the specified name to the game. * * @param name the name of the player entity to add * @return the created player entity */ def addPlayer(name: String): Player = val newPlayer = Player(this, name, middle) middle.addEntity(newPlayer) this.entities += name -> newPlayer players += name -> newPlayer newPlayer /** Removes the given entity without further observations. Makes sense in the * game mostly if the entity's HP is nonpositive. * * Removes the entity both from the adventure and the game world * (i.e. the entitys area). * * @param name the name of the entity to remove * @return whether there was an entity to remove with the given name */ def removeEntity(name: String): Boolean = this.players.remove(name) this.entities.remove(name).orElse(this.npcs.remove(name)) match case Some(e) => e.location.removeEntity(name) true case None => false /** Gets the player entity with the specified name. * * @param name name of the player to find * @return the player, if one with the name was found */ def getPlayer(name: String): Option[Player] = this.players.get(name) def getEntity[A >: Entity](name: String) = this.players.get(name) .orElse(this.npcs.get(name)) .getOrElse(this.entities.get(name)) end Adventure