[Freeciv-Dev] Re: (PR#14289) Different Gameloss Outcomes
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=14289 >
Benedict Adamson wrote:
...
> Perhaps we could have multiple possible [Gameloss] outcomes? A ruleset option
> could
> select which was wanted.
...
Jason replied:
> IMO we don't need an option here. The obvious best choice is to make
> them all barbarians.
Here is a patch that provides two ruleset choices: the traditional
outcome, and changing them all to barbarians. The civ1, civ2 and history
rulesets use the traditional outcome; the default ruleset uses the new
outcome. This patch also adds a command 'debug murder <player>', which
is useful for testing the Gameloss code.
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/common/packets.def freeciv.PR14289/common/packets.def
--- vendor.freeciv.current/common/packets.def 2005-10-13 21:54:24.000000000
+0100
+++ freeciv.PR14289/common/packets.def 2005-10-15 01:33:13.000000000 +0100
@@ -428,6 +428,7 @@
UINT8 granary_food_inc;
UINT8 tech_cost_style;
UINT8 tech_leakage;
+ UINT8 gameloss_style;
YEAR tech_cost_double_year;
BOOL killstack;
UINT8 autoupgrade_veteran_loss;
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/data/civ1/game.ruleset
freeciv.PR14289/data/civ1/game.ruleset
--- vendor.freeciv.current/data/civ1/game.ruleset 2005-10-13
21:54:01.000000000 +0100
+++ freeciv.PR14289/data/civ1/game.ruleset 2005-10-15 01:32:51.000000000
+0100
@@ -75,6 +75,16 @@
; players (human and AI) which already know the tech.
tech_leakage = 0
+; What happens when a 'GameLoss' unit is destroyed,
+; in addition to the player losing the game.
+; 0 - Cities that the player conquered are returned to their
+; original owners, were possible. All other units and cities are destroyed.
+; This is the traditional outcome.
+; 1 - Cities that the player conquered are returned to their
+; original owners, were possible. Other and cities and units become
+; barbarians, if possible. Remaining units and cities are destroyed.
+gameloss_style = 0;
+
; Research cost doubles after this year. Set to zero to disable.
tech_cost_double_year = 1
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/data/civ2/game.ruleset
freeciv.PR14289/data/civ2/game.ruleset
--- vendor.freeciv.current/data/civ2/game.ruleset 2005-10-13
21:54:02.000000000 +0100
+++ freeciv.PR14289/data/civ2/game.ruleset 2005-10-15 01:32:51.000000000
+0100
@@ -75,6 +75,16 @@
; players (human and AI) which already know the tech.
tech_leakage = 0
+; What happens when a 'GameLoss' unit is destroyed,
+; in addition to the player losing the game.
+; 0 - Cities that the player conquered are returned to their
+; original owners, were possible. All other units and cities are destroyed.
+; This is the traditional outcome.
+; 1 - Cities that the player conquered are returned to their
+; original owners, were possible. Other and cities and units become
+; barbarians, if possible. Remaining units and cities are destroyed.
+gameloss_style = 0;
+
; Research cost doubles after this year. Set to zero to disable.
tech_cost_double_year = 1
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/data/default/game.ruleset
freeciv.PR14289/data/default/game.ruleset
--- vendor.freeciv.current/data/default/game.ruleset 2005-10-13
21:54:03.000000000 +0100
+++ freeciv.PR14289/data/default/game.ruleset 2005-10-15 01:32:52.000000000
+0100
@@ -94,6 +94,16 @@
; players (human and AI) which already know the tech.
tech_leakage = 0
+; What happens when a 'GameLoss' unit is destroyed,
+; in addition to the player losing the game.
+; 0 - Cities that the player conquered are returned to their
+; original owners, were possible. All other units and cities are destroyed.
+; This is the traditional outcome.
+; 1 - Cities that the player conquered are returned to their
+; original owners, were possible. Other and cities and units become
+; barbarians, if possible. Remaining units and cities are destroyed.
+gameloss_style = 1;
+
; Research cost doubles after this year. Set to zero to disable.
tech_cost_double_year = 0
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/data/history/game.ruleset
freeciv.PR14289/data/history/game.ruleset
--- vendor.freeciv.current/data/history/game.ruleset 2005-10-13
21:54:12.000000000 +0100
+++ freeciv.PR14289/data/history/game.ruleset 2005-10-15 01:33:01.000000000
+0100
@@ -75,6 +75,16 @@
; players (human and AI) which already know the tech.
tech_leakage = 0
+; What happens when a 'GameLoss' unit is destroyed,
+; in addition to the player losing the game.
+; 0 - Cities that the player conquered are returned to their
+; original owners, were possible. All other units and cities are destroyed.
+; This is the traditional outcome.
+; 1 - Cities that the player conquered are returned to their
+; original owners, were possible. Other and cities and units become
+; barbarians, if possible. Remaining units and cities are destroyed.
+gameloss_style = 0;
+
; Research cost doubles after this year. Set to zero to disable.
tech_cost_double_year = 0
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/barbarian.c freeciv.PR14289/server/barbarian.c
--- vendor.freeciv.current/server/barbarian.c 2005-10-13 21:53:56.000000000
+0100
+++ freeciv.PR14289/server/barbarian.c 2005-10-15 01:32:46.000000000 +0100
@@ -109,7 +109,7 @@
Dead barbarians forget the map and lose the money.
**************************************************************************/
-static struct player *create_barbarian_player(bool land)
+struct player *create_barbarian_player(bool land)
{
int newplayer = game.info.nplayers;
struct player *barbarians;
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/barbarian.h freeciv.PR14289/server/barbarian.h
--- vendor.freeciv.current/server/barbarian.h 2005-10-13 21:53:56.000000000
+0100
+++ freeciv.PR14289/server/barbarian.h 2005-10-15 01:32:46.000000000 +0100
@@ -31,5 +31,6 @@
bool unleash_barbarians(struct tile *ptile);
void summon_barbarians(void);
bool is_land_barbarian(struct player *pplayer);
+struct player *create_barbarian_player(bool land);
#endif /* FC__BARBARIAN_H */
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/commands.c freeciv.PR14289/server/commands.c
--- vendor.freeciv.current/server/commands.c 2005-10-13 21:53:56.000000000
+0100
+++ freeciv.PR14289/server/commands.c 2005-10-15 01:32:46.000000000 +0100
@@ -118,10 +118,11 @@
},
{"debug", ALLOW_CTRL,
N_("debug [ player <player> | city <x> <y> | units <x> <y> | unit <id> "
- "| tech <player> | timing | info]"),
- N_("Turn on or off AI debugging of given entity."),
+ "| tech <player> | timing | info | murder <player> ]"),
+ N_("Turn on or off AI debugging of given entity or do test operations."),
N_("Print AI debug information about given entity and turn continous "
- "debugging output for this entity on or off."),
+ "debugging output for this entity on or off, "
+ "or directly perform an action on the entity."),
},
{"set", ALLOW_CTRL,
N_("set <option-name> <value>"),
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/plrhand.c freeciv.PR14289/server/plrhand.c
--- vendor.freeciv.current/server/plrhand.c 2005-10-13 22:20:18.000000000
+0100
+++ freeciv.PR14289/server/plrhand.c 2005-10-15 01:32:46.000000000 +0100
@@ -34,6 +34,7 @@
#include "script.h"
+#include "barbarian.h"
#include "citytools.h"
#include "cityturn.h"
#include "connecthand.h"
@@ -119,12 +120,13 @@
} players_iterate_end;
}
+static void dispose_player_legacy_remove(struct player *pplayer);
+static void dispose_player_legacy_barbarian(struct player *pplayer);
+
/**************************************************************************
Murder a player in cold blood.
**************************************************************************/
void kill_player(struct player *pplayer) {
- bool palace;
-
pplayer->is_dying = FALSE; /* Can't get more dead than this. */
pplayer->is_alive = FALSE;
@@ -146,16 +148,39 @@
gamelog(GAMELOG_GENO, pplayer,
"The feared barbarian leader %s is no more");
return;
- } else {
- notify_player(NULL, NULL, E_DESTROYED, _("The %s are no more!"),
- get_nation_name_plural(pplayer->nation));
- gamelog(GAMELOG_GENO, pplayer, "%s civilization destroyed");
}
+ gamelog(GAMELOG_GENO, pplayer, "%s civilization destroyed");
- /* Transfer back all cities not originally owned by player to their
- rightful owners, if they are still around */
- palace = game.info.savepalace;
- game.info.savepalace = FALSE; /* moving it around is dumb */
+ /* Dispose of the cities and units belonging to the player */
+ switch(game.info.gameloss_style) {
+ case 0:
+ dispose_player_legacy_remove(pplayer);
+ break;
+ case 1:
+ dispose_player_legacy_barbarian(pplayer);
+ break;
+ default: /*never happens */
+ dispose_player_legacy_remove(pplayer);
+ break;
+ }
+
+ /* Ensure this dead player doesn't win with a spaceship.
+ * Now that would be truly unbelievably dumb - Per */
+ spaceship_init(&pplayer->spaceship);
+ send_spaceship_info(pplayer, NULL);
+
+ send_player_info_c(pplayer, game.est_connections);
+}
+
+/**************************************************************************
+ Transfer back all cities not originally owned by player to their
+ rightful owners, if they are still around.
+
+ You should set game.info.savepalace = FALSE before calling this,
+ to prevent palaces moving around.
+**************************************************************************/
+static void return_conquests(struct player *pplayer)
+{
city_list_iterate(pplayer->cities, pcity) {
if (pcity->original != pplayer && pcity->original->is_alive) {
/* Transfer city to original owner, kill all its units outside of
@@ -164,7 +189,13 @@
transfer_city(pcity->original, pcity, 3, TRUE, TRUE, TRUE);
}
} city_list_iterate_end;
+}
+/**************************************************************************
+ Remove the units and cities that belonged to a player that is now dead.
+**************************************************************************/
+static void remove_legacy(struct player *pplayer)
+{
/* Remove all units that are still ours */
unit_list_iterate_safe(pplayer->units, punit) {
wipe_unit(punit);
@@ -174,14 +205,85 @@
city_list_iterate(pplayer->cities, pcity) {
remove_city(pcity);
} city_list_iterate_end;
+}
+
+/**************************************************************************
+ Dispose of the units and cities that belonged to a player that is now dead,
+ in the traditional manner: remove anything that can not be returned to its
+ original owner.
+**************************************************************************/
+static void dispose_player_legacy_remove(struct player *pplayer)
+{
+ const bool palace = game.info.savepalace;
+
+ game.info.savepalace = FALSE; /* moving it around is dumb */
+
+ /* Transfer back all cities not originally owned by player to their
+ rightful owners, if they are still around */
+ return_conquests(pplayer);
+ remove_legacy(pplayer);
+
game.info.savepalace = palace;
- /* Ensure this dead player doesn't win with a spaceship.
- * Now that would be truly unbelievably dumb - Per */
- spaceship_init(&pplayer->spaceship);
- send_spaceship_info(pplayer, NULL);
+ notify_player(NULL, NULL, E_DESTROYED, _("The %s are no more!"),
+ get_nation_name_plural(pplayer->nation));
+}
- send_player_info_c(pplayer, game.est_connections);
+/**************************************************************************
+ Dispose of the units and cities that belonged to a player that is now dead,
+ turning to barbarity were possible.
+**************************************************************************/
+static unsigned fall_to_barbarity(struct player *pplayer,
+ struct player *barbarians)
+{
+ unsigned int count = 0;
+
+ city_list_iterate(pplayer->cities, pcity) {
+ /* This will also transfer the units that have the city as a home city */
+ transfer_city(barbarians, pcity, 3, TRUE, TRUE, TRUE);
+ count++;
+ } city_list_iterate_end;
+
+ return count;
+}
+
+/**************************************************************************
+ Dispose of the units and cities that belonged to a player that is now dead,
+ by tring to return them to their original owner or by turning to barbarity.
+**************************************************************************/
+static void dispose_player_legacy_barbarian(struct player *pplayer)
+{
+ struct player *barbarians = create_barbarian_player(FALSE);
+ const bool palace = game.info.savepalace;
+ unsigned int fallen_cities = 0;
+
+ assert(!is_barbarian(pplayer)); /* else indestructable barbarians */
+ game.info.savepalace = FALSE; /* moving it around is dumb */
+
+ /* Transfer back all cities not originally owned by player to their
+ rightful owners, if they are still around */
+ return_conquests(pplayer);
+
+ if (barbarians) {
+ fallen_cities = fall_to_barbarity(pplayer, barbarians);
+ }
+ /* else was unable to create barbarians */
+
+ /* There will be cities and units left, if we were unable to create
+ * a barbarian player.
+ * Units that do not have a home city will also be left. */
+ remove_legacy(pplayer);
+
+ game.info.savepalace = palace;
+
+ if (fallen_cities) {
+ notify_player(NULL, NULL, E_DESTROYED,
+ _("The %s have fallen into barbarity!"),
+ get_nation_name_plural(pplayer->nation));
+ } else {
+ notify_player(NULL, NULL, E_DESTROYED, _("The %s are no more!"),
+ get_nation_name_plural(pplayer->nation));
+ }
}
/**************************************************************************
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/ruleset.c freeciv.PR14289/server/ruleset.c
--- vendor.freeciv.current/server/ruleset.c 2005-10-13 22:20:18.000000000
+0100
+++ freeciv.PR14289/server/ruleset.c 2005-10-15 01:32:46.000000000 +0100
@@ -2600,6 +2600,14 @@
freelog(LOG_ERROR, "Switching to tech_leakage 0.");
game.info.tech_leakage = 0;
}
+
+ game.info.gameloss_style =
+ secfile_lookup_int(&file, "civstyle.gameloss_style");
+ if (game.info.gameloss_style < 0 || game.info.gameloss_style > 1) {
+ freelog(LOG_ERROR, "Bad value %i for gameloss_style. Using 0.",
+ game.info.gameloss_style);
+ game.info.gameloss_style = 0;
+ }
/* City incite cost */
game.info.base_incite_cost =
diff -ruN -Xvendor.freeciv.current/diff_ignore
vendor.freeciv.current/server/stdinhand.c freeciv.PR14289/server/stdinhand.c
--- vendor.freeciv.current/server/stdinhand.c 2005-10-13 21:53:56.000000000
+0100
+++ freeciv.PR14289/server/stdinhand.c 2005-10-15 01:32:46.000000000 +0100
@@ -2188,7 +2188,8 @@
int ntokens = 0, i;
const char *usage = _("Undefined arguments. Usage: debug <diplomacy "
"<player> | city <x> <y> | units <x> <y> | "
- "unit <id> | tech <player> | timing | info>.");
+ "unit <id> | tech <player> | timing | info| "
+ "murder <player> >.");
if (server_state != RUN_GAME_STATE) {
cmd_reply(CMD_DEBUG, caller, C_SYNTAX,
@@ -2354,6 +2355,25 @@
UNIT_LOG(LOG_NORMAL, punit, _("%s's %s debugged."),
unit_owner(punit)->name, unit_name(punit->type));
}
+ } else if (ntokens > 0 && strcmp(arg[0], "murder") == 0) {
+ /* This is more a 'testing' command than a 'debugging' comand,
+ * but we want to ensure it is available only in debugging mode,
+ * and only someone interested in testing & debugging should
+ * be able to use it */
+ struct player *pplayer;
+ enum m_pre_result match_result;
+
+ if (ntokens != 2) {
+ cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+ goto cleanup;
+ }
+ pplayer = find_player_by_name_prefix(arg[1], &match_result);
+ if (pplayer == NULL) {
+ cmd_reply_no_such_player(CMD_DEBUG, caller, arg[1], match_result);
+ goto cleanup;
+ }
+
+ pplayer->is_dying = TRUE;
} else {
cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
}
|
|