#include <acknex.h>
#include <default.c>
//
//
//////////////////////////////////////////////////////////////////////////////////////////
// 3D-LIGHTNING-BOLT-SPAWN //
// ----------------------- //
// //
// Author : EvilSOB //
// Date : 25-07-2009 //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//LB_spawn(VECTOR* start, VECTOR* finish, long Div, float branch, long depth, long size)//
//--------------------------------------------------------------------------------------//
// Parameters:: //
// start = Start Vector of Lightning Bolt (sky) //
// finish = Target Vector of Lightning Bolt (ground) //
// Div = Number of primary "segments" in central bolt (suggest 20) //
// branch = 0.0->1.0 chance to "branch" at primary segment point. (suggest 0.4) //
// depth = depth of complexity to calculate into branches. (suggest 4) //
// size = diameter in quants of "core" bolt.(2^depth minimum) (suggest 8) //
// //
//////////////////////////////////////////////////////////////////////////////////////////
// Example:: //
// LB_spawn(start, finish, 20, 0.4, 4, 8); //
// //
//////////////////////////////////////////////////////////////////////////////////////////
// //
void LB_segment_fade(PARTICLE* p)
{ p.alpha -= 20 * p.skill_a * time_step;
if (p.alpha <= 0) p.lifespan = 0;
}
//
void LB_segment_flare(PARTICLE* p)
{ vec_set(p.blue, vector(128,0,0));
set(p, BEAM|BRIGHT|TRANSLUCENT|UNLIT|CAST);
p.alpha = 50;
p.size = (long)you*3;
p.skill_a = 0.3;
p.event = LB_segment_fade;
}
//
void LB_segment_core(PARTICLE* p)
{ vec_set(p.blue, vector(255,128,128));
set(p, BEAM|BRIGHT|TRANSLUCENT|UNLIT|CAST);
p.alpha = 100;
p.size = (long)you;
p.skill_a = 1.5;
p.event = LB_segment_fade;
}
//
void LB_draw_segment(VECTOR *start, VECTOR *finish, long size)
{ me = size;
VECTOR tmpV; vec_set(tmpV, finish); vec_sub(tmpV,start);
effect(LB_segment_core, 5, start, tmpV);
effect(LB_segment_flare, 1, start, tmpV);
me = size;
}
//
//
void LB_randomize(VECTOR* point, float noise)
{
point.x += random(noise*2)-noise;
point.y += random(noise*2)-noise;
point.z += random(noise)-noise/2;
}
//
void LB_subdivide(VECTOR* A, VECTOR* B, long Div, float noise, VECTOR** Points)
{ VECTOR *points = (VECTOR*)malloc(sizeof(VECTOR)*Div);
if(!Points) free(*Points); *Points = points;
var idx; for(idx=0; idx<Div; idx++)
{ vec_lerp(points[idx], A, B, (float)idx/(Div-1));
if((idx>0)&&(idx<(Div-1))) LB_randomize(points[idx], noise);
}
}
//
void LB_spawn(VECTOR* start,VECTOR* finish,long Div,float branch,long depth,long size)
{ VECTOR A, B; vec_set(A, start); vec_set(B, finish); wait(1);
long i, cnt, seg_size=vec_dist(A,B)/Div;
VECTOR *fine=0, *crude=0; LB_subdivide(A, B, Div, vec_dist(A,B)/(Div+1), crude);
for(i=1; i<Div; i++)
{ LB_subdivide(crude[i-1],crude[i],Div/2,vec_dist(crude[i-1],crude[i])/Div/2+1,fine);
for(cnt=1; cnt<(Div/2); cnt++) LB_draw_segment(fine[cnt-1], fine[cnt], size);
if((depth>1)&&(random(1)<branch))
{ VECTOR tmpV; vec_set(tmpV,crude[i]); LB_randomize(tmpV, vec_dist(A,B)/5);
LB_spawn(crude[i-1], tmpV, Div/2, branch, depth-1, size/2);
} }
free(crude); free(fine);
}
//////////////////////////////////////////////////////////////////////////////////////////
//
//
VECTOR start, finish;
void strike() { LB_spawn(start, finish, 20, 0.4, 4, 8); }
//
//
function main()
{
level_load(NULL); wait(2); diag("\n\n\n");
vec_set(sky_color, vector(1,1,1));
vec_set(camera.x, vector(-700,0,255));
//
on_space = strike;
//
vec_set(start, vector(0,0,500));
vec_set(finish, vector(0,100,0));
LB_spawn(start, finish, 20, 0.4, 4, 8);
//
while(1)
{
draw_point3d(start, vector(255,200,200), 100, 10);
draw_point3d(finish, vector(255,200,200), 100, 10);
wait(1);
}
}