Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ===================================================================
- #
- # Script: GameManager
- #
- # $$COPYRIGHT$$
- #
- # ===================================================================
- class GameManager
- ###*
- * Manages all general things around the game like holding the game settings,
- * manages the save/load of a game, etc.
- *
- * @module gs
- * @class GameManager
- * @memberof gs
- * @constructor
- ###
- constructor: ->
- ###*
- * The current scene data.
- * @property sceneData
- * @type Object
- ###
- @sceneData = {}
- ###*
- * The scene viewport containing all visual objects which are part of the scene and influenced
- * by the in-game camera.
- * @property sceneViewport
- * @type gs.Object_Viewport
- ###
- @sceneViewport = null
- ###*
- * The list of common events.
- * @property commonEvents
- * @type gs.Object_CommonEvent[]
- ###
- @commonEvents = []
- ###*
- * Indicates if the GameManager is initialized.
- * @property commonEvents
- * @type gs.Object_CommonEvent[]
- ###
- @initialized = no
- ###*
- * Temporary game settings.
- * @property tempSettings
- * @type Object
- ###
- @tempSettings = skip: false, skipTime: 5, loadMenuAccess: true, menuAccess: true, backlogAccess: true, saveMenuAccess: true, messageFading: { animation: { type: 1 }, duration: 15, easing: null }
- ###*
- * Temporary game fields.
- * @property tempFields
- * @type Object
- ###
- @tempFields = null
- ###*
- * Stores default values for backgrounds, pictures, etc.
- * @property defaults
- * @type Object
- ###
- @defaults = {
- background: { "duration": 30, "origin": 0, "zOrder": 0, "loopVertical": 0, "loopHorizontal": 0, "easing": { "type": 0, "inOut": 1 }, "animation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "motionBlur": { "enabled": 0, "delay": 2, "opacity": 100, "dissolveSpeed": 3 } },
- picture: { "appearDuration": 30, "disappearDuration": 30, "origin": 1, "zOrder": 0, "appearEasing": { "type": 0, "inOut": 1 }, "disappearEasing": { "type": 0, "inOut": 1 }, "appearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "motionBlur": { "enabled": 0, "delay": 2, "opacity": 100, "dissolveSpeed": 3 } },
- character: { "expressionDuration": 0, "appearDuration": 40, "disappearDuration": 40, "origin": 1, "zOrder": 0, "appearEasing": { "type": 2, "inOut": 2 }, "disappearEasing": { "type": 1, "inOut": 1 }, "appearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "motionBlur": { "enabled": 0, "delay": 2, "opacity": 100, "dissolveSpeed": 3 }, "changeAnimation": { "type": 1, "movement": 0, "fading": 0, "mask": { "graphic": null, "vague": 30 } }, "changeEasing": { "type": 2, "inOut": 2 } },
- text: { "appearDuration": 30, "disappearDuration": 30, "positionOrigin": 0, "origin": 0, "zOrder": 0, "appearEasing": { "type": 0, "inOut": 1 }, "disappearEasing": { "type": 0, "inOut": 1 }, "appearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "motionBlur": { "enabled": 0, "delay": 2, "opacity": 100, "dissolveSpeed": 3 } },
- video: { "appearDuration": 30, "disappearDuration": 30, "origin": 0, "zOrder": 0, "appearEasing": { "type": 0, "inOut": 1 }, "disappearEasing": { "type": 0, "inOut": 1 }, "appearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "motionBlur": { "enabled": 0, "delay": 2, "opacity": 100, "dissolveSpeed": 3 } },
- live2d: { "motionFadeInTime": 1000, "appearDuration": 30, "disappearDuration": 30, "zOrder": 0, "appearEasing": { "type": 0, "inOut": 1 }, "disappearEasing": { "type": 0, "inOut": 1 }, "appearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 1, "movement": 0, "mask": { "graphic": null, "vague": 30 } } },
- messageBox: { "appearDuration": 30, "disappearDuration": 30, "zOrder": 0, "appearEasing": { "type": 0, "inOut": 1 }, "disappearEasing": { "type": 0, "inOut": 1 }, "appearAnimation": { "type": 0, "movement": 3, "mask": { "graphic": null, "vague": 30 } }, "disappearAnimation": { "type": 0, "movement": 3, "mask": { "graphic": null, "vague": 30 } } },
- audio: { "musicFadeInDuration": 0, "musicFadeOutDuration": 0, "musicVolume": 100, "musicPlaybackRate": 100, "soundVolume": 100, "soundPlaybackRate": 100, "voiceVolume": 100, "voicePlaybackRate": 100 }
- }
- ###*
- * The game's backlog.
- * @property backlog
- * @type Object[]
- ###
- @backlog = []
- ###*
- * Character parameters by character ID.
- * @property characterParams
- * @type Object[]
- ###
- @characterParams = []
- ###*
- * The game's chapter
- * @property chapters
- * @type gs.Document[]
- ###
- @chapters = []
- ###*
- * The game's current displayed messages. Especially in NVL mode the messages
- * of the current page are stored here.
- * @property messages
- * @type Object[]
- ###
- @messages = []
- ###*
- * Count of save slots. Default is 100.
- * @property saveSlotCount
- * @type number
- ###
- @saveSlotCount = 100
- ###*
- * The index of save games. Contains the header-info for each save game slot.
- * @property saveGameSlots
- * @type Object[]
- ###
- @saveGameSlots = []
- ###*
- * Stores global data like the state of persistent game variables.
- * @property globalData
- * @type Object
- ###
- @globalData = null
- ###*
- * Indicates if the game runs in editor's live-preview.
- * @property inLivePreview
- * @type Object
- ###
- @inLivePreview = no
- ###*
- * Initializes the GameManager, should be called before the actual game starts.
- *
- * @method initialize
- ###
- initialize: ->
- @initialized = yes
- @inLivePreview = $PARAMS.preview?
- @saveSlotCount = RecordManager.system.saveSlotCount || 100
- @tempFields = new gs.GameTemp()
- window.$tempFields = @tempFields
- @createSaveGameIndex()
- @variableStore = new gs.VariableStore()
- DataManager.getDocumentsByType("persistent_variables")
- @variableStore.setupDomains(DataManager.getDocumentsByType("global_variables").select (v) -> v.items.domain||"")
- @variableStore.persistentNumbersByDomain = @globalData.persistentNumbers ? @variableStore.persistentNumbersByDomain
- @variableStore.persistentBooleansByDomain = @globalData.persistentBooleans ? @variableStore.persistentBooleansByDomain
- @variableStore.persistentStringsByDomain = @globalData.persistentStrings ? @variableStore.persistentStringsByDomain
- @variableStore.persistentListsByDomain = @globalData.persistentLists ? @variableStore.persistentListsByDomain
- @sceneViewport = new gs.Object_Viewport(new Viewport(0, 0, Graphics.width, Graphics.height, Graphics.viewport))
- for character in RecordManager.charactersArray
- if character?
- @characterParams[character.index] = {}
- if character.params?
- for param in character.params
- @characterParams[character.index][param.name] = param.value
- @setupCommonEvents()
- for i in [0...RecordManager.characters]
- @settings.voicesPerCharacter[i] = 100
- @chapters = DataManager.getDocumentsByType("vn.chapter")
- @chapters.sort (a, b) ->
- if a.items.order > b.items.order
- return 1
- else if a.items.order < b.items.order
- return -1
- else
- return 0
- ###*
- * Sets up common events.
- *
- * @method setupCommonEvents
- ###
- setupCommonEvents: ->
- for event in @commonEvents
- event?.dispose()
- @commonEvents = []
- for event in RecordManager.commonEvents
- object = new gs.Object_CommonEvent()
- object.record = event
- object.rid = event.index
- @commonEvents[event.index] = object
- @commonEvents.push(object)
- ###*
- * Preloads resources for common events with auto-preload option enabled.
- *
- * @method preloadCommonEvents
- ###
- preloadCommonEvents: ->
- for event in RecordManager.commonEvents
- continue if not event
- if event.startCondition == 1 and event.autoPreload
- gs.ResourceLoader.loadEventCommandsGraphics(event.commands)
- ###*
- * Sets up cursor depending on system settings.
- *
- * @method setupCursor
- ###
- setupCursor: ->
- if RecordManager.system.cursor?.name
- bitmap = ResourceManager.getBitmap("Graphics/Pictures/#{RecordManager.system.cursor.name}")
- Graphics.setCursorBitmap(bitmap, RecordManager.system.cursor.hx, RecordManager.system.cursor.hy)
- else
- Graphics.setCursorBitmap(null)
- ###*
- * Disposes the GameManager. Should be called before quit the game.
- *
- * @method dispose
- ###
- dispose: ->
- ###*
- * Quits the game. The implementation depends on the platform. So for example on mobile
- * devices this method has no effect.
- *
- * @method exit
- ###
- exit: -> Application.exit()
- ###*
- * Resets the GameManager by disposing and re-initializing it.
- *
- * @method reset
- ###
- reset: ->
- @initialized = no
- @interpreter = null
- @dispose()
- @initialize()
- ###*
- * Starts a new game.
- *
- * @method newGame
- ###
- newGame: ->
- @messages = []
- @variableStore.clearAllGlobalVariables()
- @variableStore.clearAllLocalVariables()
- @tempSettings.skip = no
- @tempFields.clear()
- @tempFields.inGame = yes
- @setupCommonEvents()
- @tempSettings.menuAccess = yes
- @tempSettings.saveMenuAccess = yes
- @tempSettings.loadMenuAccess = yes
- @tempSettings.backlogAccess = yes
- ###*
- * Exists the game and resets the GameManager which is important before going back to
- * the main menu or title screen.
- *
- * @method exitGame
- ###
- exitGame: ->
- @tempFields.inGame = no
- @tempFields.isExitingGame = yes
- ###*
- * Updates the GameManager. Should be called once per frame.
- *
- * @method update
- ###
- update: ->
- ###*
- * Creates the index of all save-games. Should be called whenever a new save game
- * is created.
- *
- * @method createSaveGameIndex
- * @protected
- ###
- createSaveGameIndex: ->
- @saveGameSlots = []
- for i in [0...@saveSlotCount]
- if GameStorage.exists("SaveGame_#{i}_Header")
- header = GameStorage.getObject("SaveGame_#{i}_Header")
- chapter = DataManager.getDocument(header.chapterUid)
- scene = DataManager.getDocumentSummary(header.sceneUid)
- image = header.image
- else
- header = null
- chaper = null
- scene = null
- if chapter? and scene? and !@inLivePreview
- @saveGameSlots.push({
- date: header.date,
- chapter: chapter.items.name || "DELETED"
- scene: scene.items.name || "DELETED",
- image: image #chapter.items.commands[0].params.saveGameGraphic?.name
- })
- else
- @saveGameSlots.push({ "date": "", "chapter": "", "scene": "", "image": null })
- return @saveGameSlots
- ###*
- * Resets the game's settings to its default values.
- *
- * @method resetSettings
- ###
- resetSettings: ->
- @settings = { version: 342, renderer: 0, filter: 1, confirmation: yes, adjustAspectRatio: no, allowSkip: yes, allowSkipUnreadMessages: yes, allowVideoSkip: yes, skipVoiceOnAction: yes, allowChoiceSkip: no, voicesByCharacter: [], timeMessageToVoice: true, "autoMessage": { enabled: false, time: 0, waitForVoice: yes, stopOnAction: no }, "voiceEnabled": true, "bgmEnabled": true, "soundEnabled": true, "voiceVolume": 100, "bgmVolume": 100, "seVolume": 100, "messageSpeed": 4, "fullScreen": no, "aspectRatio": 0 }
- @saveGameSlots = []
- for i in [0...@saveSlotCount]
- GameStorage.remove("SaveGame_#{i}_Header")
- GameStorage.remove("SaveGame_#{i}")
- @saveGameSlots.push({ "date": "", "chapter": "", "scene": "", "thumb": "" })
- GameStorage.setObject("settings", @settings)
- ###*
- * Saves current game settings.
- *
- * @method saveSettings
- ###
- saveSettings: ->
- GameStorage.setObject("settings", @settings)
- ###*
- * Saves current global data.
- *
- * @method saveGlobalData
- ###
- saveGlobalData: ->
- @globalData.persistentNumbers = @variableStore.persistentNumbersByDomain
- @globalData.persistentLists = @variableStore.persistentListsByDomain
- @globalData.persistentBooleans = @variableStore.persistentBooleansByDomain
- @globalData.persistentStrings = @variableStore.persistentStringsByDomain
- GameStorage.setObject("globalData", @globalData)
- ###*
- * Resets current global data. All stored data about read messages, persistent variables and
- * CG gallery will be deleted.
- *
- * @method resetGlobalData
- ###
- resetGlobalData: ->
- version = @globalData?.version
- data = @globalData
- @globalData = {
- messages: {}, cgGallery: {}, version: 342,
- persistentNumbers: { "0": [], "com.degica.vnm.default": [] },
- persistentStrings: { "0": [], "com.degica.vnm.default": [] },
- persistentBooleans: { "0": [], "com.degica.vnm.default": [] },
- persistentLists: { "0": [], "com.degica.vnm.default": [] }
- }
- for cg, i in RecordManager.cgGalleryArray
- if cg?
- @globalData.cgGallery[cg.index] = { unlocked: no }
- GameStorage.setObject("globalData", @globalData)
- @migrateGlobalData(data, version+1, @globalData.version)
- migrateGlobalData: (data, from, to) ->
- for i in [from..to]
- if this["migrateGlobalData#{i}"]?
- this["migrateGlobalData#{i}"](data)
- migrateGlobalData342: (data) ->
- if data?
- @globalData.persistentNumbers[0] = data.persistentNumbers[0] || []
- @globalData.persistentStrings[0] = data.persistentStrings[0] || []
- @globalData.persistentBooleans[0] = data.persistentBooleans[0] || []
- @globalData.persistentLists[0] = data.persistentLists[0] || []
- @globalData.persistentNumbers["com.degica.vnm.default"] = data.persistentNumbers[0] || []
- @globalData.persistentStrings["com.degica.vnm.default"] = data.persistentStrings[0] || []
- @globalData.persistentBooleans["com.degica.vnm.default"] = data.persistentBooleans[0] || []
- @globalData.persistentLists["com.degica.vnm.default"] = data.persistentLists[0] || []
- readSaveGame: (saveGame) ->
- writeSaveGame: (saveGame) ->
- prepareSaveGame: (snapshot) ->
- if snapshot
- snapshot = ResourceManager.getCustomBitmap("$snapshot")
- snapshot?.dispose()
- ResourceManager.setCustomBitmap("$snapshot", Graphics.snapshot())
- context = new gs.ObjectCodecContext()
- context.decodedObjectStore.push(Graphics.viewport)
- context.decodedObjectStore.push(@scene)
- context.decodedObjectStore.push(@scene.behavior)
- messageBoxIds = ["messageBox", "nvlMessageBox", "messageMenu"];
- messageIds = ["gameMessage_message", "nvlGameMessage_message"];
- messageBoxes = messageBoxIds.where((id) => @scene.behavior.objectManager.objectById(id) != null).select((id) => @scene.behavior.objectManager.objectById(id))
- messages = messageIds.select (id) => @scene.behavior.objectManager.objectById(id)
- sceneData = {}
- saveGame = {}
- saveGame.encodedObjectStore = null
- saveGame.sceneUid = @scene.sceneDocument.uid
- saveGame.data = {
- resourceContext: @scene.behavior.resourceContext.toDataBundle(),
- currentCharacter: @scene.currentCharacter,
- characterParams: @characterParams,
- frameCount: Graphics.frameCount,
- tempFields: @tempFields,
- viewport: @scene.viewport,
- characters: @scene.characters,
- characterNames: RecordManager.charactersArray.select((c) -> { name: c.name, index: c.index }),
- backgrounds: @scene.backgrounds,
- pictures: @scene.pictureContainer.subObjectsByDomain,
- texts: @scene.textContainer.subObjectsByDomain,
- videos: @scene.videoContainer.subObjectsByDomain,
- viewports: @scene.viewportContainer.subObjects,
- commonEvents: @scene.commonEventContainer.subObjects,
- hotspots: @scene.hotspotContainer.subObjectsByDomain,
- interpreter: @scene.interpreter,
- choices: @scene.choices,
- messageBoxes: messageBoxes.filter((mb) -> mb? ).map((mb, i) => { visible: mb.visible, id: mb.id, message: messages[i] }),
- backlog: @backlog,
- variableStore: @variableStore,
- defaults: @defaults,
- transitionData: SceneManager.transitionData,
- audio: { audioBuffers: AudioManager.audioBuffers, audioBuffersByLayer: AudioManager.audioBuffersByLayer, audioLayers: AudioManager.audioLayers, soundReferences: AudioManager.soundReferences },
- messageAreas: @scene.messageAreaContainer.subObjectsByDomain
- }
- saveGame.data = gs.ObjectCodec.encode(saveGame.data, context)
- saveGame.encodedObjectStore = context.encodedObjectStore
- @saveGame = saveGame
- createSaveGameSlot: (header) ->
- slot = {
- "date": new Date().toDateString(),
- "chapter": @scene.chapter.items.name,
- "scene": @scene.sceneDocument.items.name,
- "image": header.image
- }
- return slot;
- createSaveGameHeader: (thumbWidth, thumbHeight) ->
- thumbImage = @createSaveGameThumbImage(thumbWidth, thumbHeight)
- header = {
- "date": new Date().toDateString(),
- "chapterUid": @scene.chapter.uid,
- "sceneUid": @scene.sceneDocument.uid,
- "image": thumbImage?.image.toDataURL()
- }
- thumbImage?.dispose()
- return header
- createSaveGameThumbImage: (width, height) ->
- snapshot = ResourceManager.getBitmap("$snapshot")
- thumbImage = null
- if snapshot and snapshot.loaded
- if width and height
- thumbImage = new Bitmap(width, height)
- else
- thumbImage = new Bitmap(Graphics.width / 8, Graphics.height / 8)
- thumbImage.stretchBlt(new Rect(0, 0, thumbImage.width, thumbImage.height), snapshot, new Rect(0, 0, snapshot.width, snapshot.height))
- return thumbImage
- storeSaveGame: (name, saveGame, header) ->
- if header
- GameStorage.setData("#{name}_Header", JSON.stringify(header))
- GameStorage.setData(name, JSON.stringify(saveGame))
- ###*
- * Saves the current game at the specified slot.
- *
- * @method save
- * @param {number} slot - The slot where the game should be saved at.
- * @param {number} thumbWidth - The width for the snapshot-thumb. You can specify <b>null</b> or 0 to use an auto calculated width.
- * @param {number} thumbHeight - The height for the snapshot-thumb. You can specify <b>null</b> or 0 to use an auto calculated height.
- ###
- save: (slot, thumbWidth, thumbHeight) ->
- if @saveGame
- header = @createSaveGameHeader(thumbWidth, thumbHeight)
- @saveGameSlots[slot] = @createSaveGameSlot(header)
- @storeSaveGame("SaveGame_#{slot}", @saveGame, header)
- @sceneData = {}
- return @saveGame
- restore: (saveGame) ->
- @backlog = saveGame.data.backlog
- @defaults = saveGame.data.defaults
- @variableStore.restore(saveGame.data.variableStore)
- @sceneData = saveGame.data
- @saveGame = null
- @loadedSaveGame = null
- @tempFields = saveGame.data.tempFields
- @characterParams = saveGame.data.characterParams
- window.$tempFields = @tempFields
- window.$dataFields.backlog = @backlog
- prepareLoadGame: ->
- AudioManager.stopAllMusic(30)
- ###*
- * Loads the game from the specified save game slot. This method triggers
- * a automatic scene change.
- *
- * @method load
- * @param {number} slot - The slot where the game should be loaded from.
- ###
- load: (slot) ->
- return if !@saveGameSlots[slot] or @saveGameSlots[slot].date.trim().length == 0
- @prepareLoadGame()
- @loadedSaveGame = @loadSaveGame("SaveGame_#{slot}")
- gs.Audio.reset()
- gs.GlobalEventManager.clear()
- SceneManager.switchTo(new vn.Object_Scene())
- SceneManager.clear()
- loadSaveGame: (name) -> JSON.parse(GameStorage.getData(name))
- ###*
- * Gets the save game data for a specified slot.
- *
- * @method getSaveGame
- * @param {number} slot - The slot to get the save data from.
- * @return {Object} The save game data.
- ###
- getSaveGame: (slot) -> JSON.parse(GameStorage.getData("SaveGame_#{slot}"))
- window.GameManager = new GameManager()
- gs.GameManager = window.GameManager
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement