Split upd_slmilcosts() into prep_ships() and prep_lands(). Move the
sanity check for dead ships and land units from prod_ships() and
prod_lands() there. Move their call from prepare_sects() to its
caller, along with pay_reserve().
Create prep_planes() for symmetry. Pilots are now paid at the same
time as other military. Can matter only when the country goes broke
during the update.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When option TECH_POP is enabled, the cost of tech increases when
civilian population exceeds 50000. Only civilians in old-owned
sectors count. This differs from education and happiness, where
civilians loaded on ships and land units count, too.
The update counts population for TECH_POP with count_pop(). This is
an extra pass over all sectors.
produce also uses count_pop(), once per tech center examined.
Wasteful.
budget avoids count_pop(): it uses tax()'s civilian count. More
efficient, but the difference to the update is ugly.
Change TECH_POP to use the same civilian count as education and
happiness, i.e. count civilians on ships and land units, too.
This count is available in nat_budget[] in time for produce(): it's
computed by tax() and by ship and land unit maintenance. So use it
there. This takes care of the update and budget. produce doesn't run
enough update code to do the same. Keep calling count_pop() there.
Update it to match the update, and give it internal linkage.
Duplicating update's workings there is ugly, so mark it FIXME.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The update tallies income and expenses in full dollars. Each debit or
credit is rounded before it is added to the tally. Different things
are rounded differently. Examples:
* Each sector's military pay is rounded down. In the stock game, 1m
is paid $4.999998, so n mil cost n*$5 -$1, for all practical n. 10m
in one sector cost $49, but spread over ten sectors they cost only
$40.
* Total pay for military in ships and land units is rounded down.
* Each plane's military pay is rounded down (used to be rounded up
except for broke countries until recent commit 2eb08f4). In the
stock game, flight pay is 5 * $4.999998 = $24.99999. For a plane
with n mil, that's n * $25 - $1. Filed under plane maintenance, not
military payroll.
* Each sector's civilian tax is rounded. In the stock game, 1c pays
$0.499998. 10c in one sector pay $5, but spread over ten sectors
they pay nothing.
* An occupied sector's civilian tax is first rounded, then divided by
four and rounded down *boggle*.
* Each sector's uw tax is rounded. In the stock game, 1u pays
$0.106662. 1-4u in one sector pay nothing. 5-14u pay $1.
This is madness. Has always been that way.
Drop the rounding and track money in type double throughout the
update. Round only the final amount, randomly. This is similar to
how commands accumulate a money delta in player->dolcost.
Likewise, tally the subtotals for budget in type double. Display them
rounded to full dollars.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The update simply updates each nation's nat_money as it goes. Works.
Except it doesn't update when it runs on behalf of budget. But it
still checks nat_money to determine whether the nation is solvent.
These checks are all broken. Leads to massive mispredictions when
you'd go broke or solvent during a real update.
Track money unconditionally in nat_budget[].money. Delay update of
nat_money until prod_nat(). Replace separate money[] by new
nat_budget[].start_money. Closes bug#235.
Remaining difference between budget and update in the update test:
* #1: budget mispredicts plane #100 gets built (to be fixed)
* #2: budget shows ship, plane and land unit maintenance when broke,
but update damages them instead (correct)
* #2: sector -14,0 converts, quadrupling its taxes (correct)
* #4 & #5: bank with dust and bars taken over by che (correct)
* #4: plague deaths (correct)
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Extend struct budget member bm[] to cover ships, planes and land
units, too.
Plane maintenance changes because pilot pay is now consistently
rounded down. Before it was rounded down for broke countries, else
up. The stock game's pilots earn a little less than $25, and solvent
countries save $1 per plane. The rounding doesn't make much sense
either way. To be be addressed in a later commit.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The update summarizes sector production, building and maintenance for
budget in a two-dimensional array int p_sect[SCT_BUDG_MAX+1][2]. All
references into this array use literals as second subscript. Bzzzt,
wrong data type.
Add two one-dimensional arrays to nat_budget[], one for production,
and one for building and maintenance. p_sect[i] becomes
nat_budget[cnum].prod[i] for production, and .bm[j] for building and
maintenance. p_sect[i][0] becomes .count, and -p_sect[i][1] becomes
.money.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When we add up military payroll, we discard fractions. Payroll is
therefore lower than it should be, but I'm not fixing that now. The
number of military budget reports is actually computed from payroll,
and therefore also low.
The obvious way to fix that would be adding another out parameter to
tax() and upd_slmilcosts(). However, budget and the update track cost
and count of numerous things (sector products, unit maintenance and
building, ...), and it's time for a common way to do that.
Create struct budget_item for tracking cost and count, and struct
budget nat_budget[MAXNOC] for tracking a nation's budget. Track only
military for now; more to follow.
This fixes the military count. The cost of military remains low,
because we discard fractions exactly as before.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This way, tax() is more focused, and populace() doesn't need to be
guarded with !player->simulation.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Code dealing with money mixes int and long pretty haphazardly.
Harmless, because practical amounts of money fit into int on any
machine capable of running the server. Clean up anyway.
Code dealing with reserves mixes int and long pretty haphazardly.
Harmless, because practical reserves fit easily on any machine capable
of running the server. Clean up anyway.
Code dealing with counting people mixes int and long pretty
haphazardly. Harmless, because practical populations fit into int
easily on any machine capable of running the server. Clean up anyway.
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
Replace the fixed $1 per ETU maintenance for capital/city sectors that
are at least 60% efficient by a configurable maintenance cost, payable
regardless of efficiency. The only change in the default
configuration is that inefficient capitals now pay maintenance.
Charging sector maintenance regardless of efficiency is consistent
with unit maintenance.
New struct dchrstr member d_maint and sector-chr selector maint. Make
show_sect_build() show it. Change produce_sect() to record
maintenance in new slot p_sect[SCT_MAINT] instead of abusing
p_sect[SCT_CAPIT]. Replace the "Capital maintenance" line in budget
by "Sector maintenance".
type. Make it abstract because that's possible. Change data layout
so that the slots belonging to a sector are together in memory, it's
nicer to the cache.
(bp): The new type. Users changed.
(get_wp): Update accordingly.
(alloc_bp): New.
(update_main, calc_all): Use it. Before, calc_all() allocated 1/7
more than necessary.
other. Ensure headers in include/ can be included in any order
(except for econfig-spec.h, which is special). New header types.h to
help avoid inclusion cycles. Sort include directives. Remove some
superflous includes.
missing bits:
(budg, calc_all, update_main): Use SCT_TYPE_MAX instead of SCT_MAXDEF
to size tables.
(map_char): Update sanity check; use CANT_HAPPEN().
(show_sect_build, show_sect_stats, show_sect_capab): Use the sentinel
instead of SCT_MAXDEF.
plus one. Users changed. This indirectly fixes off-by-one loop
bounds in budg(), show_sect_build(), show_sect_stats() and
show_sect_capab(). The show bugs were harmless: the loops ran into
the sentinel, which they ignore. The budg bug was serious: the loop
ran into the entries for SCT_EFFIC. This lead to a bogus line in the
budget, printing of a null pointer, and doubled sector build cost.
Budget priorities masked this bug until rev. 1.25.
priorities (rev. 1.25), calc_all() tried to match the real sequence,
but didn't quire succeed to cope with all variations. Then it matched
until the update sequence change in src/lib/update/main.c rev. 1.25.
This is required but not sufficient for closing #1310407.
(P_LCM, P_HCM, P_TLEV, P_RLEV, P_ELEV, P_HLEV, P_URAN): Use -1 instead
of 0 for `no product', shift down product indexes and update
product.config and sector.config accordingly.
(budg, prod, show_sect_capab, produce, produce_sect): Adapt test for
no product.
(ef_elt_byname): Remove the hack to hide pchr[0].
(prod_eff): Oops on no product.
actually be paid in full didn't take the update sequence into account,
and wasn't implemented for sector building, military payroll and
capital maintenance. Remove the feature, as fixing is hardly worth
the trouble. This renders prexpense() trivial; inline and remove.
(prxy, border, ac_encounter, look, budg): Fix misuse of pr() and PR():
passed formatted string instead of format string and arguments.
Correctness depends on argument values and tables not containing '%',
which is correct, but fragile.