[SCRIPT] Increasing/Decreasing skill levels (w items)

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
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

[SCRIPT] Increasing/Decreasing skill levels (w items)

Post by akroma222 »

Hello!
I have come up with a script that will increase or decrease skill levels properly.
This was based on minmay's traitManager script (thank you again!)
Simply using champion:trainSkill doesnt account for a few pit falls
This script will....
1. Increase or decrease skill levels
2. Keeps a count of the number of levels past level 5 (MaxCapCount)
3. Removes appropriate traits when you decrease skill levels.

#2 is important, for example, in a situation where you have an item that increases a skill by 1 level and decreases the skill by 1 level when you unequip -
If you already have the highest level (=5) in that skill, using trainSkill (1) (-1) will not increase the skill any further and then bring you back down level 4 when you unequip
trainSkill will also not automatically remove traits when you decrease the level (-1) a skill.
This script corrects those issues.

I have tested this and am happy with it, but please feel free to try and find issues with it.
If there is a situation where it wont do as intended, let me know!!!

Put this in a script entity (skillManager) in your dungeon
To increase skills use: skillUp(champion,skill,levelup,silent)
To decrease skills use: skillDown(champion,skill,leveldown,silent)
Do not use a negative (-) sign in front of leveldown^^
SpoilerShow

Code: Select all

-----------------------------------------------------------------\
------------------------------------------------------------written by Akroma
--Put this in a script entity (skillManager) in your dungeon
--To increase skills use:    skillUp(champion,skill,levelup,silent)
--to decrease skills use:    skillDown(champion,skill,leveldown,silent)
--do not use a negative (-) sign in front of leveldown^^
---------------------------------------------------------------------------------
-----------------------------------------------------------------SKILL_LIST

SKILL_LIST = {
	alchemy = true,
	athletics = true,
	concentration = true,
	light_weapons = true,
	heavy_weapons = true,
	missile_weapons = true,
	poison_immunity = true,
	throwing = true,
	firearms = true,
	accuracy = true,
	critical = true,
	armors = true,
	dodge = true,
	fire_magic = true,
	air_magic = true,
	earth_magic = true,
	water_magic = true
}

----------------------------------------------------------------

skillsTotal = {}

skillsBonus = {}

skillsBase = {}

skillsMaxCapCount = {}

-----------------------------------------------------------------gatherInitialSkillLevels()
function gatherInitialSkillLevels()
	for i = 1, 4 do
		local champion = party.party:getChampion(i)		
		skillsTotal[champion:getOrdinal()] = {}
		skillsBonus[champion:getOrdinal()] = {}
		skillsBase[champion:getOrdinal()] = {}
		skillsMaxCapCount[champion:getOrdinal()] = {}
		for skill,dummy in pairs(SKILL_LIST) do
			local cSkill = champion:getSkillLevel(skill)
			skillsTotal[champion:getOrdinal()][skill] = cSkill
			skillsBase[champion:getOrdinal()][skill] = cSkill
			skillsBonus[champion:getOrdinal()][skill] = 0
			skillsMaxCapCount[champion:getOrdinal()][skill] = 0
		end
	end
end

gatherInitialSkillLevels()

----------------------------------------------------------------skillUp(champion,skill,levelup,silent)

function skillUp(champion,skill,levelup,silent)

	local tempbonus = skillsBonus[champion:getOrdinal()][skill] + levelup
	local capcount = skillsMaxCapCount[champion:getOrdinal()][skill]
	local cSkill = champion:getSkillLevel(skill)
	if cSkill == 5 then
		capcount = capcount + levelup
	end
	champion:trainSkill(skill,levelup, false)
	gatherSkillLevelsUp(champion, skill, tempbonus, capcount)
	
	print(""..skill.." bonus = "..skillsBonus[champion:getOrdinal()][skill].."")
	print(""..skill.." base = "..skillsBase[champion:getOrdinal()][skill].."")
	print(""..skill.." total = "..skillsTotal[champion:getOrdinal()][skill].."")
	print(""..skill.." capcount = "..skillsMaxCapCount[champion:getOrdinal()][skill].."")
	
end
	
-----------------------------------------------------------------gatherSkillLevelsUp(champion,skill, tempbonus, capcount)
function gatherSkillLevelsUp(champion,skill, tempbonus, capcount)
	
	local cSkill = champion:getSkillLevel(skill) + capcount
	skillsTotal[champion:getOrdinal()][skill] = cSkill
	skillsBonus[champion:getOrdinal()][skill] = tempbonus
	skillsBase[champion:getOrdinal()][skill] = skillsTotal[champion:getOrdinal()][skill] - tempbonus
	skillsMaxCapCount[champion:getOrdinal()][skill] = capcount
