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;
case TT_BUCKET:
if (c_features->type == CMT_LIQUID) {
info->wear = 0;
type_match = true;
}
break;
@ -193,7 +194,11 @@ int get_tool_use(tooluse_t *info, content_t target, uint16_t data, content_t too
}
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{
info->data = 4.0;
}
@ -852,6 +857,7 @@ void content_toolitem_init()
f->description = gettext("Wooden Bucket");
f->liquids_pointable = true;
f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 64;
f->diginfo.time = 1.5;
f->diginfo.level = 1;
@ -860,6 +866,7 @@ void content_toolitem_init()
crafting::setURecipe(CONTENT_CRAFTITEM_WOOD_PLANK,CONTENT_TOOLITEM_WBUCKET);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
i = CONTENT_TOOLITEM_TINBUCKET;
f = &g_content_toolitem_features[i];
@ -869,6 +876,7 @@ void content_toolitem_init()
f->description = gettext("Tin Bucket");
f->liquids_pointable = true;
f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 128;
f->diginfo.time = 1.75;
f->diginfo.level = 2;
@ -876,6 +884,7 @@ void content_toolitem_init()
crafting::setURecipe(CONTENT_CRAFTITEM_TIN_INGOT,CONTENT_TOOLITEM_TINBUCKET);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
i = CONTENT_TOOLITEM_IRON_BUCKET;
f = &g_content_toolitem_features[i];
@ -885,57 +894,15 @@ void content_toolitem_init()
f->description = gettext("Iron Bucket");
f->liquids_pointable = true;
f->type = TT_BUCKET;
f->param_type = CPT_CONTENT;
f->diginfo.uses = 256;
f->diginfo.time = 1.0;
f->diginfo.level = 3;
crafting::setURecipe(CONTENT_CRAFTITEM_IRON_INGOT,CONTENT_TOOLITEM_IRON_BUCKET);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
i = CONTENT_TOOLITEM_WBUCKET_WATER;
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);
content_list_add("creative",i,1,CONTENT_WATERSOURCE);
content_list_add("creative",i,1,CONTENT_LAVASOURCE);
/* 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()).liquid_type != LIQUID_SOURCE)
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;
}else if (content_features(n.getContent()).material_pointable == false && wield_is_material) {
continue;

View File

@ -168,6 +168,19 @@ InventoryItem* InventoryItem::create(content_t c, u16 count, u16 wear, u16 data)
wear = w;
if (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);
}else if ((c&CONTENT_CLOTHESITEM_MASK) == CONTENT_CLOTHESITEM_MASK) {
return new ClothesItem(c,wear,data);
@ -538,15 +551,35 @@ std::string ToolItem::getBasename() const
std::ostringstream os;
os<<content_toolitem_features(m_content).texture;
if (content_toolitem_features(m_content).param_type == CPT_ENCHANTMENT) {
EnchantmentInfo info;
u16 data = m_data;
// 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);
switch (content_toolitem_features(m_content).param_type) {
case CPT_ENCHANTMENT:
{
EnchantmentInfo info;
u16 data = m_data;
// 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 != "")
os<<"^"<<ol;
}
break;
default:;
}
return os.str();
@ -610,11 +643,24 @@ std::wstring ToolItem::getGuiText()
break;
}
case CPT_DROP:
case CPT_CONTENT:
{
txt += "\n";
txt += gettext("Contains: ");
if ((m_data&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) {
txt += "\n";
txt += gettext("Contains: ");
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;
}

View File

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

View File

@ -2800,65 +2800,45 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if (!bmeta)
return;
if (wielded_tool_features.type == TT_BUCKET) {
if (bmeta->m_water_level) {
std::string dug_s = std::string("ToolItem ");
dug_s += ((ToolItem*)wielditem)->getToolName();
dug_s += "_water 1";
std::istringstream is(dug_s, std::ios::binary);
InventoryItem *item = InventoryItem::deSerialize(is);
content_t c = wielditem->getData();
if (!c) {
if (!bmeta->m_water_level)
return;
wielditem->setData(CONTENT_WATERSOURCE);
InventoryList *mlist = player->inventory.getList("main");
InventoryItem *ritem = mlist->changeItem(item_i,item);
if (ritem)
delete ritem;
item = NULL;
if (mlist)
mlist->addDiff(item_i,wielditem);
UpdateCrafting(player->peer_id);
SendInventory(player->peer_id);
bmeta->m_water_level--;
SendInventory(player->peer_id);
v3s16 blockpos = getNodeBlockPos(p_under);
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
if (!block)
}else if (c == CONTENT_WATERSOURCE) {
if (bmeta->m_water_level > 9)
return;
block->setChangedFlag();
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);
wielditem->setData(0);
InventoryList *mlist = player->inventory.getList("main");
InventoryItem *old = mlist->changeItem(item_i,itm);
if (old)
delete old;
bmeta->m_water_level++;
if (mlist)
mlist->addDiff(item_i,wielditem);
UpdateCrafting(player->peer_id);
SendInventory(player->peer_id);
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);
bmeta->m_water_level++;
}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
i = m_clients.getIterator();
i.atEnd()==false; i++)
{
RemoteClient *client = i.getNode()->getValue();
client->SetBlocksNotSent(modified_blocks);
client->SetBlockNotSent(blockpos);
}
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 (selected_content == CONTENT_CAULDRON) {
@ -2866,37 +2846,45 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if (!cmeta)
return;
if (wielded_tool_features.type == TT_BUCKET) {
if (cmeta->m_water_level == 4) {
}
}else if (wielded_tool_features.type == TT_SPECIAL) {
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)
content_t c = wielditem->getData();
if (!c) {
if (cmeta->m_water_level != 4)
return;
block->setChangedFlag();
core::map<v3s16, MapBlock*> modified_blocks;
modified_blocks.insert(block->getPos(),block);
wielditem->setData(CONTENT_WATERSOURCE);
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 = 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
i = m_clients.getIterator();
i.atEnd()==false; i++)
{
RemoteClient *client = i.getNode()->getValue();
client->SetBlocksNotSent(modified_blocks);
client->SetBlockNotSent(blockpos);
}
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 (wieldcontent == CONTENT_CRAFTITEM_IRON_BOTTLE) {
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);
HandlePlayerHP(player,4,0,0);
return;
}else{
std::string dug_s = std::string("ToolItem ");
dug_s += ((ToolItem*)wielditem)->getToolName();
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;
}else if (wielded_tool_features.param_type == CPT_CONTENT) {
wielditem->setData(selected_node.getContent());
mlist->addDiff(item_i,wielditem);
UpdateCrafting(player->peer_id);
SendInventory(player->peer_id);
}
@ -3687,7 +3667,19 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
/*
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;
MapNode replaced_node = m_env.getMap().getNodeNoEx(p_over,&replaced_node_exists);
if (!replaced_node_exists) {
@ -3727,9 +3719,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// the node type
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
if (wieldcontent == CONTENT_BORDERSTONE) {
if (addedcontent == CONTENT_BORDERSTONE) {
uint16_t max_d = config_get_int("world.game.borderstone.radius");
v3s16 test_p;
MapNode testnode;
@ -3926,8 +3924,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
*/
InventoryList *ilist = player->inventory.getList("main");
if (!config_get_bool("world.player.inventory.creative") && ilist) {
// Remove from inventory and send inventory
if (wielditem->getCount() == 1) {
if ((wieldcontent&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
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);
}else{
wielditem->remove(1);