your entire bullet handling script shouldn;t be more complex than this and you should not manitpulate the existance of an entity ( create or remove) from an event function or a function called by an event function
example:
Code:
function bullet_hit()
{
if(EVENT_TYPE == EVENT_BLOCK)
{
my.flag8 = on;
}
}
action move_bullet
{
// parameters set here
my.enable_block = on;
my.event = bullet_hit;
while (my.flag1 != 1)
{
// movment stuff here
if (my.flag8 == 1)
{
// create bullet hole sprite here
my.flag1 = 1;
}
wait(1);
}
ent_remove(me);
}
for a litte more complex one. here is a cut and paste of teh bullet script i did in part of the FPS doc i wrote (on ackenext site ). It's a little old now, but still you can pick it part for the structure. its set up the same way as above, just more to it because it handles multiple types of guns
what is critical here is TIMING notice in the bullet_hole script i use NORMAL right away which is a temporary vector used by the engine. this Only works because i KNOW that normal is being set JUST before by the EVENT_BLOCK handling.
things this close in timing you have to be right on top of the flow of your script. timing,speed, guesswork or close enough doesn't work in these cases.
Code:
action bullet_hole
{
// just parameters set up here
my.scale_x = .5;
my.scale_y = .5;
my.scale_z = .5;
my.oriented = on;
my.alpha = 100;
my.flare = on;
my.overlay = on;
my.transparent = on;
my.passable = on;
vec_to_angle(my.pan, NORMAL);
Vec_set(temp,Normal); // copy the normal direction vector to temp
Vec_inverse(temp); // inverts the direction vector
Vec_to_angle(temp2,temp); // I convert temp direction angle to a pan/tilt angle and store it temp2
vec_set(temp,vector(100,0,0));
vec_rotate(temp,temp2);
vec_add (temp,my.x);
trace_mode = ignore_me+ignore_passable+ignore_models + ignore_maps + ignore_sprites + ignore_push;
trace(my.x,temp);
vec_set(my.x,TARGET);
sleep(5);
while (my.alpha > 0)
{
my.alpha -= .25*TIME;
wait(1);
}
ent_remove(me);
}
function bullet_event()
{
if(EVENT_TYPE == event_block)
{
my.flag3 = on;
ent_playsound(me,b_bounce,60);
if (my.flag2 == ON) // bounce
{
vec_to_angle (my.pan, bounce); // bounce direction
}
else
{
my.flag1 = ON;
}
}
if(EVENT_TYPE == event_entity && YOU.flag8 == ON)
{
if (YOU.armor >= bullet_damage[my.skill100])
{
YOU.armor -= bullet_damage[my.skill100];
my.flag1 = ON;
}
else
{
YOU.health -= bullet_damage[my.skill100]-YOU.armor;
YOU.armor = 0;
my.flag1 = ON;
}
}
}
action bullet_move
{
turn_towards_target();
my.enable_block = ON;
my.enable_entity = ON;
my.event = bullet_event;
my.flag1 = OFF;
my.flag2 = bullet_bounce[current_weapon];
my.skill100 = current_weapon;
if (my.skill100 == 3)
{
vec_set(my.skill40,my.x); // set the my.x location vector to skills 40,41,42
vec_set(temp.x,vector(1,0,0)); // vector length of 1 quant
vec_rotate(temp.x,my.pan); // temp is now a vector of length 1 quant in direction bullet goes
vec_set(temp2.x,vector(20,0,0)); // set temp2 as a vector length of 20 quants
vec_rotate(temp2.x,my.pan); // rotate it by bullets pan/tilt angles
my.skill50 = 1;
while (my.skill50 < 40)
{
effect(laser_part,1,my.skill40,temp2);
vec_add(my.skill40,temp.x);
my.skill50 += 1;
}
}
while (my.skill20 < bullet_ranges[my.skill100] && my.flag1 == OFF)
{
move_mode = IGNORE_YOU + IGNORE_PASSABLE + IGNORE_PUSH;
my.skill20+= ent_move(vector(bullet_speeds[my.skill100],0,0),nullvector);
if (my.flag3 == on)
{
ent_create(bullet_holes.string[my.skill100],my.x,bullet_hole);
my.flag3 = off;
}
wait(1);
}
ent_remove(me);
}
some of teh sissues yoru having is in timing. the calling and executing of multiple functions. 1-2 frames can pass between the time some data is set for a condition and when the function actually occurs, by then your data can be now incorrect. such as your bulletholes not exactly on the wall or they are touching but not flush aganst the wall or not even ON the right wall. reading the right data but at the wrong time
if your getting ones that are on the wall as should be but they are shredded in appearance. then those are right. use the my.decal flag on the sprite