added some explanatory tooltips for some unit attributes on sidebar

This commit is contained in:
uid68803 2003-12-30 17:24:46 +00:00
parent 7b2d7fb9cd
commit 541e1bc669
9 changed files with 164 additions and 58 deletions

View file

@ -145,15 +145,21 @@ height=600
xanchor=right
yanchor=fixed
[/unit_traits]
[unit_status]
[unit_abilities]
font_size=14
rect=897,514,1024,530
xanchor=right
yanchor=fixed
[/unit_abilities]
[unit_status]
font_size=14
rect=897,530,1024,546
xanchor=right
yanchor=fixed
[/unit_status]
[unit_moves]
font_size=14
rect=897,530,1024,546
rect=897,546,1024,562
prefix=movement
prefix_literal=": "
xanchor=right
@ -161,7 +167,7 @@ height=600
[/unit_moves]
[unit_hp]
font_size=14
rect=897,546,1024,562
rect=897,562,1024,578
prefix=hp
prefix_literal=": "
xanchor=right
@ -169,7 +175,7 @@ height=600
[/unit_hp]
[unit_xp]
font_size=14
rect=897,562,1024,578
rect=897,578,1024,594
prefix=xp
prefix_literal=": "
xanchor=right
@ -177,7 +183,7 @@ height=600
[/unit_xp]
[unit_weapons]
font_size=12
rect=897,578,1024,690
rect=897,594,1024,706
xanchor=right
yanchor=fixed
[/unit_weapons]

View file

@ -125,6 +125,58 @@ EASY="Fighter (easy)"
NORMAL="*Hero (medium)"
HARD="Champion (hard)"
lawful_description="Lawful units fight better at day, and worse at night.
Day: +25% Damage
Night: -25% Damage"
neutral_description="Neutral units are unaffected by day and night, fighting equally well under both conditions."
chaotic_description="Chaotic units fight better at night, and worse at day.
Day: -25% Damage
Night: +25% Damage"
invisible_description="This unit is invisible. It cannot be seen or attacked by enemy units."
slowed_description="This unit has been slowed. It moves at half normal speed and receives one less attack than normal in combat."
poisoned_description="This unit is poisoned. It will lose 8 HP every turn until it can seek a cure to the poison in a village or from a friendly unit with the 'cures' ability.
Units cannot be killed by poison alone. The poison will not reduce it below 1 HP."
heals_description="Heals:
Allows the unit to heal adjacent friendly units at the beginning of the turn.
A unit cared for by a healer may heal up to 4 HP per turn.
A healer may heal a total of 8 HP per turn, for all units it cares for.
A poisoned unit cannot be cured of its poison by a healer, and must seek the care of a village or a unit that can cure."
cures_description="Cures:
This unit combines herbal remedies with magic to heal units more quickly than is normally possible on the battlefield.
This unit will care for all adjacent friendly units that are injured at the beginning of the turn.
A unit cared for by a curer may heal up to 8 HP per turn.
A curer may heal a total of 18 HP per turn, for all units it cares for.
A curer can cure a unit of poison, although that unit will receive no additional healing on the turn it is cured of the poison."
teleport_description="Teleport:
This unit may teleport between any two friendly villages instantly."
leadership_description="Leadership:
This unit can lead friendly units that are next to it, making them fight better.
Adjacent friendly units of lower level will do more damage in battle."
ambush_description="Ambush:
This unit can hide in forest, and remain undetected by its enemies.
Enemy units cannot see or attack this unit when it is in forest, except for any turn immediately after this unit has attacked."
illuminates_description="Illuminates:
This unit illuminates the surrounding area, making lawful units fight better, and chaotic units fight worse.
Any units adjacent to this unit will fight as if it were dusk when it is night, and as if it were day when it is dusk."
skirmisher_description="Skirmishes:
This unit is skilled in moving past enemies quickly, and ignores all Enemy Zones of Control."
no_leader_to_recruit="You don't have a leader to recruit with."
leader_not_on_start="You must have your leader on a keep to recruit or recall units."
no_recruit_location="There are no vacant castle tiles in which to recruit a unit."

View file

