mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Add particle animation, glow
This is implemented by reusing and extending the TileAnimation code for the methods used by particles.
This commit is contained in:
parent
c5967f75f0
commit
7279f0b373
@ -4180,10 +4180,15 @@ The Biome API is still in an experimental phase and subject to change.
|
|||||||
-- ^ vertical: if true faces player using y axis only
|
-- ^ vertical: if true faces player using y axis only
|
||||||
texture = "image.png",
|
texture = "image.png",
|
||||||
-- ^ 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
|
||||||
|
animation = {Tile Animation definition},
|
||||||
|
-- ^ optional, specifies how to animate the particle texture
|
||||||
|
glow = 0
|
||||||
|
-- ^ optional, specify particle self-luminescence in darkness
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
### `ParticleSpawner` definition (`add_particlespawner`)
|
### `ParticleSpawner` definition (`add_particlespawner`)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -523,6 +523,43 @@ minetest.register_craft({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("experimental:tester_tool_2", {
|
||||||
|
description = "Tester Tool 2",
|
||||||
|
inventory_image = "experimental_tester_tool_1.png^[invert:g",
|
||||||
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
|
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
|
||||||
|
if pos == nil then return end
|
||||||
|
pos = vector.add(pos, {x=0, y=0.5, z=0})
|
||||||
|
local tex, anim
|
||||||
|
if math.random(0, 1) == 0 then
|
||||||
|
tex = "default_lava_source_animated.png"
|
||||||
|
anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5}
|
||||||
|
else
|
||||||
|
tex = "default_lava_flowing_animated.png"
|
||||||
|
anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.add_particle({
|
||||||
|
pos = pos,
|
||||||
|
velocity = {x=0, y=0, z=0},
|
||||||
|
acceleration = {x=0, y=0.04, z=0},
|
||||||
|
expirationtime = 6,
|
||||||
|
collisiondetection = true,
|
||||||
|
texture = tex,
|
||||||
|
animation = anim,
|
||||||
|
size = 4,
|
||||||
|
glow = math.random(0, 5),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = 'experimental:tester_tool_2',
|
||||||
|
recipe = {
|
||||||
|
{'group:crumbly','group:crumbly'},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
--[[minetest.register_on_joinplayer(function(player)
|
--[[minetest.register_on_joinplayer(function(player)
|
||||||
minetest.after(3, function()
|
minetest.after(3, function()
|
||||||
player:set_inventory_formspec("size[8,7.5]"..
|
player:set_inventory_formspec("size[8,7.5]"..
|
||||||
|
@ -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 "mapnode.h"
|
#include "mapnode.h"
|
||||||
|
#include "tileanimation.h"
|
||||||
|
|
||||||
struct MeshMakeData;
|
struct MeshMakeData;
|
||||||
class MapBlockMesh;
|
class MapBlockMesh;
|
||||||
@ -186,6 +187,8 @@ struct ClientEvent
|
|||||||
bool collision_removal;
|
bool collision_removal;
|
||||||
bool vertical;
|
bool vertical;
|
||||||
std::string *texture;
|
std::string *texture;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
|
u8 glow;
|
||||||
} spawn_particle;
|
} spawn_particle;
|
||||||
struct{
|
struct{
|
||||||
u16 amount;
|
u16 amount;
|
||||||
@ -206,6 +209,8 @@ struct ClientEvent
|
|||||||
bool vertical;
|
bool vertical;
|
||||||
std::string *texture;
|
std::string *texture;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
|
u8 glow;
|
||||||
} add_particlespawner;
|
} add_particlespawner;
|
||||||
struct{
|
struct{
|
||||||
u32 id;
|
u32 id;
|
||||||
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "network/clientopcodes.h"
|
#include "network/clientopcodes.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "util/srp.h"
|
#include "util/srp.h"
|
||||||
|
#include "tileanimation.h"
|
||||||
|
|
||||||
void Client::handleCommand_Deprecated(NetworkPacket* pkt)
|
void Client::handleCommand_Deprecated(NetworkPacket* pkt)
|
||||||
{
|
{
|
||||||
@ -896,9 +897,14 @@ 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;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
|
animation.type = TAT_NONE;
|
||||||
|
u8 glow = 0;
|
||||||
try {
|
try {
|
||||||
vertical = readU8(is);
|
vertical = readU8(is);
|
||||||
collision_removal = readU8(is);
|
collision_removal = readU8(is);
|
||||||
|
animation.deSerialize(is, m_proto_ver);
|
||||||
|
glow = readU8(is);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
ClientEvent event;
|
ClientEvent event;
|
||||||
@ -912,6 +918,8 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
|
|||||||
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.animation = animation;
|
||||||
|
event.spawn_particle.glow = glow;
|
||||||
|
|
||||||
m_client_event_queue.push(event);
|
m_client_event_queue.push(event);
|
||||||
}
|
}
|
||||||
@ -943,12 +951,20 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
|
|||||||
|
|
||||||
bool vertical = false;
|
bool vertical = false;
|
||||||
bool collision_removal = false;
|
bool collision_removal = false;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
|
animation.type = TAT_NONE;
|
||||||
|
u8 glow = 0;
|
||||||
u16 attached_id = 0;
|
u16 attached_id = 0;
|
||||||
try {
|
try {
|
||||||
*pkt >> vertical;
|
*pkt >> vertical;
|
||||||
*pkt >> collision_removal;
|
*pkt >> collision_removal;
|
||||||
*pkt >> attached_id;
|
*pkt >> attached_id;
|
||||||
|
|
||||||
|
// This is horrible but required (why are there two ways to deserialize pkts?)
|
||||||
|
std::string datastring(pkt->getRemainingString(), pkt->getRemainingBytes());
|
||||||
|
std::istringstream is(datastring, std::ios_base::binary);
|
||||||
|
animation.deSerialize(is, m_proto_ver);
|
||||||
|
glow = readU8(is);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
ClientEvent event;
|
ClientEvent event;
|
||||||
@ -971,6 +987,8 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
|
|||||||
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.animation = animation;
|
||||||
|
event.add_particlespawner.glow = glow;
|
||||||
|
|
||||||
m_client_event_queue.push(event);
|
m_client_event_queue.push(event);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ void NetworkPacket::putRawPacket(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
m_data = std::vector<u8>(&data[2], &data[2 + m_datasize]);
|
m_data = std::vector<u8>(&data[2], &data[2 + m_datasize]);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* NetworkPacket::getString(u32 from_offset)
|
const char* NetworkPacket::getString(u32 from_offset)
|
||||||
{
|
{
|
||||||
checkReadOffset(from_offset, 0);
|
checkReadOffset(from_offset, 0);
|
||||||
|
|
||||||
|
@ -41,12 +41,15 @@ public:
|
|||||||
u16 getPeerId() { return m_peer_id; }
|
u16 getPeerId() { return m_peer_id; }
|
||||||
u16 getCommand() { return m_command; }
|
u16 getCommand() { return m_command; }
|
||||||
const u32 getRemainingBytes() const { return m_datasize - m_read_offset; }
|
const u32 getRemainingBytes() const { return m_datasize - m_read_offset; }
|
||||||
|
const char* getRemainingString() { return getString(m_read_offset); }
|
||||||
|
|
||||||
// Returns a c-string without copying.
|
// Returns a c-string without copying.
|
||||||
// A better name for this would be getRawString()
|
// A better name for this would be getRawString()
|
||||||
char* getString(u32 from_offset);
|
const char* getString(u32 from_offset);
|
||||||
// major difference to putCString(): doesn't write len into the buffer
|
// major difference to putCString(): doesn't write len into the buffer
|
||||||
void putRawString(const char* src, u32 len);
|
void putRawString(const char* src, u32 len);
|
||||||
|
void putRawString(const std::string &src)
|
||||||
|
{ putRawString(src.c_str(), src.size()); }
|
||||||
|
|
||||||
NetworkPacket& operator>>(std::string& dst);
|
NetworkPacket& operator>>(std::string& dst);
|
||||||
NetworkPacket& operator<<(std::string src);
|
NetworkPacket& operator<<(std::string src);
|
||||||
|
@ -541,7 +541,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
|||||||
if (tile->material_flags & MATERIAL_FLAG_ANIMATION) {
|
if (tile->material_flags & MATERIAL_FLAG_ANIMATION) {
|
||||||
int frame_length_ms;
|
int frame_length_ms;
|
||||||
tiledef->animation.determineParams(tile->texture->getOriginalSize(),
|
tiledef->animation.determineParams(tile->texture->getOriginalSize(),
|
||||||
&frame_count, &frame_length_ms);
|
&frame_count, &frame_length_ms, NULL);
|
||||||
tile->animation_frame_count = frame_count;
|
tile->animation_frame_count = frame_count;
|
||||||
tile->animation_frame_length_ms = frame_length_ms;
|
tile->animation_frame_length_ms = frame_length_ms;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,9 @@ Particle::Particle(
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
v2f texpos,
|
v2f texpos,
|
||||||
v2f texsize
|
v2f texsize,
|
||||||
|
const struct TileAnimationParams &anim,
|
||||||
|
u8 glow
|
||||||
):
|
):
|
||||||
scene::ISceneNode(smgr->getRootSceneNode(), smgr)
|
scene::ISceneNode(smgr->getRootSceneNode(), smgr)
|
||||||
{
|
{
|
||||||
@ -71,7 +73,9 @@ Particle::Particle(
|
|||||||
m_material.setTexture(0, texture);
|
m_material.setTexture(0, texture);
|
||||||
m_texpos = texpos;
|
m_texpos = texpos;
|
||||||
m_texsize = texsize;
|
m_texsize = texsize;
|
||||||
|
m_animation = anim;
|
||||||
|
m_animation_frame = 0;
|
||||||
|
m_animation_time = 0.0;
|
||||||
|
|
||||||
// Particle related
|
// Particle related
|
||||||
m_pos = pos;
|
m_pos = pos;
|
||||||
@ -84,6 +88,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
|
||||||
@ -142,6 +147,18 @@ void Particle::step(float dtime)
|
|||||||
m_velocity += m_acceleration * dtime;
|
m_velocity += m_acceleration * dtime;
|
||||||
m_pos += m_velocity * dtime;
|
m_pos += m_velocity * dtime;
|
||||||
}
|
}
|
||||||
|
if (m_animation.type != TAT_NONE) {
|
||||||
|
m_animation_time += dtime;
|
||||||
|
int frame_length_i, frame_count;
|
||||||
|
m_animation.determineParams(
|
||||||
|
m_material.getTexture(0)->getSize(),
|
||||||
|
&frame_count, &frame_length_i, NULL);
|
||||||
|
float frame_length = frame_length_i / 1000.0;
|
||||||
|
while (m_animation_time > frame_length) {
|
||||||
|
m_animation_frame++;
|
||||||
|
m_animation_time -= frame_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update lighting
|
// Update lighting
|
||||||
updateLight();
|
updateLight();
|
||||||
@ -166,16 +183,32 @@ 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;
|
f32 tx0, tx1, ty0, ty1;
|
||||||
f32 tx1 = m_texpos.X + m_texsize.X;
|
|
||||||
f32 ty0 = m_texpos.Y;
|
if (m_animation.type != TAT_NONE) {
|
||||||
f32 ty1 = m_texpos.Y + m_texsize.Y;
|
const v2u32 texsize = m_material.getTexture(0)->getSize();
|
||||||
|
v2f texcoord, framesize_f;
|
||||||
|
v2u32 framesize;
|
||||||
|
texcoord = m_animation.getTextureCoords(texsize, m_animation_frame);
|
||||||
|
m_animation.determineParams(texsize, NULL, NULL, &framesize);
|
||||||
|
framesize_f = v2f(framesize.X / (float) texsize.X, framesize.Y / (float) texsize.Y);
|
||||||
|
|
||||||
|
tx0 = m_texpos.X + texcoord.X;
|
||||||
|
tx1 = m_texpos.X + texcoord.X + framesize_f.X * m_texsize.X;
|
||||||
|
ty0 = m_texpos.Y + texcoord.Y;
|
||||||
|
ty1 = m_texpos.Y + texcoord.Y + framesize_f.Y * m_texsize.Y;
|
||||||
|
} else {
|
||||||
|
tx0 = m_texpos.X;
|
||||||
|
tx1 = m_texpos.X + m_texsize.X;
|
||||||
|
ty0 = m_texpos.Y;
|
||||||
|
ty1 = m_texpos.Y + m_texsize.Y;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -210,7 +243,9 @@ 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, const struct TileAnimationParams &anim,
|
||||||
|
u8 glow,
|
||||||
|
ParticleManager *p_manager) :
|
||||||
m_particlemanager(p_manager)
|
m_particlemanager(p_manager)
|
||||||
{
|
{
|
||||||
m_gamedef = gamedef;
|
m_gamedef = gamedef;
|
||||||
@ -234,6 +269,8 @@ 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_animation = anim;
|
||||||
|
m_glow = glow;
|
||||||
|
|
||||||
for (u16 i = 0; i<=m_amount; i++)
|
for (u16 i = 0; i<=m_amount; i++)
|
||||||
{
|
{
|
||||||
@ -309,7 +346,9 @@ 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_animation,
|
||||||
|
m_glow);
|
||||||
m_particlemanager->addParticle(toadd);
|
m_particlemanager->addParticle(toadd);
|
||||||
}
|
}
|
||||||
i = m_spawntimes.erase(i);
|
i = m_spawntimes.erase(i);
|
||||||
@ -363,7 +402,9 @@ 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_animation,
|
||||||
|
m_glow);
|
||||||
m_particlemanager->addParticle(toadd);
|
m_particlemanager->addParticle(toadd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,6 +535,8 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client,
|
|||||||
event->add_particlespawner.vertical,
|
event->add_particlespawner.vertical,
|
||||||
texture,
|
texture,
|
||||||
event->add_particlespawner.id,
|
event->add_particlespawner.id,
|
||||||
|
event->add_particlespawner.animation,
|
||||||
|
event->add_particlespawner.glow,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
/* delete allocated content of event */
|
/* delete allocated content of event */
|
||||||
@ -529,13 +572,16 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client,
|
|||||||
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),
|
||||||
|
event->spawn_particle.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;
|
||||||
}
|
}
|
||||||
@ -564,6 +610,8 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
|
|||||||
// Texture
|
// Texture
|
||||||
u8 texid = myrand_range(0, 5);
|
u8 texid = myrand_range(0, 5);
|
||||||
video::ITexture *texture;
|
video::ITexture *texture;
|
||||||
|
struct TileAnimationParams anim;
|
||||||
|
anim.type = TAT_NONE;
|
||||||
|
|
||||||
// Only use first frame of animated texture
|
// Only use first frame of animated texture
|
||||||
if (tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION)
|
if (tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION)
|
||||||
@ -605,7 +653,9 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
|
|||||||
false,
|
false,
|
||||||
texture,
|
texture,
|
||||||
texpos,
|
texpos,
|
||||||
texsize);
|
texsize,
|
||||||
|
anim,
|
||||||
|
0);
|
||||||
|
|
||||||
addParticle(toadd);
|
addParticle(toadd);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "client/tile.h"
|
#include "client/tile.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
|
#include "tileanimation.h"
|
||||||
|
|
||||||
struct ClientEvent;
|
struct ClientEvent;
|
||||||
class ParticleManager;
|
class ParticleManager;
|
||||||
@ -50,7 +51,9 @@ class Particle : public scene::ISceneNode
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
v2f texpos,
|
v2f texpos,
|
||||||
v2f texsize
|
v2f texsize,
|
||||||
|
const struct TileAnimationParams &anim,
|
||||||
|
u8 glow
|
||||||
);
|
);
|
||||||
~Particle();
|
~Particle();
|
||||||
|
|
||||||
@ -102,6 +105,10 @@ private:
|
|||||||
bool m_collision_removal;
|
bool m_collision_removal;
|
||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
v3s16 m_camera_offset;
|
v3s16 m_camera_offset;
|
||||||
|
struct TileAnimationParams m_animation;
|
||||||
|
float m_animation_time;
|
||||||
|
int m_animation_frame;
|
||||||
|
u8 m_glow;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParticleSpawner
|
class ParticleSpawner
|
||||||
@ -123,6 +130,7 @@ class ParticleSpawner
|
|||||||
bool vertical,
|
bool vertical,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
u32 id,
|
u32 id,
|
||||||
|
const struct TileAnimationParams &anim, u8 glow,
|
||||||
ParticleManager* p_manager);
|
ParticleManager* p_manager);
|
||||||
|
|
||||||
~ParticleSpawner();
|
~ParticleSpawner();
|
||||||
@ -156,6 +164,8 @@ class ParticleSpawner
|
|||||||
bool m_collision_removal;
|
bool m_collision_removal;
|
||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
u16 m_attached_id;
|
u16 m_attached_id;
|
||||||
|
struct TileAnimationParams m_animation;
|
||||||
|
u8 m_glow;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,7 +322,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
|
|||||||
}
|
}
|
||||||
else if(lua_istable(L, index))
|
else if(lua_istable(L, index))
|
||||||
{
|
{
|
||||||
// {name="default_lava.png", animation={}}
|
// name="default_lava.png"
|
||||||
tiledef.name = "";
|
tiledef.name = "";
|
||||||
getstringfield(L, index, "name", tiledef.name);
|
getstringfield(L, index, "name", tiledef.name);
|
||||||
getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
|
getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
|
||||||
@ -334,28 +334,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
|
|||||||
L, index, "tileable_vertical", default_tiling);
|
L, index, "tileable_vertical", default_tiling);
|
||||||
// animation = {}
|
// animation = {}
|
||||||
lua_getfield(L, index, "animation");
|
lua_getfield(L, index, "animation");
|
||||||
if(lua_istable(L, -1)){
|
tiledef.animation = read_animation_definition(L, -1);
|
||||||
tiledef.animation.type = (TileAnimationType)
|
|
||||||
getenumfield(L, -1, "type", es_TileAnimationType,
|
|
||||||
TAT_NONE);
|
|
||||||
if (tiledef.animation.type == TAT_VERTICAL_FRAMES) {
|
|
||||||
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
|
||||||
tiledef.animation.vertical_frames.aspect_w =
|
|
||||||
getintfield_default(L, -1, "aspect_w", 16);
|
|
||||||
tiledef.animation.vertical_frames.aspect_h =
|
|
||||||
getintfield_default(L, -1, "aspect_h", 16);
|
|
||||||
tiledef.animation.vertical_frames.length =
|
|
||||||
getfloatfield_default(L, -1, "length", 1.0);
|
|
||||||
} else if (tiledef.animation.type == TAT_SHEET_2D) {
|
|
||||||
// {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
|
|
||||||
getintfield(L, -1, "frames_w",
|
|
||||||
tiledef.animation.sheet_2d.frames_w);
|
|
||||||
getintfield(L, -1, "frames_h",
|
|
||||||
tiledef.animation.sheet_2d.frames_h);
|
|
||||||
getfloatfield(L, -1, "frame_length",
|
|
||||||
tiledef.animation.sheet_2d.frame_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,6 +904,41 @@ void read_inventory_list(lua_State *L, int tableindex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
struct TileAnimationParams read_animation_definition(lua_State *L, int index)
|
||||||
|
{
|
||||||
|
if(index < 0)
|
||||||
|
index = lua_gettop(L) + 1 + index;
|
||||||
|
|
||||||
|
struct TileAnimationParams anim;
|
||||||
|
anim.type = TAT_NONE;
|
||||||
|
if (!lua_istable(L, index))
|
||||||
|
return anim;
|
||||||
|
|
||||||
|
anim.type = (TileAnimationType)
|
||||||
|
getenumfield(L, index, "type", es_TileAnimationType,
|
||||||
|
TAT_NONE);
|
||||||
|
if (anim.type == TAT_VERTICAL_FRAMES) {
|
||||||
|
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
||||||
|
anim.vertical_frames.aspect_w =
|
||||||
|
getintfield_default(L, index, "aspect_w", 16);
|
||||||
|
anim.vertical_frames.aspect_h =
|
||||||
|
getintfield_default(L, index, "aspect_h", 16);
|
||||||
|
anim.vertical_frames.length =
|
||||||
|
getfloatfield_default(L, index, "length", 1.0);
|
||||||
|
} else if (anim.type == TAT_SHEET_2D) {
|
||||||
|
// {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
|
||||||
|
getintfield(L, index, "frames_w",
|
||||||
|
anim.sheet_2d.frames_w);
|
||||||
|
getintfield(L, index, "frames_h",
|
||||||
|
anim.sheet_2d.frames_h);
|
||||||
|
getfloatfield(L, index, "frame_length",
|
||||||
|
anim.sheet_2d.frame_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
ToolCapabilities read_tool_capabilities(
|
ToolCapabilities read_tool_capabilities(
|
||||||
lua_State *L, int table)
|
lua_State *L, int table)
|
||||||
|
@ -79,6 +79,7 @@ void push_hit_params (lua_State *L,
|
|||||||
|
|
||||||
ItemStack read_item (lua_State *L, int index, Server *srv);
|
ItemStack read_item (lua_State *L, int index, Server *srv);
|
||||||
|
|
||||||
|
struct TileAnimationParams read_animation_definition(lua_State *L, int index);
|
||||||
|
|
||||||
ToolCapabilities read_tool_capabilities (lua_State *L, int table);
|
ToolCapabilities read_tool_capabilities (lua_State *L, int table);
|
||||||
void push_tool_capabilities (lua_State *L,
|
void push_tool_capabilities (lua_State *L,
|
||||||
|
@ -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,8 @@ 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"
|
||||||
|
// animation = TileAnimation definition
|
||||||
|
// glow = num
|
||||||
int ModApiParticles::l_add_particle(lua_State *L)
|
int ModApiParticles::l_add_particle(lua_State *L)
|
||||||
{
|
{
|
||||||
MAP_LOCK_REQUIRED;
|
MAP_LOCK_REQUIRED;
|
||||||
@ -47,10 +50,13 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
|
|
||||||
bool collisiondetection, vertical, collision_removal;
|
bool collisiondetection, vertical, collision_removal;
|
||||||
collisiondetection = vertical = collision_removal = false;
|
collisiondetection = vertical = collision_removal = false;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
|
|
||||||
std::string texture = "";
|
std::string texture = "";
|
||||||
std::string playername = "";
|
std::string playername = "";
|
||||||
|
|
||||||
|
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");
|
||||||
@ -101,11 +107,18 @@ int ModApiParticles::l_add_particle(lua_State *L)
|
|||||||
collision_removal = getboolfield_default(L, 1,
|
collision_removal = getboolfield_default(L, 1,
|
||||||
"collision_removal", collision_removal);
|
"collision_removal", collision_removal);
|
||||||
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
vertical = getboolfield_default(L, 1, "vertical", vertical);
|
||||||
|
|
||||||
|
lua_getfield(L, 1, "animation");
|
||||||
|
animation = read_animation_definition(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
texture = getstringfield_default(L, 1, "texture", "");
|
texture = getstringfield_default(L, 1, "texture", "");
|
||||||
playername = getstringfield_default(L, 1, "playername", "");
|
playername = getstringfield_default(L, 1, "playername", "");
|
||||||
|
|
||||||
|
glow = getintfield_default(L, 1, "glow", 0);
|
||||||
}
|
}
|
||||||
getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
|
getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size,
|
||||||
collisiondetection, collision_removal, vertical, texture);
|
collisiondetection, collision_removal, vertical, texture, animation, glow);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +140,8 @@ 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"
|
||||||
|
// animation = TileAnimation definition
|
||||||
|
// glow = num
|
||||||
int ModApiParticles::l_add_particlespawner(lua_State *L)
|
int ModApiParticles::l_add_particlespawner(lua_State *L)
|
||||||
{
|
{
|
||||||
MAP_LOCK_REQUIRED;
|
MAP_LOCK_REQUIRED;
|
||||||
@ -139,9 +154,11 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
time= minexptime= maxexptime= minsize= maxsize= 1;
|
time= minexptime= maxexptime= minsize= maxsize= 1;
|
||||||
bool collisiondetection, vertical, collision_removal;
|
bool collisiondetection, vertical, collision_removal;
|
||||||
collisiondetection = vertical = collision_removal = false;
|
collisiondetection = vertical = collision_removal = false;
|
||||||
|
struct TileAnimationParams animation;
|
||||||
ServerActiveObject *attached = NULL;
|
ServerActiveObject *attached = NULL;
|
||||||
std::string texture = "";
|
std::string texture = "";
|
||||||
std::string playername = "";
|
std::string playername = "";
|
||||||
|
u8 glow = 0;
|
||||||
|
|
||||||
if (lua_gettop(L) > 1) //deprecated
|
if (lua_gettop(L) > 1) //deprecated
|
||||||
{
|
{
|
||||||
@ -201,6 +218,10 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
collision_removal = getboolfield_default(L, 1,
|
collision_removal = getboolfield_default(L, 1,
|
||||||
"collision_removal", collision_removal);
|
"collision_removal", collision_removal);
|
||||||
|
|
||||||
|
lua_getfield(L, 1, "animation");
|
||||||
|
animation = read_animation_definition(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, 1, "attached");
|
lua_getfield(L, 1, "attached");
|
||||||
if (!lua_isnil(L, -1)) {
|
if (!lua_isnil(L, -1)) {
|
||||||
ObjectRef *ref = ObjectRef::checkobject(L, -1);
|
ObjectRef *ref = ObjectRef::checkobject(L, -1);
|
||||||
@ -211,6 +232,7 @@ 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", "");
|
||||||
|
glow = getintfield_default(L, 1, "glow", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 id = getServer(L)->addParticleSpawner(amount, time,
|
u32 id = getServer(L)->addParticleSpawner(amount, time,
|
||||||
@ -223,7 +245,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
|
|||||||
collision_removal,
|
collision_removal,
|
||||||
attached,
|
attached,
|
||||||
vertical,
|
vertical,
|
||||||
texture, playername);
|
texture, playername,
|
||||||
|
animation, glow);
|
||||||
lua_pushnumber(L, id);
|
lua_pushnumber(L, id);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1662,12 +1662,28 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spawns a particle on peer with peer_id
|
// Spawns a particle on peer with peer_id
|
||||||
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
|
void Server::SendSpawnParticle(u16 peer_id, u16 protocol_version,
|
||||||
|
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,
|
||||||
|
const struct TileAnimationParams &animation, u8 glow)
|
||||||
{
|
{
|
||||||
DSTACK(FUNCTION_NAME);
|
DSTACK(FUNCTION_NAME);
|
||||||
|
if (peer_id == PEER_ID_INEXISTENT) {
|
||||||
|
// This sucks and should be replaced by a better solution in a refactor:
|
||||||
|
std::vector<u16> clients = m_clients.getClientIDs();
|
||||||
|
for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
|
||||||
|
RemotePlayer *player = m_env->getPlayer(*i);
|
||||||
|
if (!player)
|
||||||
|
continue;
|
||||||
|
SendSpawnParticle(*i, player->protocol_version,
|
||||||
|
pos, velocity, acceleration,
|
||||||
|
expirationtime, size, collisiondetection,
|
||||||
|
collision_removal, vertical, texture, animation, glow);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id);
|
NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id);
|
||||||
|
|
||||||
@ -1676,22 +1692,39 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
|
|||||||
pkt.putLongString(texture);
|
pkt.putLongString(texture);
|
||||||
pkt << vertical;
|
pkt << vertical;
|
||||||
pkt << collision_removal;
|
pkt << collision_removal;
|
||||||
|
// This is horrible but required (why are there two ways to serialize pkts?)
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
animation.serialize(os, protocol_version);
|
||||||
|
pkt.putRawString(os.str());
|
||||||
|
pkt << glow;
|
||||||
|
|
||||||
if (peer_id != PEER_ID_INEXISTENT) {
|
Send(&pkt);
|
||||||
Send(&pkt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_clients.sendToAll(0, &pkt, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a ParticleSpawner on peer with peer_id
|
// Adds a ParticleSpawner on peer with peer_id
|
||||||
void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
|
void Server::SendAddParticleSpawner(u16 peer_id, u16 protocol_version,
|
||||||
|
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,
|
||||||
|
const struct TileAnimationParams &animation, u8 glow)
|
||||||
{
|
{
|
||||||
DSTACK(FUNCTION_NAME);
|
DSTACK(FUNCTION_NAME);
|
||||||
|
if (peer_id == PEER_ID_INEXISTENT) {
|
||||||
|
// This sucks and should be replaced:
|
||||||
|
std::vector<u16> clients = m_clients.getClientIDs();
|
||||||
|
for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
|
||||||
|
RemotePlayer *player = m_env->getPlayer(*i);
|
||||||
|
if (!player)
|
||||||
|
continue;
|
||||||
|
SendAddParticleSpawner(*i, player->protocol_version,
|
||||||
|
amount, spawntime, minpos, maxpos,
|
||||||
|
minvel, maxvel, minacc, maxacc, minexptime, maxexptime,
|
||||||
|
minsize, maxsize, collisiondetection, collision_removal,
|
||||||
|
attached_id, vertical, texture, id, animation, glow);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 0, peer_id);
|
NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 0, peer_id);
|
||||||
|
|
||||||
@ -1704,13 +1737,13 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
|
|||||||
pkt << id << vertical;
|
pkt << id << vertical;
|
||||||
pkt << collision_removal;
|
pkt << collision_removal;
|
||||||
pkt << attached_id;
|
pkt << attached_id;
|
||||||
|
// This is horrible but required
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
animation.serialize(os, protocol_version);
|
||||||
|
pkt.putRawString(os.str());
|
||||||
|
pkt << glow;
|
||||||
|
|
||||||
if (peer_id != PEER_ID_INEXISTENT) {
|
Send(&pkt);
|
||||||
Send(&pkt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_clients.sendToAll(0, &pkt, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendDeleteParticleSpawner(u16 peer_id, u32 id)
|
void Server::SendDeleteParticleSpawner(u16 peer_id, u32 id)
|
||||||
@ -3165,23 +3198,25 @@ 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,
|
||||||
|
const struct TileAnimationParams &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)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u16 peer_id = PEER_ID_INEXISTENT;
|
u16 peer_id = PEER_ID_INEXISTENT, proto_ver = 0;
|
||||||
if (playername != "") {
|
if (playername != "") {
|
||||||
RemotePlayer *player = m_env->getPlayer(playername.c_str());
|
RemotePlayer *player = m_env->getPlayer(playername.c_str());
|
||||||
if (!player)
|
if (!player)
|
||||||
return;
|
return;
|
||||||
peer_id = player->peer_id;
|
peer_id = player->peer_id;
|
||||||
|
proto_ver = player->protocol_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSpawnParticle(peer_id, pos, velocity, acceleration,
|
SendSpawnParticle(peer_id, proto_ver, pos, velocity, acceleration,
|
||||||
expirationtime, size, collisiondetection,
|
expirationtime, size, collisiondetection,
|
||||||
collision_removal, vertical, texture);
|
collision_removal, vertical, texture, animation, glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
||||||
@ -3189,18 +3224,20 @@ 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, const struct TileAnimationParams &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)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
u16 peer_id = PEER_ID_INEXISTENT;
|
u16 peer_id = PEER_ID_INEXISTENT, proto_ver = 0;
|
||||||
if (playername != "") {
|
if (playername != "") {
|
||||||
RemotePlayer *player = m_env->getPlayer(playername.c_str());
|
RemotePlayer *player = m_env->getPlayer(playername.c_str());
|
||||||
if (!player)
|
if (!player)
|
||||||
return -1;
|
return -1;
|
||||||
peer_id = player->peer_id;
|
peer_id = player->peer_id;
|
||||||
|
proto_ver = player->protocol_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 attached_id = attached ? attached->getId() : 0;
|
u16 attached_id = attached ? attached->getId() : 0;
|
||||||
@ -3211,11 +3248,11 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime,
|
|||||||
else
|
else
|
||||||
id = m_env->addParticleSpawner(spawntime, attached_id);
|
id = m_env->addParticleSpawner(spawntime, attached_id);
|
||||||
|
|
||||||
SendAddParticleSpawner(peer_id, amount, spawntime,
|
SendAddParticleSpawner(peer_id, proto_ver, amount, 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, animation, glow);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
18
src/server.h
18
src/server.h
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mods.h"
|
#include "mods.h"
|
||||||
#include "inventorymanager.h"
|
#include "inventorymanager.h"
|
||||||
#include "subgame.h"
|
#include "subgame.h"
|
||||||
|
#include "tileanimation.h" // struct TileAnimationParams
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
@ -252,7 +253,8 @@ 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,
|
||||||
|
const struct TileAnimationParams &animation, u8 glow);
|
||||||
|
|
||||||
u32 addParticleSpawner(u16 amount, float spawntime,
|
u32 addParticleSpawner(u16 amount, float spawntime,
|
||||||
v3f minpos, v3f maxpos,
|
v3f minpos, v3f maxpos,
|
||||||
@ -263,7 +265,8 @@ 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, const struct TileAnimationParams &animation,
|
||||||
|
u8 glow);
|
||||||
|
|
||||||
void deleteParticleSpawner(const std::string &playername, u32 id);
|
void deleteParticleSpawner(const std::string &playername, u32 id);
|
||||||
|
|
||||||
@ -428,7 +431,8 @@ private:
|
|||||||
void sendDetachedInventories(u16 peer_id);
|
void sendDetachedInventories(u16 peer_id);
|
||||||
|
|
||||||
// Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
|
// Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
|
||||||
void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
|
void SendAddParticleSpawner(u16 peer_id, u16 protocol_version,
|
||||||
|
u16 amount, float spawntime,
|
||||||
v3f minpos, v3f maxpos,
|
v3f minpos, v3f maxpos,
|
||||||
v3f minvel, v3f maxvel,
|
v3f minvel, v3f maxvel,
|
||||||
v3f minacc, v3f maxacc,
|
v3f minacc, v3f maxacc,
|
||||||
@ -436,16 +440,18 @@ 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,
|
||||||
|
const struct TileAnimationParams &animation, u8 glow);
|
||||||
|
|
||||||
void SendDeleteParticleSpawner(u16 peer_id, u32 id);
|
void SendDeleteParticleSpawner(u16 peer_id, u32 id);
|
||||||
|
|
||||||
// Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all)
|
// Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all)
|
||||||
void SendSpawnParticle(u16 peer_id,
|
void SendSpawnParticle(u16 peer_id, u16 protocol_version,
|
||||||
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,
|
||||||
|
const struct TileAnimationParams &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);
|
||||||
|
@ -69,7 +69,8 @@ void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const
|
void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count,
|
||||||
|
int *frame_length_ms, v2u32 *frame_size) const
|
||||||
{
|
{
|
||||||
if (type == TAT_VERTICAL_FRAMES) {
|
if (type == TAT_VERTICAL_FRAMES) {
|
||||||
int frame_height = (float)texture_size.X /
|
int frame_height = (float)texture_size.X /
|
||||||
@ -80,15 +81,17 @@ void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count,
|
|||||||
*frame_count = _frame_count;
|
*frame_count = _frame_count;
|
||||||
if (frame_length_ms)
|
if (frame_length_ms)
|
||||||
*frame_length_ms = 1000.0 * vertical_frames.length / _frame_count;
|
*frame_length_ms = 1000.0 * vertical_frames.length / _frame_count;
|
||||||
|
if (frame_size)
|
||||||
|
*frame_size = v2u32(texture_size.X, frame_height);
|
||||||
} else if (type == TAT_SHEET_2D) {
|
} else if (type == TAT_SHEET_2D) {
|
||||||
if (frame_count)
|
if (frame_count)
|
||||||
*frame_count = sheet_2d.frames_w * sheet_2d.frames_h;
|
*frame_count = sheet_2d.frames_w * sheet_2d.frames_h;
|
||||||
if (frame_length_ms)
|
if (frame_length_ms)
|
||||||
*frame_length_ms = 1000 * sheet_2d.frame_length;
|
*frame_length_ms = 1000 * sheet_2d.frame_length;
|
||||||
} else { // TAT_NONE
|
if (frame_size)
|
||||||
*frame_count = 1;
|
*frame_size = v2u32(texture_size.X / sheet_2d.frames_w, texture_size.Y / sheet_2d.frames_h);
|
||||||
*frame_length_ms = 1000;
|
|
||||||
}
|
}
|
||||||
|
// caller should check for TAT_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const
|
void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const
|
||||||
@ -97,7 +100,7 @@ void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size
|
|||||||
return;
|
return;
|
||||||
if (type == TAT_VERTICAL_FRAMES) {
|
if (type == TAT_VERTICAL_FRAMES) {
|
||||||
int frame_count;
|
int frame_count;
|
||||||
determineParams(texture_size, &frame_count, NULL);
|
determineParams(texture_size, &frame_count, NULL, NULL);
|
||||||
os << "^[verticalframe:" << frame_count << ":" << frame;
|
os << "^[verticalframe:" << frame_count << ":" << frame;
|
||||||
} else if (type == TAT_SHEET_2D) {
|
} else if (type == TAT_SHEET_2D) {
|
||||||
int q, r;
|
int q, r;
|
||||||
@ -107,3 +110,22 @@ void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size
|
|||||||
<< ":" << r << "," << q;
|
<< ":" << r << "," << q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v2f TileAnimationParams::getTextureCoords(v2u32 texture_size, int frame) const
|
||||||
|
{
|
||||||
|
v2u32 ret(0, 0);
|
||||||
|
if (type == TAT_VERTICAL_FRAMES) {
|
||||||
|
int frame_height = (float)texture_size.X /
|
||||||
|
(float)vertical_frames.aspect_w *
|
||||||
|
(float)vertical_frames.aspect_h;
|
||||||
|
ret = v2u32(0, frame_height * frame);
|
||||||
|
} else if (type == TAT_SHEET_2D) {
|
||||||
|
v2u32 frame_size;
|
||||||
|
determineParams(texture_size, NULL, NULL, &frame_size);
|
||||||
|
int q, r;
|
||||||
|
q = frame / sheet_2d.frames_w;
|
||||||
|
r = frame % sheet_2d.frames_w;
|
||||||
|
ret = v2u32(r * frame_size.X, q * frame_size.Y);
|
||||||
|
}
|
||||||
|
return v2f(ret.X / (float) texture_size.X, ret.Y / (float) texture_size.Y);
|
||||||
|
}
|
||||||
|
@ -48,8 +48,10 @@ struct TileAnimationParams {
|
|||||||
|
|
||||||
void serialize(std::ostream &os, u16 protocol_version) const;
|
void serialize(std::ostream &os, u16 protocol_version) const;
|
||||||
void deSerialize(std::istream &is, u16 protocol_version);
|
void deSerialize(std::istream &is, u16 protocol_version);
|
||||||
void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const;
|
void determineParams(v2u32 texture_size, int *frame_count,
|
||||||
|
int *frame_length_ms, v2u32 *frame_size) const;
|
||||||
void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const;
|
void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const;
|
||||||
|
v2f getTextureCoords(v2u32 texture_size, int frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user