/* Missile turret animation */ static void mturret_animate(struct SpecialObj *turret) { /* Find a target */ int targplr; double dist; if(turret->timer==0) { targplr = find_nearest_enemy(turret->x,turret->y,turret->owner, &dist); if(dist<250.0) { turret->angle = (turret->frames-turret->frame)/(double)turret->frames*M_PI_2+M_PI_4; turret_shoot(turret); } } /* Animation */ if(turret->turn>0) { if(++turret->frame>=turret->frames) { turret->frame=turret->frames-1; turret->turn=-1; } } else { if(--turret->frame>turret->frames) { turret->frame=0; turret->turn=1; } } }
/* Ground critter timer function: flee from any nearby enemy player */ static void gc_flee(struct Critter *critter) { if(critter->ff>0) { double distance; int enemy = find_nearest_enemy(critter->walker.physics.x, critter->walker.physics.y, critter->owner, &distance); if(distance<200.0) { critter->walker.walkspeed = 3; if(players[enemy].ship->physics.x < critter->walker.physics.x) { if(critter->walker.walking<0) critter->cornered+=1; critter->walker.walking = 1; } else { if(critter->walker.walking>0) critter->cornered+=1; critter->walker.walking = -1; } } else { critter->walker.walkspeed = 1; } critter->ff--; critter->timer = 1; } else { critter->walker.walkspeed = 1; critter->timerfunc = gc_dosomething; critter->timer = 2; } }
/* Turret animation */ static void turret_animate(struct SpecialObj *turret) { double dist; float targx=-1,targy=-1; int targplr; /* Get a target */ targplr = find_nearest_enemy(turret->x,turret->y,turret->owner, &dist); if(dist<160.0) { targx = players[targplr].ship->physics.x; targy = players[targplr].ship->physics.y; } else { targplr = find_nearest_pilot(turret->x,turret->y,turret->owner, &dist); if(dist<160.0) { targx = players[targplr].pilot.walker.physics.x; targy = players[targplr].pilot.walker.physics.y; } } /* Aim at target if found */ if(targx>=0) { double a = atan2(turret->y-targy, targx-turret->x); double d; if(a<0) a = 2*M_PI + a; d = shortestRotation(turret->angle,a); if(d<-0.2) { turret->turn = -0.2; } else if(d>0.2) { turret->turn = 0.2; } else { turret->turn = d/2; if(turret->timer==0) turret_shoot(turret); } } else { /* Restore normal turning speed */ if(turret->turn<0) turret->turn=-0.05; else turret->turn=0.05; } /* Rotate turret */ turret->angle += turret->turn; if(is_solid(turret->x+cos(turret->angle)*5,turret->y-sin(turret->angle)*5)) { turret->angle -= turret->turn; turret->turn = -turret->turn; } if(turret->angle>2*M_PI) turret->angle=0; else if(turret->angle<0) turret->angle=2*M_PI; turret->frame = Round(turret->angle/(2*M_PI)*(turret->frames-1)); }
static void tick_combat(struct GameState *game_state, float dt) { for (uint32 i = 0; i < game_state->ship_count; ++i) { struct Ship *ship = &game_state->ships[i]; if (ship->fire_cooldown_timer <= 0.0f) { struct Ship *target = find_nearest_enemy(game_state, ship); if (target == NULL) continue; fire_projectile(game_state, ship, target, 1); } else { ship->fire_cooldown_timer -= dt; } } }
/* shot at from ground */ static int find_target(float x, float y, int owner, float *targx, float *targy, double *dist, int airborne) { double distance; int eplr; struct Critter *ec; /* First priority, enemy ships */ eplr = find_nearest_enemy(x,y, owner, &distance); if(distance < 120.0) { *targx = players[eplr].ship->physics.x; *targy = players[eplr].ship->physics.y; if(dist) *dist = distance; return 1; } /* Second priority, enemy helicopters */ ec = find_enemy_critter(x,y, owner ,&distance,helicopter_gfx); if(distance < 120.0) { *targx = ec->physics.x; *targy = ec->physics.y; if(dist) *dist = distance; return 1; } if(airborne) { /* Third priority, airborne only, enemy soldiers */ ec = find_enemy_critter(x,y, owner,&distance,soldier_gfx); if(distance < 120.0) { *targx = ec->physics.x; *targy = ec->physics.y; if(dist) *dist = distance; return 1; } /* Fourth priority, airborne only, enemy pilots */ eplr = find_nearest_pilot(x,y,owner,&distance); if(distance < 120.0) { *targx = players[eplr].pilot.walker.physics.x; *targy = players[eplr].pilot.walker.physics.y; if(dist) *dist = distance; return 1; } } return 0; }
/*** PILOT ANIMATION ***/ void animate_pilots (void) { int p; for(p=0;p<4;p++) { struct Pilot *pilot = &players[p].pilot; if(players[p].state != ALIVE || players[p].ship) continue; animate_walker(&pilot->walker,0,NULL); /* Cool down weapon */ if (pilot->weap_cooloff > 0) pilot->weap_cooloff--; /* Autoaim */ if(pilot->lock==0) { double dist; int nearest = find_nearest_enemy(pilot->walker.physics.x,pilot->walker.physics.y, p, &dist); if (nearest>=0 && dist < 150) { pilot->attack_vector.x = (players[nearest].ship->physics.x - pilot->walker.physics.x)/dist; pilot->attack_vector.y = (players[nearest].ship->physics.y - pilot->walker.physics.y)/dist; pilot->crosshair_color = col_plrs[nearest]; } else { pilot->crosshair_color = col_white; } } else { pilot->crosshair_color = col_white; } /* Rope simulation */ if(pilot->rope) { if(pilot->ropectrl<0) { if(pilot->rope->nodelen>pilot_rope_minlen) pilot->rope->nodelen -= 0.05; } else if(pilot->ropectrl>0) { if(pilot->rope->nodelen<pilot_rope_maxlen) pilot->rope->nodelen += 0.05; } animate_spring(pilot->rope); } /* Stop parachuting when hitting something other than air */ if((pilot->walker.physics.hitground||pilot->walker.physics.underwater) && pilot->parachuting) undeploy_parachute(pilot); /* Check if falling too fast and hit the ground */ if(ter_walkable(pilot->walker.physics.hitground)) { if(pilot->toofast > PILOT_TOOFAST) { kill_pilot(pilot); } } else { if(fabs(pilot->walker.physics.vel.y)>=LETHAL_VELOCITY) { make_sweatdrops(pilot); pilot->toofast++; } else { pilot->toofast = 0; } } } }