improved bucket functionality

master
darkrose 2017-07-21 21:13:02 +10:00
parent 8574d3d6b1
commit 3faa17bc43
7 changed files with 182 additions and 152 deletions

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 392 B

View File

@ -180,6 +180,7 @@ int get_tool_use(tooluse_t *info, content_t target, uint16_t data, content_t too
break; break;
case TT_BUCKET: case TT_BUCKET:
if (c_features->type == CMT_LIQUID) { if (c_features->type == CMT_LIQUID) {
info->wear = 0;
type_match = true; type_match = true;
} }
break; break;
@ -193,7 +194,11 @@ int get_tool_use(tooluse_t *info, content_t target, uint16_t data, content_t too
} }
if (type_match) { if (type_match) {
info->data = t_features->diginfo.time; if (c_features->type == CMT_LIQUID) {
info->data = 0.1;
}else{
info->data = t_features->diginfo.time;
}
}else{ }else{
info->data = 4.0; info->data = 4.0;
} }
@ -852,6 +857,7 @@ void content_toolitem_init()
f->description = gettext("Wooden Bucket"); f->description = gettext("Wooden Bucket");
f->liquids_pointable = true; f->liquids_pointable = true;
f->type = TT_BUCKET; f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 64; f->diginfo.uses = 64;
f->diginfo.time = 1.5; f->diginfo.time = 1.5;
f->diginfo.level = 1; f->diginfo.level = 1;
@ -860,6 +866,7 @@ void content_toolitem_init()
crafting::setURecipe(CONTENT_CRAFTITEM_WOOD_PLANK,CONTENT_TOOLITEM_WBUCKET); crafting::setURecipe(CONTENT_CRAFTITEM_WOOD_PLANK,CONTENT_TOOLITEM_WBUCKET);
content_list_add("craftguide",i,1,0); content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0); content_list_add("creative",i,1,0);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
i = CONTENT_TOOLITEM_TINBUCKET; i = CONTENT_TOOLITEM_TINBUCKET;
f = &g_content_toolitem_features[i]; f = &g_content_toolitem_features[i];
@ -869,6 +876,7 @@ void content_toolitem_init()
f->description = gettext("Tin Bucket"); f->description = gettext("Tin Bucket");
f->liquids_pointable = true; f->liquids_pointable = true;
f->type = TT_BUCKET; f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 128; f->diginfo.uses = 128;
f->diginfo.time = 1.75; f->diginfo.time = 1.75;
f->diginfo.level = 2; f->diginfo.level = 2;
@ -876,6 +884,7 @@ void content_toolitem_init()
crafting::setURecipe(CONTENT_CRAFTITEM_TIN_INGOT,CONTENT_TOOLITEM_TINBUCKET); crafting::setURecipe(CONTENT_CRAFTITEM_TIN_INGOT,CONTENT_TOOLITEM_TINBUCKET);
content_list_add("craftguide",i,1,0); content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0); content_list_add("creative",i,1,0);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
i = CONTENT_TOOLITEM_IRON_BUCKET; i = CONTENT_TOOLITEM_IRON_BUCKET;
f = &g_content_toolitem_features[i]; f = &g_content_toolitem_features[i];
@ -885,57 +894,15 @@ void content_toolitem_init()
f->description = gettext("Iron Bucket"); f->description = gettext("Iron Bucket");
f->liquids_pointable = true; f->liquids_pointable = true;
f->type = TT_BUCKET; f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 256; f->diginfo.uses = 256;
f->diginfo.time = 1.0; f->diginfo.time = 1.0;
f->diginfo.level = 3; f->diginfo.level = 3;
crafting::setURecipe(CONTENT_CRAFTITEM_IRON_INGOT,CONTENT_TOOLITEM_IRON_BUCKET); crafting::setURecipe(CONTENT_CRAFTITEM_IRON_INGOT,CONTENT_TOOLITEM_IRON_BUCKET);
content_list_add("craftguide",i,1,0); content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0); content_list_add("creative",i,1,0);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
i = CONTENT_TOOLITEM_WBUCKET_WATER; content_list_add("creative",i,1,CONTENT_LAVASOURCE);
f = &g_content_toolitem_features[i];
f->content = i;
f->texture = "tool_woodbucket.png^bucket_water.png";
f->name = "WBucket_water";
f->description = gettext("Wooden Bucket of Water");
f->type = TT_SPECIAL;
f->onplace_node = CONTENT_WATERSOURCE;
f->onplace_replace_item = CONTENT_TOOLITEM_WBUCKET;
content_list_add("creative",i,1,0);
i = CONTENT_TOOLITEM_TINBUCKET_WATER;
f = &g_content_toolitem_features[i];
f->content = i;
f->texture = "tool_tinbucket.png^bucket_water.png";
f->name = "TinBucket_water";
f->description = gettext("Tin Bucket of Water");
f->type = TT_SPECIAL;
f->onplace_node = CONTENT_WATERSOURCE;
f->onplace_replace_item = CONTENT_TOOLITEM_TINBUCKET;
content_list_add("creative",i,1,0);
i = CONTENT_TOOLITEM_IRON_BUCKET_WATER;
f = &g_content_toolitem_features[i];
f->content = i;
f->texture = "tool_ironbucket.png^bucket_water.png";
f->name = "IronBucket_water";
f->description = gettext("Iron Bucket of Water");
f->type = TT_SPECIAL;
f->onplace_node = CONTENT_WATERSOURCE;
f->onplace_replace_item = CONTENT_TOOLITEM_IRON_BUCKET;
content_list_add("creative",i,1,0);
i = CONTENT_TOOLITEM_IRON_BUCKET_LAVA;
f = &g_content_toolitem_features[i];
f->content = i;
f->texture = "tool_ironbucket.png^bucket_lava.png";
f->name = "IronBucket_lava";
f->description = gettext("Iron Bucket of Lava");
f->onplace_node = CONTENT_LAVASOURCE;
f->onplace_replace_item = CONTENT_TOOLITEM_IRON_BUCKET;
f->fuel_time = BT_LAVA_BUCKET;
f->type = TT_SPECIAL;
content_list_add("creative",i,1,0);
/* SPECIAL TOOLS */ /* SPECIAL TOOLS */

