Some particle stuff, far from done
This commit is contained in:
parent
2b621cace6
commit
6a85c31a77
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,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
|
||||||
|
|
|
@ -29,6 +29,10 @@ local skin = {
|
||||||
'miniwindow.otui',
|
'miniwindow.otui',
|
||||||
'items.otui',
|
'items.otui',
|
||||||
'creatures.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
|
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
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
local skin = {
|
local skin = {
|
||||||
name = 'Example',
|
name = 'Example',
|
||||||
|
|
||||||
fonts = {},
|
|
||||||
|
|
||||||
styles = {
|
styles = {
|
||||||
'topmenu.otui'
|
'topmenu.otui'
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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/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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue