recoloring of units to team colors
This commit is contained in:
parent
729b22a62c
commit
7d8962dda0
18 changed files with 335 additions and 63 deletions
|
@ -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 |
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_; };
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
39
src/team.cpp
39
src/team.cpp
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
14
src/unit.cpp
14
src/unit.cpp
|
@ -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_) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue