empserver/src/lib/subs/landgun.c
Markus Armbruster 9f25de3dce Change comment style to use @foo rather than FOO
... when referring to a function's parameter or a struct/union's
member.

The idea of using FOO comes from the GNU coding standards:

    The comment on a function is much clearer if you use the argument
    names to speak about the argument values.  The variable name
    itself should be lower case, but write it in upper case when you
    are speaking about the value rather than the variable itself.
    Thus, "the inode number NODE_NUM" rather than "an inode".

Upcasing names is problematic for a case-sensitive language like C,
because it can create ambiguity.  Moreover, it's too much shouting for
my taste.

GTK-Doc's convention to prefix the identifier with @ makes references
to variables stand out nicely.  The rest of the GTK-Doc conventions
make no sense for us, however.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2015-12-05 12:13:17 +01:00

308 lines
6.7 KiB
C

/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2015, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure, Markus Armbruster
*
* Empire is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* landgun.c: Fire weapons
*
* Known contributors to this file:
* Markus Armbruster, 2006-2013
*/
#include <config.h>
#include "chance.h"
#include "damage.h"
#include "file.h"
#include "land.h"
#include "nat.h"
#include "optlist.h"
#include "prototypes.h"
#include "sect.h"
#include "ship.h"
static double
fortgun(int effic, int guns)
{
double d;
double g = MIN(guns, 7);
d = (roll(30) + 19.0) * (g / 7.0);
d *= effic / 100.0;
return d;
}
static double
seagun(int effic, int guns)
{
double d;
d = 0.0;
while (guns--)
d += 9.0 + roll(6);
d *= effic * 0.01;
return d;
}
static double
landunitgun(int effic, int guns)
{
double d;
d = 0.0;
while (guns--)
d += 4.0 + roll(6);
d *= effic * 0.01;
return d;
}
/*
* Fire from fortress @sp.
* Use ammo, resupply if necessary.
* Return damage if the fortress fires, else -1.
*/
int
fort_fire(struct sctstr *sp)
{
int guns = sp->sct_item[I_GUN];
if (sp->sct_type != SCT_FORTR || sp->sct_effic < FORTEFF)
return -1;
if (sp->sct_item[I_MILIT] < 5 || guns == 0)
return -1;
if (!sct_supply(sp, I_SHELL, 1))
return -1;
sp->sct_item[I_SHELL]--;
return (int)fortgun(sp->sct_effic, guns);
}
/*
* Fire from ship @sp.
* Use ammo, resupply if necessary.
* Return damage if the ship fires, else -1.
*/
int
shp_fire(struct shpstr *sp)
{
int guns;
if (sp->shp_effic < 60)
return -1;
guns = shp_usable_guns(sp);
guns = MIN(guns, (sp->shp_item[I_MILIT] + 1) / 2);
if (guns == 0)
return -1;
shp_supply(sp, I_SHELL, (guns + 1) / 2);
guns = MIN(guns, sp->shp_item[I_SHELL] * 2);
if (guns == 0)
return -1;
sp->shp_item[I_SHELL] -= (guns + 1) / 2;
return (int)seagun(sp->shp_effic, guns);
}
/*
* Drop depth-charges from ship @sp.
* Use ammo, resupply if necessary.
* Return damage if the ship drops depth-charges, else -1.
*/
int
shp_dchrg(struct shpstr *sp)
{
int dchrgs;
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_DCH) == 0)
return -1;
if (sp->shp_item[I_MILIT] == 0 || sp->shp_item[I_GUN] == 0)
return -1;
shp_supply(sp, I_SHELL, 2);
dchrgs = MIN(2, sp->shp_item[I_SHELL]);
if (dchrgs == 0)
return -1;
sp->shp_item[I_SHELL] -= dchrgs;
return (int)seagun(sp->shp_effic, 2 * dchrgs - 1);
}
/*
* Fire torpedo from ship @sp.
* Use ammo and mobility, resupply if necessary.
* Return damage if the ship fires, else -1.
*/
int
shp_torp(struct shpstr *sp, int usemob)
{
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_TORP) == 0)
return -1;
if (sp->shp_item[I_MILIT] == 0 || sp->shp_item[I_GUN] == 0)
return -1;
if (usemob && sp->shp_mobil <= 0)
return -1;
if (!shp_supply(sp, I_SHELL, SHP_TORP_SHELLS))
return -1;
sp->shp_item[I_SHELL] -= SHP_TORP_SHELLS;
if (usemob)
sp->shp_mobil -= (int)shp_mobcost(sp) / 2.0;
return TORP_DAMAGE();
}
/*
* Fire from land unit @lp.
* Use ammo, resupply if necessary.
* Return damage if the land unit fires, else -1.
*/
int
lnd_fire(struct lndstr *lp)
{
int guns, ammo, shells;
double d;
if (lp->lnd_effic < LAND_MINFIREEFF)
return -1;
if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
return -1;
if (lp->lnd_item[I_MILIT] == 0)
return -1;
guns = lnd_dam(lp);
guns = MIN(guns, lp->lnd_item[I_GUN]);
if (guns == 0)
return -1;
ammo = lchr[lp->lnd_type].l_ammo;
if (CANT_HAPPEN(ammo == 0))
ammo = 1;
lnd_supply(lp, I_SHELL, ammo);
shells = lp->lnd_item[I_SHELL];
if (shells == 0)
return -1;
d = landunitgun(lp->lnd_effic, guns);
if (shells < ammo) {
d *= (double)shells / (double)ammo;
ammo = shells;
}
lp->lnd_item[I_SHELL] -= ammo;
return d;
}
/*
* Sabotage with land unit @lp.
* Use ammo.
* Return damage if the land unit sabotages, else -1.
*/
int
lnd_sabo(struct lndstr *lp, short item[])
{
int dam;
if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
return -1;
if (!(lchr[lp->lnd_type].l_flags & L_SPY))
return -1;
if (!lp->lnd_item[I_SHELL])
return -1;
lp->lnd_item[I_SHELL]--;
dam = fortgun(3 * lp->lnd_effic, 7);
if (item[I_SHELL] > 20)
dam += seagun(lp->lnd_effic, roll0(item[I_SHELL] / 10));
if (item[I_PETROL] > 100)
dam += seagun(lp->lnd_effic, roll0(item[I_PETROL] / 50));
return dam;
}
/*
* Return number of guns ship @sp can fire.
*/
int
shp_usable_guns(struct shpstr *sp)
{
return MIN(shp_glim(sp), sp->shp_item[I_GUN]);
}
/*
* Return effective firing range for range factor @rng at tech @tlev.
*/
static double
effrange(int rng, double tlev)
{
/* FIXME don't truncate TLEV */
return techfact((int)tlev, rng / 2.0);
}
/*
* Return firing range for sector @sp.
*/
double
fortrange(struct sctstr *sp)
{
struct natstr *np = getnatp(sp->sct_own);
double rng;
if (sp->sct_type != SCT_FORTR || sp->sct_effic < FORTEFF)
return -1.0;
rng = effrange(14.0 * fire_range_factor, np->nat_level[NAT_TLEV]);
if (sp->sct_effic >= 60)
rng++;
return rng;
}
/*
* Return firing range for ship @sp.
*/
double
shp_fire_range(struct shpstr *sp)
{
return effrange(shp_frnge(sp), sp->shp_tech);
}
/*
* Return torpedo range for ship @sp.
*/
double
torprange(struct shpstr *sp)
{
return effrange(shp_frnge(sp) * 2, sp->shp_tech)
* sp->shp_effic / 100.0;
}
/*
* Return hit chance for torpedo from ship @sp at range @range.
*/
double
shp_torp_hitchance(struct shpstr *sp, int range)
{
return DTORP_HITCHANCE(range, shp_visib(sp));
}
/*
* Return firing range for land unit @sp.
*/
double
lnd_fire_range(struct lndstr *lp)
{
return effrange(lnd_frg(lp), lp->lnd_tech);
}
int
roundrange(double r)
{
return roundavg(r);
}