Commit graph

975 commits

Author SHA1 Message Date
f04d1ae032 Fix journal not to truncate long lines
Could happen only for input events.
2011-04-14 20:21:21 +02:00
27212dc46b Escape '\\' in journal, but not '\t' 2011-04-14 20:15:19 +02:00
72d051310c New journal event "command"
Redundant information.  Allows making sense of input without context.
The redundancy could help making a journal replay tool more robust.
2011-04-14 19:46:05 +02:00
157ae8ec21 Clean up superfluous include of nsc.h in prototypes.h 2011-04-14 19:46:05 +02:00
a2386edc01 Clean up superfluous include of news.h in empobj.h
Missed in commit 0ba61f17, v4.3.24.
2011-04-14 19:46:05 +02:00
d6cf175b0b Fix march and navigate not to interpret coordinates as path
Destination arguments can be a path or sector coordinates.
do_unit_move() passes the argument buffer to unit_path() to convert
coordinates to a path.  If unit_path() fails, do_unit_move() still
interprets the argument as path.

This is correct when unit_path() fails because the argument is not
coordinates.  But it can also fail when it is coordinates, namely when
the destination isn't reachable, when the path to it is too long, or
when the ships or land units aren't together.  Then do_unit_move()
interprets coordinates as path, and rejects them with "Legal
directions are:".

Except when a land unit's destination read from a march prompt isn't
reachable, because then unit_path() empties the argument buffer that
do_unit_move() uses.

Change unit_path() to succeed when the argument is not coordinates.
Make do_unit_move() discard the argument when unit_path() fails,
i.e. when it is bad coordinates.  unit_path() emptying the argument no
longer has an effect, drop it.
2011-04-12 21:51:32 +02:00
74b08563af Clean up path finding in perform_mission_bomb()
Support missions up to 1023 sectors away from the airfield, up from
99.

Don't bother to call mapdist() for distance to target, just use the
path length.
2011-04-12 21:51:32 +02:00
404a76f79e Clean up path finding in getpath()
Don't claim the destination sector is unreachable when the best path
is longer than 99 characters or the complete path is longer than 1023
characters.  Instead, report that the path is too long when the total
path is longer than 1023 characters.
2011-04-12 21:51:32 +02:00
182d62deed Remove p_mode, use MOB_FLY and MOB_SAIL instead 2011-04-12 21:51:32 +02:00
8f008bf849 Clean up path finding in unit_sub()
Don't claim the destination sector is unreachable when the best path
is longer than 1023 characters for land units or 99 characters for
ships.  Instead, report that the path is too long.  Up the limit for
ships to 1023 characters.
2011-04-12 21:51:32 +02:00
dac2c95dd5 Clean up path finding in move_ground()
Don't claim the destination sector is unreachable when the best path
is longer than 1023 characters.  Instead, report that the path is too
long.
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
92e64d7638 Inline BestLandPath(), BestDistPath() glue
Following commits will simplify the resulting code.
2011-04-12 21:51:32 +02:00
37d3846009 Optimize s_commod()'s harbor check for embarked land units 2011-04-12 21:51:31 +02:00
aef27e3521 Use path_find() directly where only cost is needed
dist(), att_reacting_units() and s_commod() are only interested in
cost, not the actual path.  BestLandPath() and BestDistPath() compute
both cost and path.  Use path_find() directly instead.

Destinations are no longer treated as unreachable when the best path
is longer than 1023 characters.
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
0095b0c979 Supply charged mobility for backward path
It used the path from supply recipient back to supply source.  Has
always been broken that way.
2011-04-11 22:29:13 +02:00
4547d3dcc2 Collect path-related stuff in path.h 2011-04-11 22:29:12 +02:00
88983a1a2e Fix bitmap overruns when WORLD_X * WORLD_Y not a multiple of 16
World-sized bitmaps were allocated with size WORLD_SZ() / 8, which
expands to (WORLD_X * WORLD_Y / 2) / 8.  The divisions truncate unless
WORLD_X * WORLD_Y is a multiple of 16.  The bitmaps were one byte too
small then.  Bitmap overruns happen when:

* A lookout looks at one of the last sectors of the sector file.
  Besides commands look and llook, this affects navigate and march
  sub-command 'l'.

* Command spy spies into one of the last sectors of the sector file.

