Allow more than 3 passengers and improve API (#4)

* Remove maximum of 3 passengers from lib_mount

* Fix up the code after actually testing it.

* Fix lint issue

* Provide a way for an API user to stop lib_mount from updating legacy
variables

* Restructure ensure_passengers_exists

- Decreases indentation level
- Makes implicit returns explicit with hopes of more readability
- Fixes lint issue?

* Change (not a == b) to a ~= b. It's convention

* Rename a function

`copya_a_passenger_to_old_api` -> `old_copy_passenger`

Resolves https://github.com/minetest-mods/lib_mount/pull/4/files#r1036365711

* Try out `new_api` change.

See: https://github.com/minetest-mods/lib_mount/pull/4#discussion_r1036364246

Co-authored-by: David Leal <halfpacho@gmail.com>
This commit is contained in:
Lazerbeak12345 2022-12-03 18:06:56 -07:00 committed by GitHub
parent d2722ed47d
commit c9d0dddf18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

190
init.lua
View File

@ -77,21 +77,105 @@ local function get_v(v)
return math.sqrt(v.x ^ 2 + v.z ^ 2)
end
local function ensure_passengers_exists(entity)
if entity.passengers ~= nil then
return
end
entity.passengers = {}
if entity.passenger ~= nil or
entity.passenger_attach_at ~= nil or
entity.passenger_eye_offset ~= nil then
table.insert(entity.passengers,{
player=entity.passenger,
attach_at=entity.passenger_attach_at,
eye_offset=entity.passenger_eye_offset
})
else
return
end
if entity.passenger2 ~= nil or
entity.passenger2_attach_at ~= nil or
entity.passenger2_eye_offset ~= nil then
table.insert(entity.passengers,{
player=entity.passenger2,
attach_at=entity.passenger2_attach_at,
eye_offset=entity.passenger2_eye_offset
})
else
return
end
if entity.passenger3 ~= nil or
entity.passenger3_attach_at ~= nil or
entity.passenger3_eye_offset ~= nil then
table.insert(entity.passengers,{
player=entity.passenger3,
attach_at=entity.passenger3_attach_at,
eye_offset=entity.passenger3_eye_offset
})
end
end
-- Copies the specified passenger to the older api. Note that this is one-directional.
-- If something changed in the old api before this is called it is lost.
-- In code you control be sure to always use the newer API and to call this function on every change.
-- If you would like to improove preformance (memory & CPU) by not updating the old API, set
-- entity.new_api to true. This will return from the funciton instead of doing anything.
local function old_copy_passenger(entity,index,player,attach,eye)
if entity.new_api then
return
end
ensure_passengers_exists(entity)
if index==1 then -- Don't forget! Lua indexes start at 1
if player then
entity.passenger = entity.passengers[index].player
end
if attach then
entity.passenger_attach_at = entity.passengers[index].attach_at
end
if eye then
entity.passenger_eye_offset = entity.passengers[index].eye_offset
end
elseif index==2 then
if player then
entity.passenger2 = entity.passengers[index].player
end
if attach then
entity.passenger2_attach_at = entity.passengers[index].attach_at
end
if eye then
entity.passenger2_eye_offset = entity.passengers[index].eye_offset
end
elseif index==3 then
if player then
entity.passenger3 = entity.passengers[index].player
end
if attach then
entity.passenger3_attach_at = entity.passengers[index].attach_at
end
if eye then
entity.passenger3_eye_offset = entity.passengers[index].eye_offset
end
end
end
local function force_detach(player)
local attached_to = player:get_attach()
if attached_to then
local entity = attached_to:get_luaentity()
if entity.driver and entity.driver == player then
entity.driver = nil
elseif entity.passenger and entity.passenger == player then
entity.passenger = nil
lib_mount.passengers[player] = nil
elseif entity.passenger2 and entity.passenger2 == player then
entity.passenger2 = nil
lib_mount.passengers[player] = nil
elseif entity.passenger3 and entity.passenger3 == player then
entity.passenger3 = nil
else
ensure_passengers_exists(entity)
for i,passenger in ipairs(entity.passengers) do
if passenger.player == player then -- If it's nil it won't match
entity.passengers[i].player = nil -- This maintains the behavior where you could have passenger 1 leave but passenger 2 is still there, and they don't move
lib_mount.passengers[player] = nil
-- Legacy support
old_copy_passenger(entity,i,true,false,false)
break -- No need to continue looping. We found them.
end
end
end
player:set_detach()
player_api.player_attached[player:get_player_name()] = false
@ -130,47 +214,29 @@ function lib_mount.attach(entity, player, is_passenger, passenger_number)
entity.player_rotation = {x=0, y=0, z=0}
end
if is_passenger == true and passenger_number == 1 then
if not entity.passenger_attach_at then
entity.passenger_attach_at = {x=0, y=0, z=0}
if is_passenger == true then
-- Legacy support
ensure_passengers_exists(entity)
local attach_updated=false
if not entity.passengers[passenger_number].attach_at then
entity.passengers[passenger_number].attach_at = {x=0, y=0, z=0}
attach_updated=true
end
if not entity.passenger_eye_offset then
entity.passenger_eye_offset = {x=0, y=0, z=0}
local eye_updated=false
if not entity.passengers[passenger_number].eye_offset then
entity.passengers[passenger_number].eye_offset = {x=0, y=0, z=0}
eye_updated=true
end
attach_at = entity.passenger_attach_at
eye_offset = entity.passenger_eye_offset
attach_at = entity.passengers[passenger_number].attach_at
eye_offset = entity.passengers[passenger_number].eye_offset
entity.passenger = player
lib_mount.passengers[entity.passenger] = player
entity.passengers[passenger_number].player = player
lib_mount.passengers[player] = player
elseif is_passenger == true and passenger_number == 2 then
if not entity.passenger2_attach_at then
entity.passenger2_attach_at = {x=0, y=0, z=0}
end
if not entity.passenger2_eye_offset then
entity.passenger2_eye_offset = {x=0, y=0, z=0}
end
attach_at = entity.passenger2_attach_at
eye_offset = entity.passenger2_eye_offset
entity.passenger2 = player
lib_mount.passengers[entity.passenger2] = player
elseif is_passenger == true and passenger_number == 3 then
if not entity.passenger3_attach_at then
entity.passenger3_attach_at = {x=0, y=0, z=0}
end
if not entity.passenger3_eye_offset then
entity.passenger3_eye_offset = {x=0, y=0, z=0}
end
attach_at = entity.passenger3_attach_at
eye_offset = entity.passenger3_eye_offset
entity.passenger3 = player
lib_mount.passengers[entity.passenger3] = player
-- Legacy support
old_copy_passenger(entity,passenger_number,true,attach_updated,eye_updated)
else
if not entity.driver_attach_at then
entity.driver_attach_at = {x=0, y=0, z=0}
@ -210,14 +276,14 @@ function lib_mount.drive(entity, dtime, is_mob, moving_anim, stand_anim, jump_he
-- Sanity checks
if entity.driver and not entity.driver:get_attach() then entity.driver = nil end
if entity.passenger and not entity.passenger:get_attach() then
entity.passenger = nil
-- Legacy support
ensure_passengers_exists(entity)
for i,passenger in ipairs(entity.passengers) do
if passenger.player and not passenger.player:get_attach() then
entity.passengers[i].player = nil
-- Legacy support
old_copy_passenger(entity,i,true,false,false)
end
if entity.passenger2 and not entity.passenger2:get_attach() then
entity.passenger2 = nil
end
if entity.passenger3 and not entity.passenger3:get_attach() then
entity.passenger3 = nil
end
aux_timer = aux_timer + dtime
@ -418,26 +484,14 @@ function lib_mount.drive(entity, dtime, is_mob, moving_anim, stand_anim, jump_he
drvr:set_velocity(new_velo)
drvr:set_hp(drvr:get_hp() - intensity)
end
if entity.passenger then
local pass = entity.passenger
lib_mount.detach(pass, {x=0, y=0, z=0})
ensure_passengers_exists(entity)-- Legacy support
for _,passenger in ipairs(entity.passengers) do
if passenger.player then
local pass = passenger.player
lib_mount.detach(pass, {x=0, y=0, z=0}) -- This function already copies to old API
pass:set_velocity(new_velo)
pass:set_hp(pass:get_hp() - intensity)
end
if entity.passenger2 then
local pass = entity.passenger2
lib_mount.detach(pass, {x=0, y=0, z=0})
pass:set_velocity(new_velo)
pass:set_hp(pass:get_hp() - intensity)
end
if entity.passenger3 then
local pass = entity.passenger3
lib_mount.detach(pass, {x=0, y=0, z=0})
pass:set_velocity(new_velo)
pass:set_hp(pass:get_hp() - intensity)
end
local pos = entity.object:get_pos()