thoughts on a 'Frozen' condition

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

Re: thoughts on a 'Frozen' condition

Post by akroma222 »

Hahah cool man, let it be show and tell time ;) :twisted:
Note: could well be some minor errors - always polishing when I learn new things
Ignore most of the standard functions dealing with conditionScripts - they are just for tracking each Champs amount of time spent w each Condition (like a data hub for conds)
Some of these call separate FX functions (also in conditionScripts) - ill post these up too

Frozen:
(good idea stopping the look cheat into turn)
SpoilerShow

Code: Select all

defineCondition{
   	name = "frozen",
   	uiName = "Frozen",
   	description = "\nProtection +25, Evasion -100\nParalyzed for the Duration\nVulnerable to Shattering",
   	icon = 7,
   	iconAtlas = "mod_assets/textures/conditions2.tga",
   	beneficial = false,
   	harmful = true,
   	tickInterval = 2,
   	onStart = function(self, champion, new)
		-----------------------------------------------------------illusionistVanish
		--if champion:getClass() == "illusionist" then
			--conditionScripts.script.vanishTemp()
		--end
		--------------------------------------------------burning
		if champion:hasCondition("burning") then
			champion:setConditionValue("burning", 0)
			hudPrint(champion:getName().."'s Burning condition is extinguished...")
		end
		------------------------------------------frozenFX
		conditionScripts.script.frozenDisabledPartyFX(champion, "onStart", nil)
		-----------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("frozen", champion:getOrdinal(), true)
		conditionScripts.script.addCondOccassion("frozen", champion:getOrdinal(), 1)
		-------------------------------------------------------------------------------	
   	end,
   	onTick = function(self, champion)
		-----------------------------------------------------------illusionistVanish
		--if champion:getClass() == "illusionist" then
			--conditionScripts.script.vanishTemp()
		--end
		------------------------------------------
		local d = self:getDuration()
		local v = champion:getConditionValue("frozen")
		local res = champion:getCurrentStat("resist_cold")
		local dur = iff(d ~= nil, d, math.ceil((100 - res)/2))
		print("tick", d, v, dur, res)
		---------------------------------------------set time
		conditionScripts.script.setFrozenTime(champion)
		---------------------------------------------breakout!
		local str = champion:getCurrentStat("strength") 
		if d and str > d then											
			self:setDuration(2)
			---------------------------------------paralyzed
			--if champion:hasCondition("paralyzed") then
				--champion:setConditionValue("paralyzed", 3)
			--end
			
		elseif d and str <= d then			
			----------------------------------------paralyzed
			--if not champion:hasCondition("paralyzed") then
				--champion:setCondition("paralyzed")
				--if champion:hasCondition("paralyzed") then
					--champion:setConditionValue("paralyzed", dur)
				--end
			--end
		end
		-------------------------------------------frozenFX
		conditionScripts.script.frozenDisabledPartyFX(champion, "onTick", d)
		---------------------------------------------------set time
		conditionScripts.script.tickFrozenTime(2)
		-----------------------------------------------------------------------------
		conditionScripts.script.condTimeCount("frozen", champion:getOrdinal())
		conditionScripts.script.storeCurrentCount("frozen", champion:getOrdinal(), 1)
		--print("frozen", self:getDuration())
		-----------------------------------------------------------------------------
   	end,
	onStop = function(self, champion)
		-----------------------------------------------------------illusionistVanish
		--if champion:getClass() == "illusionist" then
			--conditionScripts.script.vanishTemp()
		--end
		---------------------------------------------------set time
		conditionScripts.script.resetFrozenTime()
		---------------------------------------paralyzed
		--if champion:hasCondition("paralyzed") then
			--champion:setConditionValue("paralyzed", 0)
		--end
		----------------------------------------------------frozenFX
		conditionScripts.script.frozenDisabledPartyFX(champion, "onStop", self:getDuration())
		--------------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("frozen", champion:getOrdinal(), false)
		conditionScripts.script.wipeCurrCount("frozen", champion:getOrdinal())
		---------------------------------------------------------------------------------	
   	end,
	onRecomputeStats = function(self, champion)
		champion:addStatModifier("evasion",  -100)
      	champion:addStatModifier("protection", 25)
   	end,
}
and the extra bits - champs can break out of the freeze if they are strong enough VS time remaining
SpoilerShow

