void petal_explosion(int n, complex pos) { int i; for(i = 0; i < n; i++) { tsrand_fill(8); create_particle4c("petal", pos, rgba(0.6,1-afrand(0)*0.4,0.5,1-0.5*afrand(1)), Petal, asymptotic, (3+5*afrand(2))*cexp(I*M_PI*2*afrand(3)), 5, afrand(4) + afrand(5)*I, afrand(6) + 360.0I*afrand(7)); } }
static void* _delete_enemy(ListAnchor *enemies, List* enemy, void *arg) { Enemy *e = (Enemy*)enemy; if(e->hp <= 0 && e->hp != ENEMY_IMMUNE && e->hp != ENEMY_BOMB) { play_sound("enemydeath"); for(int i = 0; i < 10; i++) { tsrand_fill(2); PARTICLE( .sprite = "flare", .pos = e->pos, .timeout = 10, .rule = linear, .draw_rule = Fade, .args = { (3+afrand(0)*10)*cexp(I*afrand(1)*2*M_PI) }, ); } PARTICLE(.proto = pp_blast, .pos = e->pos, .timeout = 20, .draw_rule = Blast, .flags = PFLAG_REQUIREDPARTICLE); PARTICLE(.proto = pp_blast, .pos = e->pos, .timeout = 20, .draw_rule = Blast, .flags = PFLAG_REQUIREDPARTICLE); PARTICLE(.proto = pp_blast, .pos = e->pos, .timeout = 15, .draw_rule = GrowFade, .flags = PFLAG_REQUIREDPARTICLE); for(Projectile *p = global.projs.first; p; p = p->next) { if(p->type == PROJ_ENEMY && !(p->flags & PFLAG_NOCOLLISION) && cabs(p->pos - e->pos) < 64) { spawn_and_collect_item(e->pos, ITEM_PIV, 1); } } }
void player_graze(Player *plr, complex pos, int pts) { global.points += pts; plr->graze++; play_sound("graze"); int i = 0; for(i = 0; i < 5; ++i) { tsrand_fill(3); create_particle2c("flare", pos, NULL, Shrink, timeout_linear, 5 + 5 * afrand(2), (1+afrand(0)*5)*cexp(I*tsrand_a(1))); } }
void player_death(Player *plr) { if(plr->deathtime == -1 && global.frames - abs(plr->recovery) > 0) { int i; for(i = 0; i < 20; i++) { tsrand_fill(2); create_particle2c("flare", plr->pos, NULL, Shrink, timeout_linear, 40, (3+afrand(0)*7)*cexp(I*tsrand_a(1))); } create_particle2c("blast", plr->pos, rgb(1,0.5,0.3), GrowFade, timeout, 35, 2.4); plr->deathtime = global.frames + DEATHBOMB_TIME; } }
static void trace_laser(Enemy *e, complex vel, float damage) { ProjCollisionResult col; ProjectileList lproj = { .first = NULL }; MarisaLaserData *ld = REF(e->args[3]); PROJECTILE( .dest = &lproj, .pos = e->pos, .size = 28*(1+I), .type = PROJ_PLAYER, .damage = damage, .rule = linear, .args = { vel }, ); bool first_found = false; int timeofs = 0; int col_types = PCOL_ENTITY; struct enemy_col { LIST_INTERFACE(struct enemy_col); Enemy *enemy; int original_hp; } *prev_collisions = NULL; while(lproj.first) { timeofs = trace_projectile(lproj.first, &col, col_types | PCOL_VOID, timeofs); struct enemy_col *c = NULL; if(!first_found) { ld->trace_hit.first = col.location; first_found = true; } if(col.type & col_types) { tsrand_fill(3); PARTICLE( .sprite = "flare", .pos = col.location, .rule = linear, .timeout = 3 + 5 * afrand(2), .draw_rule = Shrink, .args = { (2+afrand(0)*6)*cexp(I*M_PI*2*afrand(1)) }, .flags = PFLAG_NOREFLECT, .layer = LAYER_PARTICLE_HIGH, ); if(col.type == PCOL_ENTITY && col.entity->type == ENT_ENEMY) { c = malloc(sizeof(struct enemy_col)); c->enemy = ENT_CAST(col.entity, Enemy); list_push(&prev_collisions, c); } else { col_types &= ~col.type; } col.fatal = false; } apply_projectile_collision(&lproj, lproj.first, &col); if(c) { c->original_hp = (ENT_CAST(col.entity, Enemy))->hp; (ENT_CAST(col.entity, Enemy))->hp = ENEMY_IMMUNE; } }