forked from oerkki/voxelands
make tool wear and usage a bit easier to understand pt1
This commit is contained in:
parent
0e6b4ff80b
commit
0f57b18e0e
|
@ -1398,21 +1398,13 @@ u16 MobSAO::punch(content_t punch_item, v3f dir, const std::string &playername)
|
|||
}
|
||||
sendPosition();
|
||||
|
||||
tooluse_t usage;
|
||||
|
||||
u16 amount = 2;
|
||||
if (f.type == TT_SWORD) {
|
||||
amount = 4*((f.hardness/100)+1);
|
||||
wear = 65535/f.hardness;
|
||||
}else if (f.type == TT_CLUB) {
|
||||
amount = 2*((f.hardness/100)+1);
|
||||
wear = 65535/f.hardness;
|
||||
}else if (f.type == TT_SPEAR) {
|
||||
amount = 3*((f.hardness/100)+1);
|
||||
wear = 65535/f.hardness;
|
||||
}else if (f.type == TT_AXE || f.type == TT_PICK) {
|
||||
amount = ((f.hardness/200)+1);
|
||||
if (!get_tool_use(&usage,m_content,0,punch_item,0)) {
|
||||
if (usage.diggable)
|
||||
doDamage(usage.data);
|
||||
wear = usage.wear;
|
||||
}
|
||||
doDamage(amount);
|
||||
}else if (m.punch_action == MPA_DIE) {
|
||||
m_hp = 0;
|
||||
m_removed = true;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,6 +18,12 @@ enum ToolType {
|
|||
TT_CLUB
|
||||
};
|
||||
|
||||
typedef struct diginfo_s {
|
||||
uint16_t uses;
|
||||
float time;
|
||||
uint8_t level;
|
||||
} diginfo_t;
|
||||
|
||||
struct ToolItemFeatures {
|
||||
content_t content;
|
||||
std::string texture;
|
||||
|
@ -48,14 +54,10 @@ struct ToolItemFeatures {
|
|||
bool has_rotate_effect;
|
||||
// whether this tool can start fires
|
||||
bool has_fire_effect;
|
||||
// digging info for this tool
|
||||
diginfo_t diginfo;
|
||||
// the type of this tool
|
||||
ToolType type;
|
||||
// the hardness of this tool
|
||||
f32 hardness;
|
||||
// the dig time of this tool
|
||||
f32 dig_time;
|
||||
// the level of the tool, this affects the amount of minerals etc.
|
||||
u8 level;
|
||||
// the data value of this item
|
||||
ContentParamType param_type;
|
||||
// used for eg. bows throwing an arrow
|
||||
|
@ -83,55 +85,46 @@ struct ToolItemFeatures {
|
|||
has_rotate_effect(false),
|
||||
has_fire_effect(false),
|
||||
type(TT_NONE),
|
||||
hardness(0.),
|
||||
dig_time(3.),
|
||||
level(0),
|
||||
param_type(CPT_NONE),
|
||||
thrown_item(CONTENT_IGNORE),
|
||||
onplace_replace_item(CONTENT_IGNORE),
|
||||
onplace_node(CONTENT_IGNORE)
|
||||
{}
|
||||
};
|
||||
struct DiggingProperties
|
||||
{
|
||||
DiggingProperties():
|
||||
diggable(false),
|
||||
time(0.0),
|
||||
wear(0)
|
||||
{
|
||||
diginfo.uses = 256;
|
||||
diginfo.time = 4.0;
|
||||
diginfo.level = 0;
|
||||
}
|
||||
DiggingProperties(bool a_diggable, float a_time, u16 a_wear):
|
||||
diggable(a_diggable),
|
||||
time(a_time),
|
||||
wear(a_wear)
|
||||
{
|
||||
}
|
||||
bool diggable;
|
||||
// Digging time in seconds
|
||||
float time;
|
||||
// Caused wear
|
||||
u16 wear;
|
||||
};
|
||||
|
||||
typedef struct tooluse_s {
|
||||
bool diggable;
|
||||
// Digging time in seconds or hit damage
|
||||
float data;
|
||||
// Caused wear
|
||||
uint16_t wear;
|
||||
// delay till tool can be used again
|
||||
float delay;
|
||||
} tooluse_t;
|
||||
|
||||
// For getting the default properties, set toolid=CONTENT_IGNORE
|
||||
DiggingProperties getDiggingProperties(content_t material, u8 mineral, content_t toolid, u16 data=0);
|
||||
int get_tool_use(tooluse_t *info, content_t target, uint16_t data, content_t toolid, uint16_t tooldata);
|
||||
std::string toolitem_overlay(content_t content, std::string ol);
|
||||
void content_toolitem_init();
|
||||
ToolItemFeatures & content_toolitem_features(content_t i);
|
||||
ToolItemFeatures & content_toolitem_features(std::string subname);
|
||||
|
||||
#define CONTENT_TOOLITEM_SMALL_PICK (CONTENT_TOOLITEM_MASK | 0x01)
|
||||
#define CONTENT_TOOLITEM_STPICK (CONTENT_TOOLITEM_MASK | 0x02)
|
||||
#define CONTENT_TOOLITEM_STONEPICK (CONTENT_TOOLITEM_MASK | 0x02)
|
||||
#define CONTENT_TOOLITEM_STEELPICK (CONTENT_TOOLITEM_MASK | 0x03)
|
||||
#define CONTENT_TOOLITEM_CREATIVEPICK (CONTENT_TOOLITEM_MASK | 0x04)
|
||||
#define CONTENT_TOOLITEM_TROWEL (CONTENT_TOOLITEM_MASK | 0x05)
|
||||
#define CONTENT_TOOLITEM_STSHOVEL (CONTENT_TOOLITEM_MASK | 0x06)
|
||||
#define CONTENT_TOOLITEM_STONESHOVEL (CONTENT_TOOLITEM_MASK | 0x06)
|
||||
#define CONTENT_TOOLITEM_STEELSHOVEL (CONTENT_TOOLITEM_MASK | 0x07)
|
||||
#define CONTENT_TOOLITEM_SMALL_AXE (CONTENT_TOOLITEM_MASK | 0x08)
|
||||
#define CONTENT_TOOLITEM_STAXE (CONTENT_TOOLITEM_MASK | 0x09)
|
||||
#define CONTENT_TOOLITEM_STONEAXE (CONTENT_TOOLITEM_MASK | 0x09)
|
||||
#define CONTENT_TOOLITEM_STEELAXE (CONTENT_TOOLITEM_MASK | 0x0A)
|
||||
#define CONTENT_TOOLITEM_CLUB (CONTENT_TOOLITEM_MASK | 0x0B)
|
||||
#define CONTENT_TOOLITEM_STSWORD (CONTENT_TOOLITEM_MASK | 0x0C)
|
||||
#define CONTENT_TOOLITEM_STONESWORD (CONTENT_TOOLITEM_MASK | 0x0C)
|
||||
#define CONTENT_TOOLITEM_STEELSWORD (CONTENT_TOOLITEM_MASK | 0x0D)
|
||||
#define CONTENT_TOOLITEM_STEELSHEARS (CONTENT_TOOLITEM_MASK | 0x0E)
|
||||
#define CONTENT_TOOLITEM_WBUCKET (CONTENT_TOOLITEM_MASK | 0x0F)
|
||||
|
|
185
src/game.cpp
185
src/game.cpp
|
@ -861,17 +861,12 @@ void the_game(
|
|||
|
||||
core::list<float> frametime_log;
|
||||
|
||||
float nodig_delay_counter = 0.0;
|
||||
float action_delay_counter = 0.0;
|
||||
float dig_time = 0.0;
|
||||
v3s16 nodepos_old(-32768,-32768,-32768);
|
||||
|
||||
float use_delay_counter = 0.5;
|
||||
|
||||
float damage_flash_timer = 0;
|
||||
|
||||
const float object_hit_delay = 0.5;
|
||||
float object_hit_delay_timer = 0.0;
|
||||
|
||||
bool invert_mouse = g_settings->getBool("invert_mouse");
|
||||
|
||||
bool respawn_menu_active = false;
|
||||
|
@ -1018,8 +1013,6 @@ void the_game(
|
|||
|
||||
/* Run timers */
|
||||
|
||||
object_hit_delay_timer -= dtime;
|
||||
|
||||
g_profiler->add("Elapsed time", dtime);
|
||||
g_profiler->avg("FPS", 1./dtime);
|
||||
|
||||
|
@ -1551,7 +1544,12 @@ void the_game(
|
|||
|
||||
InventoryItem *wield = (InventoryItem*)client.getLocalPlayer()->getWieldItem();
|
||||
InventoryList *ilist;
|
||||
if (
|
||||
|
||||
printf("action_delay_counter = %f\n",action_delay_counter);
|
||||
|
||||
if (action_delay_counter > 0.0) {
|
||||
action_delay_counter -= dtime;
|
||||
}else if (
|
||||
wield
|
||||
&& (
|
||||
content_craftitem_features(wield->getContent()).thrown_item != CONTENT_IGNORE
|
||||
|
@ -1601,26 +1599,28 @@ void the_game(
|
|||
infotext = narrow_to_wide(selected_active_object->infoText());
|
||||
|
||||
if (input->getLeftState()) {
|
||||
bool do_punch = false;
|
||||
bool do_punch_damage = false;
|
||||
if (object_hit_delay_timer <= 0.0){
|
||||
do_punch = true;
|
||||
do_punch_damage = true;
|
||||
object_hit_delay_timer = object_hit_delay;
|
||||
tooluse_t usage;
|
||||
content_t toolid = CONTENT_IGNORE;
|
||||
u16 tooldata = 0;
|
||||
InventoryList *mlist = local_inventory.getList("main");
|
||||
if (mlist != NULL) {
|
||||
InventoryItem *item = mlist->getItem(g_selected_item);
|
||||
if (item && (item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
toolid = titem->getContent();
|
||||
tooldata = titem->getData();
|
||||
}
|
||||
}
|
||||
if (input->getLeftClicked()) {
|
||||
do_punch = true;
|
||||
}
|
||||
if (do_punch) {
|
||||
infostream<<"Left-clicked object"<<std::endl;
|
||||
|
||||
if (!get_tool_use(&usage,selected_active_object->getContent(),0,toolid,tooldata)) {
|
||||
left_punch = true;
|
||||
}
|
||||
if (do_punch_damage) {
|
||||
client.clickActiveObject(0, selected_active_object->getId(), g_selected_item);
|
||||
action_delay_counter = usage.delay;
|
||||
}
|
||||
}else if (input->getRightClicked()) {
|
||||
infostream<<"Right-clicked object"<<std::endl;
|
||||
client.clickActiveObject(1, selected_active_object->getId(), g_selected_item);
|
||||
action_delay_counter = 0.25;
|
||||
}
|
||||
}else{ // selected_object == NULL
|
||||
/*
|
||||
|
@ -1671,93 +1671,80 @@ void the_game(
|
|||
if (!highlight_selected_node)
|
||||
hilightboxes.push_back(nodehilightbox);
|
||||
|
||||
if (nodig_delay_counter > 0.0) {
|
||||
nodig_delay_counter -= dtime;
|
||||
}else{
|
||||
if (nodepos != nodepos_old) {
|
||||
infostream<<"Pointing at ("<<nodepos.X<<","
|
||||
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
||||
if (nodepos != nodepos_old) {
|
||||
infostream<<"Pointing at ("<<nodepos.X<<","
|
||||
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
||||
|
||||
if (nodepos_old != v3s16(-32768,-32768,-32768)) {
|
||||
dig_time = 0.0;
|
||||
nodepos_old = v3s16(-32768,-32768,-32768);
|
||||
if (nodepos_old != v3s16(-32768,-32768,-32768)) {
|
||||
dig_time = 0.0;
|
||||
nodepos_old = v3s16(-32768,-32768,-32768);
|
||||
}
|
||||
}
|
||||
|
||||
if (input->getLeftClicked() || (input->getLeftState() && nodepos != nodepos_old)) {
|
||||
infostream<<"Started digging"<<std::endl;
|
||||
client.groundAction(0, nodepos, neighbourpos, g_selected_item);
|
||||
}
|
||||
if (input->getLeftClicked())
|
||||
selected_node_crack = 0;
|
||||
if (input->getLeftState()) {
|
||||
MapNode n = client.getNode(nodepos);
|
||||
|
||||
// Get tool name. Default is "" = bare hands
|
||||
content_t toolid = CONTENT_IGNORE;
|
||||
u16 tooldata = 0;
|
||||
InventoryList *mlist = local_inventory.getList("main");
|
||||
if (mlist != NULL) {
|
||||
InventoryItem *item = mlist->getItem(g_selected_item);
|
||||
if (item && (item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
toolid = titem->getContent();
|
||||
tooldata = titem->getData();
|
||||
}
|
||||
}
|
||||
|
||||
if (input->getLeftClicked() || (input->getLeftState() && nodepos != nodepos_old)) {
|
||||
infostream<<"Started digging"<<std::endl;
|
||||
client.groundAction(0, nodepos, neighbourpos, g_selected_item);
|
||||
}
|
||||
if (input->getLeftClicked())
|
||||
selected_node_crack = 0;
|
||||
if (input->getLeftState()) {
|
||||
MapNode n = client.getNode(nodepos);
|
||||
// Get digging properties for material and tool
|
||||
content_t material = n.getContent();
|
||||
uint16_t mineral = n.getMineral();
|
||||
tooluse_t usage;
|
||||
|
||||
// Get tool name. Default is "" = bare hands
|
||||
content_t toolid = CONTENT_IGNORE;
|
||||
u16 tooldata = 0;
|
||||
InventoryList *mlist = local_inventory.getList("main");
|
||||
if (mlist != NULL) {
|
||||
InventoryItem *item = mlist->getItem(g_selected_item);
|
||||
if (item && (item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
toolid = titem->getContent();
|
||||
tooldata = titem->getData();
|
||||
}
|
||||
}
|
||||
if (get_tool_use(&usage,material,mineral,toolid,tooldata))
|
||||
usage.diggable = false;
|
||||
|
||||
// Get digging properties for material and tool
|
||||
content_t material = n.getContent();
|
||||
u8 mineral = n.getMineral();
|
||||
DiggingProperties prop = getDiggingProperties(material, mineral, toolid, tooldata);
|
||||
float dig_time_complete = 0.0;
|
||||
|
||||
float dig_time_complete = 0.0;
|
||||
if (!usage.diggable) {
|
||||
dig_time_complete = 10000000.0;
|
||||
}else{
|
||||
dig_time_complete = usage.data;
|
||||
if (enable_particles)
|
||||
addPunchingParticles(smgr, player, nodepos, content_features(n).tiles);
|
||||
|
||||
if (prop.diggable == false) {
|
||||
dig_time_complete = 10000000.0;
|
||||
if (dig_time_complete >= 0.001) {
|
||||
selected_node_crack = (u16)((float)CRACK_ANIMATION_LENGTH
|
||||
* dig_time/dig_time_complete);
|
||||
}else{
|
||||
dig_time_complete = prop.time;
|
||||
if (enable_particles)
|
||||
addPunchingParticles(smgr, player, nodepos, content_features(n).tiles);
|
||||
|
||||
if (dig_time_complete >= 0.001) {
|
||||
selected_node_crack = (u16)((float)CRACK_ANIMATION_LENGTH
|
||||
* dig_time/dig_time_complete);
|
||||
}else {
|
||||
// This is for torches
|
||||
selected_node_crack = CRACK_ANIMATION_LENGTH;
|
||||
}
|
||||
|
||||
if (selected_node_crack >= CRACK_ANIMATION_LENGTH) {
|
||||
infostream<<"Digging completed"<<std::endl;
|
||||
client.groundAction(3, nodepos, neighbourpos, g_selected_item);
|
||||
selected_node_crack = 0;
|
||||
client.removeNode(nodepos);
|
||||
|
||||
if (enable_particles)
|
||||
addDiggingParticles(smgr, player, nodepos, content_features(n).tiles);
|
||||
|
||||
dig_time = 0.0;
|
||||
|
||||
nodig_delay_counter = dig_time_complete
|
||||
/ (float)CRACK_ANIMATION_LENGTH;
|
||||
|
||||
// We don't want a corresponding delay to
|
||||
// very time consuming nodes
|
||||
if (nodig_delay_counter > 0.5)
|
||||
nodig_delay_counter = 0.5;
|
||||
// We want a slight delay to very little
|
||||
// time consuming nodes
|
||||
float mindelay = 0.15;
|
||||
if (nodig_delay_counter < mindelay)
|
||||
nodig_delay_counter = mindelay;
|
||||
}
|
||||
selected_node_crack = CRACK_ANIMATION_LENGTH;
|
||||
}
|
||||
|
||||
dig_time += dtime;
|
||||
if (selected_node_crack >= CRACK_ANIMATION_LENGTH) {
|
||||
infostream<<"Digging completed"<<std::endl;
|
||||
client.groundAction(3, nodepos, neighbourpos, g_selected_item);
|
||||
selected_node_crack = 0;
|
||||
client.removeNode(nodepos);
|
||||
|
||||
camera.setDigging(0); // left click animation
|
||||
if (enable_particles)
|
||||
addDiggingParticles(smgr, player, nodepos, content_features(n).tiles);
|
||||
|
||||
dig_time = 0.0;
|
||||
|
||||
action_delay_counter = usage.delay;
|
||||
}
|
||||
}
|
||||
|
||||
dig_time += dtime;
|
||||
|
||||
camera.setDigging(0); // left click animation
|
||||
}
|
||||
|
||||
|
||||
|
@ -1822,14 +1809,12 @@ void the_game(
|
|||
} // selected_object == NULL
|
||||
}
|
||||
|
||||
use_delay_counter -= dtime;
|
||||
|
||||
// this lets us hold down use to eat, and limits to 2 items per second
|
||||
if (input->wasKeyDown(getKeySetting(VLKC_USE))) {
|
||||
if (use_delay_counter <= 0.0) {
|
||||
if (action_delay_counter <= 0.0) {
|
||||
client.useItem();
|
||||
/* TODO: this should come from content*_features */
|
||||
use_delay_counter = 1.0;
|
||||
action_delay_counter = 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -543,14 +543,14 @@ std::wstring ToolItem::getGuiText()
|
|||
ToolItemFeatures *f = &content_toolitem_features(m_content);
|
||||
txt += f->description;
|
||||
txt += L"\n\n";
|
||||
txt += wgettext("Strength: ");
|
||||
txt += ftows(f->hardness);
|
||||
txt += wgettext("Uses: ");
|
||||
txt += ftows(f->diginfo.uses);
|
||||
txt += L"\n";
|
||||
txt += wgettext("Speed: ");
|
||||
txt += ftows(f->dig_time);
|
||||
txt += ftows(f->diginfo.time);
|
||||
txt += L"\n";
|
||||
txt += wgettext("Level: ");
|
||||
txt += itows(f->level);
|
||||
txt += itows(f->diginfo.level);
|
||||
if (f->fuel_time != 0.0) {
|
||||
char buff[20];
|
||||
txt += L"\n";
|
||||
|
|
|
@ -50,11 +50,11 @@ CraftItem *getDiggedMineralItem(u8 mineral, Player *player, InventoryItem *tool)
|
|||
if (t->content == CONTENT_IGNORE && m.min_level > 0)
|
||||
return NULL;
|
||||
|
||||
if (t->level < m.min_level)
|
||||
if (t->diginfo.level < m.min_level)
|
||||
return NULL;
|
||||
|
||||
u16 count = m.dug_count_min;
|
||||
u16 count_max = t->level;
|
||||
u16 count_max = t->diginfo.level;
|
||||
u16 data = tool->getData();
|
||||
|
||||
if (data != 0) {
|
||||
|
|
|
@ -3287,21 +3287,27 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
InventoryList *mlist = player->inventory.getList("main");
|
||||
if (mlist != NULL && g_settings->getBool("tool_wear")) {
|
||||
InventoryItem *item = mlist->getItem(item_i);
|
||||
if (item && (std::string)item->getName() == "ToolItem") {
|
||||
if (item && (item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
|
||||
ToolItem *titem = (ToolItem*)item;
|
||||
// Get digging properties for material and tool
|
||||
DiggingProperties prop = getDiggingProperties(selected_content, mineral, titem->getContent(),titem->getData());
|
||||
|
||||
if (prop.diggable == false) {
|
||||
tooluse_t usage;
|
||||
if (get_tool_use(&usage,selected_content,mineral,titem->getContent(),titem->getData())) {
|
||||
infostream<<"Server: WARNING: Player digged"
|
||||
<<" with impossible material + tool"
|
||||
<<" combination"<<std::endl;
|
||||
}else{
|
||||
if (!usage.diggable) {
|
||||
infostream<<"Server: WARNING: Player digged"
|
||||
<<" with impossible material + tool"
|
||||
<<" combination"<<std::endl;
|
||||
}
|
||||
|
||||
if (titem->addWear(prop.wear)) {
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
if (usage.wear) {
|
||||
if (titem->addWear(usage.wear)) {
|
||||
mlist->deleteItem(item_i);
|
||||
}else{
|
||||
mlist->addDiff(item_i,titem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3336,7 +3342,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
&& selected_node_features.ondig_special_tool == wielded_tool_features.type
|
||||
&& (
|
||||
selected_node_features.liquid_type != LIQUID_NONE
|
||||
|| wielded_tool_features.level > 1
|
||||
|| wielded_tool_features.diginfo.level > 1
|
||||
)
|
||||
) {
|
||||
if (selected_node_features.ondig_special_tool_append != "") {
|
||||
|
@ -3520,8 +3526,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if (
|
||||
extra_dug_s != ""
|
||||
&& extra_rarity != 0
|
||||
&& selected_node_features.extra_dug_item_min_level <= wielded_tool_features.level
|
||||
&& selected_node_features.extra_dug_item_max_level >= wielded_tool_features.level
|
||||
&& selected_node_features.extra_dug_item_min_level <= wielded_tool_features.diginfo.level
|
||||
&& selected_node_features.extra_dug_item_max_level >= wielded_tool_features.diginfo.level
|
||||
&& myrand_range(0,extra_rarity) == 0
|
||||
) {
|
||||
std::istringstream is(extra_dug_s, std::ios::binary);
|
||||
|
|
Loading…
Reference in New Issue