From fe2543627bcec1ea0f7a429bede20ca293458ba9 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Mon, 18 Nov 2024 02:01:12 +0200 Subject: Major change! Changed Events to have multiple first persons & changed sending action results to clients using this. This improves code and made it easy to finally make arrival/leaving messages when going from one area to another! This commit is too big indeed, and there are probably bugs. I'm annoyed we didn't set up unit testing during the course. I should've taken my time to set up IDEA myself for that. Now the bugs will just have to be fixed in future commits. --- src/scalevalapokalypsi/Model/Action.scala | 75 ++++++++++++++----------------- 1 file changed, 33 insertions(+), 42 deletions(-) (limited to 'src/scalevalapokalypsi/Model/Action.scala') diff --git a/src/scalevalapokalypsi/Model/Action.scala b/src/scalevalapokalypsi/Model/Action.scala index 30fbf46..a781ee8 100644 --- a/src/scalevalapokalypsi/Model/Action.scala +++ b/src/scalevalapokalypsi/Model/Action.scala @@ -15,33 +15,25 @@ class Action(input: String): private val verb = commandText.takeWhile( _ != ' ' ) private val modifiers = commandText.drop(verb.length).trim - def takesATurnFor(actor: Player): Boolean = - this.verb match - case "rest" => true - case "go" => actor.location.hasNeighbor(modifiers) - case "get" => actor.location.hasItem(this.modifiers) - case "drop" => actor.canDrop(this.modifiers) - case "say" => false - case "laula" => false - case other => false - /** Causes the given player to take the action represented by this object, - * assuming that the command was understood. Returns a description of what - * happened as a result of the action (such as “You go west.”). The - * description is returned in an `Option` wrapper; if the command was not - * recognized, `None` is returned. + * assuming that the command was understood. Informs the player and the + * entities surrounding it about the result. Returns true if the command + * was understood and possible, false otherwise. * * @param actor the acting player - * @return A textual description of the action, or `None` if the action - * was not recognized. + * @return Boolean indicating whether the action possibly taken takes a + * turn or not. */ - def execute(actor: Player): Option[String] = + def execute(actor: Player): Boolean = val oldLocation = actor.location - val resOption: Option[(String, String)] = this.verb match - case "go" => Some(actor.go(this.modifiers)) - case "rest" => Some(actor.rest()) - case "get" => Some(actor.pickUp(this.modifiers)) - case "say" => + val resOption: Option[(Boolean, Event)] = this.verb match + case "go" => + val result = actor.go(this.modifiers) + result.foreach(r => oldLocation.observeEvent(r)) + result.map((true, _)) + case "rest" => Some((true, actor.rest())) + case "get" => Some((false, actor.pickUp(this.modifiers))) + case "say" => val to = "to" val recipient = modifiers.reverse.takeWhile(_ != ' ').reverse val recipientEntity = actor.location.getEntity(recipient) @@ -52,10 +44,10 @@ class Action(input: String): val message = modifiers.take(modifiers.length - recipient.length - 4) if maybeTo == to then - recipientEntity.map(actor.sayTo(_, message)) + recipientEntity.map(e => (false, actor.sayTo(e, message))) else - Some(actor.say(modifiers)) - case "drop" => Some(actor.drop(this.modifiers)) + Some((false, actor.say(modifiers))) + case "drop" => Some((false, actor.drop(this.modifiers))) case "laula" => val end = modifiers.takeRight("suohon".length) val start = @@ -64,28 +56,27 @@ class Action(input: String): val targetEntity = actor.location.getEntity(start) targetEntity .foreach(e => actor.setSingEffect(DefaultSingAttack(e))) - targetEntity.foreach(_.observeString(s"${actor.name} laulaa sinua suohon!")) - targetEntity.map(e => ( - "Aloitat suohonlaulun.", - s"${actor.name} aloittaa suohonlaulun." - )) + targetEntity.map(t => + (false, Event( + Map.from(Vector((t, s"${actor.name} laulaa sinua suohon!"))), + s"${actor.name} laulaa henkilöä ${t.name} suohon." + )) + ) else None - case "xyzzy" => Some(( - "The grue tastes yummy.", + case "xyzzy" => Some((false, Event( + Map.from(Vector((actor, "The grue tastes yummy."))), s"${actor.name} tastes some grue.") - ) + )) case other => None - resOption.map(_(1)).filter(_.length > 0) - .foreach(s => - actor.location.getEntities.filter(_ != actor).foreach(_.observeString(s)) - if oldLocation != actor.location then - oldLocation.getEntities.foreach(_.observeString(s)) - ) - - resOption.map(_(0)) - + val res: (Boolean, Event) = resOption + .getOrElse((false, Event( + Map.from(Vector((actor, "Tuo ei ole asia, jonka voit tehdä."))), + "" + ))) + actor.location.observeEvent(res(1)) + res(0) /** Returns a textual description of the action object, for debugging purposes. */ override def toString = s"$verb (modifiers: $modifiers)" -- cgit v1.2.3