Code: Select all

--------------------------------setFrozenTime(champion)
frostTimeSet = false
frostTime = 0

function setFrozenTime(champion)
	------------------------------------------
	if champion:hasCondition("frozen") then
		if champion:getConditionValue("frozen") then
			frostTime = champion:getConditionValue("frozen") 
		end
	end	
	------------------------------
	if not frostTimeSet then
		frostTimeSet = true
		playSound("frostbolt_hit")
		----------------------------
		if frostTime >= 30 then
			hudPrint(champion:getName().." is in Deep Freeze...!")	
		elseif frostTime >= 15 then
			hudPrint(champion:getName().." is Frozen Solid..")
		else
			hudPrint(champion:getName().." is slightly Frozen.")
		end	
	elseif frostTimeSet then
		frostTime = champion:getConditionValue("frozen")
	end
end
----------------------------------------------resetFrozenTime()
function resetFrozenTime()
	frostTimeSet = false
	frostTime = 0
end
---------------------------------------------tickFrozenTime()
function tickFrozenTime(int)
	frostTimeSet = true
	frostTime = frostTime - int
end

-----------------------------------------------------frozenDisabledPartyFX(champion, event, duration)
 function frozenDisabledPartyFX(champion, event, duration)
	------------------------------------------------------
	GameMode.setGameFlag("DisableMovement", false)
	GameMode.setGameFlag("DisableMouseLook", false)
	GameMode.setGameFlag("DisableKeyboardShortcuts", false)
	--party.party:playScreenEffect("clear_screen")
	----------------------------------------------
	--if not champion:hasCondition("frozen") then
		--print("No frozen cond...")
		--return
	--end
	-----------------------------------------------how many frozen champs
	local v = champion:getConditionValue("frozen")
	local count = 0
	for i = 1,4 do
		if party.party:getChampionByOrdinal(i):hasCondition("frozen") then 
			count = count + 1
		end
	end
	if count >= 2 then 
		GameMode.setGameFlag("DisableMovement", true)
		GameMode.setGameFlag("DisableMouseLook", true)
		GameMode.setGameFlag("DisableKeyboardShortcuts", true)
		party.frozen:enable()
		party.frozen:fadeIn(2)
		--party.frozen:fadeOut(10)
	elseif count == 1 then 
		conditionScripts.script.modifyPartyMovementSpeed()
		party.frozen:enable()
		party.frozen:fadeIn(3)
		--party.frozen:fadeOut(10)
	elseif count == 0 then 
		--party.frozen:disable()
		party.frozen:fadeOut(1)
	end
	---------------------------------------------------event FX
	if event == "onStart" then
		-------------------------------------------------
		playSound("frostbolt_hit")
		GameMode.fadeOut(0x55AAFF, 0)	
		GameMode.fadeIn(0x55AAFF, 3)
		party.party:shakeCamera(0.25, 0.25)
		party.frozen:enable()
		party.frozen:fadeIn(1)		
	---------------------------------------------------
	elseif event == "onTick" then
		if v <= 2 then
			-------------------------------------------------
			hudPrint(champion:getName().." splits and cracks the Frozen cage...")
			playSound("ice_hit")
			party.frozen:fadeOut(2)
			party.party:playScreenEffect("hit_ice_block")
			party.party:shakeCamera(1, 2)
			-------------------------------------------------
		elseif v > 2 then
			if math.random() < 0.2 then
				hudPrint(""..champion:getName().." struggles to break the Frozen cage...")
				party.party:playScreenEffect("damage_screen_blue")
				playSound("party_move_overloaded")
				party.frozen:enable()
				party.frozen:fadeIn(1)
				party.party:shakeCamera(0.35, 0.35)
			end
		else
			party.frozen:enable()
			party.frozen:fadeIn(1)
			--party.frozen:fadeOut(v)
		end
	---------------------------------------------------
	elseif event == "onStop" then
		-------------------------------------------------
		--party.party:playScreenEffect("clear_screen")
		party.frozen:disable()
		party.frozen:fadeOut(0)
		hudPrint(champion:getName().." breaks apart their Frozen cage!")
		playSound("glass_shatter_01")
		party.party:shakeCamera(1.5, 2)
		GameMode.fadeOut(0x55AAFF, 0)	
		GameMode.fadeIn(0x55AAFF, 1)
		party.party:playScreenEffect("crystal_shard_hit")
	end
