注册 | 登录

游侠NETSHOW论坛





查看: 2938|回复: 0
打印 上一主题 下一主题

[讨论] [MOD]兵种形象中颜色 [复制链接]

帖子
894
精华
1
积分
949
金钱
10688
荣誉
30
人气
17
评议
0
跳转到指定楼层
楼主
发表于 2012-12-14 09:25:46 |显示全部楼层 |倒序浏览
本帖最后由 ancientcc 于 2013-7-23 07:45 编辑


左则是图像素材,右侧是该素材在不同势力下表现出来的效果,在区别上,让图像在一些“部位”换上了势力色,使玩家一看到图像就知道该部队属哪势力。

势力色
C:\kingdom-src\data\core\team-colors.cfg
1:[color_range]块的次序依次指示了势力颜色。红色是第一个块,进入游戏后第一势力就是红色。
2:当势力数多于[color_range]块数时,转回第一个[color_range]继续赋给势力色。
3:MOD制作者可以在[side]的color字段改变势力色,例如color=blue,把该势力强制赋给蓝色,color可用的属性值就是[color_range]中出现过的id值。

如何让同一个图像在不同势力中显示不同颜色

让同一个图像在不同势力中显示不同颜色是通过改该图中一种或多种颜色实现的。

一、unit_type中的flag_rgb指定特征色值。使用flag_rgb=magenta。

二、unit::TC_image_modes()被调用形成图像运算
modifier=~RC(magenta>blue)

假设该势力的表示色是蓝色(blue)
~RC(magenta>blue)就是指示图像处理器把该图像进行颜色替换,把当中的magenta色替换成势色表示色:蓝色。

这种颜色替换是程序支持图像运算中的RC实现的。就让看RC得怎么个过程。

1:计算颜色替换映射
既然要替换就需要确定两类颜色:要被替换颜色、要被替换为的颜色。
RC(magenta>blue)中,magenta就是要被替换颜色,那它具体指的哪颜色?——它写在<data>\core\team-colors.cfg,具体是:
  1. magenta=F49AC1,3F0016,55002A,690039,7B0045,8C0051,9E005D,B10069,C30074,D6007F,EC008C,EE3D96,EF5BA1,F172AC,F287B6,F6ADCD,F8C1D9,FAD5E5,FDE9F1。
复制代码
对于magenta这种颜色来说,它有19个Unit32。

std::vector<Unit32>中第一种颜色称为参考色,参考色有两个作用:
该颜色保证会被精确替换为[color_range]中的mid_色。
要被替换的其它颜色以它作为参考,进而估算出要被替换到的颜色。

对比可以参考图1-1中的map_rgb左侧的值。

RC(magenta>blue)中,blue就是要被替换为颜色,那它具体指的哪颜色?——它也写在<data>\core\team-colors.cfg,具体是
  1. [color_range]
  2.     id=blue
  3.     rgb=2E419B,FFFFFF,0F0F0F,0000FF
  4.     name= _ "Blue"
  5. [/color_range]
复制代码
mid_(2E4198):替换颜色时和参考色对应的颜色。
max_(FFFFFF):替换颜色时会保证的时大色强颜色,具体作用看替换算法。
min_(0F0F0F):替换颜色时会保证的时小色强颜色,具体作用看替换算法。
rep_(0000FF):小地图中单位的表示颜色。
替换时,要被替换颜色是一个颜色集合,[color_ragne]没有指定要被替换为的颜色集合,而是以着参数的方式、然后通过一定算法由(要被替换颜色, [color_range])计算出要被替换为的颜色集合。

