This commit is contained in:
Aria 2025-03-21 22:23:30 +11:00
commit 9c94d113d3
Signed by untrusted user who does not match committer: aria
GPG key ID: 19AB7AA462B8AB3B
10260 changed files with 1237388 additions and 0 deletions

View file

@ -0,0 +1,117 @@
function init()
self.specialLast = false
self.active = false
tech.setVisible(false)
self.honkTimer = 0
self.energyCostPerSecond = config.getParameter("energyCostPerSecond")
self.carCustomMovementParameters = config.getParameter("carCustomMovementParameters")
self.parentOffset = config.getParameter("parentOffset")
self.collisionPoly = mcontroller.baseParameters().standingPoly
end
function uninit()
if self.active then
local transformPosition = transformPoly(self.collisionPoly)
if transformPosition then
mcontroller.setPosition(transformPosition)
end
deactivate()
end
end
function update(args)
local specialActivated = not self.specialLast and args.moves["special1"]
self.specialLast = args.moves["special1"]
if not self.active and not tech.parentLounging() and specialActivated then
local transformPosition = transformPoly(self.carCustomMovementParameters.standingPoly)
if transformPosition and status.overConsumeResource("energy", self.energyCostPerSecond * args.dt) then
mcontroller.setPosition(transformPosition)
activate()
else
-- Make some kind of error noise
end
elseif self.active and (specialActivated or not status.overConsumeResource("energy", self.energyCostPerSecond * args.dt)) then
local transformPosition = transformPoly(self.collisionPoly)
if transformPosition then
mcontroller.setPosition(transformPosition)
end
deactivate()
end
if self.active then
local diff = world.distance(tech.aimPosition(), mcontroller.position())
local aimAngle = math.atan(diff[2], diff[1])
local flip = aimAngle > math.pi / 2 or aimAngle < -math.pi / 2
mcontroller.controlParameters(self.carCustomMovementParameters)
if flip then
animator.setFlipped(true)
tech.setParentOffset({-self.parentOffset[1], self.parentOffset[2]})
mcontroller.controlFace(-1)
else
animator.setFlipped(false)
tech.setParentOffset(self.parentOffset)
mcontroller.controlFace(1)
end
if not mcontroller.onGround() then
if mcontroller.velocity()[2] > 0 then
animator.setAnimationState("movement", "jump")
else
animator.setAnimationState("movement", "fall")
end
elseif mcontroller.walking() or mcontroller.running() then
if flip and mcontroller.facingDirection() == 1 or not flip and mcontroller.facingDirection() == -1 then
animator.setAnimationState("movement", "driveReverse")
else
animator.setAnimationState("movement", "driveForward")
end
else
animator.setAnimationState("movement", "idle")
end
if args.moves["primaryFire"] and self.honkTimer <= 0 then
animator.playSound("carHorn")
self.honkTimer = config.getParameter("honkTime")
end
if self.honkTimer > 0 then self.honkTimer = self.honkTimer - args.dt end
end
end
function activate()
animator.burstParticleEmitter("carActivateParticles")
tech.setVisible(true)
tech.setParentState("sit")
tech.setToolUsageSuppressed(true)
self.active = true
end
function deactivate()
animator.burstParticleEmitter("carDeactivateParticles")
tech.setVisible(false)
tech.setParentState()
tech.setToolUsageSuppressed(false)
tech.setParentOffset({0, 0})
self.active = false
end
function transformPoly(toPoly)
local position = mcontroller.position()
local yAdjust = collisionBottom(mcontroller.collisionPoly()) - collisionBottom(toPoly)
return world.resolvePolyCollision(toPoly, {position[1], position[2] + yAdjust}, 1)
end
function collisionBottom(collisionPoly)
local lowest = 0
for _,point in pairs(collisionPoly) do
if point[2] < lowest then
lowest = point[2]
end
end
return lowest
end

View file

@ -0,0 +1,91 @@
{
"animatedParts" : {
"stateTypes" : {
"movement" : {
"default" : "idle",
"states" : {
"idle" : { },
"jump" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end",
"properties" : {
"immediateSound" : "/sfx/tech/tech_doublejump.ogg"
}
},
"fall" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end"
},
"driveForward" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
},
"driveReverse" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
}
}
}
},
"parts" : {
"foreground" : {
"properties" : {
"centered" : true,
"zLevel" : 1
},
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "humancarforeground.png:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "humancarforeground.png:jump.<frame>"
}
},
"fall" : {
"properties" : {
"image" : "humancarforeground.png:fall.<frame>"
}
},
"driveForward" : {
"properties" : {
"image" : "humancarforeground.png:move.<frame>"
}
},
"driveReverse" : {
"properties" : {
"image" : "humancarforeground.png:bmove.<frame>"
}
}
}
}
}
}
},
"sounds" : {
"carHorn" : ["/sfx/tech/honk.ogg"]
},
"particleEmitters" : {
"carActivateParticles" : {
"particles" : [ ]
},
"carDeactivateParticles" : {
"particles" : [ ]
}
}
}

View file

@ -0,0 +1,56 @@
{
"name" : "humancar",
"type" : "head",
"scripts" : [
"/scripts/vec2.lua",
"/tech/automobile/car.lua"
],
"animator" : "humancar.animation",
"description" : "Press F to use this. Traverses rough terrain quicker.",
"shortDescription" : "Human Car",
"rarity" : "Legendary",
"icon" : "/tech/humancar.png",
"chipCost" : 8,
"carCustomMovementParameters" : {
"standingPoly" : [ [-3.5, 0.25], [-2, -2.25], [2, -2.25], [3.5, 0.25], [3.5, 0.5], [2, 0.5], [-2, 0.5], [-3.5, 0.5] ],
"crouchingPoly" : [ [-3.5, 0.25], [-2, -2.25], [2, -2.25], [3.5, 0.25], [3.5, 0.5], [2, 0.5], [-2, 0.5], [-3.5, 0.5] ],
"mass" : 5.0,
"normalGroundFriction" : 50.0,
"ambulatingGroundFriction" : 6.0,
"groundForce" : 160.0,
"airForce" : 50.0,
"liquidForce" : 70.0,
"walkSpeed" : 6.0,
"runSpeed" : 30.0,
"airJumpProfile" : {
"jumpSpeed" : 20.0,
"jumpControlForce" : 700.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.15
},
"liquidJumpProfile" : {
"jumpSpeed" : 8.0,
"jumpControlForce" : 400.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.1
}
},
"energyCostPerSecond" : 10,
"parentOffset" : [0.0, 0.4],
"carCollisionTest" : [-3.5, -2.5, 3.5, 5],
"honkTime" : 1.0
}

View file

@ -0,0 +1,20 @@
{
"frameGrid" : {
"size" : [70, 38],
"dimensions" : [4, 3],
"names" : [
[ "move.1", "move.2", "move.3", "move.4" ],
[ "fall.1", "fall.2", "idle.1" ],
[ "jump.1", "jump.2" ]
]
},
"aliases" : {
"bmove.4" : "move.1",
"bmove.3" : "move.2",
"bmove.2" : "move.3",
"bmove.1" : "move.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -0,0 +1,128 @@
{
"animatedParts" : {
"stateTypes" : {
"movement" : {
"default" : "idle",
"states" : {
"idle" : { },
"jump" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end",
"properties" : {
"immediateSound" : "/sfx/tech/tech_doublejump.ogg"
}
},
"fall" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end"
},
"driveForward" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
},
"driveReverse" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
}
}
}
},
"parts" : {
"background" : {
"properties" : {
"centered" : true,
"zLevel" : -1
},
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "humanjeepbackground.png:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "humanjeepbackground.png:jump.<frame>"
}
},
"fall" : {
"properties" : {
"image" : "humanjeepbackground.png:fall.<frame>"
}
},
"driveForward" : {
"properties" : {
"image" : "humanjeepbackground.png:move.<frame>"
}
},
"driveReverse" : {
"properties" : {
"image" : "humanjeepbackground.png:bmove.<frame>"
}
}
}
}
},
"foreground" : {
"properties" : {
"centered" : true,
"zLevel" : 1
},
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "humanjeepforeground.png:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "humanjeepforeground.png:jump.<frame>"
}
},
"fall" : {
"properties" : {
"image" : "humanjeepforeground.png:fall.<frame>"
}
},
"driveForward" : {
"properties" : {
"image" : "humanjeepforeground.png:move.<frame>"
}
},
"driveReverse" : {
"properties" : {
"image" : "humanjeepforeground.png:bmove.<frame>"
}
}
}
}
}
}
},
"sounds" : {
"carHorn" : ["/sfx/tech/honk.ogg"]
},
"particleEmitters" : {
"carActivateParticles" : {
"particles" : [ ]
},
"carDeactivateParticles" : {
"particles" : [ ]
}
}
}

View file

@ -0,0 +1,56 @@
{
"name" : "humanjeep",
"type" : "head",
"scripts" : [
"/scripts/vec2.lua",
"/tech/automobile/car.lua"
],
"animator" : "humanjeep.animation",
"description" : "Press F to use this. Traverses rough terrain quicker.",
"shortDescription" : "Human Jeep",
"rarity" : "Legendary",
"icon" : "/tech/humanjeep.png",
"chipCost" : 8,
"carCustomMovementParameters" : {
"standingPoly" : [ [-3.5, 0.25], [-2, -1.75], [2, -1.75], [3.5, 0.25], [3.5, 0.5], [2, 0.5], [-2, 0.5], [-3.5, 0.5] ],
"crouchingPoly" : [ [-3.5, 0.25], [-2, -1.75], [2, -1.75], [3.5, 0.25], [3.5, 0.5], [2, 0.5], [-2, 0.5], [-3.5, 0.5] ],
"mass" : 5.0,
"normalGroundFriction" : 50.0,
"ambulatingGroundFriction" : 6.0,
"groundForce" : 160.0,
"airForce" : 50.0,
"liquidForce" : 70.0,
"walkSpeed" : 6.0,
"runSpeed" : 30.0,
"airJumpProfile" : {
"jumpSpeed" : 20.0,
"jumpControlForce" : 700.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.15
},
"liquidJumpProfile" : {
"jumpSpeed" : 8.0,
"jumpControlForce" : 400.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.1
}
},
"energyCostPerSecond" : 10,
"parentOffset" : [-1.0, 1.2],
"carCollisionTest" : [-3.5, -2.5, 3.5, 5],
"honkTime" : 1.0
}

View file

