forked from oerkki/voxelands
add support for writting text on nodes - add text to signs
This commit is contained in:
parent
1d5a1993bb
commit
56f8114d1c
|
@ -3624,9 +3624,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
};
|
||||
|
||||
TileSpec tiles[6];
|
||||
NodeMetadata *meta = data->m_env->getMap().getNodeMetadata(p+blockpos_nodes);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
// Handles facedir rotation for textures
|
||||
tiles[i] = getNodeTile(n,p,tile_dirs[i],data->m_temp_mods);
|
||||
tiles[i] = getNodeTile(n,p,tile_dirs[i],data->m_temp_mods,meta);
|
||||
}
|
||||
video::SColor c[8];
|
||||
getLights(blockpos_nodes+p,c,data,smooth_lighting);
|
||||
|
@ -3660,7 +3661,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
makeRotatedCuboid(&collector, pos, box.m_box, tiles, 6, c, txc, box.m_angle);
|
||||
}
|
||||
if (content_features(n).draw_type == CDT_NODEBOX_META) {
|
||||
NodeMetadata *meta = data->m_env->getMap().getNodeMetadata(p+blockpos_nodes);
|
||||
if (meta == NULL)
|
||||
break;
|
||||
boxes = meta->getNodeBoxes(n);
|
||||
|
|
|
@ -1046,6 +1046,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign_wall(f);
|
||||
f->setFaceText(5,FaceText(0.05,0.3,0.95,0.7));
|
||||
|
||||
i = CONTENT_SIGN;
|
||||
f = &content_features(i);
|
||||
|
@ -1072,6 +1073,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign(f);
|
||||
f->setFaceText(5,FaceText(0.05,0.0675,0.95,0.55));
|
||||
f->setInventoryTextureNodeBox(i,"sign.png", "sign_front.png", "sign.png");
|
||||
crafting::setSignRecipe(CONTENT_CRAFTITEM_WOOD_PLANK,CONTENT_SIGN);
|
||||
crafting::setSignRecipe(CONTENT_CRAFTITEM_PINE_PLANK,CONTENT_SIGN);
|
||||
|
@ -1104,6 +1106,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign_ud(f);
|
||||
f->setFaceText(5,FaceText(0.05,0.45,0.95,0.8875));
|
||||
f->setInventoryTextureNodeBox(i,"sign.png", "sign_front.png", "sign.png");
|
||||
|
||||
i = CONTENT_LOCKABLE_SIGN_WALL;
|
||||
|
@ -1133,6 +1136,8 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign_wall(f);
|
||||
f->setFaceText(4,FaceText(0.05,0.3,0.95,0.7,FTT_OWNER));
|
||||
f->setFaceText(5,FaceText(0.05,0.3,0.95,0.7));
|
||||
|
||||
i = CONTENT_LOCKABLE_SIGN;
|
||||
f = &content_features(i);
|
||||
|
@ -1159,6 +1164,8 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign(f);
|
||||
f->setFaceText(4,FaceText(0.05,0.0675,0.95,0.55,FTT_OWNER));
|
||||
f->setFaceText(5,FaceText(0.05,0.0675,0.95,0.55));
|
||||
f->setInventoryTextureNodeBox(i,"sign.png", "sign_lock.png", "sign.png");
|
||||
crafting::set1Any2Recipe(CONTENT_SIGN,CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_LOCKABLE_SIGN);
|
||||
lists::add("craftguide",i);
|
||||
|
@ -1189,6 +1196,8 @@ void content_mapnode_special(bool repeat)
|
|||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
content_nodebox_sign_ud(f);
|
||||
f->setFaceText(4,FaceText(0.05,0.45,0.95,0.8875,FTT_OWNER));
|
||||
f->setFaceText(5,FaceText(0.05,0.45,0.95,0.8875));
|
||||
f->setInventoryTextureNodeBox(i,"sign.png", "sign_lock.png", "sign.png");
|
||||
|
||||
i = CONTENT_CHEST;
|
||||
|
|
|
@ -64,13 +64,16 @@ void SignNodeMetadata::serializeBody(std::ostream &os)
|
|||
{
|
||||
os<<serializeString(m_text);
|
||||
}
|
||||
std::wstring SignNodeMetadata::infoText()
|
||||
{
|
||||
return narrow_to_wide(std::string("\"")+m_text+"\"");
|
||||
}
|
||||
std::string SignNodeMetadata::getDrawSpecString()
|
||||
{
|
||||
return std::string("field[text;;") + m_text + "]";
|
||||
std::string spec("size[5,2.5]");
|
||||
spec += "field[0.75,0;4,1.5;text;;";
|
||||
spec += m_text;
|
||||
spec += "]";
|
||||
spec += "button_exit[1.25,2;3,1;save;";
|
||||
spec += gettext("Save");
|
||||
spec += "]";
|
||||
return spec;
|
||||
}
|
||||
bool SignNodeMetadata::import(NodeMetadata *meta)
|
||||
{
|
||||
|
@ -115,7 +118,7 @@ void LockingSignNodeMetadata::serializeBody(std::ostream &os)
|
|||
}
|
||||
std::wstring LockingSignNodeMetadata::infoText()
|
||||
{
|
||||
return narrow_to_wide(std::string("(")+m_owner+") \""+m_text+"\"");
|
||||
return narrow_to_wide(std::string("(")+m_owner+")");
|
||||
}
|
||||
bool LockingSignNodeMetadata::receiveFields(std::string formname, std::map<std::string, std::string> fields, Player *player)
|
||||
{
|
||||
|
@ -126,7 +129,14 @@ bool LockingSignNodeMetadata::receiveFields(std::string formname, std::map<std::
|
|||
}
|
||||
std::string LockingSignNodeMetadata::getDrawSpecString()
|
||||
{
|
||||
return std::string("field[text;;") + m_text + "]";
|
||||
std::string spec("size[5,2.5]");
|
||||
spec += "field[0.75,0;4,1.5;text;;";
|
||||
spec += m_text;
|
||||
spec += "]";
|
||||
spec += "button_exit[1.25,2;3,1;save;";
|
||||
spec += gettext("Save");
|
||||
spec += "]";
|
||||
return spec;
|
||||
}
|
||||
bool LockingSignNodeMetadata::import(NodeMetadata *meta)
|
||||
{
|
||||
|
|
|
@ -42,9 +42,8 @@ public:
|
|||
static NodeMetadata* create(std::istream &is);
|
||||
virtual NodeMetadata* clone();
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::wstring infoText();
|
||||
|
||||
std::string getText(){ return m_text; }
|
||||
virtual std::string getText(){ return m_text; }
|
||||
void setText(std::string t){ m_text = t; }
|
||||
virtual bool receiveFields(std::string formname, std::map<std::string, std::string> fields, Player *player)
|
||||
{
|
||||
|
@ -76,7 +75,7 @@ public:
|
|||
virtual std::string getInventoryOwner(){ return m_owner; }
|
||||
virtual void setInventoryOwner(std::string t){ m_owner = t; }
|
||||
|
||||
std::string getText(){ return m_text; }
|
||||
virtual std::string getText(){ return m_text; }
|
||||
void setText(std::string t){ m_text = t; }
|
||||
virtual bool receiveFields(std::string formname, std::map<std::string, std::string> fields, Player *player);
|
||||
virtual std::string getDrawSpecString();
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "map.h"
|
||||
#include "main.h" // For g_settings and g_texturesource
|
||||
#include "content_mapblock.h"
|
||||
#include "content_nodemeta.h"
|
||||
#include "settings.h"
|
||||
#include "profiler.h"
|
||||
#include "mesh.h"
|
||||
|
@ -244,8 +245,7 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
|
|||
Gets node tile from any place relative to block.
|
||||
Returns TILE_NODE if doesn't exist or should not be drawn.
|
||||
*/
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
|
||||
NodeModMap &temp_mods)
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, NodeModMap &temp_mods, NodeMetadata *meta)
|
||||
{
|
||||
TileSpec spec;
|
||||
spec = mn.getTile(face_dir);
|
||||
|
@ -290,6 +290,47 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
|
|||
}
|
||||
}
|
||||
|
||||
if (meta) {
|
||||
printf("meta!\n");
|
||||
FaceText ft = mn.getFaceText(face_dir);
|
||||
if (ft.m_hastext) {
|
||||
printf("facetext!\n");
|
||||
// Get original texture name
|
||||
u32 orig_id = spec.texture.id;
|
||||
std::string orig_name = g_texturesource->getTextureName(orig_id);
|
||||
// Create new texture name
|
||||
std::ostringstream os;
|
||||
os<<orig_name<<"^[text:";
|
||||
os<<ft.m_pos.UpperLeftCorner.X;
|
||||
os<<",";
|
||||
os<<ft.m_pos.UpperLeftCorner.Y;
|
||||
os<<",";
|
||||
os<<ft.m_pos.LowerRightCorner.X;
|
||||
os<<",";
|
||||
os<<ft.m_pos.LowerRightCorner.Y;
|
||||
os<<",";
|
||||
switch (ft.m_type) {
|
||||
case FTT_BOOKCONTENT:
|
||||
os<<((BookNodeMetadata*)meta)->getContent();
|
||||
break;
|
||||
case FTT_OWNER:
|
||||
os<<meta->getOwner();
|
||||
break;
|
||||
case FTT_INVOWNER:
|
||||
os<<meta->getInventoryOwner();
|
||||
break;
|
||||
default:
|
||||
os<<meta->getText();
|
||||
break;
|
||||
}
|
||||
|
||||
// Get new texture
|
||||
u32 new_id = g_texturesource->getTextureId(os.str());
|
||||
|
||||
spec.texture = g_texturesource->getTexture(new_id);
|
||||
}
|
||||
}
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ private:
|
|||
|
||||
// Helper functions
|
||||
video::SColor MapBlock_LightColor(u8 alpha, u8 light, bool selected=false);
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, NodeModMap &temp_mods);
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, NodeModMap &temp_mods, NodeMetadata *meta = NULL);
|
||||
TileSpec getMetaTile(MapNode mn, v3s16 p, v3s16 face_dir, NodeModMap &temp_mods);
|
||||
u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio);
|
||||
u8 getSmoothLight(v3s16 p, v3s16 corner, VoxelManipulator &vmanip, u32 daynight_ratio);
|
||||
|
|
|
@ -404,36 +404,37 @@ TileSpec MapNode::getTileFrom(v3s16 dir, TileSpec raw_spec[6])
|
|||
{
|
||||
TileSpec spec;
|
||||
s32 dir_i = 0;
|
||||
ContentFeatures &f = content_features(*this);
|
||||
|
||||
if (
|
||||
content_features(*this).param2_type == CPT_FACEDIR_SIMPLE
|
||||
|| content_features(*this).param2_type == CPT_FACEDIR_WALLMOUNT
|
||||
f.param2_type == CPT_FACEDIR_SIMPLE
|
||||
|| f.param2_type == CPT_FACEDIR_WALLMOUNT
|
||||
) {
|
||||
dir = facedir_rotate(param2&0x0F, dir);
|
||||
}else if (
|
||||
content_features(*this).param_type == CPT_FACEDIR_SIMPLE
|
||||
|| content_features(*this).param_type == CPT_FACEDIR_WALLMOUNT
|
||||
f.param_type == CPT_FACEDIR_SIMPLE
|
||||
|| f.param_type == CPT_FACEDIR_WALLMOUNT
|
||||
) {
|
||||
dir = facedir_rotate(param1, dir);
|
||||
}
|
||||
|
||||
if(dir == v3s16(0,-1,0))
|
||||
if (dir == v3s16(0,-1,0)) {
|
||||
dir_i = 1;
|
||||
else if(dir == v3s16(1,0,0))
|
||||
}else if(dir == v3s16(1,0,0)) {
|
||||
dir_i = 2;
|
||||
else if(dir == v3s16(-1,0,0))
|
||||
}else if(dir == v3s16(-1,0,0)) {
|
||||
dir_i = 3;
|
||||
else if(dir == v3s16(0,0,1))
|
||||
}else if(dir == v3s16(0,0,1)) {
|
||||
dir_i = 4;
|
||||
else if(dir == v3s16(0,0,-1))
|
||||
}else if(dir == v3s16(0,0,-1)) {
|
||||
dir_i = 5;
|
||||
}
|
||||
|
||||
spec = raw_spec[dir_i];
|
||||
|
||||
/*
|
||||
If it contains some mineral, change texture id
|
||||
*/
|
||||
if(content_features(*this).param_type == CPT_MINERAL && g_texturesource)
|
||||
if(f.param_type == CPT_MINERAL && g_texturesource)
|
||||
{
|
||||
u8 mineral = getMineral();
|
||||
std::string mineral_texture_name = mineral_features(mineral).texture;
|
||||
|
@ -448,11 +449,11 @@ TileSpec MapNode::getTileFrom(v3s16 dir, TileSpec raw_spec[6])
|
|||
spec.texture = g_texturesource->getTexture(new_id);
|
||||
}
|
||||
}
|
||||
if (content_features(*this).rotate_tile_with_nodebox) {
|
||||
if (f.rotate_tile_with_nodebox) {
|
||||
u8 facedir = 0;
|
||||
if (content_features(*this).param_type == CPT_FACEDIR_SIMPLE) {
|
||||
if (f.param_type == CPT_FACEDIR_SIMPLE) {
|
||||
facedir = param1;
|
||||
}else if (content_features(*this).param2_type == CPT_FACEDIR_SIMPLE) {
|
||||
}else if (f.param2_type == CPT_FACEDIR_SIMPLE) {
|
||||
facedir = (param2&0x0F);
|
||||
}
|
||||
if (dir_i == 0) {
|
||||
|
@ -489,6 +490,35 @@ TileSpec MapNode::getTileFrom(v3s16 dir, TileSpec raw_spec[6])
|
|||
return spec;
|
||||
}
|
||||
#endif
|
||||
FaceText MapNode::getFaceText(v3s16 dir)
|
||||
{
|
||||
s32 dir_i = 0;
|
||||
ContentFeatures &f = content_features(*this);
|
||||
if (
|
||||
f.param2_type == CPT_FACEDIR_SIMPLE
|
||||
|| f.param2_type == CPT_FACEDIR_WALLMOUNT
|
||||
) {
|
||||
dir = facedir_rotate(param2&0x0F, dir);
|
||||
}else if (
|
||||
f.param_type == CPT_FACEDIR_SIMPLE
|
||||
|| f.param_type == CPT_FACEDIR_WALLMOUNT
|
||||
) {
|
||||
dir = facedir_rotate(param1, dir);
|
||||
}
|
||||
if (dir == v3s16(0,-1,0)) {
|
||||
dir_i = 1;
|
||||
}else if(dir == v3s16(1,0,0)) {
|
||||
dir_i = 2;
|
||||
}else if(dir == v3s16(-1,0,0)) {
|
||||
dir_i = 3;
|
||||
}else if(dir == v3s16(0,0,1)) {
|
||||
dir_i = 4;
|
||||
}else if(dir == v3s16(0,0,-1)) {
|
||||
dir_i = 5;
|
||||
}
|
||||
|
||||
return f.facetexts[dir_i];
|
||||
}
|
||||
|
||||
u8 MapNode::getMineral()
|
||||
{
|
||||
|
|
|
@ -224,6 +224,44 @@ public:
|
|||
aabb3f m_box;
|
||||
};
|
||||
|
||||
enum FaceTextType {
|
||||
FTT_INFO,
|
||||
FTT_BOOKCONTENT,
|
||||
FTT_OWNER,
|
||||
FTT_INVOWNER
|
||||
};
|
||||
|
||||
class FaceText
|
||||
{
|
||||
public:
|
||||
FaceText():
|
||||
m_hastext(false)
|
||||
{
|
||||
}
|
||||
FaceText(f32 tlx, f32 tly, f32 brx, f32 bry):
|
||||
m_type(FTT_INFO),
|
||||
m_hastext(true)
|
||||
{
|
||||
#ifndef SERVER
|
||||
m_pos = core::rect<f32>(tlx,tly,brx,bry);
|
||||
#endif
|
||||
}
|
||||
FaceText(f32 tlx, f32 tly, f32 brx, f32 bry, FaceTextType type):
|
||||
m_type(type),
|
||||
m_hastext(true)
|
||||
{
|
||||
#ifndef SERVER
|
||||
m_pos = core::rect<f32>(tlx,tly,brx,bry);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SERVER
|
||||
core::rect<f32> m_pos;
|
||||
#endif
|
||||
FaceTextType m_type;
|
||||
bool m_hastext;
|
||||
};
|
||||
|
||||
std::vector<NodeBox> transformNodeBox(MapNode &n,
|
||||
const std::vector<NodeBox> &nodebox);
|
||||
|
||||
|
@ -255,6 +293,9 @@ struct ContentFeatures
|
|||
std::vector<NodeBox> nodeboxes;
|
||||
std::vector<NodeBox> wield_nodeboxes;
|
||||
|
||||
// positions for text on faces
|
||||
FaceText facetexts[6];
|
||||
|
||||
// List of all block textures that have been used (value is dummy)
|
||||
// Exists on server too for cleaner code in content_mapnode.cpp
|
||||
core::map<std::string, bool> used_texturenames;
|
||||
|
@ -393,6 +434,7 @@ struct ContentFeatures
|
|||
0.5*BS
|
||||
));
|
||||
wield_nodeboxes.clear();
|
||||
setAllFaceTexts(FaceText());
|
||||
param_type = CPT_NONE;
|
||||
param2_type = CPT_NONE;
|
||||
draw_type = CDT_AIRLIKE;
|
||||
|
@ -483,6 +525,18 @@ struct ContentFeatures
|
|||
wield_nodeboxes.push_back(nb);
|
||||
}
|
||||
|
||||
void setFaceText(u16 i, FaceText ft)
|
||||
{
|
||||
facetexts[i] = ft;
|
||||
}
|
||||
|
||||
void setAllFaceTexts(FaceText ft)
|
||||
{
|
||||
for (u16 i=0; i<6; i++) {
|
||||
setFaceText(i,ft);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Quickhands for simple materials
|
||||
*/
|
||||
|
@ -907,6 +961,8 @@ struct MapNode
|
|||
TileSpec getTileFrom(v3s16 dir, TileSpec raw_spec[6]);
|
||||
#endif
|
||||
|
||||
FaceText getFaceText(v3s16 dir);
|
||||
|
||||
/*
|
||||
Gets mineral content of node, if there is any.
|
||||
MINERAL_NONE if doesn't contain or isn't able to contain mineral.
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
virtual NodeMetadata* clone() = 0;
|
||||
virtual void serializeBody(std::ostream &os) = 0;
|
||||
virtual std::wstring infoText() {return L"";}
|
||||
virtual std::string getText() {return "";}
|
||||
virtual Inventory* getInventory() {return NULL;}
|
||||
// This is called always after the inventory is modified, before
|
||||
// the changes are copied elsewhere
|
||||
|
|
91
src/strfnd.h
91
src/strfnd.h
|
@ -31,53 +31,52 @@
|
|||
std::string trim(const std::string &str);
|
||||
|
||||
class Strfnd{
|
||||
std::string tek;
|
||||
unsigned int p;
|
||||
std::string tek;
|
||||
unsigned int p;
|
||||
public:
|
||||
void start(std::string niinq){
|
||||
tek = niinq;
|
||||
p=0;
|
||||
}
|
||||
unsigned int where(){
|
||||
return p;
|
||||
}
|
||||
void to(unsigned int i){
|
||||
p = i;
|
||||
}
|
||||
std::string what(){
|
||||
return tek;
|
||||
}
|
||||
std::string next(std::string plop){
|
||||
//std::cout<<"tek=\""<<tek<<"\" plop=\""<<plop<<"\""<<std::endl;
|
||||
size_t n;
|
||||
std::string palautus;
|
||||
if (p < tek.size())
|
||||
{
|
||||
//std::cout<<"\tp<tek.size()"<<std::endl;
|
||||
if ((n = tek.find(plop, p)) == std::string::npos || plop == "")
|
||||
{
|
||||
//std::cout<<"\t\tn == string::npos || plop == \"\""<<std::endl;
|
||||
n = tek.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout<<"\t\tn != string::npos"<<std::endl;
|
||||
}
|
||||
palautus = tek.substr(p, n-p);
|
||||
p = n + plop.length();
|
||||
}
|
||||
//else
|
||||
//std::cout<<"\tp>=tek.size()"<<std::endl;
|
||||
//std::cout<<"palautus=\""<<palautus<<"\""<<std::endl;
|
||||
return palautus;
|
||||
}
|
||||
bool atend(){
|
||||
if(p>=tek.size()) return true;
|
||||
return false;
|
||||
}
|
||||
Strfnd(std::string s){
|
||||
start(s);
|
||||
}
|
||||
void start(std::string niinq)
|
||||
{
|
||||
tek = niinq;
|
||||
p=0;
|
||||
}
|
||||
unsigned int where()
|
||||
{
|
||||
return p;
|
||||
}
|
||||
void to(unsigned int i)
|
||||
{
|
||||
p = i;
|
||||
}
|
||||
std::string what()
|
||||
{
|
||||
return tek;
|
||||
}
|
||||
std::string next(std::string plop)
|
||||
{
|
||||
size_t n;
|
||||
std::string palautus;
|
||||
if (p < tek.size()) {
|
||||
if ((n = tek.find(plop, p)) == std::string::npos || plop == "")
|
||||
n = tek.size();
|
||||
palautus = tek.substr(p, n-p);
|
||||
p = n + plop.length();
|
||||
}
|
||||
return palautus;
|
||||
}
|
||||
std::string end()
|
||||
{
|
||||
return tek.substr(p,tek.size()-p);
|
||||
}
|
||||
bool atend()
|
||||
{
|
||||
if (p>=tek.size())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
Strfnd(std::string s)
|
||||
{
|
||||
start(s);
|
||||
}
|
||||
};
|
||||
|
||||
class WStrfnd{
|
||||
|
|
136
src/tile.cpp
136
src/tile.cpp
|
@ -26,12 +26,14 @@
|
|||
#include "tile.h"
|
||||
#include "debug.h"
|
||||
#include "main.h" // for g_settings
|
||||
#include "game.h"
|
||||
#include "filesys.h"
|
||||
#include "utility.h"
|
||||
#include "settings.h"
|
||||
#include "mesh.h"
|
||||
#include "hex.h"
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <IGUIStaticText.h>
|
||||
#include "log.h"
|
||||
#include "mapnode.h" // For texture atlas making
|
||||
#include "mineral.h" // For texture atlas making
|
||||
|
@ -218,11 +220,16 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
|
|||
|
||||
// Find last meta separator in name
|
||||
s32 last_separator_position = -1;
|
||||
for (s32 i=name.size()-1; i>=0; i--) {
|
||||
if (name[i] == separator) {
|
||||
last_separator_position = i;
|
||||
break;
|
||||
size_t text_separator_position = name.find("^[text:");
|
||||
if (text_separator_position == std::string::npos) {
|
||||
for (s32 i=name.size()-1; i>=0; i--) {
|
||||
if (name[i] == separator) {
|
||||
last_separator_position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
last_separator_position = text_separator_position;
|
||||
}
|
||||
/*
|
||||
If separator was found, construct the base name and make the
|
||||
|
@ -1670,6 +1677,127 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||
blit_with_alpha_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim);
|
||||
img->drop();
|
||||
}
|
||||
/*
|
||||
[text:x,y,X,Y,string
|
||||
writes string to texture
|
||||
*/
|
||||
else if (part_of_name.substr(0,6) == "[text:") {
|
||||
Strfnd sf(part_of_name);
|
||||
sf.next(":");
|
||||
std::string x = sf.next(",");
|
||||
std::string y = sf.next(",");
|
||||
std::string X = sf.next(",");
|
||||
std::string Y = sf.next(",");
|
||||
std::wstring text = narrow_to_wide(sf.end());
|
||||
|
||||
if (baseimg == NULL) {
|
||||
errorstream << "generateImagePart(): baseimg != NULL "
|
||||
<< "for part_of_name=\"" << part_of_name
|
||||
<< "\", cancelling." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
core::rect<f32> pos(
|
||||
mystof(x.c_str()),
|
||||
mystof(y.c_str()),
|
||||
mystof(X.c_str()),
|
||||
mystof(Y.c_str())
|
||||
);
|
||||
|
||||
video::IVideoDriver *driver = device->getVideoDriver();
|
||||
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
errorstream<<"generateImagePart(): EVDF_RENDER_TO_TARGET not supported."<<std::endl;
|
||||
warned = true;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
||||
core::dimension2d<u32> rtt_dim(dim.Width*10,dim.Height*10);
|
||||
std::string rtt_texture_name = part_of_name + "_RTT";
|
||||
|
||||
// Create render target texture
|
||||
video::ITexture *rtt = driver->addRenderTargetTexture(rtt_dim, rtt_texture_name.c_str(), video::ECF_A8R8G8B8);
|
||||
if (rtt == NULL) {
|
||||
errorstream<<"generateImagePart(): addRenderTargetTexture"
|
||||
" returned NULL."<<std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the gui
|
||||
gui::IGUIEnvironment *guienv = device->getGUIEnvironment();
|
||||
assert(guienv);
|
||||
|
||||
gui::IGUISkin* skin = guienv->getSkin();
|
||||
gui::IGUIFont *std_font = skin->getFont();
|
||||
static gui::IGUIFont *tex_font = NULL;
|
||||
#if USE_FREETYPE
|
||||
tex_font = gui::CGUITTFont::createTTFont(guienv, getPath("font","liberationsans.ttf",false).c_str(),10);
|
||||
#else
|
||||
tex_font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
|
||||
#endif
|
||||
if (tex_font)
|
||||
skin->setFont(tex_font);
|
||||
|
||||
// Set render target
|
||||
driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0));
|
||||
|
||||
const video::SColor color(255,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
const core::rect<s32> rect(core::position2d<s32>(0,0),rtt_dim);
|
||||
const core::rect<s32> srect(core::position2d<s32>(0,0),dim);
|
||||
driver->beginScene(true, true, video::SColor(255,0,0,0));
|
||||
video::ITexture *t = driver->addTexture(std::string(rtt_texture_name+"_BASE").c_str(), baseimg);
|
||||
driver->draw2DImage(
|
||||
t,
|
||||
rect,
|
||||
srect,
|
||||
&rect,
|
||||
colors,
|
||||
true
|
||||
);
|
||||
|
||||
const core::rect<s32> trect(
|
||||
(f32)rtt_dim.Width*pos.UpperLeftCorner.X,
|
||||
(f32)rtt_dim.Height*pos.UpperLeftCorner.Y,
|
||||
(f32)rtt_dim.Width*pos.LowerRightCorner.X,
|
||||
(f32)rtt_dim.Height*pos.LowerRightCorner.Y
|
||||
);
|
||||
gui::IGUIStaticText *e = guienv->addStaticText(text.c_str(), trect);
|
||||
e->setTextAlignment(gui::EGUIA_CENTER,gui::EGUIA_CENTER);
|
||||
|
||||
// Render scene
|
||||
e->draw();
|
||||
//guienv->drawAll();
|
||||
driver->endScene();
|
||||
|
||||
// remove that text so it doesn't appear in the game window for
|
||||
// some insane irrlicht too many classes reason
|
||||
e->remove();
|
||||
|
||||
// Unset render target
|
||||
driver->setRenderTarget(0, false, true, 0);
|
||||
|
||||
skin->setFont(std_font);
|
||||
|
||||
// Create image of render target
|
||||
video::IImage *image = driver->createImage(rtt, v2s32(0,0), rtt_dim);
|
||||
assert(image);
|
||||
|
||||
video::IImage *new_baseimg = driver->createImage(video::ECF_A8R8G8B8, rtt_dim);
|
||||
if (new_baseimg) {
|
||||
baseimg->copyToScaling(new_baseimg);
|
||||
baseimg->drop();
|
||||
baseimg = new_baseimg;
|
||||
}
|
||||
|
||||
if (image) {
|
||||
image->copyTo(baseimg);
|
||||
image->drop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
infostream<<"generate_image(): Invalid "
|
||||
|
|
|
@ -40,6 +40,7 @@ using namespace jthread;
|
|||
u32 parseImageTransform(const std::string& s);
|
||||
core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<u32> dim);
|
||||
void imageTransform(u32 transform, video::IImage *src, video::IImage *dst);
|
||||
video::ITexture *addText(IrrlichtDevice *device, video::ITexture *tex, core::rect<f32> pos, std::wstring &s);
|
||||
|
||||
/*
|
||||
Specifies a texture in an atlas.
|
||||
|
|
Loading…
Reference in New Issue