* A map or nmap (but not a bmap) shows one of the last sectors of the
  sector file, or a sector that can see one of the last sectors
  (visual range is two sectors at 100% efficiency).  Besides commands
  lmap, map, nmap, pmap, smap, this affects move and transport
  sub-command 'm'.

Diagnosed with valgrind.

Already broken in BSD Empire 1.1 (bitmaps were on the stack then).
2011-04-11 22:29:12 +02:00
6c9363cc4f Fix pathrange()'s computation of the range's right limit
Because of the bug, the path command's maps weren't always fitted to
the path correctly.  Broken in commit 0f458d2c, v4.3.17
2011-03-28 20:28:36 +02:00
fe372539b2 Land units no longer hit allied mines 2011-02-18 18:46:05 +01: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
928e9a4cc3 Use relations_with() in unit_interdict()
No functional change, because the value of rel only matters when cn !=
victim, and then it's the same as before.

The new value of rel permits simplifying cn != victim && rel <=
NEUTRAL to just rel <= NEUTRAL
2011-02-18 18:46:04 +01:00
5245cde582 Use relations_with() in getilists()
No functional change, even though this changes rel[intruder] from
NEUTRAL to ALLIED.  Uses of rel[]:

* getilists() and ac_encounter() compare rel[cn] to HOSTILE.  No
  change, because NEUTRAL and ALLIED are both greater than HOSTILE.

* ac_encounter() compares rel[cn] to ALLIED, but only when cn !=
  plane_owner.  Because it passes plane_owner as argument for
  getilists() parameter intruder, rel[cn] can't refer to the changed
  element of rel[] here.

The new value of rel[plane_owner] permits simplifying cn ==
plane_owner || rel[cn] == ALLIED to just rel[cn] == ALLIED.
2011-02-16 07:57:43 +01:00
983dae641c Use relations_with() in shp_fort_interdiction()
No functional change, because the change affects only
notified[victim], which isn't used in the loop around
notify_coastguard(), and gets overwritten before the interdiction fire
loop.
2011-02-16 07:55:24 +01:00
6c893f5cc3 Use relations_with() in lnd_mar_one_sector()
No functional change, because the value of rel only matters when
sect.sct_own != actor, and then it's the same as before.

The new value of rel permits simplifying sect.sct_own != actor && rel
!= ALLIED to just rel != ALLIED.
2011-02-16 07:52:25 +01:00
8cb7b75557 Use relations_with() for getrel(getnatp(US), THEM) where US!=THEM
Replacing getrel(getnatp(US), THEM) 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.

Note: getsect() sets player->owner to "player is god or owns this
sector".  Thus, after getsect(..., &sect), sect.sct_own ==
player->cnum implies player->owner.  Conversely, !player->owner
implies sect.sct_own != player->cnum.  Similarly for getship(),
getplane() and nxtitem().
2011-02-16 07:52:25 +01:00
6807cd91b5 Use relations_with() where its different value doesn't matter
Switching from getrel() to relations_with() can change the value from
NEUTRAL to ALLIED.  The change doesn't matter when the value's only
compared to HOSTILE, as both old and new value are greater than
HOSTILE.  Likewise for >= NEUTRAL.
2011-02-16 07:52:25 +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
58cbd4cc2e Make share_bmap() do nothing for sharing with oneself
Before, it overwrote '?', '.', ' ' in the bmap with the capitalized
country letter, but only for sectors the player owns.  Pretty
harmless, just weird.  It can't happen currently, because sharebmap
with self fails with "does not have friendly relations towards you".
2011-02-13 16:41:35 +01:00
2b3e11d35d Remove pointless variables from setrel() 2011-02-13 16:06:22 +01:00
985ec19f8b Make setrel() refuse to change relations to self
No current caller actually attempts that, but let's make it obvious.
2011-02-13 16:06:22 +01:00
d4f0cb3576 Change setrel(), setcont(), setrej() to return void
Nobody cares for their value anyway.
2011-02-13 16:06:22 +01:00
a302bde1fb Oops on invalid arguments in setrel(), setcont(), setrej()
Before, they recovered silently.
2011-02-13 16:06:22 +01:00
89bc9c4d5b Use feels_like_helping() in dosupport(), lnd_support()
feels_like_helping() case cn == foe is missing in the code it
replaces.  No difference in behavior, because:

