yes, I have played mods with custom features, but I've never seen one where they made brand new traits and character classes.
I played mods with custom weapons, and mods where some monsters that give 0 experience points
what i'm triyng to do is have predefined charactes in my mod that fit classic horror movie tropes.
.
and the "slasher villain" will be played by the skeleton commander, a boss that appears several times through my mod. but I want to alter him so that he no longer drops the long swords on death.
the asset pack has a monster definition .lua file for skeleton commander and it looks liek this
Code: Select all
defineObject{
name = "skeleton_commander",
baseObject = "base_monster",
components = {
{
class = "Model",
model = "assets/models/monsters/skeleton_knight_commander.fbx",
storeSourceData = true, -- must be enabled for mesh particles to work
},
{
class = "Animation",
animations = {
idle = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_idle.fbx",
moveForward = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack.fbx",
attack2 = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack2.fbx",
moveAttack = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_move_attack.fbx",
rangedAttack = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_ranged_attack.fbx",
summonUndead = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_summon_undead.fbx",
turnAttackLeft = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_attack_left.fbx",
turnAttackRight = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_attack_right.fbx",
turnAroundAttack = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_around_attack.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_get_hit_front_left.fbx",
},
currentLevelOnly = true,
onAnimationEvent = function(self, event)
if event == "summon_undead_begin" then
self.go.handLeftParticle:restart()
self.go.handRightParticle:restart()
self.go.spellLight:fadeIn(2.7)
elseif event == "summon_undead_end" then
self.go.spellLight:fadeOut(0.1)
end
end,
},
{
class = "Monster",
meshName = "skeleton_knight_commander_mesh",
footstepSound = "skeleton_footstep",
hitSound = "skeleton_hit",
dieSound = "skeleton_die",
hitEffect = "hit_dust",
capsuleHeight = 0.7,
capsuleRadius = 0.25,
collisionRadius = 0.6,
health = 900,
protection = 15,
evasion = 0,
immunities = { "sleep", "blinded", "frozen" },
resistances = {
["poison"] = "immune",
["shock"] = "weak",
},
traits = { "undead" },
exp = 750,
lootDrop = { 100, "long_sword", 100, "long_sword" },
},
{
class = "SkeletonCommanderBrain",
name = "brain",
sight = 6,
allAroundSight = true,
morale = 100, -- fearless
},
{
class = "MonsterMove",
name = "move",
sound = "skeleton_commander_walk",
cooldown = 2,
},
{
class = "MonsterTurn",
name = "turn",
sound = "skeleton_commander_walk",
},
{
class = "MonsterAttack",
name = "basicAttack",
attackPower = 20,
accuracy = 30,
pierce = 20,
woundChance = 25,
cooldown = 4,
sound = "skeleton_commander_attack",
onBeginAction = function(self)
-- randomize animation
if math.random() < 0.5 then
self:setAnimation("attack")
else
self:setAnimation("attack2")
end
end,
},
{
class = "MonsterAttack",
name = "turnAttack",
attackPower = 30,
accuracy = 30,
pierce = 20,
woundChance = 25,
cooldown = 0,
sound = "skeleton_commander_turn_attack",
turnToAttackDirection = true,
},
{
class = "MonsterAttack",
name = "rangedAttack",
attackPower = 30,
cooldown = 15,
animation = "rangedAttack",
sound = "skeleton_commander_ice_shards",
onAttack = function(self)
-- cast ice shards
local dx,dy = getForward(self.go.facing)
local spell = spawn("ice_shards", self.go.level, self.go.x + dx, self.go.y + dy, self.go.facing, self.go.elevation)
spell.iceshards:setRange(5)
spell.tiledamager:setAttackPower(32)
end,
},
{
class = "MonsterMoveAttack",
name = "moveAttack",
attackPower = 30,
accuracy = 50,
pierce = 20,
woundChance = 25,
cooldown = 6,
animation = "moveAttack",
sound = "skeleton_commander_move_attack",
},
{
class = "MonsterAttack",
name = "summonUndead",
cooldown = 80,
repeatChance = 0,
animation = "summonUndead",
sound = "skeleton_commander_summon_spell",
onAttack = function(self)
for tries=1,20 do
-- choose summon location
local dx,dy = getForward(self.go.facing)
local x = self.go.x + math.random(-1,1)
local y = self.go.y + math.random(-1,1)
-- is valid spawn point?
local map = self.go.map
local elevation = map:getElevation(x, y)
if not map:isBlocked(x, y, elevation) then
spawn("undead", self.go.level, x, y, self.go.facing, elevation)
return
end
end
end,
},
{
class = "Particle",
name = "handLeftParticle",
parentNode = "hand_left",
particleSystem = "skeleton_commander_spell",
offset = vec(0.1, 0, 0),
enabled = false,
},
{
class = "Particle",
name = "handRightParticle",
parentNode = "hand_right",
particleSystem = "skeleton_commander_spell",
offset = vec(0.1, 0, 0),
enabled = false,
},
{
class = "Light",
name = "spellLight",
parentNode = "spine1",
offset = vec(0.4, 0, 0.25),
--debugDraw = true,
color = vec(0.45,0.6,1),
brightness = 8,
range = 4,
fadeOut = 0,
fillLight = true,
},
},
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack.fbx",
event = "attack",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack.fbx",
event = "attack",
frame = 23,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack2.fbx",
event = "attack",
frame = 8,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_attack2.fbx",
event = "attack",
frame = 18,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_attack_left.fbx",
event = "attack",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_attack_right.fbx",
event = "attack",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_around_attack.fbx",
event = "attack",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_ranged_attack.fbx",
event = "attack",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_move_attack.fbx",
event = "move_forward",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_move_attack.fbx",
event = "attack",
frame = 19,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_move_attack.fbx",
event = "attack",
frame = 26,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_summon_undead.fbx",
event = "summon_undead_begin",
frame = 80,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_summon_undead.fbx",
event = "summon_undead_end",
frame = 155,
}
for i=0,2 do
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_summon_undead.fbx",
event = "attack",
frame = 155 + i * 10,
}
end
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_walk.fbx",
event = "footstep",
frame = 13,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_walk.fbx",
event = "footstep",
frame = 26,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_walk.fbx",
event = "footstep",
frame = 42,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_walk.fbx",
event = "footstep",
frame = 53,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_left.fbx",
event = "footstep",
frame = 12,
}
defineAnimationEvent{
animation = "assets/animations/monsters/skeleton_knight_commander/skeleton_knight_commander_turn_right.fbx",
event = "footstep",
frame = 12,
}
defineParticleSystem{
name = "skeleton_commander_spell",
emitters = {
-- fog
{
spawnBurst = true,
emissionTime = 0,
maxParticles = 3,
boxMin = {0.0, 0.0, 0.0},
boxMax = {0.0, 0.0, 0.0},
sprayAngle = {0,360},
velocity = {0.0,0.0},
objectSpace = true,
texture = "assets/textures/particles/fog.tga",
lifetime = {3,3},
color0 = {0.14, 0.352941, 0.803922},
opacity = 0.6,
fadeIn = 3,
fadeOut = 0.5,
size = {0.2, 0.6},
gravity = {0,0,0},
airResistance = 0.1,
rotationSpeed = 3,
blendMode = "Additive",
depthBias = -0.005,
},
-- stars
{
emissionRate = 25,
emissionTime = 2.7,
maxParticles = 1000,
boxMin = {-0.1, -0.1, -0.1},
boxMax = { 0.1, 0.1, 0.1},
sprayAngle = {0,360},
velocity = {0.5,2},
objectSpace = false,
texture = "assets/textures/particles/teleporter.tga",
lifetime = {0.1,0.15},
color0 = {2.0,2.0,3.0},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.1,
size = {0.05, 0.5},
gravity = {0,0,0},
airResistance = 5,
rotationSpeed = 2,
blendMode = "Additive",
},
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,0.0},
boxMax = {0,0,0.0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {2.8, 2.8},
colorAnimation = false,
color0 = {0.35,0.45,0.75},
opacity = 1,
fadeIn = 3.5,
fadeOut = 0.1,
size = {0.5, 0.5},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 2,
blendMode = "Additive",
objectSpace = true,
depthBias = -0.005,
},
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,0.0},
boxMax = {0,0,0.0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {2.8, 2.8},
colorAnimation = false,
color0 = {0.35,0.45,0.75},
opacity = 0.3,
fadeIn = 3.5,
fadeOut = 0.1,
size = {1.5, 1.5},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 2,
blendMode = "Additive",
objectSpace = true,
}
}
}
defineSound{
name = "skeleton_commander_walk",
filename = {
"assets/samples/monsters/skeleton_walk_01.wav",
"assets/samples/monsters/skeleton_walk_01.wav",
"assets/samples/monsters/skeleton_walk_01.wav",
"assets/samples/monsters/skeleton_commander_walk_01.wav",
"assets/samples/monsters/skeleton_commander_walk_02.wav",
},
loop = false,
volume = 1,
minDistance = 1,
maxDistance = 10,
}
defineSound{
name = "skeleton_commander_attack",
filename = "assets/samples/monsters/skeleton_commander_attack_01.wav",
loop = false,
volume = 1,
minDistance = 1,
maxDistance = 10,
}
defineSound{
name = "skeleton_commander_ice_shards",
filename = "assets/samples/monsters/skeleton_commander_attack_01.wav",
loop = false,
volume = 1,
minDistance = 1,
maxDistance = 10,
}
defineSound{
name = "skeleton_commander_turn_attack",
filename = "assets/samples/monsters/skeleton_commander_turn_attack_01.wav",
loop = false,
volume = 1,
minDistance = 1,
maxDistance = 10,
}
defineSound{
name = "skeleton_commander_move_attack",
filename = "assets/samples/monsters/skeleton_commander_move_attack_01.wav",
loop = false,
volume = 1,
minDistance = 3,
maxDistance = 10,
}
defineSound{
name = "skeleton_commander_summon_spell",
filename = "assets/samples/monsters/skeleton_commander_summon_spell_01.wav",
loop = false,
volume = 1,
minDistance = 5,
maxDistance = 13,
}
do I have to paste that ENTIRE thing into my custom monsters .lua? just to change that one line with the loot drops?
and i still have confusion about the classes, where is the line that defines what custom graphic to use for the class traits?