From d58b7a38137431b923934c9cf66ac2ed88fa3963 Mon Sep 17 00:00:00 2001 From: Lajos Meszaros Date: Thu, 7 Sep 2023 18:08:00 +0200 Subject: [PATCH] feat: fill in the game displays when a game is found --- assets/i18n.json | 2 +- src/entities/GameDisplay.ts | 15 ++++--- src/entities/Goblin.ts | 6 ++- src/entities/MirrorOnWall.ts | 4 +- src/entities/PCGame.ts | 9 ++++- src/gameStateManager.ts | 20 +++++----- src/rooms/leftCorridor.ts | 76 +++++++++++++++++++++++++++++++----- src/rooms/mainHall.ts | 2 +- 8 files changed, 101 insertions(+), 33 deletions(-) diff --git a/assets/i18n.json b/assets/i18n.json index 2cf9072..8359f3a 100644 --- a/assets/i18n.json +++ b/assets/i18n.json @@ -59,6 +59,6 @@ "english": "The mirror is missing from the wall" }, "unmounted-game-display": { - "english": "Empty game display" + "english": "A pc game is missing from the display" } } diff --git a/src/entities/GameDisplay.ts b/src/entities/GameDisplay.ts index 4dcbf46..41eabef 100644 --- a/src/entities/GameDisplay.ts +++ b/src/entities/GameDisplay.ts @@ -34,12 +34,7 @@ export class GameDisplay extends Entity { this.propVariant = new Variable('string', 'variant', variant) this.propIsMounted = new Variable('bool', 'isMounted', false) - this.script?.properties.push( - new Label('[unmounted-game-display]'), - Interactivity.off, - this.propVariant, - this.propIsMounted, - ) + this.script?.properties.push(this.propVariant, this.propIsMounted) this.script?.on('init', () => { return ` @@ -53,6 +48,7 @@ export class GameDisplay extends Entity { this.script?.on('initend', () => { return [ + new Label(`[unmounted-game-display]`), ` if (${this.propVariant.name} == "mesterlovesz") { ${new TweakSkin(TEXTURES['blank'], TEXTURES['mesterlovesz'])} @@ -81,6 +77,13 @@ export class GameDisplay extends Entity { `, ] }) + + this.script?.on('mount', () => { + return ` + ${new Transparency(1)} + ${new Label(`[game--~${this.propVariant.name}~]`)} + ` + }) } get variant() { diff --git a/src/entities/Goblin.ts b/src/entities/Goblin.ts index 3eee60e..cb12313 100644 --- a/src/entities/Goblin.ts +++ b/src/entities/Goblin.ts @@ -28,7 +28,7 @@ export class Goblin extends Entity { isBusy: Variable doneSpeaking: ScriptSubroutine - constructor({ gameStateMarker, ...props }: EntityConstructorPropsWithoutSrc & { gameStateMarker: Entity }) { + constructor({ gameStateManager, ...props }: EntityConstructorPropsWithoutSrc & { gameStateManager: Entity }) { super({ src: 'npc/goblin_base', ...props, @@ -85,7 +85,9 @@ export class Goblin extends Entity { set ${isBusy.name} 1 if (^$param1 isclass pcgame) { - sendevent goblin_received_a_game ${gameStateMarker.ref} nop + set £variant $~^$param1~__variant + + sendevent goblin_received_a_game ${gameStateManager.ref} ~£variant~ random 20 { speak -h [goblin_victory3_shorter] ${doneSpeaking.invoke()} diff --git a/src/entities/MirrorOnWall.ts b/src/entities/MirrorOnWall.ts index 0c9ecfc..a93a590 100644 --- a/src/entities/MirrorOnWall.ts +++ b/src/entities/MirrorOnWall.ts @@ -1,5 +1,5 @@ import { Entity, EntityConstructorPropsWithoutSrc, EntityModel } from 'arx-level-generator' -import { Interactivity, Label, Scale, Transparency, Variable } from 'arx-level-generator/scripting/properties' +import { Interactivity, Label, Scale, Shadow, Transparency, Variable } from 'arx-level-generator/scripting/properties' export class MirrorOnWall extends Entity { protected propIsMounted: Variable @@ -41,6 +41,6 @@ export class MirrorOnWall extends Entity { ` }) - this.script?.properties.push(new Label('[unmounted-mirror-on-wall]'), new Scale(2), this.propIsMounted) + this.script?.properties.push(new Label('[unmounted-mirror-on-wall]'), Shadow.off, new Scale(2), this.propIsMounted) } } diff --git a/src/entities/PCGame.ts b/src/entities/PCGame.ts index e2187c5..4d6c5e1 100644 --- a/src/entities/PCGame.ts +++ b/src/entities/PCGame.ts @@ -72,6 +72,7 @@ export const pcGameMesh = await loadOBJ('./pcgame', { export class PCGame extends Entity { private propVariant: Variable + private propVariantPublic: Variable constructor({ variant, ...props }: PCGameConstructorProps) { super({ @@ -91,8 +92,10 @@ export class PCGame extends Entity { this.withScript() this.propVariant = new Variable('string', 'variant', variant) + // a copy of propVariant to be able to read it outside the entity + this.propVariantPublic = new Variable('global string', `${this.ref}__variant`, variant) - this.script?.properties.push(this.propVariant) + this.script?.properties.push(this.propVariant, this.propVariantPublic) this.script?.on('init', () => { if (!this.script?.isRoot) { @@ -107,6 +110,9 @@ export class PCGame extends Entity { return '' } + // at this point this.ref is pointing to the root entity, not the invoker, so + // we have to use the private version of variant + return [ new Label(`[game--~${this.propVariant.name}~]`), ` @@ -145,5 +151,6 @@ export class PCGame extends Entity { set variant(value: PCGameVariant) { this.propVariant.value = value + this.propVariantPublic.value = value } } diff --git a/src/gameStateManager.ts b/src/gameStateManager.ts index 3f3736d..8258023 100644 --- a/src/gameStateManager.ts +++ b/src/gameStateManager.ts @@ -61,12 +61,12 @@ const achievementLittering = new ScriptSubroutine('achievement_littering', () => export const createGameStateManager = (settings: Settings) => { const manager = Entity.marker.withScript() - const numberOfGamesTheGoblinHas = new Variable('int', 'number_of_games_the_goblin_has', 0) + const numberOfCollectedGames = new Variable('int', 'number_of_collected_games', 0) const playerFoundAnyGames = new Variable('bool', 'player_found_any_games', false) const isGoblinDead = new Variable('bool', 'is_goblin_dead', false) const haveLittered = new Variable('bool', 'have_littered', false) - manager.script?.properties.push(numberOfGamesTheGoblinHas, playerFoundAnyGames, isGoblinDead) + manager.script?.properties.push(numberOfCollectedGames, playerFoundAnyGames, isGoblinDead) manager.script?.subroutines.push( tutorialWelcome, @@ -81,25 +81,25 @@ export const createGameStateManager = (settings: Settings) => { if (settings.mode === 'production') { manager.script?.on('init', () => { return ` - TIMERwelcome -m 1 3000 ${tutorialWelcome.invoke()} - ` + TIMERwelcome -m 1 3000 ${tutorialWelcome.invoke()} + ` }) } - manager.script?.on('goblin_received_a_game', () => { + manager.script?.on('game_collected', () => { return ` - inc ${numberOfGamesTheGoblinHas.name} 1 + inc ${numberOfCollectedGames.name} 1 - if (${numberOfGamesTheGoblinHas.name} == 1) { + if (${numberOfCollectedGames.name} == 1) { ${tutorialGaveGameToGoblin.invoke()} } - if (${numberOfGamesTheGoblinHas.name} == 2) { + if (${numberOfCollectedGames.name} == 2) { ${achievementListenSmall.invoke()} } - if (${numberOfGamesTheGoblinHas.name} == 5) { + if (${numberOfCollectedGames.name} == 5) { ${achievementListenMedium.invoke()} } - if (${numberOfGamesTheGoblinHas.name} == 8) { + if (${numberOfCollectedGames.name} == 8) { ${achievementListenLarge.invoke()} } ` diff --git a/src/rooms/leftCorridor.ts b/src/rooms/leftCorridor.ts index 43ef0da..3af8cf3 100644 --- a/src/rooms/leftCorridor.ts +++ b/src/rooms/leftCorridor.ts @@ -32,15 +32,71 @@ export const createLeftCorridor = async ( 350, variants.length, theta + MathUtils.degToRad(2.4), - ).map((position, i) => { - return new GameDisplay({ - variant: variants[i], - position, - orientation: new Rotation( - MathUtils.degToRad(90) + i * angle + theta, - MathUtils.degToRad(180), - MathUtils.degToRad(-90), - ), + ).reduce( + (acc, position, i) => { + const variant = variants[i] + const gameDisplay = new GameDisplay({ + variant, + position, + orientation: new Rotation( + MathUtils.degToRad(90) + i * angle + theta, + MathUtils.degToRad(180), + MathUtils.degToRad(-90), + ), + }) + + return { ...acc, [variant]: gameDisplay } + }, + {} as Record, + ) + + gameStateManager.script?.on('goblin_received_a_game', () => { + return ` + sendevent game_collected ${gameStateManager.ref} nop + + if (^$param1 == "mesterlovesz") { + sendevent mount ${gameDisplays['mesterlovesz'].ref} nop + } + if (^$param1 == "mortyr") { + sendevent mount ${gameDisplays['mortyr'].ref} nop + } + if (^$param1 == "wolfschanze") { + sendevent mount ${gameDisplays['wolfschanze'].ref} nop + } + if (^$param1 == "traktor-racer") { + sendevent mount ${gameDisplays['traktor-racer'].ref} nop + } + if (^$param1 == "americas-10-most-wanted") { + sendevent mount ${gameDisplays['americas-10-most-wanted'].ref} nop + } + if (^$param1 == "big-rigs") { + sendevent mount ${gameDisplays['big-rigs'].ref} nop + } + if (^$param1 == "streets-racer") { + sendevent mount ${gameDisplays['streets-racer'].ref} nop + } + if (^$param1 == "bikini-karate-babes") { + sendevent mount ${gameDisplays['bikini-karate-babes'].ref} nop + } + ` + }) + + Object.entries(gameDisplays).forEach(([variant, gameDisplay]) => { + gameDisplay.script?.on('combine', () => { + return ` + if (^$param1 isclass pcgame) { + set £variant $~^$param1~__variant + + if (£variant == "${variant}") { + sendevent game_collected ${gameStateManager.ref} nop + destroy ^$param1 + play clip + sendevent mount ${gameDisplay.ref} nop + } else { + speak -p [player_not_this_way] + } + } + ` }) }) @@ -55,7 +111,7 @@ export const createLeftCorridor = async ( return { meshes: [...bases], - entities: [rootMirror, mirror, ...gameDisplays], + entities: [rootMirror, mirror, ...Object.values(gameDisplays)], lights: [], zones: [], _: {}, diff --git a/src/rooms/mainHall.ts b/src/rooms/mainHall.ts index 3f30559..a57b9a2 100644 --- a/src/rooms/mainHall.ts +++ b/src/rooms/mainHall.ts @@ -41,7 +41,7 @@ export const createMainHall = async ( const goblin = new Goblin({ position: new Vector3(-200, -2, 425), orientation: new Rotation(0, MathUtils.degToRad(-100), 0), - gameStateMarker: gameStateManager, + gameStateManager, }) if (settings.mode === 'production') {