add kill_projectile() as a kind-of ACTION_DESTROY substitute

This commit is contained in:
Andrei Alexeyev 2019-07-19 12:48:22 +03:00
parent 3f99739d62
commit 439d8ea339
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
3 changed files with 38 additions and 5 deletions

View file

@ -291,7 +291,7 @@ Projectile* _proj_attach_dbginfo(Projectile *p, DebugInfo *dbg, const char *call
}
#endif
static void* _delete_projectile(ListAnchor *projlist, List *proj, void *arg) {
static void *_delete_projectile(ListAnchor *projlist, List *proj, void *arg) {
Projectile *p = (Projectile*)proj;
proj_call_rule(p, EVENT_DEATH);
ent_unregister(&p->ent);
@ -299,7 +299,7 @@ static void* _delete_projectile(ListAnchor *projlist, List *proj, void *arg) {
return NULL;
}
void delete_projectile(ProjectileList *projlist, Projectile *proj) {
static void delete_projectile(ProjectileList *projlist, Projectile *proj) {
_delete_projectile((ListAnchor*)projlist, (List*)proj, NULL);
}
@ -508,6 +508,11 @@ bool clear_projectile(Projectile *proj, uint flags) {
return true;
}
void kill_projectile(Projectile* proj) {
proj->flags |= PFLAG_INTERNAL_DEAD | PFLAG_NOCOLLISION | PFLAG_NOCLEAR;
proj->draw_rule = ProjNoDraw;
}
void process_projectiles(ProjectileList *projlist, bool collision) {
ProjCollisionResult col = { 0 };
@ -519,6 +524,11 @@ void process_projectiles(ProjectileList *projlist, bool collision) {
next = proj->next;
proj->prevpos = proj->pos;
if(proj->flags & PFLAG_INTERNAL_DEAD) {
delete_projectile(projlist, proj);
continue;
}
if(stage_cleared) {
clear_projectile(proj, CLEAR_HAZARDS_BULLETS | CLEAR_HAZARDS_FORCE);
}

View file

@ -60,6 +60,7 @@ typedef enum ProjFlags {
PFLAG_REQUIREDPARTICLE = (1 << 10), // [PROJ_PARTICLE] Visible at "minimal" particles setting.
PFLAG_PLRSPECIALPARTICLE = (1 << 11), // [PROJ_PARTICLE] Apply Power Surge effect to this particle, as if it was a PROJ_PLAYER.
PFLAG_NOCOLLISION = (1 << 12), // [PROJ_ENEMY, PROJ_PLAYER] Disable collision detection.
PFLAG_INTERNAL_DEAD = (1 << 13), // [ALL] Delete as soon as processed. (internal flag, do not use)
PFLAG_NOSPAWNEFFECTS = PFLAG_NOSPAWNFADE | PFLAG_NOSPAWNFLARE,
} ProjFlags;
@ -181,7 +182,6 @@ Projectile* create_particle(ProjArgs *args);
#define PROJECTILE(...) _PROJ_GENERIC_SPAWN(create_projectile, __VA_ARGS__)
#define PARTICLE(...) _PROJ_GENERIC_SPAWN(create_particle, __VA_ARGS__)
void delete_projectile(ProjectileList *projlist, Projectile *proj);
void delete_projectiles(ProjectileList *projlist);
void calc_projectile_collision(Projectile *p, ProjCollisionResult *out_col);
@ -198,6 +198,7 @@ Projectile* spawn_projectile_highlight_effect(Projectile *proj);
void projectile_set_prototype(Projectile *p, ProjPrototype *proto);
bool clear_projectile(Projectile *proj, uint flags);
void kill_projectile(Projectile *proj);
int linear(Projectile *p, int t);
int accelerated(Projectile *p, int t);

View file

@ -27,6 +27,26 @@ TASK(drop_items, { complex *pos; ItemCounts items; }) {
}
}
TASK(laserize_proj, { Projectile *p; int t; }) {
TASK_BIND(ARGS.p);
WAIT(ARGS.t);
complex pos = ARGS.p->pos;
double a = ARGS.p->angle;
Color clr = ARGS.p->color;
kill_projectile(ARGS.p);
complex aim = 12 * cexp(I * a);
create_laserline(pos, aim, 20, 40, &clr);
PROJECTILE(
.pos = pos,
.proto = pp_ball,
.color = &clr,
.timeout = 20,
);
}
TASK(wait_event_test, { Enemy *e; int rounds; int delay; int cnt; int cnt_inc; }) {
// WAIT_EVENT yields until the event fires.
// Returns true if the event was signaled, false if it was canceled.
@ -101,7 +121,7 @@ TASK_WITH_FINALIZER(test_enemy, {
complex aim = global.plr.pos - e->pos;
aim *= 5 * cexp(I*M_PI*0.1*nfrand()) / cabs(aim);
PROJECTILE(
Projectile *p = PROJECTILE(
.pos = e->pos,
.proto = pp_rice,
.color = RGBA(1.0, 0.0, i / (pcount - 1.0), 0.0),
@ -109,6 +129,8 @@ TASK_WITH_FINALIZER(test_enemy, {
.args = { aim },
);
INVOKE_TASK(laserize_proj, p, 30);
WAIT(3);
}
@ -131,7 +153,7 @@ TASK(stage_main, { int ignored; }) {
for(;;) {
INVOKE_TASK(test_enemy, 9000, CMPLX(VIEWPORT_W, VIEWPORT_H) * 0.5, 3*I);
WAIT(240);
WAIT(500);
}
}