Some particle stuff, far from done

This commit is contained in:
Henrique Santiago 2012-07-06 02:00:49 -03:00
parent 2b621cace6
commit 6a85c31a77
25 changed files with 645 additions and 39 deletions

View File

@ -8,6 +8,7 @@ Module
load-later: load-later:
- client_skins - client_skins
- client_locales - client_locales
- client_particles
- client_topmenu - client_topmenu
- client_background - client_background
//- client_about //- client_about

View File

@ -13,7 +13,7 @@ local localeComboBox
local function sendLocale(localeName) local function sendLocale(localeName)
local protocolGame = g_game.getProtocolGame() local protocolGame = g_game.getProtocolGame()
if protocolGame then if protocolGame then
protocolGame:sendExtendedOpcode(1, localeName) protocolGame:sendExtendedOpcode(ExtendedLocales, localeName)
return true return true
end end
return false return false
@ -32,7 +32,7 @@ local function onGameStart()
sendLocale(currentLocale.name) sendLocale(currentLocale.name)
end end
local function onServerSetLocale(protocol, opcode, buffer) local function onExtendedLocales(protocol, opcode, buffer)
local locale = installedLocales[buffer] local locale = installedLocales[buffer]
if locale then if locale then
localeComboBox:setCurrentOption(locale.languageName) localeComboBox:setCurrentOption(locale.languageName)
@ -63,7 +63,7 @@ function Locales.init()
localeComboBox.onOptionChange = onLocaleComboBoxOptionChange localeComboBox.onOptionChange = onLocaleComboBoxOptionChange
end, false) end, false)
Extended.register(1, onServerSetLocale) Extended.register(ExtendedLocales, onExtendedLocales)
connect(g_game, { onGameStart = onGameStart }) connect(g_game, { onGameStart = onGameStart })
end end
@ -71,7 +71,7 @@ function Locales.terminate()
installedLocales = nil installedLocales = nil
currentLocale = nil currentLocale = nil
localeComboBox = nil localeComboBox = nil
Extended.unregister(1) Extended.unregister(ExtendedLocales)
disconnect(g_game, { onGameStart = onGameStart }) disconnect(g_game, { onGameStart = onGameStart })
end end

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -110,15 +110,25 @@ end
function Skins.loadSkin(skin) function Skins.loadSkin(skin)
local lowerName = string.lower(skin.name) local lowerName = string.lower(skin.name)
for i=1,#skin.fonts do if skin.fonts then
g_fonts.importFont('skins/' .. lowerName .. '/fonts/' .. skin.fonts[i]) for i=1,#skin.fonts do
g_fonts.importFont('skins/' .. lowerName .. '/fonts/' .. skin.fonts[i])
if i == 1 then if i == 1 then
g_fonts.setDefaultFont(skin.fonts[i]) g_fonts.setDefaultFont(skin.fonts[i])
end
end end
end end
for i=1,#skin.styles do if skin.styles then
g_ui.importStyle('skins/' .. lowerName .. '/styles/' .. skin.styles[i]) 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
end end

View File

@ -29,6 +29,10 @@ local skin = {
'miniwindow.otui', 'miniwindow.otui',
'items.otui', 'items.otui',
'creatures.otui' 'creatures.otui'
},
particles = {
'shiny.otps'
} }
} }

View File

@ -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

View File

@ -11,3 +11,7 @@ FlatPanel < Panel
ScrollableFlatPanel < ScrollablePanel ScrollableFlatPanel < ScrollablePanel
image-source: /images/panel_flat.png image-source: /images/panel_flat.png
image-border: 1 image-border: 1
ParticlesFlatPanel < Panel
image-source: /images/panel_flat.png
image-border: 1

View File