end
Burning:
burning is one of the conditions that will Spread to other champs (given certain situs)
SpoilerShow

Code: Select all

defineCondition{
   	name = "burning",
   	uiName = "Burning",
   	description = "\nFire Damage over time\nSpreads to Furry Champions",	
   	icon = 5,
   	iconAtlas = "mod_assets/textures/conditions2.tga",
   	beneficial = false,
   	harmful = true,
   	tickInterval = 3,
   	onStart = function(self, champion, new)
		--------------------------------------------------melts Frozen dur, Frozen stops flames tho
		if champion:hasCondition("frozen") then
			champion:removeCondition("burning")
			party.burning:disable()
			party.burning:fadeOut(0.5)
			party.burnSound:disable()
			party.burnSound:fadeOut(0.5)
			champion:setConditionValue("frozen", math.ceil(champion:getConditionValue("frozen")/2))
			hudPrint(champion:getName().."'s solid Frost retards the Flames...")
		end
		-------------------------------------------------FX
		conditionScripts.script.burningFX(self, champion)
		-----------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("burning", champion:getOrdinal(), true)
		conditionScripts.script.addCondOccassion("burning", champion:getOrdinal(), 1)
		-------------------------------------------------------------------------------	
	end,
	onTick = function(self, champion)
		-------------------------------------------------FX
		conditionScripts.script.burningFX(self, champion)
		---------------------------------------------------feverBurn
		if champion:hasCondition("fever") then
			delayedCall("conditionScripts", 1.5, "feverBurn", self, champion, self:getDuration())
		end
		-----------------------------------------------------------Extend burning for Fur
		local burn = champion:hasCondition("burning")
		local burnV = champion:getConditionValue("burning")
		if burn and burnV >= 1 then
			---------------------------------------------------------
			if conditionScripts.script.checkBurningFur(champion) then
				if math.random() <= 0.25 then
					print("race weakness - duration +2")
					self:setDuration(self:getDuration() + 2)
				end
			end
		end
		--------------------------------------------------------------Spread burning to Fur
		for i = 1,4 do
			local s = party.party:getChampion(i)
			if i ~= champion:getOrdinal() 
			and conditionScripts.script.checkBurningFur(s) 
			and math.random() <= 0.15 then
				if not s:hasCondition("burning") then
					s:setCondition("burning")
					if s:hasCondition("burning") then
						print("race weakness - spreads to other champs")
						s:setConditionValue("burning", math.random(3,6))
						break
					end
				end
				if s:hasCondition("burning") then
					s:setConditionValue("burning", math.random(2,4))
					break
				end
			end
		end
		---------------------------------------------------------------Fire Damage
		local dmg = math.random(6,10)
		if champion:getCurrentStat("resist_fire") < 99 then	
			champion:playDamageSound()
			party.party:playScreenEffect("damage_screen")
		end	
		champion:damage(dmg, "fire")
		-------------------------------------------------------------flame-kin??
		-----------------------------------------------------------------------------
		conditionScripts.script.condTimeCount("burning", champion:getOrdinal())
		conditionScripts.script.storeCurrentCount("burning", champion:getOrdinal(), 1)
		--print("burning", self:getDuration())
		-----------------------------------------------------------------------------
   	end,
   	onStop = function(self, champion)
		-------------------------------------------------------FX
		if conditionScripts.script.checkBurningAll() then
			party.burning:setParticleSystem("burning_party")
			party.burnSound:setVolume(1)
		else
			party.burning:setParticleSystem("burning_champion")
			party.burnSound:setVolume(0.6)
		end
		party.burning:fadeOut(1)
		party.burnSound:fadeOut(1)
		--------------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("burning", champion:getOrdinal(), false)
		conditionScripts.script.wipeCurrCount("burning", champion:getOrdinal())
		---------------------------------------------------------------------------------
   	end,	
}
with a few extra FX... (I too have just placed a script in the onDie hook which removes lingering FX when champs die ;) )
SpoilerShow

