berserker trait?
berserker trait?
Does anyone know how to add +40 damage, with any melee weapon, in a trait?
like the aggressive trait.
I want to make a berserker skill, which at 5th level gives the berserker trait
like the aggressive trait.
I want to make a berserker skill, which at 5th level gives the berserker trait
Re: berserker trait?
You can't. Aggressive trait is hardcoded, there is no way for modders to give attack power bonuses.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: berserker trait?
arghh!minmay wrote:You can't. Aggressive trait is hardcoded, there is no way for modders to give attack power bonuses.

well then is there a way to simply increase damage to any weapons, by percentage?
Re: berserker trait?
No. Again, there is no way for modders to give attack power bonuses.
If you really, absolutely must, increase attack power, the best approach (the only remotely workable approach, in fact) is to iterate through champions' hands every frame and modify the attackPower field of wielded weapons. The easiest way is with a TimerComponent attached to the party with an interval of 0.0001 or similar (TimerComponent only activates once per update at most, so this does not waste any resources). You'll want to reset the attack power when the weapon is unwielded of course, so you want an onUnequipItem hook on every weapon as well.
If you really, absolutely must, increase attack power, the best approach (the only remotely workable approach, in fact) is to iterate through champions' hands every frame and modify the attackPower field of wielded weapons. The easiest way is with a TimerComponent attached to the party with an interval of 0.0001 or similar (TimerComponent only activates once per update at most, so this does not waste any resources). You'll want to reset the attack power when the weapon is unwielded of course, so you want an onUnequipItem hook on every weapon as well.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: berserker trait?
argh this is to much complicated for me.
I finally do something, based on Akroma/Drakkan custom traits:
this thread is a gold mine!
viewtopic.php?f=22&t=8976&hilit=axe+master+trait
I ve modified the axe trait/skill and keep the bonus it add at 3rd and 5th levels. That give more damage with any melee weapon (or any weapon that have a specific onAttack hook)
the editor script called weaponModManager:
(I did not rename the axe traits into berserker traits, and I completely quoted the mace stuff)
I'm not 100% sure that I don't made some errors, but there is no crash in the editor or in the game. Please can someone check?
In fact I did not do much more, I just quoted the mace stuff that I don't need, and added some line between the quadruple comma
I don't understand the last part of the script with the stun stuff, but if the stun is here, should I need to make something similar for other power attack?
The berzerker skill/traits, is this "balanced", too strong or lack of something? Any comment is welcome.
note: in the traits I reduce the fire resistance, that is normally given with the strength. I did that intentionally, to negate the fire resistance of the party, given by the 4 in strength for each level.
a weapon for exemple:
I finally do something, based on Akroma/Drakkan custom traits:
this thread is a gold mine!

