implement active furnaces/incinerators

This commit is contained in:
darkrose 2014-10-24 05:04:25 +10:00
parent ea517a722f
commit 19f5561c81
10 changed files with 183 additions and 26 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 737 B

View File

@ -69,7 +69,9 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
#define CONTENT_LOCKABLE_SIGN 23
#define CONTENT_LOCKABLE_SIGN_UD 24
#define CONTENT_CREATIVE_CHEST 25
// FREE 26-29
#define CONTENT_FURNACE_ACTIVE 26
#define CONTENT_LOCKABLE_FURNACE_ACTIVE 27
// FREE 28-29
#define CONTENT_RAIL 30
// deprecated, just here for backwards compat
#define CONTENT_LADDER_LEGACY 31
@ -529,6 +531,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
#define CONTENT_WOOD_PINE 0xC08
#define CONTENT_CONIFER_TREE 0xC09
#define CONTENT_LIFE_SUPPORT 0xC0A
#define CONTENT_INCINERATOR_ACTIVE 0xC0B
// FREE C0B-C0F
// beds
#define CONTENT_BED_HEAD 0xC10

View File

@ -1187,6 +1187,24 @@ void content_mapnode_special(bool repeat)
lists::add("craftguide",i);
lists::add("creative",i);
i = CONTENT_FURNACE_ACTIVE;
f = &content_features(i);
f->description = wgettext("Furnace");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->light_source = LIGHT_MAX/2;
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->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_FURNACE)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new FurnaceNodeMetadata();
f->type = CMT_STONE;
f->hardness = 3.0;
f->pressure_type = CST_SOLID;
i = CONTENT_LOCKABLE_FURNACE;
f = &content_features(i);
f->description = wgettext("Locking Furnace");
@ -1208,6 +1226,23 @@ void content_mapnode_special(bool repeat)
lists::add("craftguide",i);
lists::add("creative",i);
i = CONTENT_LOCKABLE_FURNACE_ACTIVE;
f = &content_features(i);
f->description = wgettext("Locking Furnace");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->light_source = LIGHT_MAX/2;
f->setAllTextures("furnace_side.png");
f->setTexture(0, "furnace_top.png");
f->setTexture(1, "furnace_top.png");
f->setTexture(5, "furnace_lock_active.png"); // Z-
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_LOCKABLE_FURNACE)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new LockingFurnaceNodeMetadata();
f->type = CMT_STONE;
f->hardness = 3.0;
f->pressure_type = CST_SOLID;
i = CONTENT_INCINERATOR;
f = &content_features(i);
f->description = wgettext("Incinerator");
@ -1228,6 +1263,22 @@ void content_mapnode_special(bool repeat)
lists::add("craftguide",i);
lists::add("creative",i);
i = CONTENT_INCINERATOR_ACTIVE;
f = &content_features(i);
f->description = wgettext("Incinerator");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->setAllTextures("incinerator_side.png");
f->setTexture(0, "incinerator_top.png"); // Z-
f->setTexture(1, "incinerator_top.png"); // Z-
f->setTexture(5, "incinerator_front_active.png"); // Z-
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_INCINERATOR)+" 1";
if (f->initial_metadata == NULL)
f->initial_metadata = new IncineratorNodeMetadata();
f->type = CMT_STONE;
f->hardness = 0.4;
f->pressure_type = CST_SOLID;
i = CONTENT_NC;
f = &content_features(i);
f->description = wgettext("Nyan Cat");

View File

