forked from oerkki/voxelands
cooking redo pt1
This commit is contained in:
parent
4012698444
commit
f3175d55c0
|
@ -292,10 +292,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
|||
#define CONTENT_COUCH_CHAIR_BLACK 0x865
|
||||
#define CONTENT_CAULDRON 0x866
|
||||
#define CONTENT_CRUSHER 0x867
|
||||
#define CONTENT_CRUSHER_ACTIVE 0x868
|
||||
#define CONTENT_LOCKABLE_CRUSHER 0x869
|
||||
#define CONTENT_LOCKABLE_CRUSHER_ACTIVE 0x86A
|
||||
// FREE 86B-86F
|
||||
// FREE 868-86F
|
||||
#define CONTENT_FLAG 0x870
|
||||
#define CONTENT_FLAG_BLUE 0x871
|
||||
#define CONTENT_FLAG_GREEN 0x872
|
||||
|
|
|
@ -1457,71 +1457,10 @@ void content_mapnode_special(bool repeat)
|
|||
f->type = CMT_STONE;
|
||||
f->dig_time = 3.0;
|
||||
f->pressure_type = CST_SOLID;
|
||||
f->alternate_lockstate_node = CONTENT_LOCKABLE_CRUSHER;
|
||||
crafting::setFilledRoundRecipe(CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_CRAFTITEM_TIN_INGOT,CONTENT_CRUSHER);
|
||||
content_list_add("craftguide",i,1,0);
|
||||
content_list_add("creative",i,1,0);
|
||||
|
||||
i = CONTENT_CRUSHER_ACTIVE;
|
||||
f = &content_features(i);
|
||||
f->description = gettext("Crusher");
|
||||
f->param_type = CPT_FACEDIR_SIMPLE;
|
||||
f->draw_type = CDT_CUBELIKE;
|
||||
f->setAllTextures("crusher_side.png");
|
||||
f->setTexture(0, "crusher_top.png");
|
||||
f->setTexture(1, "crusher_top.png");
|
||||
f->setTexture(5, "crusher_front.png"); // Z-
|
||||
content_nodebox_activecrusher(f);
|
||||
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_CRUSHER)+" 1";
|
||||
if(f->initial_metadata == NULL)
|
||||
f->initial_metadata = new CrusherNodeMetadata();
|
||||
f->type = CMT_STONE;
|
||||
f->dig_time = 3.0;
|
||||
f->pressure_type = CST_SOLID;
|
||||
|
||||
i = CONTENT_LOCKABLE_CRUSHER;
|
||||
f = &content_features(i);
|
||||
f->description = gettext("Locking Crusher");
|
||||
f->param_type = CPT_FACEDIR_SIMPLE;
|
||||
f->draw_type = CDT_NODEBOX_META;
|
||||
f->setAllTextures("crusher_side.png");
|
||||
f->setTexture(0, "crusher_top.png");
|
||||
f->setTexture(1, "crusher_top.png^[transformFY");
|
||||
f->setTexture(2, "crusher_side.png^[transformFX");
|
||||
f->setTexture(4, "crusher_back.png");
|
||||
f->setTexture(5, "crusher_lock.png"); // Z-
|
||||
content_nodebox_lockedcrusher(f);
|
||||
f->setInventoryTextureNodeBox(i,"crusher_top.png^[transformR90", "crusher_lock.png", "crusher_side.png^[transformFX");
|
||||
f->rotate_tile_with_nodebox = true;
|
||||
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
|
||||
if(f->initial_metadata == NULL)
|
||||
f->initial_metadata = new LockingCrusherNodeMetadata();
|
||||
f->type = CMT_STONE;
|
||||
f->dig_time = 3.0;
|
||||
f->pressure_type = CST_SOLID;
|
||||
f->alternate_lockstate_node = CONTENT_CRUSHER;
|
||||
crafting::set1Any2Recipe(CONTENT_CRUSHER,CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_LOCKABLE_CRUSHER);
|
||||
content_list_add("craftguide",i,1,0);
|
||||
content_list_add("creative",i,1,0);
|
||||
|
||||
i = CONTENT_LOCKABLE_CRUSHER_ACTIVE;
|
||||
f = &content_features(i);
|
||||
f->description = gettext("Locking Crusher");
|
||||
f->param_type = CPT_FACEDIR_SIMPLE;
|
||||
f->draw_type = CDT_CUBELIKE;
|
||||
f->light_source = 9;
|
||||
f->setAllTextures("crusher_side.png");
|
||||
f->setTexture(0, "crusher_top.png");
|
||||
f->setTexture(1, "crusher_top.png");
|
||||
f->setTexture(5, "crusher_lock_active.png"); // Z-
|
||||
content_nodebox_activelockedcrusher(f);
|
||||
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_LOCKABLE_CRUSHER)+" 1";
|
||||
if(f->initial_metadata == NULL)
|
||||
f->initial_metadata = new LockingCrusherNodeMetadata();
|
||||
f->type = CMT_STONE;
|
||||
f->dig_time = 3.0;
|
||||
f->pressure_type = CST_SOLID;
|
||||
|
||||
i = CONTENT_NC;
|
||||
f = &content_features(i);
|
||||
f->description = gettext("Nyan Cat");
|
||||
|
|
|
@ -392,52 +392,24 @@ public:
|
|||
virtual std::string getDrawSpecString(Player *player);
|
||||
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
|
||||
|
||||
virtual bool import(NodeMetadata *meta);
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
float m_step_accumulator;
|
||||
float m_fuel_totaltime;
|
||||
float m_fuel_time;
|
||||
float m_src_totaltime;
|
||||
float m_src_time;
|
||||
};
|
||||
|
||||
class LockingCrusherNodeMetadata : public NodeMetadata
|
||||
{
|
||||
public:
|
||||
LockingCrusherNodeMetadata();
|
||||
~LockingCrusherNodeMetadata();
|
||||
|
||||
virtual u16 typeId() const;
|
||||
virtual NodeMetadata* clone();
|
||||
static NodeMetadata* create(std::istream &is);
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::wstring infoText();
|
||||
virtual Inventory* getInventory() {return m_inventory;}
|
||||
virtual void inventoryModified();
|
||||
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
|
||||
virtual bool nodeRemovalDisabled();
|
||||
virtual std::string getDrawSpecString(Player *player);
|
||||
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
|
||||
|
||||
virtual bool import(NodeMetadata *meta);
|
||||
|
||||
virtual std::string getOwner(){ return m_owner; }
|
||||
virtual std::string getOwner();
|
||||
virtual void setOwner(std::string t){ m_owner = t; }
|
||||
virtual std::string getInventoryOwner(){ return m_inv_owner; }
|
||||
virtual void setInventoryOwner(std::string t){ m_inv_owner = t; }
|
||||
virtual std::string getInventoryOwner();
|
||||
virtual void setInventoryOwner(std::string t){ m_owner = t; }
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
float m_step_accumulator;
|
||||
float m_fuel_totaltime;
|
||||
float m_fuel_time;
|
||||
float m_src_totaltime;
|
||||
float m_src_time;
|
||||
float m_active_timer;
|
||||
float m_burn_counter;
|
||||
float m_cook_timer;
|
||||
float m_step_interval;
|
||||
std::string m_owner;
|
||||
std::string m_inv_owner;
|
||||
float m_lock;
|
||||
bool m_is_locked;
|
||||
bool m_is_expanded;
|
||||
bool m_is_exo;
|
||||
float m_cook_upgrade;
|
||||
float m_burn_upgrade;
|
||||
uint16_t m_expanded_slot_id;
|
||||
};
|
||||
|
||||
class LockingFurnaceNodeMetadata : public NodeMetadata
|
||||
|
|
|
@ -836,13 +836,21 @@ CrusherNodeMetadata::CrusherNodeMetadata()
|
|||
m_inventory = new Inventory();
|
||||
m_inventory->addList("fuel", 1);
|
||||
m_inventory->addList("src", 1);
|
||||
m_inventory->addList("dst", 4);
|
||||
m_inventory->addList("main", 4);
|
||||
m_inventory->addList("upgrades", 2);
|
||||
|
||||
m_step_accumulator = 0;
|
||||
m_fuel_totaltime = 0;
|
||||
m_fuel_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
m_active_timer = 0.0;
|
||||
m_burn_counter = 0;
|
||||
m_cook_timer = 0.0;
|
||||
m_step_interval = 1.0;
|
||||
m_is_locked = false;
|
||||
m_is_expanded = false;
|
||||
m_is_exo = false;
|
||||
m_cook_upgrade = 1.0;
|
||||
m_burn_upgrade = 1.0;
|
||||
m_expanded_slot_id = 0;
|
||||
|
||||
inventoryModified();
|
||||
}
|
||||
CrusherNodeMetadata::~CrusherNodeMetadata()
|
||||
{
|
||||
|
@ -856,66 +864,107 @@ NodeMetadata* CrusherNodeMetadata::clone()
|
|||
{
|
||||
CrusherNodeMetadata *d = new CrusherNodeMetadata();
|
||||
*d->m_inventory = *m_inventory;
|
||||
d->m_fuel_totaltime = m_fuel_totaltime;
|
||||
d->m_fuel_time = m_fuel_time;
|
||||
d->m_src_totaltime = m_src_totaltime;
|
||||
d->m_src_time = m_src_time;
|
||||
|
||||
d->m_active_timer = m_active_timer;
|
||||
d->m_burn_counter = m_burn_counter;
|
||||
d->m_cook_timer = m_cook_timer;
|
||||
d->m_step_interval = m_step_interval;
|
||||
d->m_is_locked = m_is_locked;
|
||||
d->m_is_expanded = m_is_expanded;
|
||||
d->m_is_exo = m_is_exo;
|
||||
d->m_cook_upgrade = m_cook_upgrade;
|
||||
d->m_burn_upgrade = m_burn_upgrade;
|
||||
d->m_expanded_slot_id = m_expanded_slot_id;
|
||||
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* CrusherNodeMetadata::create(std::istream &is)
|
||||
{
|
||||
std::string s;
|
||||
CrusherNodeMetadata *d = new CrusherNodeMetadata();
|
||||
|
||||
d->m_inventory->deSerialize(is);
|
||||
d->setOwner(deSerializeString(is));
|
||||
|
||||
int temp;
|
||||
is>>temp;
|
||||
d->m_fuel_totaltime = (float)temp/10;
|
||||
is>>temp;
|
||||
d->m_fuel_time = (float)temp/10;
|
||||
s = deSerializeString(is);
|
||||
d->m_active_timer = mystof(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_burn_counter = mystoi(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_cook_timer = mystof(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_step_interval = mystof(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_is_locked = !!mystoi(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_is_expanded = !!mystoi(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_is_exo = !!mystoi(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_cook_upgrade = mystof(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_burn_upgrade = mystof(s);
|
||||
|
||||
s = deSerializeString(is);
|
||||
d->m_expanded_slot_id = mystoi(s);
|
||||
|
||||
if (d->m_is_expanded) {
|
||||
delete d->m_inventory;
|
||||
d->m_inventory = new Inventory();
|
||||
d->m_inventory->addList("fuel", 1);
|
||||
d->m_inventory->addList("src", 1);
|
||||
d->m_inventory->addList("main", 18);
|
||||
d->m_inventory->addList("upgrades", 2);
|
||||
}
|
||||
d->m_inventory->deSerialize(is);
|
||||
d->inventoryModified();
|
||||
|
||||
return d;
|
||||
}
|
||||
void CrusherNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
os<<serializeString(m_owner);
|
||||
os<<serializeString(ftos(m_active_timer));
|
||||
os<<serializeString(itos(m_burn_counter));
|
||||
os<<serializeString(ftos(m_cook_timer));
|
||||
os<<serializeString(ftos(m_step_interval));
|
||||
os<<serializeString(itos(m_is_locked ? 1 : 0));
|
||||
os<<serializeString(itos(m_is_expanded ? 1 : 0));
|
||||
os<<serializeString(itos(m_is_exo ? 1 : 0));
|
||||
os<<serializeString(ftos(m_cook_upgrade));
|
||||
os<<serializeString(ftos(m_burn_upgrade));
|
||||
os<<serializeString(itos(m_expanded_slot_id));
|
||||
m_inventory->serialize(os);
|
||||
os<<itos(m_fuel_totaltime*10)<<" ";
|
||||
os<<itos(m_fuel_time*10)<<" ";
|
||||
}
|
||||
std::wstring CrusherNodeMetadata::infoText()
|
||||
{
|
||||
//return "Crusher";
|
||||
if (m_fuel_time >= m_fuel_totaltime) {
|
||||
const InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
const InventoryItem *src_item = src_list->getItem(0);
|
||||
|
||||
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
if(!dst_list->roomForCrushedItem(src_item))
|
||||
return narrow_to_wide(gettext("Crusher is overloaded"));
|
||||
return narrow_to_wide(gettext("Crusher is out of fuel"));
|
||||
}else{
|
||||
return narrow_to_wide(gettext("Crusher is inactive"));
|
||||
}
|
||||
char buff[256];
|
||||
if (m_is_locked) {
|
||||
snprintf(buff, 256, gettext("Locked Crusher owned by '%s'"), m_owner.c_str());
|
||||
}else if (m_is_exo) {
|
||||
snprintf(buff, 256, gettext("Exo Crusher"));
|
||||
}else{
|
||||
std::wstring s = narrow_to_wide(gettext("Crusher is active"));
|
||||
// Do this so it doesn't always show (0%) for weak fuel
|
||||
if (m_fuel_totaltime > 3) {
|
||||
s += L" (";
|
||||
s += itows(m_fuel_time/m_fuel_totaltime*100);
|
||||
s += L"%)";
|
||||
}
|
||||
return s;
|
||||
snprintf(buff, 256, gettext("Crusher"));
|
||||
}
|
||||
return narrow_to_wide(buff);
|
||||
}
|
||||
bool CrusherNodeMetadata::nodeRemovalDisabled()
|
||||
{
|
||||
/*
|
||||
Disable removal if crusher is not empty
|
||||
*/
|
||||
InventoryList *list[3] = {m_inventory->getList("src"),
|
||||
m_inventory->getList("dst"), m_inventory->getList("fuel")};
|
||||
InventoryList *list[3] = {
|
||||
m_inventory->getList("src"),
|
||||
m_inventory->getList("main"),
|
||||
m_inventory->getList("fuel")
|
||||
};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (list[i] == NULL)
|
||||
|
@ -929,124 +978,267 @@ bool CrusherNodeMetadata::nodeRemovalDisabled()
|
|||
}
|
||||
void CrusherNodeMetadata::inventoryModified()
|
||||
{
|
||||
vlprintf(CN_INFO,"Crusher inventory modification callback");
|
||||
int i;
|
||||
int k;
|
||||
int a[3] = {1,1,1};
|
||||
int b[3] = {0,0,0};
|
||||
Inventory *inv;
|
||||
InventoryList *il;
|
||||
InventoryList *im;
|
||||
InventoryItem *itm;
|
||||
InventoryList *l = m_inventory->getList("upgrades");
|
||||
InventoryList *m = m_inventory->getList("main");
|
||||
if (!l || !m)
|
||||
return;
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
itm = l->getItem(i);
|
||||
if (!itm)
|
||||
continue;
|
||||
if (itm->getContent() == CONTENT_CHEST) {
|
||||
if (m_is_expanded) {
|
||||
b[0] = 1;
|
||||
continue;
|
||||
}
|
||||
if (m_is_exo)
|
||||
continue;
|
||||
inv = new Inventory();
|
||||
inv->addList("upgrades", 2);
|
||||
inv->addList("main", 36);
|
||||
il = inv->getList("upgrades");
|
||||
im = inv->getList("main");
|
||||
if (!il || !im) {
|
||||
delete inv;
|
||||
continue;
|
||||
}
|
||||
for (k=0; k<2; k++) {
|
||||
itm = l->changeItem(k,NULL);
|
||||
if (itm)
|
||||
il->addItem(k,itm);
|
||||
}
|
||||
for (k=0; k<18; k++) {
|
||||
itm = m->changeItem(k,NULL);
|
||||
if (itm)
|
||||
im->addItem(k,itm);
|
||||
}
|
||||
delete m_inventory;
|
||||
m_inventory = inv;
|
||||
l = il;
|
||||
m = im;
|
||||
a[2] = 0;
|
||||
b[0] = 1;
|
||||
m_is_expanded = true;
|
||||
m_expanded_slot_id = i;
|
||||
}else if (itm->getContent() == CONTENT_CRAFTITEM_PADLOCK) {
|
||||
if (m_is_exo)
|
||||
continue;
|
||||
a[2] = 0;
|
||||
b[1] = 1;
|
||||
m_is_locked = true;
|
||||
}else if (itm->getContent() == CONTENT_CRAFTITEM_OERKKI_DUST) {
|
||||
if (m_is_exo) {
|
||||
b[2] = 1;
|
||||
continue;
|
||||
}
|
||||
if (m->getUsedSlots() != 0)
|
||||
continue;
|
||||
if (l->getUsedSlots() != 1)
|
||||
continue;
|
||||
if (m_is_locked)
|
||||
continue;
|
||||
if (m_is_expanded)
|
||||
continue;
|
||||
m_is_exo = true;
|
||||
a[0] = 0;
|
||||
a[1] = 0;
|
||||
b[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_is_expanded && !b[0]) {
|
||||
inv = new Inventory();
|
||||
inv->addList("upgrades", 2);
|
||||
inv->addList("main", 18);
|
||||
il = inv->getList("upgrades");
|
||||
im = inv->getList("main");
|
||||
if (!il || !im) {
|
||||
delete inv;
|
||||
}else{
|
||||
for (k=0; k<2; k++) {
|
||||
itm = l->changeItem(k,NULL);
|
||||
if (itm)
|
||||
il->addItem(k,itm);
|
||||
}
|
||||
for (k=0; k<36; k++) {
|
||||
itm = m->changeItem(k,NULL);
|
||||
if (itm) {
|
||||
if (k > 17) {
|
||||
im->addItem(itm);
|
||||
}else{
|
||||
im->addItem(k,itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete m_inventory;
|
||||
m_inventory = inv;
|
||||
l = il;
|
||||
m = im;
|
||||
m_is_expanded = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_is_locked && !b[1])
|
||||
m_is_locked = false;
|
||||
|
||||
if (m_is_exo && !b[2])
|
||||
m_is_exo = false;
|
||||
|
||||
if (m_is_expanded || m_is_locked || m->getUsedSlots() != 0)
|
||||
a[2] = 0;
|
||||
|
||||
l->clearAllowed();
|
||||
if (a[0])
|
||||
l->addAllowed(CONTENT_CHEST);
|
||||
if (a[1])
|
||||
l->addAllowed(CONTENT_CRAFTITEM_PADLOCK);
|
||||
if (a[2])
|
||||
l->addAllowed(CONTENT_CRAFTITEM_OERKKI_DUST);
|
||||
}
|
||||
bool CrusherNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
|
||||
{
|
||||
{
|
||||
MapNode n = env->getMap().getNodeNoEx(pos).getContent();
|
||||
if (n.getContent() == CONTENT_CRUSHER_ACTIVE) {
|
||||
n.param1 = n.param2;
|
||||
n.setContent(CONTENT_CRUSHER);
|
||||
env->setPostStepNodeSwap(pos,n);
|
||||
}
|
||||
}
|
||||
float cook_time;
|
||||
bool changed = false;
|
||||
bool is_cooking;
|
||||
bool cook_ongoing;
|
||||
bool room_available;
|
||||
InventoryList *dst_list;
|
||||
InventoryList *src_list;
|
||||
InventoryItem *src_item;
|
||||
InventoryList *fuel_list;
|
||||
InventoryItem *fuel_item;
|
||||
|
||||
if (dtime > 60.0)
|
||||
vlprintf(CN_INFO,"Crusher stepping a long time (%f)",dtime);
|
||||
// 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;
|
||||
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
assert(dst_list);
|
||||
if (m_is_exo) {
|
||||
Player *p = env->getPlayer(m_owner.c_str());
|
||||
if (!p)
|
||||
return false;
|
||||
dst_list = p->inventory.getList("exo");
|
||||
}else{
|
||||
dst_list = m_inventory->getList("dst");
|
||||
}
|
||||
if (!dst_list)
|
||||
return false;
|
||||
|
||||
InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
InventoryItem *src_item = src_list->getItem(0);
|
||||
src_list = m_inventory->getList("src");
|
||||
if (!src_list)
|
||||
return false;
|
||||
|
||||
bool room_available = false;
|
||||
m_active_timer += dtime;
|
||||
|
||||
if (src_item && src_item->isCrushable(CRUSH_CRUSHER))
|
||||
room_available = dst_list->roomForCrushedItem(src_item);
|
||||
if (m_cook_upgrade < 1.0)
|
||||
m_cook_upgrade = 1.0;
|
||||
if (m_burn_upgrade < 1.0)
|
||||
m_burn_upgrade = 1.0;
|
||||
|
||||
// Start only if there are free slots in dst, so that it can
|
||||
// accomodate any result item
|
||||
if (room_available) {
|
||||
m_src_totaltime = 3;
|
||||
}else{
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
/* cook_upgrade/cook_time determines time to cook one item */
|
||||
/* burn_upgrade/burn_time determines number of items that fuel can cook */
|
||||
|
||||
/*
|
||||
If fuel is burning, increment the burn counters.
|
||||
If item finishes crushing, move it to result.
|
||||
*/
|
||||
if (m_fuel_time < m_fuel_totaltime) {
|
||||
m_fuel_time += dtime;
|
||||
m_src_time += dtime;
|
||||
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
|
||||
InventoryItem *crushresult = src_item->createCrushResult();
|
||||
dst_list->addItem(crushresult);
|
||||
src_list->decrementMaterials(1);
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
changed = true;
|
||||
cook_time = 4.0/m_cook_upgrade;
|
||||
if (cook_time < 0.1)
|
||||
cook_time = 0.1;
|
||||
|
||||
// If the fuel was not used up this step, just keep burning it
|
||||
if (m_fuel_time < m_fuel_totaltime)
|
||||
continue;
|
||||
}
|
||||
if (cook_time < m_step_interval)
|
||||
m_step_interval = cook_time;
|
||||
|
||||
while (m_active_timer > m_step_interval) {
|
||||
m_active_timer -= m_step_interval;
|
||||
|
||||
is_cooking = false;
|
||||
cook_ongoing = false;
|
||||
room_available = false;
|
||||
|
||||
/*
|
||||
Get the source again in case it has all burned
|
||||
*/
|
||||
src_item = src_list->getItem(0);
|
||||
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
|
||||
is_cooking = true;
|
||||
room_available = dst_list->roomForCrushedItem(src_item);
|
||||
if (room_available && src_item->getCount() > 1)
|
||||
cook_ongoing = true;
|
||||
}else{
|
||||
m_cook_timer = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
If there is no source item, or the source item is not crushable,
|
||||
or the crusher is still cooking, or the crusher became overloaded, stop loop.
|
||||
*/
|
||||
if (
|
||||
src_item == NULL
|
||||
|| !room_available
|
||||
|| m_fuel_time < m_fuel_totaltime
|
||||
|| dst_list->roomForCrushedItem(src_item) == false
|
||||
) {
|
||||
m_step_accumulator = 0;
|
||||
if (m_cook_timer > cook_time)
|
||||
m_cook_timer = cook_time;
|
||||
|
||||
if (m_burn_counter <= 0.0 && cook_ongoing) {
|
||||
fuel_list = m_inventory->getList("fuel");
|
||||
if (!fuel_list)
|
||||
break;
|
||||
fuel_item = fuel_list->getItem(0);
|
||||
if (fuel_item && fuel_item->isFuel()) {
|
||||
content_t c = fuel_item->getContent();
|
||||
if ((c&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
|
||||
m_burn_counter = ((CraftItem*)fuel_item)->getFuelTime();
|
||||
}else if ((c&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
m_burn_counter = ((ToolItem*)fuel_item)->getFuelTime();
|
||||
}else{
|
||||
m_burn_counter = ((MaterialItem*)fuel_item)->getFuelTime();
|
||||
}
|
||||
fuel_list->decrementMaterials(1);
|
||||
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
|
||||
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
|
||||
}
|
||||
m_burn_counter *= m_burn_upgrade;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_burn_counter <= 0.0) {
|
||||
m_active_timer = 0.0;
|
||||
m_burn_counter = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
//vlprintf(CN_INFO,"Crusher is out of fuel");
|
||||
m_burn_counter -= m_step_interval;
|
||||
|
||||
InventoryList *fuel_list = m_inventory->getList("fuel");
|
||||
assert(fuel_list);
|
||||
InventoryItem *fuel_item = fuel_list->getItem(0);
|
||||
if (fuel_item && fuel_item->isFuel()) {
|
||||
if ((fuel_item->getContent()&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
|
||||
m_fuel_totaltime = ((CraftItem*)fuel_item)->getFuelTime();
|
||||
}else if ((fuel_item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
m_fuel_totaltime = ((ToolItem*)fuel_item)->getFuelTime();
|
||||
}else{
|
||||
m_fuel_totaltime = ((MaterialItem*)fuel_item)->getFuelTime();
|
||||
if (!is_cooking) {
|
||||
m_cook_timer = 0.0;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_cook_timer += m_step_interval;
|
||||
|
||||
if (m_cook_timer >= cook_time) {
|
||||
m_cook_timer -= cook_time;
|
||||
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
|
||||
InventoryItem *crushresult = src_item->createCrushResult();
|
||||
dst_list->addItem(crushresult);
|
||||
src_list->decrementMaterials(1);
|
||||
changed = true;
|
||||
}
|
||||
m_fuel_time = 0;
|
||||
content_t c = fuel_item->getContent();
|
||||
fuel_list->decrementMaterials(1);
|
||||
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
|
||||
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
|
||||
}
|
||||
changed = true;
|
||||
}else{
|
||||
m_step_accumulator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
std::string CrusherNodeMetadata::getDrawSpecString(Player *player)
|
||||
{
|
||||
float cook_time;
|
||||
|
||||
if (m_cook_upgrade < 1.0)
|
||||
m_cook_upgrade = 1.0;
|
||||
cook_time = 4.0/m_cook_upgrade;
|
||||
if (cook_time < 0.1)
|
||||
cook_time = 0.1;
|
||||
|
||||
std::string spec("size[8,9]");
|
||||
spec += "list[current_name;fuel;2,3;1,1;]";
|
||||
spec += "ring[2,3;1;#FF0000;";
|
||||
float v = 0;
|
||||
if (m_fuel_totaltime > 0.0)
|
||||
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
|
||||
if (m_burn_counter > 0.0 && m_cook_timer > 0.0)
|
||||
v = 100.0-((100.0/cook_time)*m_cook_timer);
|
||||
spec += itos((int)v);
|
||||
spec += "]";
|
||||
spec += "list[current_name;src;2,1;1,1;]";
|
||||
|
@ -1059,7 +1251,7 @@ std::vector<NodeBox> CrusherNodeMetadata::getNodeBoxes(MapNode &n)
|
|||
std::vector<NodeBox> boxes;
|
||||
boxes.clear();
|
||||
|
||||
if (m_fuel_time < m_fuel_totaltime) {
|
||||
if (m_burn_counter > 0.0) {
|
||||
boxes.push_back(NodeBox(
|
||||
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
|
||||
));
|
||||
|
@ -1067,295 +1259,15 @@ std::vector<NodeBox> CrusherNodeMetadata::getNodeBoxes(MapNode &n)
|
|||
|
||||
return transformNodeBox(n,boxes);
|
||||
}
|
||||
bool CrusherNodeMetadata::import(NodeMetadata *meta)
|
||||
std::string CrusherNodeMetadata::getOwner()
|
||||
{
|
||||
if (meta->typeId() != CONTENT_LOCKABLE_CRUSHER)
|
||||
return false;
|
||||
LockingCrusherNodeMetadata *l = (LockingCrusherNodeMetadata*)meta;
|
||||
*m_inventory = *l->getInventory();
|
||||
return true;
|
||||
if (m_is_locked)
|
||||
return m_owner;
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
LockingCrusherNodeMetadata
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
LockingCrusherNodeMetadata proto_LockingCrusherNodeMetadata;
|
||||
|
||||
LockingCrusherNodeMetadata::LockingCrusherNodeMetadata()
|
||||
std::string CrusherNodeMetadata::getInventoryOwner()
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), create);
|
||||
|
||||
m_inventory = new Inventory();
|
||||
m_inventory->addList("fuel", 1);
|
||||
m_inventory->addList("src", 1);
|
||||
m_inventory->addList("dst", 4);
|
||||
|
||||
m_step_accumulator = 0;
|
||||
m_fuel_totaltime = 0;
|
||||
m_fuel_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
m_lock = 0;
|
||||
}
|
||||
LockingCrusherNodeMetadata::~LockingCrusherNodeMetadata()
|
||||
{
|
||||
delete m_inventory;
|
||||
}
|
||||
u16 LockingCrusherNodeMetadata::typeId() const
|
||||
{
|
||||
return CONTENT_LOCKABLE_CRUSHER;
|
||||
}
|
||||
NodeMetadata* LockingCrusherNodeMetadata::clone()
|
||||
{
|
||||
LockingCrusherNodeMetadata *d = new LockingCrusherNodeMetadata();
|
||||
*d->m_inventory = *m_inventory;
|
||||
d->m_fuel_totaltime = m_fuel_totaltime;
|
||||
d->m_fuel_time = m_fuel_time;
|
||||
d->m_src_totaltime = m_src_totaltime;
|
||||
d->m_src_time = m_src_time;
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* LockingCrusherNodeMetadata::create(std::istream &is)
|
||||
{
|
||||
LockingCrusherNodeMetadata *d = new LockingCrusherNodeMetadata();
|
||||
|
||||
d->m_inventory->deSerialize(is);
|
||||
d->setOwner(deSerializeString(is));
|
||||
d->setInventoryOwner(deSerializeString(is));
|
||||
|
||||
int temp;
|
||||
is>>temp;
|
||||
d->m_fuel_totaltime = (float)temp/10;
|
||||
is>>temp;
|
||||
d->m_fuel_time = (float)temp/10;
|
||||
is>>temp;
|
||||
d->m_lock = (float)temp/10;
|
||||
|
||||
return d;
|
||||
}
|
||||
void LockingCrusherNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
m_inventory->serialize(os);
|
||||
os<<serializeString(m_owner);
|
||||
os<<serializeString(m_inv_owner);
|
||||
os<<itos(m_fuel_totaltime*10)<<" ";
|
||||
os<<itos(m_fuel_time*10)<<" ";
|
||||
os<<itos(m_lock*10)<<" ";
|
||||
}
|
||||
std::wstring LockingCrusherNodeMetadata::infoText()
|
||||
{
|
||||
char buff[256];
|
||||
char* s;
|
||||
char e[128];
|
||||
std::string ostr = m_owner;
|
||||
|
||||
e[0] = 0;
|
||||
|
||||
if (m_inv_owner != "")
|
||||
ostr += ","+m_inv_owner;
|
||||
|
||||
if (m_fuel_time >= m_fuel_totaltime) {
|
||||
const InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
const InventoryItem *src_item = src_list->getItem(0);
|
||||
|
||||
if(src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
if (!dst_list->roomForCrushedItem(src_item)) {
|
||||
s = gettext("Locking Crusher is overloaded");
|
||||
}else{
|
||||
s = gettext("Locking Crusher is out of fuel");
|
||||
}
|
||||
}else{
|
||||
s = gettext("Locking Crusher is inactive");
|
||||
}
|
||||
}else{
|
||||
s = gettext("Locking Crusher is active");
|
||||
// Do this so it doesn't always show (0%) for weak fuel
|
||||
if (m_fuel_totaltime > 3) {
|
||||
uint32_t tt = m_fuel_time/m_fuel_totaltime*100;
|
||||
snprintf(e,128, " (%d%%)",tt);
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buff,256,"%s (%s)%s",s,ostr.c_str(),e);
|
||||
return narrow_to_wide(buff);
|
||||
}
|
||||
bool LockingCrusherNodeMetadata::nodeRemovalDisabled()
|
||||
{
|
||||
/*
|
||||
Disable removal if crusher 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 LockingCrusherNodeMetadata::inventoryModified()
|
||||
{
|
||||
vlprintf(CN_INFO,"LockingCrusher inventory modification callback");
|
||||
}
|
||||
bool LockingCrusherNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
|
||||
{
|
||||
{
|
||||
MapNode n = env->getMap().getNodeNoEx(pos);
|
||||
if (n.getContent() == CONTENT_LOCKABLE_CRUSHER_ACTIVE) {
|
||||
n.param1 = n.param2;
|
||||
n.setContent(CONTENT_LOCKABLE_CRUSHER);
|
||||
env->setPostStepNodeSwap(pos,n);
|
||||
}
|
||||
}
|
||||
if (dtime > 60.0)
|
||||
vlprintf(CN_INFO,"LockingCrusher stepping a long time (%f)",dtime);
|
||||
// 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<<"Crusher step dtime="<<dtime<<std::endl;
|
||||
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
assert(dst_list);
|
||||
|
||||
InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
InventoryItem *src_item = src_list->getItem(0);
|
||||
|
||||
bool room_available = false;
|
||||
|
||||
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
|
||||
room_available = dst_list->roomForCrushedItem(src_item);
|
||||
m_lock = 300.0;
|
||||
changed = true;
|
||||
}else if (m_lock < 0.0) {
|
||||
setInventoryOwner("");
|
||||
changed = true;
|
||||
}else{
|
||||
m_lock -= dtime;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Start only if there are free slots in dst, so that it can
|
||||
// accomodate any result item
|
||||
if (room_available) {
|
||||
m_src_totaltime = 3;
|
||||
}else{
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
If fuel is burning, increment the burn counters.
|
||||
If item finishes cooking, move it to result.
|
||||
*/
|
||||
if (m_fuel_time < m_fuel_totaltime) {
|
||||
m_fuel_time += dtime;
|
||||
m_src_time += dtime;
|
||||
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
|
||||
InventoryItem *crushresult = src_item->createCrushResult();
|
||||
dst_list->addItem(crushresult);
|
||||
src_list->decrementMaterials(1);
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
changed = true;
|
||||
|
||||
// If the fuel was not used up this step, just keep burning it
|
||||
if (m_fuel_time < m_fuel_totaltime)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the source again in case it has all burned
|
||||
*/
|
||||
src_item = src_list->getItem(0);
|
||||
|
||||
/*
|
||||
If there is no source item, or the source item is not crushable,
|
||||
or the crusher is still cooking, or the crusher became overloaded, stop loop.
|
||||
*/
|
||||
if (
|
||||
src_item == NULL
|
||||
|| !room_available ||
|
||||
m_fuel_time < m_fuel_totaltime
|
||||
|| dst_list->roomForCrushedItem(src_item) == false
|
||||
) {
|
||||
m_step_accumulator = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//vlprintf(CN_INFO,"Crusher is out of fuel");
|
||||
|
||||
InventoryList *fuel_list = m_inventory->getList("fuel");
|
||||
assert(fuel_list);
|
||||
InventoryItem *fuel_item = fuel_list->getItem(0);
|
||||
if (fuel_item && fuel_item->isFuel()) {
|
||||
if ((fuel_item->getContent()&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
|
||||
m_fuel_totaltime = ((CraftItem*)fuel_item)->getFuelTime();
|
||||
}else if ((fuel_item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
m_fuel_totaltime = ((ToolItem*)fuel_item)->getFuelTime();
|
||||
}else{
|
||||
m_fuel_totaltime = ((MaterialItem*)fuel_item)->getFuelTime();
|
||||
}
|
||||
m_fuel_time = 0;
|
||||
content_t c = fuel_item->getContent();
|
||||
fuel_list->decrementMaterials(1);
|
||||
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
|
||||
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
|
||||
}
|
||||
changed = true;
|
||||
}else{
|
||||
m_step_accumulator = 0;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
std::string LockingCrusherNodeMetadata::getDrawSpecString(Player *player)
|
||||
{
|
||||
std::string spec("size[8,9]");
|
||||
spec += "list[current_name;fuel;2,3;1,1;]";
|
||||
spec += "ring[2,3;1;#FF0000;";
|
||||
float v = 0;
|
||||
if (m_fuel_totaltime > 0.0)
|
||||
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
|
||||
spec += itos((int)v);
|
||||
spec += "]";
|
||||
spec += "list[current_name;src;2,1;1,1;]";
|
||||
spec += "list[current_name;dst;5,1;2,2;]";
|
||||
spec += "list[current_player;main;0,5;8,4;]";
|
||||
return spec;
|
||||
}
|
||||
std::vector<NodeBox> LockingCrusherNodeMetadata::getNodeBoxes(MapNode &n)
|
||||
{
|
||||
std::vector<NodeBox> boxes;
|
||||
boxes.clear();
|
||||
|
||||
if (m_fuel_time < m_fuel_totaltime) {
|
||||
boxes.push_back(NodeBox(
|
||||
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
|
||||
));
|
||||
}
|
||||
|
||||
return transformNodeBox(n,boxes);
|
||||
}
|
||||
bool LockingCrusherNodeMetadata::import(NodeMetadata *meta)
|
||||
{
|
||||
if (meta->typeId() != CONTENT_CRUSHER)
|
||||
return false;
|
||||
CrusherNodeMetadata *l = (CrusherNodeMetadata*)meta;
|
||||
*m_inventory = *l->getInventory();
|
||||
return true;
|
||||
if (m_is_locked)
|
||||
return m_owner;
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -3087,7 +3087,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|| meta->typeId() == CONTENT_LOCKABLE_SIGN_WALL
|
||||
|| meta->typeId() == CONTENT_LOCKABLE_SIGN_UD
|
||||
|| meta->typeId() == CONTENT_LOCKABLE_FURNACE
|
||||
|| meta->typeId() == CONTENT_LOCKABLE_CRUSHER
|
||||
|| meta->typeId() == CONTENT_FLAG
|
||||
|| meta->typeId() == CONTENT_FLAG_BLUE
|
||||
|| meta->typeId() == CONTENT_FLAG_GREEN
|
||||
|
@ -3098,6 +3097,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|| meta->typeId() == CONTENT_FLAG_BLACK
|
||||
|| meta->typeId() == CONTENT_SAFE
|
||||
)
|
||||
&& meta->getOwner() != ""
|
||||
&& meta->getOwner() != player->getName()
|
||||
) {
|
||||
infostream<<"Player "<<player->getName()<<" cannot remove node: not node owner"<<std::endl;
|
||||
|
@ -4398,7 +4398,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
p.Z = mystoi(fn.next(","));
|
||||
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
|
||||
if (meta) {
|
||||
if (meta->typeId() == CONTENT_LOCKABLE_CHEST_DEPRECATED) {
|
||||
if (meta->typeId() == CONTENT_CHEST) {
|
||||
ChestNodeMetadata *lcm = (ChestNodeMetadata*)meta;
|
||||
if (lcm->getInventoryOwner() != "" && lcm->getInventoryOwner() != player->getName())
|
||||
return;
|
||||
}else if (meta->typeId() == CONTENT_CRUSHER) {
|
||||
CrusherNodeMetadata *lcm = (CrusherNodeMetadata*)meta;
|
||||
if (lcm->getInventoryOwner() != "" && lcm->getInventoryOwner() != player->getName())
|
||||
return;
|
||||
}else if (meta->typeId() == CONTENT_LOCKABLE_CHEST_DEPRECATED) {
|
||||
LockingDeprecatedChestNodeMetadata *lcm = (LockingDeprecatedChestNodeMetadata*)meta;
|
||||
if (lcm->getInventoryOwner() != player->getName())
|
||||
return;
|
||||
|
@ -4407,11 +4415,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
std::string name = lfm->getInventoryOwner();
|
||||
if (name != "" && name != player->getName() && lfm->getOwner() != player->getName())
|
||||
return;
|
||||
}else if (meta->typeId() == CONTENT_LOCKABLE_CRUSHER) {
|
||||
LockingCrusherNodeMetadata *lfm = (LockingCrusherNodeMetadata*)meta;
|
||||
std::string name = lfm->getInventoryOwner();
|
||||
if (name != "" && name != player->getName() && lfm->getOwner() != player->getName())
|
||||
return;
|
||||
}else if (meta->typeId() == CONTENT_SAFE) {
|
||||
SafeNodeMetadata *sm = (SafeNodeMetadata*)meta;
|
||||
std::string name = sm->getInventoryOwner();
|
||||
|
|
Loading…
Reference in New Issue