Commit graph

376 commits

Author SHA1 Message Date
91c2ecec53 Land units loaded on land units fight che again
They didn't since commit 93d033cf, v4.3.26.  Drawback: micromanagement
incentive to unload them for the update.  Similar incentive has always
existed for military on ships.

Since the previous commit, land units loaded on land units get
unloaded when the carrier dies fighting che.  Such land units get
stuck in the sector if the take over, and can be boarded.  Doesn't
feel right, and increases the micromanagement incentive.  Avoid by
letting them fight.
2011-07-10 21:10:17 +02:00
7aba25e826 Don't leave cargo stuck on land unit killed by che
When che destroy a land unit, any embarked units remain stuck on their
now dead carrier.  Closely related to and same impact as the bug fixed
in commit 8ccad0d7.  Broken since Chainsaw 3 added land units.

The obvious fix would be to match what normally happens when a carrier
gets destroyed: destroy the cargo.  Requires recursion.  To keep
things as simple as possible, destroy plane cargo, but unload land
unit cargo.  That way, the only cargo of cargo to visit are nukes on
planes.

Unloading the land units creates another problem, which will be
addressed in the next commit.
2011-07-10 21:09:37 +02:00
4c8d4228c8 Factor lnd_dies_fighting_che() out of take_casualties() 2011-07-10 21:08:56 +02:00
8ccad0d779 Units no longer die from lack of maintenance
Damage due to lack of maintenance is now limited by the unit's minimum
efficiency.

