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

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

View file

@ -0,0 +1,223 @@
require "/scripts/util.lua"
require "/items/active/weapons/weapon.lua"
-- whip primary attack plus swinging from torches like a boss
SuperWhipCrack = WeaponAbility:new()
function SuperWhipCrack:init()
self.damageConfig.baseDamage = self.chainDps * self.fireTime
self.weapon:setStance(self.stances.idle)
animator.setAnimationState("attack", "idle")
activeItem.setScriptedAnimationParameter("chains", nil)
self.cooldownTimer = self:cooldownTime()
self.weapon.onLeaveAbility = function()
self.weapon:setStance(self.stances.idle)
end
self.projectileConfig = self.projectileConfig or {}
self.chain = config.getParameter("chain")
self.anchorObjects = config.getParameter("anchorObjects", {"torch"})
self.anchor = nil
self.snapDistance = config.getParameter("snapDistance", 3.0)
end
-- Ticks on every update regardless if this is the active ability
function SuperWhipCrack:update(dt, fireMode, shiftHeld)
WeaponAbility.update(self, dt, fireMode, shiftHeld)
self.cooldownTimer = math.max(0, self.cooldownTimer - self.dt)
if self.fireMode == "primary" and self:canStartAttack() then
self:setState(self.windup)
self.fireHeld = true
elseif self.fireMode ~= "primary" and self.fireHeld then
self.fireHeld = false
self:disconnect()
end
end
function SuperWhipCrack:canStartAttack()
return not self.weapon.currentAbility and self.cooldownTimer == 0
end
-- State: windup
function SuperWhipCrack:windup()
self.weapon:setStance(self.stances.windup)
animator.setAnimationState("attack", "windup")
util.wait(self.stances.windup.duration)
self:setState(self.extend)
end
-- State: extend
function SuperWhipCrack:extend()
self.weapon:setStance(self.stances.extend)
animator.setAnimationState("attack", "extend")
animator.playSound("swing")
util.wait(self.stances.extend.duration)
if self.fireHeld then
self.anchor = self:findAnchor()
end
if self.anchor then
animator.setAnimationState("attack", "fire")
self:setState(self.swing)
else
animator.setAnimationState("attack", "fire")
self:setState(self.fire)
end
end
-- State: swing
function SuperWhipCrack:swing()
self.weapon:setStance(self.stances.swing)
self.weapon:updateAim()
self.cooldownTimer = self:cooldownTime()
while self.anchor do
if world.entityExists(self.anchor) then
local chainEndPos = vec2.add(world.entityPosition(self.anchor), {0.5, 0.5})
local chainStartPos = vec2.add(mcontroller.position(), activeItem.handPosition(self.chain.startOffset))
if not world.lineCollision(chainStartPos, chainEndPos) then
local aimVector = world.distance(chainEndPos, chainStartPos)
local swingAngle = vec2.angle(aimVector)
if not mcontroller.onGround() then
mcontroller.controlApproachVelocityAlongAngle(swingAngle, 0, 1000, true)
else
mcontroller.controlModifiers({movementSuppressed = true})
end
if self.weapon.aimDirection < 0 then
self.weapon.aimAngle = vec2.angle({-aimVector[1], aimVector[2]})
else
self.weapon.aimAngle = swingAngle
end
self.weapon:updateAim()
self.chain.endPosition = chainEndPos
activeItem.setScriptedAnimationParameter("chains", {self.chain})
coroutine.yield()
else
self:disconnect()
end
else
self:disconnect()
end
end
end
function SuperWhipCrack:disconnect()
self.anchor = nil
animator.setAnimationState("attack", "idle")
self.chain.endPosition = nil
activeItem.setScriptedAnimationParameter("chains", nil)
end
-- State: fire
function SuperWhipCrack:fire()
self.weapon:setStance(self.stances.fire)
self.weapon:updateAim()
local chainStartPos = vec2.add(mcontroller.position(), activeItem.handPosition(self.chain.startOffset))
local chainLength = world.magnitude(chainStartPos, activeItem.ownerAimPosition())
chainLength = math.min(self.chain.length[2], math.max(self.chain.length[1], chainLength))
self.chain.endOffset = vec2.add(self.chain.startOffset, {chainLength, 0})
local collidePoint = world.lineCollision(chainStartPos, vec2.add(mcontroller.position(), activeItem.handPosition(self.chain.endOffset)))
if collidePoint then
chainLength = world.magnitude(chainStartPos, collidePoint) - 0.25
if chainLength < self.chain.length[1] then
animator.setAnimationState("attack", "idle")
return
else
self.chain.endOffset = vec2.add(self.chain.startOffset, {chainLength, 0})
end
end
local chainEndPos = vec2.add(mcontroller.position(), activeItem.handPosition(self.chain.endOffset))
activeItem.setScriptedAnimationParameter("chains", {self.chain})
animator.resetTransformationGroup("endpoint")
animator.translateTransformationGroup("endpoint", self.chain.endOffset)
animator.burstParticleEmitter("crack")
animator.playSound("crack")
self.projectileConfig.power = self:crackDamage()
self.projectileConfig.powerMultiplier = activeItem.ownerPowerMultiplier()
local projectileAngle = vec2.withAngle(self.weapon.aimAngle)
if self.weapon.aimDirection < 0 then projectileAngle[1] = -projectileAngle[1] end
world.spawnProjectile(
self.projectileType,
chainEndPos,
activeItem.ownerEntityId(),
projectileAngle,
false,
self.projectileConfig
)
util.wait(self.stances.fire.duration, function()
if self.damageConfig.baseDamage > 0 then
self.weapon:setDamage(self.damageConfig, {self.chain.startOffset, {self.chain.endOffset[1] + 0.75, self.chain.endOffset[2]}}, self.fireTime)
end
end)
animator.setAnimationState("attack", "idle")
activeItem.setScriptedAnimationParameter("chains", nil)
self.cooldownTimer = self:cooldownTime()
end
function SuperWhipCrack:cooldownTime()
return self.fireTime - (self.stances.windup.duration + self.stances.extend.duration + self.stances.fire.duration)
end
function SuperWhipCrack:uninit(unloaded)
self.weapon:setDamage()
activeItem.setScriptedAnimationParameter("chains", nil)
end
function SuperWhipCrack:chainDamage()
return (self.chainDps * self.fireTime) * config.getParameter("damageLevelMultiplier")
end
function SuperWhipCrack:crackDamage()
return (self.crackDps * self.fireTime) * config.getParameter("damageLevelMultiplier")
end
function SuperWhipCrack:findAnchor()
local objectsNearCursor = world.objectQuery(activeItem.ownerAimPosition(), 5, {boundMode = "metaboundbox", order = "nearest"})
if #objectsNearCursor > 0 then
local objectName = world.entityName(objectsNearCursor[1])
local anchorValid = false
for _, anchorObject in pairs(self.anchorObjects) do
if anchorObject == objectName then
anchorValid = true
break
end
end
if anchorValid then
local pos = vec2.add(world.entityPosition(objectsNearCursor[1]), {0.5, 0.5})
local distToCursor = world.magnitude(pos, activeItem.ownerAimPosition())
local distToHand = world.magnitude(pos, vec2.add(mcontroller.position(), activeItem.handPosition(self.chain.startOffset)))
if distToCursor <= self.snapDistance and distToHand <= self.chain.length[2] and distToHand >= self.chain.length[1] then
return objectsNearCursor[1]
end
end
end
end