@ -482,6 +482,10 @@ NodeMetadata* FurnaceNodeMetadata::clone()
{
FurnaceNodeMetadata *d = new FurnaceNodeMetadata();
*d->m_inventory = *m_inventory;
d->m_fuel_totaltime = m_fuel_totaltime;
d->m_fuel_time = m_fuel_time;
d->m_src_totaltime = m_src_totaltime;
d->m_src_time = m_src_time;
return d;
}
NodeMetadata* FurnaceNodeMetadata::create(std::istream &is)
@ -564,8 +568,8 @@ bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
while(m_step_accumulator > interval)
{
MapNode n = env->getMap().getNodeNoEx(pos);
while (m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
@ -597,6 +601,10 @@ 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.setContent(CONTENT_FURNACE_ACTIVE);
env->setPostStepNodeSwap(pos,n);
}
//infostream<<"Furnace is active"<<std::endl;
m_fuel_time += dtime;
m_src_time += dtime;
@ -610,8 +618,15 @@ 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.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_FURNACE_ACTIVE) {
n.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
/*
@ -623,9 +638,12 @@ bool FurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
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;
}
@ -652,6 +670,11 @@ 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.setContent(CONTENT_FURNACE);
env->setPostStepNodeSwap(pos,n);
}
}
}
return changed;
@ -709,6 +732,10 @@ NodeMetadata* LockingFurnaceNodeMetadata::clone()
{
LockingFurnaceNodeMetadata *d = new LockingFurnaceNodeMetadata();
*d->m_inventory = *m_inventory;
d->m_fuel_totaltime = m_fuel_totaltime;
d->m_fuel_time = m_fuel_time;
d->m_src_totaltime = m_src_totaltime;
d->m_src_time = m_src_time;
return d;
}
NodeMetadata* LockingFurnaceNodeMetadata::create(std::istream &is)
@ -795,14 +822,14 @@ void LockingFurnaceNodeMetadata::inventoryModified()
}
bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
if(dtime > 60.0)
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;
while(m_step_accumulator > interval)
{
MapNode n = env->getMap().getNodeNoEx(pos);
while(m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
@ -843,6 +870,11 @@ 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.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;
@ -856,8 +888,17 @@ 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.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
}else if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
/*
@ -898,6 +939,11 @@ bool LockingFurnaceNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment
changed = true;
}else{
m_step_accumulator = 0;
if (n.getContent() == CONTENT_LOCKABLE_FURNACE_ACTIVE) {
n.setContent(CONTENT_LOCKABLE_FURNACE);
env->setPostStepNodeSwap(pos,n);
changed = true;
}
}
}
return changed;
@ -1058,6 +1104,25 @@ void IncineratorNodeMetadata::inventoryModified()
{
infostream<<"Incinerator inventory modification callback"<<std::endl;
}
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.setContent(CONTENT_INCINERATOR_ACTIVE);
env->setPostStepNodeSwap(pos,n);
return true;
}
}else if (n.getContent() == CONTENT_INCINERATOR_ACTIVE) {
n.setContent(CONTENT_INCINERATOR);
env->setPostStepNodeSwap(pos,n);
return true;
}
return false;
}
std::string IncineratorNodeMetadata::getDrawSpecString()
{
return
@ -2825,7 +2890,7 @@ bool DoorNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *en
content_t c = n.getContent();
if ((c&CONTENT_DOOR_OPEN_MASK) == CONTENT_DOOR_OPEN_MASK) {
n.setContent(n.getContent()&~CONTENT_DOOR_OPEN_MASK);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
return true;
}
return false;
@ -2837,7 +2902,7 @@ bool DoorNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *en
content_t c = n.getContent();
if ((c&CONTENT_DOOR_OPEN_MASK) != CONTENT_DOOR_OPEN_MASK) {
n.setContent(n.getContent()|CONTENT_DOOR_OPEN_MASK);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}
if (m_ptime < 0.3)
@ -2919,6 +2984,9 @@ NodeMetadata* PistonNodeMetadata::create(std::istream &is)
NodeMetadata* PistonNodeMetadata::clone()
{
PistonNodeMetadata *d = new PistonNodeMetadata();
d->m_energy = m_energy;
d->m_ptime = m_ptime;
d->m_sources = m_sources;
return d;
}
void PistonNodeMetadata::serializeBody(std::ostream &os)
@ -2950,19 +3018,19 @@ bool PistonNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *
dir = v3s16(1,0,0);
}
n.setContent(CONTENT_CIRCUIT_PISTON_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,false,env);
return true;
}else if (n.getContent() == CONTENT_CIRCUIT_PISTON_UP) {
dir = v3s16(0,1,0);
n.setContent(CONTENT_CIRCUIT_PISTON_UP_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,false,env);
return true;
}else if (n.getContent() == CONTENT_CIRCUIT_PISTON_DOWN) {
dir = v3s16(0,-1,0);
n.setContent(CONTENT_CIRCUIT_PISTON_DOWN_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,false,env);
return true;
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON) {
@ -2976,19 +3044,19 @@ bool PistonNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *
dir = v3s16(1,0,0);
}
n.setContent(CONTENT_CIRCUIT_STICKYPISTON_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,true,env);
return true;
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON_UP) {
dir = v3s16(0,1,0);
n.setContent(CONTENT_CIRCUIT_STICKYPISTON_UP_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,true,env);
return true;
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON_DOWN) {
dir = v3s16(0,-1,0);
n.setContent(CONTENT_CIRCUIT_STICKYPISTON_DOWN_OFF);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
contract(pos,dir,true,env);
return true;
}
@ -3008,19 +3076,19 @@ bool PistonNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *
}
if (extend(pos,dir,CONTENT_CIRCUIT_PISTON_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_PISTON);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_CIRCUIT_PISTON_UP_OFF) {
dir = v3s16(0,1,0);
if (extend(pos,dir,CONTENT_CIRCUIT_PISTON_UP_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_PISTON_UP);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_CIRCUIT_PISTON_DOWN_OFF) {
dir = v3s16(0,-1,0);
if (extend(pos,dir,CONTENT_CIRCUIT_PISTON_DOWN_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_PISTON_DOWN);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON_OFF) {
if (dir == v3s16(1,1,1)) {
@ -3034,19 +3102,19 @@ bool PistonNodeMetadata::stepCircuit(float dtime, v3s16 pos, ServerEnvironment *
}
if (extend(pos,dir,CONTENT_CIRCUIT_STICKYPISTON_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_STICKYPISTON);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON_UP_OFF) {
dir = v3s16(0,1,0);
if (extend(pos,dir,CONTENT_CIRCUIT_STICKYPISTON_UP_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_STICKYPISTON_UP);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}else if (n.getContent() == CONTENT_CIRCUIT_STICKYPISTON_DOWN_OFF) {
dir = v3s16(0,-1,0);
if (extend(pos,dir,CONTENT_CIRCUIT_STICKYPISTON_DOWN_ARM,env)) {
n.setContent(CONTENT_CIRCUIT_STICKYPISTON_DOWN);
env->getMap().addNodeWithEvent(pos,n);
env->setPostStepNodeSwap(pos,n);
}
}
}

View File

@ -286,6 +286,7 @@ public:
virtual std::string infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual void inventoryModified();
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString();

View File

@ -883,6 +883,8 @@ void ServerEnvironment::step(float dtime)
bool blockchanged = false;
m_poststep_nodeswaps.clear();
if (circuitstep) {
// Run node metadata
bool changed = block->m_node_metadata.stepCircuit(circuit_dtime, block->getPosRelative(), this);
@ -906,6 +908,34 @@ void ServerEnvironment::step(float dtime)
block->setChangedFlag();
}
if (m_poststep_nodeswaps.size() > 0) {
for (std::map<v3s16,MapNode>::iterator i = m_poststep_nodeswaps.begin(); i != m_poststep_nodeswaps.end(); i++) {
v3s16 p = i->first;
MapNode n = i->second;
NodeMetadata *meta = NULL;
std::string n_owner = "";
std::string i_owner = "";
meta = m_map->getNodeMetadata(p);
if (meta) {
n_owner = meta->getOwner();
i_owner = meta->getInventoryOwner();
meta = meta->clone();
}
m_map->addNodeWithEvent(p, n);
if (meta) {
m_map->setNodeMetadata(p,meta);
meta = m_map->getNodeMetadata(p);
if (meta) {
if (n_owner != "")
meta->setOwner(n_owner);
if (i_owner != "")
meta->setInventoryOwner(i_owner);
}
}
}
m_poststep_nodeswaps.clear();
}
if (!nodestep)
continue;

View File

@ -246,6 +246,8 @@ public:
return searchNearInv(pos,-radius,radius,search,found);
}
void setPostStepNodeSwap(v3s16 pos, MapNode n) {m_poststep_nodeswaps[pos] = n;}
private:
/*
@ -294,6 +296,8 @@ private:
ServerMap *m_map;
// Pointer to server (which is handling this environment)
Server *m_server;
// used by node/circuit step to swap a node after stepping is complete
std::map<v3s16,MapNode>m_poststep_nodeswaps;
// Active object list
std::map<u16, ServerActiveObject*> m_active_objects;
// Outgoing network message buffer for active objects

View File

@ -2744,7 +2744,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
meta->energise(energy,p_under,p_under,p_under);
}
}
}else if (n.getContent() == CONTENT_INCINERATOR) {
}else if (n.getContent() == CONTENT_INCINERATOR_ACTIVE) {
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
if (!meta)
return;