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,170 @@
--------------------------------------------------------------------------------
function init()
self.sensors = sensors.create()
self.minions = {}
for i = 1, entity.configParameter("throwMaxMinions") do
table.insert(self.minions, 0)
end
self.state = stateMachine.create({
"moveState",
"throwAttack",
"shoutAttack"
})
self.state.enteringState = function(stateName)
self.state.shuffleStates()
end
self.state.leavingState = function(stateName)
entity.setAnimationState("movement", "idle")
end
entity.setAggressive(false)
entity.setAnimationState("movement", "idle")
end
--------------------------------------------------------------------------------
function update(dt)
self.position = mcontroller.position()
if util.trackTarget(entity.configParameter("targetNoticeRadius")) then
entity.setAggressive(true)
self.state.pickState()
elseif self.targetId == nil then
entity.setAggressive(false)
end
self.state.update(dt)
self.sensors.clear()
end
--------------------------------------------------------------------------------
function damage(args)
if entity.health() > 0 then
if args.sourceId ~= self.targetId then
self.targetId = args.sourceId
self.targetPosition = world.entityPosition(self.targetId)
self.state.pickState()
end
end
end
--------------------------------------------------------------------------------
function move(direction)
entity.setAnimationState("movement", "walk")
mcontroller.controlMove(direction, true)
end
--------------------------------------------------------------------------------
function hasTarget()
return self.targetId ~= nil
end
--------------------------------------------------------------------------------
moveState = {}
function moveState.enter()
if hasTarget() then return nil end
return {
timer = entity.randomizeParameterRange("moveTimeRange"),
direction = util.randomDirection()
}
end
function moveState.update(dt, stateData)
if self.sensors.blockedSensors.collision.any(true) then
stateData.direction = -stateData.direction
end
move(stateData.direction)
stateData.timer = stateData.timer - dt
if stateData.timer <= 0 then
return true, entity.configParameter("moveCooldown")
end
return false
end
--------------------------------------------------------------------------------
throwAttack = {}
function throwAttack.enter()
if not hasTarget() then return nil end
for minionIndex, minionId in ipairs(self.minions) do
if minionId == 0 or not world.entityExists(minionId) then
return {
minionIndex = minionIndex,
timer = entity.configParameter("throwStartTime")
}
end
end
return nil
end
function throwAttack.update(dt, stateData)
if not hasTarget() then return true end
local toTarget = world.distance(self.targetPosition, self.position)
mcontroller.controlFace(toTarget[1])
if world.magnitude(toTarget) > entity.configParameter("throwMaxDistance") then
move(toTarget[1])
else
entity.setAnimationState("movement", "throw")
stateData.timer = stateData.timer - dt
if stateData.timer <= 0 then
if stateData.thrown then
return true, entity.configParameter("throwCooldown")
else
local entityId = world.spawnMonster("micropo", entity.toAbsolutePosition(entity.configParameter("throwSpawnOffset")))
world.callScriptedEntity(entityId, "setSpawnDirection", mcontroller.facingDirection())
self.minions[stateData.minionIndex] = entityId
stateData.thrown = true
stateData.timer = entity.configParameter("throwEndTime")
end
end
end
return false
end
--------------------------------------------------------------------------------
shoutAttack = {}
function shoutAttack.enter()
if not hasTarget() then return nil end
return {}
end
function shoutAttack.update(dt, stateData)
if not hasTarget() then return true end
local toTarget = world.distance(self.targetPosition, self.position)
mcontroller.controlFace(toTarget[1])
if world.magnitude(toTarget) > entity.configParameter("shoutMaxDistance") then
move(toTarget[1])
return false
else
entity.setAnimationState("movement", "ranged")
-- entity.setFireDirection(entity.configParameter("shoutProjectileOffset"), toTarget)
local projectile = entity.animationStateProperty("movement", "projectile")
if projectile ~= nil then
-- entity.startFiring(projectile)
else
-- entity.stopFiring()
end
return entity.animationState("movement") == "idle"
end
end

View file

@ -0,0 +1,9 @@
{
"name" : "body",
"category" : "toxicgolem",
"type" : "body",
"frames" : {
"body" : "toxicgolem.png"
}
}

View file

@ -0,0 +1,14 @@
{
"frameGrid" : {
"size" : [36, 40],
"dimensions" : [9, 5],
"names" : [
[ null, "idle.1", "idle.2", "idle.3", "idle.4", null, null, null, null ],
[ null, "jump.1", "jump.2", "jump.3", "jump.4", null, null, null, null ],
[ null, "throw.1", "throw.2", "throw.3", "throw.4", null, null, null, null ],
[ null, "walk.1", "walk.2", "walk.3", "walk.4", "walk.5", "walk.6", "walk.7", "walk.8" ],
[ null, "ranged.1", "ranged.2", "ranged.3", "ranged.4", "ranged.5", "ranged.6", "ranged.7", "ranged.8" ]
]
}
}

View file

