Skip to content

Game assessments state refreshes #1891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions public/assets/mockChapter0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ objectives
finish

gameStartActions
show_dialogue(welcome) if userstate.assessments.301
show_dialogue(unwelcome) if !userstate.assessments.301
// replace 173 with assessment id
show_dialogue(welcome) if userstate.assessments.173
show_dialogue(unwelcome) if !userstate.assessments.173

checkpointCompleteActions
show_dialogue(done)
Expand Down Expand Up @@ -92,16 +93,27 @@ dialogues
update_character(scottie, happy)

unwelcome
1
@scottie, sad
You haven't finished assessment
Finish assessment 301 first and come back?
navigate_to_assessment(405)
Anyways, welcome.
@you
Can I still go to places?
@scottie, happy
Yes, you can remain here.
move_character(scottie, hallway, right)
Finish assessment 173 first and come back?
navigate_to_assessment(173)
goto 2
2
@scottie
Have you finished the assignment?
prompt: Have you finished?
Yes -> goto 4
I don't want to -> goto 3
3
@scottie
OK
4
@scottie
Hmmm
update_assessment_status*()
Let me check
goto 2 if !userstate.assessments.173 else 3

what, What should I do now, Scottie?
@you
Expand Down
4 changes: 4 additions & 0 deletions src/features/game/action/GameActionExecuter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export default class GameActionExecuter {
case GameActionType.NavigateToAssessment:
await globalAPI.promptNavigateToAssessment(actionParams.assessmentId);
return;
case GameActionType.UpdateAssessmentStatus:
await globalAPI.updateAssessmentState();
return;
case GameActionType.Delay:
await sleep(actionParams.duration);
return;
Expand All @@ -115,6 +118,7 @@ export default class GameActionExecuter {
case GameActionType.UpdateCharacter:
return true;
case GameActionType.NavigateToAssessment:
case GameActionType.UpdateAssessmentStatus:
case GameActionType.PreviewLocation:
case GameActionType.ChangeBackground:
case GameActionType.StartAnimation:
Expand Down
1 change: 1 addition & 0 deletions src/features/game/action/GameActionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum GameActionType {
PlaySFX = 'PlaySFX',
ShowObjectLayer = 'ShowObjectLayer',
NavigateToAssessment = 'NavigateToAssessment',
UpdateAssessmentStatus = 'UpdateAssessmentStatus',
Delay = 'Delay'
}

Expand Down
19 changes: 15 additions & 4 deletions src/features/game/dialogue/GameDialogueGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import GameActionConditionChecker from '../action/GameActionConditionChecker';
import { DialogueLine, DialogueObject, PartName } from './GameDialogueTypes';

/**
Expand All @@ -18,18 +19,28 @@ export default class DialogueGenerator {
}

/**
* @returns {DialogueLine} returns the dialgoueLine that is played next,
* @returns {Promise<DialogueLine>} returns the dialgoueLine that is played next,
* based on what is dictated by the dialogueContent
*/
public generateNextLine(): DialogueLine {
public async generateNextLine(): Promise<DialogueLine> {
const dialogueLine = this.dialogueContent.get(this.currPart)![this.currLineNum];
if (!dialogueLine || !dialogueLine.line) {
return { line: '' };
}

if (dialogueLine.goto) {
if (this.dialogueContent.get(dialogueLine.goto)) {
this.currPart = dialogueLine.goto;
let currPart: string | null = dialogueLine.goto.part;
const conditionCheck = await GameActionConditionChecker.checkAllConditionsSatisfied(
dialogueLine.goto.conditions
);
if (!conditionCheck) {
currPart = dialogueLine.goto.altPart;
}

if (!currPart) {
this.currLineNum++;
} else if (this.dialogueContent.get(currPart)) {
this.currPart = currPart;
this.currLineNum = 0;
} else {
return { line: '' };
Expand Down
2 changes: 1 addition & 1 deletion src/features/game/dialogue/GameDialogueManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default class DialogueManager {
private async showNextLine(resolve: () => void) {
GameGlobalAPI.getInstance().playSound(SoundAssets.dialogueAdvance.key);
const { line, speakerDetail, actionIds, prompt } =
this.getDialogueGenerator().generateNextLine();
await this.getDialogueGenerator().generateNextLine();
const lineWithName = line.replace('{name}', this.getUsername());
this.getDialogueRenderer().changeText(lineWithName);
this.getSpeakerRenderer().changeSpeakerTo(speakerDetail);
Expand Down
8 changes: 6 additions & 2 deletions src/features/game/dialogue/GameDialogueTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IGameActionable } from '../action/GameActionTypes';
import { ActionCondition, IGameActionable } from '../action/GameActionTypes';
import { SpeakerDetail } from '../character/GameCharacterTypes';

/**
Expand All @@ -24,7 +24,11 @@ export type Choice = string;
export type DialogueLine = IGameActionable & {
line: string;
speakerDetail?: SpeakerDetail | null;
goto?: PartName;
goto?: {
conditions: ActionCondition[];
part: PartName;
altPart: PartName | null;
};
prompt?: Prompt;
};

Expand Down
18 changes: 16 additions & 2 deletions src/features/game/parser/DialogueParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GameItemType } from '../location/GameMapTypes';
import { mapValues } from '../utils/GameUtils';
import StringUtils from '../utils/StringUtils';
import ActionParser from './ActionParser';
import ConditionParser from './ConditionParser';
import Parser from './Parser';
import PromptParser from './PromptParser';
import SpeakerParser from './SpeakerParser';
Expand Down Expand Up @@ -92,7 +93,20 @@ export default class DialogueParser {
const rawStr = lines[currIndex];
switch (true) {
case isGotoLabel(rawStr):
dialogueLines[dialogueLines.length - 1].goto = rawStr.split(' ')[1];
const [gotoString, postpend] = StringUtils.splitByChar(rawStr, 'if');
const [conditionalsString, altPart] = postpend
? StringUtils.splitByChar(postpend, 'else')
: [null, null];
const conditions = conditionalsString
? StringUtils.splitByChar(conditionalsString, 'AND').map(condition =>
ConditionParser.parse(condition)
)
: [];
dialogueLines[dialogueLines.length - 1].goto = {
conditions,
part: gotoString.split(' ')[1],
altPart: altPart
};
break;
case isPrompt(rawStr):
const rawTitle = rawStr;
Expand Down Expand Up @@ -129,7 +143,7 @@ export default class DialogueParser {
}

const isInteger = (line: string) => new RegExp(/^[0-9]+$/).test(line);
const isGotoLabel = (line: string) => new RegExp(/^goto [0-9]+$/).test(line);
const isGotoLabel = (line: string) => new RegExp(/^goto [0-9]+.*$/).test(line);
const isActionLabel = (line: string) => line && (line[0] === '\t' || line.slice(0, 4) === ' ');
const isSpeaker = (line: string) => line && line[0] === '@';
const isPrompt = (line: string) => line.trim().startsWith('prompt:');
Expand Down
1 change: 1 addition & 0 deletions src/features/game/parser/ParserConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const stringToActionTypeMap = {
preview_location: GameActionType.PreviewLocation,
show_object_layer: GameActionType.ShowObjectLayer,
navigate_to_assessment: GameActionType.NavigateToAssessment,
update_assessment_status: GameActionType.UpdateAssessmentStatus,
delay: GameActionType.Delay
};

Expand Down
4 changes: 4 additions & 0 deletions src/features/game/scenes/gameManager/GameGlobalAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@ class GameGlobalAPI {
}
}

public async updateAssessmentState() {
await SourceAcademyGame.getInstance().getUserStateManager().loadAssessments();
}

/////////////////////
// Characters //
/////////////////////
Expand Down
32 changes: 31 additions & 1 deletion src/features/game/scenes/roomPreview/RoomPreview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { createContext } from 'src/commons/utils/JsSlangHelper';
import ImageAssets from '../../assets/ImageAssets';
import { getAwardProp } from '../../awards/GameAwardsHelper';
import GameAwardsManager from '../../awards/GameAwardsManager';
import CommonBackButton from '../../commons/CommonBackButton';
import { Constants, screenCenter, screenSize } from '../../commons/CommonConstants';
import CommonTextHover from '../../commons/CommonTextHover';
import { ItemId } from '../../commons/CommonTypes';
import { addLoadingScreen } from '../../effects/LoadingScreen';
import GameEscapeManager from '../../escape/GameEscapeManager';
Expand All @@ -14,10 +16,11 @@ import { Layer } from '../../layer/GameLayerTypes';
import GamePhaseManager from '../../phase/GamePhaseManager';
import { GamePhaseType } from '../../phase/GamePhaseTypes';
import SourceAcademyGame from '../../SourceAcademyGame';
import { createButton } from '../../utils/ButtonUtils';
import { mandatory } from '../../utils/GameUtils';
import { loadImage, loadSound, loadSpritesheet } from '../../utils/LoaderUtils';
import { resizeOverflow } from '../../utils/SpriteUtils';
import { roomDefaultCode } from './RoomPreviewConstants';
import { RoomConstants, roomDefaultCode } from './RoomPreviewConstants';
import { createCMRGamePhases, createVerifiedHoverContainer } from './RoomPreviewHelper';

/**
Expand Down Expand Up @@ -108,6 +111,30 @@ export default class RoomPreview extends Phaser.Scene {
})
);

const roomRefreshHover = new CommonTextHover(
this,
RoomConstants.refreshButton.x - 200,
RoomConstants.refreshButton.y - 30,
'Refresh Room'
);

const backButton = new CommonBackButton(this, () => {
this.getLayerManager().clearAllLayers();
this.scene.start('MainMenu');
});

const refreshButton = createButton(this, {
assetKey: ImageAssets.chapterRepeatButton.key,
onUp: async () => {
await SourceAcademyGame.getInstance().loadRoomCode();
this.studentCode = SourceAcademyGame.getInstance().getRoomCode();
this.getLayerManager().clearAllLayers();
this.scene.restart();
},
onHover: () => roomRefreshHover.setVisible(true),
onOut: () => roomRefreshHover.setVisible(false)
}).setPosition(RoomConstants.refreshButton.x, RoomConstants.refreshButton.y);

// Execute create
await this.eval(`create();`);
SourceAcademyGame.getInstance().getSoundManager().playBgMusic(Constants.nullInteractionId);
Expand All @@ -122,6 +149,9 @@ export default class RoomPreview extends Phaser.Scene {

// Add verified tag
this.getLayerManager().addToLayer(Layer.UI, this.getVerifCont());
this.getLayerManager().addToLayer(Layer.UI, backButton);
this.getLayerManager().addToLayer(Layer.UI, refreshButton);
this.getLayerManager().addToLayer(Layer.UI, roomRefreshHover);
}

public update() {
Expand Down
4 changes: 3 additions & 1 deletion src/features/game/scenes/roomPreview/RoomPreviewConstants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import FontAssets from '../../assets/FontAssets';
import { screenSize } from '../../commons/CommonConstants';
import { BitmapFontStyle } from '../../commons/CommonTypes';

export const roomDefaultCode = `
Expand Down Expand Up @@ -41,5 +42,6 @@ export const RoomConstants = {
assessmentNumber: 'MYROOM',
verifiedText: 'VERIFIED',
tag: { width: 128, height: 50 },
hoverTagTextConfig: { x: 64, y: 0, oriX: 0.5, oriY: 0.55 }
hoverTagTextConfig: { x: 64, y: 0, oriX: 0.5, oriY: 0.55 },
refreshButton: { x: 0.95 * screenSize.x, y: 0.92 * screenSize.y }
};