Some particle stuff, far from done
This commit is contained in:
		
							parent
							
								
									2b621cace6
								
							
						
					
					
						commit
						6a85c31a77
					
				|  | @ -8,6 +8,7 @@ Module | |||
|   load-later: | ||||
|     - client_skins | ||||
|     - client_locales | ||||
|     - client_particles | ||||
|     - client_topmenu | ||||
|     - client_background | ||||
|     //- client_about | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ local localeComboBox | |||
| local function sendLocale(localeName) | ||||
|   local protocolGame = g_game.getProtocolGame() | ||||
|   if protocolGame then | ||||
|     protocolGame:sendExtendedOpcode(1, localeName) | ||||
|     protocolGame:sendExtendedOpcode(ExtendedLocales, localeName) | ||||
|     return true | ||||
|   end | ||||
|   return false | ||||
|  | @ -32,7 +32,7 @@ local function onGameStart() | |||
|   sendLocale(currentLocale.name) | ||||
| end | ||||
| 
 | ||||
| local function onServerSetLocale(protocol, opcode, buffer) | ||||
| local function onExtendedLocales(protocol, opcode, buffer) | ||||
|   local locale = installedLocales[buffer] | ||||
|   if locale then | ||||
|     localeComboBox:setCurrentOption(locale.languageName) | ||||
|  | @ -63,7 +63,7 @@ function Locales.init() | |||
|               localeComboBox.onOptionChange = onLocaleComboBoxOptionChange | ||||
|             end, false) | ||||
| 
 | ||||
|   Extended.register(1, onServerSetLocale) | ||||
|   Extended.register(ExtendedLocales, onExtendedLocales) | ||||
|   connect(g_game, { onGameStart = onGameStart }) | ||||
| end | ||||
| 
 | ||||
|  | @ -71,7 +71,7 @@ function Locales.terminate() | |||
|   installedLocales = nil | ||||
|   currentLocale = nil | ||||
|   localeComboBox = nil | ||||
|   Extended.unregister(1) | ||||
|   Extended.unregister(ExtendedLocales) | ||||
|   disconnect(g_game, { onGameStart = onGameStart }) | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,95 @@ | |||
| Particles = { } | ||||
| 
 | ||||
| -- private variables | ||||
| local particlesWindow | ||||
| local particlesButton | ||||
| 
 | ||||
| -- private functions | ||||
| local function onExtendedParticles(protocol, opcode, buffer) | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
| -- public functions | ||||
| function Particles.init() | ||||
|   particlesWindow = g_ui.displayUI('particles.otui') | ||||
|   particlesButton = TopMenu.addLeftButton('particlesButton', tr('Particles Manager'), 'particles.png', Particles.toggle) | ||||
| 
 | ||||
|   local particlesList = particlesWindow:getChildById('particlesList') | ||||
|   g_keyboard.bindKeyPress('Up', function() particlesList:focusPreviousChild(KeyboardFocusReason) end, particlesWindow) | ||||
|   g_keyboard.bindKeyPress('Down', function() particlesList:focusNextChild(KeyboardFocusReason) end, particlesWindow) | ||||
| 
 | ||||
|   Extended.register(ExtendedParticles, onExtendedParticles) | ||||
| end | ||||
| 
 | ||||
| function Particles.terminate() | ||||
|   particlesWindow:destroy() | ||||
|   particlesWindow = nil | ||||
| 
 | ||||
|   particlesButton:destroy() | ||||
|   particlesButton = nil | ||||
| 
 | ||||
|   Extended.unregister(ExtendedParticles) | ||||
| end | ||||
| 
 | ||||
| function Particles.show() | ||||
|   Particles.refreshList() | ||||
|   particlesWindow:show() | ||||
|   particlesWindow:raise() | ||||
|   particlesWindow:focus() | ||||
| end | ||||
| 
 | ||||
