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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package scalevalapokalypsi.Model.Entities
import scala.collection.mutable.{Buffer,Map}
import scalevalapokalypsi.Model.*
/** 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,
initialHP: Int = 100,
val maxHP: Int = 100
):
private var currentLocation: Area = initialLocation
private var quitCommandGiven = false // one-way flag
private val inventory: Map[String, Item] = Map()
private var hp = initialHP
// TODO: add logic for choosing from multiplu lines - can depend on HP etc.
/** Gets a verse to sing when attacking against this entity.
*
* @return the verse to sing against this entity
*/
def getVerseAgainst: String = "Esimerkkirivi laulettavaksi"
def takeDamage(amount: Int): Unit =
hp -= amount
if hp < 0 then
println("Oh no, I died!")
/** Returns a description of the physical condition of this entity,
* i.e. the damage it has taken.
*
* @return a pair of strings, both of which describe the condition of this
* entity, the first of which is in first person and the second in
* third person.
*/
def condition: (String, String) =
if hp < maxHP * .25 then
("Sinua heikottaa ja tunnet olevasi lähellä häviötä.",
s"$name näyttää maansa myyneeltä.")
else if hp < maxHP * .50 then
("Sinnittelet yhä, mutta kuntosi on laskenut suuresti.",
s"$name näyttää sinnittelevän yhä.")
else if hp < maxHP * .75 then
("Tunnet koettelemusten vaikutuksen, mutta et anna niiden lannistaa itseäsi",
s"$name näyttää aavistuksen lannistuneelta.")
else if hp < maxHP then
("Olet voimissasi.", s"$name on yhä voimissaan.")
else
("Olet täysin kunnossa.", s"$name näyttää kuin vastasyntyneeltä.")
/** Does nothing, except possibly in inherited classes. */
def observeString(observation: String): Unit =
println(" [debug] entity got observation string & discarded it")
def observe(event: Event): Unit =
println(" [debug] entity got observation event & discarded it")
/** 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.",
s"${this.name} tries to pick up something but gets just dirt in their hands."
)
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.observeString(s"${this.name}: \"$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 turn.
* 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 = s"${this.name} at ${this.location.name}"
end Entity
|