See http://www.teaser.fr/~amajorel/wesnoth/ diff -urN wesnoth-1.8.2/src/cheat.hpp wesnoth-1.8.2-aym1/src/cheat.hpp --- wesnoth-1.8.2/src/cheat.hpp 1970-01-01 01:00:00.000000000 +0100 +++ wesnoth-1.8.2-aym1/src/cheat.hpp 2010-07-01 14:56:27.000000000 +0200 @@ -0,0 +1,118 @@ +/* + * cheat.hpp - cheats for BfW + * AYM 2010-07-01 + */ + + +#include +#include +#include +#include + +#include +#include + + +/* Include cheat.hpp once in every source file that needs cheats. Call + cheat_init() before each use of any of the variables below. The parsing will + be run once per source file that includes cheat.hpp. */ + +static const char cheat_deathless_sides_name[] = "DEATHLESS_SIDES"; +static const char cheat_deathless_team_name[] = "DEATHLESS_TEAM"; +static const char cheat_traits_name[] = "TRAITS"; + +static long cheat_deathless_sides_bitmap = 1 << 31; +static const char *cheat_deathless_team_inval = ""; +static const char *cheat_deathless_team = cheat_deathless_team_inval; +static std::vector + cheat_traits; // $TRAITS + + +static void cheat_init () +{ + /* Parse $DEATHLESS_SIDES */ + if (cheat_deathless_sides_bitmap == 1 << 31) + { + const char *s = getenv (cheat_deathless_sides_name); + cheat_deathless_sides_bitmap = 0; + if (s == NULL) + { + fprintf (stderr, "cheat_init: %s not set\n", cheat_deathless_sides_name); + } + else + { + fprintf (stderr, "cheat_init: %s set to \"%s\"\n", cheat_deathless_sides_name, s); + for (const char *p = s; *p != '\0';) + { + char *p2; + errno = 0; + long n = strtol (p, &p2, 0); + if (errno != 0) + { + fprintf (stderr, "cheat_init: %s(%d): %s\n", cheat_deathless_sides_name, int (p - s), strerror (errno)); + break; + } + fprintf (stderr, "cheat_init: %s(%d): parsed \"%.*s\" as %ld\n", cheat_deathless_sides_name, int (p - s), int (p2 - p), p, n); + if (n < 1) + fprintf (stderr, "cheat_init: %s(%d): side# < 1 (%ld)\n", cheat_deathless_sides_name, int (p - s), n); + else if (n >= 31) + fprintf (stderr, "cheat_init: %s(%d): side# >= 31 (%ld)\n", cheat_deathless_sides_name, int (p - s), n); + else + cheat_deathless_sides_bitmap |= (1 << n); + p = p2; + while (*p == ',' || isspace (*p)) + p++; + } + fprintf (stderr, "cheat_init: %s: %#lx\n", cheat_deathless_sides_name, cheat_deathless_sides_bitmap); + } + } + + if (cheat_deathless_team == cheat_deathless_team_inval) + { + cheat_deathless_team = getenv (cheat_deathless_team_name); + if (cheat_deathless_team == NULL) + fprintf (stderr, "cheat_init: %s not set\n", cheat_deathless_team_name); + else + fprintf (stderr, "cheat_init: %s set to \"%s\"\n", cheat_deathless_team_name, cheat_deathless_team); + } + + /* Parse $TRAITS */ + static bool parsed_traits = false; + if (! parsed_traits) + { + const char *s = getenv (cheat_traits_name); + if (s == NULL) + { + fprintf (stderr, "cheat_init: %s not set\n", cheat_traits_name); + } + else + { + fprintf (stderr, "cheat_init: %s set to \"%s\"\n", cheat_traits_name, s); + const char *tokstart = 0; + for (const char *p = s; ; p++) + { + if (*p == '\0' || *p == ',' || isspace (*p)) + { + if (tokstart != 0) + { + fprintf (stderr, "cheat_init: %s: \"%.*s\"\n", cheat_traits_name, p - tokstart, tokstart); + std::string t (tokstart, p - tokstart); + cheat_traits.push_back (t); + tokstart = 0; + } + if (*p == '\0') + break; + } + else + { + if (tokstart == 0) + tokstart = p; + } + } + } + parsed_traits = true; + } + +} + + diff -urN wesnoth-1.8.2/src/game.cpp wesnoth-1.8.2-aym1/src/game.cpp --- wesnoth-1.8.2/src/game.cpp 2010-05-01 01:22:12.000000000 +0200 +++ wesnoth-1.8.2-aym1/src/game.cpp 2010-07-01 23:33:16.000000000 +0200 @@ -1241,7 +1241,7 @@ std::vector chat; config game_data; - const mp::controller cntr = mp::CNTR_LOCAL; + const mp::controller cntr = mp::CNTR_COMPUTER; mp::start_local_game(disp(), game_config(), cntr); diff -urN wesnoth-1.8.2/src/unit.cpp wesnoth-1.8.2-aym1/src/unit.cpp --- wesnoth-1.8.2/src/unit.cpp 2010-05-25 23:20:10.000000000 +0200 +++ wesnoth-1.8.2-aym1/src/unit.cpp 2010-07-04 00:09:52.000000000 +0200 @@ -19,6 +19,8 @@ #include "global.hpp" +#include "cheat.hpp" // AYM 2010-07-01 + #include "unit.hpp" #include "actions.hpp" @@ -753,12 +755,27 @@ // Now randomly fill out to the number of traits required or until // there aren't any more traits. + // AYM 2008-11-06: first try to add the traits listed in $TRAITS. + // Call the RNG anyway in case that's important for compatibility. int nb_traits = std::distance(current_traits.first, current_traits.second); int max_traits = type->num_traits(); + size_t cheat_traits_index = 0; + cheat_init (); for (; nb_traits < max_traits && !candidate_traits.empty(); ++nb_traits) { int num = (state ? state->rng().get_next_random() : get_random_nocheck()) % candidate_traits.size(); + if (cheat_traits_index < cheat_traits.size ()) + { + for (size_t c = 0; c < candidate_traits.size (); c++) + if (candidate_traits[c].get_attribute ("id") + == cheat_traits[cheat_traits_index]) + { + num = c; + break; + } + cheat_traits_index++; + } modifications_.add_child("trait", candidate_traits[num]); candidate_traits.erase(candidate_traits.begin() + num); } @@ -3005,3 +3022,41 @@ { return id_ == unit_id; } + + +// AYM 2010-07-01 +bool unit::take_hit(int damage) +{ + game_display *disp = game_display::get_singleton(); + const std::vector& teams = disp->get_teams (); + cheat_init (); + fprintf (stderr, "take_hit: side %u, team \"%-*.*s\", user_team \"%-*.*s\", name \"%-*.*s\": %2d - %2d = " + , side () + , 3, 3, teams[side_ - 1].team_name ().c_str () + , 8, 8, teams[side_ - 1].user_team_name ().c_str () + , 8, 8, name_.c_str () + , hit_points_ + , damage + ); + hit_points_ -= damage; + fprintf (stderr, "%2d", hit_points_); + if (hit_points_ < 1) + { + const char *saved_by = NULL; + if (side_ < 31 && (cheat_deathless_sides_bitmap & (1 << side_))) + saved_by = cheat_deathless_sides_name; + else if (cheat_deathless_team != NULL + && ( strcmp (cheat_deathless_team, teams[side_ - 1].team_name ().c_str ()) == 0 + || strcmp (cheat_deathless_team, teams[side_ - 1].user_team_name ().c_str ()) == 0)) + saved_by = cheat_deathless_team_name; + if (saved_by != NULL) + { + fprintf (stderr, " saved by %s", saved_by); + hit_points_ = 1; + } + else + fprintf (stderr, " killed"); + } + fputc ('\n', stderr); + return hit_points_ <= 0; +} diff -urN wesnoth-1.8.2/src/unit.hpp wesnoth-1.8.2-aym1/src/unit.hpp --- wesnoth-1.8.2/src/unit.hpp 2010-05-25 23:20:10.000000000 +0200 +++ wesnoth-1.8.2-aym1/src/unit.hpp 2010-07-01 14:45:19.000000000 +0200 @@ -150,7 +150,7 @@ void refresh(); void set_hitpoints(int hitpoints) { hit_points_ = hitpoints; } - bool take_hit(int damage) { hit_points_ -= damage; return hit_points_ <= 0; } + bool take_hit(int damage); void heal(int amount); void heal_all() { hit_points_ = max_hitpoints(); } bool resting() const { return resting_; }