Added in new healing/curing

This commit is contained in:
Dave White 2003-09-16 21:38:55 +00:00
parent 6337d61888
commit 85fb467100
8 changed files with 96 additions and 66 deletions

View file

@ -481,46 +481,48 @@ std::map<gamemap::location,unit>::iterator
void calculate_healing(display& disp, const gamemap& map,
std::map<gamemap::location,unit>& units, int side)
{
std::map<gamemap::location,int> healed_units;
std::map<gamemap::location,int> healed_units, max_healing;
std::map<gamemap::location,unit>::iterator i;
for(i = units.begin(); i != units.end(); ++i) {
if(i->second.side() != side)
continue;
bool heals = false;
if(map[i->first.x][i->first.y] == gamemap::TOWER) {
heals = true;
}
if(i->second.type().regenerates()) {
heals = true;
}
gamemap::location adjacent[6];
get_adjacent_tiles(i->first,adjacent);
for(int j = 0; j != 6; ++j) {
const std::map<gamemap::location,unit>::const_iterator adj_unit =
units.find(adjacent[j]);
if(adj_unit != units.end() && adj_unit->second.type().heals() &&
adj_unit->second.side() == side) {
heals = true;
}
}
if(heals) {
//the unit heals if it's on this side, and if it's on a tower or
//it has regeneration
if(i->second.side() == side &&
(map[i->first.x][i->first.y] == gamemap::TOWER ||
i->second.type().regenerates())) {
healed_units.insert(std::pair<gamemap::location,int>(
i->first, game_config::heal_amount));
i->first, game_config::cure_amount));
}
//otherwise find the maximum healing for the unit
else {
int max_heal = 0;
gamemap::location adjacent[6];
get_adjacent_tiles(i->first,adjacent);
for(int j = 0; j != 6; ++j) {
std::map<gamemap::location,unit>::const_iterator healer =
units.find(adjacent[j]);
if(healer != units.end() && healer->second.side() == side) {
max_heal = maximum(max_heal,
healer->second.type().max_unit_healing());
}
}
if(max_heal > 0) {
max_healing.insert(std::pair<gamemap::location,int>(i->first,
max_heal));
}
}
}
//now see about units that can heal other units
for(i = units.begin(); i != units.end(); ++i) {
if(i->second.side() != side)
continue;
if(i->second.type().heals()) {
if(i->second.side() == side && i->second.type().heals()) {
gamemap::location adjacent[6];
bool gets_healed[6];
get_adjacent_tiles(i->first,adjacent);
int nhealed = 0;
@ -531,41 +533,40 @@ void calculate_healing(display& disp, const gamemap& map,
if(adj != units.end() &&
adj->second.hitpoints() < adj->second.max_hitpoints() &&
adj->second.side() == i->second.side() &&
healed_units.count(adj->first) == 0) {
healed_units[adj->first] < max_healing[adj->first]) {
++nhealed;
gets_healed[j] = true;
} else {
gets_healed[j] = false;
}
}
if(nhealed == 0)
continue;
const int healing_per_unit = game_config::healer_heals_per_turn/
nhealed;
const int healing_per_unit = i->second.type().heals()/nhealed;
for(j = 0; j != 6; ++j) {
const std::map<gamemap::location,unit>::const_iterator adj =
units.find(adjacent[j]);
if(adj != units.end() &&
adj->second.hitpoints() < adj->second.max_hitpoints() &&
adj->second.side() == i->second.side() &&
healed_units.count(adj->first) == 0) {
healed_units.insert(std::pair<gamemap::location,int>(
i->first,healing_per_unit));
}
if(!gets_healed[j])
continue;
assert(units.find(adjacent[j]) != units.end());
healed_units[adjacent[j]]
= minimum(max_healing[adjacent[j]],
healed_units[adjacent[j]]+healing_per_unit);
}
}
}
//poisoned units will take the same amount of damage per turn, as
//healing heals until they are reduced to 1 hitpoint. If they are
//healed on a turn, they recover 0 hitpoints that turn, but they
//curing heals until they are reduced to 1 hitpoint. If they are
//cured on a turn, they recover 0 hitpoints that turn, but they
//are no longer poisoned
for(i = units.begin(); i != units.end(); ++i) {
if(i->second.side() != side)
continue;
if(i->second.has_flag("poisoned")) {
const int damage = minimum<int>(game_config::heal_amount,
if(i->second.side() == side && i->second.has_flag("poisoned")) {
const int damage = minimum<int>(game_config::cure_amount,
i->second.hitpoints()-1);
if(damage > 0) {
@ -600,17 +601,22 @@ void calculate_healing(display& disp, const gamemap& map,
const int DelayAmount = 50;
if(u.has_flag("poisoned")) {
if(u.has_flag("poisoned") && h->second > 0) {
u.remove_flag("poisoned");
h->second = 0;
//poison is purged only if we are on a village or next to a curer
if(h->second >= game_config::cure_amount ||
max_healing[h->first] >= game_config::cure_amount) {
u.remove_flag("poisoned");
if(show_healing) {
sound::play_sound("heal.wav");
SDL_Delay(DelayAmount);
disp.invalidate_unit();
disp.update_display();
if(show_healing) {
sound::play_sound("heal.wav");
SDL_Delay(DelayAmount);
disp.invalidate_unit();
disp.update_display();
}
}
h->second = 0;
} else if(h->second < 0) {
if(show_healing)
sound::play_sound("groan.wav");

View file

@ -733,7 +733,7 @@ void display::draw_minimap(int x, int y, int w, int h)
const int wbox = static_cast<int>(scaling*mapx()/(zoom_*0.75) - scaling);
const int hbox = static_cast<int>(scaling*this->y()/zoom_ - scaling);
const short boxcolour = (short)0xFFFF;
const Pixel boxcolour = Pixel(SDL_MapRGB(surface->format,0xFF,0xFF,0xFF));
SDL_Surface* const screen = screen_.getSurface();
short* const data = reinterpret_cast<short*>(screen->pixels);
short* const start_top = data + (y+ybox)*screen->w + (x+xbox);
@ -1167,13 +1167,13 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
short* startdst =
reinterpret_cast<short*>(dst->pixels) + j*dst->w + xdst;
const short replace_energy = 0xFFFF;
const Pixel replace_energy =
Pixel(SDL_MapRGB(energy_image->format,0xFF,0xFF,0xFF));
const short new_energy = yloc >= show_energy_after ?
energy_colour : energy_loss_colour;
const int skip = yloc >= energy_bar_loc.first ? skip_energy_rows:0;
short* startenergy = NULL;
const int energy_w = energy_image->w + ((energy_image->w%2) == 1 ? 1:0);
@ -2079,7 +2079,7 @@ const std::pair<int,int>& display::calculate_energy_bar()
const SDL_Surface* const image = getImage("unmoved-energy.png");
const short* const begin = reinterpret_cast<short*>(image->pixels);
const short colour = 0xFFFF;
const Pixel colour = Pixel(SDL_MapRGB(image->format,0xFF,0xFF,0xFF));
for(int y = 0; y != image->h; ++y) {
const short* const i1 = begin + image->w*y;

View file

@ -45,8 +45,6 @@
LEVEL_RESULT play_game(display& disp, game_state& state, config& game_config,
game_data& units_data, CVideo& video)
{
CKey key;
std::string type = state.campaign_type;
if(type.empty())
type = "scenario";

View file

@ -16,8 +16,10 @@ namespace game_config
const int unit_cost = 1;
const int base_income = 2;
const int tower_income = 2;
const int heal_amount = 8;
const int healer_heals_per_turn = 12;
const int heal_amount = 4;
const int healer_heals_per_turn = 8;
const int cure_amount = 8;
const int curer_heals_per_turn = 18;
const int recall_cost = 20;
const std::string version = "0.4.4";
bool debug = false;

View file

@ -21,6 +21,8 @@ namespace game_config
extern const int tower_income;
extern const int heal_amount;
extern const int healer_heals_per_turn;
extern const int cure_amount;
extern const int curer_heals_per_turn;
extern const int recall_cost;
extern const std::string version;

View file

@ -34,7 +34,7 @@ namespace sound {
manager::manager()
{
const int res =
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,MIX_DEFAULT_FORMAT,2,4096);
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,MIX_DEFAULT_FORMAT,2,1024);
if(res >= 0) {
mix_ok = true;
} else {

View file

@ -9,6 +9,7 @@
See the COPYING file for more details.
*/
#include "game_config.hpp"
#include "gamestatus.hpp"
#include "language.hpp"
#include "unit_types.hpp"
@ -307,6 +308,17 @@ unit_type::unit_type(config& cfg, const movement_type_map& mv_types,
std::vector<config*>& traits)
: cfg_(cfg), possibleTraits_(traits), alpha_(1.0)
{
if(has_ability("heals")) {
heals_ = game_config::healer_heals_per_turn;
max_heals_ = game_config::heal_amount;
} else if(has_ability("cures")) {
heals_ = game_config::curer_heals_per_turn;
max_heals_ = game_config::cure_amount;
} else {
heals_ = 0;
max_heals_ = 0;
}
heals_ = has_ability("heals");
regenerates_ = has_ability("regenerates");
leadership_ = has_ability("leadership");
@ -495,7 +507,12 @@ const std::string& unit_type::ability() const
return cfg_.values["ability"];
}
bool unit_type::heals() const
int unit_type::max_unit_healing() const
{
return max_heals_;
}
int unit_type::heals() const
{
return heals_;
}

View file

@ -146,7 +146,11 @@ public:
const std::string& ability() const;
bool heals() const;
//max_unit_healing returns the maximum hitpoints a unit next to this
//unit can heal per turn. heals returns the total amount of hitpoints
//this unit can heal out of all adjacent units
int max_unit_healing() const;
int heals() const;
bool regenerates() const;
bool is_leader() const;
bool is_lightbringer() const;
@ -163,7 +167,8 @@ private:
double alpha_;
bool heals_;
int max_heals_;
int heals_;
bool regenerates_;
bool leadership_;
bool lightbringer_;