OK, this could take a while, cause its no longer up to me.
This is being caused either by a new engine bug, or an old "undocumented feature" I was using, and has been repaired.
I am using dummy entities to pass data to the particles, but its stopped working for some reason, and Im going to
chase this up in the "Bugs" forum.

For the time being, here is an older version. Its not quite as powerful, or as "pretty" but it does still work in newer engine versions.
Click to reveal..
Code:
#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);
	}
}




"There is no fate but what WE make." - CEO Cyberdyne Systems Corp.
A8.30.5 Commercial