Skip to content

Commit cef8bfd

Browse files
authored
Merge pull request #108 from NarraLeaf/develop
[prod] 0.8.7
2 parents 8cd27e6 + dd035b3 commit cef8bfd

12 files changed

Lines changed: 345 additions & 342 deletions

File tree

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## [0.8.7]
4+
5+
### Fixed
6+
7+
- Refactored Sound System: fixed offset handling and playback management.
8+
9+
## [0.8.6]
10+
11+
### Fixed
12+
13+
- Incorrect behavior of `Menu.enableWhen` and `Menu.showWhen`
14+
15+
## [0.8.5]
16+
17+
### Fixed
18+
19+
- Incorrect signature of `Menu.enableWhen` and `Menu.showWhen`
20+
321
## [0.8.4]
422

523
### _Feature_

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "narraleaf-react",
3-
"version": "0.8.4",
3+
"version": "0.8.7",
44
"description": "A React visual novel player framework",
55
"main": "./dist/main.js",
66
"types": "./dist/index.d.ts",
@@ -96,6 +96,7 @@
9696
"author": "helloyork@icloud.com",
9797
"license": "MPL-2.0",
9898
"dependencies": {
99+
"@narraleaf/sound": "0.1.0",
99100
"client-only": "^0.0.1",
100101
"clsx": "^2.1.1",
101102
"howler": "^2.2.4",

src/game/nlcore/action/actionTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export type SoundActionContentType = {
130130
[K in typeof SoundActionTypes[keyof typeof SoundActionTypes]]:
131131
K extends "sound:play" ? [FadeOptions] :
132132
K extends "sound:stop" ? [FadeOptions] :
133-
K extends "sound:setVolume" ? [volumn: number, duration: number] :
133+
K extends "sound:setVolume" ? [volume: number, duration: number] :
134134
K extends "sound:setRate" ? [number] :
135135
K extends "sound:pause" ? [FadeOptions] :
136136
K extends "sound:resume" ? [FadeOptions] :

src/game/nlcore/action/actions/sceneAction.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
3939
.flush();
4040
scene.local.init(state.getStorable());
4141

42-
state.getExposedStateAsync<ExposedStateType.scene>(scene, (exposed) => {
43-
SceneAction.initBackgroundMusic(scene, exposed);
42+
state.getExposedStateAsync<ExposedStateType.scene>(scene, async (exposed) => {
43+
await SceneAction.initBackgroundMusic(scene, exposed);
4444
awaitable.resolve(next);
4545

4646
state.logger.debug("Scene Action", "Scene init");
@@ -49,10 +49,19 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
4949
return awaitable;
5050
}
5151

52-
static initBackgroundMusic(scene: Scene, exposed: ExposedState[ExposedStateType.scene]) {
53-
if (scene.state.backgroundMusic) {
54-
exposed.setBackgroundMusic(scene.state.backgroundMusic, scene.config.backgroundMusicFade);
52+
/**
53+
* Initialize background music for the target scene.
54+
* Waits until the previous BGM has completely faded out (if any) before
55+
* resolving, ensuring seamless audio transition when jumping between scenes.
56+
*/
57+
static async initBackgroundMusic(scene: Scene, exposed: ExposedState[ExposedStateType.scene]): Promise<void> {
58+
if (!scene.state.backgroundMusic) {
59+
return;
5560
}
61+
// `setBackgroundMusic` already handles fade-out of the previous track and
62+
// fade-in of the new track. We simply await it so that the caller can
63+
// chain subsequent actions after the transition finishes.
64+
await exposed.setBackgroundMusic(scene.state.backgroundMusic, scene.config.backgroundMusicFade);
5665
}
5766

5867
static createSceneSnapshot(scene: Scene, state: GameState): SceneSnapshot {

src/game/nlcore/common/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { GameConfig, SavedGame, NotificationToken, SavedGameMetaData } from "../
88
import type { LayoutRouter } from "@lib/game/player/lib/PageRouter/router";
99
import { KeyBindingType, WebKeyboardKey } from "../game/types";
1010
import { KeyBindingValue } from "../game/keyMap";
11+
import { SoundType } from "@core/elements/sound";
1112

1213
export * from "@core/elements/type";
1314
export type {
@@ -25,4 +26,5 @@ export type {
2526

2627
export {
2728
KeyBindingType,
29+
SoundType,
2830
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ControlAction } from "../../action/actions/controlAction";
2+
import { Chained, Proxied } from "../../action/chain";
3+
import { LogicAction } from "../../game";
4+
import { Control } from "../control";
5+
6+
7+
export class DevTools {
8+
public static getActionId(action: LogicAction.Actions): string {
9+
return action.getId();
10+
}
11+
12+
public static setActionId(action: LogicAction.Actions, id: string): LogicAction.Actions {
13+
action.setId(id);
14+
return action;
15+
}
16+
17+
public static chainToActions(chain: Proxied<LogicAction.GameElement, Chained<LogicAction.Actions>>): LogicAction.Actions[] {
18+
return chain.getActions();
19+
}
20+
21+
public static wrapAction(action: LogicAction.Actions[] | Proxied<LogicAction.GameElement, Chained<LogicAction.Actions>>): ControlAction {
22+
const actions = Chained.isChained(action) ? action.getActions() : action;
23+
return Control.do(actions);
24+
}
25+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export { Gallery } from "./Gallery";
1+
export { Gallery } from "./Gallery";
2+
export { DevTools } from "./DevTools";

src/game/nlcore/elements/condition.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ export class Lambda<T = any> {
2525
return Lambda.isLambda(obj) ? obj : new Lambda(obj);
2626
}
2727

28+
/**@internal */
29+
public static not(lambda: Lambda<boolean>): Lambda<boolean> {
30+
return new Lambda((ctx) => {
31+
return !lambda.evaluate(ctx).value;
32+
});
33+
}
34+
2835
/**@internal */
2936
handler: LambdaHandler<T>;
3037

src/game/nlcore/elements/menu.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ export class Menu extends Actionable<any, Menu> {
163163
* ]);
164164
* ```
165165
*/
166-
public enableWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
166+
public enableWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence | SentencePrompt, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
167167
return this.choose({
168168
prompt,
169169
action,
170170
config: {
171-
disabled: Lambda.from(condition)
171+
disabled: Lambda.not(Lambda.from(condition))
172172
}
173173
});
174174
}
@@ -182,12 +182,12 @@ export class Menu extends Actionable<any, Menu> {
182182
* ]);
183183
* ```
184184
*/
185-
public showWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
185+
public showWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence | SentencePrompt, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
186186
return this.choose({
187187
prompt,
188188
action,
189189
config: {
190-
hidden: Lambda.from(condition)
190+
hidden: Lambda.not(Lambda.from(condition))
191191
}
192192
});
193193
}

src/game/player/elements/Player.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ export default function Player(
156156
state.stage.update();
157157
}
158158

159+
useEffect(() => {
160+
state.audioManager.initialize();
161+
}, []);
162+
159163
useEffect(() => {
160164
game.getLiveGame().setGameState(state);
161165
if (story && !game.getLiveGame().isPlaying()) {

0 commit comments

Comments
 (0)