diff -Nur freeciv/common/game.h freeciv-mod/common/game.h --- freeciv/common/game.h Mon Sep 18 23:49:03 2000 +++ freeciv-mod/common/game.h Thu Sep 28 03:46:14 2000 @@ -168,6 +168,8 @@ int hut_overflight; int pillage_select; int nuke_contamination; + int killstack; + int deathfight; } rgame; char demography[MAX_LEN_DEMOGRAPHY]; diff -Nur freeciv/common/packets.c freeciv-mod/common/packets.c --- freeciv/common/packets.c Tue Sep 26 00:17:26 2000 +++ freeciv-mod/common/packets.c Thu Sep 28 03:47:46 2000 @@ -3791,7 +3791,9 @@ if (pc && has_capability("nuclear_fallout", pc->capability)) { cptr=put_uint8(cptr, packet->nuke_contamination); } - + cptr=put_uint8(cptr, packet->killstack); + cptr=put_uint8(cptr, packet->deathfight); + put_uint16(buffer, cptr-buffer); return send_connection_data(pc, buffer, cptr-buffer); } @@ -3820,7 +3822,9 @@ } else { packet->nuke_contamination = CONTAMINATION_POLLUTION; } - + iget_uint8(&iter, &packet->killstack); + iget_uint8(&iter, &packet->deathfight); + pack_iter_end(&iter, pc); remove_packet_from_buffer(pc->buffer); return packet; diff -Nur freeciv/common/packets.h freeciv-mod/common/packets.h --- freeciv/common/packets.h Thu Sep 7 01:07:16 2000 +++ freeciv-mod/common/packets.h Thu Sep 28 03:46:44 2000 @@ -766,6 +766,8 @@ int hut_overflight; int pillage_select; int nuke_contamination; + int killstack; + int deathfight; }; /********************************************************* diff -Nur freeciv/data/default/game.ruleset freeciv-mod/data/default/game.ruleset --- freeciv/data/default/game.ruleset Sun Jul 9 22:48:10 2000 +++ freeciv-mod/data/default/game.ruleset Tue Oct 3 03:43:17 2000 @@ -38,3 +38,17 @@ ; "Pollution" - Pollution (same as industrial/population-generated). ; "Fallout" - Nuclear Fallout (distinct from industrial/population). nuke_contamination = "Fallout" + +;If this is set to 1, all units in the same tile of a killed unit will +;be killed (unless they are on a fortress, airbase or city). This is the +;freeciv default. +;If this options is set to 0, units are killed one by one, +;except by nuclear weapons, of course. +killstack = 0 + +; If deathfight is set to a large number (e.g. 1000), a battle ends until one +; of the units is destroyed. This is the freeciv default. +; If is set to a low number instead (e.g. 15), both units can survive after +; one attack. Adjust this number at taste. For numbers less than or equal 1 +; the efect is the same. +deathfight = 15 diff -Nur freeciv/server/ruleset.c freeciv-mod/server/ruleset.c --- freeciv/server/ruleset.c Tue Sep 26 00:18:30 2000 +++ freeciv-mod/server/ruleset.c Thu Sep 28 03:50:47 2000 @@ -2128,6 +2128,9 @@ game.rgame.nuke_contamination = CONTAMINATION_POLLUTION; } + game.rgame.killstack = secfile_lookup_int(&file, "civstyle.killstack"); + game.rgame.deathfight = secfile_lookup_int(&file, "civstyle.deathfight"); + section_file_check_unused(&file, filename); section_file_free(&file); } @@ -2442,7 +2445,9 @@ misc_p.hut_overflight = game.rgame.hut_overflight; misc_p.pillage_select = game.rgame.pillage_select; misc_p.nuke_contamination = game.rgame.nuke_contamination; - + misc_p.killstack = game.rgame.killstack; + misc_p.deathfight = game.rgame.deathfight; + lsend_packet_ruleset_game(dest, &misc_p); } diff -Nur freeciv/server/unitfunc.c freeciv-mod/server/unitfunc.c --- freeciv/server/unitfunc.c Mon Sep 18 23:49:19 2000 +++ freeciv-mod/server/unitfunc.c Tue Oct 3 03:18:09 2000 @@ -1654,7 +1654,8 @@ int defensepower = get_total_defense_power(attacker,defender); int attack_firepower = get_unit_type(attacker->type)->firepower; int defense_firepower = get_unit_type(defender->type)->firepower; - + int attack_counter = game.rgame.deathfight; + /* pearl harbour */ if (is_sailing_unit(defender) && map_get_city(defender->x, defender->y)) defense_firepower = 1; @@ -1674,19 +1675,21 @@ } else if (!defensepower) { defender->hp=0; } - while (attacker->hp>0 && defender->hp>0) { + do { if (myrand(attackpower+defensepower) >= defensepower) { defender->hp -= attack_firepower * game.firepower_factor; } else { attacker->hp -= defense_firepower * game.firepower_factor; } - } + attack_counter--; + } while (attacker->hp>0 && defender->hp>0 && attack_counter>0 ); + if (attacker->hp<0) attacker->hp = 0; if (defender->hp<0) defender->hp = 0; if (attacker->hp) maybe_make_veteran(attacker); - else if (defender->hp) + if (defender->hp) maybe_make_veteran(defender); } @@ -2867,7 +2870,7 @@ if( (incity) || (map_get_special(punit->x, punit->y)&S_FORTRESS) || (map_get_special(punit->x, punit->y)&S_AIRBASE) || - unitcount == 1) { + unitcount == 1 || !game.rgame.killstack) { notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_LOST, _("Game: %s lost to an attack by %s's %s%s."), get_unit_type(punit->type)->name, destroyer->name, diff -Nur freeciv/server/unithand.c freeciv-mod/server/unithand.c --- freeciv/server/unithand.c Tue Sep 26 00:18:34 2000 +++ freeciv-mod/server/unithand.c Tue Oct 3 03:22:15 2000 @@ -515,7 +515,8 @@ struct unit old_punit = *punit; /* Used for new ship algorithm. -GJW */ struct city *pcity; int def_x = pdefender->x, def_y = pdefender->y; - + int draw = 0; + freelog(LOG_DEBUG, "Start attack: %s's %s against %s's %s.", pplayer->name, unit_types[punit->type].name, game.players[pdefender->owner].name, @@ -593,15 +594,25 @@ } if (unit_flag(punit->type, F_ONEATTACK)) punit->moves_left = 0; - pwinner=(punit->hp) ? punit : pdefender; - plooser=(pdefender->hp) ? punit : pdefender; - + + if (punit->hp==0) { + plooser=punit; + pwinner=pdefender; + } else if (pdefender->hp==0) { + plooser=pdefender; + pwinner=punit; + } else { + plooser=NULL; + pwinner=NULL; + draw=1; + } + combat.attacker_unit_id=punit->id; combat.defender_unit_id=pdefender->id; combat.attacker_hp=punit->hp / game.firepower_factor; combat.defender_hp=pdefender->hp / game.firepower_factor; - combat.make_winner_veteran=pwinner->veteran?1:0; - + combat.make_winner_veteran=0;/***Can this field be removed?***/ + for(o=0; ox, punit->y, o) || map_get_known_and_seen(def_x, def_y, o)) @@ -639,7 +650,7 @@ pwinner->x, pwinner->y)); wipe_unit(plooser); } - else { + else if (pdefender==plooser) { /* The defender lost, the attacker punit lives! */ freelog(LOG_DEBUG, "Defender lost: %s's %s against %s's %s.", pplayer->name, unit_types[punit->type].name, @@ -659,6 +670,23 @@ plooser->x, plooser->y)); kill_unit(pwinner, plooser); /* no longer pplayer - want better msgs -- Syela */ + } else { + /* A draw, only possible if game.rgame.deathfight is low enough */ + freelog(LOG_DEBUG, "Atacker %s's %s against Defender %s's %s: no loosers.", + pplayer->name, unit_types[punit->type].name, + game.players[pdefender->owner].name, + unit_types[pdefender->type].name); + punit->moved=1; + + notify_player_ex(get_player(pdefender->owner), + pdefender->x, pdefender->y, E_UNIT_WIN, + _("Game: Your %s%s survived the pathetic attack" + " from %s's %s."), + unit_name(pdefender->type), + get_location_str_in(get_player(pdefender->owner), + pdefender->x, pdefender->y), + get_player(punit->owner)->name, + unit_name(punit->type)); } if (pwinner == punit && unit_flag(punit->type, F_MISSILE)) { wipe_unit(pwinner); @@ -689,7 +717,12 @@ } } - send_unit_info(0, pwinner); + if (draw) { + send_unit_info(0, punit); + send_unit_info(0, pdefender); + } else { + send_unit_info(0, pwinner); + } } /**************************************************************************