mksubj.pl neglects to terminate info/toc's last line with a newline.
info-test doesn't care. Tidy up anyway.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Deliver fails to abandon sectors when it ships out all civilians and
military. The sector remains owned until the next non-update sector
update abandons it. Has always been broken.
Distribution had the same bug until commit d0f3847 (v4.3.20) fixed it.
Fix it the same way for delivery: adjust the amount moved to avoid
moving out the last civilian, or the last military if there are no
civilians.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
People in sectors get plagued, then taxed or paid, then fed. People
on ships and land units get paid, then fed, then plagued. Sectors
were messed up when Empire 3 made the update code work for budget.
Change sectors back to how they worked before Empire 3: move do_feed()
from produce_sect() to prepare_sects(), and delay do_plague() until
after do_feed(). People in sectors now get taxed, paid and fed even
when they die of the plague, just like they do on ships and land
units.
Because do_plague() now runs after populace(), the latter's handling
of people dying off doesn't cover plague anymore. Delay it to the
very end of prepare_sects().
Additionally, move feeding and plaguing from upd_ship(), upd_land() to
prep_ship(), prep_land(), for consistency with sectors.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Ship, plane and land unit repairs depend on and change the state of
the sector. To predict repairs, we need to predict the state of the
sector before repairs. The obvious way to do that is to simulate the
sector update and all ship, plane and land unit updates there in the
correct order.
Until recently, we simulated only own sectors, ships, planes and land
units. Wrong when foreign sectors, ships, planes or land units are
involved. The fix (commit 70f6964) makes budget simulate all
countries. Correct, but does much more work than necessary. With a
little effort, we can track what needs to be simulated.
Use the bp map for tracking. We need to mark the player's sectors and
all sectors where he has ships, planes or land units. Do the former
in bp_alloc(), and the latter in prep_ships(), prep_planes(),
prep_lands().
Skip sectors not so marked. This requires delaying prepare_sects()
until after prep_ships(), prep_planes(), prep_lands(). Their order
doesn't actually matter: prep_ships() & friends only spend money, and
nothing in preparation depends on whether the country is still
solvent.
Skip ships, planes and land units in sectors not so marked.
This speeds up budget by around a third in my testing, more for small
countries. Roughly 15% slower than before the fix for repairs abroad.
The update has to do a bit more work than before, but the performance
difference is lost in the noise.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The update visits sectors in increasing order of country number.
Within a country, it visits in increasing order of sector number,
which is effectively top to bottom, left to right, starting with
absolute 0,0.
The order doesn't actually matter. Before Chainsaw's option BUDGET,
the update simply visited the sectors in sector number order. Go back
to that order, because it's faster. For the update, it's a few
percent in my testing. For budget, it's more than a third.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The update visits ships, planes and land units in increasing order of
country number. Within a country, it visits first ships, then planes,
then land units, each in increasing order of unit number.
The order is relevant when money, materials and work don't suffice to
build everything.
Money is charged to the owner, so only the relative order for the same
owner matters there. One order is as good as any.
Work and materials come from the sector, so only the relative order in
each sector matters. The current order unfairly prefers countries
with lower country numbers. Mitigating factor: the affected countries
need to be friendly (ships only) or allied.
The unfairness goes back to Chainsaw's option BUDGET. See the commit
before previous for more detailed historical notes.
The update test demonstrates the unfair behavior: sector 14,6 builds
ships 95/97 owned by country#1, but not 96 owned by country#7.
Likewise, planes 95/96/97 and land units 95/96/97.
Go back to the the pre-BUDGET order: first ships, then planes, then
land units, all in increasing order of unit number, regardless of
owner.
The update test now builds ship, plane and land unit 96 instead of 97.
Bonus: speeds up both the update and budget by a similar absolute
amount. For budget, this is roughly a factor of two in my testing.
For the update, which does much more, it's around 10%.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Ship, plane and land unit repair uses new work, except in sectors
owned by countries with a higher country number.
This inconsistency is an artifact of how the update is sequenced: we
work on countries one after the other. A country's ships, planes and
land units get repaired before higher-numbered countries' sectors
produce. Any ship, plane and land unit repairs in such sectors use
old work instead of new work.
Repair work use changed several times during Empire's history.
In BSD Empire, repairs use old work, because it updates ships and
planes before sectors.
Chainsaw added budget priorities and the budget command as option
BUDGET. Budget priorities let players choose separately for ships,
planes and land units whether to use old or new work for repairs.
The option also changed the update to work on countries one after the
other, presumably to permit a more efficient implementation of the
budget command.
Chainsaw also introduced repairs in foreign sectors under option
ALLYHARBORWORK.
With BUDGET disabled, all repairs still use old work, whether at home
or abroad. With BUDGET enabled, work use of repairs at home depends
on budget priorities, but work use abroad depend on country numbers.
Both options became standard in Empire 2.
Since v4.3.6, repairs at home always use new work (commit 967299a and
commit 520446e).
To make repairs abroad always use new work as well, we need to update
all sectors before any ship repair. This is straightforward: split
the loop over countries between sectors and unit building. For
symmetry, also split it between unit maintenance and sectors.
The budget command is differently broken, and will be fixed next.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
People in sectors first eat, then build the sector, then produce.
People in ships produce, eat, then build.
The starvation command can be off for fishing vessels, because it
doesn't consider the food they produce.
Change ships to match sectors. "Fixes" starvation. Fishing boats and
oil derricks being repaired at sea become a bit more productive.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
prod() duplicates the update's sector production code, except it
computes both output with present materials ("make" output) and output
not limited by lack of materials or production backlog ("max" output).
It also rounds materials consumed up instead of randomly.
Factor prod_output() out of produce() for reuse by prod(). prod()
runs it twice: once for "make" output and once for "max" output.
Test output changes are due to random rounding.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The collection value of a sector is
sector value = sector type value * (sector efficiency + 100)
+ sum of item values
item value = item type value * amount
The sector and item type values are configurable.
The item type collect values aren't too far off the power values:
uid mnem pow val pow/val
0 "c" 50 1 50
1 "m" 100 0 inf
2 "s" 125 5 25
3 "g" 950 60 15.8
4 "p" 7 4 1.75
5 "i" 10 2 5
6 "d" 200 20 10
7 "b" 2500 280 8.9
8 "f" 0 0 NaN
9 "o" 50 8 6.25
10 "l" 20 2 10
11 "h" 40 4 10
12 "u" 50 1 50
13 "r" 50 150 0.33
The power value is very roughly ten times the collect value, except
for civilians and uw it's 50, for rads its 0.33, and military are free
to collect. The latter two make no sense.
Replace the item type collect value by the power value / 50 for
people, and by the power value / 10 for everything else. This makes
collecting military, shells, guns and uw more expensive, and petrol,
bars, iron, oil and rads cheaper.
The sector type values are basically arbitrary. For instance, an iron
mine costs five times as much as a wilderness, but a third of an
uranium mine, regardless of actual resource contents.
Replace this by different arbitrary values:
sector value = (item value of materials necessary to build it
+ build cost) * efficiency / 100
+ sector type maximum population
+ sum of item values
Some sector types become cheaper, some more expensive.
Drop sect-chr and item selector value.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The whole idea of a sector acquiescing to takeover by lawyers waving
loan documents "proving" it's rightfully theirs is pretty
preposterous. But a capital giving itself up that way (and then
paying out half the nation's treasury on top) beggars belief.
Disallow it.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When collect refuses to confiscate a sector because it's value exceeds
the amount owed, it still tells the player the exact value. Don't.
Don't give the player something for nothing.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Replace the term
power value of materials and cost + 9
by
power value of materials and cost + maximum population / 1000 * 8 + 1
The value of ordinary sectors (maximum population 1000) doesn't
change. The stock game's mountains, plains and bridges are now worth
only 28% as much.
This concludes my tweaking of the power factor for now. I tested it
with data from a real game (Hvy Metal II). The effect is small: #5
overtakes #4, and the lead of #1 over #2 and #3 shrinks some. Closer
analysis finds the following reasons. The game had very expensive big
cities. Valuing them correctly gives countries with many cities a
noticeable boost. Planes are worth less than before, but the
difference is much larger for cheap planes. Big piles of construction
materials are worth much less, and shells, guns and bars are worth
more.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Building sectors can make you rate *lower* on the power chart, because
the power factor treats all sectors the same, regardless of build
materials and cost.
To avoid that, replace the term
efficiency / 10.0
by
(power value of materials + power value of cost + 9)
* efficiency/100.0
The value of ordinary sectors, which take no materials and cost $100,
doesn't change. The stock game's fortress is now worth 80% more due
to its materials and higher cost. The stock game's wilderness is
worth 10% less, because it costs nothing.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Give sector types capability flags (dchrstr member d_flags), like
ship, plane, land unit and nuke types have.
Member d_cost is effectively a flag since the previous commit.
Replace it by capability flag "deity". This is an xdump compatibility
break. To provide the customary grace period, we'd have make selector
cost virtual instead, and deprecate it. But we're not bothering with
maintaining xdump compatibility in this release.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Chainsaw 3 added the designate cost along with extra build cost and
materials, and used both to make fortresses expensive. Unlike build
cost and materials, the cost to designate didn't pass the test of
time: it was set to zero in Empire 2. Get rid of it.
sect-chr selector cost and struct dchrstr member d_cost have to stay,
because they're still used to configure whether a sector may be
designated by players (see commit 8d792e1).
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Building nukes makes you rate *lower* on the power chart, because the
power factor ignores nukes. Fix that.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Items, ships, planes and land units all contribute to the power
factor, which determines position on the power chart.
Items are worth
amount * item value * (0.5 + nation tech level / 1000.0)
The item values aren't quite right: producing stuff can *hurt* your
position on the power chart. Food, uw and rads are worth nothng.
Reduce the value of oil, and give rads the same value as oil. Tweak
value of iron and oil products so that production's power change is
roughly zero around p.e. 0.9 (tech 110), except for construction
materials, where it's zero at p.e. 0.5 (tech 0). Construction
materials become less valuable, shells, guns and petrol become more
valuable. Increase value of bars to roughly match the other changes.
It may still be too low. Halve the value of civilians, and give the
other half to uw. Results:
old new change
civ 100 50 / 2
mil 100 100
shell 80 125 * 1.5625
gun 400 950 * 2.375
pet 2 7 * 3.5
iron 10 10
dust 200 200
bar 1000 2500 * 2.5
food 0 0
oil 100 50 / 2
lcm 100 20 / 5
hcm 200 40 / 5
uw 0 50 new
rad 0 50 new
Ships, planes and land units are worth
base value * effic/100.0 * (0.5 + unit tech level / 1000.0)
For ships and land units, the base value is
lcm/5.0 + hcm/5.0
Build cost is ignored, but lcms are valued twice as much "loose" ones
(before this commit). Therefore, building stuff can change your
position on the power chart in both directions, depending on the type
of build.
For planes, the base value is
20 * (0.5 + nation tech level / 1000.0)
Build cost and materials are ignored, and tech is squared. This
is plainly absurd.
Unify to
(power value of money and materials to build) * effic/100.0
This formula is chosen so that building stuff doesn't change your
power factor. Bonus: it doesn't assume anything about possible build
materials.
For ships and land units, factoring in build cost overcompensates the
discounted value of construction materials more often than not.
Noteworthy changes for the stock game:
ship type old new change
ss slave ship 20 5.8 * 0.29 largest decrease
cs cargo ship 20 7.8 * 0.39
ts trade ship 60 25.5 * 0.42
frg frigate 12 7.8 * 0.65
bb battleship 24 21.8 * 0.91
cal light carrier 22 30.4 * 1.38
can nuc carrier 30 84.6 * 2.82 largest increase
land unit type old new change
hat hvy artillery 12 9.6 * 0.8 largest decrease
linf light infantry 2.4 3.32 * 1.38
cav cavalry 3 5.4 * 1.8
inf infantry 3 5.4 * 1.8
lar lt armor 3 6.4 * 2.13
com commando 3 15.4 * 5.13
eng engineer 3 30.4 * 10.13
meng mech engineer 3 45.4 * 15.13 largest increase
For planes, the power value change depends on the type. Below a
certain nation tech level, planes of this type become more valuable,
above less.
For the stock game, planes costing at most $1000 become less valuable
at any nation tech level that can build them, and planes costing at
least $1800 become more valuable at any practical tech level,
i.e. under 400. Noteworthy planes:
plane type new
sam Sea Sparrow 2.1 least valuable
f2 P-51 Mustang 4.34
lb TBD-1 Devastator 5.92
jf1 F-4 Phantom 10.6
tr C-56 Lodestar 10.78
jt C-141 Starlifter 15.86
jhb B-52 Strato-Fortress 33.54
ss KH-7 spysat 41.2 most valuable
The old value is a flat 12 at nation tech level 100, 15 at tech level
250, and 18 at tech level 400.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Actual abilities of ships, planes and land units depend almost
completely on the individual unit's tech, not the nation's tech. The
power factor should reflect that.
The power value of a unit is of the form
base value * (20 + nation's tech level) / 500
Change it to
base value * (20 + unit's tech level) / 500
Note that a plane's base value still depends on the nation's tech
level. This commit merely makes the absurdity stand out a bit more.
To be fixed later.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
In the old times, power didn't consider tech at all. Chainsaw's
option NEWPOWER (mandatory since v4.2.14, on by default before)
changed this dramatically: the power factor gets multiplied by
max(1, tech) / 500.
In the early game, small absolute tech differences yield large power
factor differences. For instance, if country A has tech level 10, and
B has 5, then A gets a factor two boost.
As the game progresses, tech differences between viable countries tend
to grow, but only slowly. The influence on power diminishes. For
instance, if C has tech level 270 and D has 240 (quite a respectable
tech lead), then C gets a modest 1.125x boost over D.
Change the factor to (20 + tech) / 500. Now A's advantage is only
1.2, and C's is 1.115.
You might think that's rather low. However, tech is not power unless
you project it, and then it manifests itself as sectors, population
and other stuff power counts.
The same tech term occurs in plane power, except with just tech
instead of max(1, tech) . Change it there as well, for consistency.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
If option RES_POP is enabled, the power factor is multiplied by a
"research factor" of 1.0 + maxpop / 10000.0, where maxpop is the
maximum population of a mine sector.
Back when this code was written (Chainsaw 3), all sectors had the same
population limit, so using a mine sector was as good as any. Since
then, it has become configurable, and the stock game has both sector
types with lower (mountains, plains) and with higher (cities)
population limits.
Space for people is worth considering for power, but multiplying total
power by a fudge factor based on the most common sector type's maximum
population is silly. Drop it.
Adjusting each sector's value for maximum population would make more
sense, with and without RES_POP. Perhaps later.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The work required for build and repairs is traditionally a function of
build materials: 20 + lcm + 2*hcm for ships, planes and land units,
and (lcm + 2*hcm + oil + rad)/5 for nukes. Make it independently
configurable instead, via new ship-chr, plane-chr, land-chr, nuke-chr
selector bwork, backed by new struct mchrstr member m_bwork, struct
plchrstr member pl_bwork, struct lchrstr member l_bwork, struct
nchrstr member n_bwork. Keep the required work exactly the same for
now.
Clients that compute work from materials need to be updated. Easy,
since build work is now exposed in xdump.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Commit eb1512d (v4.3.6) added the '=' if stopped before efficiency.
Commit 016249c (v4.3.6) changed it to '!' without updating info ship,
plane, land, nuke.
Reported-by: Harald Katzer
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
The cost of firing naval guns is 15 mobility with option NOMOBCOST
disabled. Mobility.t is correct.
Fix Options.t not to claim submarines pay half the sector movement
cost when NOMOBCOST is enabled.
Fix fire.t not to claim ships pay half the sector movement cost when
NOMOBCOST is disabled.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Don't list options separately for major server versions. It's only of
historical interest, which "info History" satisfies.
Make it a list (.L) instead of preformatted text (.nf).
Fix up so the option explanations are full sentences, starting with a
capital letter and ending with a period.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Claims the victim of a torpedo attack gets told the attacking ship's
number. This hasn't been the case for submarines since Empire 2.3.
Recent commits again reveal the attacking submarine's number, but only
when it gets hit by return fire. Update info accordingly.
Reported-by: Neeraj Jain <thisisfranz@gmail.com>
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
It's redundant; retreat path 'h' cancels orders just fine. Document
that instead. 'c' still works, and I don't plan to break it as long
as it doesn't get in the way, which seems unlikely.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Optional arguments can save typing. Mandatory arguments are more
easily discoverable: just run the command and answer its prompts.
Empire traditionally uses optional arguments only for expert features.
Consider mission:
[0:640] Command : mission
Ship, plane or land unit (p,sh,la)? s
ship(s)? 0
Mission (int, sup, osup, dsup, esc, res, air, query, clear)? int
operations point? .
frg frigate Early Bird(#0) on an interdiction mission, centered on 21,-3, radius 0
1 ship
Compare retreat:
[0:638] Command : retreat
ship(s)? 0
shp# ship type x,y fl path as flt? flags
0 frg frigate 21,-3
1 ship
Arguments are not discoverable this way.
Change retreat to work like mission: make the second argument
mandatory, and if it's 'q', show retreat orders, else treat it as path
and ask for conditions:
[0:637] Command : retreat
ship(s)? 0
Retreat path, or q to query? jj
Retreat conditions ('?' to list available ones)? i
shp# ship type x,y fl path as flt? flags
0 frg frigate 21,-3 jj i
1 ship
To reduce smart client and script breakage, keep retreat with one
argument working as before, but print a deprecation warning.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>