Skip to content
Snippets Groups Projects
Commit 2bd58e0c authored by dg's avatar dg
Browse files

PARTICLE EMITTERS !!!

git-svn-id: http://svn.net-core.org/repos/t-engine4@212 51575b47-30f0-44d4-a5cc-537603b46e54
parent 5f1f26b7
No related branches found
No related tags found
No related merge requests found
......@@ -71,6 +71,7 @@ function _M:init(w, h)
self.seens = {}
self.remembers = {}
self.effects = {}
self.particles = {}
for i = 0, w * h - 1 do self.map[i] = {} end
self:loaded()
......@@ -82,10 +83,13 @@ function _M:save()
_fov_lite = true,
_fov = true,
_map = true,
surface = true
surface = true,
particle = true,
})
end
function _M:loaded()
self.particle = core.display.loadImage("/data/gfx/particle.png"):glTexture()
self._map = core.map.newMap(self.w, self.h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight, self.tile_w, self.tile_h, self.multidisplay)
local mapseen = function(t, x, y, v)
......@@ -267,6 +271,7 @@ function _M:display()
end end
end
self:displayParticles()
self:displayEffects()
-- If nothing changed, return the same surface as before
......@@ -528,3 +533,53 @@ function _M:removeObject(x, y, i)
return true
end
-------------------------------------------------------------
-------------------------------------------------------------
-- Particle projector
-------------------------------------------------------------
-------------------------------------------------------------
_M.particles_def = {}
--- Add a new particle emitter
function _M:particleEmitter(x, y, radius, def, fct, max)
if type(def) == "string" then
if _M.particles_def[def] then
def, fct, max = _M.particles_def[def][1], _M.particles_def[def][2], _M.particles_def[def][3]
else
print("[PARTICLE] Loading from /data/gfx/particles/"..def..".lua")
local f = loadfile("/data/gfx/particles/"..def..".lua")
setfenv(f, {})
def, fct, max = f()
max = max or 1000
_M.particles_def[def] = { def, fct, max }
end
end
local e =
{
x = x, y = y, radius = radius or 1,
ps = core.particles.newEmitter(max or 1000, def, self.particle),
update = fct,
}
self.particles[#self.particles+1] = e
end
--- Display the particle emiters, called by self:display()
function _M:displayParticles()
for i = #self.particles, 1, -1 do
local e = self.particles[i]
local alive = false
alive = not e.update(e)
-- Dont bother with obviously out of screen stuff
if alive and e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
alive = e.ps:toScreen(self.display_x + (e.x - self.mx + 0.5) * self.tile_w, self.display_y + (e.y - self.my + 0.5) * self.tile_h)
end
if not alive then
table.remove(self.particles, i)
end
end
end
return {
base = 1000,
angle = { 0, 360 }, anglev = { 2000, 4000 }, anglea = { 200, 600 },
life = { 5, 10 },
size = { 3, 6 }, sizev = {0, 0}, sizea = {0, 0},
r = {200, 255}, rv = {0, 0}, ra = {0, 0},
g = {120, 170}, gv = {0, 0}, ga = {0, 0},
b = {0, 0}, bv = {0, 0}, ba = {0, 0},
a = {255, 255}, av = {0, 0}, aa = {0, 0},
}, function(self)
self.nb = (self.nb or 0) + 1
if self.nb < 4 then
self.ps:emit(100)
end
end
return {
base = 1000,
angle = { 0, 360 }, anglev = { 2000, 4000 }, anglea = { 200, 600 },
life = { 5, 10 },
size = { 3, 6 }, sizev = {0, 0}, sizea = {0, 0},
r = {0, 0}, rv = {0, 0}, ra = {0, 0},
g = {120, 170}, gv = {0, 0}, ga = {0, 0},
b = {200, 255}, bv = {0, 0}, ba = {10, 50},
a = {255, 255}, av = {0, 0}, aa = {0, 0},
}, function(self)
self.nb = (self.nb or 0) + 1
if self.nb < 4 then
self.ps:emit(100)
end
end
......@@ -13,6 +13,7 @@ newTalent{
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t)))
game.level.map:particleEmitter(x, y, 1, "flame")
return true
end,
require = { stat = { mag=10 }, },
......
......@@ -29,6 +29,7 @@ newTalent{
if not x or not y then return nil end
self:project(tg, x, y, DamageType.COLD, self:spellCrit(12 + self:combatSpellpower(0.25) * self:getTalentLevel(t)))
self:project(tg, x, y, DamageType.FREEZE, 3 + math.floor(self:getTalentLevel(t) / 3))
game.level.map:particleEmitter(x, y, 1, "freeze")
return true
end,
require = { stat = { mag=14 }, },
......
......@@ -23,45 +23,16 @@ function _M:run()
-- Ok everything is good to go, activate the game in the engine!
self:setCurrent()
self.particle = core.display.loadImage("/data/gfx/particle.png")
self.gl = self.particle:glTexture()
self.test = core.particles.newEmitter(1000, {
base = 1000,
angle = { 10, 60 }, anglev = { 3, 3000 }, anglea = { 1, 1000 },
life = { 30, 30 },
size = { 3, 50 }, sizev = {0, 0}, sizea = {0, 0},
-- x_min = 0, x_max = 0,
-- y_min = 0, y_max = 0,
r = {0, 0}, rv = {0, 0}, ra = {0, 0},
g = {0, 0}, gv = {0, 0}, ga = {0, 0},
b = {255, 255}, bv = {0, 0}, ba = {10, 50},
a = {0, 0}, av = {0, 0}, aa = {0, 0},
}, self.gl)
self.cnt = 0
end
function _M:display()
--[[
if self.background then
local bw, bh = self.background:getSize()
self.background:toScreen((self.w - bw) / 2, (self.h - bh) / 2)
end
]]
self.step:display()
self.step:toScreen(self.step.display_x, self.step.display_y)
engine.Game.display(self)
self.cnt = self.cnt + 1
-- if self.cnt < 10 then
self.test:emit(100)
-- end
self.test:toScreen(600, 600)
end
--- Skip to a module directly ?
......
......@@ -11,26 +11,24 @@
#define rng(x, y) (x + rand_div(1 + y - x))
static bool getfield(const char *key, float *min, float *max)
static void getfield(lua_State *L, const char *key, int *min, int *max)
{
double result;
lua_pushstring(L, key);
lua_gettable(L, -2);
lua_pushnumber(L, 1);
lua_gettable(L, -2);
*min = (float)lua_tonumber(L, -1);
*min = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
lua_pushnumber(L, 2);
lua_gettable(L, -2);
*max = (float)lua_tonumber(L, -1);
*max = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
printf("%s :: %f %f\n", key, (float)*min, (float)*max);
printf("%s :: %d %d\n", key, (int)*min, (int)*max);
lua_pop(L, 1);
return result;
}
static int particles_new(lua_State *L)
......@@ -49,6 +47,8 @@ static int particles_new(lua_State *L)
ps->particles = calloc(nb, sizeof(particle_type));
printf("Making particle emitter with %d particles\n", ps->nb);
// Grab all parameters
lua_rawgeti(L, LUA_REGISTRYINDEX, p_ref);
......@@ -57,27 +57,31 @@ static int particles_new(lua_State *L)
ps->base = (float)lua_tonumber(L, -1);
lua_pop(L, 1);
getfield("life", &(ps->life_min), &(ps->life_max));
getfield(L, "life", &(ps->life_min), &(ps->life_max));
getfield(L, "angle", &(ps->angle_min), &(ps->angle_max));
getfield(L, "anglev", &(ps->anglev_min), &(ps->anglev_max));
getfield(L, "anglea", &(ps->anglea_min), &(ps->anglea_max));
getfield("size", &(ps->size_min), &(ps->size_max));
getfield("sizev", &(ps->sizev_min), &(ps->sizev_max));
getfield("sizea", &(ps->sizea_min), &(ps->sizea_max));
getfield(L, "size", &(ps->size_min), &(ps->size_max));
getfield(L, "sizev", &(ps->sizev_min), &(ps->sizev_max));
getfield(L, "sizea", &(ps->sizea_min), &(ps->sizea_max));
getfield("r", &(ps->r_min), &(ps->r_max));
getfield("rv", &(ps->rv_min), &(ps->rv_max));
getfield("ra", &(ps->ra_min), &(ps->ra_max));
getfield(L, "r", &(ps->r_min), &(ps->r_max));
getfield(L, "rv", &(ps->rv_min), &(ps->rv_max));
getfield(L, "ra", &(ps->ra_min), &(ps->ra_max));
getfield("g", &(ps->g_min), &(ps->g_max));
getfield("gv", &(ps->gv_min), &(ps->gv_max));
getfield("ga", &(ps->ga_min), &(ps->ga_max));
getfield(L, "g", &(ps->g_min), &(ps->g_max));
getfield(L, "gv", &(ps->gv_min), &(ps->gv_max));
getfield(L, "ga", &(ps->ga_min), &(ps->ga_max));
getfield("b", &(ps->b_min), &(ps->b_max));
getfield("bv", &(ps->bv_min), &(ps->bv_max));
getfield("ba", &(ps->ba_min), &(ps->ba_max));
getfield(L, "b", &(ps->b_min), &(ps->b_max));
getfield(L, "bv", &(ps->bv_min), &(ps->bv_max));
getfield(L, "ba", &(ps->ba_min), &(ps->ba_max));
getfield("a", &(ps->a_min), &(ps->a_max));
getfield("av", &(ps->av_min), &(ps->av_max));
getfield("aa", &(ps->aa_min), &(ps->aa_max));
getfield(L, "a", &(ps->a_min), &(ps->a_max));
getfield(L, "av", &(ps->av_min), &(ps->av_max));
getfield(L, "aa", &(ps->aa_min), &(ps->aa_max));
lua_pop(L, 1);
luaL_unref(L, LUA_REGISTRYINDEX, p_ref);
......@@ -115,27 +119,27 @@ static int particles_emit(lua_State *L)
p->x = p->y = 0;
float angle = rng(0, 360) / (2 * M_PI);
float v = rng(1, 100) / 100.0f;
p->xa = cos(angle) * v;
p->ya = sin(angle) * v;
p->xv = cos(angle) * rng(1, 100) / 100.0f * 3;
p->yv = sin(angle) * rng(1, 100) / 100.0f * 3;
printf("%f %f : %d\n", ps->b_min, ps->b_max, rng((int)ps->r_min, (int)ps->r_max));
p->r = rng((int)ps->r_min, (int)ps->r_max) / 255.0f;
p->g = rng((int)ps->g_min, (int)ps->g_max) / 255.0f;
p->b = rng((int)ps->b_min, (int)ps->b_max) / 255.0f;
p->a = rng((int)ps->a_min, (int)ps->a_max) / 255.0f;
p->rv = 0;
p->gv = 0;
p->bv = 0;
p->av = -0.01 * rng(1, 5);
p->ra = 0;
p->ga = 0;
p->ba = 0;
p->aa = 0;
float angle = rng(ps->angle_min, ps->angle_max) * M_PI / 180;
float v = rng(ps->anglev_min, ps->anglev_max) / ps->base;
float a = rng(ps->anglea_min, ps->anglea_max) / ps->base;
p->xa = cos(angle) * a;
p->ya = sin(angle) * a;
p->xv = cos(angle) * v;
p->yv = sin(angle) * v;
p->r = rng(ps->r_min, ps->r_max) / 255.0f;
p->g = rng(ps->g_min, ps->g_max) / 255.0f;
p->b = rng(ps->b_min, ps->b_max) / 255.0f;
p->a = rng(ps->a_min, ps->a_max) / 255.0f;
p->rv = rng(ps->rv_min, ps->rv_max) / ps->base;
p->gv = rng(ps->gv_min, ps->gv_max) / ps->base;
p->bv = rng(ps->bv_min, ps->bv_max) / ps->base;
p->av = rng(ps->av_min, ps->av_max) / ps->base;
p->ra = rng(ps->ra_min, ps->ra_max) / ps->base;
p->ga = rng(ps->ga_min, ps->ga_max) / ps->base;
p->ba = rng(ps->ba_min, ps->ba_max) / ps->base;
p->aa = rng(ps->aa_min, ps->aa_max) / ps->base;
nb--;
if (!nb) break;
......@@ -151,6 +155,7 @@ static int particles_to_screen(lua_State *L)
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int i = 0;
bool alive = FALSE;
glBindTexture(GL_TEXTURE_2D, ps->texture);
......@@ -160,6 +165,8 @@ static int particles_to_screen(lua_State *L)
if (p->life)
{
alive = TRUE;
glColor4f(p->r, p->g, p->b, p->a);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 + x + p->x, 0 + y + p->y, -97);
......@@ -190,7 +197,9 @@ static int particles_to_screen(lua_State *L)
// Restore normal display
glColor4f(1, 1, 1, 1);
return 0;
lua_pushboolean(L, alive);
return 1;
}
static const struct luaL_reg particleslib[] =
......
......@@ -16,17 +16,20 @@ typedef struct {
int nb;
int texture_ref;
float base;
int base;
float size_min, sizev_min, sizea_min;
float x_min, y_min, xv_min, yv_min, xa_min, ya_min;
float r_min, g_min, b_min, a_min, rv_min, gv_min, bv_min, av_min, ra_min, ga_min, ba_min, aa_min;
int angle_min, anglev_min, anglea_min;
int angle_max, anglev_max, anglea_max;
float size_max, sizev_max, sizea_max;
float x_max, y_max, xv_max, yv_max, xa_max, ya_max;
float r_max, g_max, b_max, a_max, rv_max, gv_max, bv_max, av_max, ra_max, ga_max, ba_max, aa_max;
int size_min, sizev_min, sizea_min;
int x_min, y_min, xv_min, yv_min, xa_min, ya_min;
int r_min, g_min, b_min, a_min, rv_min, gv_min, bv_min, av_min, ra_min, ga_min, ba_min, aa_min;
float life_min, life_max;
int size_max, sizev_max, sizea_max;
int x_max, y_max, xv_max, yv_max, xa_max, ya_max;
int r_max, g_max, b_max, a_max, rv_max, gv_max, bv_max, av_max, ra_max, ga_max, ba_max, aa_max;
int life_min, life_max;
} particles_type;
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment