diff options
-rw-r--r-- | res/maps/pink_shell.tmx | 17 | ||||
-rw-r--r-- | res/scripts/common.lua | 59 | ||||
-rw-r--r-- | res/scripts/hallucination_hot_spring.lua | 2 | ||||
-rw-r--r-- | res/scripts/hallucination_interior.lua | 3 | ||||
-rw-r--r-- | res/scripts/pink_shell.lua | 148 | ||||
-rw-r--r-- | src/behaviour_system.cpp | 1 | ||||
-rw-r--r-- | src/character_system.cpp | 1 | ||||
-rw-r--r-- | src/direction.h | 17 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | 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 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="32" height="32" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="5"> | 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="32" height="32" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="11"> |
3 | <properties> | 3 | <properties> |
4 | <property name="music" value="are_you_gorgeous"/> | 4 | <property name="music" value="are_you_gorgeous"/> |
5 | </properties> | 5 | </properties> |
@@ -74,6 +74,21 @@ | |||
74 | </properties> | 74 | </properties> |
75 | <point/> | 75 | <point/> |
76 | </object> | 76 | </object> |
77 | <object id="5" name="lucas_lineup" type="warp" x="248" y="144"> | ||
78 | <point/> | ||
79 | </object> | ||
80 | <object id="7" name="boney_lineup" type="warp" x="232" y="144"> | ||
81 | <point/> | ||
82 | </object> | ||
83 | <object id="8" name="kumatora_lineup" type="warp" x="264" y="144"> | ||
84 | <point/> | ||
85 | </object> | ||
86 | <object id="9" name="duster_lineup" type="warp" x="280" y="144"> | ||
87 | <point/> | ||
88 | </object> | ||
89 | <object id="10" name="claus_lineup" type="warp" x="296" y="144"> | ||
90 | <point/> | ||
91 | </object> | ||
77 | </objectgroup> | 92 | </objectgroup> |
78 | <layer id="1" name="Upper" width="32" height="32"> | 93 | <layer id="1" name="Upper" width="32" height="32"> |
79 | <properties> | 94 | <properties> |
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 = { | |||
30 | ABOVE = 1 | 30 | ABOVE = 1 |
31 | } | 31 | } |
32 | 32 | ||
33 | BehaviourType = { | ||
34 | NONE = 0, | ||
35 | WANDER = 1, | ||
36 | PATH = 2 | ||
37 | } | ||
38 | |||
33 | CutsceneOptions = { | 39 | CutsceneOptions = { |
34 | DO_NOT_CHANGE_ANIMATION = 1 -- Prevents player party animation being set to "frozen" at the start of a cutscene or "still" at the end | 40 | DO_NOT_CHANGE_ANIMATION = 1 -- Prevents player party animation being set to "frozen" at the start of a cutscene or "still" at the end |
35 | } | 41 | } |
@@ -426,6 +432,13 @@ function WaitForSpritePath(spriteName) | |||
426 | end | 432 | end |
427 | end | 433 | end |
428 | 434 | ||
435 | --- Turns off the sprite's behaviour. | ||
436 | function DisableBehaviour(spriteName) | ||
437 | local spriteId = getSpriteByAlias(spriteName) | ||
438 | local sprite = getSprite(spriteId) | ||
439 | sprite.behaviourType = BehaviourType.NONE | ||
440 | end | ||
441 | |||
429 | --- Fades out the currently playing music. | 442 | --- Fades out the currently playing music. |
430 | -- This does not block. If you want it to block, call Delay for the same amount | 443 | -- This does not block. If you want it to block, call Delay for the same amount |
431 | -- of time. | 444 | -- of time. |
@@ -456,3 +469,49 @@ function EnablePlayerControl() | |||
456 | local playerSprite = getSprite(playerId) | 469 | local playerSprite = getSprite(playerId) |
457 | playerSprite.controllable = true | 470 | playerSprite.controllable = true |
458 | end | 471 | end |
472 | |||
473 | --- Makes the specified sprite face toward the †arget sprite. | ||
474 | -- This version of the function uses the closest cardinal direction. | ||
475 | -- @param spriteName the name of the sprite to change the direction of | ||
476 | -- @param targetName the name of the sprite to face toward | ||
477 | function FaceTowardSpriteCardinally(spriteName, targetName) | ||
478 | local spriteId = getSpriteByAlias(spriteName) | ||
479 | local targetId = getSpriteByAlias(targetName) | ||
480 | local sprite = getSprite(spriteId) | ||
481 | local target = getSprite(targetId) | ||
482 | local diff = vec2i.new(target.loc:x() - sprite.loc:x(), target.loc:y() - sprite.loc:y()) | ||
483 | local dir = cardinalDirectionFacingPoint(diff) | ||
484 | |||
485 | SetDirection(spriteName, dir) | ||
486 | end | ||
487 | |||
488 | --- Detaches the sprite's followers and erases their following trails. | ||
489 | function BreakUpParty(spriteName) | ||
490 | local spriteId = getSpriteByAlias(spriteName) | ||
491 | character():breakUpParty(spriteId) | ||
492 | end | ||
493 | |||
494 | --- Makes the specified sprite solid. | ||
495 | -- This means that other sprites will be blocked if they collide with this one. | ||
496 | function MakeSpriteSolid(spriteName) | ||
497 | local spriteId = getSpriteByAlias(spriteName) | ||
498 | local sprite = getSprite(spriteId) | ||
499 | sprite.solid = true | ||
500 | end | ||
501 | |||
502 | --- Makes the specified sprite not solid. | ||
503 | -- This means that other sprites will not be blocked if they collide with this | ||
504 | -- one. | ||
505 | function MakeSpriteNotSolid(spriteName) | ||
506 | local spriteId = getSpriteByAlias(spriteName) | ||
507 | local sprite = getSprite(spriteId) | ||
508 | sprite.solid = false | ||
509 | end | ||
510 | |||
511 | --- Sets the sprite's movement speed. | ||
512 | -- As a reference: 1 is slow (good for NPCs), 2 is Lucas's default walking speed | ||
513 | function SetMovementSpeed(spriteName, speed) | ||
514 | local spriteId = getSpriteByAlias(spriteName) | ||
515 | local sprite = getSprite(spriteId) | ||
516 | sprite.movementSpeed = speed | ||
517 | 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() | |||
14 | end | 14 | end |
15 | 15 | ||
16 | function hallucination_hot_spring.enter_hot_spring() | 16 | function hallucination_hot_spring.enter_hot_spring() |
17 | gamestate.went_in_hot_spring = true | ||
18 | |||
17 | if gamestate.ionia_in_water then | 19 | if gamestate.ionia_in_water then |
18 | -- Soft cutscene start; don't show bars but do take away control | 20 | -- Soft cutscene start; don't show bars but do take away control |
19 | DisablePlayerControl() | 21 | 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() | |||
45 | 45 | ||
46 | local clausSprite = getSprite(clausId) | 46 | local clausSprite = getSprite(clausId) |
47 | clausSprite.persistent = true | 47 | clausSprite.persistent = true |
48 | |||
49 | gamestate.claus_joined = true | ||
50 | gamestate.still_has_claus = true | ||
48 | else | 51 | else |
49 | 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) | 52 | 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) |
50 | WaitForEndOfMessage() | 53 | 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 | |||
16 | 16 | ||
17 | function pink_shell.talk_to_mixolydia() | 17 | function pink_shell.talk_to_mixolydia() |
18 | SetDirection("mixolydia", Direction.UP) | 18 | SetDirection("mixolydia", Direction.UP) |
19 | SetAnimation("mixolydia", "talk") | ||
20 | StartCutscene() | ||
21 | DisplayMessage("* Oh, me, oh, my! We have visitors! `", "Mixolydia", SpeakerType.WOMAN) | ||
22 | WaitForEndOfMessage() | ||
23 | |||
24 | SetAnimation("mixolydia", "still") | ||
25 | Delay(500) | ||
26 | |||
27 | SetDirection("mixolydia", Direction.DOWN) | ||
28 | Delay(1000) | ||
29 | |||
30 | if gamestate.went_in_hot_spring then | ||
31 | SetAnimation("mixolydia", "talk") | ||
32 | DisplayMessage("* ...You people stink.", "Mixolydia", SpeakerType.WOMAN) | ||
33 | WaitForEndOfMessage() | ||
34 | |||
35 | SetAnimation("mixolydia", "still") | ||
36 | Delay(1000) | ||
37 | end | ||
38 | |||
39 | FaceTowardSpriteCardinally("mixolydia", "lucas") | ||
40 | ShowExpression("mixolydia", "confusion") | ||
41 | Delay(1000) | ||
42 | |||
43 | RemoveExpression("mixolydia") | ||
44 | SetAnimation("mixolydia", "talk") | ||
45 | DisplayMessage("* Oh, wait a minute...", "Mixolydia", SpeakerType.WOMAN) | ||
46 | WaitForEndOfMessage() | ||
47 | |||
48 | SetAnimation("mixolydia", "still") | ||
49 | Delay(1000) | ||
50 | |||
51 | SetAnimation("mixolydia", "talk") | ||
52 | DisplayMessage("* Are you Lucas?", "Mixolydia", SpeakerType.WOMAN) | ||
53 | ShowChoice("Yes", "No") | ||
54 | WaitForEndOfMessage() | ||
55 | |||
56 | if GetChoiceSelection() == 1 then | ||
57 | DisplayMessage("* This island really has done a number on you.\n\f* But I'll humor you and listen anyway.", "Mixolydia", SpeakerType.WOMAN) | ||
58 | WaitForEndOfMessage() | ||
59 | end | ||
60 | |||
61 | if gamestate.went_in_hot_spring then | ||
62 | SetAnimation("mixolydia", "still") | ||
63 | Delay(1000) | ||
64 | |||
65 | SetAnimation("mixolydia", "talk") | ||
66 | DisplayMessage("* ...Wow, you guys really stink.", "Mixolydia", SpeakerType.WOMAN) | ||
67 | WaitForEndOfMessage() | ||
68 | end | ||
69 | |||
70 | SetAnimation("mixolydia", "still") | ||
71 | Delay(2000) | ||
72 | |||
73 | SetAnimation("mixolydia", "talk") | ||
74 | DisplayMessage("* Ionia told me about you. `\n\f* I'm Mixolydia, one of the Magifolk. `\n\f* If that's too hard to remember, <Mixo>...\n... no, <Missy> will do just fine. `", "Mixolydia", SpeakerType.WOMAN) | ||
75 | WaitForEndOfMessage() | ||
76 | |||
77 | SetAnimation("mixolydia", "still") | ||
78 | Delay(2000) | ||
79 | |||
80 | SetAnimation("mixolydia", "talk") | ||
81 | DisplayMessage("* Okay... Line up here.", "Mixolydia", SpeakerType.WOMAN) | ||
82 | WaitForEndOfMessage() | ||
83 | |||
84 | SetAnimation("mixolydia", "still") | ||
85 | Delay(1000) | ||
86 | |||
87 | -- direct everyone to stand in their positions | ||
88 | BreakUpParty("lucas") | ||
89 | MakeSpriteNotSolid("lucas") | ||
90 | MakeSpriteNotSolid("mixolydia") | ||
91 | |||
92 | UnpauseSprite("lucas") | ||
93 | SetMovementSpeed("lucas", 1) | ||
94 | DirectSpriteToLocation("lucas", "lucas_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) | ||
95 | WaitForSpritePath("lucas") | ||
96 | DisableBehaviour("lucas") | ||
97 | SetDirection("lucas", Direction.DOWN) | ||
98 | SetAnimation("lucas", "tired") | ||
99 | PauseSprite("lucas") | ||
100 | SetMovementSpeed("lucas", 2) | ||
101 | Delay(100) | ||
102 | |||
103 | UnpauseSprite("kuma") | ||
104 | SetMovementSpeed("kuma", 1) | ||
105 | DirectSpriteToLocation("kuma", "kumatora_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) | ||
106 | WaitForSpritePath("kuma") | ||
107 | DisableBehaviour("kuma") | ||
108 | SetDirection("kuma", Direction.DOWN) | ||
109 | SetAnimation("kuma", "tired") | ||
110 | PauseSprite("kuma") | ||
111 | SetMovementSpeed("kuma", 0) | ||
112 | Delay(100) | ||
113 | |||
114 | UnpauseSprite("duster") | ||
115 | SetMovementSpeed("duster", 1) | ||
116 | DirectSpriteToLocation("duster", "duster_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) | ||
117 | WaitForSpritePath("duster") | ||
118 | DisableBehaviour("duster") | ||
119 | SetDirection("duster", Direction.DOWN) | ||
120 | SetAnimation("duster", "tired") | ||
121 | PauseSprite("duster") | ||
122 | SetMovementSpeed("duster", 0) | ||
123 | Delay(100) | ||
124 | |||
125 | UnpauseSprite("boney") | ||
126 | SetMovementSpeed("boney", 1) | ||
127 | DirectSpriteToLocation("boney", "boney_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) | ||
128 | WaitForSpritePath("boney") | ||
129 | DisableBehaviour("boney") | ||
130 | SetDirection("boney", Direction.DOWN) | ||
131 | SetAnimation("boney", "tired") | ||
132 | PauseSprite("boney") | ||
133 | SetMovementSpeed("boney", 0) | ||
134 | Delay(100) | ||
135 | |||
136 | if gamestate.still_has_claus then | ||
137 | UnpauseSprite("join_claus") | ||
138 | SetMovementSpeed("join_claus", 1) | ||
139 | DirectSpriteToLocation("join_claus", "claus_lineup", PathfindingOptions.CARDINAL_DIRECTIONS_ONLY) | ||
140 | WaitForSpritePath("join_claus") | ||
141 | DisableBehaviour("join_claus") | ||
142 | SetDirection("join_claus", Direction.DOWN) | ||
143 | SetAnimation("join_claus", "tired") | ||
144 | PauseSprite("join_claus") | ||
145 | SetMovementSpeed("join_claus", 0) | ||
146 | end | ||
147 | |||
148 | MakeSpriteSolid("lucas") | ||
149 | Delay(1000) | ||
150 | |||
151 | if gamestate.went_in_hot_spring then | ||
152 | SetAnimation("mixolydia", "talk") | ||
153 | DisplayMessage("* ...Yuck. What a stench.", "Mixolydia", SpeakerType.WOMAN) | ||
154 | WaitForEndOfMessage() | ||
155 | |||
156 | SetAnimation("mixolydia", "still") | ||
157 | Delay(1000) | ||
158 | end | ||
159 | |||
160 | SetAnimation("mixolydia", "talk") | ||
161 | 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) | ||
162 | WaitForEndOfMessage() | ||
163 | |||
164 | SetAnimation("mixolydia", "still") | ||
165 | |||
166 | -- TODO: rest of scene | ||
19 | end | 167 | 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) { | |||
59 | 59 | ||
60 | void BehaviourSystem::directSpriteToLocation(int spriteId, vec2i pos, PathfindingOptions options) { | 60 | void BehaviourSystem::directSpriteToLocation(int spriteId, vec2i pos, PathfindingOptions options) { |
61 | Sprite& sprite = game_.getSprite(spriteId); | 61 | Sprite& sprite = game_.getSprite(spriteId); |
62 | sprite.orientable = true; | ||
62 | sprite.behaviourType = BehaviourType::Path; | 63 | sprite.behaviourType = BehaviourType::Path; |
63 | sprite.pathfindingDestination = pos; | 64 | sprite.pathfindingDestination = pos; |
64 | sprite.cardinalDirectionsOnly = pathfindingOptionsContains(options, PathfindingOptions::CardinalDirectionsOnly); | 65 | 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) { | |||
17 | void CharacterSystem::addSpriteToParty(int leaderId, int followerId) { | 17 | void CharacterSystem::addSpriteToParty(int leaderId, int followerId) { |
18 | Sprite& leader = game_.getSprite(leaderId); | 18 | Sprite& leader = game_.getSprite(leaderId); |
19 | Sprite& follower = game_.getSprite(followerId); | 19 | Sprite& follower = game_.getSprite(followerId); |
20 | follower.orientable = false; | ||
20 | 21 | ||
21 | vec2i targetPos = leader.loc; | 22 | vec2i targetPos = leader.loc; |
22 | 23 | ||
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) { | |||
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
93 | inline Direction cardinalDirectionFacingPoint(vec2i point) { | ||
94 | double theta = atan2(point.y(), point.x()); | ||
95 | theta /= M_PI; | ||
96 | |||
97 | if (theta < -3.0/4.0) { | ||
98 | return Direction::left; | ||
99 | } else if (theta < -1.0/4.0) { | ||
100 | return Direction::down; | ||
101 | } else if (theta < 1.0/4.0) { | ||
102 | return Direction::right; | ||
103 | } else if (theta < 3.0/4.0) { | ||
104 | return Direction::up; | ||
105 | } else { | ||
106 | return Direction::left; | ||
107 | } | ||
108 | } | ||
109 | |||
93 | #endif /* end of include guard: DIRECTION_H_AB66A90E */ | 110 | #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) { | |||
27 | game.emplaceSystem<MessageSystem>(); | 27 | game.emplaceSystem<MessageSystem>(); |
28 | game.emplaceSystem<EffectSystem>(); | 28 | game.emplaceSystem<EffectSystem>(); |
29 | 29 | ||
30 | game.loadMap("hallucination_interior"); | 30 | game.loadMap("pink_shell"); |
31 | 31 | ||
32 | vec2i warpLoc = game.getMap().getWarpPoint("debugWarp_rightside"); | 32 | vec2i warpLoc = game.getMap().getWarpPoint("fromOutside"); |
33 | 33 | ||
34 | int lucasSprite = game.emplaceSprite("lucas"); | 34 | int lucasSprite = game.emplaceSprite("lucas"); |
35 | game.getSystem<TransformSystem>().initSprite(lucasSprite, warpLoc); | 35 | game.getSystem<TransformSystem>().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) { | |||
44 | "cantCrouch", &Sprite::cantCrouch, | 44 | "cantCrouch", &Sprite::cantCrouch, |
45 | "bobsWhenNormal", &Sprite::bobsWhenNormal, | 45 | "bobsWhenNormal", &Sprite::bobsWhenNormal, |
46 | "animSlowdown", &Sprite::animSlowdown, | 46 | "animSlowdown", &Sprite::animSlowdown, |
47 | "enclosureZone", &Sprite::enclosureZone); | 47 | "enclosureZone", &Sprite::enclosureZone, |
48 | "movementSpeed", &Sprite::movementSpeed, | ||
49 | "solid", &Sprite::solid, | ||
50 | "behaviourType", &Sprite::behaviourType); | ||
48 | 51 | ||
49 | engine_.new_usertype<MessageSystem>( | 52 | engine_.new_usertype<MessageSystem>( |
50 | "message", | 53 | "message", |
@@ -230,6 +233,8 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { | |||
230 | loadMapScripts(filename); | 233 | loadMapScripts(filename); |
231 | }); | 234 | }); |
232 | 235 | ||
236 | engine_.set_function("cardinalDirectionFacingPoint", &cardinalDirectionFacingPoint); | ||
237 | |||
233 | engine_.script_file("../res/scripts/common.lua"); | 238 | engine_.script_file("../res/scripts/common.lua"); |
234 | } | 239 | } |
235 | 240 | ||