View file

@ -0,0 +1,109 @@
{
"itemName" : "testwhip",
"level" : 3,
"maxStack" : 1,
"rarity" : "legendary",
"description" : "Get cracking!",
"shortdescription" : "Test Whip",
"tooltipKind" : "sword",
"weaponType" : "Whip",
"twoHanded" : true,
"itemTags" : ["weapon"],
"inventoryIcon" : "testwhip.png:idle",
"animation" : "whip.animation",
"animationParts" : {
"weapon" : "testwhip.png",
"weaponFullbright" : ""
},
"animationCustom" : {
"particleEmitters" : { "crack" : { "particles" : [ ]}},
"sounds" : {
"swing" : [ "/sfx/melee/swing_dagger.ogg" ],
"crack" : [ "/sfx/gun/pistol1.ogg" ]
}
},
"animationScripts" : [
"/items/active/effects/chain.lua"
],
"chain" : {
"startOffset" : [0.625, 0.125],
"length" : [3, 15],
"segmentImage" : "/items/active/weapons/whip/chainlink3.png",
"segmentSize" : 0.375
},
"scripts" : [ "whip.lua" ],
"primaryAbility" : {
"scripts" : ["/items/active/weapons/whip/superwhipcrack.lua"],
"class" : "SuperWhipCrack",
"fireTime" : 1.0,
"chainDps" : 10.0,
"crackDps" : 20.0,
"damageConfig" : {
"statusEffects" : [ ],
"damageSourceKind" : "lash",
"timeoutGroup" : "primary",
"timeout" : 0.3
},
"projectileType" : "whipcrackphysical",
"projectileConfig" : {},
"stances" : {
"idle" : {
"armRotation" : -90,
"weaponRotation" : 0,
"weaponRotationCenter" : [0.0, 0.0],
"weaponOffset" : [-0.375, 0.625],
"allowRotate" : true,
"allowFlip" : true
},
"windup" : {
"duration" : 0.07,
"armRotation" : 100,
"weaponRotation" : 0,
"weaponRotationCenter" : [0.0, 0.0],
"weaponOffset" : [-0.375, 0.625],
"allowRotate" : true,
"allowFlip" : true
},
"extend" : {
"duration" : 0.07,
"armRotation" : 0,
"weaponRotation" : -90,
"weaponRotationCenter" : [0.0, 0.0],
"weaponOffset" : [-0.25, 0.875],
"allowRotate" : false,
"allowFlip" : false
},
"swing" : {
"armRotation" : 0,
"weaponRotation" : -90,
"weaponRotationCenter" : [0.0, 0.0],
"weaponOffset" : [-0.25, 0.875],
"allowRotate" : false,
"allowFlip" : false
},
"fire" : {
"duration" : 0.1,
"armRotation" : 0,
"weaponRotation" : -90,
"weaponRotationCenter" : [0.0, 0.0],
"weaponOffset" : [-0.25, 0.875],
"allowRotate" : false,
"allowFlip" : false
}
}
},
"builder" : "/items/buildscripts/buildwhip.lua"
}

View file

@ -0,0 +1,11 @@
{
"frameGrid" : {
"size" : [32, 32],
"dimensions" : [4, 2],
"names" : [
[ "idle", "windup.1", "windup.2", "windup.3" ],
[ "extend.1", "extend.2", "extend.3", "fire" ]
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B