@ -1,8 +1,6 @@
local skin = { local skin = {
name = 'Example', name = 'Example',
fonts = {},
styles = { styles = {
'topmenu.otui' 'topmenu.otui'
} }

View File

@ -186,7 +186,6 @@ SpeakChannelOrange = 12
SpeakMonsterSay = 13 SpeakMonsterSay = 13
SpeakMonsterYell = 14 SpeakMonsterYell = 14
FightOffensive = 1 FightOffensive = 1
FightBalanced = 2 FightBalanced = 2
FightDefensive = 3 FightDefensive = 3
@ -194,6 +193,10 @@ FightDefensive = 3
DontChase = 0 DontChase = 0
ChaseOpponent = 1 ChaseOpponent = 1
ExtendedActivate = 0
ExtendedLocales = 1
ExtendedParticles = 2
-- @} -- @}
KeyCodeDescs = { KeyCodeDescs = {

View File

@ -229,6 +229,8 @@ SET(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/particle.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particle.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/particleemitter.h ${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/particle.h
${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/particlemanager.h ${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/uilayout.h
${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.h ${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.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uirichtext.h ${CMAKE_CURRENT_LIST_DIR}/ui/uirichtext.h
${CMAKE_CURRENT_LIST_DIR}/ui/uitextedit.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uitextedit.cpp

View File

@ -136,6 +136,9 @@ void Application::terminate()
{ {
assert(m_initialized); assert(m_initialized);
// destroy particles
g_particles.terminate();
// destroy any remaining widget // destroy any remaining widget
g_ui.terminate(); g_ui.terminate();
@ -278,7 +281,7 @@ void Application::poll()
// poll input events // poll input events
g_window.poll(); g_window.poll();
//g_particleManager.update(); //g_particles.update();
Connection::poll(); Connection::poll();
g_dispatcher.poll(); g_dispatcher.poll();

View File

@ -41,6 +41,8 @@ class Particle;
class ParticleEmitter; class ParticleEmitter;
class ParticleAffector; class ParticleAffector;
class ParticleSystem; class ParticleSystem;
class ParticleEffect;
class ParticleEffectType;
typedef std::weak_ptr<Texture> TextureWeakPtr; typedef std::weak_ptr<Texture> TextureWeakPtr;
typedef std::weak_ptr<ParticleSystem> ParticleSystemWeakPtr; 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<ParticleEmitter> ParticleEmitterPtr;
typedef std::shared_ptr<ParticleAffector> ParticleAffectorPtr; typedef std::shared_ptr<ParticleAffector> ParticleAffectorPtr;
typedef std::shared_ptr<ParticleSystem> ParticleSystemPtr; typedef std::shared_ptr<ParticleSystem> ParticleSystemPtr;
typedef std::shared_ptr<ParticleEffect> ParticleEffectPtr;
typedef std::shared_ptr<ParticleEffectType> ParticleEffectTypePtr;
typedef std::vector<ShaderPtr> ShaderList; typedef std::vector<ShaderPtr> ShaderList;
#endif #endif

View File

@ -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;
}
}

View File

@ -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

View File

@ -24,43 +24,56 @@
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/otml/otml.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 { try {
OTMLDocumentPtr doc = OTMLDocument::parse(filename); OTMLDocumentPtr doc = OTMLDocument::parse(file);
for(const OTMLNodePtr& node : doc->children()) { for(const OTMLNodePtr& node : doc->children()) {
if(node->tag() == "ParticleSystem") { if(node->tag() == "Effect") {
ParticleSystemPtr particleSystem = ParticleSystemPtr(new ParticleSystem); ParticleEffectTypePtr particleEffectType = ParticleEffectTypePtr(new ParticleEffectType);
particleSystem->load(node); if(particleEffectType->load(node)) {
m_systems.push_back(particleSystem); particleEffectType->setFile(g_resources.resolvePath(file));
m_effectsTypes[particleEffectType->getName()] = particleEffectType;
}
}
else if(node->tag() == "Particle") {
// nothing yet
} }
} }
return true; return true;
} catch(stdext::exception& e) { } 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; 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) ParticleEffectPtr particleEffect = ParticleEffectPtr(new ParticleEffect);
(*it)->render(); if(particleEffect->load(m_effectsTypes[name]))
return particleEffect;
return nullptr;
}
void ParticleManager::terminate()
{
m_effects.clear();
m_effectsTypes.clear();
} }
void ParticleManager::update() void ParticleManager::update()
{ {
for(auto it = m_systems.begin(), end = m_systems.end(); it != end;) { for(auto it = m_effects.begin(), end = m_effects.end(); it != end;) {
const ParticleSystemPtr& particleSystem = *it; const ParticleEffectPtr& particleEffect = *it;
if(particleSystem->hasFinished()) { if(particleEffect->hasFinished()) {
it = m_systems.erase(it); it = m_effects.erase(it);
continue; continue;
} }
particleSystem->update(); particleEffect->update();
++it; ++it;
} }
} }

View File

@ -24,20 +24,24 @@
#define PARTICLEMANAGER_H #define PARTICLEMANAGER_H
#include "declarations.h" #include "declarations.h"
#include "particlesystem.h" #include "particleeffect.h"
#include "particleaffector.h"
class ParticleManager { class ParticleManager
{
public: 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(); void update();
std::map<std::string, ParticleEffectTypePtr> getEffectsTypes() { return m_effectsTypes; }
private: 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 #endif

View File

@ -35,6 +35,7 @@
#include <framework/sound/soundmanager.h> #include <framework/sound/soundmanager.h>
#include <framework/util/crypt.h> #include <framework/util/crypt.h>
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/graphics/particlemanager.h>
void Application::registerLuaFunctions() 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", "fileExists", &ResourceManager::fileExists, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources); g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &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);
} }

View File

@ -34,10 +34,12 @@ class UIHorizontalLayout;
class UIVerticalLayout; class UIVerticalLayout;
class UIGridLayout; class UIGridLayout;
class UIAnchorLayout; class UIAnchorLayout;
class UIParticles;
typedef std::shared_ptr<UIWidget> UIWidgetPtr; typedef std::shared_ptr<UIWidget> UIWidgetPtr;
typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr; typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
typedef std::shared_ptr<UIParticles> UIParticlesPtr;
typedef std::shared_ptr<UITextEdit> UITextEditPtr; typedef std::shared_ptr<UITextEdit> UITextEditPtr;
typedef std::shared_ptr<UILayout> UILayoutPtr; typedef std::shared_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UIBoxLayout> UIBoxLayoutPtr; typedef std::shared_ptr<UIBoxLayout> UIBoxLayoutPtr;

View File

@ -31,5 +31,6 @@
#include "uiverticallayout.h" #include "uiverticallayout.h"
#include "uigridlayout.h" #include "uigridlayout.h"
#include "uianchorlayout.h" #include "uianchorlayout.h"
#include "uiparticles.h"
#endif #endif

View File

@ -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);
}

View File

@ -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

View File

@ -68,7 +68,7 @@ bool Map::loadOtbm(const std::string& fileName)
} }
if (!g_things.isOtbLoaded() || !g_things.isXmlLoaded()) { 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; return false;
} }