forked from Mirrorlandia_minetest/minetest
WIP node metadata, node timers
This commit is contained in:
parent
67059e1932
commit
704782c95b
@ -177,6 +177,7 @@ set(common_SRCS
|
|||||||
content_mapnode.cpp
|
content_mapnode.cpp
|
||||||
collision.cpp
|
collision.cpp
|
||||||
nodemetadata.cpp
|
nodemetadata.cpp
|
||||||
|
nodetimer.cpp
|
||||||
serverobject.cpp
|
serverobject.cpp
|
||||||
noise.cpp
|
noise.cpp
|
||||||
porting.cpp
|
porting.cpp
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Minetest-c55
|
Minetest-c55
|
||||||
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -18,15 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "content_nodemeta.h"
|
#include "content_nodemeta.h"
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "craftdef.h"
|
|
||||||
#include "gamedef.h"
|
|
||||||
|
|
||||||
class Inventory;
|
|
||||||
|
|
||||||
#define NODEMETA_GENERIC 1
|
#define NODEMETA_GENERIC 1
|
||||||
#define NODEMETA_SIGN 14
|
#define NODEMETA_SIGN 14
|
||||||
@ -34,809 +28,149 @@ class Inventory;
|
|||||||
#define NODEMETA_FURNACE 16
|
#define NODEMETA_FURNACE 16
|
||||||
#define NODEMETA_LOCKABLE_CHEST 17
|
#define NODEMETA_LOCKABLE_CHEST 17
|
||||||
|
|
||||||
core::map<u16, NodeMetadata::Factory> NodeMetadata::m_types;
|
// Returns true if node timer must be set
|
||||||
core::map<std::string, NodeMetadata::Factory2> NodeMetadata::m_names;
|
static bool content_nodemeta_deserialize_legacy_body(
|
||||||
|
std::istream &is, s16 id, NodeMetadata *meta)
|
||||||
class SignNodeMetadata : public NodeMetadata
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SignNodeMetadata(IGameDef *gamedef, std::string text);
|
|
||||||
//~SignNodeMetadata();
|
|
||||||
|
|
||||||
virtual u16 typeId() const;
|
|
||||||
virtual const char* typeName() const
|
|
||||||
{ return "sign"; }
|
|
||||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
|
||||||
static NodeMetadata* create(IGameDef *gamedef);
|
|
||||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
|
||||||
virtual void serializeBody(std::ostream &os);
|
|
||||||
virtual std::string infoText();
|
|
||||||
|
|
||||||
virtual bool allowsTextInput(){ return true; }
|
|
||||||
virtual std::string getText(){ return m_text; }
|
|
||||||
virtual void setText(const std::string &t){ m_text = t; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_text;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ChestNodeMetadata : public NodeMetadata
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ChestNodeMetadata(IGameDef *gamedef);
|
|
||||||
~ChestNodeMetadata();
|
|
||||||
|
|
||||||
virtual u16 typeId() const;
|
|
||||||
virtual const char* typeName() const
|
|
||||||
{ return "chest"; }
|
|
||||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
|
||||||
static NodeMetadata* create(IGameDef *gamedef);
|
|
||||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
|
||||||
virtual void serializeBody(std::ostream &os);
|
|
||||||
virtual std::string infoText();
|
|
||||||
virtual Inventory* getInventory() {return m_inventory;}
|
|
||||||
virtual bool nodeRemovalDisabled();
|
|
||||||
virtual std::string getInventoryDrawSpecString();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Inventory *m_inventory;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LockingChestNodeMetadata : public NodeMetadata
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LockingChestNodeMetadata(IGameDef *gamedef);
|
|
||||||
~LockingChestNodeMetadata();
|
|
||||||
|
|
||||||
virtual u16 typeId() const;
|
|
||||||
virtual const char* typeName() const
|
|
||||||
{ return "locked_chest"; }
|
|
||||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
|
||||||
static NodeMetadata* create(IGameDef *gamedef);
|
|
||||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
|
||||||
virtual void serializeBody(std::ostream &os);
|
|
||||||
virtual std::string infoText();
|
|
||||||
virtual Inventory* getInventory() {return m_inventory;}
|
|
||||||
virtual bool nodeRemovalDisabled();
|
|
||||||
virtual std::string getInventoryDrawSpecString();
|
|
||||||
|
|
||||||
virtual std::string getOwner(){ return m_text; }
|
|
||||||
virtual void setOwner(std::string t){ m_text = t; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Inventory *m_inventory;
|
|
||||||
std::string m_text;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FurnaceNodeMetadata : public NodeMetadata
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FurnaceNodeMetadata(IGameDef *gamedef);
|
|
||||||
~FurnaceNodeMetadata();
|
|
||||||
|
|
||||||
virtual u16 typeId() const;
|
|
||||||
virtual const char* typeName() const
|
|
||||||
{ return "furnace"; }
|
|
||||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
|
||||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
|
||||||
static NodeMetadata* create(IGameDef *gamedef);
|
|
||||||
virtual void serializeBody(std::ostream &os);
|
|
||||||
virtual std::string infoText();
|
|
||||||
virtual Inventory* getInventory() {return m_inventory;}
|
|
||||||
virtual void inventoryModified();
|
|
||||||
virtual bool step(float dtime);
|
|
||||||
virtual bool nodeRemovalDisabled();
|
|
||||||
virtual std::string getInventoryDrawSpecString();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool getCookResult(bool remove, std::string &cookresult, float &cooktime);
|
|
||||||
bool getBurnResult(bool remove, float &burntime);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Inventory *m_inventory;
|
|
||||||
std::string m_infotext;
|
|
||||||
float m_step_accumulator;
|
|
||||||
float m_fuel_totaltime;
|
|
||||||
float m_fuel_time;
|
|
||||||
float m_src_totaltime;
|
|
||||||
float m_src_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
SignNodeMetadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
SignNodeMetadata proto_SignNodeMetadata(NULL, "");
|
|
||||||
|
|
||||||
SignNodeMetadata::SignNodeMetadata(IGameDef *gamedef, std::string text):
|
|
||||||
NodeMetadata(gamedef),
|
|
||||||
m_text(text)
|
|
||||||
{
|
|
||||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
|
||||||
}
|
|
||||||
u16 SignNodeMetadata::typeId() const
|
|
||||||
{
|
|
||||||
return NODEMETA_SIGN;
|
|
||||||
}
|
|
||||||
NodeMetadata* SignNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
std::string text = deSerializeString(is);
|
|
||||||
return new SignNodeMetadata(gamedef, text);
|
|
||||||
}
|
|
||||||
NodeMetadata* SignNodeMetadata::create(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
return new SignNodeMetadata(gamedef, "");
|
|
||||||
}
|
|
||||||
NodeMetadata* SignNodeMetadata::clone(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
return new SignNodeMetadata(gamedef, m_text);
|
|
||||||
}
|
|
||||||
void SignNodeMetadata::serializeBody(std::ostream &os)
|
|
||||||
{
|
|
||||||
os<<serializeString(m_text);
|
|
||||||
}
|
|
||||||
std::string SignNodeMetadata::infoText()
|
|
||||||
{
|
|
||||||
return std::string("\"")+m_text+"\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ChestNodeMetadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
ChestNodeMetadata proto_ChestNodeMetadata(NULL);
|
|
||||||
|
|
||||||
ChestNodeMetadata::ChestNodeMetadata(IGameDef *gamedef):
|
|
||||||
NodeMetadata(gamedef)
|
|
||||||
{
|
|
||||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
|
||||||
m_inventory = NULL;
|
|
||||||
}
|
|
||||||
ChestNodeMetadata::~ChestNodeMetadata()
|
|
||||||
{
|
{
|
||||||
delete m_inventory;
|
meta->clear();
|
||||||
}
|
|
||||||
u16 ChestNodeMetadata::typeId() const
|
|
||||||
{
|
|
||||||
return NODEMETA_CHEST;
|
|
||||||
}
|
|
||||||
NodeMetadata* ChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->deSerialize(is);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* ChestNodeMetadata::create(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->addList("0", 8*4);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* ChestNodeMetadata::clone(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(*m_inventory);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
void ChestNodeMetadata::serializeBody(std::ostream &os)
|
|
||||||
{
|
|
||||||
m_inventory->serialize(os);
|
|
||||||
}
|
|
||||||
std::string ChestNodeMetadata::infoText()
|
|
||||||
{
|
|
||||||
return "Chest";
|
|
||||||
}
|
|
||||||
bool ChestNodeMetadata::nodeRemovalDisabled()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Disable removal if chest contains something
|
|
||||||
*/
|
|
||||||
InventoryList *list = m_inventory->getList("0");
|
|
||||||
if(list == NULL)
|
|
||||||
return false;
|
|
||||||
if(list->getUsedSlots() == 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
std::string ChestNodeMetadata::getInventoryDrawSpecString()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"invsize[8,9;]"
|
|
||||||
"list[current_name;0;0,0;8,4;]"
|
|
||||||
"list[current_player;main;0,5;8,4;]";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
LockingChestNodeMetadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev)
|
||||||
LockingChestNodeMetadata proto_LockingChestNodeMetadata(NULL);
|
|
||||||
|
|
||||||
LockingChestNodeMetadata::LockingChestNodeMetadata(IGameDef *gamedef):
|
|
||||||
NodeMetadata(gamedef)
|
|
||||||
{
|
|
||||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
|
||||||
m_inventory = NULL;
|
|
||||||
}
|
|
||||||
LockingChestNodeMetadata::~LockingChestNodeMetadata()
|
|
||||||
{
|
|
||||||
delete m_inventory;
|
|
||||||
}
|
|
||||||
u16 LockingChestNodeMetadata::typeId() const
|
|
||||||
{
|
|
||||||
return NODEMETA_LOCKABLE_CHEST;
|
|
||||||
}
|
|
||||||
NodeMetadata* LockingChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
|
||||||
d->setOwner(deSerializeString(is));
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->deSerialize(is);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* LockingChestNodeMetadata::create(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->addList("0", 8*4);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* LockingChestNodeMetadata::clone(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(*m_inventory);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
void LockingChestNodeMetadata::serializeBody(std::ostream &os)
|
|
||||||
{
|
|
||||||
os<<serializeString(m_text);
|
|
||||||
m_inventory->serialize(os);
|
|
||||||
}
|
|
||||||
std::string LockingChestNodeMetadata::infoText()
|
|
||||||
{
|
{
|
||||||
return "Locking Chest";
|
meta->getInventory()->deSerialize(is);
|
||||||
}
|
deSerializeLongString(is); // m_text
|
||||||
bool LockingChestNodeMetadata::nodeRemovalDisabled()
|
deSerializeString(is); // m_owner
|
||||||
{
|
|
||||||
/*
|
|
||||||
Disable removal if chest contains something
|
|
||||||
*/
|
|
||||||
InventoryList *list = m_inventory->getList("0");
|
|
||||||
if(list == NULL)
|
|
||||||
return false;
|
|
||||||
if(list->getUsedSlots() == 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
std::string LockingChestNodeMetadata::getInventoryDrawSpecString()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"invsize[8,9;]"
|
|
||||||
"list[current_name;0;0,0;8,4;]"
|
|
||||||
"list[current_player;main;0,5;8,4;]";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
FurnaceNodeMetadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Prototype
|
|
||||||
FurnaceNodeMetadata proto_FurnaceNodeMetadata(NULL);
|
|
||||||
|
|
||||||
FurnaceNodeMetadata::FurnaceNodeMetadata(IGameDef *gamedef):
|
|
||||||
NodeMetadata(gamedef)
|
|
||||||
{
|
|
||||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
|
||||||
|
|
||||||
m_inventory = NULL;
|
|
||||||
|
|
||||||
m_infotext = "Furnace is inactive";
|
|
||||||
|
|
||||||
m_step_accumulator = 0;
|
|
||||||
m_fuel_totaltime = 0;
|
|
||||||
m_fuel_time = 0;
|
|
||||||
m_src_totaltime = 0;
|
|
||||||
m_src_time = 0;
|
|
||||||
}
|
|
||||||
FurnaceNodeMetadata::~FurnaceNodeMetadata()
|
|
||||||
{
|
|
||||||
delete m_inventory;
|
|
||||||
}
|
|
||||||
u16 FurnaceNodeMetadata::typeId() const
|
|
||||||
{
|
|
||||||
return NODEMETA_FURNACE;
|
|
||||||
}
|
|
||||||
NodeMetadata* FurnaceNodeMetadata::clone(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(m_gamedef);
|
|
||||||
d->m_inventory = new Inventory(*m_inventory);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
|
|
||||||
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->deSerialize(is);
|
|
||||||
|
|
||||||
int temp = 0;
|
|
||||||
is>>temp;
|
|
||||||
d->m_fuel_totaltime = (float)temp/10;
|
|
||||||
temp = 0;
|
|
||||||
is>>temp;
|
|
||||||
d->m_fuel_time = (float)temp/10;
|
|
||||||
temp = 0;
|
|
||||||
is>>temp;
|
|
||||||
d->m_src_totaltime = (float)temp/10;
|
|
||||||
temp = 0;
|
|
||||||
is>>temp;
|
|
||||||
d->m_src_time = (float)temp/10;
|
|
||||||
|
|
||||||
if(is.eof())
|
|
||||||
{
|
|
||||||
// Old furnaces didn't serialize src_totaltime and src_time
|
|
||||||
d->m_src_totaltime = 0;
|
|
||||||
d->m_src_time = 0;
|
|
||||||
d->m_infotext = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// New furnaces also serialize the infotext (so that the
|
|
||||||
// client doesn't need to have the list of cooking recipes).
|
|
||||||
d->m_infotext = deSerializeJsonString(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
NodeMetadata* FurnaceNodeMetadata::create(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->addList("fuel", 1);
|
|
||||||
d->m_inventory->addList("src", 1);
|
|
||||||
d->m_inventory->addList("dst", 4);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
|
|
||||||
{
|
|
||||||
m_inventory->serialize(os);
|
|
||||||
os<<itos(m_fuel_totaltime*10)<<" ";
|
|
||||||
os<<itos(m_fuel_time*10)<<" ";
|
|
||||||
os<<itos(m_src_totaltime*10)<<" ";
|
|
||||||
os<<itos(m_src_time*10)<<" ";
|
|
||||||
os<<serializeJsonString(m_infotext);
|
|
||||||
}
|
|
||||||
std::string FurnaceNodeMetadata::infoText()
|
|
||||||
{
|
|
||||||
return m_infotext;
|
|
||||||
}
|
|
||||||
bool FurnaceNodeMetadata::nodeRemovalDisabled()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Disable removal if furnace is not empty
|
|
||||||
*/
|
|
||||||
InventoryList *list[3] = {m_inventory->getList("src"),
|
|
||||||
m_inventory->getList("dst"), m_inventory->getList("fuel")};
|
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
if(list[i] == NULL)
|
|
||||||
continue;
|
|
||||||
if(list[i]->getUsedSlots() == 0)
|
|
||||||
continue;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
void FurnaceNodeMetadata::inventoryModified()
|
|
||||||
{
|
|
||||||
infostream<<"Furnace inventory modification callback"<<std::endl;
|
|
||||||
}
|
|
||||||
bool FurnaceNodeMetadata::step(float dtime)
|
|
||||||
{
|
|
||||||
if(dtime > 60.0)
|
|
||||||
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
|
|
||||||
|
|
||||||
InventoryList *dst_list = m_inventory->getList("dst");
|
|
||||||
assert(dst_list);
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
|
|
||||||
|
|
||||||
bool changed_this_loop = false;
|
|
||||||
|
|
||||||
// Check
|
|
||||||
// 1. if the source item is cookable
|
|
||||||
// 2. if there is room for the cooked item
|
|
||||||
std::string cookresult;
|
|
||||||
float cooktime;
|
|
||||||
bool cookable = getCookResult(false, cookresult, cooktime);
|
|
||||||
ItemStack cookresult_item;
|
|
||||||
bool room_available = false;
|
|
||||||
if(cookable)
|
|
||||||
{
|
|
||||||
cookresult_item.deSerialize(cookresult, m_gamedef->idef());
|
|
||||||
room_available = dst_list->roomForItem(cookresult_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step fuel time
|
|
||||||
bool burning = (m_fuel_time < m_fuel_totaltime);
|
|
||||||
if(burning)
|
|
||||||
{
|
|
||||||
changed_this_loop = true;
|
|
||||||
m_fuel_time += dtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string infotext;
|
|
||||||
if(room_available)
|
|
||||||
{
|
|
||||||
float burntime;
|
|
||||||
if(burning)
|
|
||||||
{
|
|
||||||
changed_this_loop = true;
|
|
||||||
m_src_time += dtime;
|
|
||||||
m_src_totaltime = cooktime;
|
|
||||||
infotext = "Furnace is cooking";
|
|
||||||
}
|
|
||||||
else if(getBurnResult(true, burntime))
|
|
||||||
{
|
|
||||||
// Fuel inserted
|
|
||||||
changed_this_loop = true;
|
|
||||||
m_fuel_time = 0;
|
|
||||||
m_fuel_totaltime = burntime;
|
|
||||||
//m_src_time += dtime;
|
|
||||||
//m_src_totaltime = cooktime;
|
|
||||||
infotext = "Furnace is cooking";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_src_time = 0;
|
|
||||||
m_src_totaltime = 0;
|
|
||||||
infotext = "Furnace is out of fuel";
|
|
||||||
}
|
|
||||||
if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime)
|
|
||||||
{
|
|
||||||
// One item fully cooked
|
|
||||||
changed_this_loop = true;
|
|
||||||
dst_list->addItem(cookresult_item);
|
|
||||||
getCookResult(true, cookresult, cooktime); // decrement source
|
|
||||||
m_src_totaltime = 0;
|
|
||||||
m_src_time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not cookable or no room available
|
|
||||||
m_src_totaltime = 0;
|
|
||||||
m_src_time = 0;
|
|
||||||
if(cookable)
|
|
||||||
infotext = "Furnace is overloaded";
|
|
||||||
else if(burning)
|
|
||||||
infotext = "Furnace is active";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
infotext = "Furnace is inactive";
|
|
||||||
m_fuel_totaltime = 0;
|
|
||||||
m_fuel_time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do this so it doesn't always show (0%) for weak fuel
|
|
||||||
if(m_fuel_totaltime > 3) {
|
|
||||||
infotext += " (";
|
|
||||||
infotext += itos(m_fuel_time/m_fuel_totaltime*100);
|
|
||||||
infotext += "%)";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(infotext != m_infotext)
|
|
||||||
{
|
|
||||||
m_infotext = infotext;
|
|
||||||
changed_this_loop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(burning && m_fuel_time >= m_fuel_totaltime)
|
|
||||||
{
|
|
||||||
m_fuel_time = 0;
|
|
||||||
m_fuel_totaltime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(changed_this_loop)
|
|
||||||
{
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_step_accumulator = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
std::string FurnaceNodeMetadata::getInventoryDrawSpecString()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
"invsize[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;]";
|
|
||||||
}
|
|
||||||
bool FurnaceNodeMetadata::getCookResult(bool remove,
|
|
||||||
std::string &cookresult, float &cooktime)
|
|
||||||
{
|
|
||||||
std::vector<ItemStack> items;
|
|
||||||
InventoryList *src_list = m_inventory->getList("src");
|
|
||||||
assert(src_list);
|
|
||||||
items.push_back(src_list->getItem(0));
|
|
||||||
|
|
||||||
CraftInput ci(CRAFT_METHOD_COOKING, 1, items);
|
|
||||||
CraftOutput co;
|
|
||||||
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
|
|
||||||
ci, co, remove, m_gamedef);
|
|
||||||
if(remove)
|
|
||||||
src_list->changeItem(0, ci.items[0]);
|
|
||||||
|
|
||||||
cookresult = co.item;
|
|
||||||
cooktime = co.time;
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
bool FurnaceNodeMetadata::getBurnResult(bool remove, float &burntime)
|
|
||||||
{
|
|
||||||
std::vector<ItemStack> items;
|
|
||||||
InventoryList *fuel_list = m_inventory->getList("fuel");
|
|
||||||
assert(fuel_list);
|
|
||||||
items.push_back(fuel_list->getItem(0));
|
|
||||||
|
|
||||||
CraftInput ci(CRAFT_METHOD_FUEL, 1, items);
|
|
||||||
CraftOutput co;
|
|
||||||
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
|
|
||||||
ci, co, remove, m_gamedef);
|
|
||||||
if(remove)
|
|
||||||
fuel_list->changeItem(0, ci.items[0]);
|
|
||||||
|
|
||||||
burntime = co.time;
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
GenericNodeMetadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
class GenericNodeMetadata : public NodeMetadata
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Inventory *m_inventory;
|
|
||||||
std::string m_text;
|
|
||||||
std::string m_owner;
|
|
||||||
|
|
||||||
std::string m_infotext;
|
|
||||||
std::string m_inventorydrawspec;
|
|
||||||
bool m_allow_text_input;
|
|
||||||
bool m_removal_disabled;
|
|
||||||
bool m_enforce_owner;
|
|
||||||
|
|
||||||
bool m_inventory_modified;
|
|
||||||
bool m_text_modified;
|
|
||||||
|
|
||||||
std::map<std::string, std::string> m_stringvars;
|
|
||||||
|
|
||||||
public:
|
|
||||||
u16 typeId() const
|
|
||||||
{
|
|
||||||
return NODEMETA_GENERIC;
|
|
||||||
}
|
|
||||||
const char* typeName() const
|
|
||||||
{
|
|
||||||
return "generic";
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericNodeMetadata(IGameDef *gamedef):
|
|
||||||
NodeMetadata(gamedef),
|
|
||||||
|
|
||||||
m_inventory(NULL),
|
|
||||||
m_text(""),
|
|
||||||
m_owner(""),
|
|
||||||
|
|
||||||
m_infotext("GenericNodeMetadata"),
|
|
||||||
m_inventorydrawspec(""),
|
|
||||||
m_allow_text_input(false),
|
|
||||||
m_removal_disabled(false),
|
|
||||||
m_enforce_owner(false),
|
|
||||||
|
|
||||||
m_inventory_modified(false),
|
|
||||||
m_text_modified(false)
|
|
||||||
{
|
|
||||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
|
||||||
}
|
|
||||||
virtual ~GenericNodeMetadata()
|
|
||||||
{
|
|
||||||
delete m_inventory;
|
|
||||||
}
|
|
||||||
NodeMetadata* clone(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
GenericNodeMetadata *d = new GenericNodeMetadata(m_gamedef);
|
|
||||||
|
|
||||||
d->m_inventory = new Inventory(*m_inventory);
|
|
||||||
d->m_text = m_text;
|
|
||||||
d->m_owner = m_owner;
|
|
||||||
|
|
||||||
d->m_infotext = m_infotext;
|
|
||||||
d->m_inventorydrawspec = m_inventorydrawspec;
|
|
||||||
d->m_allow_text_input = m_allow_text_input;
|
|
||||||
d->m_removal_disabled = m_removal_disabled;
|
|
||||||
d->m_enforce_owner = m_enforce_owner;
|
|
||||||
d->m_inventory_modified = m_inventory_modified;
|
|
||||||
d->m_text_modified = m_text_modified;
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
static NodeMetadata* create(IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef)
|
|
||||||
{
|
|
||||||
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
|
|
||||||
|
|
||||||
d->m_inventory = new Inventory(gamedef->idef());
|
|
||||||
d->m_inventory->deSerialize(is);
|
|
||||||
d->m_text = deSerializeLongString(is);
|
|
||||||
d->m_owner = deSerializeString(is);
|
|
||||||
|
|
||||||
d->m_infotext = deSerializeString(is);
|
meta->setInfoText(deSerializeString(is));
|
||||||
d->m_inventorydrawspec = deSerializeString(is);
|
meta->setInventoryDrawSpec(deSerializeString(is));
|
||||||
d->m_allow_text_input = readU8(is);
|
readU8(is); // m_allow_text_input
|
||||||
d->m_removal_disabled = readU8(is);
|
meta->setAllowRemoval(readU8(is) == 0);
|
||||||
d->m_enforce_owner = readU8(is);
|
readU8(is); // m_enforce_owner
|
||||||
|
|
||||||
int num_vars = readU32(is);
|
int num_vars = readU32(is);
|
||||||
for(int i=0; i<num_vars; i++){
|
for(int i=0; i<num_vars; i++){
|
||||||
std::string name = deSerializeString(is);
|
std::string name = deSerializeString(is);
|
||||||
std::string var = deSerializeLongString(is);
|
std::string var = deSerializeLongString(is);
|
||||||
d->m_stringvars[name] = var;
|
meta->setString(name, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
void serializeBody(std::ostream &os)
|
|
||||||
{
|
|
||||||
m_inventory->serialize(os);
|
|
||||||
os<<serializeLongString(m_text);
|
|
||||||
os<<serializeString(m_owner);
|
|
||||||
|
|
||||||
os<<serializeString(m_infotext);
|
|
||||||
os<<serializeString(m_inventorydrawspec);
|
|
||||||
writeU8(os, m_allow_text_input);
|
|
||||||
writeU8(os, m_removal_disabled);
|
|
||||||
writeU8(os, m_enforce_owner);
|
|
||||||
|
|
||||||
int num_vars = m_stringvars.size();
|
|
||||||
writeU32(os, num_vars);
|
|
||||||
for(std::map<std::string, std::string>::iterator
|
|
||||||
i = m_stringvars.begin(); i != m_stringvars.end(); i++){
|
|
||||||
os<<serializeString(i->first);
|
|
||||||
os<<serializeLongString(i->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string infoText()
|
|
||||||
{
|
|
||||||
return m_infotext;
|
|
||||||
}
|
|
||||||
Inventory* getInventory()
|
|
||||||
{
|
|
||||||
return m_inventory;
|
|
||||||
}
|
|
||||||
void inventoryModified()
|
|
||||||
{
|
|
||||||
m_inventory_modified = true;
|
|
||||||
}
|
|
||||||
bool step(float dtime)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool nodeRemovalDisabled()
|
else if(id == NODEMETA_SIGN) // SignNodeMetadata
|
||||||
{
|
{
|
||||||
return m_removal_disabled;
|
meta->setString("text", deSerializeLongString(is));
|
||||||
|
meta->setInfoText("\"${text}\"");
|
||||||
|
meta->setFormSpec("field[text;;${text}]");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
std::string getInventoryDrawSpecString()
|
else if(id == NODEMETA_CHEST) // ChestNodeMetadata
|
||||||
{
|
{
|
||||||
return m_inventorydrawspec;
|
meta->getInventory()->deSerialize(is);
|
||||||
|
meta->setInventoryDrawSpec("invsize[8,9;]"
|
||||||
|
"list[current_name;0;0,0;8,4;]"
|
||||||
|
"list[current_player;main;0,5;8,4;]");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
bool allowsTextInput()
|
else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata
|
||||||
{
|
{
|
||||||
return m_allow_text_input;
|
meta->setString("owner", deSerializeString(is));
|
||||||
|
meta->getInventory()->deSerialize(is);
|
||||||
|
meta->setInventoryDrawSpec("invsize[8,9;]"
|
||||||
|
"list[current_name;0;0,0;8,4;]"
|
||||||
|
"list[current_player;main;0,5;8,4;]");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
std::string getText()
|
else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata
|
||||||
{
|
{
|
||||||
return m_text;
|
meta->getInventory()->deSerialize(is);
|
||||||
|
int temp = 0;
|
||||||
|
is>>temp;
|
||||||
|
meta->setString("fuel_totaltime", ftos((float)temp/10));
|
||||||
|
temp = 0;
|
||||||
|
is>>temp;
|
||||||
|
meta->setString("fuel_time", ftos((float)temp/10));
|
||||||
|
temp = 0;
|
||||||
|
is>>temp;
|
||||||
|
//meta->setString("src_totaltime", ftos((float)temp/10));
|
||||||
|
temp = 0;
|
||||||
|
is>>temp;
|
||||||
|
meta->setString("src_time", ftos((float)temp/10));
|
||||||
|
|
||||||
|
meta->setInventoryDrawSpec("invsize[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;]");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
void setText(const std::string &t)
|
|
||||||
{
|
|
||||||
m_text = t;
|
|
||||||
m_text_modified = true;
|
|
||||||
}
|
|
||||||
std::string getOwner()
|
|
||||||
{
|
|
||||||
if(m_enforce_owner)
|
|
||||||
return m_owner;
|
|
||||||
else
|
else
|
||||||
return "";
|
|
||||||
}
|
|
||||||
void setOwner(std::string t)
|
|
||||||
{
|
{
|
||||||
m_owner = t;
|
throw SerializationError("Unknown legacy node metadata");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface for GenericNodeMetadata */
|
static bool content_nodemeta_deserialize_legacy_meta(
|
||||||
|
std::istream &is, NodeMetadata *meta)
|
||||||
|
{
|
||||||
|
// Read id
|
||||||
|
s16 id = readS16(is);
|
||||||
|
|
||||||
void setInfoText(const std::string &text)
|
// Read data
|
||||||
{
|
std::string data = deSerializeString(is);
|
||||||
infostream<<"GenericNodeMetadata::setInfoText(\""
|
std::istringstream tmp_is(data, std::ios::binary);
|
||||||
<<text<<"\")"<<std::endl;
|
return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta);
|
||||||
m_infotext = text;
|
|
||||||
}
|
}
|
||||||
void setInventoryDrawSpec(const std::string &text)
|
|
||||||
{
|
|
||||||
m_inventorydrawspec = text;
|
|
||||||
}
|
|
||||||
void setAllowTextInput(bool b)
|
|
||||||
{
|
|
||||||
m_allow_text_input = b;
|
|
||||||
}
|
|
||||||
void setRemovalDisabled(bool b)
|
|
||||||
{
|
|
||||||
m_removal_disabled = b;
|
|
||||||
}
|
|
||||||
void setEnforceOwner(bool b)
|
|
||||||
{
|
|
||||||
m_enforce_owner = b;
|
|
||||||
}
|
|
||||||
bool isInventoryModified()
|
|
||||||
{
|
|
||||||
return m_inventory_modified;
|
|
||||||
}
|
|
||||||
void resetInventoryModified()
|
|
||||||
{
|
|
||||||
m_inventory_modified = false;
|
|
||||||
}
|
|
||||||
bool isTextModified()
|
|
||||||
{
|
|
||||||
return m_text_modified;
|
|
||||||
}
|
|
||||||
void resetTextModified()
|
|
||||||
{
|
|
||||||
m_text_modified = false;
|
|
||||||
}
|
|
||||||
void setString(const std::string &name, const std::string &var)
|
|
||||||
{
|
|
||||||
m_stringvars[name] = var;
|
|
||||||
}
|
|
||||||
std::string getString(const std::string &name)
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string>::iterator i;
|
|
||||||
i = m_stringvars.find(name);
|
|
||||||
if(i == m_stringvars.end())
|
|
||||||
return "";
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Prototype
|
void content_nodemeta_deserialize_legacy(std::istream &is,
|
||||||
GenericNodeMetadata proto_GenericNodeMetadata(NULL);
|
NodeMetadataList *meta, NodeTimerList *timers,
|
||||||
|
IGameDef *gamedef)
|
||||||
|
{
|
||||||
|
meta->clear();
|
||||||
|
timers->clear();
|
||||||
|
|
||||||
|
u16 version = readU16(is);
|
||||||
|
|
||||||
|
if(version > 1)
|
||||||
|
{
|
||||||
|
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
|
||||||
|
<<std::endl;
|
||||||
|
throw SerializationError(__FUNCTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 count = readU16(is);
|
||||||
|
|
||||||
|
for(u16 i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
u16 p16 = readU16(is);
|
||||||
|
|
||||||
|
v3s16 p(0,0,0);
|
||||||
|
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
|
||||||
|
p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||||
|
p.Y += p16 / MAP_BLOCKSIZE;
|
||||||
|
p16 -= p.Y * MAP_BLOCKSIZE;
|
||||||
|
p.X += p16;
|
||||||
|
|
||||||
|
if(meta->get(p) != NULL)
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: "<<__FUNCTION_NAME<<": "
|
||||||
|
<<"already set data at position"
|
||||||
|
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
||||||
|
<<std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeMetadata *data = new NodeMetadata(gamedef);
|
||||||
|
bool need_timer = content_nodemeta_deserialize_legacy_meta(is, data);
|
||||||
|
meta->set(p, data);
|
||||||
|
|
||||||
|
if(need_timer)
|
||||||
|
timers->set(p, NodeTimer(1., 0.));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta)
|
||||||
|
{
|
||||||
|
// Sorry, I was too lazy to implement this. --kahrl
|
||||||
|
writeU16(os, 1); // version
|
||||||
|
writeU16(os, 0); // count
|
||||||
|
}
|
||||||
|
|
||||||
|
// END
|
||||||
|
@ -21,6 +21,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define CONTENT_NODEMETA_HEADER
|
#define CONTENT_NODEMETA_HEADER
|
||||||
|
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
|
#include "nodetimer.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Legacy nodemeta definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void content_nodemeta_deserialize_legacy(std::istream &is,
|
||||||
|
NodeMetadataList *meta, NodeTimerList *timers,
|
||||||
|
IGameDef *gamedef);
|
||||||
|
|
||||||
|
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -773,18 +773,11 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
|||||||
// Activate stored objects
|
// Activate stored objects
|
||||||
activateObjects(block);
|
activateObjects(block);
|
||||||
|
|
||||||
// Run node metadata
|
// Run node timers
|
||||||
bool changed = block->m_node_metadata->step((float)dtime_s);
|
std::map<v3s16, f32> elapsed_timers =
|
||||||
if(changed)
|
block->m_node_timers.step((float)dtime_s);
|
||||||
{
|
if(!elapsed_timers.empty())
|
||||||
MapEditEvent event;
|
errorstream<<"Node timers don't work yet!"<<std::endl;
|
||||||
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
|
||||||
event.p = block->getPos();
|
|
||||||
m_map->dispatchEvent(&event);
|
|
||||||
|
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
|
||||||
"node metadata modified in activateBlock");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle ActiveBlockModifiers */
|
/* Handle ActiveBlockModifiers */
|
||||||
ABMHandler abmhandler(m_abms, dtime_s, this, false);
|
ABMHandler abmhandler(m_abms, dtime_s, this, false);
|
||||||
@ -1064,18 +1057,11 @@ void ServerEnvironment::step(float dtime)
|
|||||||
block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
|
block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
|
||||||
"Timestamp older than 60s (step)");
|
"Timestamp older than 60s (step)");
|
||||||
|
|
||||||
// Run node metadata
|
// Run node timers
|
||||||
bool changed = block->m_node_metadata->step(dtime);
|
std::map<v3s16, f32> elapsed_timers =
|
||||||
if(changed)
|
block->m_node_timers.step(dtime);
|
||||||
{
|
if(!elapsed_timers.empty())
|
||||||
MapEditEvent event;
|
errorstream<<"Node timers don't work yet!"<<std::endl;
|
||||||
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
|
||||||
event.p = p;
|
|
||||||
m_map->dispatchEvent(&event);
|
|
||||||
|
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
|
||||||
"node metadata modified in step");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2195,7 +2195,7 @@ void the_game(
|
|||||||
ClientMap &map = client.getEnv().getClientMap();
|
ClientMap &map = client.getEnv().getClientMap();
|
||||||
NodeMetadata *meta = map.getNodeMetadata(nodepos);
|
NodeMetadata *meta = map.getNodeMetadata(nodepos);
|
||||||
if(meta){
|
if(meta){
|
||||||
infotext = narrow_to_wide(meta->infoText());
|
infotext = narrow_to_wide(meta->getInfoText());
|
||||||
} else {
|
} else {
|
||||||
MapNode n = map.getNode(nodepos);
|
MapNode n = map.getNode(nodepos);
|
||||||
if(nodedef->get(n).tname_tiles[0] == "unknown_block.png"){
|
if(nodedef->get(n).tname_tiles[0] == "unknown_block.png"){
|
||||||
@ -2321,6 +2321,8 @@ void the_game(
|
|||||||
infostream<<"Ground right-clicked"<<std::endl;
|
infostream<<"Ground right-clicked"<<std::endl;
|
||||||
|
|
||||||
// If metadata provides an inventory view, activate it
|
// If metadata provides an inventory view, activate it
|
||||||
|
errorstream<<"Need to implement metadata formspecs"<<std::endl;
|
||||||
|
#if 0
|
||||||
if(meta && meta->getInventoryDrawSpecString() != "" && !random_input)
|
if(meta && meta->getInventoryDrawSpecString() != "" && !random_input)
|
||||||
{
|
{
|
||||||
infostream<<"Launching custom inventory view"<<std::endl;
|
infostream<<"Launching custom inventory view"<<std::endl;
|
||||||
@ -2362,6 +2364,9 @@ void the_game(
|
|||||||
&g_menumgr, dest,
|
&g_menumgr, dest,
|
||||||
wtext))->drop();
|
wtext))->drop();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if(0) /* do nothing */;
|
||||||
|
#endif
|
||||||
// Otherwise report right click to server
|
// Otherwise report right click to server
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
50
src/map.cpp
50
src/map.cpp
@ -1015,21 +1015,6 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
|||||||
|
|
||||||
setNode(p, n);
|
setNode(p, n);
|
||||||
|
|
||||||
/*
|
|
||||||
Add intial metadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::string metadata_name = nodemgr->get(n).metadata_name;
|
|
||||||
if(metadata_name != ""){
|
|
||||||
NodeMetadata *meta = NodeMetadata::create(metadata_name, m_gamedef);
|
|
||||||
if(!meta){
|
|
||||||
errorstream<<"Failed to create node metadata \""
|
|
||||||
<<metadata_name<<"\""<<std::endl;
|
|
||||||
} else {
|
|
||||||
setNodeMetadata(p, meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If node is under sunlight and doesn't let sunlight through,
|
If node is under sunlight and doesn't let sunlight through,
|
||||||
take all sunlighted nodes under it and clear light from them
|
take all sunlighted nodes under it and clear light from them
|
||||||
@ -1853,7 +1838,7 @@ NodeMetadata* Map::getNodeMetadata(v3s16 p)
|
|||||||
<<std::endl;
|
<<std::endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
NodeMetadata *meta = block->m_node_metadata->get(p_rel);
|
NodeMetadata *meta = block->m_node_metadata.get(p_rel);
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1873,7 +1858,7 @@ void Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
|
|||||||
<<std::endl;
|
<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
block->m_node_metadata->set(p_rel, meta);
|
block->m_node_metadata.set(p_rel, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::removeNodeMetadata(v3s16 p)
|
void Map::removeNodeMetadata(v3s16 p)
|
||||||
@ -1887,36 +1872,7 @@ void Map::removeNodeMetadata(v3s16 p)
|
|||||||
<<std::endl;
|
<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
block->m_node_metadata->remove(p_rel);
|
block->m_node_metadata.remove(p_rel);
|
||||||
}
|
|
||||||
|
|
||||||
void Map::nodeMetadataStep(float dtime,
|
|
||||||
core::map<v3s16, MapBlock*> &changed_blocks)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
NOTE:
|
|
||||||
Currently there is no way to ensure that all the necessary
|
|
||||||
blocks are loaded when this is run. (They might get unloaded)
|
|
||||||
NOTE: ^- Actually, that might not be so. In a quick test it
|
|
||||||
reloaded a block with a furnace when I walked back to it from
|
|
||||||
a distance.
|
|
||||||
*/
|
|
||||||
core::map<v2s16, MapSector*>::Iterator si;
|
|
||||||
si = m_sectors.getIterator();
|
|
||||||
for(; si.atEnd() == false; si++)
|
|
||||||
{
|
|
||||||
MapSector *sector = si.getNode()->getValue();
|
|
||||||
core::list< MapBlock * > sectorblocks;
|
|
||||||
sector->getBlocks(sectorblocks);
|
|
||||||
core::list< MapBlock * >::Iterator i;
|
|
||||||
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
|
||||||
{
|
|
||||||
MapBlock *block = *i;
|
|
||||||
bool changed = block->m_node_metadata->step(dtime);
|
|
||||||
if(changed)
|
|
||||||
changed_blocks[block->getPos()] = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -309,8 +309,6 @@ public:
|
|||||||
NodeMetadata* getNodeMetadata(v3s16 p);
|
NodeMetadata* getNodeMetadata(v3s16 p);
|
||||||
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
||||||
void removeNodeMetadata(v3s16 p);
|
void removeNodeMetadata(v3s16 p);
|
||||||
void nodeMetadataStep(float dtime,
|
|
||||||
core::map<v3s16, MapBlock*> &changed_blocks);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Misc.
|
Misc.
|
||||||
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nameidmapping.h"
|
#include "nameidmapping.h"
|
||||||
#include "content_mapnode.h" // For legacy name-id mapping
|
#include "content_mapnode.h" // For legacy name-id mapping
|
||||||
|
#include "content_nodemeta.h" // For legacy deserialization
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#endif
|
#endif
|
||||||
@ -39,7 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
|
MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
|
||||||
m_node_metadata(new NodeMetadataList),
|
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
m_pos(pos),
|
m_pos(pos),
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
@ -79,8 +79,6 @@ MapBlock::~MapBlock()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete m_node_metadata;
|
|
||||||
|
|
||||||
if(data)
|
if(data)
|
||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
@ -605,7 +603,10 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
Node metadata
|
Node metadata
|
||||||
*/
|
*/
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
m_node_metadata->serialize(oss);
|
if(version >= 23)
|
||||||
|
m_node_metadata.serialize(oss);
|
||||||
|
else
|
||||||
|
content_nodemeta_serialize_legacy(oss, &m_node_metadata);
|
||||||
compressZlib(oss.str(), os);
|
compressZlib(oss.str(), os);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -613,6 +614,10 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
*/
|
*/
|
||||||
if(disk)
|
if(disk)
|
||||||
{
|
{
|
||||||
|
// Node timers
|
||||||
|
if(version >= 23)
|
||||||
|
m_node_timers.serialize(os);
|
||||||
|
|
||||||
// Static objects
|
// Static objects
|
||||||
m_static_objects.serialize(os);
|
m_static_objects.serialize(os);
|
||||||
|
|
||||||
@ -665,12 +670,17 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
|||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
decompressZlib(is, oss);
|
decompressZlib(is, oss);
|
||||||
std::istringstream iss(oss.str(), std::ios_base::binary);
|
std::istringstream iss(oss.str(), std::ios_base::binary);
|
||||||
m_node_metadata->deSerialize(iss, m_gamedef);
|
if(version >= 23)
|
||||||
|
m_node_metadata.deSerialize(iss, m_gamedef);
|
||||||
|
else
|
||||||
|
content_nodemeta_deserialize_legacy(iss,
|
||||||
|
&m_node_metadata, &m_node_timers,
|
||||||
|
m_gamedef);
|
||||||
}
|
}
|
||||||
catch(SerializationError &e)
|
catch(SerializationError &e)
|
||||||
{
|
{
|
||||||
errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
|
errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
|
||||||
<<" while deserializing node metadata"<<std::endl;
|
<<" while deserializing node metadata: "<<e.what()<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -678,6 +688,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
|||||||
*/
|
*/
|
||||||
if(disk)
|
if(disk)
|
||||||
{
|
{
|
||||||
|
// Node timers
|
||||||
|
if(version >= 23)
|
||||||
|
m_node_timers.deSerialize(is);
|
||||||
|
|
||||||
// Static objects
|
// Static objects
|
||||||
m_static_objects.deSerialize(is);
|
m_static_objects.deSerialize(is);
|
||||||
|
|
||||||
@ -857,7 +871,7 @@ void MapBlock::serialize_pre22(std::ostream &os, u8 version, bool disk)
|
|||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
m_node_metadata->serialize(oss);
|
content_nodemeta_serialize_legacy(oss, &m_node_metadata);
|
||||||
os<<serializeString(oss.str());
|
os<<serializeString(oss.str());
|
||||||
}
|
}
|
||||||
// This will happen if the string is longer than 65535
|
// This will happen if the string is longer than 65535
|
||||||
@ -870,7 +884,7 @@ void MapBlock::serialize_pre22(std::ostream &os, u8 version, bool disk)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
m_node_metadata->serialize(oss);
|
content_nodemeta_serialize_legacy(oss, &m_node_metadata);
|
||||||
compressZlib(oss.str(), os);
|
compressZlib(oss.str(), os);
|
||||||
//os<<serializeLongString(oss.str());
|
//os<<serializeLongString(oss.str());
|
||||||
}
|
}
|
||||||
@ -1024,7 +1038,9 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
|||||||
{
|
{
|
||||||
std::string data = deSerializeString(is);
|
std::string data = deSerializeString(is);
|
||||||
std::istringstream iss(data, std::ios_base::binary);
|
std::istringstream iss(data, std::ios_base::binary);
|
||||||
m_node_metadata->deSerialize(iss, m_gamedef);
|
content_nodemeta_deserialize_legacy(iss,
|
||||||
|
&m_node_metadata, &m_node_timers,
|
||||||
|
m_gamedef);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1032,7 +1048,9 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
|||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
decompressZlib(is, oss);
|
decompressZlib(is, oss);
|
||||||
std::istringstream iss(oss.str(), std::ios_base::binary);
|
std::istringstream iss(oss.str(), std::ios_base::binary);
|
||||||
m_node_metadata->deSerialize(iss, m_gamedef);
|
content_nodemeta_deserialize_legacy(iss,
|
||||||
|
&m_node_metadata, &m_node_timers,
|
||||||
|
m_gamedef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(SerializationError &e)
|
catch(SerializationError &e)
|
||||||
|
@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "staticobject.h"
|
#include "staticobject.h"
|
||||||
|
#include "nodemetadata.h"
|
||||||
|
#include "nodetimer.h"
|
||||||
#include "modifiedstate.h"
|
#include "modifiedstate.h"
|
||||||
|
|
||||||
class Map;
|
class Map;
|
||||||
@ -473,7 +475,8 @@ public:
|
|||||||
//JMutex mesh_mutex;
|
//JMutex mesh_mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeMetadataList *m_node_metadata;
|
NodeMetadataList m_node_metadata;
|
||||||
|
NodeTimerList m_node_timers;
|
||||||
StaticObjectList m_static_objects;
|
StaticObjectList m_static_objects;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -145,7 +145,6 @@ void ContentFeatures::reset()
|
|||||||
diggable = true;
|
diggable = true;
|
||||||
climbable = false;
|
climbable = false;
|
||||||
buildable_to = false;
|
buildable_to = false;
|
||||||
metadata_name = "";
|
|
||||||
liquid_type = LIQUID_NONE;
|
liquid_type = LIQUID_NONE;
|
||||||
liquid_alternative_flowing = "";
|
liquid_alternative_flowing = "";
|
||||||
liquid_alternative_source = "";
|
liquid_alternative_source = "";
|
||||||
@ -194,7 +193,7 @@ void ContentFeatures::serialize(std::ostream &os)
|
|||||||
writeU8(os, diggable);
|
writeU8(os, diggable);
|
||||||
writeU8(os, climbable);
|
writeU8(os, climbable);
|
||||||
writeU8(os, buildable_to);
|
writeU8(os, buildable_to);
|
||||||
os<<serializeString(metadata_name);
|
os<<serializeString(""); // legacy: used to be metadata_name
|
||||||
writeU8(os, liquid_type);
|
writeU8(os, liquid_type);
|
||||||
os<<serializeString(liquid_alternative_flowing);
|
os<<serializeString(liquid_alternative_flowing);
|
||||||
os<<serializeString(liquid_alternative_source);
|
os<<serializeString(liquid_alternative_source);
|
||||||
@ -248,7 +247,7 @@ void ContentFeatures::deSerialize(std::istream &is)
|
|||||||
diggable = readU8(is);
|
diggable = readU8(is);
|
||||||
climbable = readU8(is);
|
climbable = readU8(is);
|
||||||
buildable_to = readU8(is);
|
buildable_to = readU8(is);
|
||||||
metadata_name = deSerializeString(is);
|
deSerializeString(is); // legacy: used to be metadata_name
|
||||||
liquid_type = (enum LiquidType)readU8(is);
|
liquid_type = (enum LiquidType)readU8(is);
|
||||||
liquid_alternative_flowing = deSerializeString(is);
|
liquid_alternative_flowing = deSerializeString(is);
|
||||||
liquid_alternative_source = deSerializeString(is);
|
liquid_alternative_source = deSerializeString(is);
|
||||||
|
@ -179,8 +179,6 @@ struct ContentFeatures
|
|||||||
bool climbable;
|
bool climbable;
|
||||||
// Player can build on these
|
// Player can build on these
|
||||||
bool buildable_to;
|
bool buildable_to;
|
||||||
// Metadata name of node (eg. "furnace")
|
|
||||||
std::string metadata_name;
|
|
||||||
// Whether the node is non-liquid, source liquid or flowing liquid
|
// Whether the node is non-liquid, source liquid or flowing liquid
|
||||||
enum LiquidType liquid_type;
|
enum LiquidType liquid_type;
|
||||||
// If the content is liquid, this is the flowing version of the liquid.
|
// If the content is liquid, this is the flowing version of the liquid.
|
||||||
|
@ -19,11 +19,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "mapnode.h"
|
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
#include "gamedef.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "content_mapnode.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,161 +30,120 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
NodeMetadata::NodeMetadata(IGameDef *gamedef):
|
NodeMetadata::NodeMetadata(IGameDef *gamedef):
|
||||||
m_gamedef(gamedef)
|
m_stringvars(),
|
||||||
|
m_inventory(new Inventory(gamedef->idef())),
|
||||||
|
m_inventorydrawspec(""),
|
||||||
|
m_formspec(""),
|
||||||
|
m_infotext(""),
|
||||||
|
m_allow_removal(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata::~NodeMetadata()
|
NodeMetadata::~NodeMetadata()
|
||||||
{
|
{
|
||||||
|
delete m_inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata* NodeMetadata::create(const std::string &name, IGameDef *gamedef)
|
void NodeMetadata::serialize(std::ostream &os) const
|
||||||
{
|
{
|
||||||
// Find factory function
|
int num_vars = m_stringvars.size();
|
||||||
core::map<std::string, Factory2>::Node *n;
|
writeU32(os, num_vars);
|
||||||
n = m_names.find(name);
|
for(std::map<std::string, std::string>::const_iterator
|
||||||
if(n == NULL)
|
i = m_stringvars.begin(); i != m_stringvars.end(); i++){
|
||||||
{
|
os<<serializeString(i->first);
|
||||||
// If factory is not found, just return.
|
os<<serializeLongString(i->second);
|
||||||
errorstream<<"WARNING: NodeMetadata: No factory for name=\""
|
|
||||||
<<name<<"\""<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load the metadata. If it fails, just return.
|
m_inventory->serialize(os);
|
||||||
try
|
os<<serializeString(m_inventorydrawspec);
|
||||||
{
|
os<<serializeString(m_formspec);
|
||||||
Factory2 f2 = n->getValue();
|
os<<serializeString(m_infotext);
|
||||||
NodeMetadata *meta = (*f2)(gamedef);
|
writeU8(os, m_allow_removal);
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
catch(SerializationError &e)
|
|
||||||
{
|
|
||||||
errorstream<<"NodeMetadata: SerializationError "
|
|
||||||
<<"while creating name=\""<<name<<"\""<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata* NodeMetadata::deSerialize(std::istream &is, IGameDef *gamedef)
|
void NodeMetadata::deSerialize(std::istream &is)
|
||||||
{
|
{
|
||||||
// Read id
|
m_stringvars.clear();
|
||||||
u8 buf[2];
|
int num_vars = readU32(is);
|
||||||
is.read((char*)buf, 2);
|
for(int i=0; i<num_vars; i++){
|
||||||
s16 id = readS16(buf);
|
std::string name = deSerializeString(is);
|
||||||
|
std::string var = deSerializeLongString(is);
|
||||||
|
m_stringvars[name] = var;
|
||||||
|
}
|
||||||
|
|
||||||
// Read data
|
m_inventory->deSerialize(is);
|
||||||
std::string data = deSerializeString(is);
|
m_inventorydrawspec = deSerializeString(is);
|
||||||
|
m_formspec = deSerializeString(is);
|
||||||
|
m_infotext = deSerializeString(is);
|
||||||
|
m_allow_removal = readU8(is);
|
||||||
|
}
|
||||||
|
|
||||||
// Find factory function
|
void NodeMetadata::clear()
|
||||||
core::map<u16, Factory>::Node *n;
|
|
||||||
n = m_types.find(id);
|
|
||||||
if(n == NULL)
|
|
||||||
{
|
{
|
||||||
// If factory is not found, just return.
|
m_stringvars.clear();
|
||||||
infostream<<"WARNING: NodeMetadata: No factory for typeId="
|
m_inventory->clear();
|
||||||
<<id<<std::endl;
|
m_inventorydrawspec = "";
|
||||||
return NULL;
|
m_formspec = "";
|
||||||
}
|
m_infotext = "";
|
||||||
|
m_allow_removal = true;
|
||||||
// Try to load the metadata. If it fails, just return.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::istringstream iss(data, std::ios_base::binary);
|
|
||||||
|
|
||||||
Factory f = n->getValue();
|
|
||||||
NodeMetadata *meta = (*f)(iss, gamedef);
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
catch(SerializationError &e)
|
|
||||||
{
|
|
||||||
infostream<<"WARNING: NodeMetadata: ignoring SerializationError"<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeMetadata::serialize(std::ostream &os)
|
|
||||||
{
|
|
||||||
u8 buf[2];
|
|
||||||
writeU16(buf, typeId());
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
|
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
|
||||||
serializeBody(oss);
|
|
||||||
os<<serializeString(oss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeMetadata::registerType(u16 id, const std::string &name, Factory f,
|
|
||||||
Factory2 f2)
|
|
||||||
{
|
|
||||||
{ // typeId
|
|
||||||
core::map<u16, Factory>::Node *n;
|
|
||||||
n = m_types.find(id);
|
|
||||||
if(!n)
|
|
||||||
m_types.insert(id, f);
|
|
||||||
}
|
|
||||||
{ // typeName
|
|
||||||
core::map<std::string, Factory2>::Node *n;
|
|
||||||
n = m_names.find(name);
|
|
||||||
if(!n)
|
|
||||||
m_names.insert(name, f2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeMetadataList
|
NodeMetadataList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void NodeMetadataList::serialize(std::ostream &os)
|
void NodeMetadataList::serialize(std::ostream &os) const
|
||||||
{
|
{
|
||||||
u8 buf[6];
|
/*
|
||||||
|
Version 0 is a placeholder for "nothing to see here; go away."
|
||||||
|
*/
|
||||||
|
|
||||||
u16 version = 1;
|
if(m_data.size() == 0){
|
||||||
writeU16(buf, version);
|
writeU8(os, 0); // version
|
||||||
os.write((char*)buf, 2);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeU8(os, 1); // version
|
||||||
|
|
||||||
u16 count = m_data.size();
|
u16 count = m_data.size();
|
||||||
writeU16(buf, count);
|
writeU16(os, count);
|
||||||
os.write((char*)buf, 2);
|
|
||||||
|
|
||||||
for(core::map<v3s16, NodeMetadata*>::Iterator
|
for(std::map<v3s16, NodeMetadata*>::const_iterator
|
||||||
i = m_data.getIterator();
|
i = m_data.begin();
|
||||||
i.atEnd()==false; i++)
|
i != m_data.end(); i++)
|
||||||
{
|
{
|
||||||
v3s16 p = i.getNode()->getKey();
|
v3s16 p = i->first;
|
||||||
NodeMetadata *data = i.getNode()->getValue();
|
NodeMetadata *data = i->second;
|
||||||
|
|
||||||
u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
|
u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
|
||||||
writeU16(buf, p16);
|
writeU16(os, p16);
|
||||||
os.write((char*)buf, 2);
|
|
||||||
|
|
||||||
data->serialize(os);
|
data->serialize(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef)
|
void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
|
|
||||||
u8 buf[6];
|
u8 version = readU8(is);
|
||||||
|
|
||||||
is.read((char*)buf, 2);
|
if(version == 0){
|
||||||
u16 version = readU16(buf);
|
// Nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(version > 1)
|
if(version != 1){
|
||||||
{
|
|
||||||
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
|
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
throw SerializationError("NodeMetadataList::deSerialize");
|
throw SerializationError("NodeMetadataList::deSerialize");
|
||||||
}
|
}
|
||||||
|
|
||||||
is.read((char*)buf, 2);
|
u16 count = readU16(is);
|
||||||
u16 count = readU16(buf);
|
|
||||||
|
|
||||||
for(u16 i=0; i<count; i++)
|
for(u16 i=0; i<count; i++)
|
||||||
{
|
{
|
||||||
is.read((char*)buf, 2);
|
u16 p16 = readU16(is);
|
||||||
u16 p16 = readU16(buf);
|
|
||||||
|
|
||||||
v3s16 p(0,0,0);
|
v3s16 p(0,0,0);
|
||||||
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
|
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
|
||||||
@ -194,42 +152,32 @@ void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef)
|
|||||||
p16 -= p.Y * MAP_BLOCKSIZE;
|
p16 -= p.Y * MAP_BLOCKSIZE;
|
||||||
p.X += p16;
|
p.X += p16;
|
||||||
|
|
||||||
NodeMetadata *data = NodeMetadata::deSerialize(is, gamedef);
|
if(m_data.find(p) != m_data.end())
|
||||||
|
|
||||||
if(data == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(m_data.find(p))
|
|
||||||
{
|
{
|
||||||
infostream<<"WARNING: NodeMetadataList::deSerialize(): "
|
infostream<<"WARNING: NodeMetadataList::deSerialize(): "
|
||||||
<<"already set data at position"
|
<<"already set data at position"
|
||||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
delete data;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data.insert(p, data);
|
NodeMetadata *data = new NodeMetadata(gamedef);
|
||||||
|
data->deSerialize(is);
|
||||||
|
m_data[p] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadataList::~NodeMetadataList()
|
NodeMetadataList::~NodeMetadataList()
|
||||||
{
|
{
|
||||||
for(core::map<v3s16, NodeMetadata*>::Iterator
|
clear();
|
||||||
i = m_data.getIterator();
|
|
||||||
i.atEnd()==false; i++)
|
|
||||||
{
|
|
||||||
delete i.getNode()->getValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata* NodeMetadataList::get(v3s16 p)
|
NodeMetadata* NodeMetadataList::get(v3s16 p)
|
||||||
{
|
{
|
||||||
core::map<v3s16, NodeMetadata*>::Node *n;
|
std::map<v3s16, NodeMetadata*>::const_iterator n = m_data.find(p);
|
||||||
n = m_data.find(p);
|
if(n == m_data.end())
|
||||||
if(n == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
return n->getValue();
|
return n->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeMetadataList::remove(v3s16 p)
|
void NodeMetadataList::remove(v3s16 p)
|
||||||
@ -238,29 +186,23 @@ void NodeMetadataList::remove(v3s16 p)
|
|||||||
if(olddata)
|
if(olddata)
|
||||||
{
|
{
|
||||||
delete olddata;
|
delete olddata;
|
||||||
m_data.remove(p);
|
m_data.erase(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
|
void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
|
||||||
{
|
{
|
||||||
remove(p);
|
remove(p);
|
||||||
m_data.insert(p, d);
|
m_data.insert(std::make_pair(p, d));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeMetadataList::step(float dtime)
|
void NodeMetadataList::clear()
|
||||||
{
|
{
|
||||||
bool something_changed = false;
|
for(std::map<v3s16, NodeMetadata*>::iterator
|
||||||
for(core::map<v3s16, NodeMetadata*>::Iterator
|
i = m_data.begin();
|
||||||
i = m_data.getIterator();
|
i != m_data.end(); i++)
|
||||||
i.atEnd()==false; i++)
|
|
||||||
{
|
{
|
||||||
v3s16 p = i.getNode()->getKey();
|
delete i->second;
|
||||||
NodeMetadata *meta = i.getNode()->getValue();
|
|
||||||
bool changed = meta->step(dtime);
|
|
||||||
if(changed)
|
|
||||||
something_changed = true;
|
|
||||||
}
|
}
|
||||||
return something_changed;
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irrlichttypes.h"
|
#include "irrlichttypes.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeMetadata stores arbitary amounts of data for special blocks.
|
NodeMetadata stores arbitary amounts of data for special blocks.
|
||||||
@ -39,77 +40,89 @@ class IGameDef;
|
|||||||
class NodeMetadata
|
class NodeMetadata
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef NodeMetadata* (*Factory)(std::istream&, IGameDef *gamedef);
|
|
||||||
typedef NodeMetadata* (*Factory2)(IGameDef *gamedef);
|
|
||||||
|
|
||||||
NodeMetadata(IGameDef *gamedef);
|
NodeMetadata(IGameDef *gamedef);
|
||||||
virtual ~NodeMetadata();
|
~NodeMetadata();
|
||||||
|
|
||||||
static NodeMetadata* create(const std::string &name, IGameDef *gamedef);
|
void serialize(std::ostream &os) const;
|
||||||
static NodeMetadata* deSerialize(std::istream &is, IGameDef *gamedef);
|
void deSerialize(std::istream &is);
|
||||||
void serialize(std::ostream &os);
|
|
||||||
|
|
||||||
virtual u16 typeId() const = 0;
|
void clear();
|
||||||
virtual const char* typeName() const = 0;
|
|
||||||
virtual NodeMetadata* clone(IGameDef *gamedef) = 0;
|
|
||||||
virtual void serializeBody(std::ostream &os) = 0;
|
|
||||||
|
|
||||||
// Called on client-side; shown on screen when pointed at
|
// Generic key/value store
|
||||||
virtual std::string infoText() {return "";}
|
std::string getString(const std::string &name) const
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string>::const_iterator i;
|
||||||
|
i = m_stringvars.find(name);
|
||||||
|
if(i == m_stringvars.end())
|
||||||
|
return "";
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
void setString(const std::string &name, const std::string &var)
|
||||||
|
{
|
||||||
|
if(var.empty())
|
||||||
|
m_stringvars.erase(name);
|
||||||
|
else
|
||||||
|
m_stringvars[name] = var;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
// The inventory
|
||||||
virtual Inventory* getInventory() {return NULL;}
|
Inventory* getInventory()
|
||||||
// Called always after the inventory is modified, before the changes
|
{
|
||||||
// are copied elsewhere
|
return m_inventory;
|
||||||
virtual void inventoryModified(){}
|
}
|
||||||
|
|
||||||
// A step in time. Shall return true if metadata changed.
|
|
||||||
virtual bool step(float dtime) {return false;}
|
|
||||||
|
|
||||||
// Whether the related node and this metadata cannot be removed
|
|
||||||
virtual bool nodeRemovalDisabled(){return false;}
|
|
||||||
// If non-empty, player can interact by using an inventory view
|
// If non-empty, player can interact by using an inventory view
|
||||||
// See format in guiInventoryMenu.cpp.
|
// See format in guiInventoryMenu.cpp.
|
||||||
virtual std::string getInventoryDrawSpecString(){return "";}
|
std::string getInventoryDrawSpec() const
|
||||||
|
{
|
||||||
|
return m_inventorydrawspec;
|
||||||
|
}
|
||||||
|
void setInventoryDrawSpec(const std::string &text)
|
||||||
|
{
|
||||||
|
m_inventorydrawspec = text;
|
||||||
|
}
|
||||||
|
|
||||||
// If true, player can interact by writing text
|
// If non-empty, player can interact by using an form view
|
||||||
virtual bool allowsTextInput(){ return false; }
|
// See format in guiFormMenu.cpp.
|
||||||
// Get old text for player interaction
|
std::string getFormSpec() const
|
||||||
virtual std::string getText(){ return ""; }
|
{
|
||||||
// Set player-written text
|
return m_formspec;
|
||||||
virtual void setText(const std::string &t){}
|
}
|
||||||
|
void setFormSpec(const std::string &text)
|
||||||
|
{
|
||||||
|
m_formspec = text;
|
||||||
|
}
|
||||||
|
|
||||||
// If returns non-empty, only given player can modify text/inventory
|
// Called on client-side; shown on screen when pointed at
|
||||||
virtual std::string getOwner(){ return std::string(""); }
|
std::string getInfoText() const
|
||||||
// The name of the player who placed the node
|
{
|
||||||
virtual void setOwner(std::string t){}
|
return m_infotext;
|
||||||
|
}
|
||||||
|
void setInfoText(const std::string &text)
|
||||||
|
{
|
||||||
|
m_infotext = text;
|
||||||
|
}
|
||||||
|
|
||||||
/* Interface for GenericNodeMetadata */
|
// Whether the related node and this metadata can be removed
|
||||||
|
bool getAllowRemoval() const
|
||||||
|
{
|
||||||
|
return m_allow_removal;
|
||||||
|
}
|
||||||
|
void setAllowRemoval(bool b)
|
||||||
|
{
|
||||||
|
m_allow_removal = b;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setInfoText(const std::string &text){};
|
|
||||||
virtual void setInventoryDrawSpec(const std::string &text){};
|
|
||||||
virtual void setAllowTextInput(bool b){};
|
|
||||||
|
|
||||||
virtual void setRemovalDisabled(bool b){};
|
|
||||||
virtual void setEnforceOwner(bool b){};
|
|
||||||
|
|
||||||
virtual bool isInventoryModified(){return false;};
|
|
||||||
virtual void resetInventoryModified(){};
|
|
||||||
virtual bool isTextModified(){return false;};
|
|
||||||
virtual void resetTextModified(){};
|
|
||||||
|
|
||||||
virtual void setString(const std::string &name, const std::string &var){}
|
|
||||||
virtual std::string getString(const std::string &name){return "";}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void registerType(u16 id, const std::string &name, Factory f,
|
|
||||||
Factory2 f2);
|
|
||||||
IGameDef *m_gamedef;
|
|
||||||
private:
|
private:
|
||||||
static core::map<u16, Factory> m_types;
|
std::map<std::string, std::string> m_stringvars;
|
||||||
static core::map<std::string, Factory2> m_names;
|
Inventory *m_inventory;
|
||||||
|
std::string m_inventorydrawspec;
|
||||||
|
std::string m_formspec;
|
||||||
|
std::string m_infotext;
|
||||||
|
bool m_allow_removal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
List of metadata of all the nodes of a block
|
List of metadata of all the nodes of a block
|
||||||
*/
|
*/
|
||||||
@ -119,7 +132,7 @@ class NodeMetadataList
|
|||||||
public:
|
public:
|
||||||
~NodeMetadataList();
|
~NodeMetadataList();
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os) const;
|
||||||
void deSerialize(std::istream &is, IGameDef *gamedef);
|
void deSerialize(std::istream &is, IGameDef *gamedef);
|
||||||
|
|
||||||
// Get pointer to data
|
// Get pointer to data
|
||||||
@ -128,12 +141,11 @@ public:
|
|||||||
void remove(v3s16 p);
|
void remove(v3s16 p);
|
||||||
// Deletes old data and sets a new one
|
// Deletes old data and sets a new one
|
||||||
void set(v3s16 p, NodeMetadata *d);
|
void set(v3s16 p, NodeMetadata *d);
|
||||||
|
// Deletes all
|
||||||
// A step in time. Returns true if something changed.
|
void clear();
|
||||||
bool step(float dtime);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::map<v3s16, NodeMetadata*> m_data;
|
std::map<v3s16, NodeMetadata*> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
141
src/nodetimer.cpp
Normal file
141
src/nodetimer.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nodetimer.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeTimer
|
||||||
|
*/
|
||||||
|
|
||||||
|
void NodeTimer::serialize(std::ostream &os) const
|
||||||
|
{
|
||||||
|
writeF1000(os, duration);
|
||||||
|
writeF1000(os, elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTimer::deSerialize(std::istream &is)
|
||||||
|
{
|
||||||
|
duration = readF1000(is);
|
||||||
|
elapsed = readF1000(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeTimerList
|
||||||
|
*/
|
||||||
|
|
||||||
|
void NodeTimerList::serialize(std::ostream &os) const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Version 0 is a placeholder for "nothing to see here; go away."
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(m_data.size() == 0){
|
||||||
|
writeU8(os, 0); // version
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeU8(os, 1); // version
|
||||||
|
writeU16(os, m_data.size());
|
||||||
|
|
||||||
|
for(std::map<v3s16, NodeTimer>::const_iterator
|
||||||
|
i = m_data.begin();
|
||||||
|
i != m_data.end(); i++){
|
||||||
|
v3s16 p = i->first;
|
||||||
|
NodeTimer t = i->second;
|
||||||
|
|
||||||
|
u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
|
||||||
|
writeU16(os, p16);
|
||||||
|
t.serialize(os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTimerList::deSerialize(std::istream &is)
|
||||||
|
{
|
||||||
|
m_data.clear();
|
||||||
|
|
||||||
|
u8 version = readU8(is);
|
||||||
|
if(version == 0)
|
||||||
|
return;
|
||||||
|
if(version != 1)
|
||||||
|
throw SerializationError("unsupported NodeTimerList version");
|
||||||
|
|
||||||
|
u16 count = readU16(is);
|
||||||
|
|
||||||
|
for(u16 i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
u16 p16 = readU16(is);
|
||||||
|
|
||||||
|
v3s16 p(0,0,0);
|
||||||
|
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
|
||||||
|
p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||||
|
p.Y += p16 / MAP_BLOCKSIZE;
|
||||||
|
p16 -= p.Y * MAP_BLOCKSIZE;
|
||||||
|
p.X += p16;
|
||||||
|
|
||||||
|
NodeTimer t;
|
||||||
|
t.deSerialize(is);
|
||||||
|
|
||||||
|
if(t.duration <= 0)
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: NodeTimerList::deSerialize(): "
|
||||||
|
<<"invalid data at position"
|
||||||
|
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
||||||
|
<<std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_data.find(p) != m_data.end())
|
||||||
|
{
|
||||||
|
infostream<<"WARNING: NodeTimerList::deSerialize(): "
|
||||||
|
<<"already set data at position"
|
||||||
|
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
||||||
|
<<std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data.insert(std::make_pair(p, t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<v3s16, f32> NodeTimerList::step(float dtime)
|
||||||
|
{
|
||||||
|
std::map<v3s16, f32> elapsed_timers;
|
||||||
|
// Increment timers
|
||||||
|
for(std::map<v3s16, NodeTimer>::iterator
|
||||||
|
i = m_data.begin();
|
||||||
|
i != m_data.end(); i++){
|
||||||
|
v3s16 p = i->first;
|
||||||
|
NodeTimer t = i->second;
|
||||||
|
t.elapsed += dtime;
|
||||||
|
if(t.elapsed >= t.duration)
|
||||||
|
elapsed_timers.insert(std::make_pair(p, t.elapsed));
|
||||||
|
else
|
||||||
|
i->second = t;
|
||||||
|
}
|
||||||
|
// Delete elapsed timers
|
||||||
|
for(std::map<v3s16, f32>::const_iterator
|
||||||
|
i = elapsed_timers.begin();
|
||||||
|
i != elapsed_timers.end(); i++){
|
||||||
|
v3s16 p = i->first;
|
||||||
|
m_data.erase(p);
|
||||||
|
}
|
||||||
|
return elapsed_timers;
|
||||||
|
}
|
91
src/nodetimer.h
Normal file
91
src/nodetimer.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NODETIMER_HEADER
|
||||||
|
#define NODETIMER_HEADER
|
||||||
|
|
||||||
|
#include "irrlichttypes.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeTimer provides per-node timed callback functionality.
|
||||||
|
Can be used for:
|
||||||
|
- Furnaces, to keep the fire burnin'
|
||||||
|
- "activated" nodes that snap back to their original state
|
||||||
|
after a fixed amount of time (mesecons buttons, for example)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NodeTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeTimer(): duration(0.), elapsed(0.) {}
|
||||||
|
NodeTimer(f32 duration_, f32 elapsed_):
|
||||||
|
duration(duration_), elapsed(elapsed_) {}
|
||||||
|
~NodeTimer() {}
|
||||||
|
|
||||||
|
void serialize(std::ostream &os) const;
|
||||||
|
void deSerialize(std::istream &is);
|
||||||
|
|
||||||
|
f32 duration;
|
||||||
|
f32 elapsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
List of timers of all the nodes of a block
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NodeTimerList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeTimerList() {}
|
||||||
|
~NodeTimerList() {}
|
||||||
|
|
||||||
|
void serialize(std::ostream &os) const;
|
||||||
|
void deSerialize(std::istream &is);
|
||||||
|
|
||||||
|
// Get timer
|
||||||
|
NodeTimer get(v3s16 p){
|
||||||
|
std::map<v3s16, NodeTimer>::iterator n = m_data.find(p);
|
||||||
|
if(n == m_data.end())
|
||||||
|
return NodeTimer();
|
||||||
|
return n->second;
|
||||||
|
}
|
||||||
|
// Deletes timer
|
||||||
|
void remove(v3s16 p){
|
||||||
|
m_data.erase(p);
|
||||||
|
}
|
||||||
|
// Deletes old timer and sets a new one
|
||||||
|
void set(v3s16 p, NodeTimer t){
|
||||||
|
m_data[p] = t;
|
||||||
|
}
|
||||||
|
// Deletes all timers
|
||||||
|
void clear(){
|
||||||
|
m_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A step in time. Returns map of elapsed timers.
|
||||||
|
std::map<v3s16, f32> step(float dtime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<v3s16, NodeTimer> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1080,6 +1080,8 @@ static ContentFeatures read_content_features(lua_State *L, int index)
|
|||||||
"deprecated: use 'drop' field");
|
"deprecated: use 'drop' field");
|
||||||
warn_if_field_exists(L, index, "extra_dug_item_rarity",
|
warn_if_field_exists(L, index, "extra_dug_item_rarity",
|
||||||
"deprecated: use 'drop' field");
|
"deprecated: use 'drop' field");
|
||||||
|
warn_if_field_exists(L, index, "metadata_name",
|
||||||
|
"deprecated: use on_add and metadata callbacks");
|
||||||
|
|
||||||
// True for all ground-like things like stone and mud, false for eg. trees
|
// True for all ground-like things like stone and mud, false for eg. trees
|
||||||
getboolfield(L, index, "is_ground_content", f.is_ground_content);
|
getboolfield(L, index, "is_ground_content", f.is_ground_content);
|
||||||
@ -1096,8 +1098,6 @@ static ContentFeatures read_content_features(lua_State *L, int index)
|
|||||||
getboolfield(L, index, "climbable", f.climbable);
|
getboolfield(L, index, "climbable", f.climbable);
|
||||||
// Player can build on these
|
// Player can build on these
|
||||||
getboolfield(L, index, "buildable_to", f.buildable_to);
|
getboolfield(L, index, "buildable_to", f.buildable_to);
|
||||||
// Metadata name of node (eg. "furnace")
|
|
||||||
getstringfield(L, index, "metadata_name", f.metadata_name);
|
|
||||||
// Whether the node is non-liquid, source liquid or flowing liquid
|
// Whether the node is non-liquid, source liquid or flowing liquid
|
||||||
f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
|
f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
|
||||||
es_LiquidType, LIQUID_NONE);
|
es_LiquidType, LIQUID_NONE);
|
||||||
@ -1947,22 +1947,17 @@ private:
|
|||||||
return *(NodeMetaRef**)ud; // unbox pointer
|
return *(NodeMetaRef**)ud; // unbox pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
static NodeMetadata* getmeta(NodeMetaRef *ref)
|
static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create)
|
||||||
{
|
{
|
||||||
NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
|
NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
|
||||||
|
if(meta == NULL && auto_create)
|
||||||
|
{
|
||||||
|
meta = new NodeMetadata(ref->m_env->getGameDef());
|
||||||
|
ref->m_env->getMap().setNodeMetadata(ref->m_p, meta);
|
||||||
|
}
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
|
|
||||||
{
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL)
|
|
||||||
return NULL;
|
|
||||||
if(meta->typeId() != NODEMETA_GENERIC)
|
|
||||||
return NULL;
|
|
||||||
return (IGenericNodeMetadata*)meta;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
static void reportMetadataChange(NodeMetaRef *ref)
|
static void reportMetadataChange(NodeMetaRef *ref)
|
||||||
{
|
{
|
||||||
// Inform other things that the metadata has changed
|
// Inform other things that the metadata has changed
|
||||||
@ -1987,106 +1982,99 @@ private:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_type(self)
|
// get_string(self, name)
|
||||||
static int l_get_type(lua_State *L)
|
static int l_get_string(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
std::string name = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
if(meta == NULL){
|
if(meta == NULL){
|
||||||
lua_pushnil(L);
|
lua_pushlstring(L, "", 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Do it
|
std::string str = meta->getString(name);
|
||||||
lua_pushstring(L, meta->typeName());
|
lua_pushlstring(L, str.c_str(), str.size());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allows_text_input(self)
|
// set_string(self, name, var)
|
||||||
static int l_allows_text_input(lua_State *L)
|
static int l_set_string(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
std::string name = luaL_checkstring(L, 2);
|
||||||
if(meta == NULL) return 0;
|
size_t len = 0;
|
||||||
// Do it
|
const char *s = lua_tolstring(L, 3, &len);
|
||||||
lua_pushboolean(L, meta->allowsTextInput());
|
std::string str(s, len);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set_text(self, text)
|
NodeMetadata *meta = getmeta(ref, !str.empty());
|
||||||
static int l_set_text(lua_State *L)
|
if(meta == NULL || str == meta->getString(name))
|
||||||
{
|
return 0;
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
meta->setString(name, str);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string text = luaL_checkstring(L, 2);
|
|
||||||
meta->setText(text);
|
|
||||||
reportMetadataChange(ref);
|
reportMetadataChange(ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_text(self)
|
// get_int(self, name)
|
||||||
static int l_get_text(lua_State *L)
|
static int l_get_int(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
std::string name = lua_tostring(L, 2);
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string text = meta->getText();
|
|
||||||
lua_pushstring(L, text.c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_owner(self)
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
static int l_get_owner(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string owner = meta->getOwner();
|
|
||||||
lua_pushstring(L, owner.c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set_owner(self, string)
|
|
||||||
static int l_set_owner(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string owner = luaL_checkstring(L, 2);
|
|
||||||
meta->setOwner(owner);
|
|
||||||
reportMetadataChange(ref);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_allow_removal(self)
|
|
||||||
static int l_get_allow_removal(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL){
|
if(meta == NULL){
|
||||||
lua_pushboolean(L, true);
|
lua_pushnumber(L, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Do it
|
std::string str = meta->getString(name);
|
||||||
lua_pushboolean(L, !meta->nodeRemovalDisabled());
|
lua_pushnumber(L, stoi(str));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IGenericNodeMetadata interface */
|
// set_int(self, name, var)
|
||||||
|
static int l_set_int(lua_State *L)
|
||||||
// set_infotext(self, text)
|
|
||||||
static int l_set_infotext(lua_State *L)
|
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
std::string name = lua_tostring(L, 2);
|
||||||
if(meta == NULL) return 0;
|
int a = lua_tointeger(L, 3);
|
||||||
// Do it
|
std::string str = itos(a);
|
||||||
std::string text = luaL_checkstring(L, 2);
|
|
||||||
meta->setInfoText(text);
|
NodeMetadata *meta = getmeta(ref, true);
|
||||||
|
if(meta == NULL || str == meta->getString(name))
|
||||||
|
return 0;
|
||||||
|
meta->setString(name, str);
|
||||||
|
reportMetadataChange(ref);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_float(self, name)
|
||||||
|
static int l_get_float(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
std::string name = lua_tostring(L, 2);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
|
if(meta == NULL){
|
||||||
|
lua_pushnumber(L, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string str = meta->getString(name);
|
||||||
|
lua_pushnumber(L, stof(str));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_float(self, name, var)
|
||||||
|
static int l_set_float(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
std::string name = lua_tostring(L, 2);
|
||||||
|
float a = lua_tonumber(L, 3);
|
||||||
|
std::string str = ftos(a);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, true);
|
||||||
|
if(meta == NULL || str == meta->getString(name))
|
||||||
|
return 0;
|
||||||
|
meta->setString(name, str);
|
||||||
reportMetadataChange(ref);
|
reportMetadataChange(ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2095,140 +2083,132 @@ private:
|
|||||||
static int l_get_inventory(lua_State *L)
|
static int l_get_inventory(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
getmeta(ref, true); // try to ensure the metadata exists
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
InvRef::createNodeMeta(L, ref->m_p);
|
InvRef::createNodeMeta(L, ref->m_p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_inventory_draw_spec(self)
|
||||||
|
static int l_get_inventory_draw_spec(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
|
if(meta == NULL){
|
||||||
|
lua_pushlstring(L, "", 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string str = meta->getInventoryDrawSpec();
|
||||||
|
lua_pushlstring(L, str.c_str(), str.size());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// set_inventory_draw_spec(self, text)
|
// set_inventory_draw_spec(self, text)
|
||||||
static int l_set_inventory_draw_spec(lua_State *L)
|
static int l_set_inventory_draw_spec(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
size_t len = 0;
|
||||||
if(meta == NULL) return 0;
|
const char *s = lua_tolstring(L, 2, &len);
|
||||||
// Do it
|
std::string str(s, len);
|
||||||
std::string text = luaL_checkstring(L, 2);
|
|
||||||
meta->setInventoryDrawSpec(text);
|
NodeMetadata *meta = getmeta(ref, !str.empty());
|
||||||
|
if(meta == NULL || str == meta->getInventoryDrawSpec())
|
||||||
|
return 0;
|
||||||
|
meta->setInventoryDrawSpec(str);
|
||||||
reportMetadataChange(ref);
|
reportMetadataChange(ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_allow_text_input(self, text)
|
// get_form_spec(self)
|
||||||
static int l_set_allow_text_input(lua_State *L)
|
static int l_get_form_spec(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
// Do it
|
if(meta == NULL){
|
||||||
bool b = lua_toboolean(L, 2);
|
lua_pushlstring(L, "", 0);
|
||||||
meta->setAllowTextInput(b);
|
return 1;
|
||||||
|
}
|
||||||
|
std::string str = meta->getFormSpec();
|
||||||
|
lua_pushlstring(L, str.c_str(), str.size());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_form_spec(self, text)
|
||||||
|
static int l_set_form_spec(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
size_t len = 0;
|
||||||
|
const char *s = lua_tolstring(L, 2, &len);
|
||||||
|
std::string str(s, len);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, !str.empty());
|
||||||
|
if(meta == NULL || str == meta->getFormSpec())
|
||||||
|
return 0;
|
||||||
|
meta->setFormSpec(str);
|
||||||
reportMetadataChange(ref);
|
reportMetadataChange(ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_allow_removal(self, text)
|
// get_infotext(self)
|
||||||
|
static int l_get_infotext(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
|
if(meta == NULL){
|
||||||
|
lua_pushlstring(L, "", 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string str = meta->getInfoText();
|
||||||
|
lua_pushlstring(L, str.c_str(), str.size());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_infotext(self, text)
|
||||||
|
static int l_set_infotext(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
size_t len = 0;
|
||||||
|
const char *s = lua_tolstring(L, 2, &len);
|
||||||
|
std::string str(s, len);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, !str.empty());
|
||||||
|
if(meta == NULL || str == meta->getInfoText())
|
||||||
|
return 0;
|
||||||
|
meta->setInfoText(str);
|
||||||
|
reportMetadataChange(ref);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_allow_removal(self)
|
||||||
|
static int l_get_allow_removal(lua_State *L)
|
||||||
|
{
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
|
||||||
|
NodeMetadata *meta = getmeta(ref, false);
|
||||||
|
if(meta == NULL){
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua_pushboolean(L, meta->getAllowRemoval());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_allow_removal(self, flag)
|
||||||
static int l_set_allow_removal(lua_State *L)
|
static int l_set_allow_removal(lua_State *L)
|
||||||
{
|
{
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
NodeMetadata *meta = getmeta(ref);
|
bool flag = lua_toboolean(L, 2);
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
NodeMetadata *meta = getmeta(ref, flag != true);
|
||||||
bool b = lua_toboolean(L, 2);
|
if(meta == NULL || flag == meta->getAllowRemoval())
|
||||||
meta->setRemovalDisabled(!b);
|
return 0;
|
||||||
|
meta->setAllowRemoval(flag);
|
||||||
reportMetadataChange(ref);
|
reportMetadataChange(ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_enforce_owner(self, text)
|
|
||||||
static int l_set_enforce_owner(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
bool b = lua_toboolean(L, 2);
|
|
||||||
meta->setEnforceOwner(b);
|
|
||||||
reportMetadataChange(ref);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is_inventory_modified(self)
|
|
||||||
static int l_is_inventory_modified(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
lua_pushboolean(L, meta->isInventoryModified());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset_inventory_modified(self)
|
|
||||||
static int l_reset_inventory_modified(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
meta->resetInventoryModified();
|
|
||||||
reportMetadataChange(ref);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is_text_modified(self)
|
|
||||||
static int l_is_text_modified(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
lua_pushboolean(L, meta->isTextModified());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset_text_modified(self)
|
|
||||||
static int l_reset_text_modified(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
meta->resetTextModified();
|
|
||||||
reportMetadataChange(ref);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set_string(self, name, var)
|
|
||||||
static int l_set_string(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string name = luaL_checkstring(L, 2);
|
|
||||||
size_t len = 0;
|
|
||||||
const char *s = lua_tolstring(L, 3, &len);
|
|
||||||
std::string str(s, len);
|
|
||||||
meta->setString(name, str);
|
|
||||||
reportMetadataChange(ref);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_string(self, name)
|
|
||||||
static int l_get_string(lua_State *L)
|
|
||||||
{
|
|
||||||
NodeMetaRef *ref = checkobject(L, 1);
|
|
||||||
NodeMetadata *meta = getmeta(ref);
|
|
||||||
if(meta == NULL) return 0;
|
|
||||||
// Do it
|
|
||||||
std::string name = luaL_checkstring(L, 2);
|
|
||||||
std::string str = meta->getString(name);
|
|
||||||
lua_pushlstring(L, str.c_str(), str.size());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeMetaRef(v3s16 p, ServerEnvironment *env):
|
NodeMetaRef(v3s16 p, ServerEnvironment *env):
|
||||||
m_p(p),
|
m_p(p),
|
||||||
@ -2281,25 +2261,21 @@ public:
|
|||||||
};
|
};
|
||||||
const char NodeMetaRef::className[] = "NodeMetaRef";
|
const char NodeMetaRef::className[] = "NodeMetaRef";
|
||||||
const luaL_reg NodeMetaRef::methods[] = {
|
const luaL_reg NodeMetaRef::methods[] = {
|
||||||
method(NodeMetaRef, get_type),
|
|
||||||
method(NodeMetaRef, allows_text_input),
|
|
||||||
method(NodeMetaRef, set_text),
|
|
||||||
method(NodeMetaRef, get_text),
|
|
||||||
method(NodeMetaRef, get_owner),
|
|
||||||
method(NodeMetaRef, set_owner),
|
|
||||||
method(NodeMetaRef, get_allow_removal),
|
|
||||||
method(NodeMetaRef, set_infotext),
|
|
||||||
method(NodeMetaRef, get_inventory),
|
|
||||||
method(NodeMetaRef, set_inventory_draw_spec),
|
|
||||||
method(NodeMetaRef, set_allow_text_input),
|
|
||||||
method(NodeMetaRef, set_allow_removal),
|
|
||||||
method(NodeMetaRef, set_enforce_owner),
|
|
||||||
method(NodeMetaRef, is_inventory_modified),
|
|
||||||
method(NodeMetaRef, reset_inventory_modified),
|
|
||||||
method(NodeMetaRef, is_text_modified),
|
|
||||||
method(NodeMetaRef, reset_text_modified),
|
|
||||||
method(NodeMetaRef, set_string),
|
|
||||||
method(NodeMetaRef, get_string),
|
method(NodeMetaRef, get_string),
|
||||||
|
method(NodeMetaRef, set_string),
|
||||||
|
method(NodeMetaRef, get_int),
|
||||||
|
method(NodeMetaRef, set_int),
|
||||||
|
method(NodeMetaRef, get_float),
|
||||||
|
method(NodeMetaRef, set_float),
|
||||||
|
method(NodeMetaRef, get_inventory),
|
||||||
|
method(NodeMetaRef, get_inventory_draw_spec),
|
||||||
|
method(NodeMetaRef, set_inventory_draw_spec),
|
||||||
|
method(NodeMetaRef, get_form_spec),
|
||||||
|
method(NodeMetaRef, set_form_spec),
|
||||||
|
method(NodeMetaRef, get_infotext),
|
||||||
|
method(NodeMetaRef, set_infotext),
|
||||||
|
method(NodeMetaRef, get_allow_removal),
|
||||||
|
method(NodeMetaRef, set_allow_removal),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,12 +57,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
19: new content type handling
|
19: new content type handling
|
||||||
20: many existing content types translated to extended ones
|
20: many existing content types translated to extended ones
|
||||||
21: dynamic content type allocation
|
21: dynamic content type allocation
|
||||||
22: full 16-bit content types, minerals removed, facedir & wallmounted changed
|
22: minerals removed, facedir & wallmounted changed
|
||||||
|
23: NodeTimers, new node metadata format
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
// Highest supported serialization version
|
// Highest supported serialization version
|
||||||
#define SER_FMT_VER_HIGHEST 22
|
#define SER_FMT_VER_HIGHEST 23
|
||||||
// Lowest supported serialization version
|
// Lowest supported serialization version
|
||||||
#define SER_FMT_VER_LOWEST 0
|
#define SER_FMT_VER_LOWEST 0
|
||||||
|
|
||||||
|
@ -2417,47 +2417,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
else if(command == TOSERVER_SIGNNODETEXT)
|
else if(command == TOSERVER_SIGNNODETEXT)
|
||||||
{
|
{
|
||||||
if(!checkPriv(player->getName(), "interact"))
|
infostream<<"Server: SIGNNODETEXT not supported anymore"
|
||||||
|
<<std::endl;
|
||||||
return;
|
return;
|
||||||
/*
|
|
||||||
u16 command
|
|
||||||
v3s16 p
|
|
||||||
u16 textlen
|
|
||||||
textdata
|
|
||||||
*/
|
|
||||||
std::string datastring((char*)&data[2], datasize-2);
|
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
|
||||||
u8 buf[6];
|
|
||||||
// Read stuff
|
|
||||||
is.read((char*)buf, 6);
|
|
||||||
v3s16 p = readV3S16(buf);
|
|
||||||
is.read((char*)buf, 2);
|
|
||||||
u16 textlen = readU16(buf);
|
|
||||||
std::string text;
|
|
||||||
for(u16 i=0; i<textlen; i++)
|
|
||||||
{
|
|
||||||
is.read((char*)buf, 1);
|
|
||||||
text += (char)buf[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
|
|
||||||
if(!meta)
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta->setText(text);
|
|
||||||
|
|
||||||
actionstream<<player->getName()<<" writes \""<<text<<"\" to sign"
|
|
||||||
<<" at "<<PP(p)<<std::endl;
|
|
||||||
|
|
||||||
v3s16 blockpos = getNodeBlockPos(p);
|
|
||||||
MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
|
|
||||||
if(block)
|
|
||||||
{
|
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
|
||||||
"sign node text");
|
|
||||||
}
|
|
||||||
|
|
||||||
setBlockNotSent(blockpos);
|
|
||||||
}
|
}
|
||||||
else if(command == TOSERVER_INVENTORY_ACTION)
|
else if(command == TOSERVER_INVENTORY_ACTION)
|
||||||
{
|
{
|
||||||
@ -2540,7 +2502,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If player is not an admin, check for ownership of src and dst
|
// If player is not an admin, check for ownership of src and dst
|
||||||
if(!checkPriv(player->getName(), "server"))
|
/*if(!checkPriv(player->getName(), "server"))
|
||||||
{
|
{
|
||||||
std::string owner_from = getInventoryOwner(ma->from_inv);
|
std::string owner_from = getInventoryOwner(ma->from_inv);
|
||||||
if(owner_from != "" && owner_from != player->getName())
|
if(owner_from != "" && owner_from != player->getName())
|
||||||
@ -2561,7 +2523,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
delete a;
|
delete a;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Handle restrictions and special cases of the drop action
|
Handle restrictions and special cases of the drop action
|
||||||
@ -2581,7 +2543,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If player is not an admin, check for ownership
|
// If player is not an admin, check for ownership
|
||||||
else if(!checkPriv(player->getName(), "server"))
|
/*else if(!checkPriv(player->getName(), "server"))
|
||||||
{
|
{
|
||||||
std::string owner_from = getInventoryOwner(da->from_inv);
|
std::string owner_from = getInventoryOwner(da->from_inv);
|
||||||
if(owner_from != "" && owner_from != player->getName())
|
if(owner_from != "" && owner_from != player->getName())
|
||||||
@ -2592,7 +2554,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
delete a;
|
delete a;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Handle restrictions and special cases of the craft action
|
Handle restrictions and special cases of the craft action
|
||||||
@ -2619,7 +2581,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If player is not an admin, check for ownership of inventory
|
// If player is not an admin, check for ownership of inventory
|
||||||
if(!checkPriv(player->getName(), "server"))
|
/*if(!checkPriv(player->getName(), "server"))
|
||||||
{
|
{
|
||||||
std::string owner_craft = getInventoryOwner(ca->craft_inv);
|
std::string owner_craft = getInventoryOwner(ca->craft_inv);
|
||||||
if(owner_craft != "" && owner_craft != player->getName())
|
if(owner_craft != "" && owner_craft != player->getName())
|
||||||
@ -2630,7 +2592,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
delete a;
|
delete a;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the action
|
// Do the action
|
||||||
@ -3223,33 +3185,6 @@ Inventory* Server::getInventory(const InventoryLocation &loc)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::string Server::getInventoryOwner(const InventoryLocation &loc)
|
|
||||||
{
|
|
||||||
switch(loc.type){
|
|
||||||
case InventoryLocation::UNDEFINED:
|
|
||||||
{}
|
|
||||||
break;
|
|
||||||
case InventoryLocation::CURRENT_PLAYER:
|
|
||||||
{}
|
|
||||||
break;
|
|
||||||
case InventoryLocation::PLAYER:
|
|
||||||
{
|
|
||||||
return loc.name;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InventoryLocation::NODEMETA:
|
|
||||||
{
|
|
||||||
NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
|
|
||||||
if(!meta)
|
|
||||||
return "";
|
|
||||||
return meta->getOwner();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
void Server::setInventoryModified(const InventoryLocation &loc)
|
void Server::setInventoryModified(const InventoryLocation &loc)
|
||||||
{
|
{
|
||||||
switch(loc.type){
|
switch(loc.type){
|
||||||
@ -3272,10 +3207,6 @@ void Server::setInventoryModified(const InventoryLocation &loc)
|
|||||||
{
|
{
|
||||||
v3s16 blockpos = getNodeBlockPos(loc.p);
|
v3s16 blockpos = getNodeBlockPos(loc.p);
|
||||||
|
|
||||||
NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
|
|
||||||
if(meta)
|
|
||||||
meta->inventoryModified();
|
|
||||||
|
|
||||||
MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
|
MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
|
||||||
if(block)
|
if(block)
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
||||||
|
@ -483,7 +483,6 @@ public:
|
|||||||
Shall be called with the environment and the connection locked.
|
Shall be called with the environment and the connection locked.
|
||||||
*/
|
*/
|
||||||
Inventory* getInventory(const InventoryLocation &loc);
|
Inventory* getInventory(const InventoryLocation &loc);
|
||||||
std::string getInventoryOwner(const InventoryLocation &loc);
|
|
||||||
void setInventoryModified(const InventoryLocation &loc);
|
void setInventoryModified(const InventoryLocation &loc);
|
||||||
|
|
||||||
// Connection must be locked when called
|
// Connection must be locked when called
|
||||||
|
Loading…
Reference in New Issue
Block a user