| function Particles.hide() | ||||
|   particlesWindow:hide() | ||||
| end | ||||
| 
 | ||||
| function Particles.toggle() | ||||
|   if particlesWindow:isVisible() then | ||||
|     Particles.hide() | ||||
|   else | ||||
|     Particles.show() | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function Particles.refreshInfo() | ||||
|   local particlesList = particlesWindow:getChildById('particlesList') | ||||
|   local widget = particlesList:getFocusedChild() | ||||
| 
 | ||||
|   local name = particlesWindow:getChildById('name') | ||||
|   name:setText(widget.effect:getName()) | ||||
| 
 | ||||
|   local location = particlesWindow:getChildById('location') | ||||
|   location:setText(widget.effect:getFile()) | ||||
| 
 | ||||
|   local description = particlesWindow:getChildById('description') | ||||
|   description:setText(widget.effect:getDescription()) | ||||
| end | ||||
| 
 | ||||
| function Particles.refreshList() | ||||
|   local particlesList = particlesWindow:getChildById('particlesList') | ||||
|   particlesList.onChildFocusChange = nil | ||||
|   particlesList:destroyChildren() | ||||
| 
 | ||||
|   local firstChild = nil | ||||
|   local effects = g_particles.getEffectsTypes() | ||||
|   for name,effect in pairs(effects) do | ||||
|     local label = g_ui.createWidget('ParticlesListLabel', particlesList) | ||||
|     label:setText(name) | ||||
|     label.effect = effect | ||||
| 
 | ||||
|     if not firstChild then | ||||
|       firstChild = label | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   particlesList.onChildFocusChange = Particles.refreshInfo | ||||
|   if firstChild then | ||||
|     firstChild:focus() | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function Particles.start() | ||||
|   local particlesList = particlesWindow:getChildById('particlesList') | ||||
|   local focusedEffect = particlesList:getFocusedChild() | ||||
|   local preview = particlesWindow:getChildById('preview') | ||||
|   preview:addEffect(focusedEffect:getText()) | ||||
| end | ||||
|  | @ -0,0 +1,17 @@ | |||
| Module | ||||
|   name: client_particles | ||||
|   description: Manages particles systems | ||||
|   author: baxnie | ||||
|   website: www.otclient.info | ||||
| 
 | ||||
|   dependencies: | ||||
|     - client_extended | ||||
|     - client_locales | ||||
|     - client_topmenu | ||||
| 
 | ||||
|   @onLoad: | | ||||
|     dofile 'particles' | ||||
|     Particles.init() | ||||
| 
 | ||||
|   @onUnload: | | ||||
|     Particles.terminate() | ||||
|  | @ -0,0 +1,130 @@ | |||
| ParticlesListLabel < Label | ||||
|   font: verdana-11px-monochrome | ||||
|   background-color: alpha | ||||
|   text-offset: 2 0 | ||||
|   focusable: true | ||||
| 
 | ||||
|   $focus: | ||||
|     background-color: #ffffff22 | ||||
|     color: #ffffff | ||||
| 
 | ||||
| MainWindow | ||||
|   id: particlesWindow | ||||
|   !text: tr('Particles Manager') | ||||
|   size: 450 450 | ||||
|   visible: false | ||||
|   @onEscape: Particles.hide() | ||||
| 
 | ||||
|   TextList | ||||
|     id: particlesList | ||||
|     anchors.top: parent.top | ||||
|     anchors.left: parent.left | ||||
|     anchors.bottom: separator.top | ||||
|     width: 128 | ||||
|     padding: 1 | ||||
|     focusable: false | ||||
|     margin-bottom: 10 | ||||
|     vertical-scrollbar: particlesListScrollBar | ||||
| 
 | ||||
|   VerticalScrollBar | ||||
|     id: particlesListScrollBar | ||||
|     anchors.top: particlesList.top | ||||
|     anchors.bottom: particlesList.bottom | ||||
|     anchors.left: particlesList.right | ||||
|     step: 14 | ||||
|     pixels-scroll: true | ||||
| 
 | ||||
