Shield Blocking Script

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
ratman
Posts: 147
Joined: Fri Jan 10, 2020 1:13 am

Shield Blocking Script

Post by ratman » Tue Aug 10, 2021 4:53 pm

This makes the shields in the game a little more complex, allowing the player to actually use them for blocking instead of just giving them a bonus automatically.
This is just a redefined object of the heavy shield with a UsableItem component, and when used it first checks that the champion isn't already blocking, then if they aren't it gives them the blocking condition. The blocking condition currently gives 25 protection for about one second. (You might want to change this, it might be unbalanced.) The champion can still attack or use other items while they are blocking.
This might be OP or otherwise unbalanced, so feel free to change it however you want if you use it.
Also this only has the heavy shield definition, so unfortunately you'll have to redefine every single shield, and make a different condition for every one. And make sure that the shields check for conditions from different shields. I will probably do all this stuff eventually and update this when I'm done, but if anyone wants to use it until then feel free to.
Also if anyone knows of a more efficient way of doing this that doesn't involve so much conditions, please tell me.

Code:

Code: Select all

defineCondition{
	name = "blocking",
	uiName = "Blocking",
	description = "Using a shield.",
	iconAtlas = "assets/textures/gui/spell_icons.tga",
	icon = 4000,
	beneficial = true,
	harmful = false,
	tickInterval = 1,
	onStart = function(self, champion, new)
		self:setDuration(1)
		
		champion:modifyBaseStat("protection",25)
	end,
	
	onStop = function(self, champion)
		champion:modifyBaseStat("protection",-25)
	end
}
defineObject{
	name = "heavy_shield_new",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/heavy_shield.fbx",
		},
		{
			class = "Item",
			uiName = "Heavy Shield",
			gfxIndex = 15,
			weight = 6.0,
			traits = { "shield" },
		},
		{
			class = "EquipmentItem",
			slot = "Weapon",
		--	evasion = 6,
		},
		{
			class = "UsableItem",
			sound = "none",
			cooldown = 3.4,
			emptyItem = "heavy_shield_new",
			canBeUsedByDeadChampion = false,
			onUseItem = function(self, champion)
				if champion:hasCondition("blocking")
				then
				return false
				else

					champion:setCondition("blocking")
					champion:showAttackResult("Blocking!", "HitSplashLarge")
					end
			end,
		},
	},
}

User avatar
Willigamer
Posts: 14
Joined: Sat Jan 07, 2017 6:06 pm
Contact:

Re: Shield Blocking Script

Post by Willigamer » Fri Aug 20, 2021 4:33 pm

The way to do it with the UsableItem hook is quite interesting I think.

Personally in my mod, I took the same idea shield system from zimberzimber in his asset. It avoids the need to systematically use conditions to do so (and protection value too), and the blocking system is applied in the onDamage hook of the party, instead of doing it for each shield item (though you will probably need to rewrite each shield to put new attributes/stats on them ofc). It only uses the onDamage and optimizes a little more the size of your scripts.

I found this blocking system really good, because you have both the value that the shield can fully absorb in low-medium damage (damage from physical hits from monsters), and also a percentage chance that the champion will be able to absorb that damage (it's this value that allows you to balance the blocking system so that you're not invincible and can block against any physical attack from the monsters).

Code: Select all

onDamage = function(self, champion, damage, damageType)
	local item1 = champion:getItem(ItemSlot.Weapon)
	local item2 = champion:getItem(ItemSlot.OffHand)
	if not party.party:isFalling() or not party.party:isClimbing() or
	not party.party:isResting() or not champion:hasCondition("frozen") then
	-- bonus
	local skill = champion:getSkillLevel("shields")
	local keper = iff(champion:hasTrait("upper_keep"), 0.2, 0) -- +20% Rate
	local kght = iff(champion:getClass() == "knight", 1.25, 1) -- +25% Value
	local pwr = iff(champion:hasTrait("ancestral_knowledge"), 1.1, 1) -- +10% Value
	-- CRYSTAL SHIELD
	if (item1 and item1.go.name == "crystal_shield") or (item2 and item2.go.name == "crystal_shield") then
		if damage <= 30+(skill*6)*kght*pwr and math.random() < 0.2+keper then
			champion:showAttackResult("Parry", "AccuracySymbol")
			self.go:playSound("metal_hit")
			return false
		end
	end
end,
SpoilerShow
Image

Yea the name of this blockage values can be further improved aswell...
But I think it's now much easier with umods to do this by creating a new blockage value and its blockage chance entirely.
"Always become the one you are, be the master and the sculptor of yourself"
My LoG2 Mods :
  • Legend of Island : Coming Soon
  • Sanctuary Antique : One day maybe...

Post Reply