viewtopic.php?f=22&t=8976&hilit=axe+master+trait
I ve modified the axe trait/skill and keep the bonus it add at 3rd and 5th levels. That give more damage with any melee weapon (or any weapon that have a specific onAttack hook)
the editor script called weaponModManager:
(I did not rename the axe traits into berserker traits, and I completely quoted the mace stuff)
I'm not 100% sure that I don't made some errors, but there is no crash in the editor or in the game. Please can someone check?
In fact I did not do much more, I just quoted the mace stuff that I don't need, and added some line between the quadruple comma
SpoilerShow
Code: Select all
-------------------------------------------------------- Trait lists
TRAIT_LIST = {
woodcutter = true,
master_axeman = true,
grandmaster_axeman = true--,
-- skullcrusher = true,
-- master_maceman = true,
-- grandmaster_maceman = true
}
axe_TRAITS = {
woodcutter = true,
master_axeman = true,
grandmaster_axeman = true
}
-- mace_TRAITS = {
-- skullcrusher = true,
-- master_maceman = true,
-- grandmaster_maceman = true
-- }
--------------------------------------------------------- Modifier list
modList = {}
----------------------------------------------------------gatherModifierTraits(self, champion, weapontype1, weapontype2)
function gatherModifierTraits(self, champion, weapontype1, weapontype2)
local c = party.party:getChampion(champion)
----
---- this has been modified by adding sword, mace and dagger
if weapontype1 == "axe"
or weapontype2 == "axe"
or weapontype1 == "sword"
or weapontype2 == "sword"
or weapontype1 == "mace"
or weapontype2 == "mace"
or weapontype1 == "dagger"
or weapontype2 == "dagger" then
----
for trait,dummy in pairs(axe_TRAITS) do
if c:hasTrait(trait) then
modList[trait] = 1
print(modList[trait])
else
modList[trait] = nil
print(modList[trait])
end
end
end
-- if weapontype1 == "mace"
-- or weapontype2 == "mace" then
-- for trait,dummy in pairs(mace_TRAITS) do
-- if c:hasTrait(trait) then
-- modList[trait] = 1
-- print(modList[trait])
-- else
-- modList[trait] = nil
-- print(modList[trait])
-- end
-- end
-- end
end
---------------------------------------------------------addWeaponModifiers(self, champion, weapontype1, weapontype2)
trueAttack = 0
-- truePierce = 1
function addWeaponModifiers(self, champion, weapontype1, weapontype2)
local c = party.party:getChampion(champion)
trueAttack = self:getAttackPower()
-- truePierce = self:getPierce()
-- if truePierce == nil then
-- print("you must define weapon with 'pierce = 0'")
-- print("pierce = 1")
-- truePierce = 1
-- end
gatherModifierTraits(weaponName, champion, weapontype1, weapontype2)
----
if weapontype1 == "axe"
or weapontype2 == "axe"
or weapontype1 == "sword"
or weapontype2 == "sword"
or weapontype1 == "mace"
or weapontype2 == "mace"
or weapontype1 == "dagger"
or weapontype2 == "dagger" then
----
local cutterAttack = 0
local masterAttack = 0
local grandmasterAttack = 0
if modList["woodcutter"] == 1 then
local dx,dy = getForward(party.facing)
for i in party.map:entitiesAt(party.x + dx,party.y + dy) do
if i and i.monster then
if i.monster:hasTrait("plant") then
cutterAttack = 100
self:setAttackPower(trueAttack + cutterAttack + masterAttack + grandmasterAttack)
print(""..self:getAttackPower().."")
end
end
end
end
if modList["master_axeman"] == 1 then
masterAttack = 20
self:setAttackPower(trueAttack + cutterAttack + masterAttack + grandmasterAttack)
print(""..self:getAttackPower().."")
end
if modList["grandmaster_axeman"] == 1 then
grandmasterAttack = 50
self:setAttackPower(trueAttack + cutterAttack + masterAttack + grandmasterAttack)
print(""..self:getAttackPower().."")
end
end
-- if weapontype1 == "mace"
-- or weapontype2 == "mace" then
-- local crusherPierce = 0
-- local masterPierce = 0
-- local grandmasterPierce = 0
-- if modList["skullcrusher"] == 1 then
-- crusherPierce = 10
-- self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
-- print(""..self:getPierce().."")
-- end
-- if modList["master_maceman"] == 1 then
-- masterPierce = 20
-- self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
-- print(""..self:getPierce().."")
-- end
-- if modList["grandmaster_maceman"] == 1 then
-- grandmasterPierce = 50
-- self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
-- print(""..self:getPierce().."")
-- end
-- end
end
function removeWeaponModifiers(self, champion, weapontype1, weapontype2)
local c = party.party:getChampion(champion)
local aP = self:getAttackPower()
----
if weapontype1 == "axe"
or weapontype2 == "axe"
or weapontype1 == "sword"
or weapontype2 == "sword"
or weapontype1 == "mace"
or weapontype2 == "mace"
or weapontype1 == "dagger"
or weapontype2 == "dagger" then
----
for trait,dummy in pairs(axe_TRAITS) do
modList[trait] = nil
end
self:setAttackPower(trueAttack)
print(""..self:getAttackPower().."")
end
-- if weapontype1 == "mace"
-- or weapontype2 == "mace" then
-- for trait,dummy in pairs(mace_TRAITS) do
-- modList[trait] = nil
-- end
-- self:setPierce(truePierce)
-- print(""..self:getPierce().."")
-- end
end
-------------------------------------------------------------------------------------stunstrikeCleanup(champion, weapon, stun, stunChance)
function stunstrikeCleanup(champion, weapon, stun, stunChance)
local tempStunChance = weapon.go.meleeattack:getConditionChance("stunned")
if stun == false then
weapon.go.meleeattack:setCauseCondition("")
weapon.go.meleeattack:setConditionChance(0)
--print(weapon.go.meleeattack:getConditionChance())
else
weapon.go.meleeattack:setCauseCondition("stunned")
weapon.go.meleeattack:setConditionChance(stunChance)
--print(weapon.go.meleeattack:getConditionChance())
end
end
The berzerker skill/traits, is this "balanced", too strong or lack of something? Any comment is welcome.
SpoilerShow
Code: Select all
defineSkill{
name = "wayberserker",
uiName = "The Warrior",
priority = 200,
icon = 26,
description = "Trained as the Barbarian of Nix, you ignore fear and fight until death. Each level spent increase your critical skill by 2, your accuracy by 4 and your strength is increased by 4, also each level decrease your health by 10. On 3rd level you get a bonus in attack power of 20 with melee weapons. On 5th level you get a bonus of 40.",
onComputeCritChance = function(champion, weapon, attack, attackType, level)
return level * 2
end,
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("strength", level*4)
champion:addStatModifier("max_health", level*-10)
end
end,
traits = { [1] = "woodcutter", [2] = "apprentice_axeman", [3] = "expert_axeman", [4] = "master_axeman", [5] = "grandmaster_axeman"},
}
SpoilerShow
Code: Select all
defineTrait{
name = "woodcutter",
uiName = "Novice Warrior",
icon = 94,
description = "You started to learn how to make your ennemys fearing you.",
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("resist_fire", -8)
end
end,
}
defineTrait{
name = "apprentice_axeman",
uiName = "Monster's Head Spliter",
icon = 94,
description = "Spliting monster's heads is much better than lumbering wood.",
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("resist_fire", -8)
end
end,
}
defineTrait{
name = "expert_axeman",
uiName = "Expert Warrior",
icon = 94,
description = "You have been trained in expert fighting techniques and there are scary rumors among the monsters. You gain Attack Power +20 for any melee weapon.",
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("resist_fire", -8)
end
end,
}
defineTrait{
name = "master_axeman",
uiName = "Nix Warrior",
icon = 94,
description = "You have mastered the art of the warrior. Only one final training is needed to reach the rank of Berserker.",
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("resist_fire", -8)
end
end,
}
defineTrait{
name = "grandmaster_axeman",
uiName = "The Berzerker",
icon = 94,
description = "Finally after all this time spent on your training, you have become a Berzerker. Bonus + 40 to attack power!",
onRecomputeStats = function(champion, level)
if level > 0 then
champion:addStatModifier("resist_fire", -8)
end
end,
}
SpoilerShow
Code: Select all
defineObject{
name = "flail",
baseObject = "base_item",
components = {
{
class = "Model",
model = "assets/models/items/flail.fbx",
},
{
class = "Item",
uiName = "Flail",
gfxIndex = 87,
gfxIndexPowerAttack = 423,
impactSound = "impact_blunt",
weight = 6.5,
traits = { "heavy_weapon", "mace" },
},
{
class = "MeleeAttack",
attackPower = 24,
pierce = 10,
cooldown = 5,
swipe = "vertical",
attackSound = "swipe_heavy",
requirements = { "heavy_weapons", 3 },
powerAttackTemplate = "stun",
onAttack = function(self, champion, action, slot)
weaponModManager.script.addWeaponModifiers(self, champion:getOrdinal(), "axe")
delayedCall("weaponModManager", 0.2, "removeWeaponModifiers", self, champion:getOrdinal(), "axe")
end,
},
},
tags = { "weapon" },
}
Re: berserker trait?
Um, that method is terrible. It makes the attack power display wrong. That is a release breaker bug and completely inappropriate to use in a mod. Plus, the specific implementation doesn't even work, and I'm pretty sure it introduces a serialization error.
The method I described is extremely simple. Here is a plug-and-play version I wrote just for you:To make a weapon eligible for the traits, simply add the "berserker_weapon" trait and the following onUnequipItem hook:
So this is what your flail would look like:
This method is good performance-wise, keeps the attack power display correct, and doesn't cause serialization issues.
edit: added compensation for weapon skill bonuses, since it looks like you didn't want it to stack with those. Also, you probably want to add a note in the introduction to your dungeon that explains why weapons' attack power appears to jump around.
The method I described is extremely simple. Here is a plug-and-play version I wrote just for you:
Code: Select all
defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Timer",
name = "berserkerUpdateTimer",
timerInterval = 0.0001,
onActivate = function(self)
for champNum = 1,4 do
local champ = party.party:getChampion(champNum)
for slot=ItemSlot.Weapon,ItemSlot.OffHand do
local item = champ:getItem(slot)
if item and item:hasTrait("berserker_weapon") then
local attackClasses = {
FirearmAttackComponent = true,
MeleeAttackComponent = true,
RangedAttackComponent = true,
ThrowAttackComponent = true,
}
for _,comp in item.go:componentIterator() do
if attackClasses[comp:getClass()] then
local power
local weaponData = party.berserkerScript.get(item.go.id)
if weaponData then
power = weaponData[comp:getName()]
end
if not power then
power = comp:getAttackPower()
-- store original attack power
if weaponData then
weaponData[comp:getName()] = power
else
party.berserkerScript.set(item.go.id,{[comp:getName()]=power})
end
end
if champ:hasTrait("expert_axeman") then
local skillCompensationDiv = 1 -- compensate for weapon skill bonus
if item:hasTrait("heavy_weapon") then
skillCompensationDiv = skillCompensationDiv+champ:getSkillLevel("heavy_weapons")*0.2
end
if item:hasTrait("light_weapon") then
skillCompensationDiv = skillCompensationDiv+champ:getSkillLevel("light_weapons")*0.2
end
if item:hasTrait("missile_weapon") then
skillCompensationDiv = skillCompensationDiv+champ:getSkillLevel("missile_weapons")*0.2
end
power = power+20/skillCompensationDiv
if champ:hasTrait("grandmaster_axeman") then
power = power+20/skillCompensationDiv
end
end
comp:setAttackPower(power)
end
end
end
end
end
end,
},
{
class = "Script",
name = "berserkerScript",
source = [[
vars = {}
function set(key,val)
vars[key] = val
end
function get(key)
return vars[key]
end
function weaponUnequip(item,champion,slot)
if slot == ItemSlot.Weapon or slot == ItemSlot.OffHand then
-- reset attack power
local attackClasses = {
FirearmAttackComponent = true,
MeleeAttackComponent = true,
RangedAttackComponent = true,
ThrowAttackComponent = true,
}
for _,comp in item.go:componentIterator() do
if attackClasses[comp:getClass()] then
local weaponData = get(item.go.id)
if weaponData then
if weaponData[comp:getName()] then
comp:setAttackPower(weaponData[comp:getName()])
end
end
end
end
set(item.go.id,nil) -- remove stored weapon data
end
end]],
},
},
}
Code: Select all
onUnequipItem = function(self,champion,slot)
party.berserkerScript.weaponUnequip(self,champion,slot)
end,
Code: Select all
defineObject{
name = "flail",
baseObject = "base_item",
components = {
{
class = "Model",
model = "assets/models/items/flail.fbx",
},
{
class = "Item",
uiName = "Flail",
gfxIndex = 87,
gfxIndexPowerAttack = 423,
impactSound = "impact_blunt",
weight = 6.5,
traits = { "heavy_weapon", "mace", "berserker_weapon" },
onUnequipItem = function(self,champion,slot)
party.berserkerScript.weaponUnequip(self,champion,slot)
end,
},
{
class = "MeleeAttack",
attackPower = 24,
pierce = 10,
cooldown = 5,
swipe = "vertical",
attackSound = "swipe_heavy",
requirements = { "heavy_weapons", 3 },
powerAttackTemplate = "stun",
},
},
tags = { "weapon" },
}
edit: added compensation for weapon skill bonuses, since it looks like you didn't want it to stack with those. Also, you probably want to add a note in the introduction to your dungeon that explains why weapons' attack power appears to jump around.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: berserker trait?
aowww that's an awesome script! thanks for that!
I have just try it, totally insane!
well I did not think about the 20% damage based on weapons skill, it's good that you added the compensation!
thanks again!

