From 6ec06a971964a5ca9e6f524437eca16ce8868878 Mon Sep 17 00:00:00 2001 From: Filip Burlacu Date: Sun, 28 Dec 2014 23:01:56 -0500 Subject: [PATCH] Added a completely new GUI, and a new doc file Important internal changes: * Most GUI callbacks are now methods of their HudSystems (cleans the code, mostly) * Saving/Loading has been disconnected from GUI for now, since we need to redesign how saving/loading works anyway. * CEGUIWindow now supports animations (which are used slightly) * A small change to microbe.lua, adding a species name. This is temporary, as the entire data-passing system needs to be changed (see #240) See #130 --- .gitignore | 2 - doc/quicktips.md | 27 ++ ogre_cfg/resources.cfg | 2 + scripts/main_menu/main_menu_hud.lua | 6 +- scripts/microbe_editor/microbe_editor.lua | 16 +- scripts/microbe_editor/microbe_editor_hud.lua | 356 ++++++++++-------- scripts/microbe_stage/microbe.lua | 1 + scripts/microbe_stage/microbe_stage_hud.lua | 125 +++--- src/engine/engine.cpp | 4 + src/gui/CEGUIWindow.cpp | 12 + src/gui/CEGUIWindow.h | 7 + 11 files changed, 361 insertions(+), 197 deletions(-) create mode 100644 doc/quicktips.md diff --git a/.gitignore b/.gitignore index e7b7efc268c..c788f51b45b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ assets/* # We want certain xmls though !assets/definitions/ !assets/definitions/*.xml -# maybe add these in later -!assets/gui/layouts/*.layout # Website directory diff --git a/doc/quicktips.md b/doc/quicktips.md new file mode 100644 index 00000000000..d48aa93ddf4 --- /dev/null +++ b/doc/quicktips.md @@ -0,0 +1,27 @@ +#Quick Tips for Navigating the Source + +Most current work happens in Lua, with C++ development generally providing little more than interfaces to CEGUI, Ogre, and all the other parts of the engine. + +Before you begin, Google "Ogre3D", "CEGUI", "luabind", and "Entity Component System" so you know what they are. + +*Last Updated: Dec 27, 2014 + +#Lua +* Lua files are loaded into the engine in the order specified in the manifests. + * So, for any two files, the second one implicitly includes the first. +* The main_menu, microbe_stage, and microbe_editor each have some structure in common: + * The foo_hud.lua file defines the interactions with the GUI. + * Each defines a FooHudSystem, simple ECS Systems that have no components (yet, anyway). + * The :init method runs on program startup, and in these Systems sets up the callbacks for each button, and maybe saves a bit of extra state. + * The :update method runs every turn of the game loop + * See src/gui/CEGUIWindow.h for more details on the CEGUI features we currently have a Lua interface for. + * Each folder also has a setup.lua file, which, naturally, does necessary setup for the game mode. They define two important things: + * The necessary setup functions, that are called on startup + * a small function at the end which calls Engine:createGameState, defining: + * The Systems which will run in this GameState (and their order) + * The setup function, which for simplicity just calls the functions defined above +* The rest of the files in the subfolders contain more specific bits of functionality: + * Organelles are defined in microbe_stage/, each file defining a class for a certain type of organelle, and factory functions for all the different organelles of that type. + * Organelles are created by calling OrganelleFactory:makeOrganelle(data) -- the OrganelleFactory takes care of finding the right function + * The code for Microbes is overall currently a bit messy, and will probably change soon. +* The other files not in a subfolder define more general utility things -- hex coordinate math, lua interpretation in the in-game console, etc. Read as you need. diff --git a/ogre_cfg/resources.cfg b/ogre_cfg/resources.cfg index 429dcd09250..8b350fd4b3a 100644 --- a/ogre_cfg/resources.cfg +++ b/ogre_cfg/resources.cfg @@ -18,6 +18,8 @@ FileSystem=../gui/layouts FileSystem=../gui/looknfeel [Schemes] FileSystem=../gui/schemes +[Animations] +FileSystem=../gui/animations [General] # Keep this last so it overrides everything before diff --git a/scripts/main_menu/main_menu_hud.lua b/scripts/main_menu/main_menu_hud.lua index cafa4efb8e9..92e1b0330d4 100644 --- a/scripts/main_menu/main_menu_hud.lua +++ b/scripts/main_menu/main_menu_hud.lua @@ -8,9 +8,9 @@ end function MainMenuHudSystem:init(gameState) System.init(self, gameState) local root = gameState:rootGUIWindow() - local microbeButton = root:getChild("Background"):getChild("MicrobeButton") - local microbeEditorButton = root:getChild("Background"):getChild("MicrobeEditorButton") - local quitButton = root:getChild("Background"):getChild("QuitButton") + local microbeButton = root:getChild("Background"):getChild("MainMenuInteractive"):getChild("NewGameButton") + local microbeEditorButton = root:getChild("Background"):getChild("MainMenuInteractive"):getChild("EditorMenuButton") + local quitButton = root:getChild("Background"):getChild("MainMenuInteractive"):getChild("ExitGameButton") microbeButton:registerEventHandler("Clicked", mainMenuMicrobeStageButtonClicked) microbeEditorButton:registerEventHandler("Clicked", mainMenuMicrobeEditorButtonClicked) diff --git a/scripts/microbe_editor/microbe_editor.lua b/scripts/microbe_editor/microbe_editor.lua index 5bd6273ec53..5da464206a4 100644 --- a/scripts/microbe_editor/microbe_editor.lua +++ b/scripts/microbe_editor/microbe_editor.lua @@ -6,7 +6,7 @@ -------------------------------------------------------------------------------- class 'MicrobeEditor' -FLAGELIUM_MOMENTUM = 12.5 +FLAGELIUM_MOMENTUM = 12.5 -- what the heck is this for, and why is it here? function MicrobeEditor:__init(hudSystem) self.currentMicrobe = nil @@ -102,6 +102,8 @@ function MicrobeEditor:enqueueAction(action) while #self.actionHistory > self.actionIndex do table.remove(self.actionHistory) end + self.hudSystem.undoButton:enable() + self.hudSystem.redoButton:disable() action.redo() table.insert(self.actionHistory, action) self.actionIndex = self.actionIndex + 1 @@ -117,6 +119,12 @@ function MicrobeEditor:undo() end self.actionIndex = self.actionIndex - 1 end + -- nothing left to undo? disable undo + if self.actionIndex <= 0 then + self.hudSystem.undoButton:disable() + end + -- upon undoing, redoing is possible + self.hudSystem.redoButton:enable() end function MicrobeEditor:redo() @@ -128,6 +136,12 @@ function MicrobeEditor:redo() self.mutationPoints = self.mutationPoints - action.cost end end + -- nothing left to redo? disable redo + if self.actionIndex >= #self.actionHistory then + self.hudSystem.redoButton:disable() + end + -- upon redoing, undoing is possible + self.hudSystem.undoButton:enable() end function MicrobeEditor:getMouseHex() diff --git a/scripts/microbe_editor/microbe_editor_hud.lua b/scripts/microbe_editor/microbe_editor_hud.lua index e104231cfee..565a2bb1723 100644 --- a/scripts/microbe_editor/microbe_editor_hud.lua +++ b/scripts/microbe_editor/microbe_editor_hud.lua @@ -11,6 +11,7 @@ function MicrobeEditorHudSystem:__init() self.creationsListbox = nil self.creationFileMap = {} -- Map from player creation name to filepath self.activeButton = nil -- stores button, not name + self.helpPanelOpen = false end @@ -24,45 +25,49 @@ function MicrobeEditorHudSystem:init(gameState) sceneNode.meshName = "hex.mesh" self.hoverHex:addComponent(sceneNode) local root = gameState:rootGUIWindow() - self.mpLabel = root:getChild("BottomSection"):getChild("MutationPoints"):getChild("MPBar"):getChild("NumberLabel") - self.mpProgressBar = root:getChild("BottomSection"):getChild("MutationPoints"):getChild("MPBar") - local nucleusButton = root:getChild("EditorTools"):getChild("NucleusItem") - local flageliumButton = root:getChild("EditorTools"):getChild("FlageliumItem") - local mitochondriaButton = root:getChild("EditorTools"):getChild("MitochondriaItem") - local vacuoleButton = root:getChild("EditorTools"):getChild("VacuoleItem") - local toxinButton = root:getChild("EditorTools"):getChild("ToxinItem") - --local aminoSynthesizerButton = root:getChild("EditorTools"):getChild("AminoSynthesizerItem") - local removeButton = root:getChild("EditorTools"):getChild("RemoveItem") - self.organelleButtons["Nucleus"] = nucleusButton - self.organelleButtons["Flagelium"] = flageliumButton - self.organelleButtons["Mitochondria"] = mitochondriaButton - self.organelleButtons["Vacuole"] = vacuoleButton + self.mpLabel = root:getChild("MpPanel"):getChild("MpLabel") + self.nameLabel = root:getChild("SpeciesNamePanel"):getChild("SpeciesNameLabel") + self.nameTextbox = root:getChild("SpeciesNamePanel"):getChild("NameTextbox") + root:getChild("SpeciesNamePanel"):registerEventHandler("Clicked", + function() global_activeMicrobeEditorHudSystem:nameClicked() end) + + -- self.mpProgressBar = root:getChild("BottomSection"):getChild("MutationPoints"):getChild("MPBar") + local nucleusButton = root:getChild("NewMicrobe") + local flageliumButton = root:getChild("AddFlagellum") + local mitochondriaButton = root:getChild("AddMitochondria") + local vacuoleButton = root:getChild("AddVacuole") + local toxinButton = root:getChild("AddToxinVacuole") + local chloroplastButton = root:getChild("AddChloroplast") + self.organelleButtons["nucleus"] = nucleusButton + self.organelleButtons["flagelium"] = flageliumButton + self.organelleButtons["mitochondrion"] = mitochondriaButton + self.organelleButtons["chloroplast"] = chloroplastButton + self.organelleButtons["vacuole"] = vacuoleButton self.organelleButtons["Toxin"] = toxinButton - --self.organelleButtons["AminoSynthesizer"] = aminoSynthesizerButton - self.organelleButtons["Remove"] = removeButton self.activeButton = nil - nucleusButton:getChild("Nucleus"):registerEventHandler("Clicked", nucleusClicked) - flageliumButton:getChild("Flagelium"):registerEventHandler("Clicked", flageliumClicked) - mitochondriaButton:getChild("Mitochondria"):registerEventHandler("Clicked", mitochondriaClicked) - vacuoleButton:getChild("Vacuole"):registerEventHandler("Clicked", vacuoleClicked) - toxinButton:getChild("Toxin"):registerEventHandler("Clicked", toxinClicked) - --aminoSynthesizerButton:getChild("AminoSynthesizer"):registerEventHandler("Clicked", aminoSynthesizerClicked) - removeButton:getChild("Remove"):registerEventHandler("Clicked", removeClicked) - - self.saveLoadPanel = root:getChild("SaveLoadPanel") - self.creationsListbox = self.saveLoadPanel:getChild("SavedCreations") + nucleusButton:registerEventHandler("Clicked", function() self:nucleusClicked() end) + flageliumButton:registerEventHandler("Clicked", function() self:flageliumClicked() end) + mitochondriaButton:registerEventHandler("Clicked", function() self:mitochondriaClicked() end) + chloroplastButton:registerEventHandler("Clicked", function() self:chloroplastClicked() end) + vacuoleButton:registerEventHandler("Clicked", function() self:vacuoleClicked() end) + toxinButton:registerEventHandler("Clicked", function() self:toxinClicked() end) - root:getChild("BottomSection"):getChild("MicrobeStageButton"):registerEventHandler("Clicked", playClicked) - root:getChild("BottomSection"):getChild("MenuButton"):registerEventHandler("Clicked", menuButtonClicked) - root:getChild("MenuPanel"):getChild("MainMenuButton"):registerEventHandler("Clicked", menuMainMenuClicked) - root:getChild("MenuPanel"):getChild("PlayButton"):registerEventHandler("Clicked", menuPlayClicked) - root:getChild("MenuPanel"):getChild("ReturnButton"):registerEventHandler("Clicked", returnButtonClicked) - root:getChild("MenuPanel"):getChild("QuitButton"):registerEventHandler("Clicked", quitButtonClicked) - root:getChild("BottomSection"):getChild("SaveButton"):registerEventHandler("Clicked", rootSaveCreationClicked) - root:getChild("BottomSection"):getChild("LoadButton"):registerEventHandler("Clicked", rootLoadCreationClicked) - root:getChild("SaveLoadPanel"):getChild("ReturnButton"):registerEventHandler("Clicked", returnButtonClicked) - root:getChild("SaveLoadPanel"):getChild("SaveButton"):registerEventHandler("Clicked", saveCreationClicked) - root:getChild("SaveLoadPanel"):getChild("LoadButton"):registerEventHandler("Clicked", loadCreationClicked) + -- self.saveLoadPanel = root:getChild("SaveLoadPanel") + -- self.creationsListbox = self.saveLoadPanel:getChild("SavedCreations") + self.undoButton = root:getChild("UndoButton") + self.undoButton:registerEventHandler("Clicked", function() self.editor:undo() end) + self.redoButton = root:getChild("RedoButton") + self.redoButton:registerEventHandler("Clicked", function() self.editor:redo() end) + + root:getChild("FinishButton"):registerEventHandler("Clicked", playClicked) + --root:getChild("BottomSection"):getChild("MenuButton"):registerEventHandler("Clicked", self:menuButtonClicked) + root:getChild("MenuButton"):registerEventHandler("Clicked", menuMainMenuClicked) + --root:getChild("MenuPanel"):getChild("QuitButton"):registerEventHandler("Clicked", self:quitButtonClicked) + root:getChild("SaveMicrobeButton"):registerEventHandler("Clicked", function() self:saveCreationClicked() end) + --root:getChild("LoadMicrobeButton"):registerEventHandler("Clicked", function() self:loadCreationClicked() end) + + self.helpPanel = root:getChild("HelpPanel") + root:getChild("HelpButton"):registerEventHandler("Clicked", function() self:helpButtonClicked() end) end @@ -95,43 +100,44 @@ function MicrobeEditorHudSystem:update(renderTime, logicTime) local sceneNode = self.hoverHex:getComponent(OgreSceneNodeComponent.TYPE_ID) sceneNode.transform.position = translation sceneNode.transform:touch() + -- Handle input if Engine.mouse:wasButtonPressed(Mouse.MB_Left) then self.editor:performLocationAction() end if Engine.keyboard:wasKeyPressed(Keyboard.KC_C) then -- These global event handlers are defined in microbe_editor_hud.lua - nucleusClicked() - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_R) then + self:nucleusClicked() + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_R) then if Engine.keyboard:isKeyDown(Keyboard.KC_LCONTROL) then self.editor:redo() else - self.editor:setActiveAction("remove") + self:removeClicked() self.editor:performLocationAction() end elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_U) then if Engine.keyboard:isKeyDown(Keyboard.KC_LCONTROL) then self.editor:undo() end - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_S) then - vacuoleClicked() + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_S) then + self:vacuoleClicked() self.editor:performLocationAction() - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_T) then + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_T) then if not Engine:playerData():lockedMap():isLocked("Toxin") then - toxinClicked() + self:toxinClicked() self.editor:performLocationAction() end - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F) then - flageliumClicked() + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F) then + self:flageliumClicked() self.editor:performLocationAction() elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_M) then - mitochondriaClicked() + self:mitochondriaClicked() self.editor:performLocationAction() - --elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_A) and self.editor.currentMicrobe ~= nil then - -- aminoSynthesizerClicked() + --elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_A) and self.editor.currentMicrobe ~= nil then + -- self:aminoSynthesizerClicked() -- self.editor:performLocationAction() elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_P) then - chloroplastClicked() + self:chloroplastClicked() self.editor:performLocationAction() elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_G) then if self.editor.gridVisible then @@ -141,12 +147,11 @@ function MicrobeEditorHudSystem:update(renderTime, logicTime) self.editor.gridSceneNode.visible = true; self.editor.gridVisible = true end - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_ESCAPE) then - menuButtonClicked() - elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F2) then - playClicked() + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F2) then + self:playClicked() + elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F12) then + self:updateMicrobeName() end - properties = Entity(CAMERA_NAME .. 3):getComponent(OgreCameraComponent.TYPE_ID).properties newFovY = properties.fovY + Degree(Engine.mouse:scrollChange()/10) if newFovY < Degree(10) then @@ -158,163 +163,220 @@ function MicrobeEditorHudSystem:update(renderTime, logicTime) properties:touch() end - -function MicrobeEditorHudSystem:updateMutationPoints() - self.mpProgressBar:progressbarSetProgress(self.editor.mutationPoints/100) +function MicrobeEditorHudSystem:updateMutationPoints() + --self.mpProgressBar:progressbarSetProgress(self.editor.mutationPoints/100) self.mpLabel:setText("" .. self.editor.mutationPoints) end +----------------------------------------------------------------- +-- Event handlers ----------------------------------------------- + +function playClicked() + local guiSoundEntity = Entity("gui_sounds") + guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") + Engine:setCurrentGameState(GameState.MICROBE) +end + +function menuPlayClicked() + local guiSoundEntity = Entity("gui_sounds") + guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") + Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() + playClicked() +end + +function menuMainMenuClicked() + local guiSoundEntity = Entity("gui_sounds") + guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") + Engine:setCurrentGameState(GameState.MAIN_MENU) +end + +-- the rest of the event handlers are MicrobeEditorHudSystem methods + +function MicrobeEditorHudSystem:nameClicked() + self.nameLabel:hide() + self.nameTextbox:show() + self.nameTextbox:setFocus() +end + +function MicrobeEditorHudSystem:updateMicrobeName() + self.editor.currentMicrobe.microbe.speciesName = self.nameTextbox:getText() + self.nameLabel:setText(self.editor.currentMicrobe.microbe.speciesName) + self.nameTextbox:hide() + self.nameLabel:show() +end + +function MicrobeEditorHudSystem:helpButtonClicked() + local guiSoundEntity = Entity("gui_sounds") + guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") + if self.helpPanelOpen then + self.helpPanel:hide() + else + self.helpPanel:show() + end + self.helpPanelOpen = not self.helpPanelOpen +end --- Event handlers -function nucleusClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:nucleusClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem:setActiveAction("nucleus") + self:setActiveAction("nucleus") end -function flageliumClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:flageliumClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = global_activeMicrobeEditorHudSystem.organelleButtons["Flagelium"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("flagelium") + self.activeButton = self.organelleButtons["flagelium"] + self.activeButton:disable() + self:setActiveAction("flagelium") end -function mitochondriaClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:mitochondriaClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = - global_activeMicrobeEditorHudSystem.organelleButtons["Mitochondria"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("mitochondrion") + self.activeButton = self.organelleButtons["mitochondrion"] + self.activeButton:disable() + self:setActiveAction("mitochondrion") end -function chloroplastClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:chloroplastClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem:setActiveAction("chloroplast") + self.activeButton = self.organelleButtons["chloroplast"] + self.activeButton:disable() + self:setActiveAction("chloroplast") end -function aminoSynthesizerClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() + +function MicrobeEditorHudSystem:aminoSynthesizerClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = - global_activeMicrobeEditorHudSystem.organelleButtons["AminoSynthesizer"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("aminosynthesizer") + self.activeButton = self.organelleButtons["aminosynthesizer"] + self.activeButton:disable() + self:setActiveAction("aminosynthesizer") end -function vacuoleClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:vacuoleClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = - global_activeMicrobeEditorHudSystem.organelleButtons["Vacuole"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("vacuole") + self.activeButton = self.organelleButtons["vacuole"] + self.activeButton:disable() + self:setActiveAction("vacuole") end -function toxinClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:toxinClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = - global_activeMicrobeEditorHudSystem.organelleButtons["Toxin"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("toxin") + self.activeButton = self.organelleButtons["Toxin"] + self.activeButton:disable() + self:setActiveAction("toxin") end -function removeClicked() - if global_activeMicrobeEditorHudSystem.activeButton ~= nil then - global_activeMicrobeEditorHudSystem.activeButton:enable() +function MicrobeEditorHudSystem:removeClicked() + if self.activeButton ~= nil then + self.activeButton:enable() end - global_activeMicrobeEditorHudSystem.activeButton = - global_activeMicrobeEditorHudSystem.organelleButtons["Remove"] - global_activeMicrobeEditorHudSystem.activeButton:disable() - global_activeMicrobeEditorHudSystem:setActiveAction("remove") + self.activeButton = nil + self:setActiveAction("remove") end -function rootSaveCreationClicked() +function MicrobeEditorHudSystem:rootSaveCreationClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - panel = global_activeMicrobeEditorHudSystem.saveLoadPanel + print ("Save button clicked") + --[[ + panel = self.saveLoadPanel panel:getChild("SaveButton"):show() panel:getChild("NameTextbox"):show() panel:getChild("CreationNameDialogLabel"):show() panel:getChild("LoadButton"):hide() panel:getChild("SavedCreations"):hide() - panel:show() + panel:show()--]] end -function rootLoadCreationClicked() +function MicrobeEditorHudSystem:rootLoadCreationClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - panel = global_activeMicrobeEditorHudSystem.saveLoadPanel + panel = self.saveLoadPanel panel:getChild("SaveButton"):hide() panel:getChild("NameTextbox"):hide() panel:getChild("CreationNameDialogLabel"):hide() panel:getChild("LoadButton"):show() panel:getChild("SavedCreations"):show() panel:show() - global_activeMicrobeEditorHudSystem.creationsListbox:itemListboxResetList() - global_activeMicrobeEditorHudSystem.creationFileMap = {} + self.creationsListbox:itemListboxResetList() + self.creationFileMap = {} i = 0 pathsString = Engine:getCreationFileList("microbe") -- using pattern matching for splitting on spaces - for path in string.gmatch(pathsString, "%S+") do - item = CEGUIWindow("Thrive/ListboxItem", "creationItems"..i) - pathSep = package.config:sub(1,1) -- / for unix, \ for windows - text = string.sub(path, string.len(path) - string.find(path:reverse(), pathSep) + 2) - item:setText(text) - global_activeMicrobeEditorHudSystem.creationsListbox:itemListboxAddItem(item) - global_activeMicrobeEditorHudSystem.creationFileMap[text] = path - i = i + 1 + for path in string.gmatch(pathsString, "%S+") do + -- this is unsafe when one of the paths is, for example, C:\\Application Data\Thrive\saves + item = CEGUIWindow("Thrive/ListboxItem", "creationItems"..i) + pathSep = package.config:sub(1,1) -- / for unix, \ for windows + text = string.sub(path, string.len(path) - string.find(path:reverse(), pathSep) + 2) + item:setText(text) + self.creationsListbox:itemListboxAddItem(item) + self.creationFileMap[text] = path + i = i + 1 end - global_activeMicrobeEditorHudSystem.creationsListbox:itemListboxHandleUpdatedItemData() + self.creationsListbox:itemListboxHandleUpdatedItemData() end -function saveCreationClicked() +function MicrobeEditorHudSystem:saveCreationClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - name = panel:getChild("NameTextbox"):getText() + name = self.editor.currentMicrobe.microbe.speciesName + print("saving "..name) -- Todo: Additional input sanitation - if string.len(name) > 0 then - Engine:saveCreation(global_activeMicrobeEditorHudSystem.editor.currentMicrobe.entity.id, name, "microbe") - panel:hide() + name, _ = string.gsub(name, "%s+", "_") -- replace whitespace with underscore + if string.match(name, "^[%w_]+$") == nil then + print("unsanitary name: "..name) -- should we do the test before whitespace sanitization? + elseif string.len(name) > 0 then + Engine:saveCreation(self.editor.currentMicrobe.entity.id, name, "microbe") end end -function loadCreationClicked() +function MicrobeEditorHudSystem:loadCreationClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - item = global_activeMicrobeEditorHudSystem.creationsListbox:itemListboxGetLastSelectedItem() + item = self.creationsListbox:itemListboxGetLastSelectedItem() if not item:isNull() then - entity = Engine:loadCreation(global_activeMicrobeEditorHudSystem.creationFileMap[item:getText()]) - global_activeMicrobeEditorHudSystem.editor:loadMicrobe(entity) + entity = Engine:loadCreation(self.creationFileMap[item:getText()]) + self.editor:loadMicrobe(entity) panel:hide() end end -function playClicked() - local guiSoundEntity = Entity("gui_sounds") - guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:setCurrentGameState(GameState.MICROBE) -end +-- useful debug functions -function menuPlayClicked() - local guiSoundEntity = Entity("gui_sounds") - guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() - playClicked() +function MicrobeEditorHudSystem:loadByName(name) + if string.find(name, ".microbe") then + print("note, you don't need to add the .microbe extension") + else + name = name..".microbe" + end + name, _ = string.gsub(name, "%s+", "_") + creationFileMap = {} + i = 0 + pathsString = Engine:getCreationFileList("microbe") + -- using pattern matching for splitting on spaces + for path in string.gmatch(pathsString, "%S+") do + -- this is unsafe when one of the paths is, for example, C:\\Application Data\Thrive\saves + pathSep = package.config:sub(1,1) -- / for unix, \ for windows + text = string.sub(path, string.len(path) - string.find(path:reverse(), pathSep) + 2) + creationFileMap[text] = path + i = i + 1 + end + entity = Engine:loadCreation(creationFileMap[name]) + self.editor:loadMicrobe(entity) + self.nameLabel:setText(self.editor.currentMicrobe.microbe.speciesName) end -function menuMainMenuClicked() - local guiSoundEntity = Entity("gui_sounds") - guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:setCurrentGameState(GameState.MAIN_MENU) -end \ No newline at end of file +function saveMicrobe() global_activeMicrobeEditorHudSystem:saveCreationClicked() end +function loadMicrobe(name) global_activeMicrobeEditorHudSystem:loadByName(name) end diff --git a/scripts/microbe_stage/microbe.lua b/scripts/microbe_stage/microbe.lua index d1e21a31ff3..63567173295 100644 --- a/scripts/microbe_stage/microbe.lua +++ b/scripts/microbe_stage/microbe.lua @@ -18,6 +18,7 @@ REPRODUCTASE_TO_SPLIT = 5 function MicrobeComponent:__init(isPlayerMicrobe) Component.__init(self) + self.speciesName = "Default" self.hitpoints = 10 self.maxHitpoints = 10 self.dead = false diff --git a/scripts/microbe_stage/microbe_stage_hud.lua b/scripts/microbe_stage/microbe_stage_hud.lua index acbd11e8a67..53e966a6a4e 100644 --- a/scripts/microbe_stage/microbe_stage_hud.lua +++ b/scripts/microbe_stage/microbe_stage_hud.lua @@ -8,7 +8,7 @@ function HudSystem:__init() self.hitpointsCountLabel = nil self.hitpointsBar = nil self.compoundListItems = {} - self.rootGuiWindow = nil + self.rootGUIWindow = nil end global_if_already_displayed = false @@ -20,39 +20,40 @@ function HudSystem:activate() showMessage("'E' Releases Toxin") global_if_already_displayed = true end + self.helpOpen = false + self.menuOpen = true end function HudSystem:init(gameState) - System.init(self, gameState) - self.rootGuiWindow = gameState:rootGUIWindow() - self.compoundListBox = self.rootGuiWindow:getChild("BottomSection"):getChild("CompoundList") - self.hitpointsBar = self.rootGuiWindow:getChild("BottomSection"):getChild("LifeBar") + System.init(self, gameState) ---[[ + self.rootGUIWindow = gameState:rootGUIWindow() + self.compoundListBox = self.rootGUIWindow:getChild("CompoundsOpen"):getChild("CompoundsLabel") + self.hitpointsBar = self.rootGUIWindow:getChild("HealthPanel"):getChild("LifeBar") self.hitpointsCountLabel = self.hitpointsBar:getChild("NumberLabel") - local menuButton = self.rootGuiWindow:getChild("BottomSection"):getChild("MenuButton") - local helpButton = self.rootGuiWindow:getChild("BottomSection"):getChild("HelpButton") - local editorButton = self.rootGuiWindow:getChild("MenuPanel"):getChild("EditorButton") - local editorButton2 = self.rootGuiWindow:getChild("ReproductionPanel"):getChild("EditorButton") - local returnButton = self.rootGuiWindow:getChild("MenuPanel"):getChild("ReturnButton") - local returnButton2 = self.rootGuiWindow:getChild("HelpPanel"):getChild("ReturnButton") - local returnButton3 = self.rootGuiWindow:getChild("MessagePanel"):getChild("ReturnButton") - local returnButton4 = self.rootGuiWindow:getChild("ReproductionPanel"):getChild("ReturnButton") - local quitButton = self.rootGuiWindow:getChild("MenuPanel"):getChild("QuitButton") - menuButton:registerEventHandler("Clicked", menuButtonClicked) - helpButton:registerEventHandler("Clicked", helpButtonClicked) - editorButton:registerEventHandler("Clicked", editorButtonClicked) - editorButton2:registerEventHandler("Clicked", editorButtonClicked) - returnButton:registerEventHandler("Clicked", returnButtonClicked) - returnButton2:registerEventHandler("Clicked", returnButtonClicked) - returnButton3:registerEventHandler("Clicked", returnButtonClicked) - returnButton4:registerEventHandler("Clicked", returnButtonClicked) + self.nameLabel = self.rootGUIWindow:getChild("SpeciesNamePanel"):getChild("SpeciesNameLabel") + local menuButton = self.rootGUIWindow:getChild("MenuButton") + --local collapseButton = self.rootGUIWindow:getChild() collapseButtonClicked + local helpButton = self.rootGUIWindow:getChild("HelpButton") + self.editorButton = self.rootGUIWindow:getChild("EditorButton") + --local returnButton = self.rootGUIWindow:getChild("MenuButton") + local compoundButton = self.rootGUIWindow:getChild("CompoundsClosed") + local compoundPanel = self.rootGUIWindow:getChild("CompoundsOpen") + local quitButton = self.rootGUIWindow:getChild("QuitButton") + menuButton:registerEventHandler("Clicked", function() self:menuButtonClicked() end) + helpButton:registerEventHandler("Clicked", function() self:helpButtonClicked() end) + self.editorButton:registerEventHandler("Clicked", function() self:editorButtonClicked() end) + --returnButton:registerEventHandler("Clicked", returnButtonClicked) + compoundButton:registerEventHandler("Clicked", function() self:openCompoundPanel() end) + compoundPanel:registerEventHandler("Clicked", function() self:closeCompoundPanel() end) quitButton:registerEventHandler("Clicked", quitButtonClicked) - self.rootGuiWindow:getChild("MenuPanel"):getChild("MainMenuButton"):registerEventHandler("Clicked", menuMainMenuClicked) + self.rootGUIWindow:getChild("MainMenuButton"):registerEventHandler("Clicked", menuMainMenuClicked) -- in microbe_editor_hud.lua end function HudSystem:update(renderTime) local player = Entity("player") local playerMicrobe = Microbe(player) + self.nameLabel:setText(playerMicrobe.microbe.speciesName) self.hitpointsBar:progressbarSetProgress(playerMicrobe.microbe.hitpoints/playerMicrobe.microbe.maxHitpoints) self.hitpointsCountLabel:setText("".. math.floor(playerMicrobe.microbe.hitpoints)) @@ -67,12 +68,12 @@ function HudSystem:update(renderTime) self.compoundListItems[compoundID]:setText(compoundsString) end end - self.compoundListBox:listboxHandleUpdatedItemData() + self.compoundListBox:listboxHandleUpdatedItemData() --]] if Engine.keyboard:wasKeyPressed(Keyboard.KC_ESCAPE) then - menuButtonClicked() + self:menuButtonClicked() elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_F2) then - editorButtonClicked() + self:editorButtonClicked() elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_E) then playerMicrobe:emitAgent(CompoundRegistry.getCompoundId("oxytoxy"), 3) elseif Engine.keyboard:wasKeyPressed(Keyboard.KC_P) then @@ -99,49 +100,85 @@ function HudSystem:update(renderTime) elseif newZVal > 80 then newZVal = 80 end - offset.z = newZVal + offset.z = newZVal --]] end -function showReproductionDialog() - global_activeMicrobeStageHudSystem.rootGuiWindow:getChild("ReproductionPanel"):show() +function showReproductionDialog() global_activeMicrobeStageHudSystem:showReproductionDialog() end + +function HudSystem:showReproductionDialog() + print("Reproduction Dialog called but currently disabled. Is it needed? Note that the editor button has been enabled") + --global_activeMicrobeStageHudSystem.rootGUIWindow:getChild("ReproductionPanel"):show() + self.editorButton:enable() end function showMessage(msg) - local messagePanel = Engine:currentGameState():rootGUIWindow():getChild("MessagePanel") - messagePanel:getChild("MessageLabel"):setText(msg) - messagePanel:show() + print(msg.." (note, in-game messages currently disabled)") + --local messagePanel = Engine:currentGameState():rootGUIWindow():getChild("MessagePanel") + --messagePanel:getChild("MessageLabel"):setText(msg) + --messagePanel:show() end --Event handlers -function menuButtonClicked() +function HudSystem:menuButtonClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):show() - if Engine:currentGameState():name() == "microbe" then - Engine:currentGameState():rootGUIWindow():getChild("HelpPanel"):hide() + print("played sound") + if not self.menuOpen then + self.rootGUIWindow:getChild("StatsButton"):playAnimation("MoveToStatsButton"); + self.rootGUIWindow:getChild("HelpButton"):playAnimation("MoveToHelpButton"); + self.rootGUIWindow:getChild("OptionsButton"):playAnimation("MoveToOptionsButton"); + self.rootGUIWindow:getChild("LoadGameButton"):playAnimation("MoveToLoadGameButton"); + self.rootGUIWindow:getChild("SaveGameButton"):playAnimation("MoveToSaveGameButton"); + self.menuOpen = true + else + self.rootGUIWindow:getChild("StatsButton"):playAnimation("MoveToMenuButtonD0"); + self.rootGUIWindow:getChild("HelpButton"):playAnimation("MoveToMenuButtonD2"); + self.rootGUIWindow:getChild("OptionsButton"):playAnimation("MoveToMenuButtonD1"); + self.rootGUIWindow:getChild("LoadGameButton"):playAnimation("MoveToMenuButtonD4"); + self.rootGUIWindow:getChild("SaveGameButton"):playAnimation("MoveToMenuButtonD3"); + self.menuOpen = false end - Engine:pauseGame() end -function helpButtonClicked() +function HudSystem:openCompoundPanel() + self.rootGUIWindow:getChild("CompoundsOpen"):show() + self.rootGUIWindow:getChild("CompoundsClosed"):hide() +end + +function HudSystem:closeCompoundPanel() + self.rootGUIWindow:getChild("CompoundsOpen"):hide() + self.rootGUIWindow:getChild("CompoundsClosed"):show() +end + +function HudSystem:helpButtonClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() + --Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() if Engine:currentGameState():name() == "microbe" then - Engine:currentGameState():rootGUIWindow():getChild("HelpPanel"):show() + if self.helpOpen then + Engine:resumeGame() + self.rootGUIWindow:getChild("HelpPanel"):hide() + else + Engine:pauseGame() + self.rootGUIWindow:getChild("HelpPanel"):show() + end + self.helpOpen = not self.helpOpen end end -function editorButtonClicked() + +function HudSystem:editorButtonClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") + self.editorButton:disable() Engine:setCurrentGameState(GameState.MICROBE_EDITOR) end -function returnButtonClicked() +--[[ +function HudSystem:returnButtonClicked() local guiSoundEntity = Entity("gui_sounds") guiSoundEntity:getComponent(SoundSourceComponent.TYPE_ID):playSound("button-hover-click") - Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() + --Engine:currentGameState():rootGUIWindow():getChild("MenuPanel"):hide() if Engine:currentGameState():name() == "microbe" then Engine:currentGameState():rootGUIWindow():getChild("HelpPanel"):hide() Engine:currentGameState():rootGUIWindow():getChild("MessagePanel"):hide() @@ -150,7 +187,7 @@ function returnButtonClicked() elseif Engine:currentGameState():name() == "microbe_editor" then Engine:currentGameState():rootGUIWindow():getChild("SaveLoadPanel"):hide() end -end +end --]] function quitButtonClicked() local guiSoundEntity = Entity("gui_sounds") diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 439fe1c7d00..f5c8f714d6f 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -335,6 +335,8 @@ struct Engine::Implementation : public Ogre::WindowEventListener { CEGUI::SchemeManager::getSingleton().createFromFile("Thrive.scheme"); CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("ThriveGeneric/MouseArrow"); + CEGUI::AnimationManager::getSingleton().loadAnimationsFromXML("thrive.anims"); + //For demos: CEGUI::SchemeManager::getSingleton().createFromFile("TaharezLook.scheme"); CEGUI::SchemeManager::getSingleton().createFromFile("SampleBrowser.scheme"); @@ -868,6 +870,8 @@ Engine::update( luabind::call_member(m_impl->m_console, "update"); + CEGUI::System::getSingleton().injectTimePulse(milliseconds/1000.0f); + // Update any timed shutdown systems auto itr = m_impl->m_prevShutdownSystems->begin(); while (itr != m_impl->m_prevShutdownSystems->end()) { diff --git a/src/gui/CEGUIWindow.cpp b/src/gui/CEGUIWindow.cpp index 95a9c821502..fca297c297f 100644 --- a/src/gui/CEGUIWindow.cpp +++ b/src/gui/CEGUIWindow.cpp @@ -89,6 +89,7 @@ CEGUIWindow::CEGUIWindow( ) : m_window(window) { if (window && newWindow ) { + m_window->subscribeEvent("MouseClick", handleWindowMove); } } @@ -159,6 +160,7 @@ CEGUIWindow::luaBindings() { .def("moveInFront", &CEGUIWindow::moveInFront) .def("moveBehind", &CEGUIWindow::moveBehind) .def("setPosition", &CEGUIWindow::setPosition) + .def("playAnimation", &CEGUIWindow::playAnimation) .def("listboxAddItem", &CEGUIWindow::listboxAddItem) .def("listboxResetList", &CEGUIWindow::listboxResetList) .def("listboxHandleUpdatedItemData", &CEGUIWindow::listboxHandleUpdatedItemData) @@ -399,3 +401,13 @@ CEGUIWindow::setPosition( ){ m_window->setPosition(CEGUI::Vector2(CEGUI::UDim(position.x, 0), CEGUI::UDim(position.y, 0))); } + + +void +CEGUIWindow::playAnimation( + std::string name +) { + auto anim = CEGUI::AnimationManager::getSingleton().instantiateAnimation(name); + anim->setTargetWindow(m_window); + anim->start(); +} diff --git a/src/gui/CEGUIWindow.h b/src/gui/CEGUIWindow.h index ecc09b2ed2d..515b1f1c366 100644 --- a/src/gui/CEGUIWindow.h +++ b/src/gui/CEGUIWindow.h @@ -75,6 +75,8 @@ class CEGUIWindow { * - CEGUIWindow::moveBehind * - CEGUIWindow::setPosition * + * - CEGUIWindow::playAnimation + * * - CEGUIWindow::listboxAddItem * - CEGUIWindow::listboxResetList * - CEGUIWindow::listboxHandleUpdatedItemData @@ -377,6 +379,11 @@ class CEGUIWindow { ); + void + playAnimation( + std::string name + ); + private: