void afxEffectVector::interrupt() { if (empty()) { active = false; return; } for (int i = 0; i < fx_v->size(); i++) { (*fx_v)[i]->stop(); (*fx_v)[i]->cleanup(); delete (*fx_v)[i]; (*fx_v)[i] = 0; } swap_vecs(); fx_v2->clear(); if (empty()) { active = false; delete fx_v; fx_v =0; delete fx_v2; fx_v2 = 0; } }
void afxEffectVector::start(F32 timestamp) { if (empty()) return; // At this point both client and server effects are in the list. // Timing adjustments are made during prestart(). for (S32 i = 0; i < fx_v->size(); i++) (*fx_v)[i]->prestart(); // duration and afterlife values are pre-calculated here calc_fx_dur_and_afterlife(); // now we filter out client-only or server-only effects that // don't belong here, filter_client_server(); active = true; for (S32 j = 0; j < fx_v->size(); j++) { if ((*fx_v)[j]->start(timestamp)) fx_v2->push_back((*fx_v)[j]); else { delete (*fx_v)[j]; (*fx_v)[j] = 0; } } swap_vecs(); fx_v2->clear(); }
/* Collision detection * ------------------- * * When updating a frame, we traverse the star pairs * graph and test for a bounding box intersection. * To detect pixel-level collisions, we us pixels_collide() * using the portion of intersection as a test area. * If we detect a collision, we swap the star pair * motion vectors to create a deflection effect. * * When done, we update and draw the stars. */ static void update_sample(void* data, float elapsed_ms) { struct state* state = data; int visited[MAX_STARS][MAX_STARS] = { { 0 } }; int i, j; for (i = 0; i < MAX_STARS; i++) { for (j = 0; j < MAX_STARS; j++) { if (i != j && visited[i][j] == 0 && visited[j][i] == 0) { bbox sub; struct star* a = &state->stars[i]; struct star* b = &state->stars[j]; if (bbox_intersect(a->star_bbox, b->star_bbox, &sub)) { struct rectangle r1, r2; r1 = rect_from_sub_bbox(a->star_bbox, sub); r2 = rect_from_sub_bbox(b->star_bbox, sub); if (pixels_collide(state->star_img, &r1, state->star_img, &r2)) swap_vecs(&a->star_vec, &b->star_vec); } visited[i][j] = 1; } } } screen_color(color_from_RGB(10, 20, 50)); for (i = 0; i < MAX_STARS; i++) { update_star(&state->stars[i], elapsed_ms); draw_image(state->star_img, VEC_XY(state->stars[i].star_pos), NULL, 0); } }
void afxEffectVector::filter_client_server() { if (empty()) return; for (S32 i = 0; i < fx_v->size(); i++) { if ((*fx_v)[i]->datablock->runsHere(on_server)) fx_v2->push_back((*fx_v)[i]); else { delete (*fx_v)[i]; (*fx_v)[i] = 0; } } swap_vecs(); fx_v2->clear(); }
void afxEffectVector::stop(bool force_cleanup) { if (empty()) { active = false; return; } for (int i = 0; i < fx_v->size(); i++) { (*fx_v)[i]->stop(); if (force_cleanup || (*fx_v)[i]->deleteWhenStopped()) { // effect is over when stopped, cleanup and delete (*fx_v)[i]->cleanup(); delete (*fx_v)[i]; (*fx_v)[i] = 0; } else { // effect needs to fadeout or something, so keep it around fx_v2->push_back((*fx_v)[i]); } } swap_vecs(); fx_v2->clear(); if (empty()) { active = false; delete fx_v; fx_v =0; delete fx_v2; fx_v2 = 0; } }
void afxEffectVector::update(F32 dt) { if (empty()) { active = false; return; } for (int i = 0; i < fx_v->size(); i++) { (*fx_v)[i]->update(dt); if ((*fx_v)[i]->isDone() || (*fx_v)[i]->isAborted()) { // effect has ended, cleanup and delete (*fx_v)[i]->cleanup(); delete (*fx_v)[i]; (*fx_v)[i] = 0; } else { // effect is still going, so keep it around fx_v2->push_back((*fx_v)[i]); } } swap_vecs(); fx_v2->clear(); if (empty()) { active = false; delete fx_v; fx_v =0; delete fx_v2; fx_v2 = 0; } }