diff --git a/resources/config/start_state.json b/resources/config/start_state.json new file mode 100644 index 0000000..21d0da4 --- /dev/null +++ b/resources/config/start_state.json @@ -0,0 +1,1527 @@ +{ + "chatHistory": [ + [], + [], + [] + ], + "chatPreviewMsg": [ + "", + "", + "" + ], + "chatUnread": [ + true, + true, + true + ], + "currentLocationName": "", + "globalFloats": { + "player_hp": 200.0 + }, + "globalInts": {}, + "inventory": { + "items": [] + }, + "isDarklands": false, + "isDawn": false, + "isNight": false, + "locations": { + "location_dorm": { + "dialogueState": { + "active": true, + "currentNodeId": "line_1", + "dialogueId": "dialog_start001" + }, + "interactiveObjectStates": [ + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 10.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 10.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -10.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -10.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 15.699999809265137, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 15.699999809265137, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": 19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "animTask": { + "durationMs": 10.0, + "elapsedMs": 0.0, + "startPosX": 1.100000023841858, + "startPosY": 0.9695000052452087, + "startPosZ": -19.950000762939453, + "startRotY": 0.0, + "startScale": 1.0, + "targetPosX": 1.100000023841858, + "targetPosY": 0.9695000052452087, + "targetPosZ": -19.950000762939453, + "targetRotY": 1.5707963705062866, + "targetScale": 1.0, + "type": 1 + }, + "isActive": true, + "isAnimating": true, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "animTask": { + "durationMs": 10.0, + "elapsedMs": 0.0, + "startPosX": -1.100000023841858, + "startPosY": 0.9695000052452087, + "startPosZ": -19.950000762939453, + "startRotY": 0.0, + "startScale": 1.0, + "targetPosX": -1.100000023841858, + "targetPosY": 0.9695000052452087, + "targetPosZ": -19.950000762939453, + "targetRotY": -1.5707963705062866, + "targetScale": 1.0, + "type": 1 + }, + "isActive": true, + "isAnimating": true, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 6.664400577545166, + "positionY": 0.8999999761581421, + "positionZ": -12.526200294494629, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 5.842959880828857, + "positionY": 0.9284919500350952, + "positionZ": -12.466099739074707, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.0, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 5.1006693840026855, + "positionY": 1.0181854963302612, + "positionZ": -11.958325386047363, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 2.825000047683716, + "positionY": 0.9695000052452087, + "positionZ": -14.300000190734863, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -2.825000047683716, + "positionY": 0.9695000052452087, + "positionZ": -14.300000190734863, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -15.699999809265137, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.100000023841858, + "positionY": 0.9695000052452087, + "positionZ": -15.699999809265137, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 2.8249998092651367, + "positionY": 2.8500001430511475, + "positionZ": -12.850000381469727, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": false, + "isAnimating": false, + "positionX": 4.949999809265137, + "positionY": 2.8500001430511475, + "positionZ": -14.25, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -4.949999809265137, + "positionY": 2.8500001430511475, + "positionZ": -14.25, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 2.8500001430511475, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 2.8500001430511475, + "positionZ": 4.250000476837158, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 4.949999809265137, + "positionY": 2.8500001430511475, + "positionZ": -19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -4.949999809265137, + "positionY": 2.8500001430511475, + "positionZ": -19.950000762939453, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": false, + "isAnimating": false, + "positionX": 0.0, + "positionY": 3.2049999237060547, + "positionZ": 0.0, + "rotationY": 0.0, + "scale": 1.0 + } + ], + "locationState": { + "activeNavigationIndex": 0, + "cameraAzimuth": -2.3499999046325684, + "cameraInclination": 1.103600025177002, + "isDarklands": false, + "isDawn": false, + "isNight": false, + "targetInteractNpcIndex": -1, + "targetInteractiveObjectIndex": -1, + "targetTeleportZoneIndex": -1, + "tutorialInteractiveObjectsLocked": true + }, + "npcStates": [ + { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 1.5707963705062866, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + -6.334780216217041, + 0.0, + -15.038200378417969 + ], + "hp": 100.0, + "pathWaypoints": [ + [ + -6.296899795532227, + 0.0, + -15.041899681091309 + ] + ], + "position": [ + -6.334780216217041, + 0.0, + -15.038200378417969 + ], + "requestedWalkTarget": [ + -6.334780216217041, + 0.0, + -15.038200378417969 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + -6.296899795532227, + 0.0, + -15.041899681091309 + ] + } + ], + "playerState": { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": true, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 0.0, + 0.0, + 0.0 + ], + "hp": 200.0, + "pathWaypoints": [ + [ + 6.8031005859375, + 0.0, + -14.641900062561035 + ] + ], + "position": [ + 6.7634501457214355, + 0.0, + -14.60219955444336 + ], + "requestedWalkTarget": [ + 6.7634501457214355, + 0.0, + -14.60219955444336 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 6.8031005859375, + 0.0, + -14.641900062561035 + ] + }, + "scriptGlobals": { + "alik_door_opened": false, + "bathroom_door_opened": false, + "journal_picked_up": false, + "phone_picked_up": false, + "player_door_opened": false + }, + "teleportZoneState": { + "tp_dorm_to_2floor": false, + "tp_dorm_to_loc2": false + }, + "triggerZoneState": { + "ladder_zone001": { + "enabled": true, + "playerInside": false + }, + "pickup_phone_zone001": { + "enabled": true, + "playerInside": false + }, + "taxi_zone001": { + "enabled": true, + "playerInside": false + } + } + }, + "uni_exterior": { + "dialogueState": { + "active": false + }, + "interactiveObjectStates": [ + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -27.003389358520508, + "positionY": 0.328900009393692, + "positionZ": 8.820399284362793, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -10.496715545654297, + "positionY": 0.8919645547866821, + "positionZ": -13.977367401123047, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -10.5, + "positionY": 0.335999995470047, + "positionZ": -13.999500274658203, + "rotationY": 0.0, + "scale": 1.0 + } + ], + "locationState": { + "activeNavigationIndex": 0, + "cameraAzimuth": -2.3499999046325684, + "cameraInclination": 1.103600025177002, + "isDarklands": false, + "isDawn": false, + "isNight": false, + "targetInteractNpcIndex": -1, + "targetInteractiveObjectIndex": -1, + "targetTeleportZoneIndex": -1, + "tutorialInteractiveObjectsLocked": false + }, + "npcStates": [], + "playerState": { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": true, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 0.0, + 0.0, + 0.0 + ], + "hp": 200.0, + "pathWaypoints": [], + "position": [ + 5.0, + 0.0, + -18.399999618530273 + ], + "requestedWalkTarget": [ + 5.0, + 0.0, + -18.399999618530273 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 5.0, + 0.0, + -18.399999618530273 + ] + }, + "scriptGlobals": null, + "teleportZoneState": { + "tp_loc2_to_dorm": false, + "tp_loc2_to_loc1": true + }, + "triggerZoneState": { + "darklands_exit001": { + "enabled": true, + "playerInside": false + }, + "darklands_exit003": { + "enabled": true, + "playerInside": false + }, + "darklands_exit004": { + "enabled": true, + "playerInside": false + }, + "darklands_exit005": { + "enabled": true, + "playerInside": false + }, + "taxi_zone001": { + "enabled": true, + "playerInside": false + } + } + }, + "uni_interior": { + "dialogueState": { + "active": false + }, + "interactiveObjectStates": [ + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.0, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.0, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.0, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.0, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -5.365539073944092, + "positionY": 0.9888315200805664, + "positionZ": 2.4683666229248047, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 5.0175323486328125, + "positionY": 1.3534114360809326, + "positionZ": 0.6829134821891785, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -4.959765434265137, + "positionY": 0.919700026512146, + "positionZ": 2.3698995113372803, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.6809704899787903, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.8479499816894531, + "positionY": 0.0, + "positionZ": 2.905519962310791, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -5.064300060272217, + "positionY": 1.0603100061416626, + "positionZ": 0.4027400016784668, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": false, + "isAnimating": false, + "positionX": 3.821929931640625, + "positionY": 1.0437999963760376, + "positionZ": 1.0303499698638916, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -10.496715545654297, + "positionY": -4.108035564422607, + "positionZ": -13.977367401123047, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -10.5, + "positionY": -4.664000034332275, + "positionZ": -13.999500274658203, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 1.5, + "positionY": 0.9750000238418579, + "positionZ": 6.400000095367432, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "animTask": { + "durationMs": 10.0, + "elapsedMs": 0.0, + "startPosX": 1.5, + "startPosY": 0.9750000238418579, + "startPosZ": -1.5999999046325684, + "startRotY": 0.0, + "startScale": 1.0, + "targetPosX": 1.5, + "targetPosY": 0.9750000238418579, + "targetPosZ": -1.5999999046325684, + "targetRotY": -1.5707963705062866, + "targetScale": 1.0, + "type": 1 + }, + "isActive": true, + "isAnimating": true, + "positionX": 1.5, + "positionY": 0.9750000238418579, + "positionZ": -1.5999999046325684, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.5, + "positionY": 0.9750000238418579, + "positionZ": -1.5999999046325684, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.5, + "positionY": 0.9750000238418579, + "positionZ": 6.400000095367432, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 0.9750000238418579, + "positionZ": 8.000000953674316, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -1.5, + "positionY": 0.9750000238418579, + "positionZ": -9.599998474121094, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": false, + "isAnimating": false, + "positionX": 2.25, + "positionY": 2.4499998092651367, + "positionZ": -3.999999761581421, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 0.0, + "positionY": 2.4499998092651367, + "positionZ": 12.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -3.75, + "positionY": 2.4499998092651367, + "positionZ": -12.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": false, + "isAnimating": false, + "positionX": 3.75, + "positionY": 2.4499998092651367, + "positionZ": -4.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -3.75, + "positionY": 2.4499998092651367, + "positionZ": -4.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": 3.75, + "positionY": 2.4499998092651367, + "positionZ": 4.0, + "rotationY": 0.0, + "scale": 1.0 + }, + { + "alpha": 1.0, + "isActive": true, + "isAnimating": false, + "positionX": -3.75, + "positionY": 2.4499998092651367, + "positionZ": 4.0, + "rotationY": 0.0, + "scale": 1.0 + } + ], + "locationState": { + "activeNavigationIndex": 0, + "cameraAzimuth": -2.3499999046325684, + "cameraInclination": 1.103600025177002, + "isDarklands": false, + "isDawn": false, + "isNight": false, + "targetInteractNpcIndex": -1, + "targetInteractiveObjectIndex": -1, + "targetTeleportZoneIndex": -1, + "tutorialInteractiveObjectsLocked": false + }, + "npcStates": [ + { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "hp": 100.0, + "pathWaypoints": [ + [ + -0.31001949310302734, + 0.0, + 13.974998474121094 + ] + ], + "position": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "requestedWalkTarget": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + -0.31001949310302734, + 0.0, + 13.974998474121094 + ] + }, + { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 3.1415927410125732, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 0.7996190190315247, + 0.0, + -9.556790351867676 + ], + "hp": 100.0, + "pathWaypoints": [ + [ + 0.7899808883666992, + 0.0, + -9.52500057220459 + ] + ], + "position": [ + 0.7996190190315247, + 0.0, + -9.556790351867676 + ], + "requestedWalkTarget": [ + 0.7996190190315247, + 0.0, + -9.556790351867676 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 0.7899808883666992, + 0.0, + -9.52500057220459 + ] + }, + { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "hp": 35.0, + "pathWaypoints": [ + [ + -0.31001949310302734, + 0.0, + 13.974998474121094 + ] + ], + "position": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "requestedWalkTarget": [ + -0.2859399914741516, + 0.0, + 13.964099884033203 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + -0.31001949310302734, + 0.0, + 13.974998474121094 + ] + }, + { + "attackTargetIndex": -2, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 0.0, + 0.0, + -6.400000095367432 + ], + "hp": 35.0, + "pathWaypoints": [ + [ + -0.010019302368164063, + 0.0, + -6.425000190734863 + ] + ], + "position": [ + 0.0, + 0.0, + -6.400000095367432 + ], + "requestedWalkTarget": [ + 0.0, + 0.0, + -6.400000095367432 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + -0.010019302368164063, + 0.0, + -6.425000190734863 + ] + }, + { + "attackTargetIndex": -2, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + -5.0, + 0.0, + 12.0 + ], + "hp": 35.0, + "pathWaypoints": [ + [ + -5.010019302368164, + 0.0, + 11.974998474121094 + ] + ], + "position": [ + -5.0, + 0.0, + 12.0 + ], + "requestedWalkTarget": [ + -5.0, + 0.0, + 12.0 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + -5.010019302368164, + 0.0, + 11.974998474121094 + ] + }, + { + "attackTargetIndex": -2, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 5.0, + 0.0, + 12.0 + ], + "hp": 35.0, + "pathWaypoints": [ + [ + 4.889980316162109, + 0.0, + 11.875 + ] + ], + "position": [ + 5.0, + 0.0, + 12.0 + ], + "requestedWalkTarget": [ + 5.0, + 0.0, + 12.0 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 4.889980316162109, + 0.0, + 11.875 + ] + }, + { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": false, + "faceTargetIndex": -1, + "facingAngle": 3.1415927410125732, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 3.9899799823760986, + 0.0, + 10.375 + ], + "hp": 100.0, + "pathWaypoints": [ + [ + 3.989980697631836, + 0.0, + 10.375 + ] + ], + "position": [ + 3.9899799823760986, + 0.0, + 10.375 + ], + "requestedWalkTarget": [ + 3.9899799823760986, + 0.0, + 10.375 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 3.989980697631836, + 0.0, + 10.375 + ] + } + ], + "playerState": { + "attackTargetIndex": -1, + "attack_cooldown": 0.0, + "battle_state": 0, + "currentState": 0, + "currentWaypointIndex": 0, + "enabled": true, + "faceTargetIndex": -1, + "facingAngle": 0.0, + "homeDriftCheckTimer": 5.0, + "homePosition": [ + 0.0, + 0.0, + 0.0 + ], + "hp": 200.0, + "pathWaypoints": [ + [ + 0.9899806976318359, + 0.0, + -9.625000953674316 + ] + ], + "position": [ + 0.9426940083503723, + 0.0, + -9.6310396194458 + ], + "requestedWalkTarget": [ + 0.9426940083503723, + 0.0, + -9.6310396194458 + ], + "showWeapon": true, + "targetFacingAngle": 0.0, + "walkTarget": [ + 0.9899806976318359, + 0.0, + -9.625000953674316 + ] + }, + "scriptGlobals": { + "CONST_MSG_EMPTY": "(пусто)", + "CONST_MSG_WHERE": "Бекзат, ты где? Я жду...", + "first_time_darklands": true, + "ghost_gone": false, + "hall_door_opened": false, + "morning_can_open_door_index": 0, + "morning_did_open_door_index": 0, + "player_hold_book": false, + "player_hold_knife": false, + "teacher_arrived": false, + "teacher_door_opened": false, + "teacher_told_about_book": false, + "was_day_when_player_left": 0, + "was_state_when_player_left": 0 + }, + "teleportZoneState": { + "tp_loc1_to_loc2": true + }, + "triggerZoneState": { + "book_dialog_zone001": { + "enabled": true, + "playerInside": false + }, + "knife_dialog_zone001": { + "enabled": true, + "playerInside": false + }, + "lection_hall_zone001": { + "enabled": true, + "playerInside": false + }, + "teacher_dialog_zone001": { + "enabled": false, + "playerInside": false + } + } + } + }, + "money": 5500, + "playerHp": 200.0, + "playerMaxHp": 200.0, + "questJournal": { + "quests": [ + { + "activeObjectiveIndex": 0, + "id": "tutorial_take_items", + "objectives": [ + { + "completed": false, + "id": "take_phone", + "visible": true + }, + { + "completed": false, + "id": "take_journal", + "visible": true + } + ], + "status": 1 + }, + { + "activeObjectiveIndex": 0, + "id": "ghost_lore", + "objectives": [ + { + "completed": false, + "id": "ghost_lore_aiperi", + "visible": true + }, + { + "completed": false, + "id": "ghost_lore_alik", + "visible": false + }, + { + "completed": false, + "id": "ghost_lore_teacher", + "visible": true + } + ], + "status": 0 + }, + { + "activeObjectiveIndex": 0, + "id": "ghost_coursework", + "objectives": [ + { + "completed": false, + "id": "ghost_coursework_find", + "visible": true + }, + { + "completed": false, + "id": "ghost_coursework_mark", + "visible": true + } + ], + "status": 0 + }, + { + "activeObjectiveIndex": 0, + "id": "ghost_release", + "objectives": [ + { + "completed": false, + "id": "ghost_release_reportcard", + "visible": true + }, + { + "completed": false, + "id": "ghost_release_mark", + "visible": true + }, + { + "completed": false, + "id": "ghost_release_show", + "visible": true + } + ], + "status": 0 + }, + { + "activeObjectiveIndex": 0, + "id": "study_beginning", + "objectives": [ + { + "completed": false, + "id": "study_beginning_lecture", + "visible": true + }, + { + "completed": false, + "id": "study_beginning_task", + "visible": true + } + ], + "status": 1 + }, + { + "activeObjectiveIndex": 0, + "id": "study_project", + "objectives": [ + { + "completed": false, + "id": "study_project_book", + "visible": true + }, + { + "completed": false, + "id": "study_project_write", + "visible": true + }, + { + "completed": false, + "id": "study_project_give", + "visible": true + } + ], + "status": 0 + }, + { + "activeObjectiveIndex": 0, + "id": "aiperi_knife", + "objectives": [ + { + "completed": false, + "id": "aiperi_knife_keys", + "visible": true + }, + { + "completed": false, + "id": "aiperi_knife_take", + "visible": true + }, + { + "completed": false, + "id": "aiperi_knife_give", + "visible": true + } + ], + "status": 0 + } + ] + }, + "savedAt": "2026-07-08 15:45", + "tutorialJournalPickedUp": false, + "tutorialJournalScreenOpened": false, + "tutorialNeedOpenTaxiScreen": false, + "tutorialPhoneChatScreenOpened": false, + "tutorialPhonePickedUp": false, + "tutorialStep": 0, + "uniIntTutorialState": 0 +} \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index aada736..03f6f49 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -289,33 +289,6 @@ namespace ZL std::cout << "Load resurces step 13" << std::endl; - menuManager.onResetGame = [this]() { - gameState.currentLocationName.clear(); - gameState.isDarklands = false; - gameState.isNight = false; - gameState.isDawn = false; - gameState.playerHp = 200.f; - gameState.playerMaxHp = 200.f; - gameState.money = 5500; - gameState.globalInts.clear(); - gameState.globalFloats.clear(); - gameState.tutorialStep = TutorialStep::Step0; - gameState.uniIntTutorialState = UniIntTutorialState::Step10; - gameState.tutorialPhonePickedUp = false; - gameState.tutorialJournalPickedUp = false; - gameState.tutorialPhoneChatScreenOpened = false; - gameState.tutorialJournalScreenOpened = false; - gameState.tutorialNeedOpenTaxiScreen = false; - for (int i = 0; i < 3; ++i) { - gameState.chatUnread[i] = true; - gameState.chatPreviewMsg[i].clear(); - gameState.chatHistory[i].clear(); - } - gameState.inventory.clear(); - gameState.questJournal.loadFromFile(localizedConfigPath("resources/config/quests.json", g_currentLanguage), CONST_ZIP_FILE); - createLocations(); - }; - try { menuManager.setup(gameState.inventory, CONST_ZIP_FILE); std::cout << "UI loaded successfully" << std::endl; @@ -326,9 +299,12 @@ namespace ZL } menuManager.startGameFunc = [this]() { - gameState.currentLocationName = "location_dorm"; - currentLocation()->scriptEngine.callLocationEnterCallback(); - this->audioPlayer->crossFadeMusicAsync("audio/obshaga.ogg"); + mainThreadHandler.EnqueueMainThreadTask([this]() { + performResetToInitialState(); + gameState.currentLocationName = "location_dorm"; + currentLocation()->scriptEngine.callLocationEnterCallback(); + this->audioPlayer->crossFadeMusicAsync("audio/obshaga.ogg"); + }); }; menuManager.onSaveGame = [this](int slot) { saveGame(slot); }; @@ -353,6 +329,97 @@ namespace ZL } + void Game::rearmDormOneShotCallbacks() { + auto it = gameState.locations.find("location_dorm"); + if (it == gameState.locations.end() || !it->second) return; + + it->second->onPlayerTaxiRequired = [this]() { + menuManager.tutorialShowTaxiHint(); + }; + + menuManager.tutorialUnlockInteractiveObjectsFunc = [this]() + { + if (gameState.locations["location_dorm"]) + { + gameState.locations["location_dorm"]->state.tutorialInteractiveObjectsLocked = false; + } + }; + } + + void Game::performFullReset() { + gameState.currentLocationName.clear(); + gameState.isDarklands = false; + gameState.isNight = false; + gameState.isDawn = false; + gameState.playerHp = 200.f; + gameState.playerMaxHp = 200.f; + gameState.money = 5500; + gameState.globalInts.clear(); + gameState.globalFloats.clear(); + gameState.tutorialStep = TutorialStep::Step0; + gameState.uniIntTutorialState = UniIntTutorialState::Step10; + gameState.tutorialPhonePickedUp = false; + gameState.tutorialJournalPickedUp = false; + gameState.tutorialPhoneChatScreenOpened = false; + gameState.tutorialJournalScreenOpened = false; + gameState.tutorialNeedOpenTaxiScreen = false; + for (int i = 0; i < 3; ++i) { + gameState.chatUnread[i] = true; + gameState.chatPreviewMsg[i].clear(); + gameState.chatHistory[i].clear(); + } + gameState.inventory.clear(); + gameState.questJournal.loadFromFile(localizedConfigPath("resources/config/quests.json", g_currentLanguage), CONST_ZIP_FILE); + createLocations(); + + // Developer workflow: uncomment to (re)generate resources/config/start_state.json + // from this freshly-rebuilt state after changing gameplay/content JSON or Lua. + // Re-comment before shipping. + //saveInitialState(); + } + + void Game::performResetToInitialState() { + const std::string path = "resources/config/start_state.json"; + const std::string content = ZL::readTextFile(path); + if (!content.empty()) { + try { + nlohmann::json root = nlohmann::json::parse(content); + // GameState::load() merges into existing maps rather than replacing them, + // so any Lua globals set during play that aren't in the pristine snapshot + // must be cleared explicitly before loading it. + gameState.globalInts.clear(); + gameState.globalFloats.clear(); + gameState.load(root); // updates existing Location objects in place -- no + // destruction, no re-parsing JSON/nav files, no new + // sol2 state (GameState::load only touches map entries + // that already exist). + // Locations survive this reset, so any one-shot callbacks they consumed + // during the previous playthrough (tutorial unlock, taxi request) must be + // re-armed here -- createLocations() normally does this, but doesn't run + // on this fast path. + rearmDormOneShotCallbacks(); + return; + } catch (const std::exception& e) { + std::cerr << "[reset] Failed to parse " << path << ": " << e.what() + << " -- falling back to full rebuild" << std::endl; + } + } + performFullReset(); + } + + void Game::saveInitialState() { + nlohmann::json root; + gameState.save(root); + const std::string path = "resources/config/start_state.json"; + std::ofstream file(path); + if (file.is_open()) { + file << root.dump(2); + std::cout << "[reset] Saved initial state snapshot to " << path << std::endl; + } else { + std::cerr << "[reset] Could not open " << path << " for writing" << std::endl; + } + } + void Game::createLocations() { gameState.locations.clear(); @@ -561,19 +628,9 @@ namespace ZL if (gameState.locations["location_dorm"]->player) gameState.locations["location_dorm"]->player->state.onDeathAnimComplete = [this]() { startDarklandsTransition(); }; - gameState.locations["location_dorm"]->onPlayerTaxiRequired = [this]() { - menuManager.tutorialShowTaxiHint(); - }; - gameState.locations["location_dorm"]->state.tutorialInteractiveObjectsLocked = true; - menuManager.tutorialUnlockInteractiveObjectsFunc = [this]() - { - if (gameState.locations["location_dorm"]) - { - gameState.locations["location_dorm"]->state.tutorialInteractiveObjectsLocked = false; - } - }; + rearmDormOneShotCallbacks(); menuManager.callTaxiFunc = [this]() { diff --git a/src/Game.h b/src/Game.h index 60ff77b..e10f0e2 100644 --- a/src/Game.h +++ b/src/Game.h @@ -101,6 +101,20 @@ namespace ZL { SaveSlotInfo readSlotInfo(int slot) const; void createLocations(); + // Reset entry point used by "Start New Game": loads resources/config/start_state.json + // into the existing Location objects if present, else falls back to performFullReset(). + // Must only ever run from a deferred task (see mainThreadHandler.EnqueueMainThreadTask), + // never synchronously from a Lua/cutscene call stack. + void performResetToInitialState(); + void performFullReset(); + void saveInitialState(); + + // (Re-)arms one-shot gameplay callbacks (tutorial unlock, taxi request) that + // createLocations() wires up but that get consumed (set to nullptr) once used + // during play. Must be called after gameState.load() on the fast reset path, + // since that path keeps the existing Location objects instead of recreating them. + void rearmDormOneShotCallbacks(); + int64_t getSyncTimeMs(); void processTickCount(); void drawScene(); diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index 1eb9f5d..bc8a0b2 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -320,7 +320,7 @@ namespace ZL { } void MenuManager::showMainMenu() { - if (onResetGame) onResetGame(); + gameState_.currentLocationName.clear(); audioPlayer_.crossFadeMusicAsync("audio/main menu final.ogg"); @@ -1195,11 +1195,24 @@ namespace ZL { uiManager.setNodeVisible("hint6a", false); uiManager.setNodeVisible("hint6aarrow", false); } + else + { + if (!gameState_.tutorialNeedOpenTaxiScreen) + { + uiManager.setNodeVisible("hint6a", true); + uiManager.setNodeVisible("hint6aarrow", true); + } + } if (gameState_.tutorialJournalScreenOpened) { uiManager.setNodeVisible("hint6b", false); uiManager.setNodeVisible("hint6barrow", false); } + else + { + uiManager.setNodeVisible("hint6b", true); + uiManager.setNodeVisible("hint6barrow", true); + } if (gameState_.tutorialPhoneChatScreenOpened && gameState_.tutorialJournalScreenOpened) { gameState_.tutorialStep = TutorialStep::Step6; } diff --git a/src/MenuManager.h b/src/MenuManager.h index 2bf0bae..ba80926 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -78,7 +78,6 @@ namespace ZL { std::function onSaveGame; std::function onLoadGame; std::function getSlotInfoFunc; - std::function onResetGame; // Called when a chat message bubble should be shown (text + direction) void onChatBubbleReady(const std::string& text, bool incoming);