|   Label | ||||
|     !text: tr('Name') | ||||
|     anchors.top: parent.top | ||||
|     anchors.left: prev.right | ||||
|     margin-left: 10 | ||||
| 
 | ||||
|   FlatLabel | ||||
|     id: name | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     anchors.right: parent.right | ||||
|     margin-top: 3 | ||||
| 
 | ||||
|   Label | ||||
|     !text: tr('Location') | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     margin-top: 10 | ||||
| 
 | ||||
|   FlatLabel | ||||
|     id: location | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     anchors.right: parent.right | ||||
|     margin-top: 3 | ||||
| 
 | ||||
|   Label | ||||
|     !text: tr('Description') | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     margin-top: 10 | ||||
| 
 | ||||
|   FlatLabel | ||||
|     id: description | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     anchors.right: parent.right | ||||
|     margin-top: 3 | ||||
| 
 | ||||
|   Label | ||||
|     !text: tr('Preview') | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.left: prev.left | ||||
|     margin-top: 10 | ||||
| 
 | ||||
|   ParticlesFlatPanel | ||||
|     id: preview | ||||
|     margin-top: 3 | ||||
|     margin-bottom: 10 | ||||
|     anchors.top: prev.bottom | ||||
|     anchors.bottom: next.top | ||||
|     anchors.left: prev.left | ||||
|     anchors.right: parent.right | ||||
| 
 | ||||
|     reference: 10 10 | ||||
| 
 | ||||
|   Button | ||||
|     id: startButton | ||||
|     !text: tr('Start') | ||||
|     width: 64 | ||||
|     anchors.bottom: separator.top | ||||
|     anchors.left: location.left | ||||
|     margin-bottom: 10 | ||||
| 
 | ||||
|   Button | ||||
|     id: pauseButton | ||||
|     !text: tr('Pause') | ||||
|     width: 64 | ||||
|     anchors.bottom: prev.bottom | ||||
|     anchors.left: prev.right | ||||
|     margin-left: 5 | ||||
| 
 | ||||
|   Button | ||||
|     id: reloadButton | ||||
|     !text: tr('Reload') | ||||
|     width: 64 | ||||
|     anchors.bottom: separator.top | ||||
|     anchors.right: parent.right | ||||
|     margin-bottom: 10 | ||||
| 
 | ||||
|   HorizontalSeparator | ||||
|     id: separator | ||||
|     anchors.left: parent.left | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: next.top | ||||
|     margin-bottom: 10 | ||||
| 
 | ||||
|   Button | ||||
|     id: closeButton | ||||
|     !text: tr('Close') | ||||
|     width: 64 | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: parent.bottom | ||||
|     @onClick: Particles.hide() | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 571 B | 
|  | @ -110,6 +110,7 @@ end | |||
| function Skins.loadSkin(skin) | ||||
|   local lowerName = string.lower(skin.name) | ||||
| 
 | ||||
|   if skin.fonts then | ||||
|     for i=1,#skin.fonts do | ||||
|       g_fonts.importFont('skins/' .. lowerName .. '/fonts/' .. skin.fonts[i]) | ||||
| 
 | ||||
|  | @ -117,8 +118,17 @@ function Skins.loadSkin(skin) | |||
|         g_fonts.setDefaultFont(skin.fonts[i]) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   if skin.styles then | ||||
|     for i=1,#skin.styles do | ||||
|       g_ui.importStyle('skins/' .. lowerName .. '/styles/' .. skin.styles[i]) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   if skin.particles then | ||||
|     for i=1,#skin.particles do | ||||
|       g_particles.importParticle('skins/' .. lowerName .. '/particles/' .. skin.particles[i]) | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -29,6 +29,10 @@ local skin = { | |||
|     'miniwindow.otui', | ||||
|     'items.otui', | ||||
|     'creatures.otui' | ||||
|   }, | ||||
| 
 | ||||