@ -751,6 +751,8 @@ void display::draw_report(reports::TYPE report_num)
tooltips::clear_tooltips(rect);
SDL_Rect area = rect;
if(report.text.empty() == false) {
std::string str = item->prefix();
@ -764,7 +766,11 @@ void display::draw_report(reports::TYPE report_num)
str += report.text.substr(nchop) + item->postfix();
font::draw_text(this,rect,item->font_size(),font::NORMAL_COLOUR,str,rect.x,rect.y);
area = font::draw_text(this,rect,item->font_size(),font::NORMAL_COLOUR,str,rect.x,rect.y);
}
if(report.tooltip.empty() == false) {
tooltips::add_tooltip(area,report.tooltip);
}
if(report.image.empty() == false) {
@ -816,7 +822,6 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
if(teams_.empty())
return;
tooltips::clear_tooltips(description_rect);
SDL_Rect clipRect = clip_rect != NULL ? *clip_rect : screen_area();
@ -858,7 +863,7 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
<< "\n-(" << string_table["level"] << " "
<< u.type().level() << ")\n"
<< status << "\n"
<< unit_type::alignment_description(u.type().alignment())
<< translate_string(unit_type::alignment_description(u.type().alignment()))
<< "\n"
<< u.traits_description() << "\n";

View file

@ -8,8 +8,8 @@
namespace {
const std::string report_names[] = { "unit_description", "unit_type", "unit_level",
"unit_traits","unit_status","unit_alignment","unit_hp","unit_xp","unit_moves",
"unit_weapons","unit_image","unit_profile","time_of_day",
"unit_traits","unit_status","unit_alignment","unit_abilities","unit_hp","unit_xp",
"unit_moves","unit_weapons","unit_image","unit_profile","time_of_day",
"turn","gold","villages","num_units","upkeep", "expenses",
"income", "terrain", "position" };
}
@ -46,24 +46,55 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
switch(type) {
case UNIT_DESCRIPTION:
return report(u->second.description());
case UNIT_TYPE:
return report(u->second.type().language_name());
case UNIT_TYPE: {
report res(u->second.type().language_name());
res.tooltip = u->second.type().unit_description();
return res;
}
case UNIT_LEVEL:
str << u->second.type().level();
break;
case UNIT_TRAITS:
return report(u->second.traits_description());
case UNIT_STATUS:
if(map.on_board(loc) && u->second.invisible(map.underlying_terrain(map[loc.x][loc.y])))
return report("@" + string_table["invisible"]);
else if(u->second.has_flag("slowed"))
return report("#" + string_table["slowed"]);
else if(u->second.has_flag("poisoned"))
case UNIT_STATUS: {
std::string status = "healthy", prefix = "";
if(map.on_board(loc) && u->second.invisible(map.underlying_terrain(map[loc.x][loc.y]))) {
status = "invisible";
prefix = "@";
} else if(u->second.has_flag("slowed")) {
status = "slowed";
prefix = "#";
return report("#" + string_table["poisoned"]);
else
return report(string_table["healthy"]);
case UNIT_ALIGNMENT:
return report(unit_type::alignment_description(u->second.type().alignment()));
} else if(u->second.has_flag("poisoned")) {
status = "poisoned";
prefix = "#";
}
report res(prefix + string_table[status]);
res.tooltip = string_table[status + "_description"];
return res;
}
case UNIT_ALIGNMENT: {
const std::string& align = unit_type::alignment_description(u->second.type().alignment());
report res(translate_string(align));
res.tooltip = string_table[align + "_description"];
return res;
}
case UNIT_ABILITIES: {
std::stringstream tooltip;
const std::vector<std::string>& abilities = u->second.type().abilities();
for(std::vector<std::string>::const_iterator i = abilities.begin(); i != abilities.end(); ++i) {
str << translate_string(*i);
if(i+1 != abilities.end())
str << ",";
tooltip << string_table[*i + "_description"] << "\n\n";
}
report res(str.str());
res.tooltip = tooltip.str();
return res;
}
case UNIT_HP:
if(u->second.hitpoints() <= u->second.max_hitpoints()/3)
str << "#";
@ -118,8 +149,20 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
return report("",u->second.type().image());
case UNIT_PROFILE:
return report("",u->second.type().image_profile());
case TIME_OF_DAY:
return report("",timeofday_at(status,units,mouseover).image);
case TIME_OF_DAY: {
const time_of_day& tod = timeofday_at(status,units,mouseover);
report res("",tod.image);
std::stringstream tooltip;
tooltip << "+" << translate_string_default(tod.id,tod.name) << "\n"
<< translate_string("lawful") << " " << string_table["units"] << ": "
<< (tod.lawful_bonus > 0 ? "+" : "") << tod.lawful_bonus << "%\n"
<< translate_string("neutral") << " " << string_table["units"] << ": " << "0%\n"
<< translate_string("chaotic") << " " << string_table["units"] << ": "
<< (tod.lawful_bonus < 0 ? "+" : "") << (tod.lawful_bonus*-1) << "%";
res.tooltip = tooltip.str();
return res;
}
case TURN:
str << status.turn() << "/" << status.number_of_turns() << "\n";
break;

View file

@ -13,7 +13,7 @@
namespace reports {
enum TYPE { UNIT_DESCRIPTION, UNIT_TYPE, UNIT_LEVEL, UNIT_TRAITS, UNIT_STATUS,
UNIT_ALIGNMENT, UNIT_HP, UNIT_XP, UNIT_MOVES, UNIT_WEAPONS,
UNIT_ALIGNMENT, UNIT_ABILITIES, UNIT_HP, UNIT_XP, UNIT_MOVES, UNIT_WEAPONS,
UNIT_IMAGE, UNIT_PROFILE, TIME_OF_DAY,
TURN, GOLD, VILLAGES, NUM_UNITS, UPKEEP, EXPENSES, INCOME, TERRAIN, POSITION,
NUM_REPORTS};
@ -28,9 +28,9 @@ namespace reports {
explicit report(const std::string& text) : text(text) {}
report(const std::string& text, const std::string& image) : text(text), image(image) {}
bool empty() const { return text.empty() && image.empty(); }
bool operator==(const report& o) const { return o.text == text && o.image == image; }
bool operator==(const report& o) const { return o.text == text && o.image == image && o.tooltip == tooltip; }
bool operator!=(const report& o) const { return !(o == *this); }
std::string text, image;
std::string text, image, tooltip;
};
report generate_report(TYPE type, const gamemap& map, const unit_map& units,

View file

@ -180,6 +180,27 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
namespace gui
{
size_t text_to_lines(std::string& message, size_t max_length)
{
size_t cur_line = 0, longest_line = 0;
for(std::string::iterator i = message.begin(); i != message.end(); ++i) {
if(*i == ' ' && cur_line > max_length)
*i = '\n';
if(*i == '\n' || i+1 == message.end()) {
if(cur_line > longest_line)
longest_line = cur_line;
cur_line = 0;
} else {
++cur_line;
}
}
return longest_line;
}
int show_dialog(display& disp, SDL_Surface* image,
const std::string& caption, const std::string& msg,
DIALOG_TYPE type,
@ -229,29 +250,11 @@ int show_dialog(display& disp, SDL_Surface* image,
menu menu_(disp,menu_items,type == MESSAGE);
const int border_size = 6;
int nlines = 1;
int longest_line = 0;
int cur_line = 0;
const int max_line_length = 58;
std::string message = msg;
for(std::string::iterator message_it = message.begin();
message_it != message.end(); ++message_it) {
if(*message_it == ' ' && cur_line > max_line_length)
*message_it = '\n';
if(*message_it == '\n') {
if(cur_line > longest_line)
longest_line = cur_line;
cur_line = 0;
++nlines;
} else {
++cur_line;
}
}
const size_t longest_line = text_to_lines(message,max_line_length);
SDL_Rect text_size = { 0, 0, 0, 0 };
if(!message.empty()) {
@ -324,9 +327,6 @@ int show_dialog(display& disp, SDL_Surface* image,
button_heights += button_height_padding;
}
if(cur_line > longest_line)
longest_line = cur_line;
int check_button_height = 0;
int check_button_width = 0;

View file

@ -63,6 +63,9 @@ struct check_item {
bool checked;
};
//function to chop up one long string of text into lines
size_t text_to_lines(std::string& text, size_t max_length);
//if a menu is given, then returns -1 if the dialog was cancelled, and the
//index of the selection otherwise. If no menu is given, returns the index
//of the button that was pressed

View file

@ -24,7 +24,9 @@ display* display_ = NULL;
struct tooltip
{
tooltip(const SDL_Rect& r, const std::string& msg) : rect(r), message(msg)
{}
{
gui::text_to_lines(message,60);
}
SDL_Rect rect;
std::string message;
};
@ -143,7 +145,7 @@ void clear_tooltips()
void clear_tooltips(const SDL_Rect& rect)
{
clear_tooltips();
clear_tooltip();
for(std::vector<tooltip>::iterator i = tips.begin(); i != tips.end(); ) {
if(rectangles_overlap(i->rect,rect)) {
i = tips.erase(i);
@ -169,8 +171,7 @@ void add_tooltip(const SDL_Rect& rect, const std::string& message)
void process(int mousex, int mousey, bool lbutton)
{
for(std::vector<tooltip>::const_iterator i = tips.begin();
i != tips.end(); ++i) {
for(std::vector<tooltip>::const_iterator i = tips.begin(); i != tips.end(); ++i) {
if(mousex > i->rect.x && mousey > i->rect.y &&
mousex < i->rect.x + i->rect.w && mousey < i->rect.y + i->rect.h) {
show_tooltip(*i);

View file

@ -611,11 +611,7 @@ unit_type::ALIGNMENT unit_type::alignment() const
const std::string& unit_type::alignment_description(unit_type::ALIGNMENT align)
{
static const std::string aligns[] = { "lawful", "neutral", "chaotic" };
const string_map::const_iterator i = string_table.find(aligns[align]);
if(i != string_table.end())
return i->second;
else
return aligns[align];
return aligns[align];
}
double unit_type::alpha() const