end

-----------------------------------------------------------------skillDown(champion,skill,leveldown,silent)
function skillDown(champion,skill,leveldown,silent)

	local tempbonus = skillsBonus[champion:getOrdinal()][skill] - leveldown
	local capcount = skillsMaxCapCount[champion:getOrdinal()][skill]
	local cSkill = champion:getSkillLevel(skill)
	
	stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)
	champion:trainSkill(skill,(-leveldown + capcount), false)
	gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
	
	print(""..skill.." bonus = "..skillsBonus[champion:getOrdinal()][skill].."")
	print(""..skill.." base = "..skillsBase[champion:getOrdinal()][skill].."")
	print(""..skill.." total = "..skillsTotal[champion:getOrdinal()][skill].."")
	print(""..skill.." capcount = "..skillsMaxCapCount[champion:getOrdinal()][skill].."")
end

-----------------------------------------------------------------gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
function gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
		
	local cSkill = champion:getSkillLevel(skill)
	skillsTotal[champion:getOrdinal()][skill] = cSkill + tempbonus
	skillsBonus[champion:getOrdinal()][skill] = tempbonus
	if cSkill == 5 then	
		skillsMaxCapCount[champion:getOrdinal()][skill] = tempbonus
	end
end

--------------------------------------------------------------------------
-------------------------------------------------- -----------------------SKILL_BONUSES

SKILL_BONUSES = {

       	alchemy = {
          	[4] = "improved_alchemy",
          	[5] = "bomb_expert"
       	},
		athletics = {
          	[3] = "pack_mule"
       	},
		concentration = {
          	[3] = "meditation"
       	},
		light_weapons = {
          	[3] = "dual_wield",
          	[5] = "improved_dual_wield"
       	},
		heavy_weapons = {
          	[5] = "two_handed_mastery"
       	},
		missile_weapons = {
          	[4] = "piercing_arrows"
       	},
		throwing = {
          	[5] = "double_throw"
       	},
		firearms = {
          	[5] = "firearm_mastery"
       	},
		accuracy = {
          	[2] = "reach" 
       	},
		critical = {
          	[3] = "backstab", 
		  	[5] = "assassin"
       	},
		armors = {
          	[3] = "uncanny_speed"
		},
		fire_magic = {
          	[5] = "fire_mastery"
       	},
		air_magic = {
          	[5] = "air_mastery"
       	},
		earth_magic = {
          	[5] = "earth_mastery"
       	},
		water_magic = {
          	[5] = "water_mastery"
       	}
}
------------------------------------------------------------------------------stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)

	function stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)

       	for s,bonuses in pairs(SKILL_BONUSES) do
			if s == skill then
          		local sLevel = cSkill
             	local bonus = bonuses[(sLevel + capcount)]
             	if bonus then
               		champion:removeTrait(bonus)
					print(""..bonus.." removed")
					hudPrint(""..champion:getName().." loses the "..bonus.." trait.")
             	end
          	end
       	end
    end
	
If you want to use this script to +/- skill levels when you equip an item, use the onEquip/onUnequip hooks
Eg. Assassins Dagger - Ninjas get critical skill +1
Item component (you will need to change (if champion:getClass() == "ninja" then ) to something else if you dont have a Ninja class defined)
SpoilerShow

Code: Select all

{
           	class ="Item",
           	uiName = "Assassin's Dagger",
           	gfxAtlas = "mod_assets/textures/items.tga",
		gfxIndex = 142,
		gameEffect = [[
		- Life Leech
		- Critical Chance +5% 
		- Ninjas gain Critical skill +1.]],
           	weight = 1.0,
           	impactSound = "impact_blade",
		projectileRotationSpeed = 100,
		projectileRotationX = 90,
		projectileRotationY = -90,
		secondaryAction = "throw",
           	traits = { "dagger", "light_weapon" , "aquatic"},
           	description = "A wave-bladed slender dagger that only the most vile of the lizardmen assassins dare to use.",
        	onEquipItem = function(self, champion, slot)
	
			if slot == 1 or slot == 2 then
		
				if champion:getClass() == "ninja" then
			
					return skillManager.script.skillUp(champion,"critical", 1, false)
		
				end
	
			end
		end,
		onUnequipItem = function(self, champion, slot)
	
			if slot == 1 or slot == 2 then 
		
				if champion:getClass() == "ninja" then
			
					return skillManager.script.skillDown(champion,"critical", 1, false)
		
		end
	
			end
		end,
	},
