/** * @brief Modifies the player's standing with a faction. * * Affects enemies and allies too. * * @param f Faction to modify player's standing. * @param mod Modifier to modify by. * * @sa faction_modPlayerRaw */ void faction_modPlayer( int f, double mod ) { int i; Faction *faction; double m; if (!faction_isFaction(f)) { WARN("%d is an invalid faction", f); return; } /* Modify faction standing with parent faction. */ faction_modPlayerRaw( f, mod ); /* Now mod allies to a lesser degree */ faction = &faction_stack[f]; for (i=0; i<faction->nallies; i++) { /* Enemies are made faster. */ m = RNG_2SIGMA()/4. + 0.5; if (mod > 0.) m *= 0.75; /* Modify faction standing */ faction_modPlayerRaw( faction->allies[i], m*mod ); } /* Now mod enemies */ for (i=0; i<faction->nenemies; i++) { /* Enemies are made faster. */ m = RNG_2SIGMA()/4. + 0.5; if (mod < 0.) m *= 0.75; /* Modify faction standing. */ faction_modPlayerRaw( faction->enemies[i], -m*mod ); } }
/** * @brief Calculates the intensity in a system node. * * @todo Make it time/item dependent. */ static double econ_calcSysI( unsigned int dt, StarSystem *sys, int price ) { (void) dt; (void) sys; (void) price; return 0.; #if 0 int i; double I; double prodfactor, p; double ddt; Planet *planet; ddt = (double)(dt / NTIME_UNIT_LENGTH); /* Calculate production level. */ p = 0.; for (i=0; i<sys->nplanets; i++) { planet = sys->planets[i]; if (planet_hasService(planet, PLANET_SERVICE_INHABITED)) { /* * Calculate production. */ /* We base off the current production. */ prodfactor = planet->cur_prodfactor; /* Add a variability factor based on the Gaussian distribution. */ prodfactor += ECON_PROD_VAR * RNG_2SIGMA() * ddt; /* Add a tendency to return to the planet's base production. */ prodfactor -= ECON_PROD_VAR * (planet->cur_prodfactor - prodfactor)*ddt; /* Save for next iteration. */ planet->cur_prodfactor = prodfactor; /* We base off the sqrt of the population otherwise it changes too fast. */ p += prodfactor * sqrt(planet->population); } } /* The intensity is basically the modified production. */ I = p / ECON_PROD_MODIFIER; return I; #endif }
/** * @brief Creates a number in the two-sigma range [-2:2]. * * This function behaves much like the rnd.sigma function but uses the two-sigma range, * meaning that numbers are in the 95% quadrant and thus are much more random. They are * biased towards 0 and approximately 63% will be within [-1:1]. The rest will be in * either the [-2:-1] range or the [1:2] range. * * @usage n = 5.5 + rnd.twosigma()/4. -- Creates a number from 5 to 6 heavily biased to 5.5. * * @luareturn Returns a number from [-2:2] biased heavily towards 0. * @luafunc twosigma() */ static int rnd_twosigma( lua_State *L ) { lua_pushnumber(L, RNG_2SIGMA()); return 1; }
/** * @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 ID. * @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 unsigned int parent, const unsigned int target ) { Vector2d v; double mass, rdir; Pilot *pilot_target; double x,y, t, dist; Weapon* w; /* Create basic features */ w = malloc(sizeof(Weapon)); memset(w, 0, sizeof(Weapon)); w->faction = pilot_get(parent)->faction; /* non-changeable */ w->parent = parent; /* 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) { 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)); /* 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 /* fire straight */ rdir = dir; rdir += RNG_2SIGMA() * outfit->u.blt.accuracy/2. * 1./180.*M_PI; 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; }