Change party status effect display to use small icons instead of text

Also:
- Redo PC status effect drawing to use a loop
- Add status icon for hyperactivity effect
- Fix display of monster name/AP on the text bar
This commit is contained in:
2015-01-16 03:22:50 -05:00
parent 71ce8946a0
commit 31b63b1ab7
7 changed files with 60 additions and 171 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1795,6 +1795,7 @@ bool handle_keystroke(sf::Event& event){
univ.party.status[ePartyStatus::DETECT_LIFE] += 10;
univ.party.status[ePartyStatus::FIREWALK] += 10;
add_string_to_buf("Debug: Stealth, Detect Life, Firewalk!");
draw_text_bar();
print_buf();
put_pc_screen();
break;
@@ -2149,7 +2150,7 @@ void post_load() {
put_pc_screen();
draw_terrain();
draw_buttons(0);
draw_text_bar(1);
draw_text_bar();
print_buf();
@@ -2274,17 +2275,14 @@ void increase_age() {
// Party spell effects
if(univ.party.status[ePartyStatus::STEALTH] == 1) {
reset_text_bar();
add_string_to_buf("Your footsteps grow louder. ");
}
move_to_zero(univ.party.status[ePartyStatus::STEALTH]);
if(univ.party.status[ePartyStatus::DETECT_LIFE] == 1) {
reset_text_bar();
add_string_to_buf("You stop detecting monsters. ");
}
move_to_zero(univ.party.status[ePartyStatus::DETECT_LIFE]);
if(univ.party.status[ePartyStatus::FIREWALK] == 1) {
reset_text_bar();
add_string_to_buf("Your feet stop glowing. ");
}
move_to_zero(univ.party.status[ePartyStatus::FIREWALK]);
@@ -2299,7 +2297,6 @@ void increase_age() {
pause(150);
}
else add_string_to_buf(" You land safely. ");
reset_text_bar();
}
move_to_zero(univ.party.status[ePartyStatus::FLIGHT]);

View File

@@ -90,9 +90,6 @@ short which_graphic_index[6] = {50,50,50,50,50,50};
char combat_graphics[5] = {28,29,36,79,2};
short debug_nums[6] = {0,0,0,0,0,0};
short remember_tiny_text = 300; // Remembers what's in the tiny text-bar, to prevent redrawing.
// 50 indicates area name, other number indicates which-rect.
// Add 200 if last mess. was in town
char light_area[13][13];
char unexplored_area[13][13];
@@ -584,7 +581,8 @@ void redraw_screen(int refresh) {
break;
default:
redraw_terrain();
draw_text_bar(bool(refresh & REFRESH_BAR));
if(refresh & REFRESH_BAR)
draw_text_bar();
refresh_text_bar();
draw_buttons(0);
break;
@@ -659,75 +657,46 @@ void draw_buttons(short mode) {
rect_draw_some_item(buttons_gworld, source_rect, mainPtr, dest_rec, sf::BlendAdd);
}
void reset_text_bar() {
remember_tiny_text = 300;
}
//short mode; // 0 - no redraw 1 - forced
void draw_text_bar(short mode) {
//short num_rect[3] = {12,10,4}; // Why? Just... why?
void draw_text_bar() {
short i;
location loc;
std::string combat_string;
loc = (is_out()) ? global_to_local(univ.party.p_loc) : univ.town.p_loc;
if(mode == 1)
remember_tiny_text = 500;
if((univ.party.status[ePartyStatus::STEALTH] > 0) || (univ.party.status[ePartyStatus::FLIGHT] > 0) ||
(univ.party.status[ePartyStatus::DETECT_LIFE] > 0) || (univ.party.status[ePartyStatus::FIREWALK] > 0) )
remember_tiny_text = 500;
bool in_area = false;
if(is_out()) {
for(i = 0; i < 8; i++)
if(loc.in(univ.out->info_rect[i])) {
if((remember_tiny_text == i) && (mode == 0))
return;
else {
put_text_bar(univ.out->rect_names[i]);
remember_tiny_text = i;
return;
}
} // TODO: I'm pretty sure this brace location is correct, but must verify it
if(remember_tiny_text != 50 + univ.party.i_w_c.x + univ.party.i_w_c.y) {
put_text_bar(univ.out->rect_names[i]);
in_area = true;
}
if(!in_area) {
put_text_bar(univ.out->out_name);
remember_tiny_text = 50 + univ.party.i_w_c.x + univ.party.i_w_c.y;
}
}
if(is_town()) {
for(i = 0; i < 16; i++)
if(loc.in(univ.town->room_rect(i))) {
if((remember_tiny_text == 200 + i) && (mode == 0))
return;
else {
put_text_bar(univ.town->rect_names[i]);
remember_tiny_text = 200 + i;
return;
}
} // TODO: I'm pretty sure this brace location is correct, but must verify it
if(remember_tiny_text != 250) {
put_text_bar(univ.town->rect_names[i]);
in_area = true;
}
if(!in_area) {
put_text_bar(univ.town->town_name);
remember_tiny_text = 250;
}
}
if((is_combat()) && (current_pc < 6) && !monsters_going) {
std::ostringstream sout;
sout << univ.party[current_pc].name << " (ap: " << univ.party[current_pc].ap << ')';
combat_string = sout.str();
put_text_bar((char *) combat_string.c_str());
remember_tiny_text = 500;
put_text_bar(sout.str());
}
if((is_combat()) && (monsters_going)) // Print bar for 1st monster with >0 ap -
// that is monster that is going
if((is_combat()) && (monsters_going))
// Print bar for 1st monster with >0 ap - that is monster that is going
for(i = 0; i < univ.town->max_monst(); i++)
if((univ.town.monst[i].active > 0) && (univ.town.monst[i].ap > 0)) {
combat_string = print_monster_going(univ.town.monst[i].number,univ.town.monst[i].ap);
put_text_bar((char *) combat_string.c_str());
remember_tiny_text = 500;
put_text_bar(print_monster_going(univ.town.monst[i].number,univ.town.monst[i].ap));
i = 400;
}
text_bar_gworld.display();
}
void put_text_bar(std::string str) {
@@ -744,22 +713,24 @@ void put_text_bar(std::string str) {
win_draw_string(text_bar_gworld, to_rect, str, eTextMode::LEFT_TOP, style);
if(!monsters_going) {
to_rect.left = 205;
to_rect.left = to_rect.right - 15;
to_rect.width() = 12;
to_rect.height() = 12;
if(univ.party.status[ePartyStatus::STEALTH] > 0) {
win_draw_string(text_bar_gworld, to_rect, "Stealth", eTextMode::LEFT_TOP, style);
to_rect.left -= 60;
rect_draw_some_item(status_gworld, get_stat_effect_rect(25), text_bar_gworld, to_rect, sf::BlendAlpha);
to_rect.offset(-15, 0);
}
if(univ.party.status[ePartyStatus::FLIGHT] > 0) {
win_draw_string(text_bar_gworld, to_rect, "Flying", eTextMode::LEFT_TOP, style);
to_rect.left -= 60;
rect_draw_some_item(status_gworld, get_stat_effect_rect(23), text_bar_gworld, to_rect, sf::BlendAlpha);
to_rect.offset(-15, 0);
}
if(univ.party.status[ePartyStatus::DETECT_LIFE] > 0) {
win_draw_string(text_bar_gworld, to_rect, "Detect Life", eTextMode::LEFT_TOP, style);
to_rect.left -= 60;
rect_draw_some_item(status_gworld, get_stat_effect_rect(24), text_bar_gworld, to_rect, sf::BlendAlpha);
to_rect.offset(-15, 0);
}
if(univ.party.status[ePartyStatus::FIREWALK] > 0) {
win_draw_string(text_bar_gworld, to_rect, "Firewalk", eTextMode::LEFT_TOP, style);
to_rect.left -= 60;
rect_draw_some_item(status_gworld, get_stat_effect_rect(26), text_bar_gworld, to_rect, sf::BlendAlpha);
to_rect.offset(-15, 0);
}
}
@@ -1025,7 +996,7 @@ void draw_terrain(short mode) {
if(mode == 0) {
redraw_terrain();
draw_text_bar(0);
draw_text_bar();
if((overall_mode >= MODE_COMBAT) && (overall_mode != MODE_LOOK_OUTDOORS) && (overall_mode != MODE_LOOK_TOWN) && (overall_mode != MODE_RESTING))
draw_pcs(center,1);
if(overall_mode == MODE_FANCY_TARGET)

View File

@@ -36,8 +36,7 @@ void load_main_screen();
void redraw_screen(int refresh);
void put_background();
void draw_buttons(short mode);
void reset_text_bar();
void draw_text_bar(short mode);
void draw_text_bar();
void refresh_text_bar();
void put_text_bar(std::string str);
void draw_terrain(short mode = 0);

View File

@@ -71,6 +71,16 @@ extern location golem_m_locs[16];
extern cUniverse univ;
extern sf::Texture pc_gworld;
// First icon is displayed for positive values, second for negative, if -1 no negative icon.
// This omits two special cases - major poison, and normal speed; they are hard-coded.
std::map<eStatus, std::pair<short, short>> statIcons = {
{eStatus::POISONED_WEAPON, {4,-1}}, {eStatus::BLESS_CURSE, {2,3}}, {eStatus::POISON, {0,-1}},
{eStatus::HASTE_SLOW, {6,8}}, {eStatus::INVULNERABLE, {5,-1}}, {eStatus::MAGIC_RESISTANCE, {9,19}},
{eStatus::WEBS, {10,-1}}, {eStatus::DISEASE, {11,-1}}, {eStatus::INVISIBLE, {12,-1}},
{eStatus::DUMB, {13,18}}, {eStatus::MARTYRS_SHIELD, {14,-1}}, {eStatus::ASLEEP, {15,21}},
{eStatus::PARALYZED, {16,-1}}, {eStatus::ACID, {17,-1}}, {eStatus::FORCECAGE, {20,-1}},
};
// Variables for spell selection
short on_which_spell_page = 0;
short store_last_cast_mage = 6,store_last_cast_priest = 6;
@@ -1843,17 +1853,7 @@ static void draw_spell_info(cDialog& me, const eSkill store_situation, const sho
}
}
// TODO: Use the map here to simplify drawing the graphics in draw_pc_effects()
static void put_target_status_graphics(cDialog& me, short for_pc) {
// First icon is displayed for positive values, second for negative, if -1 no negative icon.
// This omits two special cases - major poison, and normal speed; they are hard-coded.
static std::map<eStatus, std::pair<short, short>> statIcons = {
{eStatus::POISONED_WEAPON, {4,-1}}, {eStatus::BLESS_CURSE, {2,3}}, {eStatus::POISON, {0,-1}},
{eStatus::HASTE_SLOW, {6,8}}, {eStatus::INVULNERABLE, {5,-1}}, {eStatus::MAGIC_RESISTANCE, {9,19}},
{eStatus::WEBS, {10,-1}}, {eStatus::DISEASE, {11,-1}}, {eStatus::INVISIBLE, {12,-1}},
{eStatus::DUMB, {13,18}}, {eStatus::MARTYRS_SHIELD, {14,-1}}, {eStatus::ASLEEP, {15,-1}},
{eStatus::PARALYZED, {16,-1}}, {eStatus::ACID, {17,-1}}, {eStatus::FORCECAGE, {20,-1}},
};
bool isAlive = univ.party[for_pc].main_status == eMainStatus::ALIVE;
univ.party[for_pc].status[eStatus::HASTE_SLOW]; // This just makes sure it exists in the map, without changing its value if it does
std::string id = "pc" + std::to_string(for_pc + 1);

View File

@@ -79,6 +79,7 @@ extern short combat_posing_monster, current_working_monster; // 0-5 PC 100 + x -
extern bool supressing_some_spaces;
extern location ok_space[4];
extern sf::Texture bg_gworld;
extern std::map<eStatus, std::pair<short, short>> statIcons;
// Draws the pc area in upper right
void put_pc_screen() {
@@ -563,24 +564,13 @@ short total_encumberance(short pc_num) {
return store;
}
static rectangle get_stat_effect_rect(eStatus which_effect) {
int code = (int) which_effect;
rectangle get_stat_effect_rect(int code) {
rectangle base = {0,0,12,12};
base.offset(12 * (code % 3), 12 * (code / 3));
return base;
}
void draw_pc_effects(short pc) {
// TODO: Calculate these rects from scratch instead of hard-coding them. (use above function)
// TODO: The duplication of rectangle here shouldn't be necessary...
rectangle source_rects[18] = {
rectangle{00,0,12,12},rectangle{00,12,12,24},rectangle{00,24,12,36},
rectangle{12,0,24,12},rectangle{12,12,24,24},rectangle{12,24,24,36},
rectangle{24,0,36,12},rectangle{24,12,36,24},rectangle{24,24,36,36},
rectangle{36,0,47,12},rectangle{36,12,47,24},rectangle{36,24,47,36},
rectangle{47,0,60,12},rectangle{47,12,60,24},rectangle{47,24,60,36},
rectangle{60,0,72,12},rectangle{60,12,72,24},rectangle{60,24,72,36}
};
rectangle dest_rect = {18,15,30,27},dlog_dest_rect = {66,354,78,366};
short right_limit = 250;
short name_width;
@@ -595,90 +585,19 @@ void draw_pc_effects(short pc) {
if(exceptSplit(univ.party[pc].main_status) != eMainStatus::ALIVE)
return;
// TODO: This used to draw the status icons in the spell dialog, but it no longer does. Fix that.
if((univ.party[pc].status[eStatus::POISONED_WEAPON] > 0) && (dest_rect.right < right_limit)) {
rect_draw_some_item(status_gworld,source_rects[4],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if(univ.party[pc].status[eStatus::BLESS_CURSE] > 0) {
rect_draw_some_item(status_gworld,source_rects[2],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
else if(univ.party[pc].status[eStatus::BLESS_CURSE] < 0) {
rect_draw_some_item(status_gworld,source_rects[3],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if(univ.party[pc].status[eStatus::POISON] > 0) {
rect_draw_some_item(status_gworld,source_rects[(univ.party[pc].status[eStatus::POISON] > 4) ? 1 : 0],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if(univ.party[pc].status[eStatus::INVULNERABLE] > 0) {
rect_draw_some_item(status_gworld,source_rects[5],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if(univ.party[pc].status[eStatus::HASTE_SLOW] > 0) {
rect_draw_some_item(status_gworld,source_rects[6],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
else if(univ.party[pc].status[eStatus::HASTE_SLOW] < 0) {
rect_draw_some_item(status_gworld,source_rects[8],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}else{
rect_draw_some_item(status_gworld,source_rects[7],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::MAGIC_RESISTANCE] > 0) && (dest_rect.right < right_limit)) {
rect_draw_some_item(status_gworld,source_rects[9],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::WEBS] > 0) && (dest_rect.right < right_limit)) {
rect_draw_some_item(status_gworld,source_rects[10],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::DISEASE] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[11],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::INVISIBLE] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[12],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::DUMB] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[13],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::MARTYRS_SHIELD] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[14],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::ASLEEP] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[15],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::PARALYZED] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[16],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
}
if((univ.party[pc].status[eStatus::ACID] > 0) && (dest_rect.right < right_limit)){
rect_draw_some_item(status_gworld,source_rects[17],pc_stats_gworld,dest_rect,sf::BlendAlpha);
dest_rect.left += 13;
dest_rect.right += 13;
univ.party[pc].status[eStatus::HASTE_SLOW]; // This just makes sure it exists in the map, without changing its value if it does
for(auto next : univ.party[pc].status) {
short placedIcon = -1;
if(next.first == eStatus::POISON && next.second > 4) placedIcon = 1;
else if(next.second > 0) placedIcon = statIcons[next.first].first;
else if(next.second < 0) placedIcon = statIcons[next.first].second;
else if(next.first == eStatus::HASTE_SLOW) placedIcon = 7;
if(placedIcon >= 0) {
rect_draw_some_item(status_gworld, get_stat_effect_rect(placedIcon), pc_stats_gworld, dest_rect, sf::BlendAlpha);
dest_rect.offset(13, 0);
}
if(dest_rect.right >= right_limit) break;
}
}
@@ -947,7 +866,8 @@ void damaged_message(short damage,eMonstMelee type) {
// This prepares the monster's string for the text bar
std::string print_monster_going(mon_num_t m_num,short ap) {
std::ostringstream sout(get_m_name(m_num));
std::ostringstream sout;
sout << get_m_name(m_num);
sout << " (ap: " << ap << ')';
return sout.str();
}
@@ -1210,6 +1130,7 @@ void add_string_to_buf(std::string str, unsigned short indent) {
if(str.find_last_not_of(' ') == std::string::npos)
return;
// TODO: Base this on pixel length instead of character length
if(indent && str.find_last_not_of(' ') > 48) {
if(indent > 20) indent = 20;
size_t split = str.find_last_of(' ', 49);

View File

@@ -41,4 +41,5 @@ void make_cursor_sword() ;
short calc_day();
bool day_reached(unsigned short which_day, unsigned short which_event);
void Draw_Some_Item (sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld, location target, char masked, short main_win);
rectangle get_stat_effect_rect(int which_effect);