Draft: Cord reimplementation
I've ultimately come to the conclusion that trying to expose the base game's cord system isn't worth it. It would be a monumental task trying to reverse engineer them given how little readily available information there is, and there's a good chance they won't be flexible enough to cover every use case someone might come up with. Now that BeamRenderer is fairly well understood, I've started working on a total reimplementation of cords.
What's needed for vanilla parity:
-
[x] Automatically calculate the appropriate spritesheet coordinates of each point
- This will require tweaking later on for dynamic Point addition & removal
-
[x] Automatically handle updating point positions via an Update() call
-
[x] Automatically handle rendering with BeamRenderer via a Render() call
- Currently requires feeding in Sprite, LayerID, UseOverlayData. Will handle storage of these later.
-
[ ] Automatically generate and remove new Points to handle variable rope distances
- Currently has a fixed Point count
What's needed for developers:
1. Container class for Points
-
[x] Retrieval of class from Cord (implemented as
PointDeque)- Beam returns
PointDequefor GetPoints() now, SetPoints() still takes a table
- Beam returns
-
[ ] Exposure of deque functions to lua
- Currently have [Push/Pop][Front/Back]
- Will definitely need __len, erase, Point getter/setter
2. Game state interactions
-
[ ] Handling for connecting both ends of a Cord to Entities
- Currently takes an Entity as a source, but the other end is free-floating
- Might also want to allow an arbitrary Vector source/target (would need to be updated before calling Update()
- Do I want to handle restricting target Entity movement? Maybe make this optional?
3. Documentation
- [ ] Pages for Cord, PointDeque
- [ ] Update Beam page for PointDeque
- [ ] Tutorial, example mod
- [ ] Changelog entry
What'd be nice:
- [ ] Snap points to nearest entity/grid
- [ ] Handle edge cases where large angle changes between points causes visual distortion
- [ ] Rope & Point mass
Test script:
mod = RegisterMod("REPENTOTEST", 1)
local spritesheetHeight = 64
local sprite = Sprite()
sprite:Load("gfx/1000.193_anima chain.anm2", true)
sprite:Play("Idle", false)
local layer = sprite:GetLayer("chain")
layer:SetWrapSMode(1)
layer:SetWrapTMode(0)
mod:AddCallback(ModCallbacks.MC_POST_PLAYER_INIT, function(_, player)
local cord = Cord(player, Vector(80, 160), 12)
player:GetData().cord = cord
end)
mod:AddCallback(ModCallbacks.MC_POST_PLAYER_UPDATE, function(_, player)
if player:GetData().cord ~= nil then
player:GetData().cord:Update()
end
end)
mod:AddCallback(ModCallbacks.MC_POST_PLAYER_RENDER, function(_, player)
if player:GetData().cord ~= nil then
player:GetData().cord:Render(sprite, 1, false)
end
end)