View File

@ -297,7 +297,15 @@ void getPointedNode(Client *client, v3f player_position,
if (content_features(n.getContent()).pointable == false) { if (content_features(n.getContent()).pointable == false) {
if (content_features(n.getContent()).liquid_type != LIQUID_SOURCE) if (content_features(n.getContent()).liquid_type != LIQUID_SOURCE)
continue; continue;
if (!wield || content_toolitem_features(wield->getContent()).liquids_pointable == false) if (
!wield
|| content_toolitem_features(wield->getContent()).liquids_pointable == false
|| (
content_toolitem_features(wield->getContent()).liquids_pointable
&& content_toolitem_features(wield->getContent()).param_type == CPT_CONTENT
&& wield->getData() != 0
)
)
continue; continue;
}else if (content_features(n.getContent()).material_pointable == false && wield_is_material) { }else if (content_features(n.getContent()).material_pointable == false && wield_is_material) {
continue; continue;

View File

@ -168,6 +168,19 @@ InventoryItem* InventoryItem::create(content_t c, u16 count, u16 wear, u16 data)
wear = w; wear = w;
if (wear > w) if (wear > w)
wear = w; wear = w;
if (c == CONTENT_TOOLITEM_WBUCKET_WATER) {
c = CONTENT_TOOLITEM_WBUCKET;
data = CONTENT_WATERSOURCE;
}else if (c == CONTENT_TOOLITEM_TINBUCKET_WATER) {
c = CONTENT_TOOLITEM_TINBUCKET;
data = CONTENT_WATERSOURCE;
}else if (c == CONTENT_TOOLITEM_IRON_BUCKET_WATER) {
c = CONTENT_TOOLITEM_IRON_BUCKET;
data = CONTENT_WATERSOURCE;
}else if (c == CONTENT_TOOLITEM_IRON_BUCKET_LAVA) {
c = CONTENT_TOOLITEM_WBUCKET;
data = CONTENT_LAVASOURCE;
}
return new ToolItem(c,wear,data); return new ToolItem(c,wear,data);
}else if ((c&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK) { }else if ((c&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK) {
return new ClothesItem(c,wear,data); return new ClothesItem(c,wear,data);
@ -538,15 +551,35 @@ std::string ToolItem::getBasename() const
std::ostringstream os; std::ostringstream os;
os<<content_toolitem_features(m_content).texture; os<<content_toolitem_features(m_content).texture;
if (content_toolitem_features(m_content).param_type == CPT_ENCHANTMENT) { switch (content_toolitem_features(m_content).param_type) {
EnchantmentInfo info; case CPT_ENCHANTMENT:
u16 data = m_data; {
// TODO: adding more than 2 overlays messes up alpha EnchantmentInfo info;
for (int i=0; i<2 && enchantment_get(&data,&info); i++) { u16 data = m_data;
std::string ol = toolitem_overlay(m_content,info.overlay); // TODO: adding more than 2 overlays messes up alpha
for (int i=0; i<2 && enchantment_get(&data,&info); i++) {
std::string ol = toolitem_overlay(m_content,info.overlay);
if (ol != "")
os<<"^"<<ol;
}
}
break;
case CPT_CONTENT:
case CPT_DROP:
{
/* TODO: no hardcoding */
std::string ol = "";
if (m_data == CONTENT_WATERSOURCE) {
ol = toolitem_overlay(m_content,"water");
}else if (m_data == CONTENT_LAVASOURCE) {
ol = toolitem_overlay(m_content,"lava");
}
if (ol != "") if (ol != "")
os<<"^"<<ol; os<<"^"<<ol;
} }
break;
default:;
} }
return os.str(); return os.str();
@ -610,11 +643,24 @@ std::wstring ToolItem::getGuiText()
break; break;
} }
case CPT_DROP: case CPT_DROP:
case CPT_CONTENT:
{ {
txt += "\n";
txt += gettext("Contains: ");
if ((m_data&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) { if ((m_data&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) {
txt += "\n";
txt += gettext("Contains: ");
txt += content_mob_features(m_data).description; txt += content_mob_features(m_data).description;
}else if ((m_data&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
CraftItemFeatures *cif = content_craftitem_features(m_data);
if (cif)
txt += cif->description;
}else if ((m_data&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
txt += content_toolitem_features(m_data).description;
}else if ((m_data&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK) {
ClothesItemFeatures *cif = content_clothesitem_features(m_data);
if (cif)
txt += cif->description;
}else{
txt += content_features(m_data).description;
} }
break; break;
} }

View File

@ -145,6 +145,7 @@ enum ContentParamType
CPT_PLANTGROWTH, CPT_PLANTGROWTH,
CPT_ENCHANTMENT, CPT_ENCHANTMENT,
CPT_DROP, CPT_DROP,
CPT_CONTENT,
CPT_BLOCKDATA, CPT_BLOCKDATA,
CPT_SPECIAL CPT_SPECIAL
}; };

View File

@ -2800,65 +2800,45 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if (!bmeta) if (!bmeta)
return; return;
if (wielded_tool_features.type == TT_BUCKET) { if (wielded_tool_features.type == TT_BUCKET) {
if (bmeta->m_water_level) { content_t c = wielditem->getData();
std::string dug_s = std::string("ToolItem "); if (!c) {
dug_s += ((ToolItem*)wielditem)->getToolName(); if (!bmeta->m_water_level)
dug_s += "_water 1"; return;
std::istringstream is(dug_s, std::ios::binary); wielditem->setData(CONTENT_WATERSOURCE);
InventoryItem *item = InventoryItem::deSerialize(is);
InventoryList *mlist = player->inventory.getList("main"); InventoryList *mlist = player->inventory.getList("main");
InventoryItem *ritem = mlist->changeItem(item_i,item); if (mlist)
if (ritem) mlist->addDiff(item_i,wielditem);
delete ritem; UpdateCrafting(player->peer_id);
item = NULL; SendInventory(player->peer_id);
bmeta->m_water_level--; bmeta->m_water_level--;
SendInventory(player->peer_id); }else if (c == CONTENT_WATERSOURCE) {
v3s16 blockpos = getNodeBlockPos(p_under); if (bmeta->m_water_level > 9)
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
if (!block)
return; return;
block->setChangedFlag(); wielditem->setData(0);
core::map<v3s16, MapBlock*> modified_blocks;
modified_blocks.insert(block->getPos(),block);
for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator();
i.atEnd()==false; i++)
{
RemoteClient *client = i.getNode()->getValue();
client->SetBlocksNotSent(modified_blocks);
client->SetBlockNotSent(blockpos);
}
}
}else if (wielded_tool_features.type == TT_SPECIAL) {
if (
bmeta->m_water_level < 10
&& wielded_tool_features.onplace_node == CONTENT_WATERSOURCE
&& wielded_tool_features.onplace_replace_item != CONTENT_IGNORE
) {
InventoryItem *itm = InventoryItem::create(wielded_tool_features.onplace_replace_item,1,0);
InventoryList *mlist = player->inventory.getList("main"); InventoryList *mlist = player->inventory.getList("main");
InventoryItem *old = mlist->changeItem(item_i,itm); if (mlist)
if (old) mlist->addDiff(item_i,wielditem);
delete old; UpdateCrafting(player->peer_id);
bmeta->m_water_level++;
SendInventory(player->peer_id); SendInventory(player->peer_id);
v3s16 blockpos = getNodeBlockPos(p_under); bmeta->m_water_level++;
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos); }else if (c == CONTENT_LAVASOURCE) {
if (!block) return;
return; }
block->setChangedFlag(); v3s16 blockpos = getNodeBlockPos(p_under);
core::map<v3s16, MapBlock*> modified_blocks; MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
modified_blocks.insert(block->getPos(),block); if (!block)
return;
block->setChangedFlag();
core::map<v3s16, MapBlock*> modified_blocks;
modified_blocks.insert(block->getPos(),block);
for(core::map<u16, RemoteClient*>::Iterator for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator(); i = m_clients.getIterator();
i.atEnd()==false; i++) i.atEnd()==false; i++)
{ {
RemoteClient *client = i.getNode()->getValue(); RemoteClient *client = i.getNode()->getValue();
client->SetBlocksNotSent(modified_blocks); client->SetBlocksNotSent(modified_blocks);
client->SetBlockNotSent(blockpos); client->SetBlockNotSent(blockpos);
}
} }
} }
}else if (selected_content == CONTENT_CAULDRON) { }else if (selected_content == CONTENT_CAULDRON) {
@ -2866,37 +2846,45 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if (!cmeta) if (!cmeta)
return; return;
if (wielded_tool_features.type == TT_BUCKET) { if (wielded_tool_features.type == TT_BUCKET) {
if (cmeta->m_water_level == 4) { content_t c = wielditem->getData();
} if (!c) {
}else if (wielded_tool_features.type == TT_SPECIAL) { if (cmeta->m_water_level != 4)
if (
!cmeta->m_water_level
&& wielded_tool_features.onplace_node == CONTENT_WATERSOURCE
&& wielded_tool_features.onplace_replace_item != CONTENT_IGNORE
) {
InventoryItem *itm = InventoryItem::create(wielded_tool_features.onplace_replace_item,1,0);
InventoryList *mlist = player->inventory.getList("main");
InventoryItem *old = mlist->changeItem(item_i,itm);
if (old)
delete old;
cmeta->m_water_level = 4;
SendInventory(player->peer_id);
v3s16 blockpos = getNodeBlockPos(p_under);
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
if (!block)
return; return;
block->setChangedFlag(); wielditem->setData(CONTENT_WATERSOURCE);
core::map<v3s16, MapBlock*> modified_blocks; InventoryList *mlist = player->inventory.getList("main");
modified_blocks.insert(block->getPos(),block); if (mlist)
mlist->addDiff(item_i,wielditem);
UpdateCrafting(player->peer_id);
SendInventory(player->peer_id);
cmeta->m_water_level = 0;
}else if (c == CONTENT_WATERSOURCE) {
if (cmeta->m_water_level > 3)
return;
wielditem->setData(0);
InventoryList *mlist = player->inventory.getList("main");
if (mlist)
mlist->addDiff(item_i,wielditem);
UpdateCrafting(player->peer_id);
SendInventory(player->peer_id);
cmeta->m_water_level = 4;
}else if (c == CONTENT_LAVASOURCE) {
return;
}
v3s16 blockpos = getNodeBlockPos(p_under);
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
if (!block)
return;
block->setChangedFlag();
core::map<v3s16, MapBlock*> modified_blocks;
modified_blocks.insert(block->getPos(),block);
for(core::map<u16, RemoteClient*>::Iterator for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator(); i = m_clients.getIterator();
i.atEnd()==false; i++) i.atEnd()==false; i++)
{ {
RemoteClient *client = i.getNode()->getValue(); RemoteClient *client = i.getNode()->getValue();
client->SetBlocksNotSent(modified_blocks); client->SetBlocksNotSent(modified_blocks);
client->SetBlockNotSent(blockpos); client->SetBlockNotSent(blockpos);
}
} }
}else if (wieldcontent == CONTENT_CRAFTITEM_IRON_BOTTLE) { }else if (wieldcontent == CONTENT_CRAFTITEM_IRON_BOTTLE) {
if (cmeta->m_water_level && cmeta->m_water_hot && wielditem->getCount() == 1) { if (cmeta->m_water_level && cmeta->m_water_hot && wielditem->getCount() == 1) {
@ -3476,17 +3464,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
SendInventory(player->peer_id); SendInventory(player->peer_id);
HandlePlayerHP(player,4,0,0); HandlePlayerHP(player,4,0,0);
return; return;
}else{ }else if (wielded_tool_features.param_type == CPT_CONTENT) {
std::string dug_s = std::string("ToolItem "); wielditem->setData(selected_node.getContent());
dug_s += ((ToolItem*)wielditem)->getToolName(); mlist->addDiff(item_i,wielditem);
dug_s += selected_node_features.dug_item;
dug_s += " 1";
std::istringstream is(dug_s, std::ios::binary);
item = InventoryItem::deSerialize(is);
InventoryItem *ritem = mlist->changeItem(item_i,item);
if (ritem)
delete ritem;
item = NULL;
UpdateCrafting(player->peer_id); UpdateCrafting(player->peer_id);
SendInventory(player->peer_id); SendInventory(player->peer_id);
} }
@ -3687,7 +3667,19 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
/* /*
Handle material items Handle material items
*/ */
if (std::string("MaterialItem") == item->getName()) { if (
(wieldcontent&0xF000) == 0
|| (
(wieldcontent&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK
&& wielded_tool_features.param_type == CPT_CONTENT
&& item->getData() != 0
)
|| (
(wieldcontent&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK
&& wielded_craft_features->param_type == CPT_CONTENT
&& item->getData() != 0
)
) {
bool replaced_node_exists = false; bool replaced_node_exists = false;
MapNode replaced_node = m_env.getMap().getNodeNoEx(p_over,&replaced_node_exists); MapNode replaced_node = m_env.getMap().getNodeNoEx(p_over,&replaced_node_exists);
if (!replaced_node_exists) { if (!replaced_node_exists) {
@ -3727,9 +3719,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// the node type // the node type
content_t addedcontent = wieldcontent; content_t addedcontent = wieldcontent;
if (
(wieldcontent&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK
|| (wieldcontent&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK
) {
addedcontent = item->getData();
}
// don't allow borderstone to be place near another player's borderstone // don't allow borderstone to be place near another player's borderstone
if (wieldcontent == CONTENT_BORDERSTONE) { if (addedcontent == CONTENT_BORDERSTONE) {
uint16_t max_d = config_get_int("world.game.borderstone.radius"); uint16_t max_d = config_get_int("world.game.borderstone.radius");
v3s16 test_p; v3s16 test_p;
MapNode testnode; MapNode testnode;
@ -3926,8 +3924,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
*/ */
InventoryList *ilist = player->inventory.getList("main"); InventoryList *ilist = player->inventory.getList("main");
if (!config_get_bool("world.player.inventory.creative") && ilist) { if (!config_get_bool("world.player.inventory.creative") && ilist) {
// Remove from inventory and send inventory if ((wieldcontent&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
if (wielditem->getCount() == 1) { ToolItem *titem = (ToolItem*)wielditem;
if (titem->addWear(1)) {
ilist->deleteItem(item_i);
}else{
wielditem->setData(0);
ilist->addDiff(item_i,wielditem);
}
}else if ((wieldcontent&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
wielditem->setData(0);
ilist->addDiff(item_i,wielditem);
}else if (wielditem->getCount() == 1) {
ilist->deleteItem(item_i); ilist->deleteItem(item_i);
}else{ }else{
wielditem->remove(1); wielditem->remove(1);