diff --git a/README.md b/README.md new file mode 100644 index 0000000..8585eac --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# Vehicles +Adds various vehicles to Minetest. + +## How to drive/pilot/etc. + +### Basic controls +All vehicles are steered by looking around. You can use the forward button(same as you would use for walking), to move the vehicles, but only some will be able to reverse. For example, cars can reverse but planes cannot. + +### Boosts +Some vehicles can have a small boost when the 'use/aux1' key is held. It will only last for a limited time and it will not recharge whilst the key is still held down. + +### Weapons +Vehicles can also use weapons, for example the jet and tank, which will fire a missile when 'sneak' is pressed. They require a missile to be in the drivers inventory to do this. It is possible to have a second weapon, fired with 'use/aux1', but currently only the assault suit does this. It can use both bullets and missiles. The gun turret uses bullets. + +### Flight/Jumping/Hovering +Some vehicles can fly, for example the jet. The jet will move upward when the driver looks up, or when the driver presses 'jump'. Using the jump key does not work very well at the moment. The plane is a bit differrent; It will hold it's height when 'jump' is pressed. + +It is also possible for vehicles to jump or hover for a small amount of time. Currently only the Assault suit does this. + +### Boats and Watercrafts +The speed boat can be used on water, but if it is driven onto land it will stop completely. If you are lucky you can move back into water, but be careful because this does not always work. + +### The Lightcycles +The Lightcycles can place light barriers when 'sneak' is pressed. If the barrier from one type hits the other type, the vehicle will explode + +### Other +Vehicles will explode if they touch lava, so be careful. +Don't drive cars or planes etc. into water! they will sink. + +If you do get a vehicle in a tricky spot, you can punch it whilst driving and it will be dropped. + +## The API +vehicles.object_drive is the function used for the movement of vehicles. +It should be used in this format: + +```lua +vehicles.object_drive(entity, dtime, { + -- table keys here +}) +``` + +In the above case, entity is used in place of an entity or object. If the function was to be used inside on_step for an entity, 'entity' would be replaced with 'self.object' + +The table should contain the relevant variables listed below. The function is written so that these are all somewhat optional. + +* `speed`: This defines the speed of the vehicle, if unset it will be '10' +* `fixed`: Setting this to 'true' will disable movement from the vehicle +* `decell`: This defines the decelleration of the vehicle. The default is 0 +* `shoots`: If true then the vehicle can shoot with 'sneak'(arrow must be defined, default is false) +* `arrow`: This should be the entity name for the weapon fired (default is nil) (requires an item with the name arrow_name.."_item" to be in the drivers inventory) +* `reload_time`: how long it takes before the weapon can be fired again (default is 1) +* `shoot_y`: y offset of the weapon, default is 1.5 +* `shoot_angle`: This will make the weapon shoot at a differrent vertical angle (default is 0) +* `infinite_arrow`: if this is set then the vehicle won't need an arrow item to be in the inventory +* `arrow2/reload_time2/shoots2/shoot_y2/infinite_arrow2`: same as above but fired with 'use/aux1' +* `jump`: can be either 'hover' or 'jump' (default is nil). Hover lasts longer than jump. +* `fly`: if true then the vehicle will fly (default is false) +* `fly_mode`: can be either 'hold' or 'rise' (default is 'hold'). hold will keep the vehicle in place when 'jump' is pressed, and 'rise' will cause the vehicle to rise when the same key is pressed. +* `rise_speed`: dependant on fly_mode being set to 'rise'. Defines the speed at which the vehicle will rise. (default is 0.1) +* `gravity`: the gravity acting on the vehicle. This should be positive. (default is 1) +* `boost`: if set to 'true' then the vehicle can boost with 'use/aux1' (default is false) +* `boost_duration`: dependant on 'boost'. Determines how long a boost will last (default is 5). +* `boost_charge`: dependant on 'boost'. Determines how long it takes before boost can be used again (default is 4) +* `boost_effect`: particle texture that will fly out from behind the vehicle whilst boosting (default is nil) +* `hover_speed`: the speed at which the vehicle will hover if 'jump' is set to 'hover' (default is 1.5) +* `jump_speed`: the speed at which the vehicle will jump if 'jump' is set to 'jump' (default is 5) +* `simple_vehicle`: removes all functionality except basic movement, use to reduce lag. (not implemented yet), default is false +* `is_watercraft`: if set to true then the vehicle won't be stopped by water. it will act like a boat unless swims is true. (default is false) +* `swims`: will allow the vehicle to move underwater (not yet implemented) (default is false) +* `driving_sound`: name of the sound file that will play when the vehicle is driving (default is nil) +* `sound_duration`: !VERY IMPORTANT! if there is a driving sound then this should match it's duration. If this is not set then the sound could overlap and increase in volume (default is 5) +* `extra_yaw`: use this if the model has incorrect rotation. It will rotate the model so it faces the right way whilst being driven (default is 0) +* `moving_anim/stand_anim/jump_anim/shoot_anim/shoot_anim2`: animations for actions. Can be set individually. (default is nil) +* `place_node`: name of the node that is placed by the vehicle (default is nil) +* `place_chance`: nodes are placed when a random number between place_chance and 1 is equal to 1 (default is 1) +* `place_trigger`: if true the vehicle will place the node defined by place_node when 'sneak' is pressed. (default is false) +* `death_node`: name of the node that will make the vehicle explode, default is nil +* `destroy_node`: name of the node that is destroyed if it toughes the vehicle, default is nil diff --git a/api_old.lua b/api_old.lua deleted file mode 100644 index 4850ee9..0000000 --- a/api_old.lua +++ /dev/null @@ -1,792 +0,0 @@ ---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}) - player:set_properties({visual_size = {x=1, y=1}}) -end - -function object_attach(entity, player, attach_at, visible, eye_offset) - 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=eye_offset.x, y=eye_offset.y+1, 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) - - -timer = 0 - - ---basic driving, use for basic vehicles/mounts, with optional weapons -function object_drive(entity, dtime, speed, decell, shoots, arrow, reload, moving_anim, stand_anim, jump, jump_anim, shoot_anim, shoot_y) - --variables - local shoot_y = shoot_y or 1.5 - 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/4,y=velo.y+1*-2,z=-dir.z*speed/4} - local vec_stop = {x=velo.x*decell,y=velo.y+1*-2,z=velo.z*decell} - local yaw = entity.driver:get_look_yaw(); - --timer - local absolute_speed = math.sqrt(math.pow(velo.x, 2)+math.pow(velo.z, 2)) - if absolute_speed <= speed and ctrl.up then - timer = timer + 1*dtime - end - if not ctrl.up then - timer = 0 - end - --timer dependant variables - local vec_forward = {x=dir.x*speed/4*math.atan(0.5*timer-2)+8*dir.x,y=velo.y+1*-2,z=dir.z*speed/4*math.atan(0.5*timer-2)+8*dir.z} - local vec_forward_hover = {x=dir.x*speed/4*math.atan(0.5*timer-2)+8*dir.x,y=1.5,z=dir.z*speed/4*math.atan(0.5*timer-2)+8*dir.z} - local vec_forward_jump = {x=dir.x*speed/4*math.atan(0.5*timer-2)+8*dir.x,y=4,z=dir.z*speed/4*math.atan(0.5*timer-2)+8*dir.z} - - --respond to controls - --water effects - local pos = entity.object:getpos() - local node = minetest.get_node(pos).name - if node == "default:water_source" or node == "default:river_water_source" or node == "default:river_water_flowing" or node == "default:water_flowing" then - entity.object:setvelocity({x=velo.x*0.9, y=-1, z=velo.z*0.9}) - elseif ctrl.up then - entity.object:setyaw(yaw+math.pi+math.pi/2) - entity.object:setvelocity(vec_forward) - --lib_mount animation - if moving_anim ~= nil and not entity.moving and not hovering then - entity.object:set_animation(moving_anim, 20, 0) - entity.moving = true - end - elseif ctrl.down then - entity.object:setyaw(yaw+math.pi+math.pi/2) - entity.object:setvelocity(vec_backward) - --lib_mount animation - if moving_anim ~= nil and not entity.moving and not hovering then - entity.object:set_animation(moving_anim, 20, 0) - entity.moving = true - end - elseif not ctrl.down or ctrl.up then - entity.object:setyaw(yaw+math.pi+math.pi/2) - entity.object:setvelocity(vec_stop) - --lib_mount animation - if moving_anim ~= nil and entity.moving and not hovering then - entity.object:set_animation(stand_anim, 20, 0) - entity.moving = false - end - end - if ctrl.sneak and shoots and entity.loaded then - local pname = entity.driver:get_player_name(); - local inv = minetest.get_inventory({type="player", name=pname}); - if inv:contains_item("main", arrow.."_item") or arrow == "vehicles:water" then - local remov = inv:remove_item("main", arrow.."_item") - entity.loaded = false - local pos = entity.object:getpos() - local obj = minetest.env:add_entity({x=pos.x+0+dir.x*2,y=pos.y+shoot_y+dir.y,z=pos.z+0+dir.z*2}, arrow) - local vec = {x=dir.x*14,y=dir.y*14,z=dir.z*14} - local yaw = entity.driver:get_look_yaw(); - obj:setyaw(yaw+math.pi/2) - obj:setvelocity(vec) - local object = obj:get_luaentity() - object.launcher = entity.driver - if shoot_anim ~= nil and entity.object:get_animation().range ~= shoot_anim then - entity.object:set_animation(shoot_anim, 20, 0) - end - minetest.after(reload, function() - entity.loaded = true - if stand_anim ~= nil and shoot_anim ~= nil then - entity.object:set_animation(stand_anim, 20, 0) - end - end) - end - end - - if jump == "hover" and ctrl.jump and not entity.jumpcharge then - if not ctrl.up then - local vec_hover = {x=velo.x+0,y=1,z=velo.z+0} - entity.object:setvelocity(vec_hover) - else - entity.object:setvelocity(vec_forward_hover) - end - hovering = true - if jump_anim ~= nil and entity.object:get_animation().range ~= jump_anim and hovering then - entity.object:set_animation(jump_anim, 20, 0) - end - minetest.after(5, function() - entity.jumpcharge = true - end) - minetest.after(10, function() - entity.jumpcharge = false - hovering = false - end) - end - - if jump == "jump" and ctrl.jump and not entity.jumpcharge then - if not ctrl.up then - local vec_jump = {x=velo.x+0,y=4,z=velo.z+0} - entity.object:setvelocity(vec_jump) - else - entity.object:setvelocity(vec_forward_hover) - end - hovering = true - if jump_anim ~= nil and entity.object:get_animation().range ~= jump_anim and hovering then - entity.object:set_animation(jump_anim, 20, 0) - end - minetest.after(0.5, function() - entity.jumpcharge = true - end) - minetest.after(1, function() - entity.jumpcharge = false - hovering = false - 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, move_anim, stand_anim) - local ctrl = entity.driver:get_player_control() - local velo = entity.object:getvelocity() - local dir = entity.driver:get_look_dir() - --speed indicator - --minetest.chat_send_player(entity.driver:get_player_name(), ""..velocity.."") - - --timer - local absolute_speed = math.sqrt(math.pow(velo.x, 2)+math.pow(velo.z, 2)) - if absolute_speed <= speed and ctrl.up then - timer = timer + 1*dtime - end - if not ctrl.up then - timer = 0 - end - - --stuff left behind for future - --local xaccell = math.abs(math.atan(velo.x)) - --local zaccell = math.abs(math.atan(velo.z)) - local accell = 1 - - --vectors - local vec_forward = {x=dir.x*(speed*0.2)*math.log(timer+0.5)+4*dir.x,y=velo.y-0.5,z=dir.z*(speed*0.2)*math.log(timer+0.5)+4*dir.z} - --local vec_forward = {x=dir.x*speed/4*math.atan(0.5*timer-2)+8*dir.x,y=velo.y-0.5,z=dir.z*speed/4*math.atan(0.5*timer-2)+8*dir.z} - --local vec_forward = {x=dir.x*speed*accell,y=velo.y-0.5,z=dir.z*speed*accell} - --local vec_nitro = {x=dir.x*(speed*1.5)*accell,y=velo.y-0.5,z=dir.z*(speed*1.5)*accell} - local vec_nitro = {x=dir.x*(speed*0.2)*math.log(timer+0.5)+8*dir.x,y=velo.y-0.5,z=dir.z*(speed*0.2)*math.log(timer+0.5)+8*dir.z} - local vec_backward = {x=-dir.x*(speed/4)*accell,y=velo.y-0.5,z=-dir.z*(speed/4)*accell} - local vec_stop = {x=velo.x*decell,y=velo.y-1,z=velo.z*decell} - - --face the right way - local yaw = entity.driver:get_look_yaw(); - --if ctrl.up or ctrl.down then - entity.object:setyaw(yaw+math.pi+math.pi/2) - --end - if not entity.nitro then - minetest.after(4, function() - entity.nitro = true - end) - end - --respond to controls - --water effects - local pos = entity.object:getpos() - local node = minetest.get_node(pos).name - if node == "default:water_source" or node == "default:river_water_source" or node == "default:river_water_flowing" or node == "default:water_flowing" then - entity.object:setvelocity({x=velo.x*0.9, y=-1, z=velo.z*0.9}) - elseif ctrl.up and ctrl.sneak and entity.nitro then - entity.object:setvelocity(vec_nitro) - local pos = entity.object:getpos() - minetest.add_particlespawner( - 5, --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=-velo.x, y=-velo.y, z=-velo.z}, --minvel - {x=-velo.x, y=-velo.y, z=-velo.z}, --maxvel - {x=-0,y=-0,z=-0}, --minacc - {x=0,y=1,z=0}, --maxacc - 0.1, --minexptime - 0.2, --maxexptime - 5, --minsize - 10, --maxsize - false, --collisiondetection - "vehicles_nitro.png" --texture - ) - minetest.after(nitro_duration, function() - entity.nitro = false - end) - --lib_mount animation - if moving_anim ~= nil and not entity.moving then - entity.object:set_animation(move_anim, 20, 0) - entity.moving = true - end - elseif ctrl.up then - entity.object:setvelocity(vec_forward) - --lib_mount animation - if moving_anim ~= nil and not entity.moving then - entity.object:set_animation(move_anim, 20, 0) - entity.moving = true - end - elseif ctrl.down then - entity.object:setvelocity(vec_backward) - --lib_mount animation - if moving_anim ~= nil and not entity.moving then - entity.object:set_animation(move_anim, 20, 0) - entity.moving = true - end - elseif not ctrl.down or ctrl.up then - entity.object:setvelocity(vec_stop) - --lib_mount animation - if stand_anim ~= nil and entity.moving then - entity.object:set_animation(stand_anim, 20, 0) - entity.moving = false - end - end - --play engine sound - if entity.sound_ready then - minetest.sound_play("engine", - {gain = 4, max_hear_distance = 3, loop = false}) - entity.sound_ready = false - minetest.after(11, function() - entity.sound_ready = true - end) - 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 - - ---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 - local pname = entity.driver:get_player_name(); - local inv = minetest.get_inventory({type="player", name=pname}); - if inv:contains_item("main", arrow.."_item") then - local remov = inv:remove_item("main", arrow.."_item") - 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*12, y=dir.y*12, z=dir.z*12} - obj:setyaw(yaw+math.pi/2) - obj:setvelocity(vec) - local object = obj:get_luaentity() - object.launcher = entity.driver - minetest.after(shoot_interval, function() - entity.loaded = true - end) - end - end -end - ---basic flying, with optional weapons -function object_fly(entity, dtime, speed, accel, decell, shoots, arrow, reload, moving_anim, stand_anim, mode2) - local mode2 = mode2 or "hold" - 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 vec_rise = {x=entity.object:getvelocity().x, y=speed*accel, z=entity.object:getvelocity().z} - 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/exist - --local pitch = entity.driver:get_look_pitch(); - - -- --timer - -- local absolute_speed = math.sqrt(math.pow(velo.x, 2)+math.pow(velo.z, 2)) - -- if absolute_speed <= speed and ctrl.up then - -- timer = timer + 1*dtime - -- end - -- if not ctrl.up then - -- timer = 0 - -- end - -- --timer dependant variables - -- local vec_forward = {x=dir.x*speed/4*math.atan(0.5*timer-2)+8*dir.x,y=dir.y*speed/4*math.atan(0.5*timer-2)+8*dir.y,z=dir.z*speed/4*math.atan(0.5*timer-2)+8*dir.z} - - --water effects - local pos = entity.object:getpos() - local node = minetest.get_node(pos).name - if node == "default:water_source" or node == "default:river_water_source" or node == "default:river_water_flowing" or node == "default:water_flowing" then - entity.object:setvelocity({x=velo.x*0.9, y=-1, z=velo.z*0.9}) - elseif 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) - - --lib_mount animation - if moving_anim ~= nil and not entity.moving then - entity.object:set_animation(moving_anim, 20, 0) - entity.moving = true - end - elseif ctrl.jump and mode2 == "rise" then - entity.object:setyaw(yaw+math.pi+math.pi/2) - entity.object:setvelocity(vec_rise) - --lib_mount animation - if moving_anim ~= nil and not entity.moving then - entity.object:set_animation(moving_anim, 20, 0) - entity.moving = true - end - elseif not ctrl.up and not 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}) - --lib_mount animation - if stand_anim ~= nil and entity.moving then - entity.object:set_animation(stand_anim, 20, 0) - entity.moving = false - end - end - if ctrl.jump and ctrl.up and mode2 == "hold" then - entity.object:setvelocity({x=dir.x*speed, y=0, z=dir.z*speed}) - elseif not ctrl.jump and not ctrl.up then - entity.object:setvelocity({x=velo.x*decell, y=-1, z=velo.z*decell}) - end - if ctrl.sneak and shoots and entity.loaded then - local pname = entity.driver:get_player_name(); - local inv = minetest.get_inventory({type="player", name=pname}); - if inv:contains_item("main", arrow.."_item") then - local remov = inv:remove_item("main", arrow.."_item") - 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) - local object = obj:get_luaentity() - object.launcher = entity.driver - minetest.after(reload, function() - entity.loaded = true - end) - end - 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_craftitem(vehicle.."_spawner", { - description = desc, - inventory_image = texture, - liquids_pointable = is_boat, - wield_scale = {x = 1.5, y = 1.5, z = 1}, - on_place = 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) - obj:setvelocity({x=0, y=-1, z=0}) - local object = obj:get_luaentity() - object.owner = placer - item:take_item() - return item - end - end, -}) -end - ---explodinate - -function explode(ent, radius) - local pos = ent.object:getpos() - minetest.add_particlespawner({ - amount = 90, - time = 4, - minpos = {x=pos.x-0.6, y=pos.y, z=pos.z-0.6}, - maxpos = {x=pos.x+0.6, y=pos.y+1, z=pos.z+0.6}, - minvel = {x=-0.1, y=3.5, z=-0.1}, - maxvel = {x=0.1, y=4.5, z=0.1}, - minacc = {x=-1.3, y=-0.7, z=-1.3}, - maxacc = {x=1.3, y=-0.7, z=1.3}, - minexptime = 2, - maxexptime = 3, - minsize = 15, - maxsize = 25, - collisiondetection = false, - texture = "vehicles_explosion.png" - }) - minetest.after(1, function() - minetest.add_particlespawner({ - amount = 30, - time = 4, - minpos = {x=pos.x-1, y=pos.y+2, z=pos.z-1}, - maxpos = {x=pos.x+1, y=pos.y+3, z=pos.z+1}, - minvel = {x=0, y=-1, z=0}, - maxvel = {x=0, y=-2, z=0}, - minacc = {x=0, y=-0.6, z=0}, - maxacc = {x=0, y=-0.6, z=0}, - minexptime = 1, - maxexptime = 3, - minsize = 1, - maxsize = 2, - collisiondetection = false, - texture = "vehicles_explosion.png" - }) - 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/locale/template.txt b/locale/template.txt index 8688fbb..a8b7e79 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -22,7 +22,7 @@ Jet Engine = Lambogoni (grey) = Lambogoni (yellow) = Masda (orange) = -Masda (pink) = +Masda (pink) = Missile = Musting (purple) = Musting (white) = @@ -56,9 +56,9 @@ Wings = arrows(left) = arrows(right) = mt sign = -neon arrows (left) = -neon arrows (right) = -pacman sign = -scifi_nodes sign = +neon arrows (left) = +neon arrows (right) = +pacman sign = +scifi_nodes sign = tyre stack = whee sign = diff --git a/locale/vehicles.fr.tr b/locale/vehicles.fr.tr index ee2d114..a521b04 100644 --- a/locale/vehicles.fr.tr +++ b/locale/vehicles.fr.tr @@ -17,7 +17,7 @@ Fire truck = Camion de pompiers Flag = Drapeau Geep = Geep Gun turret = Tourelle d'arme à feu -Hazard stipes = Stipes de danger +Hazard stipes = Stipes de danger Jet = Jet Jet Engine = Moteur à réaction Lambogoni (grey) = Lambogoni (gris) diff --git a/readme.txt b/readme.txt deleted file mode 100644 index cd3f935..0000000 --- a/readme.txt +++ /dev/null @@ -1,104 +0,0 @@ -How to drive/pilot/etc.: - -Basic controls: -All vehicles are steered by looking around. -You can use the forward button(same as you would use for walking), to move the vehicles, but only some will be able to reverse. For example, cars can reverse but planes cannot. - -Boosts: -Some vehicles can have a small boost when the 'use/aux1' key is held. It will only last for a limited time and it will not recharge whilst the key is still held down. - -Weapons: -Vehicles can also use weapons, for example the jet and tank, which will fire a missile when 'sneak' is pressed. They require a missile to be in the drivers inventory to do this. It is possible to have a second weapon, fired with 'use/aux1', but currently only the assault suit does this. It can use both bullets and missiles. The gun turret uses bullets. - -Flight/Jumping/Hovering: -Some vehicles can fly, for example the jet. The jet will move upward when the driver looks up, or when the driver presses 'jump'. Using the jump key does not work very well at the moment. The plane is a bit differrent; It will hold it's height when 'jump' is pressed. -It is also possible for vehicles to jump or hover for a small amount of time. Currently only the Assault suit does this. - -Boats and watercraft: -The speed boat can be used on water, but if it is driven onto land it will stop completely. If you are lucky you can move back into water, but be careful because this does not always work. - -The Lightcycles: -The Lightcycles can place light barriers when 'sneak' is pressed. If the barrier from one type hits the other type, the vehicle will explode - -Other things: -Vehicles will explode if they touch lava, so be careful. -Don't drive cars or planes etc. into water! they will sink. -If you do get a vehicle in a tricky spot, you can punch it whilst driving and it will be dropped. - -The API: -vehicles.object_drive is the function used for the movement of vehicles. -It should be used in this format: -vehicles.object_drive(entity, dtime, { -}) - -In the above case, entity is used in place of an entity or object. If the function was to be used inside on_step for an entity, 'entity' would be replaced with 'self.object' -The table should contain the relevant variables listed below. The function is written so that these are all somewhat optional. - -speed: This defines the speed of the vehicle, if unset it will be '10' - -fixed: Setting this to 'true' will disable movement from the vehicle - -decell: This defines the decelleration of the vehicle. The default is 0 - -shoots: If true then the vehicle can shoot with 'sneak'(arrow must be defined, default is false) - -arrow: This should be the entity name for the weapon fired (default is nil) (requires an item with the name arrow_name.."_item" to be in the drivers inventory) - -reload_time: how long it takes before the weapon can be fired again (default is 1) - -shoot_y: y offset of the weapon, default is 1.5 - -shoot_angle: This will make the weapon shoot at a differrent vertical angle (default is 0) - -infinite_arrow: if this is set then the vehicle won't need an arrow item to be in the inventory - -arrow2/reload_time2/shoots2/shoot_y2/infinite_arrow2: same as above but fired with 'use/aux1' - -jump: can be either 'hover' or 'jump' (default is nil). Hover lasts longer than jump. - -fly: if true then the vehicle will fly (default is false) - -fly_mode: can be either 'hold' or 'rise' (default is 'hold'). hold will keep the vehicle in place when 'jump' is pressed, and 'rise' will cause the vehicle to rise when the same key is pressed. - -rise_speed: dependant on fly_mode being set to 'rise'. Defines the speed at which the vehicle will rise. (default is 0.1) - -gravity: the gravity acting on the vehicle. This should be positive. (default is 1) - -boost: if set to 'true' then the vehicle can boost with 'use/aux1' (default is false) - -boost_duration: dependant on 'boost'. Determines how long a boost will last (default is 5). - -boost_charge: dependant on 'boost'. Determines how long it takes before boost can be used again (default is 4) - -boost_effect: particle texture that will fly out from behind the vehicle whilst boosting (default is nil) - -hover_speed: the speed at which the vehicle will hover if 'jump' is set to 'hover' (default is 1.5) - -jump_speed: the speed at which the vehicle will jump if 'jump' is set to 'jump' (default is 5) - -simple_vehicle: removes all functionality except basic movement, use to reduce lag. (not implemented yet), default is false - -is_watercraft: if set to true then the vehicle won't be stopped by water. -it will act like a boat unless swims is true. (default is false) - -swims: will allow the vehicle to move underwater (not yet implemented) (default is false) - -driving_sound: name of the sound file that will play when the vehicle is driving (default is nil) - -sound_duration: !VERY IMPORTANT! if there is a driving sound then this should match it's duration. If this is not set then the sound could overlap and increase in volume (default is 5) - -extra_yaw: use this if the model has incorrect rotation. It will rotate the model so it faces the right way whilst being driven (default is 0) - -moving_anim/stand_anim/jump_anim/shoot_anim/shoot_anim2: animations for actions. Can be set individually. (default is nil) - -place_node: name of the node that is placed by the vehicle (default is nil) - -place_chance: nodes are placed when a random number between place_chance and 1 is equal to 1 (default is 1) - -place_trigger: if true the vehicle will place the node defined by place_node when 'sneak' is pressed. (default is false) - -death_node: name of the node that will make the vehicle explode, default is nil - -destroy_node: name of the node that is destroyed if it toughes the vehicle, default is nil - -