From 7fa69be4e88f1fcf057871fec7e4503f50578465 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Mon, 1 Mar 2021 22:19:46 -0500 Subject: Started writing the Mixolydia scene! Looking pretty good so far. TODO: direction facing functions have inverted Y coordinate. confusion expression doesn't exist yet. rest of scene. --- res/maps/pink_shell.tmx | 17 +++- res/scripts/common.lua | 59 ++++++++++++ res/scripts/hallucination_hot_spring.lua | 2 + res/scripts/hallucination_interior.lua | 3 + res/scripts/pink_shell.lua | 148 +++++++++++++++++++++++++++++++ src/behaviour_system.cpp | 1 + src/character_system.cpp | 1 + src/direction.h | 17 ++++ src/main.cpp | 4 +- src/script_system.cpp | 7 +- 10 files changed, 255 insertions(+), 4 deletions(-) diff --git a/res/maps/pink_shell.tmx b/res/maps/pink_shell.tmx index d7915d9..2389b70 100644 --- a/res/maps/pink_shell.tmx +++ b/res/maps/pink_shell.tmx @@ -1,5 +1,5 @@ - + @@ -74,6 +74,21 @@ + + + + + + + + + + + + + + + diff --git a/res/scripts/common.lua b/res/scripts/common.lua index 1b0c4a9..dad9c5d 100644 --- a/res/scripts/common.lua +++ b/res/scripts/common.lua @@ -30,6 +30,12 @@ SpriteLayer = { ABOVE = 1 } +BehaviourType = { + NONE = 0, + WANDER = 1, + PATH = 2 +} + CutsceneOptions = { DO_NOT_CHANGE_ANIMATION = 1 -- Prevents player party animation being set to "frozen" at the start of a cutscene or "still" at the end } @@ -426,6 +432,13 @@ function WaitForSpritePath(spriteName) end end +--- Turns off the sprite's behaviour. +function DisableBehaviour(spriteName) + local spriteId = getSpriteByAlias(spriteName) + local sprite = getSprite(spriteId) + sprite.behaviourType = BehaviourType.NONE +end + --- Fades out the currently playing music. -- This does not block. If you want it to block, call Delay for the same amount -- of time. @@ -456,3 +469,49 @@ function EnablePlayerControl() local playerSprite = getSprite(playerId) playerSprite.controllable = true end + +--- Makes the specified sprite face toward the †arget sprite. +-- This version of the function uses the closest cardinal direction. +-- @param spriteName the name of the sprite to change the direction of +-- @param targetName the name of the sprite to face toward +function FaceTowardSpriteCardinally(spriteName, targetName) + local spriteId = getSpriteByAlias(spriteName) + local targetId = getSpriteByAlias(targetName) + local sprite = getSprite(spriteId) + local target = getSprite(targetId) + local diff = vec2i.new(target.loc:x() - sprite.loc:x(), target.loc:y() - sprite.loc:y()) + local dir = cardinalDirectionFacingPoint(diff) + + SetDirection(spriteName, dir) +end + +--- Detaches the sprite's followers and erases their following trails. +function BreakUpParty(spriteName) + local spriteId = getSpriteByAlias(spriteName) + character():breakUpParty(spriteId) +end + +--- Makes the specified sprite solid. +-- This means that other sprites will be blocked if they collide with this one. +function MakeSpriteSolid(spriteName) + local spriteId = getSpriteByAlias(spriteName) + local sprite = getSprite(spriteId) + sprite.solid = true +end + +--- Makes the specified sprite not solid. +-- This means that other sprites will not be blocked if they collide with this +-- one. +function MakeSpriteNotSolid(spriteName) + local spriteId = getSpriteByAlias(spriteName) + local sprite = getSprite(spriteId) + sprite.solid = false +end + +--- Sets the sprite's movement speed. +-- As a reference: 1 is slow (good for NPCs), 2 is Lucas's default walking speed +function SetMovementSpeed(spriteName, speed) + local spriteId = getSpriteByAlias(spriteName) + local sprite = getSprite(spriteId) + sprite.movementSpeed = speed +end diff --git a/res/scripts/hallucination_hot_spring.lua b/res/scripts/hallucination_hot_spring.lua index c432eb3..805f85a 100644 --- a/res/scripts/hallucination_hot_spring.lua +++ b/res/scripts/hallucination_hot_spring.lua @@ -14,6 +14,8 @@ function hallucination_hot_spring.off_right() end function hallucination_hot_spring.enter_hot_spring() + gamestate.went_in_hot_spring = true + if gamestate.ionia_in_water then -- Soft cutscene start; don't show bars but do take away control DisablePlayerControl() diff --git a/res/scripts/hallucination_interior.lua b/res/scripts/hallucination_interior.lua index 4fbaa99..9ef808e 100644 --- a/res/scripts/hallucination_interior.lua +++ b/res/scripts/hallucination_interior.lua @@ -45,6 +45,9 @@ function hallucination_interior.join_claus() local clausSprite = getSprite(clausId) clausSprite.persistent = true + + gamestate.claus_joined = true + gamestate.still_has_claus = true else DisplayMessage("* You won't let me join in?\nWhy not? Why not?\n\f* Why won't you let me join in?", "Claus", SpeakerType.MAN) WaitForEndOfMessage() diff --git a/res/scripts/pink_shell.lua b/res/scripts/pink_shell.lua index 4223188..5747186 100644 --- a/res/scripts/pink_shell.lua +++ b/res/scripts/pink_shell.lua @@ -16,4 +16,152 @@ end function pink_shell.talk_to_mixolydia() SetDirection("mixolydia", Direction.UP) + SetAnimation("mixolydia", "talk") + StartCutscene() + DisplayMessage("* Oh, me, oh, my! We have visitors! `", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(500) + + SetDirection("mixolydia", Direction.DOWN) + Delay(1000) + + if gamestate.went_in_hot_spring then + SetAnimation("mixolydia", "talk") + DisplayMessage("* ...You people stink.", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(1000) + end + + FaceTowardSpriteCardinally("mixolydia", "lucas") + ShowExpression("mixolydia", "confusion") + Delay(1000) + + RemoveExpression("mixolydia") + SetAnimation("mixolydia", "talk") + DisplayMessage("* Oh, wait a minute...", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(1000) + + SetAnimation("mixolydia", "talk") + DisplayMessage("* Are you Lucas?", "Mixolydia", SpeakerType.WOMAN) + ShowChoice("Yes", "No") + WaitForEndOfMessage() + + if GetChoiceSelection() == 1 then + DisplayMessage("* This island really has done a number on you.\n\f* But I'll humor you and listen anyway.", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + end + + if gamestate.went_in_hot_spring then + SetAnimation("mixolydia", "still") + Delay(1000) + + SetAnimation("mixolydia", "talk") + DisplayMessage("* ...Wow, you guys really stink.", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + end + + SetAnimation("mixolydia", "still") + Delay(2000) + + SetAnimation("mixolydia", "talk") + DisplayMessage("* Ionia told me about you. `\n\f* I'm Mixolydia, one of the Magifolk. `\n\f* If that's too hard to remember, ...\n... no, will do just fine. `", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(2000) + + SetAnimation("mixolydia", "talk") + DisplayMessage("* Okay... Line up here.", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(1000) + + -- direct everyone to stand in their positions + BreakUpParty("lucas") + MakeSpriteNotSolid("lucas") + MakeSpriteNotSolid("mixolydia") + + UnpauseSprite("lucas") + SetMovementSpeed("lucas", 1) + DirectSpriteToLocation("lucas", "lucas_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) + WaitForSpritePath("lucas") + DisableBehaviour("lucas") + SetDirection("lucas", Direction.DOWN) + SetAnimation("lucas", "tired") + PauseSprite("lucas") + SetMovementSpeed("lucas", 2) + Delay(100) + + UnpauseSprite("kuma") + SetMovementSpeed("kuma", 1) + DirectSpriteToLocation("kuma", "kumatora_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) + WaitForSpritePath("kuma") + DisableBehaviour("kuma") + SetDirection("kuma", Direction.DOWN) + SetAnimation("kuma", "tired") + PauseSprite("kuma") + SetMovementSpeed("kuma", 0) + Delay(100) + + UnpauseSprite("duster") + SetMovementSpeed("duster", 1) + DirectSpriteToLocation("duster", "duster_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) + WaitForSpritePath("duster") + DisableBehaviour("duster") + SetDirection("duster", Direction.DOWN) + SetAnimation("duster", "tired") + PauseSprite("duster") + SetMovementSpeed("duster", 0) + Delay(100) + + UnpauseSprite("boney") + SetMovementSpeed("boney", 1) + DirectSpriteToLocation("boney", "boney_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) + WaitForSpritePath("boney") + DisableBehaviour("boney") + SetDirection("boney", Direction.DOWN) + SetAnimation("boney", "tired") + PauseSprite("boney") + SetMovementSpeed("boney", 0) + Delay(100) + + if gamestate.still_has_claus then + UnpauseSprite("join_claus") + SetMovementSpeed("join_claus", 1) + DirectSpriteToLocation("join_claus", "claus_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) + WaitForSpritePath("join_claus") + DisableBehaviour("join_claus") + SetDirection("join_claus", Direction.DOWN) + SetAnimation("join_claus", "tired") + PauseSprite("join_claus") + SetMovementSpeed("join_claus", 0) + end + + MakeSpriteSolid("lucas") + Delay(1000) + + if gamestate.went_in_hot_spring then + SetAnimation("mixolydia", "talk") + DisplayMessage("* ...Yuck. What a stench.", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + Delay(1000) + end + + SetAnimation("mixolydia", "talk") + DisplayMessage("* Tanetane Island...\nIt wreaks havoc on a person's mind.\n\f* Every trauma you've suffered is pulled out.\n\f* The things down there tear at your weaknesses and the scars in your heart.\n\f* But I'll bring you back to your senses now. `", "Mixolydia", SpeakerType.WOMAN) + WaitForEndOfMessage() + + SetAnimation("mixolydia", "still") + + -- TODO: rest of scene end diff --git a/src/behaviour_system.cpp b/src/behaviour_system.cpp index 4a194f0..a05912c 100644 --- a/src/behaviour_system.cpp +++ b/src/behaviour_system.cpp @@ -59,6 +59,7 @@ void BehaviourSystem::tick(double dt) { void BehaviourSystem::directSpriteToLocation(int spriteId, vec2i pos, PathfindingOptions options) { Sprite& sprite = game_.getSprite(spriteId); + sprite.orientable = true; sprite.behaviourType = BehaviourType::Path; sprite.pathfindingDestination = pos; sprite.cardinalDirectionsOnly = pathfindingOptionsContains(options, PathfindingOptions::CardinalDirectionsOnly); diff --git a/src/character_system.cpp b/src/character_system.cpp index 53debb2..48d2a33 100644 --- a/src/character_system.cpp +++ b/src/character_system.cpp @@ -17,6 +17,7 @@ void CharacterSystem::initSprite(int spriteId, int movementSpeed) { void CharacterSystem::addSpriteToParty(int leaderId, int followerId) { Sprite& leader = game_.getSprite(leaderId); Sprite& follower = game_.getSprite(followerId); + follower.orientable = false; vec2i targetPos = leader.loc; diff --git a/src/direction.h b/src/direction.h index 3dd95f9..595693f 100644 --- a/src/direction.h +++ b/src/direction.h @@ -90,4 +90,21 @@ inline Direction directionFacingPoint(vec2i point) { } } +inline Direction cardinalDirectionFacingPoint(vec2i point) { + double theta = atan2(point.y(), point.x()); + theta /= M_PI; + + if (theta < -3.0/4.0) { + return Direction::left; + } else if (theta < -1.0/4.0) { + return Direction::down; + } else if (theta < 1.0/4.0) { + return Direction::right; + } else if (theta < 3.0/4.0) { + return Direction::up; + } else { + return Direction::left; + } +} + #endif /* end of include guard: DIRECTION_H_AB66A90E */ diff --git a/src/main.cpp b/src/main.cpp index b98c8f1..d0220fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,9 +27,9 @@ void loop(Renderer& renderer, std::mt19937& rng) { game.emplaceSystem(); game.emplaceSystem(); - game.loadMap("hallucination_interior"); + game.loadMap("pink_shell"); - vec2i warpLoc = game.getMap().getWarpPoint("debugWarp_rightside"); + vec2i warpLoc = game.getMap().getWarpPoint("fromOutside"); int lucasSprite = game.emplaceSprite("lucas"); game.getSystem().initSprite(lucasSprite, warpLoc); diff --git a/src/script_system.cpp b/src/script_system.cpp index 931759d..a3686b4 100644 --- a/src/script_system.cpp +++ b/src/script_system.cpp @@ -44,7 +44,10 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { "cantCrouch", &Sprite::cantCrouch, "bobsWhenNormal", &Sprite::bobsWhenNormal, "animSlowdown", &Sprite::animSlowdown, - "enclosureZone", &Sprite::enclosureZone); + "enclosureZone", &Sprite::enclosureZone, + "movementSpeed", &Sprite::movementSpeed, + "solid", &Sprite::solid, + "behaviourType", &Sprite::behaviourType); engine_.new_usertype( "message", @@ -230,6 +233,8 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { loadMapScripts(filename); }); + engine_.set_function("cardinalDirectionFacingPoint", &cardinalDirectionFacingPoint); + engine_.script_file("../res/scripts/common.lua"); } -- cgit 1.4.1