@ -0,0 +1,20 @@
{
"frameGrid" : {
"size" : [54, 32],
"dimensions" : [4, 3],
"names" : [
[ "move.1", "move.2", "move.3", "move.4" ],
[ "fall.1", "fall.2", "idle.1" ],
[ "jump.1", "jump.2" ]
]
},
"aliases" : {
"bmove.4" : "move.1",
"bmove.3" : "move.2",
"bmove.2" : "move.3",
"bmove.1" : "move.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

View file

@ -0,0 +1,20 @@
{
"frameGrid" : {
"size" : [54, 32],
"dimensions" : [4, 3],
"names" : [
[ "move.1", "move.2", "move.3", "move.4" ],
[ "fall.1", "fall.2", "idle.1" ],
[ "jump.1", "jump.2" ]
]
},
"aliases" : {
"bmove.4" : "move.1",
"bmove.3" : "move.2",
"bmove.2" : "move.3",
"bmove.1" : "move.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,128 @@
{
"animatedParts" : {
"stateTypes" : {
"movement" : {
"default" : "idle",
"states" : {
"idle" : { },
"jump" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end",
"properties" : {
"immediateSound" : "/sfx/tech/tech_doublejump.ogg"
}
},
"fall" : {
"frames" : 2,
"cycle" : 0.5,
"mode" : "end"
},
"driveForward" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
},
"driveReverse" : {
"frames" : 4,
"cycle" : 0.5,
"mode" : "loop"
}
}
}
},
"parts" : {
"background" : {
"properties" : {
"centered" : true,
"zLevel" : -1
},
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "penguintankbackground.png:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "penguintankbackground.png:jump.<frame>"
}
},
"fall" : {
"properties" : {
"image" : "penguintankbackground.png:fall.<frame>"
}
},
"driveForward" : {
"properties" : {
"image" : "penguintankbackground.png:move.<frame>"
}
},
"driveReverse" : {
"properties" : {
"image" : "penguintankbackground.png:bmove.<frame>"
}
}
}
}
},
"foreground" : {
"properties" : {
"centered" : true,
"zLevel" : 1
},
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "penguintankforeground.png:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "penguintankforeground.png:jump.<frame>"
}
},
"fall" : {
"properties" : {
"image" : "penguintankforeground.png:fall.<frame>"
}
},
"driveForward" : {
"properties" : {
"image" : "penguintankforeground.png:move.<frame>"
}
},
"driveReverse" : {
"properties" : {
"image" : "penguintankforeground.png:bmove.<frame>"
}
}
}
}
}
}
},
"sounds" : {
"carHorn" : ["/sfx/tech/honk.ogg"]
},
"particleEmitters" : {
"carActivateParticles" : {
"particles" : [ ]
},
"carDeactivateParticles" : {
"particles" : [ ]
}
}
}

View file

@ -0,0 +1,56 @@
{
"name" : "penguintank",
"type" : "head",
"scripts" : [
"/scripts/vec2.lua",
"/tech/automobile/car.lua"
],
"animator" : "penguintank.animation",
"description" : "Press F to use this. Traverses rough terrain quicker.",
"shortDescription" : "Penguin Tank",
"rarity" : "Legendary",
"icon" : "/tech/humanjeep.png",
"chipCost" : 8,
"carCustomMovementParameters" : {
"standingPoly" : [ [-2.5, -1.75], [2.5, -1.75], [1.5, 0.5], [-1.5, 0.5] ],
"crouchingPoly" : [ [-2.5, -1.75], [2.5, -1.75], [1.5, 0.5], [-1.5, 0.5] ],
"mass" : 5.0,
"normalGroundFriction" : 50.0,
"ambulatingGroundFriction" : 6.0,
"groundForce" : 160.0,
"airForce" : 50.0,
"liquidForce" : 70.0,
"walkSpeed" : 3.0,
"runSpeed" : 15.0,
"airJumpProfile" : {
"jumpSpeed" : 10.0,
"jumpControlForce" : 700.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.15
},
"liquidJumpProfile" : {
"jumpSpeed" : 5.0,
"jumpControlForce" : 400.0,
"jumpInitialPercentage" : 0.75,
"jumpHoldTime" : 0.1
}
},
"energyCostPerSecond" : 10,
"parentOffset" : [-0.7, 1.6],
"carCollisionTest" : [-3.5, -2.5, 3.5, 5],
"honkTime" : 1.0
}

View file