Code: Select all

-------------------------------------------------------------------------------------------------------------------BURNING
function burningFX(self, champion)
	if conditionScripts.script.checkBurningAll() then
		party.burning:setParticleSystem("burning_party")
		party.burnSound:setVolume(1)
	else
		party.burning:setParticleSystem("burning_champion")
		party.burnSound:setVolume(0.6)
	end
	party.burning:enable()
	party.burning:fadeIn(1)
	party.burnSound:enable()
	party.burnSound:fadeIn(1)
end
-------------------------------------checkBurningFur(champion)
function checkBurningFur(champion)
	local ord = champion:getOrdinal()
	if burningFur[ord] then
		return true
	else
		return false
	end
end
----------------------------------------burningVengence(condition, champion, duration, damage)
function burningVengence(condition, champion, duration, damage)
	if condition and condition == "burning" then
		if champion:hasCondition("rage") then
			local r = champion:getConditionValue("rage")
			local d = 1
			if r < 20 then
				local d = d + (20 - r)
				champion:setConditionValue("rage", d)
			end
		end
	end
end
Bleeding: is on my list of maybes (it is/was going to be a secondary chance thing for the Chest Injury/wound)

I caught your Polymorph Chicken video in another thread - Super!
I havent got any new Polymorphs to show - one of those messy things I am hoping will be done as I go
I do have a Druid Class that features Shapeshifting as its main thang...
I had imagined maybe up to 3 - 5 polymorphs - but the Druid needs to find Stone Idols or Symbols first before he can unlock each one (nothing to show tho)

Also I noticed you mentioned - not forgetting to punish the player for trying to Sleep/rest off conditions
This is critical! - Disease is next to useless as a condition, as it was, and poison wasnt really scary either - I have seen to this!

Diseased:
Does not expire with time or sleep... it sticks... and then it Spreads! And causes secondary Conditions :cry:
SpoilerShow

Code: Select all

defineCondition{
   	name = "diseased",
   	uiName = "Diseased",
   	description = "\nNo Health Regeneration\nDevelops secondary Conditions\nSpreads to other Champions",
   	icon = 4,
   	beneficial = false,
   	harmful = true,
   	tickInterval = 0,
	onStart = function(self, champion, new)
		-----------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("diseased", champion:getOrdinal(), true)
		conditionScripts.script.addCondOccassion("diseased", champion:getOrdinal(), 1)
		-------------------------------------------------------------------------------	
	end,
	onTick = function(self, champion)
		----------------------------------
		self:setDuration(60)
		------------------------------------------------Spread to champs x3 x3 while sleeping, underground or underwater
		local lightCond = {"intoxicated", "weakened", "blinded", "slow", "fever"}
		local currT = conditionScripts.script.checkOccassionTotal("diseased", champion:getOrdinal())
		--local tile = party.map:getAutomapTile(party.x,party.y)
		local water = conditionScripts.script.checkPartyUnderwater()
		local under = gameMapEnvScripts.script.getMapUnderground()
		local m = 0.001
		if party.party:isResting() then
			m = m * 5
		end
		if water or under then
			m = m * 5
		end
		if currT > 100 and math.random() < m then
			for i = 1,4 do
				for i,j in pairs(lightCond) do
					if math.random() < 0.25 then
						if (math.random(1,40) > champion:getCurrentStat("vitality")) and math.random() < m then
							champion:setCondition(j)
							if not j == "fever" and champion:hasCondition(j) then
								champion:setConditionValue(j, 25)
								print("Develops into secondary conditions")
								break
							end
						end
					elseif champion:getOrdinal() ~= i and i ~= 5 then
						local victim = party.party:getChampion(i)
						if not victim:hasCondition("diseased") then
							if (math.random(1,50) > victim:getCurrentStat("vitality")) and math.random() < m then
								victim:setCondition("diseased")
								print("Diseased has been spread...")
								break
							end
						end
					end
				end
			end
		end
		-----------------------------------------------------------------------------
		conditionScripts.script.condTimeCount("diseased", champion:getOrdinal())
		conditionScripts.script.storeCurrentCount("diseased", champion:getOrdinal(), 1)
		--print("diseased", self:getDuration())
		-----------------------------------------------------------------------------
	end,
	onStop = function(self, champion)
		--------------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("diseased", champion:getOrdinal(), false)
		conditionScripts.script.wipeCurrCount("diseased", champion:getOrdinal())
		---------------------------------------------------------------------------------
	end,
}
Wild Fever:
another Spreading condition... less menacing but it spreads faster
SpoilerShow

