Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @brief Creates a new weapon.
- *
- * @param outfit Outfit which spawned the weapon.
- * @param dir Direction the shooter is facing.
- * @param pos Position of the shooter.
- * @param vel Velocity of the shooter.
- * @param parent Shooter.
- * @param target Target ID of the shooter.
- * @return A pointer to the newly created weapon.
- */
- static Weapon* weapon_create( const Outfit* outfit,
- const double dir, const Vector2d* pos, const Vector2d* vel,
- const Pilot* parent, const unsigned int target )
- {
- Vector2d v, approach_vector, relative_location, offset_location;
- double mass, rdir, lead_angle;
- int lead_angle_int;
- Pilot *pilot_target;
- double x,y, acc, t, dist, radial_speed, speed;
- Weapon* w;
- /* Create basic features */
- w = malloc(sizeof(Weapon));
- memset(w, 0, sizeof(Weapon));
- w->dam_mod = 1.; /* Default of 100% damage. */
- w->faction = parent->faction; /* non-changeable */
- w->parent = parent->id; /* non-changeable */
- w->target = target; /* non-changeable */
- w->outfit = outfit; /* non-changeable */
- w->update = weapon_update;
- w->status = WEAPON_STATUS_OK;
- w->strength = 1.;
- switch (outfit->type) {
- /* Bolts treated together */
- case OUTFIT_TYPE_BOLT:
- case OUTFIT_TYPE_TURRET_BOLT:
- /* Only difference is the direction of fire */
- if ((outfit->type == OUTFIT_TYPE_TURRET_BOLT) && (w->parent!=w->target) &&
- (w->target != 0)) { /* Must have valid target */
- pilot_target = pilot_get(w->target);
- if (pilot_target == NULL)
- rdir = dir;
- else {
- /* Get the distance */
- dist = vect_dist( pos, &pilot_target->solid->pos );
- /* Aim. */
- if (dist > outfit->u.blt.range*1.2) {
- /* the target is out of range; just shoot straight at it*/
- x = pilot_target->solid->pos.x - pos->x;
- y = pilot_target->solid->pos.y - pos->y;
- }
- else {
- /* Try to predict where the enemy will be. */
- /* Time for shots to reach that distance */
- /*t = dist / (w->outfit->u.blt.speed + VMOD(*vel));*/
- /* determine the radial, or approach speed */
- vect_cset(&approach_vector, VX(parent->solid->vel) - VX(pilot_target->solid->vel), VY(parent->solid->vel) - VY(pilot_target->solid->vel) );
- vect_cset(&relative_location, VX(pilot_target->solid->pos) - VX(parent->solid->pos), VY(pilot_target->solid->pos) - VY(parent->solid->pos) );
- radial_speed = vect_dot(&approach_vector, &relative_location);
- radial_speed = radial_speed / VMOD(relative_location);
- speed = w->outfit->u.blt.speed;
- /* Time for shots to reach that distance */
- /* if the target is not hittable (ie, fleeing faster than our shots can fly), just face the target */
- if((speed+radial_speed) > 0)
- t = dist / (speed + radial_speed);
- else
- t = 0;
- /* Position is calculated on where it should be */
- x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
- - (pos->x + vel->x*t);
- y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
- - (pos->y + vel->y*t);
- }
- /*establish a default*/
- rdir = VANGLE(relative_location);
- lead_angle = M_PI;
- /*uncomment this line if turrets have a leadangle characteristic*/
- /*lead_angle = outfit->u.blt.leadangle;*/
- /*only do this if the lead angle is implemented; save compute cycled on fixed weapons*/
- if(lead_angle > 0)
- {
- if(fabs( angle_diff(ANGLE(x, y), VANGLE(relative_location)) ) > lead_angle)
- {
- /* the target is moving too fast for the turret to keep up */
- if(ANGLE(x, y) < VANGLE(relative_location))
- rdir = angle_diff(lead_angle, VANGLE(relative_location));
- else
- rdir = angle_diff(-1*lead_angle, VANGLE(relative_location));
- }
- else
- {
- /* the turret can aim properly*/
- rdir = ANGLE(x, y);
- }
- }
- else
- {
- /* just to be safe, handles non-leading turrets */
- rdir = VANGLE(relative_location);
- }
- }
- }
- else /* fire straight */
- rdir = dir;
- /* Calculate accuarcy. */
- acc = outfit->u.blt.accuracy/2. * 1./180.*M_PI;
- /* Stat modifiers. */
- if (outfit->type == OUTFIT_TYPE_TURRET_BOLT) {
- acc *= 2. - parent->stats.accuracy_turret; /* Invert. */
- w->dam_mod *= parent->stats.damage_turret;
- }
- else {
- acc *= 2. - parent->stats.accuracy_forward; /* Invert. */
- w->dam_mod *= parent->stats.damage_forward;
- }
- acc = MAX( 0., acc ); /* Make sure it doesn't become negative. */
- /* Calculate direction. */
- rdir += RNG_2SIGMA() * acc;
- if (rdir < 0.)
- rdir += 2.*M_PI;
- else if (rdir >= 2.*M_PI)
- rdir -= 2.*M_PI;
- mass = 1; /* Lasers are presumed to have unitary mass */
- vectcpy( &v, vel );
- vect_cadd( &v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
- w->timer = outfit->u.blt.range / outfit->u.blt.speed;
- w->falloff = w->timer - outfit->u.blt.falloff / outfit->u.blt.speed;
- w->solid = solid_create( mass, rdir, pos, &v );
- w->voice = sound_playPos( w->outfit->u.blt.sound,
- w->solid->pos.x,
- w->solid->pos.y,
- w->solid->vel.x,
- w->solid->vel.y);
- break;
- /* Beam weapons are treated together. */
- case OUTFIT_TYPE_BEAM:
- case OUTFIT_TYPE_TURRET_BEAM:
- if ((outfit->type == OUTFIT_TYPE_TURRET_BEAM) && (w->parent!=w->target)) {
- pilot_target = pilot_get(target);
- rdir = (pilot_target == NULL) ? dir :
- vect_angle(pos, &pilot_target->solid->pos);
- }
- else
- rdir = dir;
- if (rdir < 0.)
- rdir += 2.*M_PI;
- else if (rdir >= 2.*M_PI)
- rdir -= 2.*M_PI;
- mass = 1.; /**< Needs a mass. */
- w->solid = solid_create( mass, rdir, pos, NULL );
- w->think = think_beam;
- w->timer = outfit->u.bem.duration;
- w->voice = sound_playPos( w->outfit->u.bem.sound,
- w->solid->pos.x,
- w->solid->pos.y,
- w->solid->vel.x,
- w->solid->vel.y);
- break;
- /* Treat seekers together. */
- case OUTFIT_TYPE_AMMO:
- case OUTFIT_TYPE_TURRET_AMMO:
- if (w->outfit->type == OUTFIT_TYPE_TURRET_AMMO) {
- pilot_target = pilot_get(w->target);
- if (pilot_target == NULL)
- rdir = dir;
- else {
- /* Get the distance */
- dist = vect_dist( pos, &pilot_target->solid->pos );
- /* Aim. */
- /* Try to predict where the enemy will be. */
- /* Time for shots to reach that distance */
- if (outfit->u.amm.thrust == 0.)
- t = dist / (w->outfit->u.amm.speed + VMOD(*vel));
- else
- t = dist / w->outfit->u.amm.speed;
- /* Position is calculated on where it should be */
- x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
- - (pos->x + vel->x*t);
- y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
- - (pos->y + vel->y*t);
- /* Set angle to face. */
- rdir = ANGLE(x, y);
- }
- }
- else {
- rdir = dir;
- }
- if (outfit->u.amm.accuracy != 0.) {
- rdir += RNG_2SIGMA() * outfit->u.amm.accuracy/2. * 1./180.*M_PI;
- if ((rdir > 2.*M_PI) || (rdir < 0.))
- rdir = fmod(rdir, 2.*M_PI);
- }
- if (rdir < 0.)
- rdir += 2.*M_PI;
- else if (rdir >= 2.*M_PI)
- rdir -= 2.*M_PI;
- /* If thrust is 0. we assume it starts out at speed. */
- vectcpy( &v, vel );
- if (outfit->u.amm.thrust == 0.)
- vect_cadd( &v, cos(rdir) * w->outfit->u.amm.speed,
- sin(rdir) * w->outfit->u.amm.speed );
- /* Set up ammo details. */
- mass = w->outfit->mass;
- w->lockon = outfit->u.amm.lockon;
- w->timer = outfit->u.amm.duration;
- w->solid = solid_create( mass, rdir, pos, &v );
- if (w->outfit->u.amm.thrust != 0.)
- weapon_setThrust( w, w->outfit->u.amm.thrust * mass );
- /* Handle seekers. */
- if (w->outfit->u.amm.ai > 0) {
- w->think = think_seeker; /* AI is the same atm. */
- /* If they are seeking a pilot, increment lockon counter. */
- pilot_target = pilot_get(target);
- if (pilot_target != NULL)
- pilot_target->lockons++;
- }
- /* Play sound. */
- w->voice = sound_playPos(w->outfit->u.amm.sound,
- w->solid->pos.x,
- w->solid->pos.y,
- w->solid->vel.x,
- w->solid->vel.y);
- break;
- /* just dump it where the player is */
- default:
- WARN("Weapon of type '%s' has no create implemented yet!",
- w->outfit->name);
- w->solid = solid_create( 1., dir, pos, vel );
- break;
- }
- /* Set life to timer. */
- w->life = w->timer;
- return w;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement