diff --git a/api.lua b/api.lua new file mode 100644 index 0000000..a32c5db --- /dev/null +++ b/api.lua @@ -0,0 +1,707 @@ +--vehicles/mounts api by D00Med, based on lib_mount(see below) + +--License of lib_mount: +-- Minetest mod: lib_mount +-- ======================= +-- by blert2112 + +-- Based on the Boats mod by PilzAdam. + + +-- ----------------------------------------------------------- +-- ----------------------------------------------------------- + + +-- Minetest Game mod: boats +-- ======================== +-- by PilzAdam + +-- License of source code: +-- ----------------------- +-- WTFPL + + +--from lib_mount (required by new functions) + + +local mobs_redo = false +if minetest.get_modpath("mobs")then +if mobs.mod and mobs.mod == "redo" then + mobs_redo = true +end +end + +--attach position seems broken, and eye offset will cause problems if the vehicle/mount/player is destroyed whilst driving/riding + +local function force_detach(player) + local attached_to = player:get_attach() + if attached_to and attached_to:get_luaentity() then + local entity = attached_to:get_luaentity() + if entity.driver then + if entity ~= nil then entity.driver = nil end + end + player:set_detach() + end + default.player_attached[player:get_player_name()] = false + player:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0}) +end + +function object_attach(entity, player, attach_at, visible, eye_offset) + eye_offset = eye_offset or {x=0, y=0, z=0} + force_detach(player) + entity.driver = player + entity.loaded = true + player:set_attach(entity.object, "", attach_at, {x=0, y=0, z=0}) + --this is to hide the player when the attaching doesn't work properly + if not visible then + player:set_properties({visual_size = {x=0, y=0}}) + else + player:set_properties({visual_size = {x=1, y=1}}) + end + player:set_eye_offset(eye_offset, {x=0, y=2, z=-40}) + default.player_attached[player:get_player_name()] = true + minetest.after(0.2, function() + default.player_set_animation(player, "sit" , 30) + end) + entity.object:setyaw(player:get_look_yaw() - math.pi / 2) +end + +function object_detach(entity, player, offset) + entity.driver = nil + entity.object:setvelocity({x=0, y=0, z=0}) + player:set_detach() + default.player_attached[player:get_player_name()] = false + default.player_set_animation(player, "stand" , 30) + player:set_properties({ + visual_size = {x = 1, y = 1}, + }) + player:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0}) + local pos = player:getpos() + pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + minetest.after(0.1, function() + player:setpos(pos) + end) +end +------------------------------------------------------------------------------- + + +minetest.register_on_leaveplayer(function(player) + force_detach(player) +end) + +minetest.register_on_shutdown(function() + local players = minetest.get_connected_players() + for i = 1,#players do + force_detach(players[i]) + end +end) + +minetest.register_on_dieplayer(function(player) + force_detach(player) + return true +end) + +------------------------------------------------------------------------------- + +--mixed code(from this mod and lib_mount) + +--basic driving, use for basic vehicles/mounts, with optional weapons +function object_drive(entity, dtime, speed, decell, shoots, arrow, reload, moving_anim, stand_anim, jumps) + local ctrl = entity.driver:get_player_control() + local velo = entity.object:getvelocity() + local dir = entity.driver:get_look_dir(); + local name = entity.driver:get_player_name() + local vec_forward = {x=dir.x*speed,y=velo.y+1*-2,z=dir.z*speed} + local vec_backward = {x=-dir.x*speed,y=velo.y+1*-2,z=-dir.z*speed} + local vec_stop = {x=velo.x*decell,y=velo.y+1*-2,z=velo.z*decell} + local yaw = entity.driver:get_look_yaw(); + if ctrl.up then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_forward) + elseif ctrl.down then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_backward) + elseif not ctrl.down or ctrl.up then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_stop) + end + if ctrl.sneak and shoots and entity.loaded then + entity.loaded = false + local pos = entity.object:getpos() + local obj = minetest.env:add_entity({x=pos.x+0+dir.x*2,y=pos.y+1.5+dir.y,z=pos.z+0+dir.z*2}, arrow) + local vec = {x=dir.x*9,y=dir.y*9,z=dir.z*9} + local yaw = entity.driver:get_look_yaw(); + obj:setyaw(yaw+math.pi/2) + obj:setvelocity(vec) + obj:setacceleration({x=0, y=-2, z=0}) + object = obj:get_luaentity() + object.launcher = entity.driver + minetest.after(reload, function() + entity.loaded = true + minetest.chat_send_player(name, "Catapult loaded") + end) + end + --lib_mount animation + if velo.x == 0 and velo.y == 0 and velo.z == 0 then + if stand_anim and stand_anim ~= nil and mobs_redo == true then + set_animation(entity, stand_anim) + end + return + end + if moving_anim and moving_anim ~= nil then + set_animation(entity, moving_anim) + end + --jumping not working + -- local jumps = jumps or false + -- if jumps == true and ctrl.jump then + -- local xvel = entity.object:getvelocity().x + -- local zvel = entity.object:getvelocity().z + -- local yvel = entity.object:getvelocity().y + -- local vel = {x=xvel,y=10,z=zvel} + -- entity.object:setvelocity(vel) + -- minetest.after(1.5, function() + -- local xvel = entity.object:getvelocity().x + -- local zvel = entity.object:getvelocity().z + -- local yvel = entity.object:getvelocity().y + -- local vel = {x=xvel,y=-10,z=zvel} + -- entity.object:setvelocity(vel) + -- end) + -- end +end + + + +--simplified in an attempt to reduce lag +function object_drive_simple(entity, dtime, speed, decell) + local ctrl = entity.driver:get_player_control() + local velo = entity.object:getvelocity() + local dir = entity.driver:get_look_dir(); + local vec_forward = {x=dir.x*speed,y=velo.y+1*-2,z=dir.z*speed} + local vec_backward = {x=-dir.x*speed,y=velo.y+1*-2,z=-dir.z*speed} + local vec_stop = {x=velo.x*decell,y=velo.y+1*-2,z=velo.z*decell} + local yaw = entity.driver:get_look_yaw(); + entity.object:setyaw(yaw+math.pi+math.pi/2) + if ctrl.up then + entity.object:setvelocity(vec_forward) + elseif ctrl.down then + entity.object:setvelocity(vec_backward) + elseif not ctrl.down or ctrl.up then + entity.object:setvelocity(vec_stop) + end +end + +--same as above but with improvements for cars and nitro/boost +function object_drive_car(entity, dtime, speed, decell, nitro_duration) + local ctrl = entity.driver:get_player_control() + local velo = entity.object:getvelocity() + local dir = entity.driver:get_look_dir(); + local vec_forward = {x=dir.x*speed,y=velo.y-0.5,z=dir.z*speed} + local vec_nitro = {x=dir.x*(speed*1.5),y=velo.y-0.5,z=dir.z*(speed*1.5)} + local vec_backward = {x=-dir.x*speed,y=velo.y-0.5,z=-dir.z*speed} + local vec_stop = {x=velo.x*decell,y=velo.y-1,z=velo.z*decell} + local yaw = entity.driver:get_look_yaw(); + entity.object:setyaw(yaw+math.pi+math.pi/2) + if not entity.nitro then + minetest.after(4, function() + entity.nitro = true + end) + end + if ctrl.up and ctrl.sneak and entity.nitro then + entity.object:setvelocity(vec_nitro) + local pos = entity.object:getpos() + minetest.add_particlespawner( + 10, --amount + 1, --time + {x=pos.x-0.5, y=pos.y, z=pos.z-0.5}, --minpos + {x=pos.x+0.5, y=pos.y, z=pos.z+0.5}, --maxpos + {x=0, y=0, z=0}, --minvel + {x=-velo.x, y=-velo.y, z=-velo.z}, --maxvel + {x=-0,y=-0,z=-0}, --minacc + {x=0,y=0,z=0}, --maxacc + 0.1, --minexptime + 0.2, --maxexptime + 10, --minsize + 15, --maxsize + false, --collisiondetection + "vehicles_nitro.png" --texture + ) + minetest.after(nitro_duration, function() + entity.nitro = false + end) + elseif ctrl.up then + entity.object:setvelocity(vec_forward) + elseif ctrl.down then + entity.object:setvelocity(vec_backward) + elseif not ctrl.down or ctrl.up then + entity.object:setvelocity(vec_stop) + end +end + +--for boats and watercraft +function object_float(entity, dtime, speed, decell) + local ctrl = entity.driver:get_player_control() + local velo = entity.object:getvelocity() + local dir = entity.driver:get_look_dir() + local pos = entity.object:getpos() + local vec_forward = {x=dir.x*speed,y=velo.y,z=dir.z*speed} + local vec_backward = {x=-dir.x*speed,y=velo.y,z=-dir.z*speed} + local vec_stop = {x=velo.x*decell,y=velo.y,z=velo.z*decell} + local yaw = entity.driver:get_look_yaw(); + entity.object:setyaw(yaw+math.pi+math.pi/2) + if minetest.get_node(pos).name == "default:river_water_source" or minetest.get_node(pos).name == "default:water_source" then + entity.floating = true + else entity.floating = false + end + if ctrl.up and entity.floating then + entity.object:setvelocity(vec_forward) + elseif ctrl.down and entity.floating then + entity.object:setvelocity(vec_backward) + elseif not ctrl.down or ctrl.up then + entity.object:setvelocity(vec_stop) + end +end + +--attempts to improve object_drive_car +-- function object_drive_experimental(entity, dtime, power, traction, nitro_duration) + -- local ctrl = entity.driver:get_player_control() + -- local velo = entity.object:getvelocity() + -- local speed = math.abs(velo.x)+math.abs(velo.z) + -- local nitro_remaining = entity.nitro + -- local dir = entity.driver:get_look_dir() + -- local yaw1 = entity.object:getyaw() + -- local dir_x = -math.sin(yaw1) + -- local dir_z = math.cos(yaw1) + -- local vec_forward = {x=dir_x*power,y=velo.y-0.5,z=dir_z*power} + -- local vec_nitro = {x=dir.x*(power*1.5),y=velo.y-0.5,z=dir.z*(power*1.5)} + -- local vec_backward = {x=-dir.x*power,y=velo.y-0.5,z=-dir.z*power} + -- local vec_stop = {x=velo.x*traction,y=velo.y-1,z=velo.z*traction} + -- local yaw = entity.driver:get_look_yaw(); + -- if ctrl.left then + -- entity.object:setyaw(yaw1+math.pi/180+speed/360) + -- elseif ctrl.right then + -- entity.object:setyaw(yaw1-math.pi/180-speed/360) + -- else + -- entity.object:setyaw(yaw1) + -- end + -- if not entity.nitro then + -- minetest.after(4, function() + -- entity.nitro = true + -- end) + -- end + -- if ctrl.up and ctrl.sneak and entity.nitro then + -- entity.object:setvelocity(vec_nitro) + -- local pos = entity.object:getpos() + -- minetest.add_particlespawner( + -- 15, --amount + -- 1, --time + -- {x=pos.x-0.5, y=pos.y, z=pos.z-0.5}, --minpos + -- {x=pos.x+0.5, y=pos.y, z=pos.z+0.5}, --maxpos + -- {x=0, y=0, z=0}, --minvel + -- {x=-velo.x, y=-velo.y, z=-velo.z}, --maxvel + -- {x=-0,y=-0,z=-0}, --minacc + -- {x=0,y=0,z=0}, --maxacc + -- 0.1, --minexptime + -- 0.2, --maxexptime + -- 10, --minsize + -- 15, --maxsize + -- false, --collisiondetection + -- "vehicles_nitro.png" --texture + -- ) + -- minetest.after(nitro_duration, function() + -- entity.nitro = false + -- end) + -- elseif ctrl.up then + -- entity.object:setvelocity(vec_forward) + -- elseif ctrl.down then + -- entity.object:setvelocity(vec_backward) + -- elseif not ctrl.down or ctrl.up then + -- entity.object:setvelocity(vec_stop) + -- end +-- end + +--stationary object, useful for gun turrets etc. +function object_turret(entity, dtime, height, arrow, shoot_interval) + local ctrl = entity.driver:get_player_control() + local yaw = entity.driver:get_look_yaw(); + entity.object:setyaw(yaw+math.pi+math.pi/2) + if ctrl.sneak and entity.loaded then + entity.loaded = false + local pos = entity.object:getpos() + local dir = entity.driver:get_look_dir(); + local obj = minetest.env:add_entity({x=pos.x+dir.x*1.2,y=pos.y+height,z=pos.z+dir.z*1.2}, arrow) + local yaw = entity.driver:get_look_yaw(); + local vec = {x=dir.x*9, y=dir.y*9, z=dir.z*9} + obj:setyaw(yaw+math.pi/2) + obj:setvelocity(vec) + minetest.after(shoot_interval, function() + entity.loaded = true + end) + end +end + +--basic flying, with optional weapons +function object_fly(entity, dtime, speed, accel, decell, shoots, arrow, moving_anim, stand_anim) + local ctrl = entity.driver:get_player_control() + local dir = entity.driver:get_look_dir(); + local velo = entity.object:getvelocity() + local vec_forward = {x=dir.x*speed,y=(dir.y*speed)/4+math.abs(velo.z+velo.x)/10,z=dir.z*speed} + local acc_forward = {x=dir.x*accel/2,y=dir.y*accel/2+3,z=dir.z*accel/2} + local vec_backward = {x=-dir.x*speed,y=dir.y*speed+3,z=-dir.z*speed} + local acc_backward = {x=dir.x*accel/2,y=dir.y*accel/2+3,z=dir.z*accel/2} + local vec_stop = {x=velo.x*decell, y=velo.y, z=velo.z*decell} + local yaw = entity.driver:get_look_yaw(); + --pitch doesn't work + --local pitch = entity.driver:get_look_pitch(); + if ctrl.up then + entity.object:setyaw(yaw+math.pi+math.pi/2) + --entity.object:setpitch(pitch+math.pi+math.pi/2) + entity.object:setvelocity(vec_forward) + entity.object:setacceleration(acc_forward) + elseif ctrl.down then + entity.object:setyaw(yaw+math.pi+math.pi/2) + --entity.object:setpitch(pitch+math.pi+math.pi/2) + entity.object:setvelocity(vec_backward) + entity.object:setacceleration(acc_backward) + elseif not ctrl.down or ctrl.up then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_stop) + entity.object:setacceleration({x=0, y=-4.5, z=0}) + end + if ctrl.jump and ctrl.up then + entity.object:setvelocity({x=dir.x*speed, y=0, z=dir.z*speed}) + elseif ctrl.jump and not ctrl.up then + entity.object:setvelocity({x=velo.x*decell, y=0, z=velo.z*decell}) + end + if ctrl.sneak and shoots and entity.loaded then + entity.loaded = false + local pos = entity.object:getpos() + local obj = minetest.env:add_entity({x=pos.x+0+dir.x*2,y=pos.y+1.5+dir.y,z=pos.z+0+dir.z*2}, arrow) + local vec = {x=dir.x*9,y=dir.y*9,z=dir.z*9} + obj:setyaw(yaw+math.pi/2) + obj:setvelocity(vec) + minetest.after(1, function() + entity.loaded = true + end) + end + --lib_mount animation + if minetest.get_modpath("mobs")then + if velo.x == 0 and velo.y == 0 and velo.z == 0 then + if stand_anim and stand_anim ~= nilthen then + set_animation(entity, stand_anim) + end + return + end + if moving_anim and moving_anim ~= nil then + set_animation(entity, moving_anim) + end + end +end + +--flying with jump to increase height in addition to looking up/down +function object_fly_2(entity, dtime, speed, accel, decell, shoots, arrow, moving_anim, stand_anim) + local ctrl = entity.driver:get_player_control() + local dir = entity.driver:get_look_dir(); + local yvel = entity.object:getvelocity().y + local vec_forward = {x=dir.x*speed,y=yvel,z=dir.z*speed} + local acc_forward = {x=dir.x*accel/2,y=yvel,z=dir.z*accel/2} + local vec_backward = {x=-dir.x*speed,y=yvel,z=-dir.z*speed} + local acc_backward = {x=dir.x*accel/2,y=yvel,z=dir.z*accel/2} + local vec_stop = {x=entity.object:getvelocity().x*decell, y=entity.object:getvelocity().y, z=entity.object:getvelocity().z*decell} + local vec_rise = {x=entity.object:getvelocity().x, y=speed*accel, z=entity.object:getvelocity().z} + local yaw = entity.driver:get_look_yaw(); + if ctrl.up then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_forward) + entity.object:setacceleration(acc_forward) + elseif ctrl.down then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_backward) + entity.object:setacceleration(acc_backward) + elseif ctrl.jump then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_rise) + elseif not ctrl.down or ctrl.up or ctrl.jump then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_stop) + entity.object:setacceleration({x=0, y=-4.5, z=0}) + end + if ctrl.sneak and shoots and entity.loaded then + entity.loaded = false + local pos = entity.object:getpos() + local obj = minetest.env:add_entity({x=pos.x+0+dir.x*2,y=pos.y+1.5+dir.y,z=pos.z+0+dir.z*2}, arrow) + local vec = {x=dir.x*9,y=dir.y*9,z=dir.z*9} + local yaw = entity.driver:get_look_yaw(); + obj:setyaw(yaw+math.pi/2) + obj:setvelocity(vec) + minetest.after(1, function() + entity.loaded = true + end) + end + --lib_mount animation + local velo = entity.object:getvelocity() + if velo.x == 0 and velo.y == 0 and velo.z == 0 then + if stand_anim and stand_anim ~= nilthen then + set_animation(entity, stand_anim) + end + entity.object:setpos(entity.object:getpos()) + return + end + if moving_anim and moving_anim ~= nil then + set_animation(entity, moving_anim) + end +end + +--gliding +function object_glide(entity, dtime, speed, decell, gravity, moving_anim, stand_anim) + local ctrl = entity.driver:get_player_control() + local dir = entity.driver:get_look_dir(); + local velo = entity.object:getvelocity(); + local vec_glide = {x=dir.x*speed*decell, y=velo.y, z=dir.z*speed*decell} + local yaw = entity.driver:get_look_yaw(); + if not ctrl.sneak then + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec_glide) + entity.object:setacceleration({x=0, y=gravity, z=0}) + end + if ctrl.sneak then + local vec = {x=0,y=gravity*15,z=0} + local yaw = entity.driver:get_look_yaw(); + entity.object:setyaw(yaw+math.pi+math.pi/2) + entity.object:setvelocity(vec) + end + if velo.y == 0 then + local pos = entity.object:getpos() + for dx=-1,1 do + for dy=-1,1 do + for dz=-1,1 do + local p = {x=pos.x+dx, y=pos.y-1, z=pos.z+dz} + local t = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} + local n = minetest.env:get_node(p).name + if n ~= "massdestruct:parachute" and n ~= "air" then + local pos = entity.object:getpos() + entity.object:remove() + return + end + end + end + end + end + --lib_mount animation + if velo.x == 0 and velo.y == 0 and velo.z == 0 then + if stand_anim and stand_anim ~= nilthen then + set_animation(entity, stand_anim) + end + return + end + if moving_anim and moving_anim ~= nil then + set_animation(entity, moving_anim) + end +end + +--lib_mount (not required by new functions) + + +-- local function is_group(pos, group) + -- local nn = minetest.get_node(pos).name + -- return minetest.get_item_group(nn, group) ~= 0 +-- end + +-- local function get_sign(i) + -- i = i or 0 + -- if i == 0 then + -- return 0 + -- else + -- return i / math.abs(i) + -- end +-- end + +-- local function get_velocity(v, yaw, y) + -- local x = -math.sin(yaw) * v + -- local z = math.cos(yaw) * v + -- return {x = x, y = y, z = z} +-- end + +-- local function get_v(v) + -- return math.sqrt(v.x ^ 2 + v.z ^ 2) +-- end + +-- lib_mount = {} + +-- function lib_mount.attach(entity, player, attach_at, eye_offset) + -- eye_offset = eye_offset or {x=0, y=0, z=0} + -- force_detach(player) + -- entity.driver = player + -- player:set_attach(entity.object, "", attach_at, {x=0, y=0, z=0}) + + -- player:set_properties({visual_size = {x=1, y=1}}) + + -- player:set_eye_offset(eye_offset, {x=0, y=0, z=0}) + -- default.player_attached[player:get_player_name()] = true + -- minetest.after(0.2, function() + -- default.player_set_animation(player, "sit" , 30) + -- end) + -- entity.object:setyaw(player:get_look_yaw() - math.pi / 2) +-- end + +-- function lib_mount.detach(entity, player, offset) + -- entity.driver = nil + -- player:set_detach() + -- default.player_attached[player:get_player_name()] = false + -- default.player_set_animation(player, "stand" , 30) + -- player:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0}) + -- local pos = player:getpos() + -- pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + -- minetest.after(0.1, function() + -- player:setpos(pos) + -- end) +-- end + +-- function lib_mount.drive(entity, dtime, moving_anim, stand_anim, can_fly) + -- entity.v = get_v(entity.object:getvelocity()) * get_sign(entity.v) + + -- local ctrl = entity.driver:get_player_control() + -- local yaw = entity.object:getyaw() + -- if ctrl.up then + -- entity.v = entity.v + 0.1 + -- elseif ctrl.down then + -- entity.v = entity.v - 0.1 + -- end + -- if ctrl.left then + -- if entity.v < 0 then + -- entity.object:setyaw(yaw - (1 + dtime) * 0.03) + -- else + -- entity.object:setyaw(yaw + (1 + dtime) * 0.03) + -- end + -- elseif ctrl.right then + -- if entity.v < 0 then + -- entity.object:setyaw(yaw + (1 + dtime) * 0.03) + -- else + -- entity.object:setyaw(yaw - (1 + dtime) * 0.03) + -- end + -- end + + -- local velo = entity.object:getvelocity() + -- if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then + -- if stand_anim and stand_anim ~= nil and mobs_redo == true then + -- set_animation(entity, stand_anim) + -- end + -- entity.object:setpos(entity.object:getpos()) + -- return + -- end + -- if moving_anim and moving_anim ~= nil and mobs_redo == true then + -- set_animation(entity, moving_anim) + -- end + -- local s = get_sign(entity.v) + -- entity.v = entity.v - 0.02 * s + -- if s ~= get_sign(entity.v) then + -- entity.object:setvelocity({x = 0, y = 0, z = 0}) + -- entity.v = 0 + -- return + -- end + -- if math.abs(entity.v) > 5 then + -- entity.v = 5 * get_sign(entity.v) + -- end + + -- local p = entity.object:getpos() + -- p.y = p.y - 0.5 + -- local new_velo = {x = 0, y = 0, z = 0} + -- local new_acce = {x = 0, y = 0, z = 0} + -- if not is_group(p, "crumbly") then + -- local nodedef = minetest.registered_nodes[minetest.get_node(p).name] + -- if (not nodedef) or nodedef.walkable then + -- entity.v = 0 + -- new_acce = {x = 0, y = 1, z = 0} + -- else + -- new_acce = {x = 0, y = -9.8, z = 0} + -- end + -- new_velo = get_velocity(entity.v, entity.object:getyaw(), + -- entity.object:getvelocity().y) + -- entity.object:setpos(entity.object:getpos()) + -- else + -- p.y = p.y + 1 + -- if is_group(p, "crumbly") then + -- local y = entity.object:getvelocity().y + -- if y >= 5 then + -- y = 5 + -- elseif y < 0 then + -- new_acce = {x = 0, y = 20, z = 0} + -- else + -- new_acce = {x = 0, y = 5, z = 0} + -- end + -- new_velo = get_velocity(entity.v, entity.object:getyaw(), y) + -- entity.object:setpos(entity.object:getpos()) + -- else + -- new_acce = {x = 0, y = 0, z = 0} + -- if math.abs(entity.object:getvelocity().y) < 1 then + -- local pos = entity.object:getpos() + -- pos.y = math.floor(pos.y) + 0.5 + -- entity.object:setpos(pos) + -- new_velo = get_velocity(entity.v, entity.object:getyaw(), 0) + -- else + -- new_velo = get_velocity(entity.v, entity.object:getyaw(), + -- entity.object:getvelocity().y) + -- entity.object:setpos(entity.object:getpos()) + -- end + -- end + -- end + -- if can_fly and can_fly == true and ctrl.jump then + -- new_velo.y = new_velo.y + 0.75 + -- end + -- entity.object:setvelocity(new_velo) + -- entity.object:setacceleration(new_acce) +-- end + +--other stuff + + + +function register_vehicle_spawner(vehicle, desc, texture, is_boat) +minetest.register_tool(vehicle.."_spawner", { + description = desc, + inventory_image = texture, + liquids_pointable = is_boat, + wield_scale = {x = 1.5, y = 1.5, z = 1}, + tool_capabilities = { + full_punch_interval = 0.7, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.0, [2]=1.00, [3]=0.35}, uses=30, maxlevel=3}, + }, + damage_groups = {fleshy=1}, + }, + on_use = function(item, placer, pointed_thing) + local dir = placer:get_look_dir(); + local playerpos = placer:getpos(); + if pointed_thing.type == "node" and not is_boat then + local obj = minetest.env:add_entity(pointed_thing.above, vehicle) + local object = obj:get_luaentity() + object.owner = placer + item:take_item() + return item + elseif pointed_thing.type == "node" and minetest.get_item_group(pointed_thing.name, "water")then + local obj = minetest.env:add_entity(pointed_thing.under, vehicle) + local object = obj:get_luaentity() + object.owner = placer + item:take_item() + return item + end + end, +}) +end + + +--out of date, left behind in case it is needed again +function vehicle_drop(ent, player, name) + if ent.owner == player then + local pos = ent.object:getpos() + minetest.env:add_item(pos, name.."_spawner") + ent.object:remove() + end +end + +function destroy(ent, player, name) + if ent.object:get_hp() == 0 and ent.owner == player then + local pos = ent.object:getpos() + minetest.env:add_item(pos, "vehicles:tank_spawner") + end +end \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..cbfbcdb --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +mobs \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..eb51a5a --- /dev/null +++ b/init.lua @@ -0,0 +1,388 @@ +--vehicle api +dofile(minetest.get_modpath("orcinvasion").."/api.lua") + +--mapgen +minetest.register_decoration({ + deco_type = "schematic", + place_on = {"default:desert_sand", "default:snowblock", "default:dirt_with_snow", "default:dirt_with_dry_grass"}, + sidelen = 116, + noise_params = { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + y_min = 5, + y_max = 31000, + schematic = minetest.get_modpath("orcinvasion").."/schematics/castle.mts", + flags = "place_center_x", + rotation = "random", + }) + +--siege engines + + +minetest.register_entity("orcinvasion:catapult", { + visual = "mesh", + mesh = "catapult.b3d", + textures = {"catapult2.png"}, + velocity = 15, + acceleration = -5, + stepheight = 1.5, + damage = 2, + physical = true, + collisionbox = {-2, -0.4, -2, 2, 2, 2}, + on_rightclick = function(self, clicker) + if self.driver and clicker == self.driver then + object_detach(self, clicker, {x=1, y=0, z=1}) + elseif not self.driver then + object_attach(self, clicker, {x=0, y=6, z=6}, false, {x=0, y=0, z=5}) + end + end, + on_step = function(self, dtime) + if self.driver then + object_drive(self, dtime, 1, 0.5, true, "orcinvasion:rock", 10, nil, nil, false) + return false + end + return true + end, +}) + +register_vehicle_spawner("orcinvasion:catapult", "catapult", "orcinvasion_ctplt.png", false) + +--nodes and items + +minetest.register_node("orcinvasion:brick", { + description = "Orc Brick", + tiles = { + "orcinvasion_brick.png", + }, + groups = {cracky=3} +}) + +minetest.register_craftitem("orcinvasion:meat", { + description = "orc meat", + wield_image = "orcinvasion_orcflesh.png", + inventory_image = "orcinvasion_orcflesh.png", + on_use = minetest.item_eat(-1) +}) + +minetest.register_craft({ + type = "cooking", + output = "mobs:meat", + recipe = "orcinvasion:meat", + cooktime = 5, +}) + +minetest.register_node("orcinvasion:spawner", { + description = "Orc Spawner", + tiles = { + "orcinvasion_spawner.png", + }, + groups = {cracky=3} +}) + +minetest.register_node("orcinvasion:spawner2", { + description = "Orc(archer) Spawner", + tiles = { + "orcinvasion_spawner2.png", + }, + groups = {cracky=3} +}) + +minetest.register_node("orcinvasion:flag", { + description = "Orc flag", + drawtype = "torchlike", + tiles = {"orcinvasion_flag.png"}, + paramtype = "light", + is_ground_content = false, + buildable_to = true, + sunlight_propagates = true, + inventory_image = "orcinvasion_flag.png", + visual_scale = 5.5, + wield_scale = {x=0.5, y=0.5, z=0.5}, + groups = {oddly_breakable_by_hand=1, flammable=1, attatched_node=1}, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 1, 0.3} + }, + walkable = false, +}) + +minetest.register_node("orcinvasion:spears", { + description = "Orc spears", + drawtype = "plantlike", + tiles = {"orcinvasion_spears.png"}, + paramtype = "light", + is_ground_content = false, + buildable_to = true, + sunlight_propagates = true, + inventory_image = "orcinvasion_spears.png", + visual_scale = 2, + wield_scale = {x=0.5, y=0.5, z=0.5}, + groups = {oddly_breakable_by_hand=1, flammable=1, attatched_node=1}, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 1, 0.3} + }, + walkable = false, +}) + + +minetest.register_node("orcinvasion:torch", { + description = "Orc Torch", + drawtype = "torchlike", + inventory_image = "orcinvasion_torch_inv.png", + wield_image = "orcinvasion_torch_inv.png", + tiles = {{ + name = "orcinvasion_torch.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 1.00}, + }}, + selection_box = { + type = "wallmounted", + }, + light_source = 20, + sunlight_propogates = true, + paramtype = "light", + paramtype2 = "wallmounted", + groups = {cracky=1, oddly_breakeable_by_hand=1} +}) + +--abms + +minetest.register_abm({ + nodenames = {"orcinvasion:spawner"}, + interval = 10, + chance = 10, + action = function(pos) + minetest.env:add_entity({x=pos.x, y=pos.y+2, z=pos.z}, "orcinvasion:orc_soldier") + end +}) + +minetest.register_abm({ + nodenames = {"orcinvasion:spawner2"}, + interval = 10, + chance = 10, + action = function(pos) + minetest.env:add_entity({x=pos.x, y=pos.y+2, z=pos.z}, "orcinvasion:orc_archer") + end +}) + + +--mobs + + + +mobs:register_mob("orcinvasion:orc_soldier", { + type = "monster", + passive = false, + reach = 2, + damage = 2, + attack_type = "dogfight", + hp_min = 72, + hp_max = 82, + armor = 100, + collisionbox = {-0.4, 0, -0.4, 0.4, 2, 0.4}, + visual = "mesh", + mesh = "orc_soldier.b3d", + textures = { + {"orc_soldier.png"}, + {"orc_soldier2.png"}, + {"orc_soldier3.png"}, + }, + drops = {{name = "orcinvasion:meat", chance = 10, min = 1, max = 3},}, + blood_texture = "mobs_blood.png", + visual_size = {x=1, y=1}, + makes_footstep_sound = true, + walk_velocity = 1, + run_velocity = 2, + jump = true, + water_damage = 0, + lava_damage = 2, + light_damage = 0, + view_range = 14, + animation = { + speed_normal = 10, + speed_run = 30, + walk_start = 52, + walk_end = 72, + stand_start = 1, + stand_end = 10, + run_start = 52, + run_end = 71, + punch_start = 20, + punch_end = 50, + + }, +}) + + +mobs:register_spawn("orcinvasion:orc_soldier", {"default:snow","default:snow_block", "default:desert_sand"}, 20, 10, 350, 2, 31000) + +mobs:register_egg("orcinvasion:orc_soldier", "Orc (soldier)", "default_desert_sand.png", 1) + +mobs:register_mob("orcinvasion:orc_archer", { + type = "monster", + passive = false, + reach = 2, + damage = 2, + attack_type = "shoot", + shoot_interval = 2, + shoot_offset = 0.5, + arrow = "orcinvasion:arrow", + hp_min = 42, + hp_max = 52, + armor = 100, + collisionbox = {-0.4, 0, -0.4, 0.4, 2.5, 0.4}, + visual = "mesh", + mesh = "orc_archer.b3d", + textures = { + {"orcinvasion_archer.png"}, + }, + drops = {{name = "orcinvasion:meat", chance = 10, min = 1, max = 3},}, + blood_texture = "mobs_blood.png", + visual_size = {x=1, y=1}, + makes_footstep_sound = true, + walk_velocity = 1, + run_velocity = 2, + jump = true, + water_damage = 0, + lava_damage = 2, + light_damage = 0, + view_range = 14, + animation = { + speed_normal = 10, + speed_run = 30, + walk_start = 55, + walk_end = 75, + stand_start = 1, + stand_end = 10, + run_start = 55, + run_end = 75, + shoot_start = 20, + shoot_end = 35, + + }, +}) + + +mobs:register_spawn("orcinvasion:orc_archer", {"default:wood","default:dirt_with_grass", "default:desert_sand"}, 20, 10, 650, 2, 31000) + +mobs:register_egg("orcinvasion:orc_archer", "Orc (archer)", "default_desert_sand.png", 1) + +mobs:register_mob("orcinvasion:ogre", { + type = "monster", + passive = false, + reach = 2, + damage = 2, + attack_type = "dogfight", + hp_min = 72, + hp_max = 82, + armor = 90, + collisionbox = {-0.6, 0, -0.6, 0.6, 3.2, 0.6}, + visual = "mesh", + mesh = "ogre.b3d", + textures = { + {"orcinvasion_ogre.png"}, + }, + blood_texture = "mobs_blood.png", + visual_size = {x=1, y=1}, + makes_footstep_sound = true, + walk_velocity = 1, + run_velocity = 2, + jump = true, + water_damage = 0, + lava_damage = 2, + light_damage = 0, + view_range = 14, + animation = { + speed_normal = 10, + speed_run = 30, + walk_start = 40, + walk_end = 60, + stand_start = 1, + stand_end = 20, + run_start = 40, + run_end = 60, + punch_start = 20, + punch_end = 35, + + }, +}) + + +mobs:register_spawn("orcinvasion:ogre", {"default:dirt_with_dry_grass","default:dirt_with_grass", "default:desert_sand"}, 20, 10, 1050, 2, 31000) + +mobs:register_egg("orcinvasion:ogre", "Ogre", "default_dry_grass.png", 1) + +--arrows +mobs:register_arrow("orcinvasion:arrow", { + visual = "sprite", + visual_size = {x=0.3, y=0.3}, + textures = {"orcinvasion_arrow.png"}, + velocity = 12, + hit_player = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 2}, + }, nil) + end, + hit_mob = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 2}, + }, nil) + end, + hit_node = function(self, pos, node) + self.object:remove() + end, +}) + +minetest.register_entity("orcinvasion:rock", { + visual = "mesh", + mesh = "rock.b3d", + textures = {"orcinvasion_rock.png"}, + velocity = 15, + acceleration = -5, + damage = 2, + collisionbox = {0, 0, 0, 0, 0, 0}, + on_step = function(self, obj, pos) + minetest.after(30, function() + self.object:remove() + end) + local pos = self.object:getpos() + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name ~= "orcinvasion:rock" and n ~= "orcinvasion:catapult" and obj:get_luaentity().name ~= "__builtin:item" then + obj:punch(self.launcher, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=15}, + }, nil) + self.object:remove() + end + end + end + + for dx=-1,1 do + for dy=-1,1 do + for dz=-1,1 do + local p = {x=pos.x+dx, y=pos.y, z=pos.z+dz} + local t = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} + local n = minetest.env:get_node(p).name + if n ~= "orcinvasion:rock" and n ~= "orcinvasion:catapult" and n ~= "air" then + local pos = self.object:getpos() + tnt.boom(pos, {damage_radius=5,radius=2,ignore_protection=false}) + self.object:remove() + return + end + end + end + end + end, +}) + + + diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..b6dddaa --- /dev/null +++ b/license.txt @@ -0,0 +1,24 @@ + +License for Code +---------------- + +Copyright (C) 2016 DOOmed + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +License for Textures, Models and Sounds +--------------------------------------- + +CC-BY-SA 3.0 UNPORTED. Created by DOOmed diff --git a/models/arrow.b3d b/models/arrow.b3d new file mode 100644 index 0000000..3155fd1 Binary files /dev/null and b/models/arrow.b3d differ diff --git a/models/catapult.b3d b/models/catapult.b3d new file mode 100644 index 0000000..30ddb31 Binary files /dev/null and b/models/catapult.b3d differ diff --git a/models/ogre.b3d b/models/ogre.b3d new file mode 100644 index 0000000..a7576a2 Binary files /dev/null and b/models/ogre.b3d differ diff --git a/models/orc_archer.b3d b/models/orc_archer.b3d new file mode 100644 index 0000000..e197e17 Binary files /dev/null and b/models/orc_archer.b3d differ diff --git a/models/orc_soldier.b3d b/models/orc_soldier.b3d new file mode 100644 index 0000000..a299afc Binary files /dev/null and b/models/orc_soldier.b3d differ diff --git a/models/rock.b3d b/models/rock.b3d new file mode 100644 index 0000000..7b22b26 Binary files /dev/null and b/models/rock.b3d differ diff --git a/models/wyvern.b3d b/models/wyvern.b3d new file mode 100644 index 0000000..85fcefe Binary files /dev/null and b/models/wyvern.b3d differ diff --git a/schematics/castle.mts b/schematics/castle.mts new file mode 100644 index 0000000..2b5114d Binary files /dev/null and b/schematics/castle.mts differ diff --git a/textures/catapult2.png b/textures/catapult2.png new file mode 100644 index 0000000..91ebf24 Binary files /dev/null and b/textures/catapult2.png differ diff --git a/textures/orc_soldier.png b/textures/orc_soldier.png new file mode 100644 index 0000000..ec665c8 Binary files /dev/null and b/textures/orc_soldier.png differ diff --git a/textures/orc_soldier2.png b/textures/orc_soldier2.png new file mode 100644 index 0000000..cea415e Binary files /dev/null and b/textures/orc_soldier2.png differ diff --git a/textures/orc_soldier3.png b/textures/orc_soldier3.png new file mode 100644 index 0000000..6535c4a Binary files /dev/null and b/textures/orc_soldier3.png differ diff --git a/textures/orcinvasion_archer.png b/textures/orcinvasion_archer.png new file mode 100644 index 0000000..d9d2152 Binary files /dev/null and b/textures/orcinvasion_archer.png differ diff --git a/textures/orcinvasion_arrow.png b/textures/orcinvasion_arrow.png new file mode 100644 index 0000000..c9e9314 Binary files /dev/null and b/textures/orcinvasion_arrow.png differ diff --git a/textures/orcinvasion_brick.png b/textures/orcinvasion_brick.png new file mode 100644 index 0000000..61a755e Binary files /dev/null and b/textures/orcinvasion_brick.png differ diff --git a/textures/orcinvasion_ctplt.png b/textures/orcinvasion_ctplt.png new file mode 100644 index 0000000..680f570 Binary files /dev/null and b/textures/orcinvasion_ctplt.png differ diff --git a/textures/orcinvasion_flag.png b/textures/orcinvasion_flag.png new file mode 100644 index 0000000..35ea156 Binary files /dev/null and b/textures/orcinvasion_flag.png differ diff --git a/textures/orcinvasion_ogre.png b/textures/orcinvasion_ogre.png new file mode 100644 index 0000000..e4eac6f Binary files /dev/null and b/textures/orcinvasion_ogre.png differ diff --git a/textures/orcinvasion_orcflesh.png b/textures/orcinvasion_orcflesh.png new file mode 100644 index 0000000..bd018d9 Binary files /dev/null and b/textures/orcinvasion_orcflesh.png differ diff --git a/textures/orcinvasion_rock.png b/textures/orcinvasion_rock.png new file mode 100644 index 0000000..1c9cb92 Binary files /dev/null and b/textures/orcinvasion_rock.png differ diff --git a/textures/orcinvasion_spawner.png b/textures/orcinvasion_spawner.png new file mode 100644 index 0000000..e81c268 Binary files /dev/null and b/textures/orcinvasion_spawner.png differ diff --git a/textures/orcinvasion_spawner2.png b/textures/orcinvasion_spawner2.png new file mode 100644 index 0000000..553cc5d Binary files /dev/null and b/textures/orcinvasion_spawner2.png differ diff --git a/textures/orcinvasion_spear.png b/textures/orcinvasion_spear.png new file mode 100644 index 0000000..4439dac Binary files /dev/null and b/textures/orcinvasion_spear.png differ diff --git a/textures/orcinvasion_spears.png b/textures/orcinvasion_spears.png new file mode 100644 index 0000000..d6a6a1b Binary files /dev/null and b/textures/orcinvasion_spears.png differ diff --git a/textures/orcinvasion_sword.png b/textures/orcinvasion_sword.png new file mode 100644 index 0000000..f4600b0 Binary files /dev/null and b/textures/orcinvasion_sword.png differ diff --git a/textures/orcinvasion_torch.png b/textures/orcinvasion_torch.png new file mode 100644 index 0000000..f73836a Binary files /dev/null and b/textures/orcinvasion_torch.png differ diff --git a/textures/orcinvasion_torch_inv.png b/textures/orcinvasion_torch_inv.png new file mode 100644 index 0000000..2eab2d1 Binary files /dev/null and b/textures/orcinvasion_torch_inv.png differ diff --git a/textures/orcinvasion_wyvern.png b/textures/orcinvasion_wyvern.png new file mode 100644 index 0000000..2e9b521 Binary files /dev/null and b/textures/orcinvasion_wyvern.png differ