From 5a0594d7dc2a20820f87be5f6055449ae4e3f0cc Mon Sep 17 00:00:00 2001 From: poikilos <7557867+poikilos@users.noreply.github.com> Date: Mon, 15 May 2017 10:32:32 -0400 Subject: [PATCH] mock_tnt now causes damage but only to players and mobs (and causes playereffects if playereffects is installed). Also, switched from monoidal_effects to player_monoids and playereffects. Author of monoidal_effects says it is deprecated by player_monoids and that functionality stripped out is present in playereffects. --- etc/Mods,WIP/mock_tnt/depends.txt | 3 +- etc/Mods,WIP/mock_tnt/init.lua | 150 +++++++++++++++--- etc/Mods,WIP/mock_tnt/playereffects.lua | 33 ++++ .../textures/playereffects_example_black.png | Bin 0 -> 69 bytes .../game-install-ENLIVEN | 63 ++++++-- 5 files changed, 214 insertions(+), 35 deletions(-) create mode 100644 etc/Mods,WIP/mock_tnt/playereffects.lua create mode 100644 etc/Mods,WIP/mock_tnt/textures/playereffects_example_black.png diff --git a/etc/Mods,WIP/mock_tnt/depends.txt b/etc/Mods,WIP/mock_tnt/depends.txt index 1a59d96..ebb56fb 100644 --- a/etc/Mods,WIP/mock_tnt/depends.txt +++ b/etc/Mods,WIP/mock_tnt/depends.txt @@ -1,3 +1,2 @@ default - - +playereffects? \ No newline at end of file diff --git a/etc/Mods,WIP/mock_tnt/init.lua b/etc/Mods,WIP/mock_tnt/init.lua index 79914c9..7bc9455 100644 --- a/etc/Mods,WIP/mock_tnt/init.lua +++ b/etc/Mods,WIP/mock_tnt/init.lua @@ -7,6 +7,29 @@ if enable_tnt == nil then enable_tnt = minetest.is_singleplayer() end +local function notify(name, retcode) + if(retcode == false) then + minetest.chat_send_player(name, "You did not suffer any ill effects.") + -- else + -- NOTE: tostring(retcode) is just a number, and debuff countdowns are automatically shown on right anyway + -- minetest.chat_send_player(name, "You temporarily suffer from "..tostring(retcode)) + end +end + +if (minetest.global_exists("playereffects")) then + dofile(minetest.get_modpath(minetest.get_current_modname()).."/playereffects.lua") +end + +local function apply_flashbang_debuffs(player) + if (minetest.global_exists("playereffects")) then + -- see also /usr/local/share/minetest/games/ENLIVEN/mods/playereffects/examples.lua + local ret = playereffects.apply_effect_type("blind", 10, player) + notify(player:get_player_name(), ret) + local ret = playereffects.apply_effect_type("low_speed", 12, player) + notify(player:get_player_name(), ret) + end +end + local tnt_radius = tonumber(minetest.setting_get("tnt_radius") or 3) local function rand_pos(center, pos, radius) @@ -61,7 +84,7 @@ if not enable_tnt then end -local function add_effects(pos, radius) +local function add_effects(pos, radius, drops) minetest.add_particle({ pos = pos, velocity = vector.new(), @@ -91,18 +114,19 @@ local function add_effects(pos, radius) -- we just dropped some items. Look at the items entities and pick -- one of them to use as texture local texture = "mock_tnt_blast.png" --fallback texture - -- local most = 0 - -- for name, stack in pairs(drops) do - -- local count = stack:get_count() - -- if count > most then - -- most = count - -- local def = minetest.registered_nodes[name] - -- if def and def.tiles and def.tiles[1] then - -- texture = def.tiles[1] - -- end - -- end - -- end - + if drops ~= nil then + local most = 0 + for name, stack in pairs(drops) do + local count = stack:get_count() + if count > most then + most = count + local def = minetest.registered_nodes[name] + if def and def.tiles and def.tiles[1] then + texture = def.tiles[1] + end + end + end + end minetest.add_particlespawner({ amount = 64, time = 0.1, @@ -235,6 +259,80 @@ local function UNUSED_mock_tnt_explode(pos, radius, ignore_protection, ignore_on return drops, radius end +local function eject_drops(drops, pos, radius) + local drop_pos = vector.new(pos) + for _, item in pairs(drops) do + local count = math.min(item:get_count(), item:get_stack_max()) + while count > 0 do + local take = math.max(1,math.min(radius * radius, + count, + item:get_stack_max())) + rand_pos(pos, drop_pos, radius) + local dropitem = ItemStack(item) + dropitem:set_count(take) + local obj = minetest.add_item(drop_pos, dropitem) + if obj then + obj:get_luaentity().collect = true + obj:setacceleration({x = 0, y = -10, z = 0}) + obj:setvelocity({x = math.random(-3, 3), + y = math.random(0, 10), + z = math.random(-3, 3)}) + end + count = count - take + end + end +end + +local function entity_physics(pos, radius, drops) + local objs = minetest.get_objects_inside_radius(pos, radius) + for _, obj in pairs(objs) do + local obj_pos = obj:getpos() + local dist = math.max(1, vector.distance(pos, obj_pos)) + + local damage = (4 / dist) * radius + if obj:is_player() then + -- currently the engine has no method to set + -- player velocity. See #2960 + -- instead, we knock the player back 1.0 node, and slightly upwards + local dir = vector.normalize(vector.subtract(obj_pos, pos)) + local moveoff = vector.multiply(dir, dist + 1.0) + local newpos = vector.add(pos, moveoff) + newpos = vector.add(newpos, {x = 0, y = 0.2, z = 0}) + obj:setpos(newpos) + + obj:set_hp(obj:get_hp() - damage) + else + local do_damage = true + local do_knockback = true + local entity_drops = {} + local luaobj = obj:get_luaentity() + local objdef = minetest.registered_entities[luaobj.name] + + if objdef and objdef.on_blast then + do_damage, do_knockback, entity_drops = objdef.on_blast(luaobj, damage) + end + + if do_knockback then + local obj_vel = obj:getvelocity() + obj:setvelocity(calc_velocity(pos, obj_pos, + obj_vel, radius * 10)) + end + if do_damage then + if not obj:get_armor_groups().immortal then + obj:punch(obj, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, nil) + end + end + for _, item in pairs(entity_drops) do + add_drop(drops, item) + end + end + end +end + + function mock_tnt.boom(pos, def) minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 2*64}) minetest.set_node(pos, {name = "mock_tnt:boom"}) @@ -242,13 +340,27 @@ function mock_tnt.boom(pos, def) -- def.ignore_on_blast) -- append entity drops -- local damage_radius = (radius / def.radius) * def.damage_radius + local drops = {} + local radius = def.damage_radius local damage_radius = def.damage_radius - -- entity_physics(pos, damage_radius, drops) - -- if not def.disable_drops then - -- eject_drops(drops, pos, radius) - -- end - -- add_effects(pos, radius, drops) - add_effects(pos, damage_radius) + entity_physics(pos, damage_radius, drops) + + local objs = minetest.get_objects_inside_radius(pos, radius) + for _, obj in pairs(objs) do + local obj_pos = obj:getpos() + local dist = math.max(1, vector.distance(pos, obj_pos)) + + local damage = (4 / dist) * radius + if obj:is_player() then + apply_flashbang_debuffs(obj) + end + end + + if not def.disable_drops then + eject_drops(drops, pos, radius) + end + add_effects(pos, radius, drops) + -- add_effects_nodrops(pos, damage_radius) end minetest.register_node("mock_tnt:boom", { diff --git a/etc/Mods,WIP/mock_tnt/playereffects.lua b/etc/Mods,WIP/mock_tnt/playereffects.lua new file mode 100644 index 0000000..a7cc7c1 --- /dev/null +++ b/etc/Mods,WIP/mock_tnt/playereffects.lua @@ -0,0 +1,33 @@ +-- Slows the user down +playereffects.register_effect_type("low_speed", "Low speed", nil, {"speed"}, + function(player) + player:set_physics_override(0.25,nil,nil) + end, + + function(effect, player) + player:set_physics_override(1,nil,nil) + end +) + +-- Makes the player screen black for 5 seconds (very experimental!) +playereffects.register_effect_type("blind", "Blind", nil, {}, + function(player) + local hudid = player:hud_add({ + hud_elem_type = "image", + position = { x=0.5, y=0.5 }, + scale = { x=-100, y=-100 }, + text = "playereffects_example_black.png", + }) + if(hudid ~= nil) then + return { hudid = hudid } + else + minetest.log("error", "[playereffects] [examples] The effect \"Blind\" could not be applied. The call to hud_add(...) failed.") + return false + end + end, + function(effect, player) + player:hud_remove(effect.metadata.hudid) + end +) + + diff --git a/etc/Mods,WIP/mock_tnt/textures/playereffects_example_black.png b/etc/Mods,WIP/mock_tnt/textures/playereffects_example_black.png new file mode 100644 index 0000000000000000000000000000000000000000..cf671d132881ed90f439205faa0b9831b9ca996c GIT binary patch literal 69 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2ryJf1F&Asp9}6A}`DJQfB. +#monoidal_effects by Byakuren [raymoo on GitHub] is deprecated by player_monoids by Byakuren [raymoo on GitHub] +playereffects by Wuzzy +#according to the author https://forum.minetest.net/viewtopic.php?t=13941 +#cd $HOME\Downloads +#MTMOD_DL_ZIP=master.zip +#MTMOD_SRC_ZIP=monoidal_effects.zip +#MTMOD_UNZ_NAME=monoidal_effects-master +#MTMOD_DEST_NAME=monoidal_effects +#MTMOD_DEST_PATH=$MT_MYGAME_MODS_PATH/$MTMOD_DEST_NAME +##if [ -d "$MTMOD_UNZ_NAME" ]; then +#rm -Rf $MTMOD_UNZ_NAME +##fi +#if [ -f $MTMOD_DL_ZIP ]; then +# rm -f $MTMOD_DL_ZIP +#fi +#if [ -f $MTMOD_SRC_ZIP ]; then +# rm $MTMOD_SRC_ZIP +#fi +#wget https://github.com/minetest-mods/monoidal_effects/archive/master.zip +#mv $MTMOD_DL_ZIP $MTMOD_SRC_ZIP +#unzip $MTMOD_SRC_ZIP +#sudo mv $MTMOD_UNZ_NAME "$MTMOD_DEST_PATH" +#if [ ! -d "$MTMOD_DEST_PATH" ]; then +# echo "ERROR: failed to unzip $MTMOD_DEST_PATH, so cannot continue." +# exit 1 +#fi + +cd $HOME\Downloads MTMOD_DL_ZIP=master.zip -MTMOD_SRC_ZIP=monoidal_effects.zip -MTMOD_UNZ_NAME=monoidal_effects-master -MTMOD_DEST_NAME=monoidal_effects +MTMOD_SRC_ZIP=player_monoids.zip +MTMOD_UNZ_NAME=player_monoids-master +MTMOD_DEST_NAME=player_monoids MTMOD_DEST_PATH=$MT_MYGAME_MODS_PATH/$MTMOD_DEST_NAME #if [ -d "$MTMOD_UNZ_NAME" ]; then rm -Rf $MTMOD_UNZ_NAME @@ -1205,7 +1239,7 @@ fi if [ -f $MTMOD_SRC_ZIP ]; then rm $MTMOD_SRC_ZIP fi -wget https://github.com/minetest-mods/monoidal_effects/archive/master.zip +wget https://github.com/minetest-mods/player_monoids/archive/master.zip mv $MTMOD_DL_ZIP $MTMOD_SRC_ZIP unzip $MTMOD_SRC_ZIP sudo mv $MTMOD_UNZ_NAME "$MTMOD_DEST_PATH" @@ -1214,6 +1248,7 @@ if [ ! -d "$MTMOD_DEST_PATH" ]; then exit 1 fi + cd "$HOME/Downloads" MTMOD_DL_ZIP=master MTMOD_SRC_ZIP=worldedit.zip