diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 0c23daae7..0d34779d4 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -1,4 +1,9 @@ local S = minetest.get_translator("mcl_fishing") +local mod_throwing = minetest.get_modpath("mcl_throwing") + +local entity_mapping = { + ["mcl_fishing:bobber"] = "mcl_fishing:bobber_entity", +} local go_fishing = function(itemstack, user, pointed_thing) if pointed_thing and pointed_thing.under then @@ -83,26 +88,308 @@ local go_fishing = function(itemstack, user, pointed_thing) return nil end +local bobber_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_fishing_bobber.png"}, + visual_size = {x=0.5, y=0.5}, + collisionbox = {0.45,0.45,0.45,0.45,0.45,0.45}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + + _lastpos={}, + _dive = false, + _waittick = nil, + _tick = 0, + player=nil, + _oldy = nil, + objtype="fishing", +} + +local fish = function(itemstack, player) + local pos = player:get_pos() + + local objs = minetest.get_objects_inside_radius(pos, 250) + local num = 0 + local ent = nil + local noent = true + + --Check for bobber if so handle. + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent.player and ent.objtype=="fishing" then + if (player:get_player_name() == ent.player) then + noent = false + if ent._dive == true then + local itemname + local itemcount = 1 + local itemwear = 0 + -- FIXME: Maybe use a better seeding + local pr = PseudoRandom(os.time() * math.random(1, 100)) + local r = pr:next(1, 100) + if r <= 85 then + -- Fish + items = mcl_loot.get_loot({ + items = { + { itemstring = "mcl_fishing:fish_raw", weight = 60 }, + { itemstring = "mcl_fishing:salmon_raw", weight = 25 }, + { itemstring = "mcl_fishing:clownfish_raw", weight = 2 }, + { itemstring = "mcl_fishing:pufferfish_raw", weight = 13 }, + } + }, pr) + elseif r <= 95 then + -- Junk + items = mcl_loot.get_loot({ + items = { + { itemstring = "mcl_core:bowl", weight = 10 }, + { itemstring = "mcl_fishing:fishing_rod", weight = 2, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage + { itemstring = "mcl_mobitems:leather", weight = 10 }, + { itemstring = "3d_armor:boots_leather", weight = 10, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, + { itemstring = "mcl_core:stick", weight = 5 }, + { itemstring = "mcl_mobitems:string", weight = 5 }, + { itemstring = "mcl_potions:potion_water", weight = 10 }, + { itemstring = "mcl_mobitems:bone", weight = 10 }, + { itemstring = "mcl_dye:black", weight = 1, amount_min = 10, amount_max = 10 }, + { itemstring = "mcl_mobitems:string", weight = 10 }, -- TODO: Tripwire Hook + } + }, pr) + else + -- Treasure + items = mcl_loot.get_loot({ + items = { + -- TODO: Enchanted Bow + { itemstring = "mcl_bows:bow", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage + -- TODO: Enchanted Book + { itemstring = "mcl_books:book" }, + -- TODO: Enchanted Fishing Rod + { itemstring = "mcl_fishing:fishing_rod", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage + { itemstring = "mcl_mobs:nametag", }, + { itemstring = "mcl_mobitems:saddle", }, + { itemstring = "mcl_flowers:waterlily", }, + } + }, pr) + end + local item + if #items >= 1 then + item = ItemStack(items[1]) + else + item = ItemStack() + end + local inv = player:get_inventory() + if inv:room_for_item("main", item) then + inv:add_item("main", item) + end + if not minetest.settings:get_bool("creative_mode") then + local idef = itemstack:get_definition() + itemstack:add_wear(65535/65) -- 65 uses + if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then + minetest.sound_play(idef.sound.breaks, {pos=player.get_pos(), gain=0.5}) + end + end + end + --Check if object is on land. + local epos = ent.object:get_pos() + epos.y = math.floor(epos.y) + local node = minetest.get_node(epos) + local def = minetest.registered_nodes[node.name] + if def.walkable then + if not minetest.settings:get_bool("creative_mode") then + local idef = itemstack:get_definition() + itemstack:add_wear((65535/65)*2) -- if so and not creative then wear double like in MC. + if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then + minetest.sound_play(idef.sound.breaks, {pos=player.get_pos(), gain=0.5}) + end + end + end + --Destroy bobber. + ent.object:remove() + return itemstack + end + end + end + end + --Check for flying bobber. + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent._thrower and ent.objtype=="fishing" then + if player:get_player_name() == ent._thrower then + noent = false + break + end + end + end + end + --If no bobber or flying_bobber exists then throw bobber. + if noent == true then + local playerpos = player:get_pos() + local dir = player:get_look_dir() + local obj = mcl_throwing.throw("mcl_throwing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15) + obj:get_luaentity()._thrower = player:get_player_name() + end +end + +-- Movement function of bobber +local bobber_on_step = function(self, dtime) + self.timer=self.timer+dtime + local epos = self.object:get_pos() + epos.y = math.floor(epos.y) + local node = minetest.get_node(epos) + local def = minetest.registered_nodes[node.name] + + --If we have no player remove self. + if self.player == nil then + self.object:remove() + end + + --Check if player is nearby + if self._tick % 5 == 0 and self.player ~= nil then + --Destroy bobber if item not wielded. + if (minetest.get_player_by_name(self.player):get_wielded_item():get_name() ~= "mcl_fishing:fishing_rod") then + self.object:remove() + end + + --Destroy bobber if player is too far away. + local objpos = self.object:get_pos() + local playerpos = minetest.get_player_by_name(self.player):get_pos() + if (((playerpos.y - objpos.y) >= 33) or ((playerpos.y - objpos.y) <= -33)) then + self.object:remove() + elseif (((playerpos.x - objpos.x) >= 33) or ((playerpos.x - objpos.x) <= -33)) then + self.object:remove() + elseif (((playerpos.z - objpos.z) >= 33) or ((playerpos.z - objpos.z) <= -33)) then + self.object:remove() + elseif ((((playerpos.z + playerpos.x) - (objpos.z + objpos.x)) >= 33) or ((playerpos.z + playerpos.x) - (objpos.z + objpos.x)) <= -33) then + self.object:remove() + elseif ((((playerpos.y + playerpos.x) - (objpos.y + objpos.x)) >= 33) or ((playerpos.y + playerpos.x) - (objpos.y + objpos.x)) <= -33) then + self.object:remove() + elseif ((((playerpos.z + playerpos.y) - (objpos.z + objpos.y)) >= 33) or ((playerpos.z + playerpos.y) - (objpos.z + objpos.y)) <= -33) then + self.object:remove() + end + + end + --if in liquid then bob. + if def.liquidtype == "source" then + if self._oldy == nil then + self.object:set_pos({x=self.object:get_pos().x,y=math.floor(self.object:get_pos().y)+.5,z=self.object:get_pos().z}) + self._oldy = self.object:get_pos().y + end + minetest.log(self.object:get_pos().y.." "..self._oldy) + -- reset to original position after dive. + if self.object:get_pos().y > self._oldy then + self.object:set_pos({x=self.object:get_pos().x,y=self._oldy,z=self.object:get_pos().z}) + self.object:set_velocity({x=0,y=0,z=0}) + self.object:set_acceleration({x=0,y=0,z=0}) + end + if self._dive then + for i=1,2 do + --spray bubbles there's a fish. + minetest.add_particle({ + pos = {x=epos["x"]+math.random(-1,1)*math.random()/2,y=epos["y"]+0.1,z=epos["z"]+math.random(-1,1)*math.random()/2}, + velocity = {x=0, y=4, z=0}, + acceleration = {x=0, y=-5, z=0}, + expirationtime = math.random(), + size = math.random()+0.5, + collisiondetection = true, + vertical = false, + texture = "mcl_particles_bubble.png", + }) + end + if self._tick ~= self._waittick then + self._tick = self._tick + 1 + else + self._waittick = nil + self._tick = 0 + self._dive = false + end + else if self._waittick == nil then + --wait for random number of ticks. + self._waittick = math.random(50,800) + else + if self._tick ~= self._waittick then + self._tick = self._tick + 1 + else + --wait time is over time to dive. + self._dive = true + self.object:set_velocity({x=0,y=-2,z=0}) + self.object:set_acceleration({x=0,y=5,z=0}) + self._waittick = 30 + self._tick = 0 + end + end + end +end + + -- Destroy when hitting a solid node + --if self._lastpos.x~=nil then + -- if (def and def.walkable) or not def then + --self.object:remove() + -- return + -- end + --end + --self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +bobber_ENTITY.on_step = bobber_on_step + +minetest.register_entity("mcl_fishing:bobber_entity", bobber_ENTITY) + +--If player leaves area remove bobber. +minetest.register_on_leaveplayer(function(player) + local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) + local num = 0 + local ent = nil + local noent = true + + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent.player and ent.objtype=="fishing" then + ent.object:remove() + elseif ent._thrower and ent.objtype=="fishing" then + ent.object:remove() + end + end + end +end) + +--if player dies remove bobber. +minetest.register_on_dieplayer(function(player) + local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) + local num = 0 + local ent = nil + local noent = true + + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent.player and ent.objtype=="fishing" then + ent.object:remove() + elseif ent._thrower and ent.objtype=="fishing" then + ent.object:remove() + end + end + end +end) + -- Fishing Rod minetest.register_tool("mcl_fishing:fishing_rod", { description = S("Fishing Rod"), _doc_items_longdesc = S("Fishing rods can be used to catch fish."), - _doc_items_usagehelp = S("Rightclick a water source to try to go fishing. Who knows what you're going to catch?"), + _doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"), -- This item is incomplete, hide it from creative inventory - groups = { tool=1, not_in_creative_inventory=1 }, + groups = { tool=1}, inventory_image = "mcl_fishing_fishing_rod.png", stack_max = 1, - liquids_pointable = true, - on_place = go_fishing, + on_place = fish, + on_secondary_use = fish, sound = { breaks = "default_tool_breaks" }, }) ---[[ - -Temporarily removed from crafting as the fishing rod is massively overpowered atm. - -TODO: Re-enable crafting when fishing rod has been improved. - +--Make fishing rods craftable again. minetest.register_craft({ output = "mcl_fishing:fishing_rod", recipe = { @@ -119,8 +406,6 @@ minetest.register_craft({ {'mcl_mobitems:string','','mcl_core:stick'}, } }) -]] - minetest.register_craft({ type = "fuel", recipe = "mcl_fishing:fishing_rod", diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png new file mode 100644 index 000000000..0c93fd4f9 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png index f8b4f8714..2fbcc7344 100644 Binary files a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png and b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png differ diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 7205a17b5..1c579bd8d 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -2,6 +2,7 @@ mcl_throwing = {} local S = minetest.get_translator("mcl_throwing") local mod_death_messages = minetest.get_modpath("mcl_death_messages") +local mod_fishing = minetest.get_modpath("mcl_fishing") -- -- Snowballs and other throwable items @@ -10,12 +11,14 @@ local mod_death_messages = minetest.get_modpath("mcl_death_messages") local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) local entity_mapping = { + ["mcl_throwing:flying_bobber"] = "mcl_throwing:flying_bobber_entity", ["mcl_throwing:snowball"] = "mcl_throwing:snowball_entity", ["mcl_throwing:egg"] = "mcl_throwing:egg_entity", ["mcl_throwing:ender_pearl"] = "mcl_throwing:ender_pearl_entity", } local velocities = { + ["mcl_throwing:flying_bobber_entity"] = 5, ["mcl_throwing:snowball_entity"] = 22, ["mcl_throwing:egg_entity"] = 22, ["mcl_throwing:ender_pearl_entity"] = 22, @@ -117,6 +120,22 @@ local pearl_ENTITY={ _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl } +local flying_bobber_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. + visual_size = {x=0.5, y=0.5}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = get_staticdata, + on_activate = on_activate, + + _lastpos={}, + _thrower = nil, + objtype="fishing", +} + -- Snowball on_step()--> called when snowball is moving. local snowball_on_step = function(self, dtime) self.timer=self.timer+dtime @@ -284,13 +303,39 @@ local pearl_on_step = function(self, dtime) self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node end +-- Movement function of flying bobber +local flying_bobber_on_step = function(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + --local player = minetest.get_player_by_name(self._thrower) + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + if (def and (def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source")) or not def then + local make_child= function(object) + local ent = object:get_luaentity() + ent.player = self._thrower + ent.child = true + end + make_child(minetest.add_entity(self._lastpos, "mcl_fishing:bobber_entity")) + self.object:remove() + return + end + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + snowball_ENTITY.on_step = snowball_on_step egg_ENTITY.on_step = egg_on_step pearl_ENTITY.on_step = pearl_on_step +flying_bobber_ENTITY.on_step = flying_bobber_on_step minetest.register_entity("mcl_throwing:snowball_entity", snowball_ENTITY) minetest.register_entity("mcl_throwing:egg_entity", egg_ENTITY) minetest.register_entity("mcl_throwing:ender_pearl_entity", pearl_ENTITY) +minetest.register_entity("mcl_throwing:flying_bobber_entity", flying_bobber_ENTITY) local how_to_throw = S("Use the punch key to throw.")