This is minmay's traitManager script, the basis for the skillManager script
Just place the script in a script entity called (traitManager)
It will add/remove traits properly -
If your champion already has a trait, then equips/unequips an item that gives and removes the same trait - the trait will not be removed.
SpoilerShow

Code: Select all

-- USAGE: Instead of calling champion:addTrait and
-- champion:removeTrait, call traitManager.addTrait and
-- traitManager.removeTrait. This will prevent equipment swapping
-- from destroying permanent traits and the like.
-- For example, instead of champion:addTrait("tough",true) call
-- traitManager.addTrait(champion,"tough",true).
-- Note: You shouldn't (and can't) use this script for skill
-- traits (such as quick_strike) as the counts would be
-- rendered inaccurate anyway by players increasing their skills.
 
TRAIT_LIST = {
	-- Regular traits.
	
	head_hunter = true,
	skilled = true,
	fast_learner = true,
	rage = true,
	fast_metabolism = true,
	endure_elements = true,
	poison_immunity = true,
	chitin_armor = true,
	quick = true,
	mutation = true,
	aggressive = true,
	agile = true,
	healthy = true,
	athletic = true,
	strong_mind = true,
	aura = true,
	tough = true,
	cold_resistant = true,
	evasive = true,
	fire_resistant = true,
	weapon_specialization = true,
	endurance = true,
	lightning_speed = true,
	natural_armor = true,
	poison_resistant = true,
	uncanny_speed = true,
	leadership = true,
	nightstalker = true,
	
	-- Skill traits. Currently excluded.
	
	--[["pack_mule",
	"meditation",
	"two_handed_mastery",
	"light_armor_proficiency",
	"heavy_armor_proficiency",
	"armor_expert",
	"shield_expert",
	"staff_defence",
	"improved_alchemy",
	"bomb_expert",
	"backstab",
	"assassin",
	"firearm_mastery",
	"dual_wield",
	"improved_dual_wield",
	"piercing_arrows",
	"double_throw",
	"reach",
	"uncanny_speed",
	"fire_mastery",
	"air_mastery",
	"earth_mastery",
	"water_mastery"]]
	
--LoG1 skill traits
	--[["greater_lightning_bolt",
	"air_circle",
	"light_armor",
	"heavy_armor",
	"shield_expert",
	"backstab",
	"reach_attack",
	"improved_backstab",
	"quick_strike",
	"improved_critical",
	"piercing_attack",
	"improved_quick_strike",
	"assassin_master",
	"endurance",
	"porter",
	"chop",
	"cleave",
	"rampage",
	"axe_master",
	"stab",
	"piercing_strike",
	"flurry_slashes",
	"dagger_master",
	"stealth",
	"light_armor",
	"improved_stealth",
	"improved_poison_bolt",
	"earth_circle",
	"greater_fireball",
	"fire_circle",
	"improved_frostbolt",
	"ice_circle",
	"bash",
	"crushing_blow",
	"devastating_blow",
	"mace_master",
	"quick_shot",
	"improved_quick_shot",
	"volley",
	"master_archer",
	"combat_caster",
	"improved_combat_caster",
	"archmage",
	"light_armor",
	"slash",
	"parry",
	"thrust",
	"flurry_slashes",
	"sword_master",
	"quick_throw",
	"improved_quick_throw",
	"double_throw",
	"throwing_master",
	"jab",
	"kick",
	"three_point_technique"]]
}

traits = {}

-- add a trait and increase "level" of that trait by 1
function addTrait(champion,trait,silent)
	if not TRAIT_LIST[trait] then
		print("warning: invalid trait: "..trait)
	end

	if traits[champion:getOrdinal()][trait] == 0 then
		champion:addTrait(trait,silent)
	end
	traits[champion:getOrdinal()][trait] = traits[champion:getOrdinal()][trait] + 1
end

-- decrease "level" of a trait by 1, removing it if it reaches 0
function removeTrait(champion,trait)
	--local name = champion:getName() 
	if traits[champion:getOrdinal()][trait] == 1 then
		champion:removeTrait(trait)
		--hudPrint(""..name.." gained the agile trait.")
	end
	traits[champion:getOrdinal()][trait] = traits[champion:getOrdinal()][trait] - 1