@ -0,0 +1,20 @@
{
"frameGrid" : {
"size" : [46, 31],
"dimensions" : [4, 3],
"names" : [
[ "move.1", "move.2", "move.3", "move.4" ],
[ "fall.1", "fall.2", "idle.1" ],
[ "jump.1", "jump.2" ]
]
},
"aliases" : {
"bmove.4" : "move.1",
"bmove.3" : "move.2",
"bmove.2" : "move.3",
"bmove.1" : "move.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,20 @@
{
"frameGrid" : {
"size" : [46, 31],
"dimensions" : [4, 3],
"names" : [
[ "move.1", "move.2", "move.3", "move.4" ],
[ "fall.1", "fall.2", "idle.1" ],
[ "jump.1", "jump.2" ]
]
},
"aliases" : {
"bmove.4" : "move.1",
"bmove.3" : "move.2",
"bmove.2" : "move.3",
"bmove.1" : "move.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/devel/tech/blink.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

View file

@ -0,0 +1,52 @@
{
"animatedParts" : {
"stateTypes" : {
"blinking" : {
"default" : "off",
"states" : {
"off" : { },
"in" : {
"frames" : 5,
"cycle" : 0.15,
"mode" : "transition",
"transition" : "off"
},
"out" : {
"frames" : 5,
"cycle" : 0.15,
"mode" : "transition",
"transition" : "off"
}
}
}
},
"parts" : {
"blinkeffect" : {
"properties" : {
"centered" : true
},
"partStates" : {
"blinking" : {
"in" : {
"properties" : {
"image" : "blinkin.png:<frameIndex>"
}
},
"out" : {
"properties" : {
"image" : "blinkout.png:<frameIndex>"
}
}
}
}
}
}
},
"sounds" : {
"activate" : [ "/sfx/tech/tech_blink1.ogg" ]
}
}

View file

@ -0,0 +1,158 @@
function init()
self.mode = "none"
self.timer = 0
self.targetPosition = nil
self.energyUsage = config.getParameter("energyUsage")
self.blinkMode = config.getParameter("blinkMode")
self.blinkOutTime = config.getParameter("blinkOutTime")
self.blinkInTime = config.getParameter("blinkInTime")
end
function uninit()
tech.setParentDirectives()
end
function update(args)
local specialActivated = not self.specialLast and args.moves["special1"]
self.specialLast = args.moves["special1"]
if specialActivated and not tech.parentLounging() and self.mode == "none" then
local blinkPosition = nil
if self.blinkMode == "random" then
local randomBlinkAvoidCollision = config.getParameter("randomBlinkAvoidCollision")
local randomBlinkAvoidMidair = config.getParameter("randomBlinkAvoidMidair")
local randomBlinkAvoidLiquid = config.getParameter("randomBlinkAvoidLiquid")
blinkPosition =
findRandomBlinkLocation(randomBlinkAvoidCollision, randomBlinkAvoidMidair, randomBlinkAvoidLiquid) or
findRandomBlinkLocation(randomBlinkAvoidCollision, randomBlinkAvoidMidair, false) or
findRandomBlinkLocation(randomBlinkAvoidCollision, false, false)
elseif self.blinkMode == "cursor" then
blinkPosition = blinkAdjust(tech.aimPosition(), true, true, false, false)
elseif self.blinkMode == "cursorPenetrate" then
blinkPosition = blinkAdjust(tech.aimPosition(), false, true, false, false)
end
if blinkPosition and status.overConsumeResource("energy", self.energyUsage) then
self.targetPosition = blinkPosition
self.mode = "start"
else
-- Make some kind of error noise
end
end
if self.mode == "start" then
mcontroller.setVelocity({0, 0})
self.mode = "out"
self.timer = 0
animator.playSound("activate")
elseif self.mode == "out" then
tech.setParentDirectives("?multiply=00000000")
animator.setAnimationState("blinking", "out")
mcontroller.setVelocity({0, 0})
self.timer = self.timer + args.dt
if self.timer > self.blinkOutTime then
mcontroller.setPosition(self.targetPosition)
self.mode = "in"
self.timer = 0
end
elseif self.mode == "in" then
tech.setParentDirectives()
animator.setAnimationState("blinking", "in")
mcontroller.setVelocity({0, 0})
self.timer = self.timer + args.dt
if self.timer > self.blinkInTime then
self.mode = "none"
end
end
end
function blinkAdjust(position, doPathCheck, doCollisionCheck, doLiquidCheck, doStandCheck)
local blinkCollisionCheckDiameter = config.getParameter("blinkCollisionCheckDiameter")
local blinkVerticalGroundCheck = config.getParameter("blinkVerticalGroundCheck")
local blinkFootOffset = config.getParameter("blinkFootOffset")
local blinkHeadOffset = config.getParameter("blinkHeadOffset")
if doPathCheck then
local collisionBlocks = world.collisionBlocksAlongLine(mcontroller.position(), position, {"Null", "Block", "Dynamic", "Slippery"}, 1)
if #collisionBlocks ~= 0 then
local diff = world.distance(position, mcontroller.position())
diff[1] = diff[1] > 0 and 1 or -1
diff[2] = diff[2] > 0 and 1 or -1
position = {collisionBlocks[1][1] - math.min(diff[1], 0), collisionBlocks[1][2] - math.min(diff[2], 0)}
end
end
if doCollisionCheck then
local diff = world.distance(position, mcontroller.position())
local collisionPoly = mcontroller.collisionPoly()
--Add foot offset if there is ground
if diff[2] < 0 then
local groundBlocks = world.collisionBlocksAlongLine(position, {position[1], position[2] + blinkFootOffset}, {"Null", "Block", "Dynamic", "Slippery"}, 1)
if #groundBlocks > 0 then
position[2] = groundBlocks[1][2] + 1 - blinkFootOffset
end
end
--Add head offset if there is ceiling
if diff[2] > 0 then
local ceilingBlocks = world.collisionBlocksAlongLine(position, {position[1], position[2] + blinkHeadOffset}, {"Null", "Block", "Dynamic", "Slippery"}, 1)
if #ceilingBlocks > 0 then
position[2] = ceilingBlocks[1][2] - blinkHeadOffset
end
end
--Resolve position
position = world.resolvePolyCollision(collisionPoly, position, blinkCollisionCheckDiameter)
if not position or world.lineTileCollision(mcontroller.position(), position, {"Null", "Block", "Dynamic", "Slippery"}) then
return nil
end
end
if doStandCheck then
local groundFound = false
for i = 1, blinkVerticalGroundCheck * 2 do
local checkPosition = {position[1], position[2] - i / 2}
if world.pointTileCollision(checkPosition, {"Null", "Block", "Dynamic", "Platform"}) then
groundFound = true
position = {checkPosition[1], checkPosition[2] + 0.5 - blinkFootOffset}
break
end
end
if not groundFound then
return nil
end
end
if doLiquidCheck and (world.liquidAt(position) or world.liquidAt({position[1], position[2] + blinkFootOffset})) then
return nil
end
return position
end
function findRandomBlinkLocation(doCollisionCheck, doLiquidCheck, doStandCheck)
local randomBlinkTries = config.getParameter("randomBlinkTries")
local randomBlinkDiameter = config.getParameter("randomBlinkDiameter")
for i=1,randomBlinkTries do
local position = mcontroller.position()
position[1] = position[1] + (math.random() * 2 - 1) * randomBlinkDiameter
position[2] = position[2] + (math.random() * 2 - 1) * randomBlinkDiameter
local position = blinkAdjust(position, false, doCollisionCheck, doLiquidCheck, doStandCheck)
if position then
return position
end
end
return nil
end

View file

@ -0,0 +1,6 @@
{
"frameGrid" : {
"size" : [43, 43],
"dimensions" : [5, 1]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

View file

@ -0,0 +1,7 @@
{
"frameGrid" : {
"size" : [43, 43],
"dimensions" : [5, 1]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

View file

@ -0,0 +1,35 @@
{
"name" : "randblink",
"type" : "head",
"scripts" : ["blink.lua"],
"animator" : "blink.animation",
"energyUsage" : 20,
"description" : "Press 'F' to teleport to random places with this Random Blink tech! Are you brave enough?",
"shortDescription" : "Random Blink",
"rarity" : "Legendary",
"icon" : "/tech/blink.png",
"chipCost" : 8,
"blinkCollisionCheckDiameter" : 4,
"blinkVerticalGroundCheck" : 10,
// Specific to humanoid
"blinkFootOffset" : -2.5,
"blinkHeadOffset" : 1,
"blinkOutTime" : 0.15,
"blinkInTime" : 0.15,
"blinkMode" : "random",
"randomBlinkTries" : 60,
"randomBlinkDiameter" : 40,
"randomBlinkAvoidCollision" : true,
"randomBlinkAvoidMidair" : true,
"randomBlinkAvoidLiquid" : true
}

View file

@ -0,0 +1,28 @@
{
"name" : "targetblink",
"type" : "head",
"scripts" : ["blink.lua"],
"animator" : "blink.animation",
"description" : "Teleport to your mouse cursor.",
"shortDescription" : "Targeted Blink",
"rarity" : "Legendary",
"icon" : "/tech/blink.png",
"chipCost" : 8,
"energyUsage" : 110,
"blinkCollisionCheckDiameter" : 2,
"blinkVerticalGroundCheck" : 10,
// Specific to humanoid
"blinkFootOffset" : -2.5,
"blinkHeadOffset" : 1,
"blinkOutTime" : 0.15,
"blinkInTime" : 0.15,
"blinkMode" : "cursor"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

View file

@ -0,0 +1,51 @@
function init()
self.lastJump = false
self.lastBoostDirection = nil
self.energyUsagePerSecond = config.getParameter("energyUsagePerSecond")
self.boostSpeed = config.getParameter("boostSpeed")
self.boostControlForce = config.getParameter("boostControlForce")
end
function update(args)
local boostDirection
if not mcontroller.onGround() then
if not mcontroller.canJump() and args.moves["jump"] and not self.lastJump then
local diag = 1 / math.sqrt(2)
if args.moves["right"] and args.moves["up"] then
boostDirection = {self.boostSpeed * diag, self.boostSpeed * diag}
elseif args.moves["right"] and args.moves["down"] then
boostDirection = {self.boostSpeed * diag, -self.boostSpeed * diag}
elseif args.moves["left"] and args.moves["up"] then
boostDirection = {-self.boostSpeed * diag, self.boostSpeed * diag}
elseif args.moves["left"] and args.moves["down"] then
boostDirection = {-self.boostSpeed * diag, -self.boostSpeed * diag}
elseif args.moves["right"] then
boostDirection = {self.boostSpeed, 0}
elseif args.moves["down"] then
boostDirection = {0, -self.boostSpeed}
elseif args.moves["left"] then
boostDirection = {-self.boostSpeed, 0}
elseif args.moves["up"] then
boostDirection = {0, self.boostSpeed}
end
elseif args.moves["jump"] and self.lastBoostDirection then
boostDirection = self.lastBoostDirection
end
end
self.lastJump = args.moves["jump"]
self.lastBoostDirection = boostDirection
if boostDirection and status.overConsumeResource("energy", self.energyUsagePerSecond * args.dt) then
mcontroller.controlApproachVelocity(boostDirection, self.boostControlForce)
animator.setAnimationState("boosting", "on")
animator.setParticleEmitterActive("boostParticles", true)
else
animator.setAnimationState("boosting", "off")
animator.setParticleEmitterActive("boostParticles", false)
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

View file

@ -0,0 +1,45 @@
{
"animatedParts" : {
"stateTypes" : {
"boosting" : {
"default" : "off",
"states" : {
"off" : {
},
"on" : {
"properties" : {
"persistentSound" : "/sfx/tech/tech_bubbleboost.ogg"
}
}
}
}
},
"parts" : {
"bubble" : {
"partStates" : {
"boosting" : {
"on" : {
"properties" : {
"centered" : true,
"image" : "bubble.png"
}
}
}
}
}
}
},
"particleEmitters" : {
"boostParticles" : {
"emissionRate" : 20.0,
"particles" : [
{
"particle" : "bubbleboost",
"offsetRegion" : [-1, -1.5, 1, 1.5]
}
]
}
}
}

View file

@ -0,0 +1,18 @@
{
"name" : "bubbleboost",
"type" : "legs",
"scripts" : ["booster.lua"],
"animator" : "bubbleboost.animation",
"description" : "Remind yourself of December 2013 with the Bubble Boost.",
"shortDescription" : "Bubble Boost",
"rarity" : "Legendary",
"icon" : "/tech/bubbleboost.png",
"chipCost" : 8,
"boostControlForce" : 750,
"boostSpeed" : 30,
"energyUsagePerSecond" : 0
}

View file

@ -0,0 +1,23 @@
{
"animatedParts" : {
"stateTypes" : {
"boosting" : {
"default" : "off",
"states" : {
"off" : {
},
"on" : {
}
}
}
}
},
"particleEmitters" : {
"boostParticles" : {
"emissionRate" : 0.0,
"particles" : [
]
}
}
}

View file

@ -0,0 +1,18 @@
{
"name" : "cameramanboost",
"type" : "legs",
"scripts" : ["booster.lua"],
"animator" : "cameramanboost.animation",
"description" : "Press and hold Jump in the air to float around.",
"shortDescription" : "Camera Man Boost",
"rarity" : "Legendary",
"icon" : "/tech/booster.png",
"chipCost" : 8,
"boostControlForce" : 5000,
"boostSpeed" : 8,
"energyUsagePerSecond" : 0
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

View file

@ -0,0 +1,274 @@
function init()
self.modes = {"off", "worldInfo", "rectQuery", "radQuery", "lineQuery", "showCollision", "resolveCollision", "lineCollision"}
self.mode = 1
self.radii = {0.5, 1.5, 5}
self.radius = 2
self.shapes = {"square", "diamond", "octagon"}
self.shape = 1
self.boundModes = {"MetaBoundBox", "CollisionArea", "Position"}
self.boundMode = 1
self.entityTypes = {"all", "creature", "mobile", "player", "monster", "npc", "itemDrop", "projectile", "plant", "plantDrop", "effect"}
self.entityType = 1
self.collideTolerance = 2
self.lastMoves = {}
end
function update(args)
if args.moves["special1"] and not self.lastMoves["special1"] then
cycleMode()
elseif args.moves["special2"] and not self.lastMoves["special2"] then
cycleRadius()
elseif args.moves["special3"] and not self.lastMoves["special3"] then
if self.mode == 3 or self.mode == 4 or self.mode == 5 then
if args.moves["down"] and not self.lastMoves["down"] then
cycleBoundMode()
else
cycleEntityType()
end
elseif self.mode == 6 or self.mode == 7 then
cycleShape()
end
end
self.lastMoves = args.moves
local modeStr = self.modes[self.mode]
args.aimPosition = tech.aimPosition()
if modeStr == "worldInfo" then
doWorldInfo(args)
elseif modeStr == "rectQuery" then
doRectQuery(args)
elseif modeStr == "radQuery" then
doRadQuery(args)
elseif modeStr == "lineQuery" then
doLineQuery(args)
elseif modeStr == "showCollision" then
doShowCollision(args)
elseif modeStr == "resolveCollision" then
doResolveCollision(args)
elseif modeStr == "lineCollision" then
doLineCollision(args)
end
return 0
end
function cycleMode()
self.mode = (self.mode % #self.modes) + 1
end
function cycleRadius()
self.radius = (self.radius % #self.radii) + 1
end
function cycleShape()
self.shape = (self.shape % #self.shapes) + 1
end
function cycleBoundMode()
self.boundMode = (self.boundMode % #self.boundModes) + 1
end
function cycleEntityType()
self.entityType = (self.entityType % #self.entityTypes) + 1
end
function doWorldInfo(args)
local pos = args.aimPosition
local message = string.format("Position %.3f, %.3f\nGravity %s\nLight %.3f\nWind %s\nFG %s (mod %s)\nBG %s (mod %s)",
pos[1], pos[2],
world.gravity(pos),
world.lightLevel(pos),
world.windLevel(pos),
world.material(pos, "foreground"),
world.mod(pos, "foreground"),
world.material(pos, "background"),
world.mod(pos, "background"))
world.debugPoint(pos, "green")
world.debugText(message, {pos[1] + 1, pos[2] - 1}, "white")
end
function makeQueryOptions()
local queryOptions = {
boundMode = self.boundModes[self.boundMode]
}
if self.entityTypes[self.entityType] ~= "all" then
queryOptions.includedTypes = {self.entityTypes[self.entityType]}
end
return queryOptions
end
function doRectQuery(args)
local queryRadius = self.radii[self.radius]
local ll = {args.aimPosition[1] - queryRadius, args.aimPosition[2] - queryRadius}
local ur = {args.aimPosition[1] + queryRadius, args.aimPosition[2] + queryRadius}
local entityIds = world.entityQuery(ll, ur, makeQueryOptions())
drawDebugRect({ll[1], ll[2], ur[1], ur[2]}, "#7777FF")
world.debugText(string.format("%s entities (rect, %s, %s)", #entityIds, self.entityTypes[self.entityType], self.boundModes[self.boundMode]), {ll[1], ur[2]}, "white")
for _, entityId in pairs(entityIds) do
world.debugPoint(world.entityPosition(entityId), "green")
world.debugText(world.entityType(entityId).." "..entityId, world.entityPosition(entityId), "white")
end
end
function doRadQuery(args)
local queryRadius = self.radii[self.radius]
local entityIds = world.entityQuery(args.aimPosition, queryRadius, makeQueryOptions())
drawDebugPoly(makePoly("octagon", queryRadius), "#7777FF", args.aimPosition)
world.debugText(string.format("%s entities (rad, %s, %s)", #entityIds, self.entityTypes[self.entityType], self.boundModes[self.boundMode]), {args.aimPosition[1] - queryRadius, args.aimPosition[2] + queryRadius}, "white")
for _, entityId in pairs(entityIds) do
world.debugPoint(world.entityPosition(entityId), "green")
world.debugText(world.entityType(entityId).." "..entityId, world.entityPosition(entityId), "white")
end
end
function doLineQuery(args)
local queryRadius = self.radii[self.radius]
local ll = {args.aimPosition[1] - queryRadius, args.aimPosition[2] - queryRadius}
local ur = {args.aimPosition[1] + queryRadius, args.aimPosition[2] + queryRadius}
local entityIds = world.entityLineQuery(ll, ur, makeQueryOptions())
world.debugLine(ll, ur, "#7777FF")
world.debugText(string.format("%s entities (line, %s, %s)", #entityIds, self.entityTypes[self.entityType], self.boundModes[self.boundMode]), {ll[1], ur[2]}, "white")
for _, entityId in pairs(entityIds) do
world.debugPoint(world.entityPosition(entityId), "green")
world.debugText(world.entityType(entityId).." "..entityId, world.entityPosition(entityId), "white")
end
end
function doShowCollision(args)
local polyRadius = self.radii[self.radius]
local polyShape = self.shapes[self.shape]
local collidePoly = makePoly(polyShape, polyRadius)
local colliding = world.polyCollision(collidePoly, args.aimPosition)
if colliding then
drawDebugPoly(collidePoly, "red", args.aimPosition)
else
drawDebugPoly(collidePoly, "green", args.aimPosition)
end
end
function doResolveCollision(args)
local polyRadius = self.radii[self.radius]
local polyShape = self.shapes[self.shape]
local collidePoly = makePoly(polyShape, polyRadius)
local resolvedPoint = world.resolvePolyCollision(collidePoly, args.aimPosition, self.collideTolerance)
if resolvedPoint == nil then
drawDebugPoly(collidePoly, "red", args.aimPosition)
elseif resolvedPoint[1] == args.aimPosition[1] and resolvedPoint[2] == args.aimPosition[2] then
drawDebugPoly(collidePoly, "green", args.aimPosition)
else
world.debugLine(args.aimPosition, resolvedPoint, "yellow")
drawDebugPoly(collidePoly, "blue", resolvedPoint)
world.debugText(string.format("%.2f", world.magnitude(args.aimPosition, resolvedPoint)), args.aimPosition, "white")
end
end
function doLineCollision(args)
local lineRadius = self.radii[self.radius]
local lineMin = {args.aimPosition[1] - lineRadius, args.aimPosition[2] + lineRadius}
local lineMax = {args.aimPosition[1] + lineRadius, args.aimPosition[2] - lineRadius}
local colliding = world.lineTileCollision(lineMin, lineMax)
if colliding then
world.debugLine(lineMin, lineMax, "red")
else
world.debugLine(lineMin, lineMax, "green")
end
end
function makePoly(shape, radius)
if shape == "square" then
return {
{-radius, -radius},
{-radius, radius},
{radius, radius},
{radius, -radius}
}
elseif shape == "diamond" then
return {
{-radius, 0},
{0, radius},
{radius, 0},
{0, -radius}
}
elseif shape == "octagon" then
local smr = radius / 3
return {
{-radius, smr},
{-smr, radius},
{smr, radius},
{radius, smr},
{radius, -smr},
{smr, -radius},
{-smr, -radius},
{-radius, -smr}
}
end
sb.logInfo("Failed to make poly for shape %s and radius %s", shape, radius)
return {}
end
function drawDebugRect(rect, color, basePos)
if basePos then rect = translate(rect, basePos) end
world.debugLine({rect[1], rect[2]}, {rect[1], rect[4]}, color)
world.debugLine({rect[1], rect[2]}, {rect[3], rect[2]}, color)
world.debugLine({rect[3], rect[4]}, {rect[1], rect[4]}, color)
world.debugLine({rect[3], rect[4]}, {rect[3], rect[2]}, color)
end
function drawDebugPoly(poly, color, basePos)
local basePos = basePos or {0, 0}
if #poly >= 3 then
for i, point in ipairs(poly) do
world.debugLine(translate(point, basePos), translate(poly[(i % #poly) + 1], basePos), color)
end
end
end
function translate(pointOrRect, offset)
if #pointOrRect == 4 then
return {pointOrRect[1] + offset[1], pointOrRect[2] + offset[2], pointOrRect[3] + offset[1], pointOrRect[4] + offset[2]}
elseif #pointOrRect == 2 then
return {pointOrRect[1] + offset[1], pointOrRect[2] + offset[2]}
end
end
function printTable(t, indent)
if not indent then
indent = ""
sb.logInfo("Printing table...")
end
local tnames = {}
for k,v in pairs(t) do
tnames[#tnames + 1] = k
end
table.sort(tnames, function(a, b) return a < b end)
for _, key in ipairs(tnames) do
if type(t[key]) == "table" then
sb.logInfo(indent.."table "..key)
printTable(t[key], indent.." ")
elseif type(t[key]) == "function" then
sb.logInfo(indent.."function "..key)
else
sb.logInfo(indent..type(t[key]).." "..key.." = %s", t[key])
end
end
end

View file

@ -0,0 +1,13 @@
{
"name" : "debug",
"type" : "head",
"scripts" : ["debug.lua"],
"description" : "Debug info! Use F/G/H to cycle mode/size/shape",
"shortDescription" : "Debug Inspector",
"rarity" : "Legendary",
"icon" : "/tech/booster.png",
"chipCost" : 8
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

BIN
assets/devel/tech/mech.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

View file

@ -0,0 +1,3 @@
{
}

View file

@ -0,0 +1,58 @@
function init()
self.flightSpeed = config.getParameter("flightSpeed", 10)
self.flightForce = 500
storage.active = false
end
function update(args)
if not self.specialLast and args.moves["special1"]
and (storage.active or not status.statPositive("activeMovementAbilities")) then
storage.active = not storage.active
if storage.active then
status.setPersistentEffects("movementAbility", {{stat = "activeMovementAbilities", amount = 1}})
else
status.clearPersistentEffects("movementAbility")
end
end
self.specialLast = args.moves["special1"]
if storage.active then
if args.moves["up"] and args.moves["right"] then
mcontroller.controlApproachVelocity({self.flightSpeed, self.flightSpeed}, self.flightForce)
elseif args.moves["down"] and args.moves["right"] then
mcontroller.controlApproachVelocity({self.flightSpeed, -self.flightSpeed}, self.flightForce)
elseif args.moves["up"] and args.moves["left"] then
mcontroller.controlApproachVelocity({-self.flightSpeed, self.flightSpeed}, self.flightForce)
elseif args.moves["down"] and args.moves["left"] then
mcontroller.controlApproachVelocity({-self.flightSpeed, -self.flightSpeed}, self.flightForce)
elseif args.moves["up"] then
mcontroller.controlApproachVelocity({0, self.flightSpeed}, self.flightForce)
elseif args.moves["down"] then
mcontroller.controlApproachVelocity({0, -self.flightSpeed}, self.flightForce)
elseif args.moves["right"] then
mcontroller.controlApproachVelocity({self.flightSpeed, 0}, self.flightForce)
elseif args.moves["left"] then
mcontroller.controlApproachVelocity({-self.flightSpeed, 0}, self.flightForce)
else
mcontroller.controlApproachVelocity({0, 0}, self.flightForce)
end
mcontroller.controlParameters({
collisionEnabled = false,
gravityEnabled = false,
liquidImpedance = 0,
liquidFriction = 0
})
end
if storage.active then
tech.setParentDirectives("?fade=3399FFFF;0.4?multiply=FFFFFF66")
else
tech.setParentDirectives()
end
end
function uninit()
status.clearPersistentEffects("movementAbility")
end

View file

@ -0,0 +1,16 @@
{
"name" : "noclip",
"type" : "head",
"scripts" : [ "noclip.lua" ],
"animator" : "noclip.animation",
"description" : "There are no clips here.",
"shortDescription" : "Noclip",
"rarity" : "Legendary",
"icon" : "/tech/noclip.png",
"chipCost" : 8,
"flightSpeed" : 50
}

View file

@ -0,0 +1,16 @@
{
"name" : "noclipcamera",
"type" : "head",
"scripts" : [ "noclip.lua" ],
"animator" : "noclip.animation",
"description" : "There are no clips here.",
"shortDescription" : "Noclip (Camera Pan)",
"rarity" : "Legendary",
"icon" : "/tech/noclip.png",
"chipCost" : 100,
"flightSpeed" : 8
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

View file

@ -0,0 +1,3 @@
{
}

View file

@ -0,0 +1,51 @@
require "/scripts/poly.lua"
function init()
self.shrinkFactor = config.getParameter("shrinkFactor", 0.5)
self.shrinkTime = config.getParameter("shrinkTime", 1.0)
self.standingPoly = mcontroller.baseParameters().standingPoly
self.crouchingPoly = mcontroller.baseParameters().crouchingPoly
self.active = false
self.shrinkTimer = 0
end
function update(args)
if not self.specialLast and args.moves["special1"] then
storage.active = not storage.active
end
self.specialLast = args.moves["special1"]
if storage.active then
self.shrinkTimer = math.min(self.shrinkTime, self.shrinkTimer + args.dt)
updateShrink()
tech.setToolUsageSuppressed(true)
elseif self.shrinkTimer > 0 then
self.shrinkTimer = math.max(0, self.shrinkTimer - args.dt)
updateShrink()
else
tech.setToolUsageSuppressed(false)
end
end
function updateShrink()
if self.shrinkTimer > 0 then
local scaleAmount = 1 - util.round(self.shrinkFactor * (self.shrinkTimer / self.shrinkTime), 2)
tech.setParentDirectives("?scalenearest=" .. scaleAmount .. "=" .. scaleAmount)
mcontroller.controlParameters({
standingPoly = poly.scale(self.standingPoly, scaleAmount),
crouchingPoly = poly.scale(self.crouchingPoly, scaleAmount)
})
mcontroller.controlModifiers({
speedModifier = scaleAmount,
airJumpModifier = scaleAmount
})
else
tech.setParentDirectives()
end
end
function uninit()
self.shrinkTimer = 0
updateShrink()
end

View file

@ -0,0 +1,17 @@
{
"name" : "shrink",
"type" : "head",
"scripts" : [ "shrink.lua" ],
"animator" : "shrink.animation",
"description" : "Drink Me",
"shortDescription" : "Shrink",
"rarity" : "Legendary",
"icon" : "/tech/shrink.png",
"chipCost" : 8,
"shrinkFactor" : 0.5,
"shrinkTime" : 0.5
}

View file

@ -0,0 +1,3 @@
{
}

View file

@ -0,0 +1,14 @@
function init()
end
function update(args)
if args.moves["special1"] and not self.specialLast then
world.sendEntityMessage(entity.id(), "unlockMech")
world.sendEntityMessage(entity.id(), "toggleMech")
end
self.specialLast = args.moves["special1"]
end
function uninit()
end

View file

@ -0,0 +1,13 @@
{
"name" : "summonmech",
"type" : "head",
"scripts" : [ "summonmech.lua" ],
"description" : "Call your modular mech anywhere!",
"shortDescription" : "Summon Mech",
"rarity" : "Legendary",
"icon" : "/tech/mech.png",
"chipCost" : 0
}