Before, units could die.  Unfortunately, the update left any embarked
units on their dead carrier.  Should have seen this when I fixed a
related bug in commit c2c0d1ff, v4.3.22.  Broken for ships and land
units when Empire 2 added their maintenance cost, and for planes when
commit 2e40a4bb (v4.3.4) replaced nuclear stockpiles by nuke units.
The common root cause of these bugs is the update bypassing pre-write
functions (bug#1010856).

If another unit with the same number got built, it picked up the stuck
cargo, triggering the oops from commit 6fb5caf6, which see.

In "stuck on dead carrier" state, units pretty much behave as if their
carrier was still alive, with additional protection from the fact that
a dead carrier can't be damaged or boarded.

The server detects this state on startup since commit 7da9aab5, and
refuses to start.

Only a deity can take units off a dead carrier.
2011-07-10 21:08:50 +02:00
352bc320d2 Remove option TRADESHIPS, customize table ship-chr instead
Trade ships are now enabled when a ship type with capability trade
exists.  No such type exists by default; to enable trade ships,
deities have to customize table ship-chr.

Before, trade ship types were ignored when option TRADESHIPS was
disabled.  Except for xdump ship-chr, which happily dumped unusable
trade ship types.
2011-06-25 16:52:08 +02:00
c4254764bf Fix scuttle_it()'s "is a trade ship" sanity check
Only trade ships can be auto-scuttled.  orde() rejects scuttle orders
for other ships.  scuttle_it() double-checks, but gets the test wrong:
it rejects only when opt_TRADESHIPS is enabled.  Fix that.  While
there, make it oops on inadmissible ships.
2011-06-25 16:51:56 +02:00
98cd2a3a70 Update known contributors comments 2011-04-14 20:21:23 +02:00
a12a315cd9 Fix stop orders to expire even when the country is broke
Broken in commit 8da88626, v4.3.8.
2011-04-12 21:51:32 +02:00
8d23975299 Clean up path finding in nav_ship()
Destinations are no longer treated as unreachable when the best path
is longer than 99 characters.  Instead, consider up to 1023 characters
of the best path.
2011-04-12 21:51:32 +02:00
e450c31ddb Inline BestShipPath(), BestAirPath() glue
Following commits will simplify the resulting code.
2011-04-12 21:51:32 +02:00
bbd6e9182f Compute distribution paths center by center
This way, we compute all distribution paths from the same center in
one go, and thus fully exploit the fast multiple paths from same
source capability of Dijkstra's algorithm.

Sorting by dist center increases the average length of runs from 4.5
to 73 for my continental test case, and from 3 to 10 for my island
test case.

Compared to the commit before the previous one, distribution path
assembly runs more than 40 times faster for my continental test case,
and more than 5 times faster for my island test case.

The new path finder now runs my continental test case more than 30
times faster than the old A*, and the island test case more than 6
times, in a fraction of the memory.  This makes the continental
updates run 3.5 times faster, and the island updates 6% faster.
Distribution path assembly no longer dominates the continental
update's run time: it takes less than 10% instead of more than 70%.

In a sense, this is the path cache done right.
2011-04-12 21:51:31 +02:00
bf97fa9c9c Exploit fast "multiple paths from same source" in distribution
Dijkstra's algorithm can find multiple paths from the same source.
This is much faster than starting from scratch for every path.

Make distribution path assembly work that way.  This speeds up runs of
distributions to the same center.  The next commit will reorder path
searches to maximize the length of these runs.  It also has benchmark
results.

Allocates four bytes per sector, actually uses only the first 4*n
bytes, where n is the number of distributing sectors.
2011-04-12 21:51:31 +02:00
18dd516076 Add performance statistics to path finder
New function path_find_print_stats() prints a few numbers of interest
when compiled with PATH_FIND_STATS defined.
2011-04-12 21:51:31 +02:00
ffbbfcb25f Use the new path finder for land paths, drop old A*
This gets rid of the memory leak mentioned in the previous commit.

To get rid of the buffer overruns for long paths mentioned in the
previous commit, make BestLandPath() fail when path length exceeds
1023 characters.

assemble_dist_paths() and move_ground() pass buffers with a different
size.  Eliminate assemble_dist_paths()'s buffer.  Update now works
regardless of distribution distance (the distribute command still
limits to 1023, to be fixed in a later commit).  Enlarge
move_ground()'s buffers.  Doubles the length of paths accepted by
explore, move, and transport.

I use two test cases to benchmark the path finders: "continental" (Hvy
Metal 2 updates) and "island" (Hvy Plastic 2 updates).

The new path finder runs my tests around 3-4 times faster than the old
A* without its caches.  That's enough to meet its cached performance
for "island", but it's only half as fast for "continental".  Not for
long; big speedups are coming.
2011-04-12 21:48:58 +02:00
7e2008e7f4 License upgrade to GPL version 3 or later
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.
2011-04-12 21:20:58 +02:00
5333782046 Remove pointless check for sea from finish_sects()
Checking "sea or unowned" is pointless, because sea is always unowned.
2011-04-11 22:29:13 +02:00
6eecd9cdc8 Optimize assemble_dist_paths() for foreign distribution center
You can't distribute to a foreign sector.  This case is relatively
rare.  However, unsuccessful path search is relatively expensive, and
the extra check doesn't really slow down the common case.
2011-04-11 22:29:13 +02:00
b8002d5603 Optimize dodistribute() for sectors with no distribution center
import_cost is now -1 in that case, so checking that suffices.
2011-04-11 22:29:13 +02:00
f4db4e37b1 Fix assemble_dist_paths()'s recovery from invalid dist center
The recovery avoided crashing here, but left the path costs undefined.
If they happend to be non-negative, dodistribute() still crashed.  Set
the costs to -1 to avoid that.

While there, oops on invalid distribution center.
2011-04-11 22:29:13 +02:00
08cb463878 Speed up export cost calculation in assemble_dist_paths()
Import and export paths enter the same sectors, except for the last
one.  Compute export cost from import cost instead of reverting the
import path.  Do it in dodistribute(), so that we need to store only
import costs.
2011-04-11 22:29:13 +02:00
791ba26c5e Merge dodistribute() parameters dist_i_cost, dist_e_cost
Only one of them is used, depending on argument imex.  Replace them by
a single parameter path_cost.
2011-04-11 22:29:12 +02:00
d1bdeb4353 Remove dodistribute() parameter path
It was only used to see whether a path to the dist center exists.  Use
negative cost for that.
2011-04-11 22:29:12 +02:00
99c73f399a SAVE_FINISH_PATHS hasn't been used since 4.2.2, remove it
Since 4.2.2, assemble_dist_paths() stores a dummy path instead of the
real path to the dist center.  That's possible because distribution
doesn't actually use the path, only whether it exists.

The code to store and free the real path is still around, under #ifdef
SAVE_FINISH_PATHS.  Remove it.
2011-04-11 22:29:12 +02:00
25665bc49a Print distribution costs when compiled with DISTRIBUTE_DEBUG 2011-04-11 22:29:12 +02:00
9fee5efe57 Log distribution path assembly's CPU use (user and system time) 2011-04-11 22:29:12 +02:00
3dafd404fa Log update's CPU use (user and system time) 2011-04-11 22:29:12 +02:00
6852ec6bc5 Use relations_with() for getrel(NP, THEM) where NP isn't THEM
Replacing getrel(NP, THEM), where NP is known to be getnatp(US), by
relations_with(US, THEM) makes a difference only when US equals THEM.
Replace in places where it's obvious that they're not equal.

Adds a few calls to getnatp() hidden in relations_with().  Keeping
that optimized isn't worth it.
2011-02-18 18:46:05 +01:00
58cc82589e Use relations_with() in nav_loadship()
No functional change, because the value of rel only matters when
sectp->sct_own != sp->shp_own, and then it's the same as before.

The new value of rel permits simplifying sectp->sct_own == sp->shp_own
|| rel >= FRIENDLY to just rel >= FRIENDLY.
2011-02-16 07:55:24 +01:00
Markus Armbruster
8e75b22e0d Use relations_with() for US==THEM || getrel(getnatp(US), THEM)
Replacing getrel(getnatp(US), THEM) by relations_with(US, THEM) makes
a difference only when US equals THEM.

Replace patterns like "us == them || getrel(getnatp(us), them)..." by
"relations_with(us, them)...".
2011-02-16 07:51:39 +01:00
ef7b9cedc3 Rearrange uses of getrel() slightly
Just to make the next few commits easier to review.
2011-02-16 07:50:26 +01:00
7ebbe7da4c Eliminate a few pointless relations variables
Just to make the next few commits easier to review.
2011-02-16 07:48:30 +01:00
723cc96d9c Eliminate nav_loadship() variables landown, shipown
Code is clearer without them.  Works because load_it() never changes
ship or sector owner.
2011-02-13 16:03:34 +01:00
4a142dd102 Drop redundant nav_loadship() parameter cnum 2011-02-13 16:03:34 +01:00
6d014e8069 Eliminate nav_ship() variable cnum
Code is clearer without it.
2011-02-13 16:03:34 +01:00
439f111f98 Remove option SLOW_WAR
SLOW_WAR has issues:

* The check whether the attacker old-owns the attacked sector is
  broken, because att_abort() uses sect.sct_oldown uninitialized.

  Spotted by the Clang Static Analyzer.

* Its implementation in setrel() is somewhat scary.  It's actually
  okay, because that part of setrel() only runs within decl().  Other
  callers don't reach it: update_main() because player->god != 0
  there, and the rest because they never pass a rel < HOSTILE.

* Documentation is a bit vague.

SLOW_WAR hasn't been used in a public game in years.  Fixing it is not
worth it, so remove it instead.
2011-02-13 15:59:49 +01:00
9ad8618ba3 Fix autonav to use correct coordinate system
When autonav reported to a ship owner that it can't load or unload
foreign civilians, it used the sector owner's coordinate system.  This
disclosed the sector owner's origin.  Abusable.
2010-06-21 21:03:21 +02:00
25d29c8f8f Convert tab after #define to space 2010-06-20 18:38:54 +02:00
243a15052f Convert spaces to tabs 2010-06-20 18:36:44 +02:00
7465574195 Break long lines more tastefully 2010-06-20 18:36:44 +02:00
373651359e Coding style fixes, mostly indentation and whitespace 2010-06-20 18:36:38 +02:00
7d1c358e23 Drop ancient #ifdef DEBUG cruft
A few are left in src/lib/as/.
2010-05-24 18:23:32 +02:00
531bac70a4 Remove superfluous casts to natid 2010-05-24 18:23:32 +02:00
93d033cff4 Don't let embarked land units fight a che revolt
When take_casualties() kills a land unit, it neglects to take it off
its carrier.  This triggers an oops in unit_cargo_init().  Instead of
fixing this, just don't let them fight.  They can't defend against
other attacks, either.
2010-05-13 20:12:19 +02:00
10f5000aa1 Fix che revolt to damage only land units that actually fight
guerrilla() lets only the sector owner's land units fight.  But
take_casualties() spread the casualties among all land units in the
sector.  Thus, defending land units could survive a defeat if foreign
land units were present.  The sector takeover then had che capture
them, or their crews blow them up.  The foreign land units were
damaged silently.
2010-05-13 20:08:21 +02:00
b8f5eaff0b Clean up dead stores
Does not change optimized code (gcc -O).

Spotted by the Clang Static Analyzer.
2010-01-19 08:40:42 +01:00
73e25ff21e Update copyright notice 2010-01-19 08:40:17 +01:00
2fa5f65257 Generation numbers to catch write back of stale copies
Oops when a stale copy is written back, i.e. the processor was yielded
since the copy was made.  Such bugs are difficult to spot.  Sequence
numbers catch them when they do actual harm (they also catch different
bugs).  Generation numbers catch them even when they don't.

New ef_generation to count generations.  Call new ef_make_stale() to
increment it whenever the processor may be yielded.

New struct emptypedstr member generation.  To conserve space, make it
a bit-field of twelve bits, i.e. generations are only recorded modulo
2^12.  Make sure all members of unit empobj_storage share it.  It is
only used in copies; its value on disk and in the cache is
meaningless.  Copies with generation other than ef_generation are
stale.  Stale copies that are a multiple of 2^12 generations old can't
be detected, but that is sufficiently improbable.

Set generation to ef_generation by calling new ef_mark_fresh() when
making copies in ef_read() and ef_blank().  nav_ship() and
fltp_to_list() make copies without going through ef_read(), and
therefore need to call ef_mark_fresh() as well.  Also call it in
obj_changed() to make check_sect_ok() & friends freshen their argument
when it is unchanged.

New must_be_fresh() oopses when its argument is stale.  Call it in
ef_write() to catch write back of stale copies.
2010-01-19 08:36:01 +01:00
c528fcbe3e Update known contributors comments 2009-12-13 17:34:28 +01:00
c63ec06d15 Fix use of invalid pointer when depleting resource "none"
prod() and produce() dereferenced resource uninitialized for products
depleting resource "none" (p_nrdep != 0 && p_nrndx == 0).  The latter
even wrote to it.

Depleting "none" makes no sense, and the depletion is now ignored.
Before, it could conceivably crash the server or corrupt the game.
2009-12-08 08:11:01 +01:00
44c36fa7d5 Make sector maintenance cost configurable
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".
2009-07-19 13:58:47 -04:00