Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.40 KB | None | 0 0
  1. /**
  2.  * @brief Creates a new weapon.
  3.  *
  4.  *    @param outfit Outfit which spawned the weapon.
  5.  *    @param dir Direction the shooter is facing.
  6.  *    @param pos Position of the shooter.
  7.  *    @param vel Velocity of the shooter.
  8.  *    @param parent Shooter.
  9.  *    @param target Target ID of the shooter.
  10.  *    @return A pointer to the newly created weapon.
  11.  */
  12. static Weapon* weapon_create( const Outfit* outfit,
  13.       const double dir, const Vector2d* pos, const Vector2d* vel,
  14.       const Pilot* parent, const unsigned int target )
  15. {
  16.    Vector2d v, approach_vector, relative_location, offset_location;
  17.    double mass, rdir, lead_angle;
  18.    int lead_angle_int;
  19.    Pilot *pilot_target;
  20.    double x,y, acc, t, dist, radial_speed, speed;
  21.    Weapon* w;
  22.    
  23.  
  24.    /* Create basic features */
  25.    w = malloc(sizeof(Weapon));
  26.    memset(w, 0, sizeof(Weapon));
  27.    w->dam_mod = 1.; /* Default of 100% damage. */
  28.    w->faction = parent->faction; /* non-changeable */
  29.    w->parent = parent->id; /* non-changeable */
  30.    w->target = target; /* non-changeable */
  31.    w->outfit = outfit; /* non-changeable */
  32.    w->update = weapon_update;
  33.    w->status = WEAPON_STATUS_OK;
  34.    w->strength = 1.;
  35.    
  36.    switch (outfit->type) {
  37.  
  38.       /* Bolts treated together */
  39.       case OUTFIT_TYPE_BOLT:
  40.       case OUTFIT_TYPE_TURRET_BOLT:
  41.          /* Only difference is the direction of fire */
  42.          if ((outfit->type == OUTFIT_TYPE_TURRET_BOLT) && (w->parent!=w->target) &&
  43.                (w->target != 0)) { /* Must have valid target */
  44.  
  45.             pilot_target = pilot_get(w->target);
  46.             if (pilot_target == NULL)
  47.                rdir = dir;
  48.  
  49.             else {
  50.                /* Get the distance */
  51.                dist = vect_dist( pos, &pilot_target->solid->pos );
  52.  
  53.                /* Aim. */
  54.                if (dist > outfit->u.blt.range*1.2) {
  55.                   /* the target is out of range; just shoot straight at it*/
  56.                  
  57.                   x = pilot_target->solid->pos.x - pos->x;
  58.                   y = pilot_target->solid->pos.y - pos->y;
  59.                }
  60.                else {
  61.                   /* Try to predict where the enemy will be. */
  62.                   /* Time for shots to reach that distance */
  63.  
  64.  
  65.                   /*t = dist / (w->outfit->u.blt.speed + VMOD(*vel));*/
  66.  
  67.                   /* determine the radial, or approach speed */
  68.                   vect_cset(&approach_vector, VX(parent->solid->vel) - VX(pilot_target->solid->vel), VY(parent->solid->vel) - VY(pilot_target->solid->vel) );
  69.                   vect_cset(&relative_location, VX(pilot_target->solid->pos) -  VX(parent->solid->pos),  VY(pilot_target->solid->pos) - VY(parent->solid->pos) );
  70.  
  71.                   radial_speed = vect_dot(&approach_vector, &relative_location);
  72.                   radial_speed = radial_speed / VMOD(relative_location);
  73.  
  74.                   speed = w->outfit->u.blt.speed;
  75.  
  76.                   /* Time for shots to reach that distance */
  77.                   /* if the target is not hittable (ie, fleeing faster than our shots can fly), just face the target */
  78.                   if((speed+radial_speed) > 0)
  79.                      t = dist / (speed + radial_speed);
  80.                   else
  81.                      t = 0;
  82.  
  83.                   /* Position is calculated on where it should be */
  84.                   x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
  85.                      - (pos->x + vel->x*t);
  86.                   y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
  87.                      - (pos->y + vel->y*t);
  88.                }
  89.  
  90.              
  91.  
  92.                /*establish a default*/
  93.                rdir = VANGLE(relative_location);
  94.          
  95.  
  96.                lead_angle = M_PI;
  97.                
  98.                /*uncomment this line if turrets have a leadangle characteristic*/
  99.            /*lead_angle = outfit->u.blt.leadangle;*/
  100.                
  101.                /*only do this if the lead angle is implemented; save compute cycled on fixed weapons*/
  102.                if(lead_angle > 0)
  103.                {
  104.  
  105.                
  106.                 if(fabs( angle_diff(ANGLE(x, y), VANGLE(relative_location)) ) > lead_angle)
  107.                     {
  108.  
  109.                         /* the target is moving too fast for the turret to keep up */
  110.                        
  111.                         if(ANGLE(x, y) < VANGLE(relative_location))
  112.                             rdir = angle_diff(lead_angle, VANGLE(relative_location));
  113.                         else
  114.                             rdir = angle_diff(-1*lead_angle, VANGLE(relative_location));
  115.                            
  116.                        
  117.                     }
  118.                    else
  119.                    {
  120.                         /* the turret can aim properly*/
  121.                      
  122.                         rdir = ANGLE(x, y);
  123.                      
  124.                    }
  125.                }
  126.                else
  127.                   {
  128.                    /* just to be safe, handles non-leading turrets */
  129.                    rdir = VANGLE(relative_location);
  130.                   }
  131.  
  132.                
  133.             }
  134.          }
  135.          else /* fire straight */
  136.             rdir = dir;
  137.  
  138.          /* Calculate accuarcy. */
  139.          acc =  outfit->u.blt.accuracy/2. * 1./180.*M_PI;
  140.  
  141.          /* Stat modifiers. */
  142.          if (outfit->type == OUTFIT_TYPE_TURRET_BOLT) {
  143.             acc         *= 2. - parent->stats.accuracy_turret; /* Invert. */
  144.             w->dam_mod  *= parent->stats.damage_turret;
  145.          }
  146.          else {
  147.             acc         *= 2. - parent->stats.accuracy_forward; /* Invert. */
  148.             w->dam_mod  *= parent->stats.damage_forward;
  149.          }
  150.          acc = MAX( 0., acc ); /* Make sure it doesn't become negative. */
  151.  
  152.          /* Calculate direction. */
  153.          rdir += RNG_2SIGMA() * acc;
  154.          if (rdir < 0.)
  155.             rdir += 2.*M_PI;
  156.          else if (rdir >= 2.*M_PI)
  157.             rdir -= 2.*M_PI;
  158.  
  159.          mass = 1; /* Lasers are presumed to have unitary mass */
  160.          vectcpy( &v, vel );
  161.          vect_cadd( &v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
  162.          w->timer = outfit->u.blt.range / outfit->u.blt.speed;
  163.          w->falloff = w->timer - outfit->u.blt.falloff / outfit->u.blt.speed;
  164.          w->solid = solid_create( mass, rdir, pos, &v );
  165.          w->voice = sound_playPos( w->outfit->u.blt.sound,
  166.                w->solid->pos.x,
  167.                w->solid->pos.y,
  168.                w->solid->vel.x,
  169.                w->solid->vel.y);
  170.          break;
  171.  
  172.       /* Beam weapons are treated together. */
  173.       case OUTFIT_TYPE_BEAM:
  174.       case OUTFIT_TYPE_TURRET_BEAM:
  175.          if ((outfit->type == OUTFIT_TYPE_TURRET_BEAM) && (w->parent!=w->target)) {
  176.             pilot_target = pilot_get(target);
  177.             rdir = (pilot_target == NULL) ? dir :
  178.                   vect_angle(pos, &pilot_target->solid->pos);
  179.          }
  180.          else
  181.             rdir = dir;
  182.          if (rdir < 0.)
  183.             rdir += 2.*M_PI;
  184.          else if (rdir >= 2.*M_PI)
  185.             rdir -= 2.*M_PI;
  186.          mass = 1.; /**< Needs a mass. */
  187.          w->solid = solid_create( mass, rdir, pos, NULL );
  188.          w->think = think_beam;
  189.          w->timer = outfit->u.bem.duration;
  190.          w->voice = sound_playPos( w->outfit->u.bem.sound,
  191.                w->solid->pos.x,
  192.                w->solid->pos.y,
  193.                w->solid->vel.x,
  194.                w->solid->vel.y);
  195.          break;
  196.  
  197.       /* Treat seekers together. */
  198.       case OUTFIT_TYPE_AMMO:
  199.       case OUTFIT_TYPE_TURRET_AMMO:
  200.          if (w->outfit->type == OUTFIT_TYPE_TURRET_AMMO) {
  201.             pilot_target = pilot_get(w->target);
  202.             if (pilot_target == NULL)
  203.                rdir = dir;
  204.  
  205.             else {
  206.                /* Get the distance */
  207.                dist = vect_dist( pos, &pilot_target->solid->pos );
  208.  
  209.                /* Aim. */
  210.                /* Try to predict where the enemy will be. */
  211.                /* Time for shots to reach that distance */
  212.                if (outfit->u.amm.thrust == 0.)
  213.                   t = dist / (w->outfit->u.amm.speed + VMOD(*vel));
  214.                else
  215.                   t = dist / w->outfit->u.amm.speed;
  216.  
  217.                /* Position is calculated on where it should be */
  218.                x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
  219.                   - (pos->x + vel->x*t);
  220.                y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
  221.                   - (pos->y + vel->y*t);
  222.  
  223.                /* Set angle to face. */
  224.                rdir = ANGLE(x, y);
  225.             }
  226.          }
  227.          else {
  228.             rdir = dir;
  229.          }
  230.          if (outfit->u.amm.accuracy != 0.) {
  231.             rdir += RNG_2SIGMA() * outfit->u.amm.accuracy/2. * 1./180.*M_PI;
  232.             if ((rdir > 2.*M_PI) || (rdir < 0.))
  233.                rdir = fmod(rdir, 2.*M_PI);
  234.          }
  235.          if (rdir < 0.)
  236.             rdir += 2.*M_PI;
  237.          else if (rdir >= 2.*M_PI)
  238.             rdir -= 2.*M_PI;
  239.  
  240.          /* If thrust is 0. we assume it starts out at speed. */
  241.          vectcpy( &v, vel );
  242.          if (outfit->u.amm.thrust == 0.)
  243.             vect_cadd( &v, cos(rdir) * w->outfit->u.amm.speed,
  244.                   sin(rdir) * w->outfit->u.amm.speed );
  245.  
  246.          /* Set up ammo details. */
  247.          mass        = w->outfit->mass;
  248.          w->lockon   = outfit->u.amm.lockon;
  249.          w->timer    = outfit->u.amm.duration;
  250.          w->solid    = solid_create( mass, rdir, pos, &v );
  251.          if (w->outfit->u.amm.thrust != 0.)
  252.             weapon_setThrust( w, w->outfit->u.amm.thrust * mass );
  253.  
  254.          /* Handle seekers. */
  255.          if (w->outfit->u.amm.ai > 0) {
  256.             w->think = think_seeker; /* AI is the same atm. */
  257.  
  258.             /* If they are seeking a pilot, increment lockon counter. */
  259.             pilot_target = pilot_get(target);
  260.             if (pilot_target != NULL)
  261.                pilot_target->lockons++;
  262.          }
  263.  
  264.          /* Play sound. */
  265.          w->voice    = sound_playPos(w->outfit->u.amm.sound,
  266.                w->solid->pos.x,
  267.                w->solid->pos.y,
  268.                w->solid->vel.x,
  269.                w->solid->vel.y);
  270.          break;
  271.  
  272.       /* just dump it where the player is */
  273.       default:
  274.          WARN("Weapon of type '%s' has no create implemented yet!",
  275.                w->outfit->name);
  276.          w->solid = solid_create( 1., dir, pos, vel );
  277.          break;
  278.    }
  279.  
  280.    /* Set life to timer. */
  281.    w->life = w->timer;
  282.  
  283.    return w;
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement