aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/Model/Entity.scala
blob: d8e85590e07d06ab5bcdeb6960c04a63b7017320 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package o1game.Model

import scala.collection.mutable.{Buffer,Map}



/** A `Player` object represents a player character controlled by one real-life player
  * of the program.
  *
  * A player object’s state is mutable: the player’s location and possessions can change,
  * for instance.
  *
  * @param startingArea the player’s initial location */
class Player(name: String, initialLocation: Area) extends Entity(name, initialLocation):

	private val observations: Buffer[String] = Buffer.empty

	override def observe(observation: String): Unit =
		this.observations.append(observation)

	def readAndClearObservations(): Vector[String] =
		val res = this.observations.toVector
		observations.clear()
		res

end Player

/** An in-game entity.
  *
  * @param name the name of the entity
  * @param initialLocation the Area where the entity is instantiated
  */
class Entity(val name: String, initialLocation: Area):
	private var currentLocation: Area = initialLocation
	private var quitCommandGiven = false // one-way flag
	private val inventory: Map[String, Item] = Map()

	/** Determines if the player has indicated a desire to quit the game. */
	def hasQuit = this.quitCommandGiven // TODO: This is probably unneccessary?

	/** Does nothing, except possibly in inherited classes. */
	def observe(observation: String): Unit =
		println("no observation made.")
		()

	/** Returns the player’s current location. */
	def location = this.currentLocation

	/** Attempts to move the player in the given direction. This is successful if there
	  * is an exit from the player’s current location towards the direction name. Returns
	  * a description of the result: "You go DIRECTION." or "You can't go DIRECTION." */
	def go(direction: String): (String, String) =
		val destination = this.location.neighbor(direction)
		if destination.isDefined then
			val removeSuccess = this.currentLocation.removeEntity(this.name)
			assert(removeSuccess.isDefined) // Production - assertions off
			this.currentLocation = destination.getOrElse(this.currentLocation)
			destination.foreach(_.addEntity(this))
			(s"You go $direction.", s"$name goes $direction")
		else
			(
				s"You can't go $direction.",
				s"$name tries to go $direction and stumbles in their feet."
			)

	def pickUp(itemName: String): (String, String) =
		this.currentLocation.removeItem(itemName) match
			case Some(i) =>
				this.inventory += i.name -> i
				(s"You pick up the ${i.name}", s"$name picks up the ${i.name}")
			case None => (s"There is no $itemName here to pick up.", "WHAAAT THIS SHOULDN'T HAPPEN???")

	def drop(itemName: String): (String, String) =
		this.inventory.remove(itemName) match
			case Some(item) =>
				this.currentLocation.addItem(item)
				(s"You drop the $itemName", s"$name drops the $itemName")
			case None => ("You don't have that!", s"$name reaches their backpack to drop $itemName but miserably fails to find it there.")

	def sayTo(entity: Entity, message: String): (String, String) =
		entity.observe(s"Alice: \"$message\"")
		(s"You say so to ${entity.name}.", "")

	def say(message: String): (String, String) =
		("You say that aloud.", s"$name: \"$message\"")

	/** Tells whether this entity can drop the specified item
	 * (if an action were to specify so).
	 *
	 * @param itemName the name to check
	 * @return whether this entity has this item and can drop it
	 */
	def canDrop(itemName: String): Boolean = this.inventory.contains(itemName)

	/** Causes the player to rest for a short while (this has no substantial effect in game terms).
	  * Returns a description of what happened. */
	def rest(): (String, String) =
		("You rest for a while. Better get a move on, though.", "")

	/** Returns a brief description of the player’s state, for debugging purposes. */
	override def toString = "Now at: " + this.location.name

end Entity