Code: Select all

defineCondition{
   	name = "fever",
   	uiName = "Wild Fever",
   	description = "\nFood Consumption x5\nElemental Resistances -50\nQuickens other Condition Effects\nSpreads via other Conditions",
   	icon = 4,
   	iconAtlas = "mod_assets/textures/conditions2.tga",
   	beneficial = false,
   	harmful = true,
   	tickInterval = 0,
	onStart = function(self, champion, new)
		---------------------------------------------durationSet
		--loca dur = self:getDuration()
		--if not dur then
		--	self:setDuration(60)
		--end
		-----------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("fever", champion:getOrdinal(), true)
		conditionScripts.script.addCondOccassion("fever", champion:getOrdinal(), 1)
		-------------------------------------------------------------------------------	
	end,
	onTick = function(self, champion)
		------------------------------------------durationSet
		--loca dur = self:getDuration()
		--if dur and dur < 60 then
		self:setDuration(60)
		--end
		---------------------------------------------------------------------SpreadFever
		--init - onReceiveCondition - spread wildfever
		-----------------------------------------------------------------------------
		conditionScripts.script.condTimeCount("fever", champion:getOrdinal())
		conditionScripts.script.storeCurrentCount("fever", champion:getOrdinal(), 1)
		--print("fever", self:getDuration())
		-----------------------------------------------------------------------------
	end,
	onStop = function(self, champion)
		--------------------------------------------------------------------------------
		conditionScripts.script.setCondCurrent("fever", champion:getOrdinal(), false)
		conditionScripts.script.wipeCurrCount("fever", champion:getOrdinal())
		---------------------------------------------------------------------------------
	end,
	onRecomputeStats = function(self, champion)
		champion:addStatModifier("resist_fire", -50)
		champion:addStatModifier("resist_cold", -50)
		champion:addStatModifier("resist_poison", -50)
		champion:addStatModifier("resist_shock", -50)
		-------------------------------------------------
		local f = champion:getCurrentStat("food_rate")
		champion:addStatModifier("food_rate", f * 5)
   	end,
}
SpoilerShow
Image
...and yeah heaps more too :D :? :lol:
Conditions have been some of the more fun things to work on imho!
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: thoughts on a 'Frozen' condition

Post by akroma222 »

Lolz looking over some of this - I really do need to check more often if the Champs are even still alive/enabled/interested :lol: :roll:
User avatar
AndakRainor
Posts: 674
Joined: Thu Nov 20, 2014 5:18 pm

Re: thoughts on a 'Frozen' condition

Post by AndakRainor »

Just an advice; you should use a getChampions() function or something, like the one I defined for my spells pack (with some optional parameter to filter the resulting array). Call it from all spells where it is needed and you won't have to ever worry about it again.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: thoughts on a 'Frozen' condition

Post by akroma222 »

Yup, I know exactly the function youre referring to
Will do! :)
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: thoughts on a 'Frozen' condition

Post by Isaac »

What [exactly] is wrong with using the default "paralyzed" condition; (I must have missed it).
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: thoughts on a 'Frozen' condition

Post by zimberzimber »

Isaac wrote:What [exactly] is wrong with using the default "paralyzed" condition; (I must have missed it).
Some things rendering the champion immune to it
Multiple conditions with same effect might remove it while its still needed
Visual clutter
Wrong/Irrelevant "Paralyzed" text on attack UI
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
AndakRainor
Posts: 674
Joined: Thu Nov 20, 2014 5:18 pm

Re: thoughts on a 'Frozen' condition

Post by AndakRainor »

Warning:

PartyComponent.onClickItemSlot(self, champion, container, slot, button) => champion is nil if you click on the attack panel's hands

Your hooks could cause a crash!
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: thoughts on a 'Frozen' condition

Post by akroma222 »

Yup it sure is - thanks for the reminder to update here! ;)
Post Reply