add support for privileged crafting, add mithril key
This commit is contained in:
parent
4f00ebe5dc
commit
0373e64007
Binary file not shown.
Before Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 394 B |
Binary file not shown.
After Width: | Height: | Size: 402 B |
|
@ -31,6 +31,7 @@
|
|||
#include "content_toolitem.h"
|
||||
#include "content_list.h"
|
||||
#include "player.h"
|
||||
#include "server.h"
|
||||
#include "mapnode.h" // For content_t
|
||||
#include "settings.h" // for g_settings
|
||||
|
||||
|
@ -68,7 +69,7 @@ static bool checkShapelessRecipe(content_t recipe[9], content_t result)
|
|||
return false;
|
||||
}
|
||||
|
||||
void setRecipe(content_t recipe[9], content_t result, u16 count)
|
||||
void setRecipe(content_t recipe[9], content_t result, u16 count, uint64_t privs)
|
||||
{
|
||||
if (checkRecipe(recipe,result))
|
||||
return;
|
||||
|
@ -78,10 +79,11 @@ void setRecipe(content_t recipe[9], content_t result, u16 count)
|
|||
}
|
||||
d.result = result;
|
||||
d.result_count = count;
|
||||
d.privs = privs;
|
||||
shaped_recipes.push_back(d);
|
||||
}
|
||||
|
||||
void setShapelessRecipe(content_t recipe[9], content_t result, u16 count)
|
||||
void setShapelessRecipe(content_t recipe[9], content_t result, u16 count, uint64_t privs)
|
||||
{
|
||||
if (checkShapelessRecipe(recipe,result))
|
||||
return;
|
||||
|
@ -91,6 +93,7 @@ void setShapelessRecipe(content_t recipe[9], content_t result, u16 count)
|
|||
}
|
||||
d.result = result;
|
||||
d.result_count = count;
|
||||
d.privs = privs;
|
||||
shapeless_recipes.push_back(d);
|
||||
}
|
||||
|
||||
|
@ -677,15 +680,19 @@ void setShortsRecipe(u16 input, u16 result)
|
|||
setRecipe(r,result,1);
|
||||
}
|
||||
|
||||
InventoryItem *getResult(InventoryItem **items)
|
||||
InventoryItem *getResult(InventoryItem **items, Player *player, Server *server)
|
||||
{
|
||||
for (std::vector<CraftDef>::iterator i=shaped_recipes.begin(); i!=shaped_recipes.end(); i++) {
|
||||
CraftDef d = *i;
|
||||
if (d.privs != 0 && (server->getPlayerPrivs(player)&d.privs) != d.privs)
|
||||
continue;
|
||||
if (d == items)
|
||||
return InventoryItem::create(d.result,d.result_count);
|
||||
}
|
||||
for (std::vector<CraftDefShapeless>::iterator i=shapeless_recipes.begin(); i!=shapeless_recipes.end(); i++) {
|
||||
CraftDefShapeless d = *i;
|
||||
if (d.privs != 0 && (server->getPlayerPrivs(player)&d.privs) != d.privs)
|
||||
continue;
|
||||
if (d == items)
|
||||
return InventoryItem::create(d.result,d.result_count);
|
||||
}
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
#include "inventory.h"
|
||||
|
||||
class Player;
|
||||
class Server;
|
||||
|
||||
struct CraftDef {
|
||||
content_t recipe[9];
|
||||
content_t result;
|
||||
u16 result_count;
|
||||
uint64_t privs;
|
||||
|
||||
bool operator==(InventoryItem * const *items)
|
||||
{
|
||||
|
@ -125,6 +127,7 @@ struct CraftDefShapeless {
|
|||
content_t recipe[9];
|
||||
content_t result;
|
||||
u16 result_count;
|
||||
uint64_t privs;
|
||||
|
||||
bool operator==(InventoryItem * const *items)
|
||||
{
|
||||
|
@ -170,8 +173,8 @@ namespace crafting {
|
|||
void initCrafting();
|
||||
|
||||
// add recipes
|
||||
void setRecipe(u16 recipe[9], u16 result, u16 count);
|
||||
void setShapelessRecipe(u16 recipe[9], u16 result, u16 count);
|
||||
void setRecipe(u16 recipe[9], u16 result, u16 count, uint64_t privs = 0);
|
||||
void setShapelessRecipe(u16 recipe[9], u16 result, u16 count, uint64_t privs = 0);
|
||||
|
||||
// shortcuts
|
||||
// one input yields one result
|
||||
|
@ -277,7 +280,7 @@ namespace crafting {
|
|||
// pants recipe 5 input in an upside-down V yields one result
|
||||
void setShortsRecipe(u16 input, u16 result);
|
||||
|
||||
InventoryItem *getResult(InventoryItem **items);
|
||||
InventoryItem *getResult(InventoryItem **items, Player *player, Server *server);
|
||||
content_t *getRecipe(InventoryItem *item);
|
||||
content_t *getRecipe(InventoryItem *item, int i);
|
||||
int getResultCount(InventoryItem *item);
|
||||
|
|
|
@ -3345,7 +3345,8 @@ bool ForgeNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
|
|||
return false;
|
||||
|
||||
// Get result of crafting grid
|
||||
InventoryItem *result = crafting::getResult(items);
|
||||
/* TODO: player/server args */
|
||||
InventoryItem *result = crafting::getResult(items,NULL,NULL);
|
||||
if (!result)
|
||||
return false;
|
||||
if (rlist->itemFits(0,result))
|
||||
|
@ -3390,7 +3391,8 @@ bool ForgeNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
|
|||
return false;
|
||||
|
||||
// Get result of crafting grid
|
||||
InventoryItem *result = crafting::getResult(items);
|
||||
/* TODO: player/server args */
|
||||
InventoryItem *result = crafting::getResult(items,NULL,NULL);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <map>
|
||||
#include "intl.h"
|
||||
#include "enchantment.h"
|
||||
#include "auth.h"
|
||||
|
||||
std::map<content_t,struct ToolItemFeatures> g_content_toolitem_features;
|
||||
|
||||
|
@ -599,7 +600,7 @@ void content_toolitem_init()
|
|||
i = CONTENT_TOOLITEM_KEY;
|
||||
f = &g_content_toolitem_features[i];
|
||||
f->content = i;
|
||||
f->texture = "key.png";
|
||||
f->texture = "tool_key.png";
|
||||
f->name = "key";
|
||||
f->description = wgettext("Key");
|
||||
f->type = TT_SPECIAL;
|
||||
|
@ -899,4 +900,24 @@ void content_toolitem_init()
|
|||
crafting::setRecipe(r,i,1);
|
||||
}
|
||||
lists::add("craftguide",i);
|
||||
|
||||
i = CONTENT_TOOLITEM_MITHRIL_KEY;
|
||||
f = &g_content_toolitem_features[i];
|
||||
f->content = i;
|
||||
f->texture = "tool_mithril_key.png";
|
||||
f->name = "mithrilkey";
|
||||
f->description = wgettext("Mithril Key");
|
||||
f->type = TT_SPECIAL;
|
||||
f->level = 5;
|
||||
f->has_unlock_effect = true;
|
||||
f->has_super_unlock_effect = true;
|
||||
/* this can only be crafted by server admin */
|
||||
{
|
||||
content_t r[9] = {
|
||||
CONTENT_CRAFTITEM_MITHRIL_UNBOUND, CONTENT_IGNORE, CONTENT_IGNORE,
|
||||
CONTENT_IGNORE, CONTENT_IGNORE, CONTENT_IGNORE,
|
||||
CONTENT_IGNORE, CONTENT_IGNORE, CONTENT_IGNORE
|
||||
};
|
||||
crafting::setRecipe(r,i,1,PRIV_SERVER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ struct ToolItemFeatures {
|
|||
bool has_punch_effect;
|
||||
// whether this tool can lock/unlock nodes
|
||||
bool has_unlock_effect;
|
||||
bool has_super_unlock_effect;
|
||||
// whether this tool can rotate nodes
|
||||
bool has_rotate_effect;
|
||||
// whether this tool can start fires
|
||||
|
@ -75,6 +76,7 @@ struct ToolItemFeatures {
|
|||
damaging_nodes_diggable(true),
|
||||
has_punch_effect(true),
|
||||
has_unlock_effect(false),
|
||||
has_super_unlock_effect(false),
|
||||
has_rotate_effect(false),
|
||||
has_fire_effect(false),
|
||||
type(TT_NONE),
|
||||
|
@ -163,5 +165,6 @@ ToolItemFeatures & content_toolitem_features(std::string subname);
|
|||
#define CONTENT_TOOLITEM_MITHRIL_SWORD (CONTENT_TOOLITEM_MASK | 0x2E)
|
||||
#define CONTENT_TOOLITEM_MITHRIL_SPEAR (CONTENT_TOOLITEM_MASK | 0x2F)
|
||||
#define CONTENT_TOOLITEM_MOB_SPAWNER (CONTENT_TOOLITEM_MASK | 0x30)
|
||||
#define CONTENT_TOOLITEM_MITHRIL_KEY (CONTENT_TOOLITEM_MASK | 0x31)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2497,9 +2497,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (!wielded_tool_features.has_punch_effect)
|
||||
return;
|
||||
// KEY
|
||||
if (wielded_tool_features.has_unlock_effect && selected_node_features.alternate_lockstate_node != CONTENT_IGNORE) {
|
||||
if (
|
||||
wielded_tool_features.has_unlock_effect
|
||||
&& (
|
||||
selected_node_features.alternate_lockstate_node != CONTENT_IGNORE
|
||||
|| (
|
||||
wielded_tool_features.has_super_unlock_effect
|
||||
&& selected_content == CONTENT_BORDERSTONE
|
||||
)
|
||||
)
|
||||
) {
|
||||
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
|
||||
if ((getPlayerPrivs(player) & PRIV_SERVER) == 0) {
|
||||
if ((getPlayerPrivs(player) & PRIV_SERVER) == 0 && !wielded_tool_features.has_super_unlock_effect) {
|
||||
// non-admins can't unlock other players things
|
||||
if (meta && meta->getOwner() != player->getName()) {
|
||||
if (meta->getOwner() != "")
|
||||
|
@ -2508,29 +2517,42 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (borderstone_locked)
|
||||
return;
|
||||
}
|
||||
content_t c = selected_node_features.alternate_lockstate_node;
|
||||
NodeMetadata *ometa = NULL;
|
||||
if (meta) {
|
||||
if (meta->getEnergy())
|
||||
return;
|
||||
ometa = meta->clone();
|
||||
}
|
||||
selected_node.setContent(c);
|
||||
// send the node
|
||||
core::list<u16> far_players;
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
sendAddNode(p_under, selected_node, 0, &far_players, 30);
|
||||
// wear out the key - admin's key doesn't wear
|
||||
ToolItem *titem = (ToolItem*)wielditem;
|
||||
if ((getPlayerPrivs(player) & PRIV_SERVER) == 0 && g_settings->getBool("tool_wear")) {
|
||||
bool weared_out = titem->addWear(10000);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
if (selected_content == CONTENT_BORDERSTONE) {
|
||||
if (!wielded_tool_features.has_super_unlock_effect)
|
||||
return;
|
||||
selected_node.setContent(CONTENT_STONE);
|
||||
m_env.getMap().removeNodeMetadata(p_under);
|
||||
// send the node
|
||||
sendAddNode(p_under, selected_node, 0, &far_players, 30);
|
||||
}else{
|
||||
content_t c = selected_node_features.alternate_lockstate_node;
|
||||
if (meta) {
|
||||
if (meta->getEnergy())
|
||||
return;
|
||||
ometa = meta->clone();
|
||||
}
|
||||
selected_node.setContent(c);
|
||||
// send the node
|
||||
sendAddNode(p_under, selected_node, 0, &far_players, 30);
|
||||
// wear out the key - admin's key doesn't wear
|
||||
ToolItem *titem = (ToolItem*)wielditem;
|
||||
if (
|
||||
!wielded_tool_features.has_super_unlock_effect
|
||||
&& (getPlayerPrivs(player) & PRIV_SERVER) == 0
|
||||
&& g_settings->getBool("tool_wear")
|
||||
) {
|
||||
bool weared_out = titem->addWear(10000);
|
||||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (weared_out) {
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
// the slow add to map
|
||||
{
|
||||
|
@ -5643,7 +5665,7 @@ void Server::UpdateCrafting(u16 peer_id)
|
|||
}
|
||||
|
||||
// Get result of crafting grid
|
||||
InventoryItem *result = crafting::getResult(items);
|
||||
InventoryItem *result = crafting::getResult(items,player,this);
|
||||
if (result)
|
||||
rlist->addItem(result);
|
||||
}
|
||||
|
|
|
@ -445,6 +445,8 @@ public:
|
|||
core::list<Player*> getPlayers() {return m_env.getPlayers();}
|
||||
core::list<Player*> getPlayers(bool ign_disconnected) {return m_env.getPlayers(ign_disconnected);}
|
||||
|
||||
uint64_t getPlayerPrivs(Player *player);
|
||||
|
||||
// Saves g_settings to configpath given at initialization
|
||||
void saveConfig();
|
||||
|
||||
|
@ -570,8 +572,6 @@ private:
|
|||
void handlePeerChange(PeerChange &c);
|
||||
void handlePeerChanges();
|
||||
|
||||
uint64_t getPlayerPrivs(Player *player);
|
||||
|
||||
/*
|
||||
Variables
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue