1
0
mirror of https://github.com/SmallJoker/boost_cart.git synced 2025-07-15 23:00:24 +02:00

Compare commits

...

10 Commits

Author SHA1 Message Date
ae33bd7a68 Bump to 5.0.0 and fix the copper rail
moreores only adds the copper rail when the 'carts' mod was found
2019-10-18 10:09:29 +02:00
e4edb96d30 Use initial_properties, backup old_pos for loading 2018-09-01 14:49:16 +02:00
3386942d71 Add basic documentation 2018-07-30 17:16:14 +02:00
d486143f42 Reset acceleration at speed limit 2018-07-07 15:23:30 +02:00
34155473a9 Fix controls not working when going uphill 2018-07-04 22:04:55 +02:00
7e275e1985 Disallow rail switching up/downhill 2018-07-04 21:23:06 +02:00
c6b9e4b672 Various improvements and bugfixes
Clear driver on leave using the detach callback (0.5.x and later)
Fix upright_sprite attachment position
Fallback to the regular node sound when metal does not exist
Set animation to "stand" on attach
2018-05-12 11:36:00 +02:00
3781f6d4c0 Make moreores' copper rail connect again, add metal sounds 2018-05-04 14:38:52 +02:00
f4c1a2ec3b Fix edge case crash due nil old_pos, remove player_api warning 2018-01-15 18:41:40 +01:00
57d09fac79 Revert velocity calculation change from e3688b5
Accelerates carts too much when going up/downhill
Caused by wrong vector length calculation. This will need to be altered again if there will be 45° rails
2017-11-28 18:33:37 +01:00
8 changed files with 186 additions and 74 deletions

View File

@ -1,6 +1,4 @@
local HAVE_MESECONS_ENABLED = minetest.global_exists("mesecon")
function boost_cart:on_rail_step(entity, pos, distance)
-- Play rail sound
if entity.sound_counter <= 0 then
@ -13,18 +11,20 @@ function boost_cart:on_rail_step(entity, pos, distance)
end
entity.sound_counter = entity.sound_counter - distance
if HAVE_MESECONS_ENABLED then
if boost_cart.MESECONS then
boost_cart:signal_detector_rail(pos)
end
end
local cart_entity = {
physical = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
visual = "mesh",
mesh = "cart.x",
visual_size = {x=1, y=1},
textures = {"cart.png"},
initial_properties = {
physical = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
visual = "mesh",
mesh = "cart.x",
visual_size = {x=1, y=1},
textures = {"cart.png"},
},
driver = nil,
punched = false, -- used to re-send velocity and position
@ -38,9 +38,9 @@ local cart_entity = {
}
-- Model and textures
if boost_cart.mtg_compat then
cart_entity.mesh = "carts_cart.b3d"
cart_entity.textures = {"carts_cart.png"}
if boost_cart.MTG_CARTS then
cart_entity.initial_properties.mesh = "carts_cart.b3d"
cart_entity.initial_properties.textures = {"carts_cart.png"}
end
function cart_entity:on_rightclick(clicker)
@ -54,6 +54,12 @@ function cart_entity:on_rightclick(clicker)
elseif not self.driver then
self.driver = player_name
boost_cart:manage_attachment(clicker, self.object)
if default.player_set_animation then
-- player_api(/default) does not update the animation
-- when the player is attached, reset to default animation
default.player_set_animation(clicker, "stand")
end
end
end
@ -69,18 +75,29 @@ function cart_entity:on_activate(staticdata, dtime_s)
return
end
self.railtype = data.railtype
if data.old_dir then
self.old_dir = data.old_dir
self.old_dir = data.old_dir or self.old_dir
self.old_pos = data.old_pos or self.old_pos
-- Correct the position when the cart drives further after the last 'step()'
if self.old_pos and boost_cart:is_rail(self.old_pos, self.railtype) then
self.object:set_pos(self.old_pos)
end
end
function cart_entity:get_staticdata()
return minetest.serialize({
railtype = self.railtype,
old_dir = self.old_dir
old_dir = self.old_dir,
old_pos = self.old_pos
})
end
-- 0.5.x and later: When the driver leaves
function cart_entity:on_detach_child(child)
if child and child:get_player_name() == self.driver then
self.driver = nil
end
end
function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
local pos = self.object:get_pos()
local vel = self.object:get_velocity()
@ -216,11 +233,12 @@ function cart_entity:on_step(dtime)
)
local dir_changed = not vector.equals(dir, self.old_dir)
local new_acc = {x=0, y=0, z=0}
local acc = 0
if stop_wiggle or vector.equals(dir, {x=0, y=0, z=0}) then
vel = {x=0, y=0, z=0}
local pos_r = vector.round(pos)
if not boost_cart:is_rail(pos_r, self.railtype) then
if not boost_cart:is_rail(pos_r, self.railtype)
and self.old_pos then
pos = self.old_pos
elseif not stop_wiggle then
pos = pos_r
@ -232,7 +250,7 @@ function cart_entity:on_step(dtime)
else
-- Direction change detected
if dir_changed then
vel = vector.multiply(dir, v3_len(vel))
vel = vector.multiply(dir, math.abs(vel.x + vel.z))
update.vel = true
if dir.y ~= self.old_dir.y then
pos = vector.round(pos)
@ -250,7 +268,7 @@ function cart_entity:on_step(dtime)
end
-- Calculate current cart acceleration
local acc = nil
acc = nil
local acc_meta = minetest.get_meta(pos):get_string("cart_acceleration")
if acc_meta == "halt" and not self.punched then
@ -269,7 +287,7 @@ function cart_entity:on_step(dtime)
acc = speed_mod * 10
end
end
if acc == nil and boost_cart.mtg_compat then
if acc == nil and boost_cart.MTG_CARTS then
-- MTG Cart API adaption
local rail_node = minetest.get_node(vector.round(pos))
local railparam = carts.railparams[rail_node.name]
@ -292,21 +310,20 @@ function cart_entity:on_step(dtime)
else
acc = 0
end
new_acc = vector.multiply(dir, acc)
end
-- Limits
local max_vel = boost_cart.speed_max
for _,v in pairs({"x","y","z"}) do
if math.abs(vel[v]) > max_vel then
vel[v] = boost_cart:get_sign(vel[v]) * max_vel
new_acc[v] = 0
update.vel = true
end
-- Limit cart speed
local vel_len = vector.length(vel)
if vel_len > boost_cart.speed_max then
vel = vector.multiply(vel, boost_cart.speed_max / vel_len)
update.vel = true
end
if vel_len >= boost_cart.speed_max and acc > 0 then
acc = 0
end
self.object:set_acceleration(new_acc)
self.object:set_acceleration(vector.multiply(dir, acc))
self.old_pos = vector.round(pos)
local old_y_dir = self.old_dir.y
if not vector.equals(dir, {x=0, y=0, z=0}) and not stop_wiggle then
@ -361,18 +378,14 @@ function cart_entity:on_step(dtime)
-- Change player model rotation, depending on the Y direction
if player and dir.y ~= old_y_dir then
local feet = {x=0, y=0, z=0}
local feet = {x=0, y=-4, z=0}
local eye = {x=0, y=-4, z=0}
feet.y = boost_cart.old_player_model and 6 or -4
if dir.y ~= 0 then
-- TODO: Find a better way to calculate this
if boost_cart.old_player_model then
feet.y = feet.y + 2
feet.z = -dir.y * 6
else
feet.y = feet.y + 4
feet.z = -dir.y * 2
end
feet.y = feet.y + 4
feet.z = -dir.y * 2
eye.z = -dir.y * 8
end
player:set_attach(self.object, "", feet,
@ -395,7 +408,7 @@ end
minetest.register_entity(":carts:cart", cart_entity)
-- Register item to place the entity
if not boost_cart.mtg_compat then
if not boost_cart.MTG_CARTS then
minetest.register_craftitem(":carts:cart", {
description = "Cart (Sneak+Click to pick up)",
inventory_image = minetest.inventorycube(

View File

@ -1,4 +0,0 @@
default
mesecons?
moreores?
carts?

View File

@ -1 +0,0 @@
This mod offers improved minecarts and a few more rail types.

71
doc/mod_api.txt Normal file
View File

@ -0,0 +1,71 @@
boost_cart API
==============
This file provides information about the API of boost_cart for the use in
mods. The API might change slightly when the development goes on, so avoid
using internal tables or functions which are not documented here.
Types
-----
* `SwitchIgnore` -> `number/nil`
* Specifies which player control was pressed. This value is used to prefer
straight rails instead of preferring left and right rail checks.
* `1`: Ignore left rail
* `2`: Ignore right rail
* `nil`: Ignore no rail
Entity movement
---------------
These functions are grouped so that they make sense and then sorted alphabetically.
* `boost_cart:manage_attachment(player, obj)`
* Attaches or detaches the player to/from an object, depending on what is
supplied to `obj`.
* `player`: `ObjectRef` of the player
* `obj`: `ObjectRef` (to attach) or `nil` (to detach)
* `boost_cart:get_sign(n)` -> `number`
* Returns the sign for the given number. Values: `-1`, `0`, `1`
* `n`: any `number`
* `boost_cart:velocity_to_dir(vel)` -> `vector`
* Returns the cart direction depending on `vel`. Each coordinate can have
one of the `get_sign()` return values.
* `vel`: velocity as `vector`
* `boost_cart:boost_rail(pos, amount)`
* Sets the rail acceleration for the given position to `amount` and punches
carts which are at the given position.
* `pos`: `vector`, rail position
* `amount`: `number`, negative to brake, positive to boost
* `boost_cart:get_rail_direction(pos, dir, ctrl, old_switch, railtype)`
-> `vector, SwitchIgnore`
* Returns the direction to where the next rail is, and which player control that
should be ignored in the next call.
* `pos`: `vector`, position of the cart
* `dir`: `vector`, movement direction of the cart (see `velocity_to_dir()`)
* `ctrl`: Player controls table or `nil` (no player)
* `old_switch`: `SwitchIgnore`
* `railtype`: (optional) `number`, gets passed indirectly to `is_rail()`
Rail helper functions
---------------------
* `boost_cart:get_rail_groups(groups)` -> `table`
* Returns a group table with preset values for a common rail node
* `groups`: (optional) `table`, additional groups append (or overwrite)
* Hint: To register an incompatible rail type, set the group
`connect_to_raillike` to the value returned by
`minetest.raillike_group(new_rail_type)`
* `boost_cart:is_rail(pos, [railtype])` -> `boolean`
* Returns whether the node at `pos` is a rail. When `railtype` is specified,
`true` is only returned when the node is in the same rail group.
* `pos`: `vector` of the node to check
* `railtype`: (optional) `number`, rail group number
* `boost_cart:register_rail(name, def)`
* Registers a new rail with preset node definition defaults as fallback
* `name`: `string`, node name of the new rail
* `def`: Node definition table, containing at least the following keys:
* `description`
* `groups`
* `tiles`

View File

@ -10,16 +10,17 @@ function boost_cart:manage_attachment(player, obj)
if not player then
return
end
local status = obj ~= nil
local wants_attach = obj ~= nil
local attached = player:get_attach() ~= nil
local player_name = player:get_player_name()
if default.player_attached[player_name] == status then
boost_cart.player_attached[player_name] = attached or wants_attach
if attached == wants_attach then
return
end
default.player_attached[player_name] = status
if status then
local y_pos = self.old_player_model and 6 or -4
player:set_attach(obj, "", {x=0, y=y_pos, z=0}, {x=0, y=0, z=0})
if wants_attach then
player:set_attach(obj, "", {x=0, y=-4, z=0}, {x=0, y=0, z=0})
player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
else
player:set_detach()
@ -104,6 +105,16 @@ function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
right.z = -dir.x
end
local straight_priority = ctrl and dir.y ~= 0
-- Normal, to disallow rail switching up- & downhill
if straight_priority then
cur = self:check_front_up_down(pos, dir, true, railtype)
if cur then
return cur
end
end
if ctrl then
if old_switch == 1 then
left_check = false
@ -127,9 +138,11 @@ function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
end
-- Normal
cur = self:check_front_up_down(pos, dir, true, railtype)
if cur then
return cur
if not straight_priority then
cur = self:check_front_up_down(pos, dir, true, railtype)
if cur then
return cur
end
end
-- Left, if not already checked
@ -208,6 +221,9 @@ function boost_cart:boost_rail(pos, amount)
end
function boost_cart:register_rail(name, def_overwrite)
local sound_func = default.node_sound_metal_defaults
or default.node_sound_defaults
local def = {
drawtype = "raillike",
paramtype = "light",
@ -217,7 +233,8 @@ function boost_cart:register_rail(name, def_overwrite)
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
}
},
sounds = sound_func()
}
for k, v in pairs(def_overwrite) do
def[k] = v

View File

@ -1,12 +1,15 @@
if not minetest.features.object_use_texture_alpha then
error("[boost_cart] Your Minetest version is no longer supported."
.. " (Version < 5.0.0)")
end
boost_cart = {}
boost_cart.modpath = minetest.get_modpath("boost_cart")
if not minetest.settings then
error("[boost_cart] Your Minetest version is no longer supported."
.. " (Version <= 0.4.15)")
end
boost_cart.MESECONS = minetest.global_exists("mesecon")
boost_cart.MTG_CARTS = minetest.global_exists("carts") and carts.pathfinder
boost_cart.PLAYER_API = minetest.global_exists("player_api")
boost_cart.player_attached = {}
local function getNum(setting)
return tonumber(minetest.settings:get(setting))
@ -20,27 +23,22 @@ boost_cart.punch_speed_max = getNum("boost_cart.punch_speed_max") or 7
boost_cart.path_distance_max = 3
-- Support for non-default games
if not default.player_attached then
default.player_attached = {}
if boost_cart.PLAYER_API then
-- This is a table reference!
boost_cart.player_attached = player_api.player_attached
end
minetest.after(1, function()
boost_cart.old_player_model = type(player_api) ~= "table"
end)
dofile(boost_cart.modpath.."/functions.lua")
dofile(boost_cart.modpath.."/rails.lua")
if minetest.global_exists("mesecon") then
if boost_cart.MESECONS then
dofile(boost_cart.modpath.."/detector.lua")
--else
-- minetest.register_alias("carts:powerrail", "boost_cart:detectorrail")
-- minetest.register_alias("carts:powerrail", "boost_cart:detectorrail_on")
end
boost_cart.mtg_compat = minetest.global_exists("carts") and carts.pathfinder
if boost_cart.mtg_compat then
if boost_cart.MTG_CARTS then
minetest.log("action", "[boost_cart] Overwriting definitions of similar carts mod")
end
dofile(boost_cart.modpath.."/cart_entity.lua")

View File

@ -1 +1,7 @@
name = boost_cart
name = boost_cart
description = """
Boost Cart
The mod that add a cart and new kinds of rails to your world.
"""
depends = default
optional_depends = mesecons, moreores, carts, player_api

View File

@ -16,9 +16,21 @@ boost_cart:register_rail(":"..regular_rail_itemname, {
})
-- Moreores' copper rail
local copperrail_registered = false
if minetest.get_modpath("moreores") then
minetest.register_alias("carts:copperrail", "moreores:copper_rail")
else
local raildef = minetest.registered_nodes["moreores:copper_rail"]
if raildef and minetest.raillike_group then
-- Ensure that this rail uses the same connect_to_raillike
raildef.groups.connect_to_raillike = minetest.raillike_group("rail")
minetest.override_item("moreores:copper_rail", {
groups = raildef.groups
})
copperrail_registered = true
end
end
if not copperrail_registered then
boost_cart:register_rail(":carts:copperrail", {
description = "Copper rail",
tiles = {