Detect light level

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: Detect light level

Post by Diarmuid »

There you go!

This should go in objects.lua
SpoilerShow

Code: Select all

cloneObject{
   name = "party",
   baseObject = "party",
   onCastSpell = function(caster, spell)
      return lightTracker.spellTrack(caster, spell)
   end,
}
then this should go in a script entity named lightTracker
SpoilerShow

Code: Select all

lightLevel = 0

function lightTrack(sourceTimer)
	if sourceTimer.level == party.level then
		if lightLevel > 0 then
			lightLevel = lightLevel - 0.25
		elseif lightLevel < 0 then
			lightLevel = lightLevel + 0.25
		end
	end
end

function spellTrack(caster, spell)
	if spell == "light" then
		if lightLevel >= 0 then
			lightLevel = 600
		elseif lightLevel < 0 then
			lightLevel = 0
		end
  	end
	if spell == "darkness" then
		if lightLevel > 0 then
			lightLevel = 0
		elseif lightLevel <= 0 then
			lightLevel = -600
		end
  	end
end

function lightState()
	local lightReturn = false
	local currentItem
    local champion
    for champID=1,4 do
      	champion = party:getChampion(champID)
      	currentItem = champion:getItem(7)
      	if currentItem ~= nil then
         	if currentItem.name == "torch"
          		or currentItem.name == "torch_everburning" 
				or currentItem.name == "magic_orb" then
	            lightReturn = true
	         end
      	end
      	currentItem = champion:getItem(8)
      	if currentItem ~= nil then
         	if currentItem.name == "torch"
          		or currentItem.name == "torch_everburning" 
				or currentItem.name == "magic_orb" then
	            lightReturn = true
            end
      	end
   	end
	if lightLevel > 0 then
		lightReturn = true
	end
	if lightLevel < 0 then
		lightReturn = false
	end
	return lightReturn
end
You then need to put a 0.25 interval timer on every level that activates lightTracker.lightTrack()

There is a lightLevel variable which goes from -600 to 600 and expresses light/darkness remaining time. You can access it directly in other scripts/script entities through lightTracker.lightLevel.

I've also provided a function to easily check light, which you can call through lightTracker.lightState(). It checks for active light and darkness spells, if champions carry any active torches or magic orb, and interactions between torches and spells, and returns true or false. (For example, if you carry a torch in the hand, but a Darkness spell is active, it will return false). An example usage:
SpoilerShow

Code: Select all

function lightTest()
	if lightTracker.lightState() == true then
		hudPrint("There is Light")
	end
	if lightTracker.lightState() == false then
		hudPrint("It is dark")
	end		
end
lightState() doesn't check for wall torches, of course, but these can be easily taken into acount separately.

Enjoy! ;)

Credits to LordYig's darkness zone script from which I borrowed and modified some elements for the above code.
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Detect light level

Post by Komag »

Brilliant script, must more direct and straightforward than my bulky setup :D

don't forget to account for a champion carrying an empty torch
Finished Dungeons - complete mods to play
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: Detect light level

Post by Diarmuid »

Thank you Komag, I didn't think of it because somehow I though the object name changed when the torch burned out.

Here's the updated code, now lightState() only returns true if it detects a torch with fuel > 0.

Code: Select all

lightLevel = 0

function lightTrack(sourceTimer)
	if sourceTimer.level == party.level then
		if lightLevel > 0 then
			lightLevel = lightLevel - 0.25
		elseif lightLevel < 0 then
			lightLevel = lightLevel + 0.25
		end
	end
end

function spellTrack(caster, spell)
	if spell == "light" then
		if lightLevel >= 0 then
			lightLevel = 600
		elseif lightLevel < 0 then
			lightLevel = 0
		end
  	end
	if spell == "darkness" then
		if lightLevel > 0 then
			lightLevel = 0
		elseif lightLevel <= 0 then
			lightLevel = -600
		end
  	end
end

function lightState()
	local lightReturn = false
	local currentItem
    local champion
    for champID=1,4 do
      	champion = party:getChampion(champID)
      	currentItem = champion:getItem(7)
      	if currentItem ~= nil then
         	if currentItem.name == "torch" and currentItem:getFuel() > 0 then
					lightReturn = true
			elseif currentItem.name == "torch_everburning" 
			  or currentItem.name == "magic_orb" then
	            lightReturn = true
	        end
      	end
      	currentItem = champion:getItem(8)
      	if currentItem ~= nil then
         	if currentItem.name == "torch" and currentItem:getFuel() > 0 then
					lightReturn = true
			elseif currentItem.name == "torch_everburning" 
			  or currentItem.name == "magic_orb" then
	            lightReturn = true
	        end
      	end
   	end
	if lightLevel > 0 then
		lightReturn = true
	end
	if lightLevel < 0 then
		lightReturn = false
	end
	return lightReturn
end
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Detect light level

Post by Komag »

will this line:

Code: Select all

if currentItem.name == "torch" and currentItem:getFuel() > 0 then
cause a problem if there is an item that is not a torch? will rock:getFuel() cause a crash or just return nil? if it's nil then I think everything is all set
Finished Dungeons - complete mods to play
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: Detect light level

Post by Diarmuid »

I've tested it, and getFuel() only crashes if used on an empty slot. If not, it returns 0 for any other item (ie, longsword:getFuel() returns 0).
User avatar
petri
Posts: 1917
Joined: Thu Mar 01, 2012 4:58 pm
Location: Finland

Re: Detect light level

Post by petri »

Also, the second condition after the "and" will not be evaluated if the first condition is false.

So getFuel() will only be called if the item is a torch.
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Detect light level

Post by Komag »

Ah, I didn't know that about the "and" code, thanks!
Finished Dungeons - complete mods to play
Post Reply