Posted By: Joozey
Electricity script - 05/25/10 15:01
Probably there are plenty released in the past, but here a tiny one from me:
http://www.youtube.com/watch?v=xE9sZULURKo
Link to model and code:
http://joozey.nl/3dgs/contribs/Electricity.zip
Have fun!
http://www.youtube.com/watch?v=xE9sZULURKo
Link to model and code:
http://joozey.nl/3dgs/contribs/Electricity.zip
Have fun!
Code:
//defines //handy #define new(x) malloc(sizeof(x)) #define remove(x) free(x) //length of the model (you need to adapt this if you got your own model) #define ELECTRIC_LENGTH 50 //model name #define ELECTRICITY_MODEL "electricity.mdl" //structure typedef struct { VECTOR start; VECTOR end; var seconds; ENTITY *electricity_entity; var deviation; } ELECTRICITY; //prototypes void ELECTRICITY_Shoot( ELECTRICITY *e ); void ELECTRICITY_Run( ELECTRICITY *e ); ELECTRICITY *ELECTRICITY_Create( VECTOR *start, VECTOR *end, var seconds, var deviation ); void ELECTRICITY_Remove( ELECTRICITY *e ); //runs as many time as has been assigned on seconds (not really seconds by the way) void ELECTRICITY_Run( ELECTRICITY *e ) { //shoot a new electric (will recursively loop in here again) ELECTRICITY_Shoot( e ); //factor for decaying alpha with seconds var factor = 100/e->seconds; set( e->electricity_entity, TRANSLUCENT ); //loop while we still got seconds while( e->seconds > 0 ) { e->seconds -= 1 * time_step; e->electricity_entity.alpha -= factor * time_step; //decay alpha wait(1); } //remove the entity ent_remove( e->electricity_entity ); remove( e ); } //create a new electricity (you call this to create a new thunder, also used for recursive loop internally) ELECTRICITY *ELECTRICITY_Create( VECTOR *start, VECTOR *end, var seconds, var deviation ) { ELECTRICITY *e = new(ELECTRICITY); vec_set( e->start, start ); vec_set( e->end, end ); e->seconds = seconds; e->deviation = deviation; e->electricity_entity = ent_create(ELECTRICITY_MODEL, e->start, NULL); //start running ELECTRICITY_Run( e ); return e; } //remove electricity //since the run function still uses the electricity when it is removed here, errors may pop up //so we make sure the run ends, and let the run function take care of removing //we end the run by putting seconds on 0 void ELECTRICITY_Remove( ELECTRICITY *e ) { e->seconds = 0; } //shoot a new segment of electricity void ELECTRICITY_Shoot( ELECTRICITY *e ) { VECTOR newStart; VECTOR newEnd; //get direction from current position to global end vec_set( newEnd, e->end ); vec_sub( newEnd, e->start ); //rotate a bit by given deviation vec_rotate( newEnd, vector( random(e->deviation*2)-e->deviation, random(e->deviation*2)-e->deviation, random(e->deviation*2)-e->deviation ) ); //scale it to the model's length vec_normalize( newEnd, ELECTRIC_LENGTH ); //place it at the previous electric segment vec_set( newStart, e->start ); vec_add( newStart, newEnd ); //place the real model vec_set( e->electricity_entity.x, e->start ); //rotate the real model VECTOR *vAngle = vector( 0, 0, 0 ); vec_set( vAngle, e->start ); vec_sub( vAngle, newStart ); vec_to_angle( e->electricity_entity.pan, vAngle ); //since this function is recursive, we need to limit it before it goes endless looping //we look if the electric segment approaches the global end, if so, we dont make a new segment anymore // //TODO: make the last segment end exactly on the designated end position //currently it is not exactly on the spot but stops right before or after it if( vec_dist( e->start, e->end ) > ELECTRIC_LENGTH + 10 ) { ELECTRICITY *e = ELECTRICITY_Create( newStart, e->end, e->seconds, e->deviation ); } //this is the very last segment,we treat it a bit different if( vec_dist( e->start, e->end ) <= ELECTRIC_LENGTH + 10 && vec_dist( e->start, e->end ) >= ELECTRIC_LENGTH - 10 ) { //at least give the last segment a deviation of 0 so it will point directly towards global end ELECTRICITY *e = ELECTRICITY_Create( newStart, e->end, e->seconds, e->deviation ); } }