|   particles = { | ||||
|     'shiny.otps' | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,52 @@ | |||
| Particle | ||||
|   name: shiny_star | ||||
| 
 | ||||
|   min-position-radius: 0 | ||||
|   max-position-radius: 8 | ||||
|   min-position-angle: 0 | ||||
|   max-position-angle: 360 | ||||
|   velocity: 4 | ||||
|   min-velocity-angle: 0 | ||||
|   max-velocity-angle: 360 | ||||
| 
 | ||||
|   particle-size: 4 4 | ||||
|   texture: shiny_star.png | ||||
|   composition-mode: addition | ||||
| 
 | ||||
| Effect | ||||
|   name: Shiny3 | ||||
|   description: 3 Shiny stars derping aroud | ||||
| 
 | ||||
|   System | ||||
|     position: 0 0 | ||||
| 
 | ||||
|     Emitter | ||||
|       position: 0 0 | ||||
|       delay: 0 | ||||
|       duration: 0 | ||||
|       burstRate: 0 | ||||
|       burstCount: 3 | ||||
|       particle-type: shiny_star | ||||
| 
 | ||||
|     AttractionAffector | ||||
|       position: 0 0 | ||||
|       acceleration: 2 | ||||
| 
 | ||||
| Effect | ||||
|   name: Shiny5 | ||||
|   description: 5 Shiny stars derping aroud | ||||
| 
 | ||||
|   System | ||||
|     position: 0 0 | ||||
| 
 | ||||
|     Emitter | ||||
|       position: 0 0 | ||||
|       delay: 0 | ||||
|       duration: 0 | ||||
|       burstRate: 0 | ||||
|       burstCount: 5 | ||||
|       particle-type: shiny_star | ||||
| 
 | ||||
|     AttractionAffector | ||||
|       position: 0 0 | ||||
|       acceleration: 2 | ||||
|  | @ -11,3 +11,7 @@ FlatPanel < Panel | |||
| ScrollableFlatPanel < ScrollablePanel | ||||
|   image-source: /images/panel_flat.png | ||||
|   image-border: 1 | ||||
| 
 | ||||
| ParticlesFlatPanel < Panel | ||||
|   image-source: /images/panel_flat.png | ||||
|   image-border: 1 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| local skin = { | ||||
| 	name = 'Example', | ||||
| 
 | ||||
| 	fonts = {}, | ||||
| 
 | ||||
| 	styles = { | ||||
| 		'topmenu.otui' | ||||
| 	} | ||||
|  |  | |||
|  | @ -186,7 +186,6 @@ SpeakChannelOrange = 12 | |||
| SpeakMonsterSay = 13 | ||||
| SpeakMonsterYell = 14 | ||||
| 
 | ||||
| 
 | ||||
| FightOffensive = 1 | ||||
| FightBalanced = 2 | ||||
| FightDefensive = 3 | ||||
|  | @ -194,6 +193,10 @@ FightDefensive = 3 | |||
| DontChase = 0 | ||||
| ChaseOpponent = 1 | ||||
| 
 | ||||
| ExtendedActivate = 0 | ||||
| ExtendedLocales = 1 | ||||
| ExtendedParticles = 2 | ||||
| 
 | ||||
| -- @} | ||||
| 
 | ||||
| KeyCodeDescs = { | ||||
|  |  | |||
|  | @ -229,6 +229,8 @@ SET(framework_SOURCES ${framework_SOURCES} | |||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particle.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particleeffect.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particleeffect.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particle.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.h | ||||
|  | @ -350,6 +352,8 @@ SET(framework_SOURCES ${framework_SOURCES} | |||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uilayout.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uiparticles.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uiparticles.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uirichtext.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uirichtext.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/ui/uitextedit.cpp | ||||
|  |  | |||
|  | @ -136,6 +136,9 @@ void Application::terminate() | |||
| { | ||||
|     assert(m_initialized); | ||||
| 
 | ||||
|     // destroy particles
 | ||||
|     g_particles.terminate(); | ||||
| 
 | ||||
|     // destroy any remaining widget
 | ||||
|     g_ui.terminate(); | ||||
| 
 | ||||
|  | @ -278,7 +281,7 @@ void Application::poll() | |||
| 
 | ||||
|     // poll input events
 | ||||
|     g_window.poll(); | ||||
|     //g_particleManager.update();
 | ||||
|     //g_particles.update();
 | ||||
| 
 | ||||
|     Connection::poll(); | ||||
|     g_dispatcher.poll(); | ||||
|  |  | |||
|  | @ -41,6 +41,8 @@ class Particle; | |||
| class ParticleEmitter; | ||||
| class ParticleAffector; | ||||
| class ParticleSystem; | ||||
| class ParticleEffect; | ||||
| class ParticleEffectType; | ||||
| 
 | ||||
| typedef std::weak_ptr<Texture> TextureWeakPtr; | ||||
| typedef std::weak_ptr<ParticleSystem> ParticleSystemWeakPtr; | ||||
|  | @ -58,6 +60,8 @@ typedef std::shared_ptr<Particle> ParticlePtr; | |||
| typedef std::shared_ptr<ParticleEmitter> ParticleEmitterPtr; | ||||
| typedef std::shared_ptr<ParticleAffector> ParticleAffectorPtr; | ||||
| typedef std::shared_ptr<ParticleSystem> ParticleSystemPtr; | ||||
| typedef std::shared_ptr<ParticleEffect> ParticleEffectPtr; | ||||
| typedef std::shared_ptr<ParticleEffectType> ParticleEffectTypePtr; | ||||
| typedef std::vector<ShaderPtr> ShaderList; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -0,0 +1,79 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include "particleeffect.h" | ||||
| 
 | ||||
| ParticleEffectType::ParticleEffectType() | ||||
| { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool ParticleEffectType::load(const OTMLNodePtr& node) | ||||
| { | ||||
|     m_node = node; | ||||
|     for(const OTMLNodePtr& childNode : node->children()) { | ||||
|         if(childNode->tag() == "name") { | ||||
|             setName(childNode->value()); | ||||
|         } | ||||
|         else if(childNode->tag() == "description") { | ||||
|             setDescription(childNode->value()); | ||||
|         } | ||||
|     } | ||||
|     return !m_name.empty(); | ||||
| } | ||||
| 
 | ||||
| bool ParticleEffect::load(const ParticleEffectTypePtr& effectType) | ||||
| { | ||||
|     if(!effectType) | ||||
|         return false; | ||||
| 
 | ||||
|     for(const OTMLNodePtr& childNode : effectType->getNode()->children()) { | ||||
|         if(childNode->tag() == "System") { | ||||
|             ParticleSystemPtr system = ParticleSystemPtr(new ParticleSystem); | ||||
|             if(system->load(childNode)) { | ||||
|                 m_systems.push_back(system); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void ParticleEffect::render() | ||||
| { | ||||
|     for(auto it = m_systems.begin(), end = m_systems.end(); it != end; ++it) | ||||
|         (*it)->render(); | ||||
| } | ||||
| 
 | ||||
| void ParticleEffect::update() | ||||
| { | ||||
|     for(auto it = m_systems.begin(), end = m_systems.end(); it != end;) { | ||||
|         const ParticleSystemPtr& system = *it; | ||||
| 
 | ||||
|         if(system->hasFinished()) { | ||||
|             it = m_systems.erase(it); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         system->update(); | ||||
|         ++it; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,68 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef PARTICLEEFFECT_H | ||||
| #define PARTICLEEFFECT_H | ||||
| 
 | ||||
| #include "declarations.h" | ||||
| #include "particlesystem.h" | ||||
| #include <framework/luascript/luaobject.h> | ||||
| #include <framework/otml/otml.h> | ||||
| 
 | ||||
| class ParticleEffectType : public LuaObject | ||||
| { | ||||
| public: | ||||
|     ParticleEffectType(); | ||||
| 
 | ||||
|     bool load(const OTMLNodePtr& node); | ||||
| 
 | ||||
|     void setName(const std::string& name) { m_name = name; } | ||||
|     void setFile(const std::string& file) { m_file = file; } | ||||
|     void setDescription(const std::string& description) { m_description = description; } | ||||
| 
 | ||||
|     std::string getName() { return m_name; } | ||||
|     std::string getFile() { return m_file; } | ||||
|     std::string getDescription() { return m_description; } | ||||
|     OTMLNodePtr getNode() { return m_node; } | ||||
| 
 | ||||
| private: | ||||
|     std::string m_name; | ||||
|     std::string m_file; | ||||
|     std::string m_description; | ||||
|     OTMLNodePtr m_node; | ||||
| }; | ||||
| 
 | ||||
| class ParticleEffect : public LuaObject | ||||
| { | ||||
| public: | ||||
|     ParticleEffect() {} | ||||
| 
 | ||||
|     bool load(const ParticleEffectTypePtr& effectType); | ||||
|     bool hasFinished() { return m_systems.size() == 0; } | ||||
|     void render(); | ||||
|     void update(); | ||||
| 
 | ||||
| private: | ||||
|     std::vector<ParticleSystemPtr> m_systems; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  | @ -24,43 +24,56 @@ | |||
| #include <framework/core/resourcemanager.h> | ||||
| #include <framework/otml/otml.h> | ||||
| 
 | ||||
| ParticleManager g_particleManager; | ||||
| ParticleManager g_particles; | ||||
| 
 | ||||
| bool ParticleManager::load(const std::string& filename) | ||||
| bool ParticleManager::importParticle(const std::string& file) | ||||
| { | ||||
|     try { | ||||
|         OTMLDocumentPtr doc = OTMLDocument::parse(filename); | ||||
|         OTMLDocumentPtr doc = OTMLDocument::parse(file); | ||||
|         for(const OTMLNodePtr& node : doc->children()) { | ||||
|             if(node->tag() == "ParticleSystem") { | ||||
|                 ParticleSystemPtr particleSystem = ParticleSystemPtr(new ParticleSystem); | ||||
|                 particleSystem->load(node); | ||||
|                 m_systems.push_back(particleSystem); | ||||
|             if(node->tag() == "Effect") { | ||||
|                 ParticleEffectTypePtr particleEffectType = ParticleEffectTypePtr(new ParticleEffectType); | ||||
|                 if(particleEffectType->load(node)) { | ||||
|                     particleEffectType->setFile(g_resources.resolvePath(file)); | ||||
|                     m_effectsTypes[particleEffectType->getName()] = particleEffectType; | ||||
|                 } | ||||
|             } | ||||
|             else if(node->tag() == "Particle") { | ||||
|                 // nothing yet
 | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } catch(stdext::exception& e) { | ||||
|         g_logger.error(stdext::format("could not load particles: %s", e.what())); | ||||
|         g_logger.error(stdext::format("could not load particles file %s: %s", file, e.what())); | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ParticleManager::render() | ||||
| ParticleEffectPtr ParticleManager::createEffect(const std::string& name) | ||||
| { | ||||
|     for(auto it = m_systems.begin(), end = m_systems.end(); it != end; ++it) | ||||
|         (*it)->render(); | ||||
|     ParticleEffectPtr particleEffect = ParticleEffectPtr(new ParticleEffect); | ||||
|     if(particleEffect->load(m_effectsTypes[name])) | ||||
|         return particleEffect; | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| void ParticleManager::terminate() | ||||
| { | ||||
|     m_effects.clear(); | ||||
|     m_effectsTypes.clear(); | ||||
| } | ||||
| 
 | ||||
| void ParticleManager::update() | ||||
| { | ||||
|     for(auto it = m_systems.begin(), end = m_systems.end(); it != end;) { | ||||
|         const ParticleSystemPtr& particleSystem = *it; | ||||
|     for(auto it = m_effects.begin(), end = m_effects.end(); it != end;) { | ||||
|         const ParticleEffectPtr& particleEffect = *it; | ||||
| 
 | ||||
|         if(particleSystem->hasFinished()) { | ||||
|             it = m_systems.erase(it); | ||||
|         if(particleEffect->hasFinished()) { | ||||
|             it = m_effects.erase(it); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         particleSystem->update(); | ||||
|         particleEffect->update(); | ||||
|         ++it; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -24,20 +24,24 @@ | |||
| #define PARTICLEMANAGER_H | ||||
| 
 | ||||
| #include "declarations.h" | ||||
| #include "particlesystem.h" | ||||
| #include "particleaffector.h" | ||||
| #include "particleeffect.h" | ||||
| 
 | ||||
| class ParticleManager { | ||||
| class ParticleManager | ||||
| { | ||||
| public: | ||||
|     bool load(const std::string& filename); | ||||
|     bool importParticle(const std::string& file); | ||||
|     ParticleEffectPtr createEffect(const std::string& name); | ||||
|     void terminate(); | ||||
| 
 | ||||
|     void render(); | ||||
|     void update(); | ||||
| 
 | ||||
|     std::map<std::string, ParticleEffectTypePtr> getEffectsTypes() { return m_effectsTypes; } | ||||
| 
 | ||||
| private: | ||||
|     std::list<ParticleSystemPtr> m_systems; | ||||
|     std::list<ParticleEffectPtr> m_effects; | ||||
|     std::map<std::string, ParticleEffectTypePtr> m_effectsTypes; | ||||
| }; | ||||
| 
 | ||||
| extern ParticleManager g_particleManager; | ||||
| extern ParticleManager g_particles; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
| #include <framework/sound/soundmanager.h> | ||||
| #include <framework/util/crypt.h> | ||||
| #include <framework/core/resourcemanager.h> | ||||
| #include <framework/graphics/particlemanager.h> | ||||
| 
 | ||||
| void Application::registerLuaFunctions() | ||||
| { | ||||
|  | @ -648,4 +649,21 @@ void Application::registerLuaFunctions() | |||
|     g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources); | ||||
|     g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources); | ||||
|     g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources); | ||||
| 
 | ||||
|     // ParticleManager
 | ||||
|     g_lua.registerSingletonClass("g_particles"); | ||||
|     g_lua.bindSingletonFunction("g_particles", "importParticle", &ParticleManager::importParticle, &g_particles); | ||||
|     g_lua.bindSingletonFunction("g_particles", "getEffectsTypes", &ParticleManager::getEffectsTypes, &g_particles); | ||||
| 
 | ||||
|     // ParticleEffect
 | ||||
|     g_lua.registerClass<ParticleEffectType>(); | ||||
|     g_lua.bindClassStaticFunction<ParticleEffectType>("create", []{ return ParticleEffectTypePtr(new ParticleEffectType); }); | ||||
|     g_lua.bindClassMemberFunction<ParticleEffectType>("getName", &ParticleEffectType::getName); | ||||
|     g_lua.bindClassMemberFunction<ParticleEffectType>("getFile", &ParticleEffectType::getFile); | ||||
|     g_lua.bindClassMemberFunction<ParticleEffectType>("getDescription", &ParticleEffectType::getDescription); | ||||
| 
 | ||||
|     // UIParticles
 | ||||
|     g_lua.registerClass<UIParticles, UIWidget>(); | ||||
|     g_lua.bindClassStaticFunction<UIParticles>("create", []{ return UIParticlesPtr(new UIParticles); } ); | ||||
|     g_lua.bindClassMemberFunction<UIParticles>("addEffect", &UIParticles::addEffect); | ||||
| } | ||||
|  |  | |||
|  | @ -34,10 +34,12 @@ class UIHorizontalLayout; | |||
| class UIVerticalLayout; | ||||
| class UIGridLayout; | ||||
| class UIAnchorLayout; | ||||
| class UIParticles; | ||||
| 
 | ||||
| typedef std::shared_ptr<UIWidget> UIWidgetPtr; | ||||
| typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr; | ||||
| 
 | ||||
| typedef std::shared_ptr<UIParticles> UIParticlesPtr; | ||||
| typedef std::shared_ptr<UITextEdit> UITextEditPtr; | ||||
| typedef std::shared_ptr<UILayout> UILayoutPtr; | ||||
| typedef std::shared_ptr<UIBoxLayout> UIBoxLayoutPtr; | ||||
|  |  | |||
|  | @ -31,5 +31,6 @@ | |||
| #include "uiverticallayout.h" | ||||
| #include "uigridlayout.h" | ||||
| #include "uianchorlayout.h" | ||||
| #include "uiparticles.h" | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -0,0 +1,54 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include "uiparticles.h" | ||||
| #include <framework/graphics/particlemanager.h> | ||||
| 
 | ||||
| void UIParticles::drawSelf(Fw::DrawPane drawPane) | ||||
| { | ||||
|     if((drawPane & Fw::ForegroundPane) == 0) | ||||
|         return; | ||||
| 
 | ||||
|     for(auto it = m_effects.begin(), end = m_effects.end(); it != end; ++it) | ||||
|         (*it)->render(); | ||||
| } | ||||
| 
 | ||||
| void UIParticles::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) | ||||
| { | ||||
|     UIWidget::onStyleApply(styleName, styleNode); | ||||
| 
 | ||||
|     /*for(const OTMLNodePtr& node : styleNode->children()) {
 | ||||
|         if(node->tag() == "reference") | ||||
|             setItemId(node->value<int>()); | ||||
|         else if(node->tag() == "item-count") | ||||
|             setItemCount(node->value<int>()); | ||||
|         else if(node->tag() == "virtual") | ||||
|             setVirtual(node->value<bool>()); | ||||
|     }*/ | ||||
| } | ||||
| 
 | ||||
| void UIParticles::addEffect(const std::string& name) | ||||
| { | ||||
|     ParticleEffectPtr effect = g_particles.createEffect(name); | ||||
|     if(effect) | ||||
|         m_effects.push_back(effect); | ||||
| } | ||||
|  | @ -0,0 +1,42 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
 | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef UIPARTICLES_H | ||||
| #define UIPARTICLES_H | ||||
| 
 | ||||
| #include <framework/graphics/particleeffect.h> | ||||
| #include <framework/ui/uiwidget.h> | ||||
| 
 | ||||
| class UIParticles : public UIWidget | ||||
| { | ||||
| public: | ||||
|     void drawSelf(Fw::DrawPane drawPane); | ||||
| 
 | ||||
|     void addEffect(const std::string& name); | ||||
| 
 | ||||
|     void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); | ||||
| 
 | ||||
| private: | ||||
|     std::vector<ParticleEffectPtr> m_effects; | ||||
| }; | ||||
| 
 | ||||
| #endif // UIPARTICLES_H
 | ||||
|  | @ -68,7 +68,7 @@ bool Map::loadOtbm(const std::string& fileName) | |||
|     } | ||||
| 
 | ||||
|     if (!g_things.isOtbLoaded() || !g_things.isXmlLoaded()) { | ||||
|         g_logger.error(stdext::format("OTB and XML are not loaded yet to load a map.")); | ||||
|         g_logger.error("OTB and XML are not loaded yet to load a map."); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Henrique Santiago
						Henrique Santiago