* cn == foe && cn == friend can't happen.  Because you can't get into
  ground combat against yourself (assault, attack and paradrop don't
  let you), friend != foe for support.

* cn == foe && cn != friend behaves the same: no support.
  feels_like_helping() returns 0 because of the explicit case.  The
  replaced code doesn't support because cn can't be at war with
  itself.
2011-02-13 16:06:22 +01:00
c095ad285b Factor feels_like_helping() out of quiet_bigdef(), sd(), dd() 2011-02-13 16:06:22 +01:00
7374002fd7 Plug memory leaks in mission execution code
Mission execution first builds lists of eligible units, one list per
country.  These lists are passed to perform_mission() one by one,
where they get freed.

Bugs:

* unit_interdict() didn't pass the list for the submarine's owner, but
  build_mission_list_type() built one.  Any submarine movement within
  own submarine interdiction mission op areas leaked memory.

* dosupport() passed only lists for countries that actually support
  (ally at war with victim), but build_mission_list_type() built lists
  for all countries hostile to the victim.  Ground combat within
  support mission op areas countries that are hostile to one of the
  party without actually supporting the other leaked memory.

* perform_mission() failed to free missiles targeting units.

Fixing the latter is straightforward.

Fix the first two by deciding whether a country acts on a mission
trigger before building any lists, in ground_interdict(),
unit_interdict(), dosupport().  Remove the code dealing with that from
build_mission_list_type() and the loops around perform_mission().
2011-02-13 16:06:22 +01:00
6a35432346 Move code from def_support(), off_support() to dosupport() 2011-02-13 16:06:22 +01:00
05b3e1b8d8 Oops on invalid actor and victim arguments in nreport()
Replaces the existing, silent recovery from invalid victim argument.
2011-02-13 16:03:34 +01:00
38e59474b1 Clean up use of current player in march code
lnd_mar() and lnd_mar_one_sector() take an actor argument.
Nevertheless, they sometimes used player->cnum.  Fortunately, they are
the same: all callers pass current player for actor.  Normalize to
actor for consistency.
2011-02-13 16:03:34 +01:00
98c5a92baa Fix land unit attack mobility cost out of allied sectors
Land units pay a mobility penalty when marching into a non-old-owned
sector without sector mobility, to slow them down in newly taken
sectors.  Attacking land units pay this penalty regardless of sector
mobility.

When attacking out of an allied sector, the penalty was computed as if
the land unit was owned by that ally.  Attacking sectors old-owned by
that ally was too cheap, and taking back one's own was too expensive.

Broken since attacking land units pay the "newly taken" mobility
penalty: commit 2e693275, v4.3.6.
2011-02-13 16:03:34 +01:00
13d9057bd8 Fix attack when attacking sector gets taken by ally
When an attacking sector got lost while the player was at a prompt,
and the new owner was allied to the player, the server got confused:

1. If the sector attacked with mil, the server let the ghost mil
attack, but not occupy.

2. If the sector was allied, the server reported the sector loss and
land units dropping out of the attack, but claimed the lost sector was
yours.

Fix 1. by dropping sectors from attack when they change owner away
from the player, regardless of relations.  Side effect: also drops any
surviving land units there.  Before, they dropped out only if the new
owner wasn't allied to the player.  That change's okay.

Fix 2. the obvious way: change the messages.

Broken in 4.0.0.
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
a5c2a24db6 Planes get to sweep and sonar only after flak and interception
If defenders get to shoot before bombs are dropped, they surely get to
shoot before time-consuming missions like sweep and sonar.

Sweep and sonar used to happen after air defense, but before flak and
interception.  Air defense existed from Chainsaw 3 to v4.3.19.
2010-07-25 18:23:45 +02:00
765bf06ab2 Make disabled recursive supply in s_commod() compile again
Untested.  Broken in commit 98f24d5c, v4.3.20.
2010-07-25 17:48:53 +02:00
a8a68287bb Remove unused variables in disabled lnd_fort_interdiction() 2010-07-25 17:48:53 +02:00
f0da4769dc Clean up unobvious coordinate system use in detonate()
Use the obviously correct player->cnum instead of own.  They're
actually equal here.
2010-07-25 17:48:53 +02:00