I have just try it, totally insane!

well I did not think about the 20% damage based on weapons skill, it's good that you added the compensation!
thanks again!
Re: berserker trait?
Hey minmay,
thanks for posting a better method!
The one a wrote for Drakkan is quite old/outdated/terrible...
I will link that thread to this one
Akroma
thanks for posting a better method!

The one a wrote for Drakkan is quite old/outdated/terrible...

I will link that thread to this one
Akroma
Labyrinth of Lies (viewtopic.php?f=14&t=4400)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Re: berserker trait?
Thanks for the update idea minmay, just what I needed, but isn't it easier to use an onRecomputeStats and a script_entity? That way you can store the weapon data in the script entity, you don't have to add a timer to the party and you don't have to loop through all champions. Seems easier and cleaner.
Re: berserker trait?
The reason I didn't use onRecomputeStats is that onRecomputeStats hooks don't run if the champion doesn't have the trait. If you use onRecomputeStats and the trait is removed from the champion, weapons can get stuck with the wrong damage values.Thorham wrote:Thanks for the update idea minmay, just what I needed, but isn't it easier to use an onRecomputeStats and a script_entity? That way you can store the weapon data in the script entity, you don't have to add a timer to the party and you don't have to loop through all champions. Seems easier and cleaner.
The onUnequipItem hook exists for a similar reason. The timer/onRecomputeStats approach could be expanded to catch the items as they are unequipped via the mouse or quick weapon swap, since it can look at the mouse item and the champion's inventory (impossible to unequip AND drop an item on the same frame). However, if you have some kind of custom interface for unequipping the items that doesn't put them in any of those slots (maybe you made a monster that throws globs of grease that gets on your hands and your weapons fall on the ground, idk), the timer/onRecomputeStats hooks won't catch those.
If the trait can never be removed in your dungeon, then the timer is unnecessary and you can move it to an onRecomputeStats hook. If weapons always end up in the mouse or inventory on the frame after being unequipped, then the onUnequipItem hook is necessary. But I didn't want to make those assumptions about bongobeat's dungeon.
It already uses a ScriptComponent to store the weapon information...
Here's a very similar trait I wrote for someone else that uses an approach more like the one you were thinking of, aside from storing the attack power bonus in a very silly place (I did this because the person I wrote it for doesn't even know how to add a component to an object):
Code: Select all
defineTrait{
name = "munitions",
uiName = "Munitions Expert",
description = "You are skilled with firearms. Wielded firearms gain +1 attack power per experience level.",
onRecomputeStats = function(champion, level)
-- Change firearm's attack power as soon as it's wielded. Change it back as soon as it's unwielded.
-- Update constantly in case level changes.
if level > 0 then
local clevel = champion:getLevel()
for slot=ItemSlot.Weapon,ItemSlot.MaxSlots+1 do
local item
if (slot == ItemSlot.MaxSlots+1) then
item = getMouseItem()
else
item = champion:getItem(slot)
end
if item then
-- We store the attack power bonus in the item's multiple field (which
-- will never matter for an unstackable item, and nobody would make a
-- stackable firearm, right?)
local wielded = (slot == ItemSlot.Weapon or slot == ItemSlot.OffHand)
local setTrait = nil
for _,comp in item.go:componentIterator() do
if comp:getClass() == "FirearmAttackComponent" then
if item:hasTrait("mexpert") then
if wielded and item:getMultiple() ~= clevel then
comp:setAttackPower(comp:getAttackPower()-item:getMultiple()+clevel)
item:setMultiple(clevel)
elseif not wielded then
comp:setAttackPower(comp:getAttackPower()-item:getMultiple())
setTrait = false
end
elseif wielded then
comp:setAttackPower(comp:getAttackPower()+clevel)
item:setMultiple(clevel)
setTrait = true
end
end
end
if setTrait == true then
item:addTrait("mexpert")
elseif setTrait == false then
item:removeTrait("mexpert")
end
end
end
end
end,
}
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.