From: Zefram Date: Sat, 5 Jul 2014 20:29:07 +0000 (+0100) Subject: Resumable digging X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=463fc7b971a2da7bbfd88f8834d90c247727a55b;p=zefram%2Fminetest%2Fminetest_engine.git Resumable digging When a node is partially dug but then digging stops, retain the invested digging effort for a while rather than discard it. Digging of that node can be resumed from the partially-dug state. The ultimate vision towards which this works is that the effort required to dig a node could be shared not just between multiple left clicks but also between multiple tools and even multiple players, each involved tool suffering wear pro rata. This would necessarily be mediated by the server, and would even, through partial tool wear, be semantically visible to mods. This patch doesn't do that. This patch does the simple client-side version, under the prevailing paradigm that all the effort of digging a node is credited to a single tool. This requires that the total time invested to dig the node must be at least what the dominant tool would take, regardless of which other tools were involved in the digging. When a node is partially dug, what is retained is the time that was spent digging it, regardless of which tool was used. The partially-dug node shows the crack progression that it had reached with the tool last used on it, which is based on the time spent digging divided by the time that would be taken to fully dig using that tool. When resuming digging, if a different tool is used, the time spent digging is simply added up, and the crack progression is recomputed for the new tool's total dig time. This can result in crack progression jumping forward or backward. A partially-dug state is retained for only one node at a time: starting digging on a different node throws away the partially-dug state. The partial digging effort also decays over time: whatever dig time was accumulated when digging stops will be lost linearly over the next ten seconds. Resuming digging stops the decay, and new dig time is added onto the decayed accumulated time. If the resumed digging is stopped again at a partially-dug state then a fresh ten-second decay process starts, using the revised accumulated dig time. --- diff --git a/src/game.cpp b/src/game.cpp index 76819314..823bce18 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1593,7 +1593,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input, float nodig_delay_timer = 0.0; float dig_time = 0.0; - u16 dig_index = 0; + float dig_time_decay_rate = 0.0; + float dig_time_complete = 0.0; + v3s16 dig_pos = v3s16(0,0,0); PointedThing pointed_old; bool digging = false; bool ldown_for_dig = false; @@ -2783,8 +2785,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, if(!digging) { client.interact(1, pointed_old); - client.setCrack(-1, v3s16(0,0,0)); - dig_time = 0.0; + dig_time_decay_rate = dig_time * 0.1; } } if(!digging && ldown_for_dig && !input->getLeftState()) @@ -2837,8 +2838,14 @@ void the_game(bool &kill, bool random_input, InputHandler *input, { infostream<<"Started digging"<get(n).groups, tp); } - float dig_time_complete = 0.0; - if(params.diggable == false) { // I guess nobody will wait for this long @@ -2875,17 +2880,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, } } - if(dig_time_complete >= 0.001) - { - dig_index = (u16)((float)crack_animation_length - * dig_time/dig_time_complete); - } - // This is for torches - else - { - dig_index = crack_animation_length; - } - SimpleSoundSpec sound_dig = nodedef->get(n).sound_dig; if(sound_dig.exists() && params.diggable){ if(sound_dig.name == "__group"){ @@ -2900,21 +2894,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input, } } - // Don't show cracks if not diggable - if(dig_time_complete >= 100000.0) - { - } - else if(dig_index < crack_animation_length) - { - //TimeTaker timer("client.setTempMod"); - //infostream<<"dig_index="<= dig_time_complete) { infostream<<"Digging completed"<event()->put(e); } - if(dig_time_complete < 100000.0) - dig_time += dtime; - else { - dig_time = 0; - client.setCrack(-1, nodepos); - } - camera.setDigging(0); // left click animation } @@ -3073,6 +3048,25 @@ void the_game(bool &kill, bool random_input, InputHandler *input, input->resetLeftReleased(); input->resetRightReleased(); + /* + Handle partial digging state + */ + if(!digging && dig_time > 0) { + dig_time -= dig_time_decay_rate * dtime; + if(dig_time < 0) + dig_time = 0; + } + if(dig_time > 0 && dig_time_complete < 100000.0) { + client.setCrack(dig_time_complete >= 0.001 ? + (u16)((float)crack_animation_length + * dig_time/dig_time_complete) : + // This is for torches + crack_animation_length, + dig_pos); + } else { + client.setCrack(-1, v3s16(0,0,0)); + } + /* Calculate stuff for drawing */