New weapon skills - Resolved

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
Post Reply
cameronC
Posts: 80
Joined: Wed Apr 11, 2012 10:54 pm

Re: some weapon skill help pls

Post by cameronC »

You can have onAttack look at the traits of the attacking champion and build a table of what modifiers the weapon is getting, then write a function to reduce the weapon stats back to normal by passing it this table and use delayedCall to that function from onAttack. So, everytime someone attacks their weapon is modified then reduced automatically according to traits and other stuff. Not sure how this works out timing wise, but simple enough to make.

You can also have an onHitMonster that every weapon hooks into that checks the champs traits and manipulates everything accordingly. This was done in another of Drakkan's thread about a trait that adds damage to undead monsters only.
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.

Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: some weapon skill help pls

Post by akroma222 »

Thats sounds a lot better cameronC, do you volunteer for this?? ;)
Timing will work fine, as long as the delay call is set to less than any cooldowns and chainActionDelay values for power attacks
cameronC
Posts: 80
Joined: Wed Apr 11, 2012 10:54 pm

Re: some weapon skill help pls

Post by cameronC »

akroma222 wrote:Thats sounds a lot better cameronC, do you volunteer for this?? ;)
I do, I do. Let's see how 'simple' this is...

of course, the real solution is to let us put more hooks in trait definitions, like on onReceiveCondition can be...
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.

Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: some weapon skill help pls

Post by akroma222 »

Okay, so I may have a preliminary working solution...
onAttack will call weaponModManager.script.addWeaponModifiers(self, champion, weapontype1, weapontype2)
you must pass a weapontype - axe weapons pass "axe" for example (you can pass up to 2 weapontypes)
This will create a table modList based on weapontypes and the champions traits.
addWeaponModifiers will then add bonuses appropriately
delayedCall will then trigger 0.2 sec later, wiping modList clean and returning the weapon to its original state

add these traits
SpoilerShow

Code: Select all

defineTrait{
    	name = "woodcutter",
    	uiName = "Wood Cutter",
    	icon = 94,
    	description = "I like to chop the woods",
}

defineTrait{
    	name = "master_axeman",
    	uiName = "Axe Master",
    	icon = 94,
    	description = "So masterful with axes right now!",
}

defineTrait{
    	name = "grandmaster_axeman",
    	uiName = "Axe Grand Master",
    	icon = 94,
    	description = "So grandmasterful with axes right now!",
}

defineTrait{
    	name = "skullcrusher",
    	uiName = "Skull Crusher",
    	icon = 94,
    	description = "I like to crush the skulls",
}

defineTrait{
    	name = "master_maceman",
    	uiName = "Mace Master",
    	icon = 94,
    	description = "So masterful with maces right now!",
}

defineTrait{
    	name = "grandmaster_maceman",
    	uiName = "Mace Grand Master",
    	icon = 94,
    	description = "So grandmasterful with maces right now!",
}
An axe and a mace definition
SpoilerShow

Code: Select all

defineObject{
       	name = "hand_axe",		
       	baseObject = "base_item",
	tags = { "weapon", "axe" },
       	components = {
       	{
          	class = "Model",
          	model = "assets/models/items/hand_axe.fbx",
       	},
       	{
          	class ="Item",
          	uiName = "Hand Axe",
          	gfxAtlas = "assets/textures/gui/items.tga",
          	gfxIndex = 25,
          	weight = 2.6,
          	impactSound = "impact_blade",
          	traits = { "axe", "heavy_weapon"},
       	   	description = "A short but solid axe commonly used for chopping wood."
       	},
	{
                class = "MeleeAttack",
                attackPower = 10,
                accuracy = 0,
                swipe = "horizontal",
                attackSound = "swipe",
                cooldown = 4.5,
		pierce = 0,
                baseDamageStat = "strength",
                damageType = "physical",
         	onAttack = function(self, champion, action, slot)
			weaponModManager.script.addWeaponModifiers(self, champion:getOrdinal(), "axe")
             		delayedCall("weaponModManager", 0.2, "removeWeaponModifiers", self,  champion:getOrdinal(), "axe")
          	end,
        },
       	}
    }	


