new furnace and incinerator code

This commit is contained in:
darkrose 2015-08-29 03:26:33 +10:00
parent bbc733ce04
commit f875216124
23 changed files with 418 additions and 176 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 805 B

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 349 B

View File

@ -1971,6 +1971,10 @@ void meshgen_nodebox(MeshMakeData *data, v3s16 p, MapNode &n, bool selected, boo
TileSpec tiles[6];
NodeMetadata *meta = data->m_env->getMap().getNodeMetadata(p+data->m_blockpos_nodes);
if (meta) {
NodeMetadata *cmeta = meta->clone();
meta = cmeta;
}
for (int i = 0; i < 6; i++) {
// Handles facedir rotation for textures
tiles[i] = getNodeTile(n,p,tile_dirs[i],data->m_temp_mods,meta);
@ -1978,8 +1982,12 @@ void meshgen_nodebox(MeshMakeData *data, v3s16 p, MapNode &n, bool selected, boo
std::vector<NodeBox> boxes = content_features(n).getNodeBoxes(n);
meshgen_build_nodebox(data,p,n,selected,boxes,tiles);
if (!meta || !has_meta)
if (!meta)
return;
if (!has_meta) {
delete meta;
return;
}
boxes = meta->getNodeBoxes(n);
if (boxes.size() > 0) {
@ -1989,6 +1997,8 @@ void meshgen_nodebox(MeshMakeData *data, v3s16 p, MapNode &n, bool selected, boo
}
meshgen_build_nodebox(data,p,n,selected,boxes,tiles);
}
delete meta;
}
void meshgen_glasslike(MeshMakeData *data, v3s16 p, MapNode &n, bool selected)

View File

@ -1443,12 +1443,17 @@ void content_mapnode_special(bool repeat)
f = &content_features(i);
f->description = wgettext("Furnace");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->draw_type = CDT_NODEBOX_META;
f->setAllTextures("furnace_side.png");
f->setTexture(0, "furnace_top.png");
f->setTexture(1, "furnace_top.png");
f->setTexture(2, "furnace_side.png^[transformFX");
f->setTexture(4, "furnace_back.png");
f->setTexture(5, "furnace_front.png"); // Z-
f->setInventoryTextureCube("furnace_top.png", "furnace_front.png", "furnace_side.png");
f->setAllMetaTextures("fire.png");
content_nodebox_furnace(f);
f->setInventoryTextureNodeBox(i,"furnace_top.png^[transformR90", "furnace_front.png", "furnace_side.png^[transformFX");
f->solidness = 0; // drawn separately, makes no faces
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new FurnaceNodeMetadata();
@ -1470,8 +1475,7 @@ void content_mapnode_special(bool repeat)
f->setAllTextures("furnace_side.png");
f->setTexture(0, "furnace_top.png");
f->setTexture(1, "furnace_top.png");
f->setTexture(5, "furnace_front_active.png"); // Z-
f->setInventoryTextureCube("furnace_top.png", "furnace_front_active.png", "furnace_side.png");
f->setTexture(5, "furnace_front.png"); // Z-
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_FURNACE)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new FurnaceNodeMetadata();
@ -1483,12 +1487,17 @@ void content_mapnode_special(bool repeat)
f = &content_features(i);
f->description = wgettext("Locking Furnace");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->draw_type = CDT_NODEBOX_META;
f->setAllTextures("furnace_side.png");
f->setTexture(0, "furnace_top.png");
f->setTexture(1, "furnace_top.png");
f->setTexture(2, "furnace_side.png^[transformFX");
f->setTexture(4, "furnace_back.png");
f->setTexture(5, "furnace_lock.png"); // Z-
f->setInventoryTextureCube("furnace_top.png", "furnace_lock.png", "furnace_side.png");
f->setAllMetaTextures("fire.png");
content_nodebox_lockedfurnace(f);
f->setInventoryTextureNodeBox(i,"furnace_top.png^[transformR90", "furnace_lock.png", "furnace_side.png^[transformFX");
f->solidness = 0; // drawn separately, makes no faces
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new LockingFurnaceNodeMetadata();
@ -1523,12 +1532,17 @@ void content_mapnode_special(bool repeat)
f = &content_features(i);
f->description = wgettext("Incinerator");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->draw_type = CDT_NODEBOX_META;
f->setAllTextures("incinerator_side.png");
f->setTexture(0, "incinerator_top.png"); // Z-
f->setTexture(1, "incinerator_top.png"); // Z-
f->setTexture(0, "incinerator_top.png");
f->setTexture(1, "incinerator_top.png");
f->setTexture(2, "incinerator_side.png^[transformFX");
f->setTexture(4, "incinerator_back.png");
f->setTexture(5, "incinerator_front.png"); // Z-
f->setInventoryTextureCube("incinerator_top.png", "incinerator_front.png", "incinerator_side.png");
f->setAllMetaTextures("fire.png");
content_nodebox_incinerator(f);
f->setInventoryTextureNodeBox(i,"incinerator_top.png^[transformR90", "incinerator_front.png", "incinerator_side.png^[transformFX");
f->solidness = 0; // drawn separately, makes no faces
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new IncineratorNodeMetadata();

View File

@ -1531,3 +1531,79 @@ void content_nodebox_forge(ContentFeatures *f)
0.1875*BS,0.375*BS,0.1875*BS,0.375*BS,0.4375*BS,0.375*BS
));
}
void content_nodebox_furnace(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.3125*BS,-0.5*BS,-0.4375*BS,0.5*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.4375*BS,-0.3125*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.3125*BS,0.25*BS,-0.4375*BS,0.3125*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.3125*BS,-0.5*BS,-0.4375*BS,0.3125*BS,-0.25*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.3125*BS,-0.0625*BS,-0.4375*BS,0.3125*BS,0.0625*BS,-0.375*BS
));
}
void content_nodebox_lockedfurnace(ContentFeatures *f)
{
content_nodebox_furnace(f);
f->addNodeBox(NodeBox(
-0.3125*BS,-0.375*BS,-0.5*BS,0.3125*BS,-0.3125*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
-0.3125*BS,0.3125*BS,-0.5*BS,0.3125*BS,0.375*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
-0.3125*BS,-0.3125*BS,-0.5*BS,-0.25*BS,0.3125*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
0.25*BS,-0.3125*BS,-0.5*BS,0.3125*BS,0.3125*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
-0.125*BS,-0.3125*BS,-0.5*BS,-0.0625*BS,0.3125*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
0.0625*BS,-0.3125*BS,-0.5*BS,0.125*BS,0.3125*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
0.3125*BS,-0.1875*BS,-0.5*BS,0.375*BS,0.*BS,-0.4375*BS
));
f->addNodeBox(NodeBox(
0.1875*BS,-0.1875*BS,-0.5*BS,0.25*BS,0.*BS,-0.4375*BS
));
}
void content_nodebox_incinerator(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.25*BS,-0.5*BS,-0.4375*BS,0.5*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.4375*BS,-0.25*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.25*BS,0.25*BS,-0.4375*BS,-0.1875*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
0.1875*BS,0.25*BS,-0.4375*BS,0.25*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.1875*BS,0.3125*BS,-0.4375*BS,0.1875*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.25*BS,-0.5*BS,-0.4375*BS,0.25*BS,-0.0625*BS,-0.375*BS
));
}

