empserver/src/lib/commands/atta.c
Markus Armbruster a109de948b Remove option TREATIES
TREATIES has issues:

* Treaties can cover attack, assault, paradrop, board, lboard, fire,
  build (s|p|l|n) and enlist, but not bomb, launch, torpedo and
  enlistment centers.

* Usability is very poor.  While a treaty is in effect, every player
  action that violates a treaty condition triggers a prompt like this:

    This action is in contravention of  treaty #0 (with Curmudgeon)
    Do you wish to go ahead anyway? [yn]

  If you decline, the action is not executed.  If you accept, it is.
  In both cases, your decision is reported in the news.

  You cannot get rid of these prompts until the treaty expires.

* Virtually nobody uses them.

* Virtually unused code is buggy code.  There is at least one race
  condition: multifire() reads the firing sector, ship or land unit
  before the treaty prompt, and writes it back after, triggering a
  generation oops.  Any updates made by other threads while trechk()
  waits for input are wiped out, triggering a seqno mismatch oops.

* The treaty prompts could confuse smart clients that aren't prepared
  for them.  WinACE isn't, but is reported to work anyway at least
  common usage.  Ron Koenderink (the WinACE maintainer) suspects there
  could be a few situations where it will fail.

This feature is not earning its keep.  Remove it.  Drop command
treaty, consider treaty, offer treaty, xdump treaty, reject treaties.
Output of accept changed, obviously.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2014-02-16 11:44:14 +01:00

145 lines
4.1 KiB
C

/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2014, 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.
*
* ---
*
* atta.c: Attack another sector
*
* Known contributors to this file:
* Dave Pare
* Ken Stevens, 1995
* Steve McClure, 1996
*/
#include <config.h>
#include "combat.h"
#include "commands.h"
#include "path.h"
#include "ship.h"
int
atta(void)
{
struct combat off[6]; /* attacking sectors */
struct combat def[1]; /* defending sector */
coord newx, newy;
struct sctstr sect;
int fort_sup, ship_sup, land_sup, plane_sup;
struct emp_qelem olist; /* attacking units */
struct emp_qelem dlist; /* defending units */
int ototal; /* total attacking strength */
int a_engineer = 0; /* attacker engineers are present */
int a_spy = 0; /* the best attacker scout */
double osupport = 1.0; /* attack support */
double dsupport = 1.0; /* defense support */
int last, n;
char *p;
char buf[1024];
att_combat_init(def, EF_SECTOR);
/*
* Collect input from the attacker
*/
/* What are we attacking? */
if (!(p = getstarg(player->argp[1], "Sector : ", buf)))
return RET_SYN;
if (!sarg_xy(p, &def->x, &def->y))
return RET_SYN;
if (att_abort(A_ATTACK, NULL, def))
return RET_FAIL;
/* Show what we're attacking */
att_show(def);
/* Ask about offensive support */
att_ask_support(2, &fort_sup, &ship_sup, &land_sup, &plane_sup);
if (att_abort(A_ATTACK, NULL, def)) {
att_empty_attack(A_ATTACK, 0, def);
return RET_OK;
}
/* initialize the off[] array */
for (n = 0, last = -1; n < 6; ++n) { /* Directions */
newx = def->x + diroff[n + 1][0];
newy = def->y + diroff[n + 1][1];
getsect(newx, newy, &sect); /* incase cross world boundary */
if (!player->owner
&& relations_with(sect.sct_own, player->cnum) != ALLIED)
continue;
att_combat_init(&off[++last], EF_SECTOR);
off[last].x = sect.sct_x;
off[last].y = sect.sct_y;
}
off->last = last;
/* Ask the player what he wants to attack with */
att_ask_offense(A_ATTACK, off, def, &olist, &a_spy, &a_engineer);
if (att_abort(A_ATTACK, off, def)) {
pr("Attack aborted\n");
att_empty_attack(A_ATTACK, 0, def);
return att_free_lists(&olist, NULL);
}
ototal = att_get_offense(A_ATTACK, off, &olist, def);
if (att_abort(A_ATTACK, off, def)) {
pr("Attack aborted\n");
att_empty_attack(A_ATTACK, 0, def);
return att_free_lists(&olist, NULL);
}
/*
* We have now got all the answers from the attacker. From this point
* forward, we can assume that this battle is the _only_ thing
* happening in the game.
*/
/* Get the real defense */
att_get_defense(&olist, def, &dlist, a_spy, ototal);
/* Get attacker and defender support */
att_get_support(A_ATTACK, fort_sup, ship_sup, land_sup, plane_sup,
&olist, off, &dlist, def, &osupport, &dsupport,
a_engineer);
if (att_abort(A_ATTACK, off, def)) {
pr("Attack aborted\n");
att_empty_attack(A_ATTACK, 0, def);
return att_free_lists(&olist, &dlist);
}
/*
* Death, carnage, and destruction.
*/
att_fight(A_ATTACK, off, &olist, osupport, def, &dlist, dsupport);
return RET_OK;
}