end

-- get the traits the party started with
function gatherInitialTraits()
	for i = 1, 4 do
		local champion = party.party:getChampion(i)
		traits[champion:getOrdinal()] = {}
		for trait,dummy in pairs(TRAIT_LIST) do
			if champion:hasTrait(trait) then
				traits[champion:getOrdinal()][trait] = 1
			else
				traits[champion:getOrdinal()][trait] = 0
			end
		end
	end
end
gatherInitialTraits()
Last edited by akroma222 on Sun Dec 21, 2014 8:28 am, edited 2 times in total.
Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by Grimfan »

Wow Akroma. Nice scripting. It will be great to see what new classes, races, spells and traits you'll spring on us with your next mod. :)
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by akroma222 »

Thanks Grimfan!
I will be getting the ground work done first this time, wont start building until I have all the pieces I need - hopefully this should help me stay organised >> less errors/bugs ;)
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by Drakkan »

this is so cool. Not sure when but I will definitely some day get to define some leveling items. thanks akroma !
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by Drakkan »

hi akroma,

I have following item defined, which is not working regarding skill up. I have define hero with 1 point in throwing, when he equip this ring, skill is not improving. Please check if you see what could be the problem
SpoilerShow

Code: Select all

defineObject{
		name = "pointy_ring",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/hardstone_bracelet.fbx",
		},
		{
			class = "Item",
			uiName = "Precious Ring",
			gfxAtlas = "mod_assets/icons/drakkanicons.tga",
			gfxIndex = 33,
			weight = 0.2,
			description = "This shiny green ring emits a powerfull magic aura. It improves your Throwing skill as well.",
			traits = { "bracers" },

onEquipItem = function(self, champion, slot)
   
         if slot == 8 then
      

               return skillManager.script.skillUp(champion,"throwing", 1, false)
      
 
         end
      end,
      onUnequipItem = function(self, champion, slot)
   
         if slot == 8 then
              
               return skillManager.script.skillDown(champion,"throwing", 1, false)
       
         end
      end,
		},
		{
		class = "EquipmentItem",
		protection= 2,
		accuracy = 5,
		},
	},
}
EDIT: small bug discovered in the script regarding correct traits. this is not regarding my problem unfortunately :/

please correct

Code: Select all

  		  dodge    = {
                 [3] = "uncanny_speed"			
			  },
          armors   = {
				 [2] = "light_armor_proficiency",
				 [4] = "heavy_armor_proficiency" 
              },
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by akroma222 »

Hey Drakkan,
sorry for the late reply...
I assume you item is to be worn in the bracers slot?
You need to change
if slot == 8 then (which is for necklaces)
to
if slot == 10 then (for bracers)

Works fine now ;)

Item slots...
SpoilerShow
ItemSlot.Weapon = 1
ItemSlot.OffHand = 2
ItemSlot.Head = 3
ItemSlot.Chest = 4
ItemSlot.Legs = 5
ItemSlot.Feet = 6
ItemSlot.Cloak = 7
ItemSlot.Necklace = 8
ItemSlot.Gloves = 9
ItemSlot.Bracers = 10
ItemSlot.Weapon2 = 11
ItemSlot.OffHand2 = 12
ItemSlot.BackpackFirst = 13
ItemSlot.BackpackLast = 32
ItemSlot.MaxSlots = 32
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [SCRIPT] Increasing/Decreasing skill levels (w items)

Post by Drakkan »

akroma222 wrote:Hey Drakkan,
sorry for the late reply...
I assume you item is to be worn in the bracers slot?
You need to change
if slot == 8 then (which is for necklaces)
to
if slot == 10 then (for bracers)

Works fine now ;)

Item slots...
SpoilerShow
ItemSlot.Weapon = 1
ItemSlot.OffHand = 2
ItemSlot.Head = 3
ItemSlot.Chest = 4
ItemSlot.Legs = 5
ItemSlot.Feet = 6
ItemSlot.Cloak = 7
ItemSlot.Necklace = 8
ItemSlot.Gloves = 9
ItemSlot.Bracers = 10
ItemSlot.Weapon2 = 11
ItemSlot.OffHand2 = 12
ItemSlot.BackpackFirst = 13
ItemSlot.BackpackLast = 32
ItemSlot.MaxSlots = 32
thanks akroma, working fine. Not sure where I saw bracelet is slot 8... thanks !
Breath from the unpromising waters.
Eye of the Atlantis
Post Reply