View File

@ -68,5 +68,8 @@ void content_nodebox_flower_pot(ContentFeatures *f);
void content_nodebox_parcel(ContentFeatures *f);
void content_nodebox_cauldron(ContentFeatures *f);
void content_nodebox_forge(ContentFeatures *f);
void content_nodebox_furnace(ContentFeatures *f);
void content_nodebox_lockedfurnace(ContentFeatures *f);
void content_nodebox_incinerator(ContentFeatures *f);
#endif

View File

@ -710,19 +710,25 @@ void FurnaceNodeMetadata::inventoryModified()
}
bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
if(dtime > 60.0)
{
MapNode n = env->getMap().getNodeNoEx(pos).getContent();
if (n.getContent() == CONTENT_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}
if (dtime > 60.0)
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
MapNode n = env->getMap().getNodeNoEx(pos);
while (m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
InventoryList *dst_list = m_inventory->getList("dst");
assert(dst_list);
@ -749,12 +755,6 @@ bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
If item finishes cooking, move it to result.
*/
if (m_fuel_time < m_fuel_totaltime) {
if (n.getContent() == CONTENT_FURNACE) {
n.param2 = n.param1;
n.setContent(CONTENT_FURNACE_ACTIVE);
env->setPostStepNodeSwap(pos,n);
}
//infostream<<"Furnace is active"<<std::endl;
m_fuel_time += dtime;
m_src_time += dtime;
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
@ -767,17 +767,8 @@ bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
changed = true;
// If the fuel was not used up this step, just keep burning it
if (m_fuel_time < m_fuel_totaltime) {
if (m_fuel_time < m_fuel_totaltime)
continue;
}else if (n.getContent() == CONTENT_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
/*
@ -821,24 +812,37 @@ bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
changed = true;
}else{
m_step_accumulator = 0;
MapNode n = env->getMap().getNodeNoEx(pos).getContent();
if (n.getContent() == CONTENT_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}
}
return changed;
}
std::string FurnaceNodeMetadata::getDrawSpecString()
{
return
"size[8,9]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"
"list[current_player;main;0,5;8,4;]";
std::string spec("size[8,9]");
spec += "list[current_name;fuel;2,3;1,1;]";
spec += "ring[2,3;1;#FF0000;";
float v = 0;
if (m_fuel_totaltime > 0.0)
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
spec += itos((int)v);
spec += "]";
spec += "list[current_name;src;2,1;1,1;]";
spec += "list[current_name;dst;5,1;2,2;]";
spec += "list[current_player;main;0,5;8,4;]";
return spec;
}
std::vector<NodeBox> FurnaceNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();
if (m_fuel_time < m_fuel_totaltime) {
boxes.push_back(NodeBox(
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
));
}
return transformNodeBox(n,boxes);
}
bool FurnaceNodeMetadata::import(NodeMetadata *meta)
{
@ -971,13 +975,20 @@ void LockingFurnaceNodeMetadata::inventoryModified()
}
bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
{
MapNode n = env->getMap().getNodeNoEx(pos);
if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}
if (dtime > 60.0)
infostream<<"LockingFurnace stepping a long time ("<<dtime<<")"<<std::endl;
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
MapNode n = env->getMap().getNodeNoEx(pos);
while(m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
@ -1019,13 +1030,6 @@ bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment
If item finishes cooking, move it to result.
*/
if (m_fuel_time < m_fuel_totaltime) {
if (n.getContent() == CONTENT_LOCKABLE_FURNACE) {
n.param2 = n.param1;
n.setContent(CONTENT_LOCKABLE_FURNACE_ACTIVE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
//infostream<<"Furnace is active"<<std::endl;
m_fuel_time += dtime;
m_src_time += dtime;
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
@ -1038,19 +1042,8 @@ bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment
changed = true;
// If the fuel was not used up this step, just keep burning it
if (m_fuel_time < m_fuel_totaltime) {
if (m_fuel_time < m_fuel_totaltime)
continue;
}else if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
}else if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
/*
@ -1062,9 +1055,12 @@ bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment
If there is no source item, or the source item is not cookable,
or the furnace is still cooking, or the furnace became overloaded, stop loop.
*/
if(src_item == NULL || !room_available || m_fuel_time < m_fuel_totaltime ||
dst_list->roomForCookedItem(src_item) == false)
{
if (
src_item == NULL
|| !room_available ||
m_fuel_time < m_fuel_totaltime
|| dst_list->roomForCookedItem(src_item) == false
) {
m_step_accumulator = 0;
break;
}
@ -1091,24 +1087,37 @@ bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment
changed = true;
}else{
m_step_accumulator = 0;
if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
}
}
return changed;
}
std::string LockingFurnaceNodeMetadata::getDrawSpecString()
{
return
"size[8,9]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"
"list[current_player;main;0,5;8,4;]";
std::string spec("size[8,9]");
spec += "list[current_name;fuel;2,3;1,1;]";
spec += "ring[2,3;1;#FF0000;";
float v = 0;
if (m_fuel_totaltime > 0.0)
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
spec += itos((int)v);
spec += "]";
spec += "list[current_name;src;2,1;1,1;]";
spec += "list[current_name;dst;5,1;2,2;]";
spec += "list[current_player;main;0,5;8,4;]";
return spec;
}
std::vector<NodeBox> LockingFurnaceNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();
if (m_fuel_time < m_fuel_totaltime) {
boxes.push_back(NodeBox(
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
));
}
return transformNodeBox(n,boxes);
}
bool LockingFurnaceNodeMetadata::import(NodeMetadata *meta)
{
@ -1207,6 +1216,11 @@ IncineratorNodeMetadata::IncineratorNodeMetadata()
m_inventory = new Inventory();
m_inventory->addList("fuel", 1);
m_should_fire = false;
m_step_accumulator = 0;
m_fuel_totaltime = 0;
m_fuel_time = 0;
}
IncineratorNodeMetadata::~IncineratorNodeMetadata()
{
@ -1220,6 +1234,8 @@ NodeMetadata* IncineratorNodeMetadata::clone()
{
IncineratorNodeMetadata *d = new IncineratorNodeMetadata();
*d->m_inventory = *m_inventory;
d->m_fuel_totaltime = m_fuel_totaltime;
d->m_fuel_time = m_fuel_time;
return d;
}
NodeMetadata* IncineratorNodeMetadata::create(std::istream &is)
@ -1227,20 +1243,30 @@ NodeMetadata* IncineratorNodeMetadata::create(std::istream &is)
IncineratorNodeMetadata *d = new IncineratorNodeMetadata();
d->m_inventory->deSerialize(is);
int temp;
is>>temp;
d->m_fuel_totaltime = (float)temp/10;
is>>temp;
d->m_fuel_time = (float)temp/10;
return d;
}
void IncineratorNodeMetadata::serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
os<<itos(m_fuel_totaltime*10)<<" ";
os<<itos(m_fuel_time*10)<<" ";
}
std::wstring IncineratorNodeMetadata::infoText()
{
InventoryList *list = m_inventory->getList("fuel");
InventoryItem *fitem;
if (list && list->getUsedSlots() > 0 && (fitem = list->getItem(0)) != NULL && fitem->isFuel())
if (m_fuel_time < m_fuel_totaltime)
return wgettext("Incinerator is active");
InventoryList *fuel_list = m_inventory->getList("fuel");
if (fuel_list) {
InventoryItem *fuel_item = fuel_list->getItem(0);
if (fuel_item && fuel_item->isFuel())
return wgettext("Incinerator is active");
}
return wgettext("Incinerator is inactive");
}
bool IncineratorNodeMetadata::nodeRemovalDisabled()
@ -1262,32 +1288,113 @@ void IncineratorNodeMetadata::inventoryModified()
bool IncineratorNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
MapNode n = env->getMap().getNodeNoEx(pos);
InventoryList *list = m_inventory->getList("fuel");
InventoryItem *fitem;
if (list && list->getUsedSlots() > 0 && (fitem = list->getItem(0)) != NULL && fitem->isFuel()) {
if (n.getContent() == CONTENT_INCINERATOR) {
n.param1 = n.param2;
n.setContent(CONTENT_INCINERATOR_ACTIVE);
env->setPostStepNodeSwap(pos,n);
return true;
}
}else if (n.getContent() == CONTENT_INCINERATOR_ACTIVE) {
if (n.getContent() == CONTENT_INCINERATOR_ACTIVE) {
n.param2 = n.param1;
n.setContent(CONTENT_INCINERATOR);
env->setPostStepNodeSwap(pos,n);
return true;
}
return false;
if (dtime > 60.0)
infostream<<"Incinerator stepping a long time ("<<dtime<<")"<<std::endl;
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
while(m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
/*
If fuel is burning, increment the burn counters.
*/
if (m_fuel_time < m_fuel_totaltime) {
m_fuel_time += dtime;
changed = true;
// If the fuel was not used up this step, just keep burning it
if (m_fuel_time < m_fuel_totaltime)
continue;
}
/*
If the furnace is still cooking, stop loop.
*/
if (m_fuel_time < m_fuel_totaltime) {
m_step_accumulator = 0;
break;
}
if (!m_should_fire) {
m_step_accumulator = 0;
break;
}
//infostream<<"Furnace is out of fuel"<<std::endl;
InventoryList *fuel_list = m_inventory->getList("fuel");
assert(fuel_list);
InventoryItem *fuel_item = fuel_list->getItem(0);
if (fuel_item && fuel_item->isFuel()) {
if ((fuel_item->getContent()&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
m_fuel_totaltime = ((CraftItem*)fuel_item)->getFuelTime();
}else if ((fuel_item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
m_fuel_totaltime = ((ToolItem*)fuel_item)->getFuelTime();
}else{
m_fuel_totaltime = ((MaterialItem*)fuel_item)->getFuelTime();
}
m_fuel_time = 0;
content_t c = fuel_item->getContent();
fuel_list->decrementMaterials(1);
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
}
m_should_fire = false;
changed = true;
}else{
m_step_accumulator = 0;
}
}
return changed;
}
std::string IncineratorNodeMetadata::getDrawSpecString()
{
return
std::string("size[8,7]"
"label[1,0.5;")+gettext("Add fuel, then punch to incinerate wielded item")+"]"
"label[3.5,1.5;Fuel]"
"list[current_name;fuel;4,1;1,1;]"
"list[current_player;main;0,3;8,4;]";
std::string spec("size[8,7]");
spec += "label[1,0.5;";
spec += gettext("Add fuel, then punch to incinerate wielded item");
spec += "]";
spec += "label[3,1.5;Fuel]";
spec += "list[current_name;fuel;4,1;1,1;]";
spec += "ring[4,1;1;#FF0000;";
float v = 0;
if (m_fuel_totaltime > 0.0)
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
spec += itos((int)v);
spec += "]";
spec += "list[current_player;main;0,3;8,4;]";
return spec;
}
std::vector<NodeBox> IncineratorNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();
InventoryList *list = m_inventory->getList("fuel");
InventoryItem *fitem;
if (
(
m_fuel_time < m_fuel_totaltime
) || (
list
&& list->getUsedSlots() > 0
&& (fitem = list->getItem(0)) != NULL
&& fitem->isFuel()
)
) {
boxes.push_back(NodeBox(
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
));
}
return transformNodeBox(n,boxes);
}
/*
@ -2560,7 +2667,8 @@ std::string BookShelfNodeMetadata::getDrawSpecString()
"list[current_name;0;0.5,0;7,2;]"
"list[current_player;main;0,3;8,4;]";
}
std::vector<NodeBox> BookShelfNodeMetadata::getNodeBoxes(MapNode &n) {
std::vector<NodeBox> BookShelfNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();

View File

@ -254,6 +254,7 @@ public:
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString();
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
virtual bool import(NodeMetadata *meta);
@ -282,6 +283,7 @@ public:
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString();
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
virtual bool import(NodeMetadata *meta);
@ -339,9 +341,15 @@ public:
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString();
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
bool m_should_fire;
float m_fuel_totaltime;
float m_fuel_time;
private:
Inventory *m_inventory;
float m_step_accumulator;
};

View File

@ -786,6 +786,7 @@ void content_toolitem_init()
f->hardness = 700.;
f->dig_time = 0.2;
f->level = 5;
f->has_punch_effect = false;
crafting::setPickRecipe(CONTENT_CRAFTITEM_MITHRIL,CONTENT_TOOLITEM_MITHRIL_PICK);
lists::add("craftguide",i);

View File

@ -118,22 +118,19 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
/* Convert m_init_draw_spec to m_inventorylists */
m_inventorylists.clear();
m_rings.clear();
m_images.clear();
m_fields.clear();
Strfnd f(m_formspec_string);
while(f.atend() == false)
{
while (f.atend() == false) {
std::string type = trim(f.next("["));
if(type == "invsize" || type == "size")
{
if (type == "invsize" || type == "size") {
v2f invsize;
invsize.X = mystof(f.next(","));
if(type == "size")
{
if (type == "size") {
invsize.Y = mystof(f.next("]"));
}
else{
}else{
invsize.Y = mystof(f.next(";"));
errorstream<<"WARNING: invsize is deprecated, use size"<<std::endl;
f.next("]");
@ -157,15 +154,14 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
recalculateAbsolutePosition(false);
basepos = getBasePos();
bp_set = 2;
}
else if(type == "list")
{
}else if (type == "list") {
std::string name = f.next(";");
InventoryLocation loc;
if(name == "context" || name == "current_name")
if (name == "context" || name == "current_name") {
loc = m_current_inventory_location;
else
}else{
loc.deSerialize(name);
}
std::string listname = f.next(";");
v2s32 pos = basepos;
pos.X += mystof(f.next(",")) * (float)spacing.X;
@ -197,12 +193,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
<<", pos=("<<pos.X<<","<<pos.Y<<")"
<<", geom=("<<geom.X<<","<<geom.Y<<")"
<<std::endl;
if(bp_set != 2)
if (bp_set != 2)
errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl;
m_inventorylists.push_back(ListDrawSpec(loc, listname, bg, pos, geom, i_start, i_end));
}
else if(type == "image")
{
}else if (type == "image") {
v2s32 pos = basepos;
pos.X += mystof(f.next(",")) * (float)spacing.X;
pos.Y += mystof(f.next(";")) * (float)spacing.Y;
@ -214,12 +208,23 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
<<", pos=("<<pos.X<<","<<pos.Y<<")"
<<", geom=("<<geom.X<<","<<geom.Y<<")"
<<std::endl;
if(bp_set != 2)
if (bp_set != 2)
errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
m_images.push_back(ImageDrawSpec(name, pos, geom));
}
else if(type == "field")
{
}else if (type == "ring") {
v2s32 pos = basepos;
pos.X += mystof(f.next(",")) * (float)spacing.X;
pos.Y += mystof(f.next(";")) * (float)spacing.Y;
int rad = mystof(f.next(";")) * (float)imgsize.Y;
pos.X += rad/2;
pos.Y += rad/2;
std::string c = f.next(";");
int val = mystoi(f.next("]"));
video::SColor col;
if (!parseColorString(c,col,true))
col = video::SColor(255,255,0,0);
m_rings.push_back(RingDrawSpec(col,val,pos,rad));
}else if (type == "field") {
std::string fname = f.next(";");
std::string flabel = f.next(";");
bool multi = false;
@ -337,9 +342,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
m_fields.push_back(spec);
}
else if(type == "label")
{
}else if (type == "label") {
v2s32 pos;
pos.X = mystof(f.next(",")) * (float)spacing.X;
pos.Y = mystof(f.next(";")) * (float)spacing.Y;
@ -347,7 +350,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
rect = core::rect<s32>(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15));
std::string flabel = f.next("]");
if(bp_set != 2)
if (bp_set != 2)
errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
@ -358,9 +361,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
);
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid);
m_fields.push_back(spec);
}
else if(type == "button" || type == "button_exit")
{
}else if (type == "button" || type == "button_exit") {
v2s32 pos;
pos.X = mystof(f.next(",")) * (float)spacing.X;
pos.Y = mystof(f.next(";")) * (float)spacing.Y;
@ -372,7 +373,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
std::string fname = f.next(";");
std::string flabel = f.next("]");
if(bp_set != 2)
if (bp_set != 2)
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
@ -386,9 +387,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
spec.is_exit = true;
Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
m_fields.push_back(spec);
}
else if(type == "image_button" || type == "image_button_exit")
{
}else if (type == "image_button" || type == "image_button_exit") {
v2s32 pos;
pos.X = mystof(f.next(",")) * (float)spacing.X;
pos.Y = mystof(f.next(";")) * (float)spacing.Y;
@ -401,7 +400,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
std::string fimage = f.next(";");
std::string fname = f.next(";");
std::string flabel = f.next("]");
if(bp_set != 2)
if (bp_set != 2)
errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
@ -421,9 +420,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
e->setScaleImage(true);
m_fields.push_back(spec);
}
else
{
}else{
// Ignore others
std::string ts = f.next("]");
infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
@ -432,8 +429,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
// If there's inventory, put the usage string at the bottom
if (m_inventorylists.size())
{
if (m_inventorylists.size()) {
core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
size.Y-rect.getHeight()-5);
@ -441,8 +437,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(text, rect, false, true, this, 256);
}
// If there's fields, add a Proceed button
if (m_fields.size() && bp_set != 2)
{
if (m_fields.size() && bp_set != 2) {
// if the size wasn't set by an invsize[] or size[] adjust it now to fit all the fields
rect = core::rect<s32>(
screensize.X/2 - 160,
@ -609,25 +604,41 @@ void GUIFormSpecMenu::drawMenu()
Phase 1: Item images; prepare tooltip
*/
for(u32 i=0; i<m_inventorylists.size(); i++)
{
for (u32 i=0; i<m_rings.size(); i++) {
draw_progress_ring(
driver,
v2s32(m_screensize_old.X,m_screensize_old.Y),
m_rings[i].pos,
m_rings[i].rad,
m_rings[i].value,
m_rings[i].colour
);
}
for (u32 i=0; i<m_inventorylists.size(); i++) {
drawList(m_inventorylists[i], 1);
}
for(u32 i=0; i<m_images.size(); i++)
{
for (u32 i=0; i<m_images.size(); i++) {
const ImageDrawSpec &spec = m_images[i];
video::ITexture *texture = Environment->getVideoDriver()->getTexture(getTexturePath(spec.name).c_str());
video::ITexture *texture = driver->getTexture(getTexturePath(spec.name).c_str());
// Image size on screen
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
// Image rectangle on screen
core::rect<s32> rect = imgrect + spec.pos;
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
driver->draw2DImage(texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
driver->draw2DImage(
texture,
rect,
core::rect<s32>(
core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())
),
NULL,
colors,
true
);
}
/*

View File

@ -121,6 +121,24 @@ class GUIFormSpecMenu : public GUIModalMenu
v2s32 geom;
};
struct RingDrawSpec
{
RingDrawSpec()
{
}
RingDrawSpec(video::SColor &a_color, int value, v2s32 a_pos, int a_rad):
colour(a_color),
value(value),
pos(a_pos),
rad(a_rad)
{
}
video::SColor colour;
int value;
v2s32 pos;
int rad;
};
struct FieldSpec
{
FieldSpec()
@ -198,6 +216,7 @@ protected:
core::array<ListDrawSpec> m_inventorylists;
core::array<ImageDrawSpec> m_images;
core::array<RingDrawSpec> m_rings;
core::array<FieldSpec> m_fields;
ItemSpec *m_selected_item;

View File

@ -2866,7 +2866,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
SendInventory(player->peer_id);
}
}
}else if (selected_content == CONTENT_INCINERATOR_ACTIVE) {
}else if (selected_content == CONTENT_INCINERATOR) {
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
if (!meta)
return;
@ -2874,27 +2874,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
InventoryList *plist = player->inventory.getList("main");
if (plist == NULL || ilist == NULL)
return;
InventoryItem *fitem = ilist->getItem(0);
if (!fitem || !fitem->getCount() || !fitem->isFuel())
return;
if (((IncineratorNodeMetadata*)meta)->m_fuel_totaltime <= ((IncineratorNodeMetadata*)meta)->m_fuel_time) {
InventoryItem *fitem = ilist->getItem(0);
if (!fitem || !fitem->getCount() || !fitem->isFuel())
return;
((IncineratorNodeMetadata*)meta)->m_should_fire = true;
}
plist->deleteItem(item_i);
UpdateCrafting(peer_id);
SendInventory(peer_id);
if (fitem->getCount() == 1) {
content_t c = fitem->getContent();
ilist->deleteItem(0);
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA)
ilist->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
}else{
fitem->remove(1);
}
v3s16 blockpos = getNodeBlockPos(p_under);
meta->inventoryModified();
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
if(block)
block->raiseModified(MOD_STATE_WRITE_NEEDED);
setBlockNotSent(blockpos);
}else if (
selected_node_features.draw_type != CDT_TORCHLIKE
&& wielded_tool_features.has_rotate_effect

View File

@ -928,7 +928,7 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color
if (alpha_pos != std::string::npos) {
color_name = value.substr(0, alpha_pos);
alpha_string = value.substr(alpha_pos + 1);
} else {
}else{
color_name = value;
}
@ -953,11 +953,13 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color
return false;
unsigned char d1, d2;
if (!hex_digit_decode(alpha_string.at(0), d1)
|| !hex_digit_decode(alpha_string.at(1), d2))
if (
!hex_digit_decode(alpha_string.at(0), d1)
|| !hex_digit_decode(alpha_string.at(1), d2)
)
return false;
color_temp |= ((d1 & 0xf) << 4 | (d2 & 0xf)) << 24;
} else {
}else{
color_temp |= 0xff << 24; // Fully opaque
}
@ -970,10 +972,11 @@ bool parseColorString(const std::string &value, video::SColor &color, bool quiet
{
bool success;
if (value[0] == '#')
if (value[0] == '#') {
success = parseHexColorString(value, color);
else
}else{
success = parseNamedColorString(value, color);
}
if (!success && !quiet)
errorstream << "Invalid color: \"" << value << "\"" << std::endl;

View File

@ -41,6 +41,7 @@ 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);
bool parseColorString(const std::string &value, video::SColor &color, bool quiet);
/*
Specifies a texture in an atlas.