@ -0,0 +1,273 @@
{
"animatedParts" : {
"stateTypes" : {
"movement" : {
"priority" : 0,
"default" : "idle",
"states" : {
"idle" : {
"frames" : 4,
"mode" : "loop"
},
"jump" : {
"frames" : 4,
"mode" : "loop"
},
"throw" : {
"frames" : 4,
"mode" : "end"
},
"walk" : {
"frames" : 8,
"mode" : "loop"
},
"ranged" : {
"frames" : 8,
"mode" : "transition",
"transition" : "idle",
"frameProperties" : {
"projectile" : [ null, null, null, null, "poopBurst", null, null, null ]
}
}
}
}
},
"parts" : {
"body" : {
"partStates" : {
"movement" : {
"idle" : {
"properties" : {
"image" : "<partImage>:idle.<frame>"
}
},
"jump" : {
"properties" : {
"image" : "<partImage>:jump.<frame>"
}
},
"throw" : {
"properties" : {
"image" : "<partImage>:throw.<frame>"
}
},
"walk" : {
"properties" : {
"image" : "<partImage>:walk.<frame>"
}
},
"ranged" : {
"properties" : {
"image" : "<partImage>:ranged.<frame>"
}
}
}
}
}
}
},
"particleEmitters" : {
"damage" : {
"emissionRate" : 0.7,
"particles" : [
]
},
"deathPoof" : {
"particles" : [
{
"particle" : {
"type" : "animated",
"animation" : "/animations/puff2c/puff2c.animation",
"size" : 1,
"angularVelocity" : 35,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [0, 0],
"finalVelocity" : [0, 0],
"approach" : [1, 1],
"timeToLive" : 0.4,
"layer" : "middle"
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz1/fizz1.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [-8, 8],
"finalVelocity" : [-3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [-4, 2],
"finalVelocity" : [-3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz1/fizz1.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [8, 8],
"finalVelocity" : [3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [4, 2],
"finalVelocity" : [3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz2/fizz2.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [-8, 8],
"finalVelocity" : [-3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [-4, 2],
"finalVelocity" : [-3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz2/fizz2.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [8, 8],
"finalVelocity" : [3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [4, 2],
"finalVelocity" : [3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz3/fizz3.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [-8, 8],
"finalVelocity" : [-3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [-4, 2],
"finalVelocity" : [-3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz3/fizz3.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [8, 8],
"finalVelocity" : [3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [4, 2],
"finalVelocity" : [3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz4/fizz4.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [-8, 8],
"finalVelocity" : [-3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [-4, 2],
"finalVelocity" : [-3, -4]
}
}
},
{
"particle" : {
"type" : "animated",
"animation" : "/animations/fizz4/fizz4.animation",
"size" : 1,
"angularVelocity" : 20,
"fade" : 1,
"destructionTime" : 7,
"position" : [0, 0],
"initialVelocity" : [8, 8],
"finalVelocity" : [3, -4],
"approach" : [15, 15],
"timeToLive" : 3.45,
"layer" : "middle",
"variance" : {
"initialVelocity" : [4, 2],
"finalVelocity" : [3, -4]
}
}
}
]
}
},
"effects" : {
"blink" : {
"type" : "flash",
"time" : 0.25,
"directives" : "fade=ffffff;0.5"
}
},
"sounds" : {
"turnHostile" : [ ],
"deathPuff" : [ "/sfx/npc/enemydeathpuff.ogg" ]
}
}

View file

@ -0,0 +1,121 @@
{
"type" : "toxicgolem",
"categories" : [ "toxicgolem" ],
"parts" : [ "body" ],
"animation" : "toxicgolem.animation",
"reversed" : true,
"dropPools" : [ "noMeatMonsterTreasure" ],
"baseParameters" : {
"scripts" : [
"/monsters/dungeon/toxicgolem/behavior.lua",
"/scripts/sensors.lua",
"/scripts/stateMachine.lua",
"/scripts/util.lua",
"/scripts/vec2.lua"
],
"metaBoundBox" : [-1.625, -2.375, 1.75, 2.0],
"scale" : 1.0,
"movementSettings" : {
"collisionPoly" : [ [-1.625, -2.375], [1.75, -2.375], [1.75, 2.0], [-1.625, 2.0] ],
"mass" : 1.0,
"walkSpeed" : 3,
"runSpeed" : 6,
"flySpeed" : 15,
"airJumpProfile" : {
"jumpSpeed" : 20.0
}
},
"bodyMaterialKind" : "organic",
"knockoutTime" : 0.1,
"knockoutEffect" : "blink",
"deathParticles" : "deathPoof",
"touchDamage" : {
"poly" : [ [-1.625, -2.375], [1.75, -2.375], [1.75, 2.0], [-1.625, 2.0] ],
"damage" : 15,
"teamType" : "enemy",
"damageSourceKind" : "lash",
"statusEffects" : [ ]
},
"dropPools" : [ "potreasure" ],
"statusSettings" : {
"statusProperties" : {
"targetMaterialKind" : "organic"
},
"appliesEnvironmentStatusEffects" : false,
"minimumLiquidStatusEffectPercentage" : 0.1,
"primaryScriptSources" : [
"/stats/monster_primary.lua"
],
"primaryScriptDelta" : 5,
"stats" : {
"knockbackStunTime" : {
"baseValue" : 0.25
},
"knockbackThreshold" : {
"baseValue" : 10
},
"maxHealth" : {
"baseValue" : 72
},
"protection" : {
"baseValue" : 1.0
},
"healthRegen" : {
"baseValue" : 0.0
},
"poisonImmunity" : {
"baseValue" : 1.0
}
},
"resources" : {
"stunned" : {
"deltaValue" : -1.0,
"initialValue" : 0.0
},
"health" : {
"maxStat" : "maxHealth",
"deltaStat" : "healthRegen",
"defaultPercentage" : 100
}
}
},
"mouthOffset" : [0, 0],
"feetOffset" : [0, -8],
"blockedSensors" : [ [3, -2], [3, -1], [3, 0], [3, 1], [3, 1.5] ],
"moveTimeRange" : [2.5, 5.0],
"moveCooldown" : 2.0,
"targetNoticeRadius" : 30,
"throwMaxDistance" : 15,
"throwMaxMinions" : 5,
"throwStartTime" : 0.5,
"throwEndTime" : 0.5,
"throwSpawnOffset" : [1.875, 1],
"throwCooldown" : 5,
"shoutMaxDistance" : 10,
"shoutProjectileOffset" : [0.875, 0.75]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB