forked from Mirrorlandia_minetest/minetest
Adding particle blend, glow and animation (#4705)
This commit is contained in:
parent
649448a2a9
commit
93e3555eae
@ -237,6 +237,43 @@ function math.sign(x, tolerance)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Video enums and pack function
|
||||||
|
|
||||||
|
-- E_BLEND_FACTOR
|
||||||
|
minetest.ebf = {
|
||||||
|
zero = 0, -- src & dest (0, 0, 0, 0)
|
||||||
|
one = 1, -- src & dest (1, 1, 1, 1)
|
||||||
|
dst_color = 2, -- src (destR, destG, destB, destA)
|
||||||
|
one_minus_dst_color = 3, -- src (1-destR, 1-destG, 1-destB, 1-destA)
|
||||||
|
src_color = 4, -- dest (srcR, srcG, srcB, srcA)
|
||||||
|
one_minus_src_color = 5, -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA)
|
||||||
|
src_alpha = 6, -- src & dest (srcA, srcA, srcA, srcA)
|
||||||
|
one_minus_src_alpha = 7, -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA)
|
||||||
|
dst_alpha = 8, -- src & dest (destA, destA, destA, destA)
|
||||||
|
one_minus_dst_alpha = 9, -- src & dest (1-destA, 1-destA, 1-destA, 1-destA)
|
||||||
|
src_alpha_saturate = 10,-- src (min(srcA, 1-destA), idem, ...)
|
||||||
|
}
|
||||||
|
|
||||||
|
-- E_MODULATE_FUNC
|
||||||
|
minetest.emfn = {
|
||||||
|
modulate_1x = 1,
|
||||||
|
modulate_2x = 2,
|
||||||
|
modulate_4x = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- E_ALPHA_SOURCE
|
||||||
|
minetest.eas = {
|
||||||
|
none = 0,
|
||||||
|
vertex_color = 1,
|
||||||
|
texture = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- BlendFunc = source * sourceFactor + dest * destFactor
|
||||||
|
function minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)
|
||||||
|
return alphaSource * 4096 + modulate * 256 + srcFact * 16 + dstFact
|
||||||
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function get_last_folder(text,count)
|
function get_last_folder(text,count)
|
||||||
local parts = text:split(DIR_DELIM)
|
local parts = text:split(DIR_DELIM)
|
||||||
|
189
doc/lua_api.txt
189
doc/lua_api.txt
@ -414,6 +414,119 @@ the word "`alpha`", then each texture pixel will contain the RGB of
|
|||||||
`<color>` and the alpha of `<color>` multiplied by the alpha of the
|
`<color>` and the alpha of `<color>` multiplied by the alpha of the
|
||||||
texture pixel.
|
texture pixel.
|
||||||
|
|
||||||
|
Particle blend
|
||||||
|
--------------
|
||||||
|
Blend function is defined by integer number.
|
||||||
|
There is a huge number of acceptable blend modificators.
|
||||||
|
Colour of a resulting pixel calculated using formulae:
|
||||||
|
|
||||||
|
red = source_red * source_factor + destination_red * destination_factor
|
||||||
|
|
||||||
|
and so on for every channel.
|
||||||
|
|
||||||
|
Here is a some examples:
|
||||||
|
|
||||||
|
Default value:
|
||||||
|
|
||||||
|
material_type_param = 0,
|
||||||
|
|
||||||
|
Use this value to disable blending. Texture will be applied to existing pixels
|
||||||
|
using alpha channel of it. Its recomended to use 1-bit alpha
|
||||||
|
in that case. This value will leave z-buffer writeable.
|
||||||
|
|
||||||
|
Additive blend:
|
||||||
|
|
||||||
|
material_type_param = 12641,
|
||||||
|
|
||||||
|
Source = src_alpha, destination = one, alpha source is a texture and
|
||||||
|
vertex_color, modulate_1x.
|
||||||
|
Black color is completely transparent, white color is completely opaque.
|
||||||
|
Alpha channel still used to calculate result color, but not nessesary.
|
||||||
|
'destination = one' means that resulting color will be calculated using
|
||||||
|
overwritten pixels values.
|
||||||
|
For example with color of source (our texture) RGBA = (0,192,255,63)
|
||||||
|
"blue-cyan", 1/4 opaque.
|
||||||
|
and already rendered pixel color (40,192,0) "dark lime green" we will get color:
|
||||||
|
|
||||||
|
R = source_red(0) * source_factor(src_alpha=63/255) +
|
||||||
|
destination_red(40) * destination_factor(one) =
|
||||||
|
0 * 63/255 + 40 * 1 = 40
|
||||||
|
|
||||||
|
G = 192 * 63/255 + 192 * 1 = 239
|
||||||
|
B = 255 * 63/255 + 0 * 1 = 63
|
||||||
|
|
||||||
|
Result: (40,239,63), "green" (a kind of).
|
||||||
|
Note, if you made a texture with some kind of shape with colour 662211h
|
||||||
|
it will appear dark red with a single particle, then yellow with a
|
||||||
|
several of them and white if player looking thru a lot of them. With
|
||||||
|
this you could made a nice-looking fire.
|
||||||
|
|
||||||
|
Substractive blend:
|
||||||
|
|
||||||
|
material_type_param = 12548,
|
||||||
|
|
||||||
|
Source = zero, destination = src_color, alpha source is a texture and
|
||||||
|
vertex_color, modulate_1x.
|
||||||
|
Texture darkness act like an alpha channel.
|
||||||
|
Black color is completely opaque, white color is completely transparent.
|
||||||
|
'destination = src_color' means that destination in multiplied by
|
||||||
|
a source values. 'source = zero' means that source values ignored
|
||||||
|
(multiplied by 0).
|
||||||
|
|
||||||
|
Invert blend:
|
||||||
|
|
||||||
|
material_type_param = 12597,
|
||||||
|
|
||||||
|
Source = one_minus_dst_color, destination = one_minus_src_alpha, alpha source
|
||||||
|
is a texture and vertex_color, modulate_1x.
|
||||||
|
Pixels invert color if source color value is big enough. If not, they just
|
||||||
|
black.
|
||||||
|
'destination = one_minus_src_alpha' means, that effect is masked by a
|
||||||
|
source alpha channel.
|
||||||
|
|
||||||
|
You can design and use your own blend using those enum values and function
|
||||||
|
'minetest.pack_texture_blend_func'. Returned value of a function is
|
||||||
|
your 'material_type_param'.
|
||||||
|
|
||||||
|
A values in a brackets is a multiplicators of a red, green, blue
|
||||||
|
and alpha channels respectively.
|
||||||
|
|
||||||
|
* 'minetest.ebf': global table, containing blend factor enum values. Such as:
|
||||||
|
* zero = 0 -- src & dest (0, 0, 0, 0)
|
||||||
|
* one = 1 -- src & dest (1, 1, 1, 1)
|
||||||
|
* dst_color = 2 -- src (destR, destG, destB, destA)
|
||||||
|
* one_minus_dst_color = 3 -- src (1-destR, 1-destG, 1-destB, 1-destA)
|
||||||
|
* src_color = 4 -- dest (srcR, srcG, srcB, srcA)
|
||||||
|
* one_minus_src_color = 5 -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA)
|
||||||
|
* src_alpha = 6 -- src & dest (srcA, srcA, srcA, srcA)
|
||||||
|
* one_minus_src_alpha = 7 -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA)
|
||||||
|
* dst_alpha = 8 -- src & dest (destA, destA, destA, destA)
|
||||||
|
* one_minus_dst_alpha = 9 -- src & dest (1-destA, 1-destA, 1-destA, 1-destA)
|
||||||
|
* src_alpha_saturate = 10 -- src (min(srcA, 1-destA), idem, ...)
|
||||||
|
|
||||||
|
* 'minetest.emfn': global table, containing modulate enum values.
|
||||||
|
* Multiply the components of the arguments, and shift the products to the
|
||||||
|
* left by x bits for brightening. Contain:
|
||||||
|
* modulate_1x = 1 -- no bit shift
|
||||||
|
* modulate_2x = 2 -- 1 bits shift
|
||||||
|
* modulate_4x = 4 -- 2 bits shift
|
||||||
|
|
||||||
|
'modulate_4x' is quite useful when you want to make additive blend stronger
|
||||||
|
with a lower amount of particles.
|
||||||
|
|
||||||
|
* 'minetest.eas': global table, containing alpha source enum values. Such as:
|
||||||
|
* none = 0 -- do not use alpha.
|
||||||
|
* vertex_color = 1 -- use vertex color alpha.
|
||||||
|
* texture = 2 -- use texture alpha.
|
||||||
|
|
||||||
|
You can use both 'vertex_color' and 'texture' source by using value 3.
|
||||||
|
|
||||||
|
* 'minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)': return integer
|
||||||
|
* Pack texture blend funcion variable. Depending from that variable blend
|
||||||
|
* function will be applied in time of a render poligons with selected material.
|
||||||
|
* Therefore resulting pixel will be 'source * srcFact + destination * dstFact'
|
||||||
|
* Use result of this function as 'material_type_param'.
|
||||||
|
|
||||||
Sounds
|
Sounds
|
||||||
------
|
------
|
||||||
Only Ogg Vorbis files are supported.
|
Only Ogg Vorbis files are supported.
|
||||||
@ -3650,7 +3763,7 @@ Definition tables
|
|||||||
|
|
||||||
### Tile definition
|
### Tile definition
|
||||||
* `"image.png"`
|
* `"image.png"`
|
||||||
* `{name="image.png", animation={Tile Animation definition}}`
|
* `{name="image.png", animation={Animation definition}}`
|
||||||
* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
|
* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
|
||||||
tileable_horizontal=bool}`
|
tileable_horizontal=bool}`
|
||||||
* backface culling enabled by default for most nodes
|
* backface culling enabled by default for most nodes
|
||||||
@ -3661,8 +3774,50 @@ Definition tables
|
|||||||
* deprecated, yet still supported field names:
|
* deprecated, yet still supported field names:
|
||||||
* `image` (name)
|
* `image` (name)
|
||||||
|
|
||||||
### Tile animation definition
|
### Animation definition
|
||||||
* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}`
|
|
||||||
|
#### Node animation, particle and particle spawners
|
||||||
|
* `{ type="vertical_frames",
|
||||||
|
aspect_w=16,
|
||||||
|
-- ^ specify width of a picture in pixels.
|
||||||
|
aspect_h=16,
|
||||||
|
-- ^ specify height of a frame in pixels.
|
||||||
|
length=3.0
|
||||||
|
-- ^ specify full loop length.
|
||||||
|
first_frame = 0, -- <- only for particles, use
|
||||||
|
min_first_frame = 0, -- <- for particle spawners
|
||||||
|
max_first_frame = 0,
|
||||||
|
loop_animation = true, -- <- only for particles and particle spawners
|
||||||
|
-- specify if animation should start from beginning after last frame.
|
||||||
|
}`
|
||||||
|
|
||||||
|
#### Particle and particle spawners only
|
||||||
|
* `{
|
||||||
|
type="2d_animation_sheet", -- <- only for particles and particle spawners
|
||||||
|
vertical_frame_num = 1,
|
||||||
|
horizontal_frame_num = 1,
|
||||||
|
-- ^ specify amount of frames in texture.
|
||||||
|
-- Can be used both for animation or for texture transform
|
||||||
|
-- together with first_frame variable.
|
||||||
|
-- A animation texture separated on equal parts of frames,
|
||||||
|
-- by horizontal and vertical numbers. For example with
|
||||||
|
-- vertical_frame_num = 4 and horizontal_frame_num = 3 we got
|
||||||
|
-- 4*3 = 12 frames in total. Animation sequence start from
|
||||||
|
-- left top frame and go on to the right until reach end of
|
||||||
|
-- row. Next row also start from left frame.
|
||||||
|
first_frame = 0, -- <- only for particles, use
|
||||||
|
min_first_frame = 0, -- <- for particle spawners
|
||||||
|
max_first_frame = 0,
|
||||||
|
-- ^ specify first frame to start animation.
|
||||||
|
frame_length = -1,
|
||||||
|
-- ^ specify length of a frame in seconds. Negative and zero values
|
||||||
|
-- disable animation. A sequence with vertical_frame_num = 4 and
|
||||||
|
-- horizontal_frame_num = 3, first_frame = 4 and frame_length = 0.1
|
||||||
|
-- will end in (4*3-4)*0.1 = 0.8 seconds.
|
||||||
|
loop_animation = true,
|
||||||
|
-- specify if animation should start from beginning after last frame.
|
||||||
|
}`
|
||||||
|
* All settings are optional. Default values is located in this example.
|
||||||
|
|
||||||
### Node definition (`register_node`)
|
### Node definition (`register_node`)
|
||||||
|
|
||||||
@ -4117,6 +4272,20 @@ The Biome API is still in an experimental phase and subject to change.
|
|||||||
-- ^ Uses texture (string)
|
-- ^ Uses texture (string)
|
||||||
playername = "singleplayer"
|
playername = "singleplayer"
|
||||||
-- ^ optional, if specified spawns particle only on the player's client
|
-- ^ optional, if specified spawns particle only on the player's client
|
||||||
|
material_type_param = 12641,
|
||||||
|
-- ^ optional, if specified spawns particle with
|
||||||
|
-- specified material type param and disable z-buffer.
|
||||||
|
-- Some examples:
|
||||||
|
-- Default value: 0,
|
||||||
|
-- Additive blend: 12641,
|
||||||
|
-- Substractive blend: 12548,
|
||||||
|
-- Invert blend: 12597,
|
||||||
|
-- See also "Particle blend".
|
||||||
|
animation = {Animation definition},
|
||||||
|
-- ^ see above. Note, that particle and particle spawners have differences.
|
||||||
|
glow = 15,
|
||||||
|
-- ^ optional, specify particle self-luminescence in darkness.
|
||||||
|
values may vary from 0 (no glow) to 15 (bright glow).
|
||||||
}
|
}
|
||||||
|
|
||||||
### `ParticleSpawner` definition (`add_particlespawner`)
|
### `ParticleSpawner` definition (`add_particlespawner`)
|
||||||
@ -4151,6 +4320,20 @@ The Biome API is still in an experimental phase and subject to change.
|
|||||||
-- ^ Uses texture (string)
|
-- ^ Uses texture (string)
|
||||||
playername = "singleplayer"
|
playername = "singleplayer"
|
||||||
-- ^ Playername is optional, if specified spawns particle only on the player's client
|
-- ^ Playername is optional, if specified spawns particle only on the player's client
|
||||||
|
material_type_param = 12641,
|
||||||
|
-- ^ optional, if specified spawns particle with specified material type
|
||||||
|
-- param and disable z-buffer.
|
||||||
|
-- Some examples:
|
||||||
|
-- Default value: 0,
|
||||||
|
-- Additive blend: 12641,
|
||||||
|
-- Substractive blend: 12548,
|
||||||
|
-- Invert blend: 12597,
|
||||||
|
-- See also "Particle blend".
|
||||||
|
animation = {Animation definition},
|
||||||
|
-- ^ see above. Note, that particle and particle spawners have differences.
|
||||||
|
glow = 15,
|
||||||
|
-- ^ optional, specify particle self-luminescence in darkness.
|
||||||
|
values may vary from 0 (no glow) to 15 (bright glow).
|
||||||
}
|
}
|
||||||
|
|
||||||
### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`)
|
### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`)
|
||||||
|
18
src/client.h
18
src/client.h
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "particles.h"
|
#include "particles.h"
|
||||||
#include "network/networkpacket.h"
|
#include "network/networkpacket.h"
|
||||||
|
#include "nodedef.h" // AnimationType
|
||||||
|
|
||||||
struct MeshMakeData;
|
struct MeshMakeData;
|
||||||
class MapBlockMesh;
|
class MapBlockMesh;
|
||||||
@ -185,6 +186,14 @@ struct ClientEvent
|
|||||||
bool collision_removal;
|
bool collision_removal;
|
||||||
bool vertical;
|
bool vertical;
|
||||||
std::string *texture;
|
std::string *texture;
|
||||||
|
u32 material_type_param;
|
||||||
|
AnimationType animation_type;
|
||||||
|
u16 vertical_frame_num;
|
||||||
|
u16 horizontal_frame_num;
|
||||||
|
u16 first_frame;
|
||||||
|
float frame_length;
|
||||||
|
bool loop_animation;
|
||||||
|
u8 glow;
|
||||||
} spawn_particle;
|
} spawn_particle;
|
||||||
struct{
|
struct{
|
||||||
u16 amount;
|
u16 amount;
|
||||||
@ -205,6 +214,15 @@ struct ClientEvent
|
|||||||
bool vertical;
|
bool vertical;
|
||||||
std::string *texture;
|
std::string *texture;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
u32 material_type_param;
|
||||||
|
AnimationType animation_type;
|
||||||
|
u16 vertical_frame_num;
|
||||||
|
u16 horizontal_frame_num;
|
||||||
|
u16 min_first_frame;
|
||||||
|
u16 max_first_frame;
|
||||||
|
float frame_length;
|
||||||
|
bool loop_animation;
|
||||||
|
u8 glow;
|
||||||
} add_particlespawner;
|
} add_particlespawner;
|
||||||
struct{
|
struct{
|
||||||
u32 id;
|
u32 id;
|
||||||
|
@ -896,23 +896,46 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
|
|||||||
std::string texture = deSerializeLongString(is);
|
std::string texture = deSerializeLongString(is);
|
||||||
bool vertical = false;
|
bool vertical = false;
|
||||||
bool collision_removal = false;
|
bool collision_removal = false;
|
||||||
|
u32 material_type_param = 0;
|
||||||
|
AnimationType animation_type = AT_NONE;
|
||||||
|
u16 vertical_frame_num = 1;
|
||||||
|
u16 horizontal_frame_num = 1;
|
||||||
|
u16 first_frame = 0;
|
||||||
|
float frame_length = -1;
|
||||||
|
bool loop_animation = true;
|
||||||
|
u8 glow = 0;
|
||||||
try {
|
try {
|
||||||
vertical = readU8(is);
|
vertical = readU8(is);
|
||||||
collision_removal = readU8(is);
|
collision_removal = readU8(is);
|
||||||
|
material_type_param = readU32(is);
|
||||||
|
animation_type = (AnimationType)readU8(is);
|
||||||
|
vertical_frame_num = readU16(is);
|
||||||
|
horizontal_frame_num = readU16(is);
|
||||||
|
first_frame = readU16(is);
|
||||||
|
frame_length = readF1000(is);
|
||||||
|
loop_animation = readU8(is);
|
||||||
|
glow = readU8(is);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
ClientEvent event;
|
ClientEvent event;
|
||||||
event.type = CE_SPAWN_PARTICLE;
|
event.type = CE_SPAWN_PARTICLE;
|
||||||
event.spawn_particle.pos = new v3f (pos);
|
event.spawn_particle.pos = new v3f (pos);
|
||||||
event.spawn_particle.vel = new v3f (vel);
|
event.spawn_particle.vel = new v3f (vel);
|
||||||
event.spawn_particle.acc = new v3f (acc);
|
event.spawn_particle.acc = new v3f (acc);
|
||||||
event.spawn_particle.expirationtime = expirationtime;
|
event.spawn_particle.expirationtime = expirationtime;
|
||||||
event.spawn_particle.size = size;
|
event.spawn_particle.size = size;
|
||||||
event.spawn_particle.collisiondetection = collisiondetection;
|
event.spawn_particle.collisiondetection = collisiondetection;
|
||||||
event.spawn_particle.collision_removal = collision_removal;
|
event.spawn_particle.collision_removal = collision_removal;
|
||||||
event.spawn_particle.vertical = vertical;
|
event.spawn_particle.vertical = vertical;
|
||||||
event.spawn_particle.texture = new std::string(texture);
|
event.spawn_particle.texture = new std::string(texture);
|
||||||
|
event.spawn_particle.material_type_param = material_type_param;
|
||||||
|
event.spawn_particle.animation_type = animation_type;
|
||||||
|
event.spawn_particle.vertical_frame_num = vertical_frame_num;
|
||||||
|
event.spawn_particle.horizontal_frame_num = horizontal_frame_num;
|
||||||
|
event.spawn_particle.first_frame = first_frame;
|
||||||
|
event.spawn_particle.frame_length = frame_length;
|
||||||
|
event.spawn_particle.loop_animation = loop_animation;
|
||||||
|
event.spawn_particle.glow = glow;
|
||||||
m_client_event_queue.push(event);
|
m_client_event_queue.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,6 +955,15 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
|
|||||||
float maxsize;
|
float maxsize;
|
||||||
bool collisiondetection;
|
bool collisiondetection;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
u32 material_type_param = 0;
|
||||||
|
u8 animation_type = (u8)AT_NONE;
|
||||||
|
u16 vertical_frame_num = 1;
|
||||||
|
u16 horizontal_frame_num = 1;
|
||||||
|
u16 min_first_frame = 0;
|
||||||
|
u16 max_first_frame = 0;
|
||||||
|
float frame_length = -1;
|
||||||
|
bool loop_animation = true;
|
||||||
|
u8 glow = 0;
|
||||||
|
|
||||||
*pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel
|
*pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel
|
||||||
>> minacc >> maxacc >> minexptime >> maxexptime >> minsize
|
>> minacc >> maxacc >> minexptime >> maxexptime >> minsize
|
||||||
@ -948,29 +980,46 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
|
|||||||
*pkt >> vertical;
|
*pkt >> vertical;
|
||||||
*pkt >> collision_removal;
|
*pkt >> collision_removal;
|
||||||
*pkt >> attached_id;
|
*pkt >> attached_id;
|
||||||
|
*pkt >> material_type_param;
|
||||||
|
*pkt >> animation_type;
|
||||||
|
*pkt >> vertical_frame_num;
|
||||||
|
*pkt >> horizontal_frame_num;
|
||||||
|
*pkt >> min_first_frame;
|
||||||
|
*pkt >> max_first_frame;
|
||||||
|
*pkt >> frame_length;
|
||||||
|
*pkt >> loop_animation;
|
||||||
|
*pkt >> glow;
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
ClientEvent event;
|
ClientEvent event;
|
||||||
event.type = CE_ADD_PARTICLESPAWNER;
|
event.type = CE_ADD_PARTICLESPAWNER;
|
||||||
event.add_particlespawner.amount = amount;
|
event.add_particlespawner.amount = amount;
|
||||||
event.add_particlespawner.spawntime = spawntime;
|
event.add_particlespawner.spawntime = spawntime;
|
||||||
event.add_particlespawner.minpos = new v3f (minpos);
|
event.add_particlespawner.minpos = new v3f (minpos);
|
||||||
event.add_particlespawner.maxpos = new v3f (maxpos);
|
event.add_particlespawner.maxpos = new v3f (maxpos);
|
||||||
event.add_particlespawner.minvel = new v3f (minvel);
|
event.add_particlespawner.minvel = new v3f (minvel);
|
||||||
event.add_particlespawner.maxvel = new v3f (maxvel);
|
event.add_particlespawner.maxvel = new v3f (maxvel);
|
||||||
event.add_particlespawner.minacc = new v3f (minacc);
|
event.add_particlespawner.minacc = new v3f (minacc);
|
||||||
event.add_particlespawner.maxacc = new v3f (maxacc);
|
event.add_particlespawner.maxacc = new v3f (maxacc);
|
||||||
event.add_particlespawner.minexptime = minexptime;
|
event.add_particlespawner.minexptime = minexptime;
|
||||||
event.add_particlespawner.maxexptime = maxexptime;
|
event.add_particlespawner.maxexptime = maxexptime;
|
||||||
event.add_particlespawner.minsize = minsize;
|
event.add_particlespawner.minsize = minsize;
|
||||||
event.add_particlespawner.maxsize = maxsize;
|
event.add_particlespawner.maxsize = maxsize;
|
||||||
event.add_particlespawner.collisiondetection = collisiondetection;
|
event.add_particlespawner.collisiondetection = collisiondetection;
|
||||||
event.add_particlespawner.collision_removal = collision_removal;
|
event.add_particlespawner.collision_removal = collision_removal;
|
||||||
event.add_particlespawner.attached_id = attached_id;
|
event.add_particlespawner.attached_id = attached_id;
|
||||||
event.add_particlespawner.vertical = vertical;
|
event.add_particlespawner.vertical = vertical;
|
||||||
event.add_particlespawner.texture = new std::string(texture);
|
event.add_particlespawner.texture = new std::string(texture);
|
||||||
event.add_particlespawner.id = id;
|
event.add_particlespawner.id = id;
|
||||||
|
event.add_particlespawner.material_type_param = material_type_param;
|
||||||
|
event.add_particlespawner.animation_type = (AnimationType)animation_type;
|
||||||
|
event.add_particlespawner.vertical_frame_num = vertical_frame_num;
|
||||||
|
event.add_particlespawner.horizontal_frame_num = horizontal_frame_num;
|
||||||
|
event.add_particlespawner.min_first_frame = min_first_frame;
|
||||||
|
event.add_particlespawner.max_first_frame = max_first_frame;
|
||||||
|
event.add_particlespawner.frame_length = frame_length;
|
||||||
|
event.add_particlespawner.loop_animation = loop_animation;
|
||||||
|
event.add_particlespawner.glow = glow;
|
||||||
|
|
||||||
m_client_event_queue.push(event);
|
m_client_event_queue.push(event);
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con
|
|||||||
{
|
{
|
||||||
int version = readU8(is);
|
int version = readU8(is);
|
||||||
name = deSerializeString(is);
|
name = deSerializeString(is);
|
||||||
animation.type = (TileAnimationType)readU8(is);
|
animation.type = (AnimationType)readU8(is);
|
||||||
animation.aspect_w = readU16(is);
|
animation.aspect_w = readU16(is);
|
||||||
animation.aspect_h = readU16(is);
|
animation.aspect_h = readU16(is);
|
||||||
animation.length = readF1000(is);
|
animation.length = readF1000(is);
|
||||||
@ -531,7 +531,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
|||||||
tile->material_flags = 0;
|
tile->material_flags = 0;
|
||||||
if (backface_culling)
|
if (backface_culling)
|
||||||
tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
||||||
if (tiledef->animation.type == TAT_VERTICAL_FRAMES)
|
if (tiledef->animation.type == AT_VERTICAL_FRAMES)
|
||||||
tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
||||||
if (tiledef->tileable_horizontal)
|
if (tiledef->tileable_horizontal)
|
||||||
tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
|
tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
|
||||||
|
@ -161,9 +161,10 @@ enum NodeDrawType
|
|||||||
/*
|
/*
|
||||||
Stand-alone definition of a TileSpec (basically a server-side TileSpec)
|
Stand-alone definition of a TileSpec (basically a server-side TileSpec)
|
||||||
*/
|
*/
|
||||||
enum TileAnimationType{
|
enum AnimationType{
|
||||||
TAT_NONE=0,
|
AT_NONE = 0,
|
||||||
TAT_VERTICAL_FRAMES=1,
|
AT_VERTICAL_FRAMES = 1,
|
||||||
|
AT_2D_ANIMATION_SHEET = 2,
|
||||||
};
|
};
|
||||||
struct TileDef
|
struct TileDef
|
||||||
{
|
{
|
||||||
@ -172,7 +173,7 @@ struct TileDef
|
|||||||
bool tileable_horizontal;
|
bool tileable_horizontal;
|
||||||
bool tileable_vertical;
|
bool tileable_vertical;
|
||||||
struct{
|
struct{
|
||||||
enum TileAnimationType type;
|
enum AnimationType type;
|
||||||
int aspect_w; // width for aspect ratio
|
int aspect_w; // width for aspect ratio
|
||||||
int aspect_h; // height for aspect ratio
|
int aspect_h; // height for aspect ratio
|
||||||
float length; // seconds
|
float length; // seconds
|
||||||
@ -184,7 +185,7 @@ struct TileDef
|
|||||||
backface_culling = true;
|
backface_culling = true;
|
||||||
tileable_horizontal = true;
|
tileable_horizontal = true;
|
||||||
tileable_vertical = true;
|
tileable_vertical = true;
|
||||||
animation.type = TAT_NONE;
|
animation.type = AT_NONE;
|
||||||
animation.aspect_w = 1;
|
animation.aspect_w = 1;
|
||||||
animation.aspect_h = 1;
|
animation.aspect_h = 1;
|
||||||
animation.length = 1.0;
|
animation.length = 1.0;
|
||||||
|
@ -43,6 +43,22 @@ v3f random_v3f(v3f min, v3f max)
|
|||||||
rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z);
|
rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 check_material_type_param(u32 material_type_param)
|
||||||
|
{
|
||||||
|
u32 alphaSource = (material_type_param & 0x0000F000) >> 12;
|
||||||
|
u32 modulo = (material_type_param & 0x00000F00) >> 8;
|
||||||
|
u32 srcFact = (material_type_param & 0x000000F0) >> 4;
|
||||||
|
u32 dstFact = material_type_param & 0x0000000F;
|
||||||
|
if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) {
|
||||||
|
return material_type_param;
|
||||||
|
} else {
|
||||||
|
errorstream << "Server send incorrect ";
|
||||||
|
errorstream << "material_type_param value for particle.";
|
||||||
|
errorstream << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Particle::Particle(
|
Particle::Particle(
|
||||||
IGameDef *gamedef,
|
IGameDef *gamedef,
|
||||||
scene::ISceneManager* smgr,
|
scene::ISceneManager* smgr,
|
||||||
@ -58,7 +74,14 @@ Particle::Particle(
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
v2f texpos,
|
v2f texpos,
|
||||||
v2f texsize
|
v2f texsize,
|
||||||
|
u32 material_type_param,
|
||||||
|
u16 vertical_frame_num,
|
||||||
|
u16 horizontal_frame_num,
|
||||||
|
u16 first_frame,
|
||||||
|
float frame_length,
|
||||||
|
bool loop_animation,
|
||||||
|
u8 glow
|
||||||
):
|
):
|
||||||
scene::ISceneNode(smgr->getRootSceneNode(), smgr)
|
scene::ISceneNode(smgr->getRootSceneNode(), smgr)
|
||||||
{
|
{
|
||||||
@ -71,11 +94,26 @@ Particle::Particle(
|
|||||||
m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
m_material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
m_material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
m_material.setFlag(video::EMF_FOG_ENABLE, true);
|
m_material.setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
if (material_type_param != 0) {
|
||||||
|
m_material.MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||||
|
m_material.MaterialTypeParam = irr::core::FR(material_type_param);
|
||||||
|
// We must disable z-buffer if we want to avoid transparent pixels
|
||||||
|
// to overlap pixels with lower z-value.
|
||||||
|
m_material.setFlag(video::EMF_ZWRITE_ENABLE, false);
|
||||||
|
} else {
|
||||||
|
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
|
}
|
||||||
m_material.setTexture(0, texture);
|
m_material.setTexture(0, texture);
|
||||||
|
|
||||||
m_texpos = texpos;
|
m_texpos = texpos;
|
||||||
m_texsize = texsize;
|
m_texsize = texsize;
|
||||||
|
m_vertical_frame_num = vertical_frame_num;
|
||||||
|
m_horizontal_frame_num = horizontal_frame_num;
|
||||||
|
m_first_frame = first_frame;
|
||||||
|
m_frame_length = frame_length;
|
||||||
|
m_loop_animation = loop_animation;
|
||||||
|
m_texsize.Y /= m_vertical_frame_num;
|
||||||
|
m_texsize.X /= m_horizontal_frame_num;
|
||||||
|
|
||||||
// Particle related
|
// Particle related
|
||||||
m_pos = pos;
|
m_pos = pos;
|
||||||
@ -88,6 +126,7 @@ Particle::Particle(
|
|||||||
m_collisiondetection = collisiondetection;
|
m_collisiondetection = collisiondetection;
|
||||||
m_collision_removal = collision_removal;
|
m_collision_removal = collision_removal;
|
||||||
m_vertical = vertical;
|
m_vertical = vertical;
|
||||||
|
m_glow = glow;
|
||||||
|
|
||||||
// Irrlicht stuff
|
// Irrlicht stuff
|
||||||
m_collisionbox = aabb3f
|
m_collisionbox = aabb3f
|
||||||
@ -170,16 +209,29 @@ void Particle::updateLight()
|
|||||||
else
|
else
|
||||||
light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0);
|
light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0);
|
||||||
|
|
||||||
m_light = decode_light(light);
|
m_light = decode_light(light + m_glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::updateVertices()
|
void Particle::updateVertices()
|
||||||
{
|
{
|
||||||
video::SColor c(255, m_light, m_light, m_light);
|
video::SColor c(255, m_light, m_light, m_light);
|
||||||
f32 tx0 = m_texpos.X;
|
u16 frame = m_first_frame;
|
||||||
f32 tx1 = m_texpos.X + m_texsize.X;
|
if (m_frame_length > 0) {
|
||||||
f32 ty0 = m_texpos.Y;
|
if (m_loop_animation)
|
||||||
f32 ty1 = m_texpos.Y + m_texsize.Y;
|
frame = m_first_frame + (u32)(m_time / m_frame_length)
|
||||||
|
% (m_vertical_frame_num *
|
||||||
|
m_horizontal_frame_num - m_first_frame);
|
||||||
|
else if (m_time >=
|
||||||
|
(m_vertical_frame_num * m_horizontal_frame_num
|
||||||
|
- m_first_frame) * m_frame_length)
|
||||||
|
frame = m_vertical_frame_num * m_horizontal_frame_num - 1;
|
||||||
|
else
|
||||||
|
frame = m_first_frame + (u16)(m_time / m_frame_length);
|
||||||
|
}
|
||||||
|
f32 tx0 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num);
|
||||||
|
f32 tx1 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num + 1);
|
||||||
|
f32 ty0 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num);
|
||||||
|
f32 ty1 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num + 1);
|
||||||
|
|
||||||
m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0,
|
m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0,
|
||||||
c, tx0, ty1);
|
c, tx0, ty1);
|
||||||
@ -214,7 +266,16 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
|
|||||||
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
|
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
|
||||||
float minexptime, float maxexptime, float minsize, float maxsize,
|
float minexptime, float maxexptime, float minsize, float maxsize,
|
||||||
bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical,
|
bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical,
|
||||||
video::ITexture *texture, u32 id, ParticleManager *p_manager) :
|
video::ITexture *texture, u32 id,
|
||||||
|
u32 material_type_param,
|
||||||
|
u16 vertical_frame_num,
|
||||||
|
u16 horizontal_frame_num,
|
||||||
|
u16 min_first_frame,
|
||||||
|
u16 max_first_frame,
|
||||||
|
float frame_length,
|
||||||
|
bool loop_animation,
|
||||||
|
u8 glow,
|
||||||
|
ParticleManager *p_manager) :
|
||||||
m_particlemanager(p_manager)
|
m_particlemanager(p_manager)
|
||||||
{
|
{
|
||||||
m_gamedef = gamedef;
|
m_gamedef = gamedef;
|
||||||
@ -238,6 +299,14 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
|
|||||||
m_vertical = vertical;
|
m_vertical = vertical;
|
||||||
m_texture = texture;
|
m_texture = texture;
|
||||||
m_time = 0;
|
m_time = 0;
|
||||||
|
m_vertical_frame_num = vertical_frame_num;
|
||||||
|
m_horizontal_frame_num = horizontal_frame_num;
|
||||||
|
m_min_first_frame = min_first_frame;
|
||||||
|
m_max_first_frame = max_first_frame;
|
||||||
|
m_frame_length = frame_length;
|
||||||
|
m_loop_animation = loop_animation;
|
||||||
|
m_material_type_param = material_type_param;
|
||||||
|
m_glow = glow;
|
||||||
|
|
||||||
for (u16 i = 0; i<=m_amount; i++)
|
for (u16 i = 0; i<=m_amount; i++)
|
||||||
{
|
{
|
||||||
@ -251,7 +320,6 @@ ParticleSpawner::~ParticleSpawner() {}
|
|||||||
void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
||||||
{
|
{
|
||||||
m_time += dtime;
|
m_time += dtime;
|
||||||
|
|
||||||
bool unloaded = false;
|
bool unloaded = false;
|
||||||
v3f attached_offset = v3f(0,0,0);
|
v3f attached_offset = v3f(0,0,0);
|
||||||
if (m_attached_id != 0) {
|
if (m_attached_id != 0) {
|
||||||
@ -285,7 +353,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
float size = rand()/(float)RAND_MAX
|
float size = rand()/(float)RAND_MAX
|
||||||
*(m_maxsize-m_minsize)
|
*(m_maxsize-m_minsize)
|
||||||
+m_minsize;
|
+m_minsize;
|
||||||
|
u16 first_frame = m_min_first_frame +
|
||||||
|
rand() %
|
||||||
|
(m_max_first_frame -
|
||||||
|
m_min_first_frame + 1);
|
||||||
Particle* toadd = new Particle(
|
Particle* toadd = new Particle(
|
||||||
m_gamedef,
|
m_gamedef,
|
||||||
m_smgr,
|
m_smgr,
|
||||||
@ -301,7 +372,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
m_vertical,
|
m_vertical,
|
||||||
m_texture,
|
m_texture,
|
||||||
v2f(0.0, 0.0),
|
v2f(0.0, 0.0),
|
||||||
v2f(1.0, 1.0));
|
v2f(1.0, 1.0),
|
||||||
|
m_material_type_param,
|
||||||
|
m_vertical_frame_num,
|
||||||
|
m_horizontal_frame_num,
|
||||||
|
first_frame,
|
||||||
|
m_frame_length,
|
||||||
|
m_loop_animation,
|
||||||
|
m_glow);
|
||||||
m_particlemanager->addParticle(toadd);
|
m_particlemanager->addParticle(toadd);
|
||||||
}
|
}
|
||||||
i = m_spawntimes.erase(i);
|
i = m_spawntimes.erase(i);
|
||||||
@ -331,7 +409,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
float size = rand()/(float)RAND_MAX
|
float size = rand()/(float)RAND_MAX
|
||||||
*(m_maxsize-m_minsize)
|
*(m_maxsize-m_minsize)
|
||||||
+m_minsize;
|
+m_minsize;
|
||||||
|
u16 first_frame = m_min_first_frame +
|
||||||
|
rand() %
|
||||||
|
(m_max_first_frame -
|
||||||
|
m_min_first_frame + 1);
|
||||||
Particle* toadd = new Particle(
|
Particle* toadd = new Particle(
|
||||||
m_gamedef,
|
m_gamedef,
|
||||||
m_smgr,
|
m_smgr,
|
||||||
@ -347,7 +428,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
m_vertical,
|
m_vertical,
|
||||||
m_texture,
|
m_texture,
|
||||||
v2f(0.0, 0.0),
|
v2f(0.0, 0.0),
|
||||||
v2f(1.0, 1.0));
|
v2f(1.0, 1.0),
|
||||||
|
m_material_type_param,
|
||||||
|
m_vertical_frame_num,
|
||||||
|
m_horizontal_frame_num,
|
||||||
|
first_frame,
|
||||||
|
m_frame_length,
|
||||||
|
m_loop_animation,
|
||||||
|
m_glow);
|
||||||
m_particlemanager->addParticle(toadd);
|
m_particlemanager->addParticle(toadd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,6 +547,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||||||
video::ITexture *texture =
|
video::ITexture *texture =
|
||||||
gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture));
|
gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture));
|
||||||
|
|
||||||
|
float frame_length = -1;
|
||||||
|
u16 vertical_frame_num = 1;
|
||||||
|
u16 horizontal_frame_num = 1;
|
||||||
|
u32 material_type_param =
|
||||||
|
check_material_type_param(event->add_particlespawner.material_type_param);
|
||||||
|
|
||||||
|
switch (event->add_particlespawner.animation_type) {
|
||||||
|
case AT_NONE:
|
||||||
|
break;
|
||||||
|
case AT_VERTICAL_FRAMES: {
|
||||||
|
v2u32 size = texture->getOriginalSize();
|
||||||
|
int frame_height = (float)size.X /
|
||||||
|
(float)event->add_particlespawner.vertical_frame_num *
|
||||||
|
(float)event->add_particlespawner.horizontal_frame_num;
|
||||||
|
vertical_frame_num = size.Y / frame_height;
|
||||||
|
frame_length =
|
||||||
|
event->add_particlespawner.frame_length /
|
||||||
|
vertical_frame_num;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AT_2D_ANIMATION_SHEET: {
|
||||||
|
vertical_frame_num =
|
||||||
|
event->add_particlespawner.vertical_frame_num;
|
||||||
|
horizontal_frame_num =
|
||||||
|
event->add_particlespawner.horizontal_frame_num;
|
||||||
|
frame_length =
|
||||||
|
event->add_particlespawner.frame_length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player,
|
ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player,
|
||||||
event->add_particlespawner.amount,
|
event->add_particlespawner.amount,
|
||||||
event->add_particlespawner.spawntime,
|
event->add_particlespawner.spawntime,
|
||||||
@ -478,6 +599,14 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||||||
event->add_particlespawner.vertical,
|
event->add_particlespawner.vertical,
|
||||||
texture,
|
texture,
|
||||||
event->add_particlespawner.id,
|
event->add_particlespawner.id,
|
||||||
|
material_type_param,
|
||||||
|
vertical_frame_num,
|
||||||
|
horizontal_frame_num,
|
||||||
|
event->add_particlespawner.min_first_frame,
|
||||||
|
event->add_particlespawner.max_first_frame,
|
||||||
|
frame_length,
|
||||||
|
event->add_particlespawner.loop_animation,
|
||||||
|
event->add_particlespawner.glow,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
/* delete allocated content of event */
|
/* delete allocated content of event */
|
||||||
@ -502,6 +631,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||||||
video::ITexture *texture =
|
video::ITexture *texture =
|
||||||
gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture));
|
gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture));
|
||||||
|
|
||||||
|
float frame_length = -1;
|
||||||
|
u16 vertical_frame_num = 1;
|
||||||
|
u16 horizontal_frame_num = 1;
|
||||||
|
u32 material_type_param =
|
||||||
|
check_material_type_param(event->spawn_particle.material_type_param);
|
||||||
|
|
||||||
|
switch (event->spawn_particle.animation_type) {
|
||||||
|
case AT_NONE:
|
||||||
|
break;
|
||||||
|
case AT_VERTICAL_FRAMES: {
|
||||||
|
v2u32 size = texture->getOriginalSize();
|
||||||
|
int frame_height = (float)size.X /
|
||||||
|
(float)event->spawn_particle.vertical_frame_num *
|
||||||
|
(float)event->spawn_particle.horizontal_frame_num;
|
||||||
|
vertical_frame_num = size.Y / frame_height;
|
||||||
|
frame_length =
|
||||||
|
event->spawn_particle.frame_length /
|
||||||
|
vertical_frame_num;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AT_2D_ANIMATION_SHEET: {
|
||||||
|
vertical_frame_num =
|
||||||
|
event->spawn_particle.vertical_frame_num;
|
||||||
|
horizontal_frame_num =
|
||||||
|
event->spawn_particle.horizontal_frame_num;
|
||||||
|
frame_length =
|
||||||
|
event->spawn_particle.frame_length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Particle* toadd = new Particle(gamedef, smgr, player, m_env,
|
Particle* toadd = new Particle(gamedef, smgr, player, m_env,
|
||||||
*event->spawn_particle.pos,
|
*event->spawn_particle.pos,
|
||||||
*event->spawn_particle.vel,
|
*event->spawn_particle.vel,
|
||||||
@ -513,13 +675,21 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||||||
event->spawn_particle.vertical,
|
event->spawn_particle.vertical,
|
||||||
texture,
|
texture,
|
||||||
v2f(0.0, 0.0),
|
v2f(0.0, 0.0),
|
||||||
v2f(1.0, 1.0));
|
v2f(1.0, 1.0),
|
||||||
|
material_type_param,
|
||||||
|
vertical_frame_num,
|
||||||
|
horizontal_frame_num,
|
||||||
|
event->spawn_particle.first_frame,
|
||||||
|
frame_length,
|
||||||
|
event->spawn_particle.loop_animation,
|
||||||
|
event->spawn_particle.glow);
|
||||||
|
|
||||||
addParticle(toadd);
|
addParticle(toadd);
|
||||||
|
|
||||||
delete event->spawn_particle.pos;
|
delete event->spawn_particle.pos;
|
||||||
delete event->spawn_particle.vel;
|
delete event->spawn_particle.vel;
|
||||||
delete event->spawn_particle.acc;
|
delete event->spawn_particle.acc;
|
||||||
|
delete event->spawn_particle.texture;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -588,7 +758,8 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
|
|||||||
false,
|
false,
|
||||||
texture,
|
texture,
|
||||||
texpos,
|
texpos,
|
||||||
texsize);
|
texsize,
|
||||||
|
0, 1, 1, 0, -1, true, 0);
|
||||||
|
|
||||||
addParticle(toadd);
|
addParticle(toadd);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,14 @@ class Particle : public scene::ISceneNode
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
v2f texpos,
|
v2f texpos,
|
||||||
v2f texsize
|
v2f texsize,
|
||||||
|
u32 material_type_param,
|
||||||
|
u16 vertical_frame_num,
|
||||||
|
u16 horizontal_frame_num,
|
||||||
|
u16 first_frame,
|
||||||
|
float frame_length,
|
||||||
|
bool loop_animation,
|
||||||
|
u8 glow
|
||||||
);
|
);
|
||||||
~Particle();
|
~Particle();
|
||||||
|
|
||||||
@ -102,6 +109,12 @@ private:
|
|||||||
bool m_collision_removal;
|
bool m_collision_removal;
|
||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
v3s16 m_camera_offset;
|
v3s16 m_camera_offset;
|
||||||
|
u16 m_vertical_frame_num;
|
||||||
|
u16 m_horizontal_frame_num;
|
||||||
|
u16 m_first_frame;
|
||||||
|
float m_frame_length;
|
||||||
|
bool m_loop_animation;
|
||||||
|
u8 m_glow;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParticleSpawner
|
class ParticleSpawner
|
||||||
@ -123,8 +136,15 @@ class ParticleSpawner
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
u32 id,
|
u32 id,
|
||||||
|
u32 material_type_param,
|
||||||
|
u16 vertical_frame_num,
|
||||||
|
u16 horizontal_frame_num,
|
||||||
|
u16 min_first_frame,
|
||||||
|
u16 max_first_frame,
|
||||||
|
float frame_length,
|
||||||
|
bool loop_animation,
|
||||||
|
u8 glow,
|
||||||
ParticleManager* p_manager);
|
ParticleManager* p_manager);
|
||||||
|
|
||||||
~ParticleSpawner();
|
~ParticleSpawner();
|
||||||
|
|
||||||
void step(float dtime, ClientEnvironment *env);
|
void step(float dtime, ClientEnvironment *env);
|
||||||
@ -156,6 +176,14 @@ class ParticleSpawner
|
|||||||
bool m_collision_removal;
|
bool m_collision_removal;
|
||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
u16 m_attached_id;
|
u16 m_attached_id;
|
||||||
|
u32 m_material_type_param;
|
||||||
|
u16 m_vertical_frame_num;
|
||||||
|
u16 m_horizontal_frame_num;
|
||||||
|
u16 m_min_first_frame;
|
||||||
|
u16 m_max_first_frame;
|
||||||
|
float m_frame_length;
|
||||||
|
bool m_loop_animation;
|
||||||
|
u8 m_glow;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,10 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
struct EnumString es_TileAnimationType[] =
|
struct EnumString es_AnimationType[] =
|
||||||
{
|
{
|
||||||
{TAT_NONE, "none"},
|
{AT_NONE, "none"},
|
||||||
{TAT_VERTICAL_FRAMES, "vertical_frames"},
|
{AT_VERTICAL_FRAMES, "vertical_frames"},
|
||||||
|
{AT_2D_ANIMATION_SHEET, "2d_animation_sheet"},
|
||||||
{0, NULL},
|
{0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -335,9 +336,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
|
|||||||
lua_getfield(L, index, "animation");
|
lua_getfield(L, index, "animation");
|
||||||
if(lua_istable(L, -1)){
|
if(lua_istable(L, -1)){
|
||||||
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
||||||
tiledef.animation.type = (TileAnimationType)
|
tiledef.animation.type = (AnimationType)
|
||||||
getenumfield(L, -1, "type", es_TileAnimationType,
|
getenumfield(L, -1, "type", es_AnimationType,
|
||||||
TAT_NONE);
|
AT_NONE);
|
||||||
tiledef.animation.aspect_w =
|
tiledef.animation.aspect_w =
|
||||||
getintfield_default(L, -1, "aspect_w", 16);
|
getintfield_default(L, -1, "aspect_w", 16);
|
||||||
tiledef.animation.aspect_h =
|
tiledef.animation.aspect_h =
|
||||||
|
@ -159,6 +159,6 @@ bool push_json_value (lua_State *L,
|
|||||||
void read_json_value (lua_State *L, Json::Value &root,
|
void read_json_value (lua_State *L, Json::Value &root,
|
||||||
int index, u8 recursion = 0);
|
int index, u8 recursion = 0);
|
||||||
|
|
||||||
extern struct EnumString es_TileAnimationType[];
|
extern struct EnumString es_AnimationType[];
|
||||||
|
|
||||||
#endif /* C_CONTENT_H_ */
|
#endif /* C_CONTENT_H_ */
|
||||||
|
@ -513,6 +513,28 @@ int getintfield_default(lua_State *L, int table,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_material_type_param(lua_State *L, int table,
|
||||||
|
const char *fieldname, int default_)
|
||||||
|
{
|
||||||
|
int material_type_param =
|
||||||
|
getintfield_default(L, table, fieldname, default_);
|
||||||
|
u32 alphaSource = (material_type_param & 0x0000F000) >> 12;
|
||||||
|
u32 modulo = (material_type_param & 0x00000F00) >> 8;
|
||||||
|
u32 srcFact = (material_type_param & 0x000000F0) >> 4;
|
||||||
|
u32 dstFact = material_type_param & 0x0000000F;
|
||||||
|
if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) {
|
||||||
|
return material_type_param;
|
||||||
|
} else {
|
||||||
|
std::ostringstream error_text;
|
||||||
|
error_text << "Incorrect material_type_param value ";
|
||||||
|
error_text << "for particle or particle spawner.";
|
||||||
|
error_text << std::endl;
|
||||||
|
throw LuaError(error_text.str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float getfloatfield_default(lua_State *L, int table,
|
float getfloatfield_default(lua_State *L, int table,
|
||||||
const char *fieldname, float default_)
|
const char *fieldname, float default_)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,8 @@ float getfloatfield_default(lua_State *L, int table,
|
|||||||
const char *fieldname, float default_);
|
const char *fieldname, float default_);
|
||||||
int getintfield_default (lua_State *L, int table,
|
int getintfield_default (lua_State *L, int table,
|
||||||
const char *fieldname, int default_);
|
const char *fieldname, int default_);
|
||||||
|
int check_material_type_param(lua_State *L, int table,
|
||||||
|
const char *fieldname, int default_);
|
||||||
|
|
||||||
bool getstringfield(lua_State *L, int table,
|
bool getstringfield(lua_State *L, int table,
|
||||||
const char *fieldname, std::string &result);
|
const char *fieldname, std::string &result);
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "lua_api/l_object.h"
|
#include "lua_api/l_object.h"
|
||||||
#include "lua_api/l_internal.h"
|
#include "lua_api/l_internal.h"
|
||||||
#include "common/c_converter.h"
|
#include "common/c_converter.h"
|
||||||
|
#include "common/c_content.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "particles.h"
|
#include "particles.h"
|
||||||
|
|
||||||
@ -34,6 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
// collision_removal = bool
|
// collision_removal = bool
|
||||||
// vertical = bool
|
// vertical = bool
|
||||||
// texture = e.g."default_wood.png"
|
// texture = e.g."default_wood.png"
|
||||||
|
// material_type_param = num
|
||||||
|
// animation = animation definition
|
||||||
|
// glow = indexed color or color string
|
||||||
int ModApiParticles::l_add_particle(lua_State *L)
|
int ModApiParticles::l_add_particle(lua_State *L)
|
||||||
{
|
{
|
||||||
MAP_LOCK_REQUIRED;
|
MAP_LOCK_REQUIRED;
|
||||||
@ -44,13 +48,24 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
|
|
||||||
float expirationtime, size;
|
float expirationtime, size;
|
||||||
expirationtime = size = 1;
|
expirationtime = size = 1;
|
||||||
|
float frame_or_loop_length = -1;
|
||||||
|
|
||||||
|
AnimationType animation_type = AT_NONE;
|
||||||
|
|
||||||
|
u16 vertical_frame_num_or_aspect = 1;
|
||||||
|
u16 horizontal_frame_num_or_aspect = 1;
|
||||||
|
u16 first_frame = 0;
|
||||||
|
|
||||||
bool collisiondetection, vertical, collision_removal;
|
bool collisiondetection, vertical, collision_removal;
|
||||||
collisiondetection = vertical = collision_removal = false;
|
collisiondetection = vertical = collision_removal = false;
|
||||||
|
bool loop_animation = true;
|
||||||
|
|
||||||
std::string texture = "";
|
std::string texture = "";
|
||||||
std::string playername = "";
|
std::string playername = "";
|
||||||
|
|
||||||
|
u32 material_type_param = 0;
|
||||||
|
u8 glow = 0;
|
||||||
|
|
||||||
if (lua_gettop(L) > 1) // deprecated
|
if (lua_gettop(L) > 1) // deprecated
|
||||||
{
|
{
|
||||||
log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition");
|
log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition");
|
||||||
@ -96,6 +111,59 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
|
|
||||||
expirationtime = getfloatfield_default(L, 1, "expirationtime", 1);
|
expirationtime = getfloatfield_default(L, 1, "expirationtime", 1);
|
||||||
size = getfloatfield_default(L, 1, "size", 1);
|
size = getfloatfield_default(L, 1, "size", 1);
|
||||||
|
|
||||||
|
lua_getfield(L, 1, "animation");
|
||||||
|
if (lua_istable(L, -1)) {
|
||||||
|
animation_type = (AnimationType)
|
||||||
|
getenumfield(L, -1, "type", es_AnimationType,
|
||||||
|
AT_NONE);
|
||||||
|
}
|
||||||
|
switch (animation_type) {
|
||||||
|
case AT_NONE:
|
||||||
|
break;
|
||||||
|
case AT_2D_ANIMATION_SHEET:
|
||||||
|
frame_or_loop_length =
|
||||||
|
getfloatfield_default(L, -1, "frame_length", -1);
|
||||||
|
vertical_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "vertical_frame_num", 1);
|
||||||
|
horizontal_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "horizontal_frame_num", 1);
|
||||||
|
first_frame =
|
||||||
|
getintfield_default(L, -1, "first_frame", 0);
|
||||||
|
loop_animation =
|
||||||
|
getboolfield_default(L, -1, "loop_animation", true);
|
||||||
|
break;
|
||||||
|
case AT_VERTICAL_FRAMES:
|
||||||
|
frame_or_loop_length =
|
||||||
|
getfloatfield_default(L, -1, "length", -1);
|
||||||
|
vertical_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "aspect_w", 1);
|
||||||
|
horizontal_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "aspect_h", 1);
|
||||||
|
first_frame =
|
||||||
|
getintfield_default(L, -1, "first_frame", 0);
|
||||||
|
loop_animation =
|
||||||
|
getboolfield_default(L, -1, "loop_animation", true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
if (animation_type == AT_2D_ANIMATION_SHEET &&
|
||||||
|
first_frame >= vertical_frame_num_or_aspect *
|
||||||
|
horizontal_frame_num_or_aspect) {
|
||||||
|
std::ostringstream error_text;
|
||||||
|
error_text << "first_frame should be lower, than "
|
||||||
|
<< "vertical_frame_num * horizontal_frame_num. "
|
||||||
|
<< "Got first_frame=" << first_frame
|
||||||
|
<< ", vertical_frame_num="
|
||||||
|
<< vertical_frame_num_or_aspect
|
||||||
|
<< " and horizontal_frame_num="
|
||||||
|
<< horizontal_frame_num_or_aspect << std::endl;
|
||||||
|
throw LuaError(error_text.str());
|
||||||
|
}
|
||||||
|
|
||||||
collisiondetection = getboolfield_default(L, 1,
|
collisiondetection = getboolfield_default(L, 1,
|
||||||
"collisiondetection", collisiondetection);
|
"collisiondetection", collisiondetection);
|
||||||
collision_removal = getboolfield_default(L, 1,
|
collision_removal = getboolfield_default(L, 1,
|
||||||
@ -103,9 +171,16 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
||||||
texture = getstringfield_default(L, 1, "texture", "");
|
texture = getstringfield_default(L, 1, "texture", "");
|
||||||
playername = getstringfield_default(L, 1, "playername", "");
|
playername = getstringfield_default(L, 1, "playername", "");
|
||||||
|
material_type_param = check_material_type_param(L, 1, "material_type_param", 0);
|
||||||
|
glow = getintfield_default (L, 1, "glow", 0);
|
||||||
}
|
}
|
||||||
getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
|
getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime,
|
||||||
collisiondetection, collision_removal, vertical, texture);
|
size, collisiondetection, collision_removal, vertical,
|
||||||
|
texture, material_type_param,
|
||||||
|
animation_type,
|
||||||
|
vertical_frame_num_or_aspect,
|
||||||
|
horizontal_frame_num_or_aspect,
|
||||||
|
first_frame, frame_or_loop_length, loop_animation, glow);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,21 +202,33 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
// collision_removal = bool
|
// collision_removal = bool
|
||||||
// vertical = bool
|
// vertical = bool
|
||||||
// texture = e.g."default_wood.png"
|
// texture = e.g."default_wood.png"
|
||||||
|
// material_type_param = num
|
||||||
|
// animation = animation definition
|
||||||
|
// glow = indexed color or color string
|
||||||
int ModApiParticles::l_add_particlespawner(lua_State *L)
|
int ModApiParticles::l_add_particlespawner(lua_State *L)
|
||||||
{
|
{
|
||||||
MAP_LOCK_REQUIRED;
|
MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
// Get parameters
|
// Get parameters
|
||||||
u16 amount = 1;
|
u16 amount = 1;
|
||||||
|
u16 vertical_frame_num_or_aspect = 1;
|
||||||
|
u16 horizontal_frame_num_or_aspect = 1;
|
||||||
|
u16 min_first_frame = 0;
|
||||||
|
u16 max_first_frame = 0;
|
||||||
v3f minpos, maxpos, minvel, maxvel, minacc, maxacc;
|
v3f minpos, maxpos, minvel, maxvel, minacc, maxacc;
|
||||||
minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0);
|
minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0);
|
||||||
float time, minexptime, maxexptime, minsize, maxsize;
|
float time, minexptime, maxexptime, minsize, maxsize;
|
||||||
time= minexptime= maxexptime= minsize= maxsize= 1;
|
time= minexptime= maxexptime= minsize= maxsize= 1;
|
||||||
|
AnimationType animation_type = AT_NONE;
|
||||||
|
float frame_or_loop_length = -1;
|
||||||
bool collisiondetection, vertical, collision_removal;
|
bool collisiondetection, vertical, collision_removal;
|
||||||
collisiondetection = vertical = collision_removal = false;
|
collisiondetection = vertical = collision_removal = false;
|
||||||
|
bool loop_animation = true;
|
||||||
ServerActiveObject *attached = NULL;
|
ServerActiveObject *attached = NULL;
|
||||||
std::string texture = "";
|
std::string texture = "";
|
||||||
std::string playername = "";
|
std::string playername = "";
|
||||||
|
u32 material_type_param = 0;
|
||||||
|
u8 glow = 0;
|
||||||
|
|
||||||
if (lua_gettop(L) > 1) //deprecated
|
if (lua_gettop(L) > 1) //deprecated
|
||||||
{
|
{
|
||||||
@ -196,6 +283,65 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime);
|
maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime);
|
||||||
minsize = getfloatfield_default(L, 1, "minsize", minsize);
|
minsize = getfloatfield_default(L, 1, "minsize", minsize);
|
||||||
maxsize = getfloatfield_default(L, 1, "maxsize", maxsize);
|
maxsize = getfloatfield_default(L, 1, "maxsize", maxsize);
|
||||||
|
|
||||||
|
|
||||||
|
lua_getfield(L, 1, "animation");
|
||||||
|
if (lua_istable(L, -1)) {
|
||||||
|
animation_type = (AnimationType)
|
||||||
|
getenumfield(L, -1, "type", es_AnimationType,
|
||||||
|
AT_NONE);
|
||||||
|
}
|
||||||
|
switch (animation_type) {
|
||||||
|
case AT_NONE:
|
||||||
|
break;
|
||||||
|
case AT_2D_ANIMATION_SHEET:
|
||||||
|
frame_or_loop_length =
|
||||||
|
getfloatfield_default(L, -1, "frame_length", -1);
|
||||||
|
vertical_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "vertical_frame_num", 1);
|
||||||
|
horizontal_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "horizontal_frame_num", 1);
|
||||||
|
min_first_frame =
|
||||||
|
getintfield_default(L, -1, "min_first_frame", 0);
|
||||||
|
max_first_frame =
|
||||||
|
getintfield_default(L, -1, "max_first_frame", 0);
|
||||||
|
loop_animation =
|
||||||
|
getboolfield_default(L, -1, "loop_animation", true);
|
||||||
|
break;
|
||||||
|
case AT_VERTICAL_FRAMES:
|
||||||
|
frame_or_loop_length =
|
||||||
|
getfloatfield_default(L, -1, "length", -1);
|
||||||
|
vertical_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "aspect_w", 1);
|
||||||
|
horizontal_frame_num_or_aspect =
|
||||||
|
getintfield_default(L, -1, "aspect_h", 1);
|
||||||
|
min_first_frame =
|
||||||
|
getintfield_default(L, -1, "min_first_frame", 0);
|
||||||
|
max_first_frame =
|
||||||
|
getintfield_default(L, -1, "max_first_frame", 0);
|
||||||
|
loop_animation =
|
||||||
|
getboolfield_default(L, -1, "loop_animation", true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
if (animation_type == AT_2D_ANIMATION_SHEET &&
|
||||||
|
max_first_frame >= vertical_frame_num_or_aspect *
|
||||||
|
horizontal_frame_num_or_aspect) {
|
||||||
|
std::ostringstream error_text;
|
||||||
|
error_text << "max_first_frame should be lower, than "
|
||||||
|
<< "vertical_frame_num * horizontal_frame_num. "
|
||||||
|
<< "Got max_first_frame="
|
||||||
|
<< max_first_frame
|
||||||
|
<< ", vertical_frame_num="
|
||||||
|
<< vertical_frame_num_or_aspect
|
||||||
|
<< " and horizontal_frame_num="
|
||||||
|
<< horizontal_frame_num_or_aspect << std::endl;
|
||||||
|
throw LuaError(error_text.str());
|
||||||
|
}
|
||||||
|
|
||||||
collisiondetection = getboolfield_default(L, 1,
|
collisiondetection = getboolfield_default(L, 1,
|
||||||
"collisiondetection", collisiondetection);
|
"collisiondetection", collisiondetection);
|
||||||
collision_removal = getboolfield_default(L, 1,
|
collision_removal = getboolfield_default(L, 1,
|
||||||
@ -211,6 +357,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
||||||
texture = getstringfield_default(L, 1, "texture", "");
|
texture = getstringfield_default(L, 1, "texture", "");
|
||||||
playername = getstringfield_default(L, 1, "playername", "");
|
playername = getstringfield_default(L, 1, "playername", "");
|
||||||
|
material_type_param = check_material_type_param(L, 1, "material_type_param", 0);
|
||||||
|
glow = getintfield_default(L, 1, "glow", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 id = getServer(L)->addParticleSpawner(amount, time,
|
u32 id = getServer(L)->addParticleSpawner(amount, time,
|
||||||
@ -223,9 +371,17 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
collision_removal,
|
collision_removal,
|
||||||
attached,
|
attached,
|
||||||
vertical,
|
vertical,
|
||||||
texture, playername);
|
texture,
|
||||||
|
playername,
|
||||||
|
material_type_param,
|
||||||
|
animation_type,
|
||||||
|
vertical_frame_num_or_aspect,
|
||||||
|
horizontal_frame_num_or_aspect,
|
||||||
|
min_first_frame, max_first_frame,
|
||||||
|
frame_or_loop_length,
|
||||||
|
loop_animation,
|
||||||
|
glow);
|
||||||
lua_pushnumber(L, id);
|
lua_pushnumber(L, id);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1658,7 +1658,11 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
|
|||||||
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
|
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
|
||||||
float expirationtime, float size, bool collisiondetection,
|
float expirationtime, float size, bool collisiondetection,
|
||||||
bool collision_removal,
|
bool collision_removal,
|
||||||
bool vertical, const std::string &texture)
|
bool vertical, const std::string &texture,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow)
|
||||||
{
|
{
|
||||||
DSTACK(FUNCTION_NAME);
|
DSTACK(FUNCTION_NAME);
|
||||||
|
|
||||||
@ -1670,6 +1674,12 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
|
|||||||
pkt << vertical;
|
pkt << vertical;
|
||||||
pkt << collision_removal;
|
pkt << collision_removal;
|
||||||
|
|
||||||
|
pkt << material_type_param
|
||||||
|
<< (u8)animation_type
|
||||||
|
<< vertical_frame_num
|
||||||
|
<< horizontal_frame_num << first_frame
|
||||||
|
<< frame_length << loop_animation << glow;
|
||||||
|
|
||||||
if (peer_id != PEER_ID_INEXISTENT) {
|
if (peer_id != PEER_ID_INEXISTENT) {
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
@ -1682,7 +1692,10 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
|
|||||||
void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
|
void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
|
||||||
v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
|
v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
|
||||||
float minsize, float maxsize, bool collisiondetection, bool collision_removal,
|
float minsize, float maxsize, bool collisiondetection, bool collision_removal,
|
||||||
u16 attached_id, bool vertical, const std::string &texture, u32 id)
|
u16 attached_id, bool vertical, const std::string &texture, u32 id,
|
||||||
|
u32 material_type_param, AnimationType animation_type, u16 vertical_frame_num, u16 horizontal_frame_num,
|
||||||
|
u16 min_first_frame, u16 max_first_frame, float frame_length,
|
||||||
|
bool loop_animation, u8 glow)
|
||||||
{
|
{
|
||||||
DSTACK(FUNCTION_NAME);
|
DSTACK(FUNCTION_NAME);
|
||||||
|
|
||||||
@ -1698,6 +1711,12 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
|
|||||||
pkt << collision_removal;
|
pkt << collision_removal;
|
||||||
pkt << attached_id;
|
pkt << attached_id;
|
||||||
|
|
||||||
|
pkt << material_type_param
|
||||||
|
<< (u8)animation_type
|
||||||
|
<< vertical_frame_num << horizontal_frame_num
|
||||||
|
<< min_first_frame << max_first_frame
|
||||||
|
<< frame_length << loop_animation << glow;
|
||||||
|
|
||||||
if (peer_id != PEER_ID_INEXISTENT) {
|
if (peer_id != PEER_ID_INEXISTENT) {
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
@ -3147,7 +3166,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
|
|||||||
v3f velocity, v3f acceleration,
|
v3f velocity, v3f acceleration,
|
||||||
float expirationtime, float size, bool
|
float expirationtime, float size, bool
|
||||||
collisiondetection, bool collision_removal,
|
collisiondetection, bool collision_removal,
|
||||||
bool vertical, const std::string &texture)
|
bool vertical, const std::string &texture,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow)
|
||||||
{
|
{
|
||||||
// m_env will be NULL if the server is initializing
|
// m_env will be NULL if the server is initializing
|
||||||
if (!m_env)
|
if (!m_env)
|
||||||
@ -3163,7 +3186,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
|
|||||||
|
|
||||||
SendSpawnParticle(peer_id, pos, velocity, acceleration,
|
SendSpawnParticle(peer_id, pos, velocity, acceleration,
|
||||||
expirationtime, size, collisiondetection,
|
expirationtime, size, collisiondetection,
|
||||||
collision_removal, vertical, texture);
|
collision_removal, vertical, texture,
|
||||||
|
material_type_param, animation_type,
|
||||||
|
vertical_frame_num, horizontal_frame_num,
|
||||||
|
first_frame, frame_length, loop_animation,
|
||||||
|
glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
||||||
@ -3171,7 +3198,9 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
|||||||
float minexptime, float maxexptime, float minsize, float maxsize,
|
float minexptime, float maxexptime, float minsize, float maxsize,
|
||||||
bool collisiondetection, bool collision_removal,
|
bool collisiondetection, bool collision_removal,
|
||||||
ServerActiveObject *attached, bool vertical, const std::string &texture,
|
ServerActiveObject *attached, bool vertical, const std::string &texture,
|
||||||
const std::string &playername)
|
const std::string &playername, u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num, u16 min_first_frame, u16 max_first_frame,
|
||||||
|
float frame_length, bool loop_animation, u8 glow)
|
||||||
{
|
{
|
||||||
// m_env will be NULL if the server is initializing
|
// m_env will be NULL if the server is initializing
|
||||||
if (!m_env)
|
if (!m_env)
|
||||||
@ -3197,7 +3226,10 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
|||||||
minpos, maxpos, minvel, maxvel, minacc, maxacc,
|
minpos, maxpos, minvel, maxvel, minacc, maxacc,
|
||||||
minexptime, maxexptime, minsize, maxsize,
|
minexptime, maxexptime, minsize, maxsize,
|
||||||
collisiondetection, collision_removal, attached_id, vertical,
|
collisiondetection, collision_removal, attached_id, vertical,
|
||||||
texture, id);
|
texture, id, material_type_param, animation_type,
|
||||||
|
vertical_frame_num, horizontal_frame_num,
|
||||||
|
min_first_frame, max_first_frame, frame_length, loop_animation,
|
||||||
|
glow);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
27
src/server.h
27
src/server.h
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "serialization.h" // For SER_FMT_VER_INVALID
|
#include "serialization.h" // For SER_FMT_VER_INVALID
|
||||||
|
#include "nodedef.h" // AnimationType
|
||||||
#include "mods.h"
|
#include "mods.h"
|
||||||
#include "inventorymanager.h"
|
#include "inventorymanager.h"
|
||||||
#include "subgame.h"
|
#include "subgame.h"
|
||||||
@ -254,7 +255,11 @@ public:
|
|||||||
v3f pos, v3f velocity, v3f acceleration,
|
v3f pos, v3f velocity, v3f acceleration,
|
||||||
float expirationtime, float size,
|
float expirationtime, float size,
|
||||||
bool collisiondetection, bool collision_removal,
|
bool collisiondetection, bool collision_removal,
|
||||||
bool vertical, const std::string &texture);
|
bool vertical, const std::string &texture,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow);
|
||||||
|
|
||||||
u32 addParticleSpawner(u16 amount, float spawntime,
|
u32 addParticleSpawner(u16 amount, float spawntime,
|
||||||
v3f minpos, v3f maxpos,
|
v3f minpos, v3f maxpos,
|
||||||
@ -265,7 +270,12 @@ public:
|
|||||||
bool collisiondetection, bool collision_removal,
|
bool collisiondetection, bool collision_removal,
|
||||||
ServerActiveObject *attached,
|
ServerActiveObject *attached,
|
||||||
bool vertical, const std::string &texture,
|
bool vertical, const std::string &texture,
|
||||||
const std::string &playername);
|
const std::string &playername,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num,
|
||||||
|
u16 min_first_frame, u16 max_first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow);
|
||||||
|
|
||||||
void deleteParticleSpawner(const std::string &playername, u32 id);
|
void deleteParticleSpawner(const std::string &playername, u32 id);
|
||||||
|
|
||||||
@ -441,7 +451,12 @@ private:
|
|||||||
float minsize, float maxsize,
|
float minsize, float maxsize,
|
||||||
bool collisiondetection, bool collision_removal,
|
bool collisiondetection, bool collision_removal,
|
||||||
u16 attached_id,
|
u16 attached_id,
|
||||||
bool vertical, const std::string &texture, u32 id);
|
bool vertical, const std::string &texture, u32 id,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num,
|
||||||
|
u16 min_first_frame, u16 max_first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow);
|
||||||
|
|
||||||
void SendDeleteParticleSpawner(u16 peer_id, u32 id);
|
void SendDeleteParticleSpawner(u16 peer_id, u32 id);
|
||||||
|
|
||||||
@ -450,7 +465,11 @@ private:
|
|||||||
v3f pos, v3f velocity, v3f acceleration,
|
v3f pos, v3f velocity, v3f acceleration,
|
||||||
float expirationtime, float size,
|
float expirationtime, float size,
|
||||||
bool collisiondetection, bool collision_removal,
|
bool collisiondetection, bool collision_removal,
|
||||||
bool vertical, const std::string &texture);
|
bool vertical, const std::string &texture,
|
||||||
|
u32 material_type_param, AnimationType animation_type,
|
||||||
|
u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame,
|
||||||
|
float frame_length, bool loop_animation,
|
||||||
|
u8 glow);
|
||||||
|
|
||||||
u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas);
|
u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas);
|
||||||
void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);
|
void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);
|
||||||
|
Loading…
Reference in New Issue
Block a user