recoloring of units to team colors

This commit is contained in:
John W. C. McNabb 2005-11-12 20:44:09 +00:00
parent 729b22a62c
commit 7d8962dda0
18 changed files with 335 additions and 63 deletions

View file

@ -4,6 +4,7 @@ name= _ "Orcish Sovereign"
race=orc
image="orcish-sovereign.png"
image_defensive="orcish-sovereign-defend.png"
flag_rgb=77,2,2,104,3,3,109,2,2,130,2,13,130,13,2,137,12,12,132,9,6
#profile=misc/kapoue.png
hitpoints=75
ability=leadership

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -676,7 +676,7 @@ void unit_preview_pane::draw_contents()
SDL_Rect clip_area = area;
const clip_rect_setter clipper(screen,clip_area);
surface unit_image(image::get_image(u.type().image(),image::UNSCALED));
surface unit_image(image::get_image(u.image_loc(),image::UNSCALED));
if(left_side() == false && unit_image != NULL) {
unit_image.assign(image::reverse_image(unit_image));
}

View file

@ -921,7 +921,6 @@ void display::draw_report(reports::TYPE report_num)
SDL_BlitSurface(surf,NULL,screen_.getSurface(),&rect);
update_rect(rect);
}
//if the rectangle has just changed, assign the surface to it
if(new_rect != rect || surf == NULL) {
surf.assign(NULL);
@ -945,6 +944,7 @@ void display::draw_report(reports::TYPE report_num)
SDL_Rect area = rect;
int x = rect.x, y = rect.y;
if(!report.empty()) {
// Add prefix, postfix elements. Make sure that they get the same tooltip as the guys
// around them.
@ -963,6 +963,7 @@ void display::draw_report(reports::TYPE report_num)
bool used_ellipsis=false;
std::stringstream ellipsis_tooltip;
SDL_Rect ellipsis_area =rect;
for(reports::report::iterator i = report.begin(); i != report.end(); ++i) {
if(i->text.empty() == false){
if(used_ellipsis == false) {
@ -977,7 +978,7 @@ void display::draw_report(reports::TYPE report_num)
x += area.w;
}
}
} else if(i->image.empty() == false){
} else if(i->image.get_filename().empty() == false){
if(used_ellipsis == false) {
// Draw an image element
surface img(image::get_image(i->image,image::UNSCALED));
@ -987,7 +988,7 @@ void display::draw_report(reports::TYPE report_num)
}
if(img == NULL) {
ERR_DP << "could not find image for report: '" << i->image << "'\n";
ERR_DP << "could not find image for report: '" << i->image.get_filename() << "'\n";
continue;
}
@ -1057,7 +1058,7 @@ void display::draw_minimap(int x, int y, int w, int h)
continue;
const int side = u->second.side();
const SDL_Color& col = team::get_side_colour(side);
const SDL_Color col = team::get_side_colour(side);
const Uint32 mapped_col = SDL_MapRGB(video().getSurface()->format,col.r,col.g,col.b);
SDL_Rect rect = { x + (u->first.x * w) / map_w,
y + (u->first.y * h + (is_odd(u->first.x) ? h / 2 : 0)) / map_h,
@ -1144,7 +1145,7 @@ void display::draw_unit_on_tile(int x, int y, surface unit_image_override,
if(loc != hiddenUnit_ || !hideEnergy_) {
if(unit_image == NULL) {
unit_image.assign(image::get_image(it->second.image(),it->second.stone() ? image::GREYED : image::SCALED));
unit_image.assign(image::get_image(u.image_loc(),it->second.stone() ? image::GREYED : image::SCALED));
}
if(unit_image == NULL) {
@ -1260,11 +1261,17 @@ void display::draw_unit_on_tile(int x, int y, surface unit_image_override,
if(preferences::show_side_colours()) {
const char* const selected = selectedHex_ == loc ? "selected-" : "";
std::vector<Uint32> temp_rgb;
//ellipse not pure red=255!
for(int i=0;i<256;i++){
temp_rgb.push_back((Uint32)(i<<16));
}
//selected ellipse not pure red at all!
char buf[50];
snprintf(buf,sizeof(buf),"misc/%sellipse-%d-top.png",selected,team::get_side_colour_index(it->second.side()));
ellipse_back.assign(image::get_image(buf));
snprintf(buf,sizeof(buf),"misc/%sellipse-%d-bottom.png",selected,team::get_side_colour_index(it->second.side()));
ellipse_front.assign(image::get_image(buf));
snprintf(buf,sizeof(buf),"misc/%sellipse-1-top.png",selected);
ellipse_back.assign(image::get_image(image::locator(buf,it->second.team_rgb(),temp_rgb)));
snprintf(buf,sizeof(buf),"misc/%sellipse-1-bottom.png",selected);
ellipse_front.assign(image::get_image(image::locator(buf,it->second.team_rgb(),temp_rgb)));
}
draw_unit(xpos,ypos - height_adjust,unit_image,false,
@ -1273,7 +1280,11 @@ void display::draw_unit_on_tile(int x, int y, surface unit_image_override,
const fixed_t bar_alpha = highlight_ratio < ftofxp(1.0) && blend_with == 0 ? highlight_ratio : ftofxp(1.0);
if(energy_file != NULL) {
draw_bar(*energy_file,xpos,ypos,(u.max_hitpoints()*2)/3,unit_energy,energy_colour,bar_alpha);
if(u.max_hitpoints()!= u.hitpoints()){
draw_bar(*energy_file,xpos,ypos,(u.max_hitpoints()*2)/3,unit_energy,energy_colour,bar_alpha);
}else{
draw_bar(*energy_file,xpos,ypos,0,unit_energy,energy_colour,bar_alpha);
}
}
if(u.experience() > 0 && u.can_advance()) {

View file

@ -139,8 +139,20 @@ locator::locator(const std::string &filename) :
init_index();
}
locator::locator(const std::string &filename, const gamemap::location &loc) :
val_(filename, loc)
locator::locator(const char *filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
val_(filename, new_rgb, swap_rgb)
{
init_index();
}
locator::locator(const std::string &filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
val_(filename, new_rgb, swap_rgb)
{
init_index();
}
locator::locator(const std::string &filename, const gamemap::location &loc, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
val_(filename, loc, new_rgb, swap_rgb)
{
init_index();
}
@ -154,7 +166,8 @@ locator& locator::operator=(const locator &a)
}
locator::value::value(const locator::value& a) :
type_(a.type_), filename_(a.filename_), loc_(a.loc_)
type_(a.type_), filename_(a.filename_), loc_(a.loc_),
new_color(a.new_color), swap_colors(a.swap_colors)
{
}
@ -163,17 +176,28 @@ locator::value::value() :
{}
locator::value::value(const char *filename) :
type_(FILE), filename_(filename)
type_(FILE), filename_(filename)
{
}
locator::value::value(const char *filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
type_(SUB_FILE), filename_(filename), new_color(new_rgb), swap_colors(swap_rgb)
{
}
locator::value::value(const std::string& filename) :
type_(FILE), filename_(filename)
type_(FILE), filename_(filename)
{
}
locator::value::value(const std::string& filename, const gamemap::location& loc) :
type_(SUB_FILE), filename_(filename), loc_(loc)
locator::value::value(const std::string& filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
type_(SUB_FILE), filename_(filename), new_color(new_rgb), swap_colors(swap_rgb)
{
}
locator::value::value(const std::string& filename, const gamemap::location& loc, Uint32 new_rgb, std::vector<Uint32> swap_rgb) :
type_(SUB_FILE), filename_(filename), loc_(loc), new_color(new_rgb), swap_colors(swap_rgb)
{
}
@ -184,7 +208,7 @@ bool locator::value::operator==(const value& a) const
} else if(type_ == FILE) {
return filename_ == a.filename_;
} else if(type_ == SUB_FILE) {
return filename_ == a.filename_ && loc_ == a.loc_;
return filename_ == a.filename_ && loc_ == a.loc_ && new_color==a.new_color; //note not checking swap_colors purposely
} else {
return false;
}
@ -199,8 +223,9 @@ bool locator::value::operator<(const value& a) const
} else if(type_ == SUB_FILE) {
if(filename_ != a.filename_)
return filename_ < a.filename_;
return loc_ < a.loc_;
if(loc_ != a.loc_)
return loc_ < a.loc_;
return new_color < a.new_color;
} else {
return false;
}
@ -240,15 +265,20 @@ surface locator::load_image_sub_file() const
if(mask == NULL)
return surface(NULL);
SDL_Rect srcrect = {
((tile_size*3) / 4) * val_.loc_.x,
tile_size * val_.loc_.y + (tile_size/2) * (val_.loc_.x % 2),
tile_size, tile_size
};
surface tmp(cut_surface(mother_surface, srcrect));
surface surf(mask_surface(tmp, mask));
surface surf=mother_surface;
if(val_.loc_.x>-1 && val_.loc_.y>-1){
SDL_Rect srcrect = {
((tile_size*3) / 4) * val_.loc_.x,
tile_size * val_.loc_.y + (tile_size/2) * (val_.loc_.x % 2),
tile_size, tile_size
};
surface tmp(cut_surface(mother_surface, srcrect));
surf=mask_surface(tmp, mask);
}
if(val_.swap_colors.size()){
surf=recolor_image(surf,get_new_color(),get_swap_colors());
}
return surf;
}
@ -610,7 +640,7 @@ locator get_alternative(const image::locator &i_locator, const std::string &alt)
res = locator(alternative);
break;
case locator::SUB_FILE:
res = locator(alternative, i_locator.get_loc());
res = locator(alternative, i_locator.get_loc(), i_locator.get_new_color(), i_locator.get_swap_colors());
break;
default:
wassert(false);

View file

@ -54,8 +54,10 @@ namespace image {
value();
value(const value &a);
value(const char *filename);
value(const char *filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb);
value(const std::string& filename);
value(const std::string& filename, const gamemap::location& loc);
value(const std::string& filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb);;
value(const std::string& filename, const gamemap::location& loc, Uint32 new_rgb, std::vector<Uint32> swap_rgb);
bool operator==(const value& a) const;
bool operator<(const value& a) const;
@ -63,17 +65,21 @@ namespace image {
type type_;
std::string filename_;
gamemap::location loc_;
Uint32 new_color;
std::vector<Uint32> swap_colors;
};
// Constructing locators is somewhat slow, accessing image
// through locators is fast. The idea is that calling functions
// should store locators, and not strings to construct locators
// (the second will work, of course, but will be slower)
locator();
locator();
locator(const locator &a);
locator(const char *filename);
locator(const char *filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb);
locator(const std::string& filename);
locator(const std::string& filename, const gamemap::location& loc);
locator(const std::string& filename, Uint32 new_rgb, std::vector<Uint32> swap_rgb);
locator(const std::string& filename, const gamemap::location& loc, Uint32 new_rgb=0, std::vector<Uint32> swap_rgb= std::vector<Uint32>());
locator& operator=(const locator &a);
bool operator==(const locator &a) const { return index_ == a.index_; }
@ -82,6 +88,8 @@ namespace image {
const std::string &get_filename() const { return val_.filename_; }
const gamemap::location& get_loc() const { return val_.loc_ ; }
const Uint32& get_new_color() const { return val_.new_color ; }
const std::vector<Uint32>& get_swap_colors() const { return val_.swap_colors ; }
const type get_type() const { return val_.type_; };
// const int get_index() const { return index_; };

View file

@ -110,7 +110,7 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
case UNIT_DESCRIPTION:
return report(u->second.description());
case UNIT_TYPE:
return report(u->second.type().language_name(),"",u->second.unit_description());
return report(u->second.type().language_name(),"",u->second.unit_description());
case UNIT_LEVEL:
str << u->second.type().level();
break;
@ -276,7 +276,7 @@ Units cannot be killed by poison alone. The poison will not reduce it below 1 HP
return res;
}
case UNIT_IMAGE:
return report("",u->second.type().image(),"");
return report("",u->second.image_loc(),"");
case UNIT_PROFILE:
return report("",u->second.type().image_profile(),"");
case TIME_OF_DAY: {

View file

@ -48,7 +48,7 @@ namespace reports {
// Invariant: either text or image should be empty
// It would be okay to create a class for this, but it's a pretty simple
// invariant so I left it like the original report class.
std::string image;
image::locator image;
std::string text;
std::string tooltip;
@ -58,6 +58,11 @@ namespace reports {
element(const std::string& text, const std::string& image, const std::string& tooltip) :
image(image), text(text), tooltip(tooltip) {}
element(const std::string& text, const image::locator& image, const std::string& tooltip) :
image(image), text(text), tooltip(tooltip) {}
element(const std::string& text, const char* image, const std::string& tooltip) :
image(image), text(text), tooltip(tooltip) {}
bool operator==(const element& o) const {
return o.text == text && o.image == image && o.tooltip == tooltip;
}
@ -69,6 +74,12 @@ namespace reports {
report(const std::string& text, const std::string& image, const std::string& tooltip) {
this->push_back(element(text, image, tooltip));
}
report(const std::string& text, const char* image, const std::string& tooltip) {
this->push_back(element(text, image, tooltip));
}
report(const std::string& text, const image::locator& image, const std::string& tooltip) {
this->push_back(element(text, image, tooltip));
}
// Convenience functions
void add_text(std::stringstream& text, std::stringstream& tooltip);

View file

@ -318,6 +318,107 @@ surface greyscale_image(surface const &surf)
return create_optimized_surface(nsurf);
}
surface recolor_image(surface surf, Uint32 new_rgb, std::vector<Uint32> old_rgb)
{
// function to replace vectors of colors with new color (at equal greyscale)
// parallel input vectors chosen to prevent need to include SDL structures
// elsewhere in code or create new rgb structure. It might be better to
// just pass a vector of SDL colors instead...
Uint16 new_red =(new_rgb & 0x00FF0000)>>16;
Uint16 new_green=(new_rgb & 0x0000FF00)>>8;
Uint16 new_blue =(new_rgb & 0x000000FF);
if(surf == NULL)
return NULL;
surface nsurf(make_neutral_surface(surf));
if(nsurf == NULL) {
std::cerr << "failed to make neutral surface\n";
return NULL;
}
Uint16 old_avg=0;
const Uint16 new_grey = (Uint16)((77*(Uint16) new_red +
150*(Uint16)new_green +
29*(Uint16)new_blue) / 256);
const Uint16 new_avg = (Uint16)(((Uint16) new_red +
(Uint16) new_green +
(Uint16) new_blue) / 3);
for(std::vector<Uint32>::const_iterator temp_rgb = old_rgb.begin();
temp_rgb!=old_rgb.end();temp_rgb++)
{
//calculate brightest old color average
int old_r=((*temp_rgb) & 0X00FF0000)>>16;
int old_g=((*temp_rgb) & 0X0000FF00)>>8;
int old_b=((*temp_rgb) & 0X000000FF);
//const Uint8 avg = (red+green+blue)/3;
//use the correct formula for RGB to grayscale
//conversion. ok, this is no big deal :)
//the correct formula being:
//gray=0.299red+0.587green+0.114blue
//get grey level of old color
// const Uint16 old_grey = (Uint16)((77*(Uint16) old_r +
// 150*(Uint16)old_g +
// 29*(Uint16)old_b) / 256);
//strict average gives better looking results than grey
const Uint16 old_grey = (Uint16)(((Uint16) old_r +
(Uint16)old_g +
(Uint16)old_b) / 3);
if (old_grey>old_avg){
old_avg = old_grey;
}
}
for(std::vector<Uint32>::const_iterator temp_rgb = old_rgb.begin();
temp_rgb!=old_rgb.end();temp_rgb++)
{
int old_r=((*temp_rgb) & 0X00FF0000)>>16;
int old_g=((*temp_rgb) & 0X0000FF00)>>8;
int old_b=((*temp_rgb) & 0X000000FF);
// std::cout<<"recolor:"<<old_r<<","<<old_g<<","<<old_b<<"\n";
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + nsurf->w*surf->h;
//const Uint16 old_grey = (Uint16)((77*(Uint16) old_r +
// 150*(Uint16)old_g +
// 29*(Uint16)old_b) / 256);
const Uint16 old_grey = (Uint16)(((Uint16) old_r +
(Uint16)old_g +
(Uint16)old_b) / 3);
//calculate new color
Uint8 new_r, new_g, new_b;
// std::cout<<"recolor new vs old:"<<new_avg <<","<< old_avg<<"\n";
// std::cout<<"recolor new:"<<new_red<<"\n";
if(0 != new_avg){
new_r=(Uint8)( old_grey * new_red / old_avg );
new_g=(Uint8)( old_grey * new_green / old_avg );
new_b=(Uint8)( old_grey * new_blue / old_avg );
}else{//new color is black, so use grey scale
new_r=old_avg;
new_g=old_avg;
new_b=old_avg;
}
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
if(red==old_r && green==old_g && blue==old_b){
*beg = SDL_MapRGBA(nsurf->format,new_r,new_g,new_b,alpha);
}
++beg;
}
}
return create_optimized_surface(nsurf);
}
surface brighten_image(surface const &surf, fixed_t amount)
{
if(surf == NULL) {

View file

@ -21,6 +21,7 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
//older versions of SDL don't define the
//mouse wheel macros, so define them ourselves
@ -104,6 +105,8 @@ surface scale_surface(surface const &surf, int w, int h);
surface scale_surface_blended(surface const &surf, int w, int h);
surface adjust_surface_colour(surface const &surf, int r, int g, int b);
surface greyscale_image(surface const &surf);
surface recolor_image(surface surf, Uint32 new_rgb, std::vector<Uint32> old_rgb);
surface brighten_image(surface const &surf, fixed_t amount);
surface get_surface_portion(surface const &surf, SDL_Rect &rect);
surface adjust_surface_alpha(surface const &surf, fixed_t amount);

View file

@ -859,21 +859,20 @@ bool team::shroud_map::copy_from(const std::vector<const shroud_map*>& maps)
return cleared;
}
const SDL_Color& team::get_side_colour(int side)
{
size_t index = size_t(get_side_colour_index(side) - 1);
const Uint32 team::get_side_rgb(int side){
size_t index = size_t(get_side_colour_index(side) - 1);
static const SDL_Color sides[] = { {0xFF,0x00,0x00,0},
{0x00,0x00,0xFF,0},
{0x00,0xFF,0x00,0},
{0xFF,0xFF,0x00,0},
{0xFF,0x00,0xFF,0},
{0xFF,0x7F,0x00,0},
{0x89,0x89,0x89,0},
{0xFF,0xFF,0xFF,0},
{0x94,0x50,0x27,0},
{0x02,0xF5,0xE1,0},
{0xFF,0x00,0xFF,0} };
static const Uint32 sides[] = { 0x00FF0000,
0x000000FF,
0x0000FF00,
0x00FFFF00,
0x00FF00FF,
0x00FF7F00,
0x00898989,
0x00FFFFFF,
0x00945027,
0x0002F5E1,
0x00FF00FF };
static const size_t nsides = sizeof(sides)/sizeof(*sides);
@ -881,7 +880,17 @@ const SDL_Color& team::get_side_colour(int side)
return sides[index];
} else {
return sides[0];
}
}
}
const SDL_Color team::get_side_colour(int side)
{
Uint32 rgb=get_side_rgb(side);
SDL_Color color={ (0x00FF0000 & rgb)>>16,
(0x0000FF00 & rgb)>>8,
(0x000000FF & rgb),
0} ;
return color;
}
int team::get_side_colour_index(int side)

View file

@ -199,7 +199,8 @@ public:
static int nteams();
//function which, when given a 1-based side will return the colour used by that side.
static const SDL_Color& get_side_colour(int side);
static const Uint32 get_side_rgb(int side);
static const SDL_Color get_side_colour(int side);
static int get_side_colour_index(int side);
void log_recruitable();
@ -243,7 +244,7 @@ struct teams_manager {
bool is_observer();
//function which will validate a side. Throws game::game_error
//function which will validate a side. Trows game::game_error
//if the side is invalid
void validate_side(int side); //throw game::game_error

View file

@ -217,6 +217,11 @@ int unit::side() const
return side_;
}
Uint32 unit::team_rgb() const
{
return(team::get_side_rgb(side()));
}
unit_race::GENDER unit::gender() const
{
return gender_;
@ -909,6 +914,15 @@ const std::string& unit::image() const
}
}
const image::locator unit::image_loc() const
{
if(type().flag_rgb().size()){
return(image::locator(image(),team_rgb(),type().flag_rgb()));
}else{
return(image::locator(image()));
}
}
const unit_animation* unit::get_animation() const
{
switch(state_) {

View file

@ -18,6 +18,7 @@
#include "race.hpp"
#include "team.hpp"
#include "unit_types.hpp"
#include "image.hpp"
#include <set>
#include <string>
@ -55,6 +56,7 @@ public:
bool unrenamable() const; /** < Set to true for some scenario-specific units which should not be renamed */
bool advances() const;
int side() const;
Uint32 team_rgb() const;
unit_race::GENDER gender() const;
void set_side(int new_side);
fixed_t alpha() const;
@ -128,6 +130,7 @@ public:
//gets the unit image that should currently be displayed
//(could be in the middle of an attack etc)
const std::string& image() const;
const image::locator image_loc() const;
void set_standing();
void set_defending(bool hits, attack_type::RANGE range, int start_frame, int acceleration);

View file

@ -111,10 +111,14 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
adjust_map_position(disp, xsrc, ysrc, disp.hex_size(), disp.hex_size());
while(animation_time < 0) {
const std::string* unit_image = &teleport_animation.get_current_frame(unit_animation::UNIT_FRAME).image;
image::locator unit_loc;
if (unit_image->empty()) {
unit_image = &u.type().image();
unit_loc = u.image_loc();
}else{
unit_loc = image::locator(*unit_image,u.team_rgb(),u.type().flag_rgb());
}
surface image(image::get_image(*unit_image));
surface image(image::get_image(unit_loc));
if (!face_left) {
image.assign(image::reverse_image(image));
}
@ -133,7 +137,7 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
for(int i = 0; i < nsteps; ++i) {
events::pump();
surface image(image::get_image(u.type().image_moving()));
surface image(image::get_image( image::locator(u.type().image_moving(),u.team_rgb(),u.type().flag_rgb()) ));
if(!face_left) {
image.assign(image::reverse_image(image));
}
@ -206,10 +210,15 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
adjust_map_position(disp, xdst, ydst, disp.hex_size(), disp.hex_size());
while(animation_time < end_at) {
const std::string* unit_image = &teleport_animation.get_current_frame(unit_animation::UNIT_FRAME).image;
image::locator unit_loc;
if (unit_image->empty()) {
unit_image = &u.type().image();
unit_loc = u.image_loc();
}else{
unit_loc = image::locator(*unit_image,u.team_rgb(),u.type().flag_rgb());
}
surface image(image::get_image(*unit_image));
surface image(image::get_image(unit_loc));
if (!face_left) {
image.assign(image::reverse_image(image));
}
@ -305,7 +314,7 @@ void unit_die(display& disp, const gamemap::location& loc, const unit& u, const
const unit_animation::frame& frame = anim.get_current_frame();
const surface surf(image::get_image(frame.image));
const surface surf(image::get_image(image::locator(frame.image,u.team_rgb(), u.type().flag_rgb())));
if(surf.get() != NULL) {
unit_image = surf;
}
@ -469,7 +478,8 @@ bool unit_attack_ranged(display& disp, unit_map& units,
}
if(!hide) {
const surface image((unit_image == NULL) ? surface(NULL) : image::get_image(*unit_image));
const surface image((unit_image == NULL) ? surface(NULL) : image::get_image(image::locator(*unit_image,att->second.team_rgb(),att->second.type().flag_rgb())));
disp.draw_tile(a.x,a.y,image);
}
@ -540,7 +550,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
missile_image = &default_diag_missile;
}
surface img(image::get_image(*missile_image));
surface img(image::get_image(image::locator(*missile_image)));
if(hflip) {
img.assign(image::reverse_image(img));
@ -803,7 +813,10 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
const unit_animation::frame& unit_frame = attack_anim.get_current_frame(unit_animation::UNIT_FRAME);
int new_halo_x = unit_frame.halo_x;
int new_halo_y = unit_frame.halo_y;
const std::string& unit_image = unit_frame.image.empty() ? attacker.image() : unit_frame.image;
const std::string& unit_image_name = unit_frame.image.empty() ? attacker.image() : unit_frame.image;
image::locator unit_image(unit_image_name,attacker.team_rgb(),attacker.type().flag_rgb());
if(!attacker.facing_left()) {
xoffset *= -1;

View file

@ -524,7 +524,8 @@ unit_type::unit_type(const unit_type& o)
alignment_(o.alignment_),
movementType_(o.movementType_), possibleTraits_(o.possibleTraits_),
genders_(o.genders_), defensive_animations_(o.defensive_animations_),
teleport_animations_(o.teleport_animations_), death_animations_(o.death_animations_)
teleport_animations_(o.teleport_animations_),
death_animations_(o.death_animations_), flag_rgb_(o.flag_rgb_)
{
gender_types_[0] = o.gender_types_[0] != NULL ? new unit_type(*o.gender_types_[0]) : NULL;
gender_types_[1] = o.gender_types_[1] != NULL ? new unit_type(*o.gender_types_[1]) : NULL;
@ -660,6 +661,61 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
for(config::child_list::const_iterator death = deaths.begin(); death != deaths.end(); ++death) {
death_animations_.push_back(death_animation(**death));
}
std::vector<unsigned char> flag_red_,flag_green_,flag_blue_;
std::vector<std::string> flag_string_ = utils::split(cfg["flag_red"]);
for(std::vector<std::string>::iterator c=flag_string_.begin();c!=flag_string_.end();c++){
flag_red_.push_back(atoi(c->c_str()));
}
flag_string_ = utils::split(cfg["flag_green"]);
for(std::vector<std::string>::iterator c=flag_string_.begin();c!=flag_string_.end();c++){
flag_green_.push_back(atoi(c->c_str()));
}
flag_string_ = utils::split(cfg["flag_blue"]);
for(std::vector<std::string>::iterator c=flag_string_.begin();c!=flag_string_.end();c++){
flag_blue_.push_back(atoi(c->c_str()));
}
//fill in empty rgb values with 0
while(flag_red_.size()>flag_green_.size()){
flag_green_.push_back(0);
}//size of green now >=red
while(flag_green_.size()>flag_blue_.size()){
flag_blue_.push_back(0);
}//size of blue now >= green >= red
while(flag_blue_.size()>flag_green_.size()){
flag_green_.push_back(0);
}//size of green now = blue >= red
while(flag_green_.size()>flag_red_.size()){
flag_red_.push_back(0);
}//size of green=red=blue
//construct rgb values;
for(int i=0;i!=flag_red_.size();i++){
//stolen from display.cpp, but don't want to include header
//for such a simple function
flag_rgb_.push_back(Uint32 (0xFF000000 | (flag_red_[i] << 16) | (flag_green_[i] << 8) | flag_blue_[i]) );
}
flag_string_ = utils::split(cfg["flag_rgb"]);
for(std::vector<std::string>::iterator c=flag_string_.begin();c!=flag_string_.end();c++){
int r,g,b;
r=(atoi(c->c_str()));
c++;
if(c!=flag_string_.end()){
g=(atoi(c->c_str()));
}else{
LOG_STREAM(err, config) <<"Missing Green in flag_rgb:"<<id();
g=0;
}
c++;
if(c!=flag_string_.end()){
b=(atoi(c->c_str()));
}else{
LOG_STREAM(err, config) <<"Missing Blue in flag_rgb:"<<id();
b=0;
}
flag_rgb_.push_back(Uint32 (0xFF000000 | (r << 16) | (g << 8) | b) );
}
}
unit_type::~unit_type()
@ -1167,6 +1223,12 @@ void unit_type::add_advancement(const unit_type &to_unit,int xp)
}
}
const std::vector<Uint32>& unit_type::flag_rgb() const
{
return flag_rgb_;
}
game_data::game_data()
{}

View file

@ -198,6 +198,9 @@ public:
const std::string& unit_description() const;
const std::string& get_hit_sound() const;
const std::string& die_sound() const;
const std::vector<Uint32>& flag_rgb() const;
int hitpoints() const;
std::vector<attack_type> attacks() const;
const unit_movement_type& movement_type() const;
@ -319,6 +322,8 @@ private:
};
std::vector<death_animation> death_animations_;
std::vector<Uint32> flag_rgb_;
};
struct game_data