@new_range:[color_range]块。
@old_rgb:要被替换颜色颜色集合。
  1. std::map<Uint32, Uint32> recolor_range(const color_range& new_range, const std::vector<Uint32>& old_rgb){
  2.         std::map<Uint32, Uint32> map_rgb;

  3.         Uint16 new_red  = (new_range.mid() & 0x00FF0000)>>16;
  4.         Uint16 new_green= (new_range.mid() & 0x0000FF00)>>8;
  5.         Uint16 new_blue = (new_range.mid() & 0x000000FF);
  6.         Uint16 max_red  = (new_range.max() & 0x00FF0000)>>16;
  7.         Uint16 max_green= (new_range.max() & 0x0000FF00)>>8 ;
  8.         Uint16 max_blue = (new_range.max() & 0x000000FF)    ;
  9.         Uint16 min_red  = (new_range.min() & 0x00FF0000)>>16;
  10.         Uint16 min_green= (new_range.min() & 0x0000FF00)>>8 ;
  11.         Uint16 min_blue = (new_range.min() & 0x000000FF)    ;

  12.         // Map first color in vector to exact new color
  13.         Uint32 temp_rgb= old_rgb.empty() ? 0 : old_rgb[0];
  14.         Uint16 old_r=(temp_rgb & 0X00FF0000)>>16;
  15.         Uint16 old_g=(temp_rgb & 0X0000FF00)>>8;
  16.         Uint16 old_b=(temp_rgb & 0X000000FF);
  17.         Uint16 reference_avg = (( old_r + old_g + old_b) / 3);

  18.         for(std::vector< Uint32 >::const_iterator temp_rgb2 = old_rgb.begin();
  19.               temp_rgb2 != old_rgb.end(); ++temp_rgb2)
  20.         {
  21.                 Uint16 old_r=((*temp_rgb2) & 0X00FF0000)>>16;
  22.                 Uint16 old_g=((*temp_rgb2) & 0X0000FF00)>>8;
  23.                 Uint16 old_b=((*temp_rgb2) & 0X000000FF);

  24.                 const Uint16 old_avg = (( old_r + old_g +  old_b) / 3);
  25.              // Calculate new color
  26.                 Uint32 new_r, new_g, new_b;

  27.                 if(reference_avg && old_avg <= reference_avg){
  28.                         float old_rat = static_cast<float>(old_avg)/reference_avg;
  29.                         new_r=Uint32( old_rat * new_red   + (1 - old_rat) * min_red);
  30.                         new_g=Uint32( old_rat * new_green + (1 - old_rat) * min_green);
  31.                         new_b=Uint32( old_rat * new_blue  + (1 - old_rat) * min_blue);
  32.                 }else if(255 - reference_avg){
  33.                         float old_rat = (255.0f - static_cast<float>(old_avg)) /
  34.                                 (255.0f - reference_avg);

  35.                         new_r=static_cast<Uint32>( old_rat * new_red   + (1 - old_rat) * max_red);
  36.                         new_g=static_cast<Uint32>( old_rat * new_green + (1 - old_rat) * max_green);
  37.                         new_b=static_cast<Uint32>( old_rat * new_blue  + (1 - old_rat) * max_blue);
  38.                 }else{
  39.                         new_r=0; new_g=0; new_b=0; // Suppress warning
  40.                         assert(false);
  41.                         // Should never get here.
  42.                         // Would imply old_avg > reference_avg = 255
  43.              }

  44.                 if(new_r>255) new_r=255;
  45.                 if(new_g>255) new_g=255;
  46.                 if(new_b>255) new_b=255;

  47.                 Uint32 newrgb = (new_r << 16) + (new_g << 8) + (new_b );
  48.                 map_rgb[*temp_rgb2]=newrgb;
  49.         }

  50.         return map_rgb;
  51. }
复制代码
计算出要被替换为的颜色集合参考图1-1中的map_rgb右侧的值。

  • 1、生成的替换映射和具体图像无关。
  • 2、替换映射长度等于源数组(magenta)长度。
  • 3、在计算替换映射时,不使用[color_range]中的rep_字段。
  • 4、参考色会保证被替换为[color_range]中的avg_。


2:调用recolor_image,用计算出的替换映射重着色图像

map_rgb:重着色映射。它的first值就是这写在<kingdom-src>/data/core/team-colors.cfg中的magenta值。注:map_rgb是个映射,它要按first值进行排序。
recolor_image函数逻辑很简单:逐个检查像素,是非透明像素时(透明像素已不用显示),它的rgb分量如果在map_rgb.first中就用相应的map_rgb.second中的值进行替换。

为支持兵种图形在不同势力中有不同颜色,制作mod时
1、选择一种“较清晰”特征色,把它作为参考色;
2、选定其它要被替换的特征色,和参考色合在一起,以“,”号进行隔开,类似:F49AC1,3F0016,55002A,690039,7B0045
3、使用magenta=......(后面.....内容就是2形成的颜色项,把这个magenta替换掉<data>\core\team_colors.cfg中原先的值。
4、unit_type中的flag_rgb指定关键字值。使用flag_rgb=magenta,推荐使用宏:{MAGENTA_IS_THE_TEAM_COLOR}
附件: 你需要登录才可以下载或查看附件。没有帐号?注册

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

手机版|Archiver|游侠NETSHOW论坛 ( 苏ICP备2023007791号 )

GMT+8, 2025-10-10 12:55 , Processed in 0.325265 second(s), 13 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

分享到