defineObject{
	name = "bone_club",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/bone_club.fbx",
		},
		{
			class = "Item",
			uiName = "Bone Club",
			description = "A makeshift club made from the leg bone of an unknown beast.",
			gfxIndex = 298,
			impactSound = "impact_blunt",
			weight = 1.2,
			traits = { "heavy_weapon", "mace" },
		},
		{
			class = "MeleeAttack",
			attackPower = 4,
			accuracy = 0,
			pierce = 10,
			cooldown = 3,
			swipe = "vertical",
			attackSound = "swipe",
			onAttack = function(self, champion, action, slot)
				weaponModManager.script.addWeaponModifiers(self, champion:getOrdinal(), "mace")
             			delayedCall("weaponModManager", 0.2, "removeWeaponModifiers", self,  champion:getOrdinal(), "mace")
          		end,
		},
	},
	tags = { "weapon" },
}
And a script entity (weaponModManager) with this:
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, weapontype) 

function gatherModifierTraits(self, champion, weapontype1, weapontype2)
	local c = party.party:getChampion(champion)
	
	modList[c] = {}
	
	if weapontype1 == "axe" 
	or weapontype2 == "axe" then
	
		for trait,dummy in pairs(axe_TRAITS) do
		
			if c:hasTrait(trait) then
				modList[c][trait] = 1
				--print(modList[c][trait])
			else
				modList[c][trait] = nil
				--print(modList[c][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[c][trait] = 1
				--print(modList[c][trait])
			else
				modList[c][trait] = nil
				--print(modList[c][trait])
			end
		end
	end
end

---------------------------------------------------------addWeaponModifiers(self, champion, weapontype)

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" then
	
		local cutterAttack = 0
		local masterAttack = 0
		local grandmasterAttack = 0
		
		if modList[c]["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[c]["master_axeman"] == 1 then
			masterAttack = 20
			self:setAttackPower(trueAttack + cutterAttack + masterAttack + grandmasterAttack)
			print(""..self:getAttackPower().."")
		end
		if modList[c]["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[c]["skullcrusher"] == 1 then
			crusherPierce = 10
			self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
			print(""..self:getPierce().."")
		end
		if modList[c]["master_maceman"] == 1 then
			masterPierce = 20
			self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
			print(""..self:getPierce().."")
		end
		if modList[c]["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" then
		for trait,dummy in pairs(axe_TRAITS) do
			modList[c][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[c][trait] = nil
		end
		self:setPierce(truePierce)
		print(""..self:getPierce().."")
	end
end	
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: some weapon skill help pls

Post by Drakkan »

here is final axe and master asset as I intended - please check, if it is ok, should be... however curently not sure, if damage is calculated correctly, seems kind of overpowered

for all axe items add on attack function
SpoilerShow

Code: Select all

            onAttack = function(self, champion, action, slot)
         weaponModManager.script.addWeaponModifiers(self, champion:getOrdinal(), "axe")
                   delayedCall("weaponModManager", 0.2, "removeWeaponModifiers", self,  champion:getOrdinal(), "axe")
             end,
for all maces as well
SpoilerShow

Code: Select all

         onAttack = function(self, champion, action, slot)
            weaponModManager.script.addWeaponModifiers(self, champion:getOrdinal(), "mace")
                      delayedCall("weaponModManager", 0.2, "removeWeaponModifiers", self,  champion:getOrdinal(), "mace")
                end,
-- skills (icons need to be set for some default or use your own)
SpoilerShow

Code: Select all

defineSkill{
name = "axe_prof",
uiName = "Axe proficience",
priority = 10,
iconAtlas = "mod_assets/icons/testujuikony.tga",
icon = 0,
description = "Swinging the axe makes your character much stronger. Each point invested increases your Strength and Hit points. Third skill point also provide you with bonus +10 to attack power and finally on level 5 you gain ultimate bonus +20 to attack power with axes.",
traits = { [1] = "novice_axeman", [2] = "apprentice_axeman", [3] = "expert_axeman", [4] = "master_axeman", [5] = "grandmaster_axeman"  },
}


defineSkill{
name = "mace_prof",
uiName = "Mace proficience",
priority = 10,
iconAtlas = "mod_assets/icons/testujuikony.tga",
icon = 0,
description = "You become more resistant on the battlefield while fighting with Mace. Each point invested increases your Vitality and Hit points. On Level 3 your attack with mace ignores 10 points of opponents armor and finally on level 5 your attack ignores 30 points of armor.",
	traits = { [1] = "novice_mace", [2] = "apprentice_mace", [3] = "expert_mace", [4] = "master_mace", [5] = "grandmaster_mace"  },
}
-- and traits for them
SpoilerShow

Code: Select all

defineTrait{
	name = "novice_axeman",
	uiName = "Novice Axeman",
	icon = 94,
	description = "You started to learn how cut the trees. Strength bonus +1, Health +5.",
	onRecomputeStats = function(champion, level)
		if level > 0 then
			level = champion:getLevel()
			champion:addStatModifier("strength", 1)
			champion:addStatModifier("max_health", 5)
--			champion:addStatModifier("max_energy", 30 + (level-1) * 3)
		end
	end,
}


defineTrait{
	name = "apprentice_axeman",
	uiName = "Apprentice Axeman",
	icon = 94,
	description = "Cuting monster heads is much better than lumbering the woods. Strength bonus +1, Health +5.",
	onRecomputeStats = function(champion, level)
		if level > 0 then
			level = champion:getLevel()
			champion:addStatModifier("strength", 1)
			champion:addStatModifier("max_health", 5)
--			champion:addStatModifier("max_energy", 30 + (level-1) * 3)
		end
	end,
}


defineTrait{
	name = "expert_axeman",
	uiName = "Expert Axeman",
	icon = 94,
	description = "You have learned how to use axe and there are scary rumors among the monsters. Strength bonus +1, Health +5. Attack power +10 while using axes.",
	onRecomputeStats = function(champion, level)
		if level > 0 then
			level = champion:getLevel()
			champion:addStatModifier("strength", 1)
			champion:addStatModifier("max_health", 5)
--			champion:addStatModifier("max_energy", 30 + (level-1) * 3)
		end
	end,
}


defineTrait{
	name = "master_axeman",
	uiName = "Master Axeman",
	icon = 94,
	description = "You have mastered the axe. Only one final training is before you to reach the rank of Grandmaster. Bonus +1 Strength, Health +5.",
	onRecomputeStats = function(champion, level)
		if level > 0 then
			level = champion:getLevel()
			champion:addStatModifier("strength", 1)
			champion:addStatModifier("max_health", 5)
--			champion:addStatModifier("max_energy", 30 + (level-1) * 3)
		end
	end,
}


defineTrait{
       name = "grandmaster_axeman",
       uiName = "Axe Grand Master",
       icon = 94,
       description = "Finally ! You are able to kill any monster with one mighty swing ! Bonus + 20 to attack power with axes !",
}





defineTrait{
name = "novice_mace",
uiName = "Mace Novice",
icon = 94,
description = "You can withstand some hard blows. Bonus +1 Vitality and + 5 Hit points.",
onRecomputeStats = function(champion, level)
if level > 0 then
level = champion:getLevel()
champion:addStatModifier("vitality", 1)
champion:addStatModifier("max_health", 5)
-- champion:addStatModifier("max_energy", 30 + (level-1) * 3)
end
end,
}


defineTrait{
name = "apprentice_mace",
uiName = "Mace Apprentice",
icon = 94,
description = "You are more resistant now. Bonus +1 Vitality and + 5 Hit points.",
onRecomputeStats = function(champion, level)
if level > 0 then
level = champion:getLevel()
champion:addStatModifier("vitality", 1)
champion:addStatModifier("max_health", 5)
-- champion:addStatModifier("max_energy", 30 + (level-1) * 3)
end
end,
}


defineTrait{
name = "expert_mace",
uiName = "Mace Expert",
icon = 94,
description = "You learned how to use mace properly. Bonus +1 Vitality and + 5 Hit points and you ignore 10 points of opponents armor with mace.",
onRecomputeStats = function(champion, level)
if level > 0 then
level = champion:getLevel()
champion:addStatModifier("vitality", 1)
champion:addStatModifier("max_health", 5)
-- champion:addStatModifier("max_energy", 30 + (level-1) * 3)
end
end,
}


defineTrait{
name = "master_mace",
uiName = "Mace Master",
icon = 94,
description = "Only one final training is before you to reach rank of the Granmaster. Bonus +1 Vitality and + 5 Hit points.",
onRecomputeStats = function(champion, level)
if level > 0 then
level = champion:getLevel()
champion:addStatModifier("vitality", 1)
champion:addStatModifier("max_health", 5)
-- champion:addStatModifier("max_energy", 30 + (level-1) * 3)
end
end,
}


defineTrait{
       name = "grandmaster_mace",
       uiName = "Mace Grand Master",
       icon = 94,
       description = "Bash them hard, bash them good ! You ignore 30 points of opponents armor.",
}
and of course your manager inside script named weaponModManager
SpoilerShow

Code: Select all

-------------------------------------------------------- Trait lists

TRAIT_LIST = {
-- woodcutter = true,
   expert_axeman = true,
   grandmaster_axeman = true,
-- skullcrusher = true,
   expert_maceman = true,
   grandmaster_maceman = true
}

axe_TRAITS = {
--   woodcutter = true,
   expert_axeman = true,
   grandmaster_axeman = true
}

mace_TRAITS = {
-- skullcrusher = true,
   expert_maceman = true,
   grandmaster_maceman = true
}

--------------------------------------------------------- Modifier list

modList = {}

----------------------------------------------------------gatherModifierTraits(self, champion, weapontype) 

function gatherModifierTraits(self, champion, weapontype1, weapontype2)
   local c = party.party:getChampion(champion)
   
   modList[c] = {}
   
   if weapontype1 == "axe" 
   or weapontype2 == "axe" then
   
      for trait,dummy in pairs(axe_TRAITS) do
      
         if c:hasTrait(trait) then
            modList[c][trait] = 1
            --print(modList[c][trait])
         else
            modList[c][trait] = nil
            --print(modList[c][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[c][trait] = 1
            --print(modList[c][trait])
         else
            modList[c][trait] = nil
            --print(modList[c][trait])
         end
      end
   end
end

---------------------------------------------------------addWeaponModifiers(self, champion, weapontype)

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" then
   
--      local cutterAttack = 0
      local expertAttack = 0
      local grandmasterAttack = 0
      
--      if modList[c]["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[c]["expert_axeman"] == 1 then
         expertAttack = 10
         self:setAttackPower(trueAttack + expertAttack + grandmasterAttack)
         print(""..self:getAttackPower().."")
      end
      if modList[c]["grandmaster_axeman"] == 1 then
         grandmasterAttack = 20
         self:setAttackPower(trueAttack + expertAttack + grandmasterAttack)
         print(""..self:getAttackPower().."")
      end
   end
   
   if weapontype1 == "mace" 
   or weapontype2 == "mace" then
   
--    local crusherPierce = 0
      local expertPierce = 0
      local grandmasterPierce = 0
      
--      if modList[c]["skullcrusher"] == 1 then
--         crusherPierce = 10
--         self:setPierce(truePierce + crusherPierce + grandmasterPierce)
--         print(""..self:getPierce().."")
--      end
      if modList[c]["expert_maceman"] == 1 then
         expertPierce = 10
         self:setPierce(truePierce + expertPierce + grandmasterPierce)
         print(""..self:getPierce().."")
      end
      if modList[c]["grandmaster_mace"] == 1 then
         grandmasterPierce = 30
         self:setPierce(truePierce + expertPierce + 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" then
      for trait,dummy in pairs(axe_TRAITS) do
         modList[c][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[c][trait] = nil
      end
      self:setPierce(truePierce)
      print(""..self:getPierce().."")
   end
end   
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: some weapon skill help pls

Post by akroma222 »

Hey Drakkan,
It would be hard for anyone to tell if your axe and mace traits are overpowered... as this is dependent upon a number of other factors such as -
how powerful your other weapon types can become,
how tough the monsters are that you are going to have to face,
how powerful you decide to define the actual axe and mace weapons as etc etc

You will know once you and others start play testing your mod ;)

One thing... your description of axe grandmaster states
description = "Finally ! You are able to kill any monster with one mighty swing ! Bonus + 20 to attack power with axes !",
... do you intend for players to be able to 'one-shot' any monster with any axe?
That is probably over powered (and I dont think we even made that possible with the weaponModifier script)
Maybe something like...
"Finally your mighty swings are able to devastate even the toughest monsters! Bonus + 20 to attack power with axes !",

EDIT
Also maybe consider just creating an Axe Skill that does the recomputing of stats, instead of a skill that only gives you extra individual traits that do this...
For example, athletics and concentration
SpoilerShow

Code: Select all

defineSkill{
	name = "athletics",
	uiName = "Athletics",
	priority = 20,
	icon = 12,
	description = "Increases your health by 20 for each skill point. At 3rd skill level your carrying capacity is increased by 15 kg.",
	traits = { [3] = "pack_mule" },
	onRecomputeStats = function(champion, level)
		champion:addStatModifier("max_health", level*20)
	end,
}

defineSkill{
	name = "concentration",
	uiName = "Concentration",
	priority = 30,
	icon = 26,
	description = "Increases your energy by 20 for each skill point. At 3rd level your Energy regeneration rate is increased by 25% while resting.",
	onRecomputeStats = function(champion, level)
		champion:addStatModifier("max_energy", level*20)
	end,
	traits = { [3] = "meditation" },
}
You could possibly make your axe skill more like them (spelling on "Axe proficiency" corrected ;) )
SpoilerShow

Code: Select all

defineSkill{
name = "axe_prof",
uiName = "Axe proficiency",
priority = 10,
iconAtlas = "mod_assets/icons/testujuikony.tga",
icon = 0,
description = "Swinging the axe makes your character much stronger. Each point invested increases your Strength (+1) and Hit points (+5). At the 3rd skill level you gain the Expert Axeman trait (Attack Power +10) and at the 5th level you gain the Master Axeman trait (Attack Power +30).",
onRecomputeStats = function(champion, level)
		if level > 0 then
			level = champion:getLevel()
                health = chamion::getMaxHealth()
			champion:addStatModifier("strength", level)
                champion:addStatModifier("max_health", health +  level)
               end
end,
traits = {  [3] = "expert_axeman", [5] = "grandmaster_axeman"  },
}
Then you can just keep the Expert and Master Axeman traits to give the champion the attack power bonuses.
If you do do it this way though, the issue of 'what will Light and Heavy Weapons skills do then??' is raised...
Just another way of doing things I guess... completely up to you! ;)
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: some weapon skill help pls

Post by Drakkan »

akroma222 wrote:Hey Drakkan,
You will know once you and others start play testing your mod ;)
thanks for ideas and corrections. I will probably use the "original" system (no trait every level) but I have problem to define script for swords, where on level 1 and 3 you gain Dexterity+1 and energy +5, while on level 2 and 4 you gain +1 STR and +5hp and on level 5 you gain some trait. Are you able to script this skill ?

Code: Select all

 defineSkill{
name = "sword_prof",
uiName = "Sword proficiency",
priority = 10,
        iconAtlas = "mod_assets/icons/testujuikony.tga",
icon = 0,
description = "Mastering the sword requires both dexterity and Strength. Each point invested increases your Strength / Hit points or Dexterity / energy. On Level 5 any attack with sword is 20% faster.",
--lev1,3 = dex +1,+5 energy
--lev2,4 = str +1, +5 hp
--lev5 = only trait bonus
--traits = { [1] = "novice_sword", [2] = "apprentice_sword", [3] = "expert_sword",  [4] = "master_sword", [5] = "grandmaster_sword"   },
}
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: some weapon skill help pls

Post by Drakkan »

And a script entity (weaponModManager) with this:
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, weapontype) 

function gatherModifierTraits(self, champion, weapontype1, weapontype2)
	local c = party.party:getChampion(champion)
	
	modList[c] = {}
	
	if weapontype1 == "axe" 
	or weapontype2 == "axe" then
	
		for trait,dummy in pairs(axe_TRAITS) do
		
			if c:hasTrait(trait) then
				modList[c][trait] = 1
				--print(modList[c][trait])
			else
				modList[c][trait] = nil
				--print(modList[c][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[c][trait] = 1
				--print(modList[c][trait])
			else
				modList[c][trait] = nil
				--print(modList[c][trait])
			end
		end
	end
end

---------------------------------------------------------addWeaponModifiers(self, champion, weapontype)

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" then
	
		local cutterAttack = 0
		local masterAttack = 0
		local grandmasterAttack = 0
		
		if modList[c]["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[c]["master_axeman"] == 1 then
			masterAttack = 20
			self:setAttackPower(trueAttack + cutterAttack + masterAttack + grandmasterAttack)
			print(""..self:getAttackPower().."")
		end
		if modList[c]["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[c]["skullcrusher"] == 1 then
			crusherPierce = 10
			self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
			print(""..self:getPierce().."")
		end
		if modList[c]["master_maceman"] == 1 then
			masterPierce = 20
			self:setPierce(truePierce + crusherPierce + masterPierce + grandmasterPierce)
			print(""..self:getPierce().."")
		end
		if modList[c]["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" then
		for trait,dummy in pairs(axe_TRAITS) do
			modList[c][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[c][trait] = nil
		end
		self:setPierce(truePierce)
		print(""..self:getPierce().."")
	end
end	

Hi akroma / any other modder
I am using this weaponmanager skill and game just crashed when saving because of this script. Please could somebody review what is wrong inside ?

Code: Select all

=== Software Failure ===

weaponModManager: cannot serialize table key of type table
stack traceback:
	[C]: in function 'error'
	[string "Script.lua"]: in function 'saveValue'
	[string "Script.lua"]: in function 'saveState'
	[string "GameObject.lua"]: in function 'saveState'
	[string "Map.lua"]: in function 'saveState'
	[string "GameMode.lua"]: in function 'saveGame'
	[string "GameMode.lua"]: in function 'quickSave'
	[string "GameMode.lua"]: in function 'keyPressed'
	[string "Grimrock.lua"]: in function 'pollEvents'
	[string "Grimrock.lua"]: in function 'display'
	[string "Grimrock.lua"]: in main chunk
Breath from the unpromising waters.
Eye of the Atlantis
minmay
Posts: 2790
Joined: Mon Sep 23, 2013 2:24 am

Re: some weapon skill help pls

Post by minmay »

That script is using a Champion reference as a key in a table, which cannot be serialized.
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.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: some weapon skill help pls

Post by akroma222 »

Minmay, thank you for pointing out exactly what was wrong!
Drakkan, thank you for reporting this!

This now works with saves... it was completely unnecessary to use a champ ref as a key in a table
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)
	
	if  weapontype1 == "axe"
	or  weapontype2 == "axe" 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" 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" 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


Checked on skillManager and traitManager too and they seem to save fine

Akroma
Post Reply

Return to “Mod Creation”