possible to raise or lower "ProjectileSpell" light height?

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

possible to raise or lower "ProjectileSpell" light height?

Post by Komag »

I can adjust the height of the particle system in its definition using boxMin and boxMax, but there doesn't seem to be any control for the ProjectileSpell light itself.

For "LightSource" objects we have lightPosition = vec(0, 4.5, 0), for example, but lightPosition doesn't seem to have any effect on ProjectileSpells.

Is there some other variable or way of doing it? For example, a way to make a fireball shoot very low near the floor as it goes across the room?
Finished Dungeons - complete mods to play
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by Komag »

I've faked the effect by spawning a zillion short-lived fx lights in a row along the path, and it works and looks decent but hurts the framerate/performance somewhat for a few seconds
Finished Dungeons - complete mods to play
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by Diarmuid »

Doesn't fx:translate work?

Here's an adapted version of the fx animation function from exsp which simulates ProjectileSpell effects. It normally relies on spell info stored by exsp:defineSpell functions, and self is the spell object. You can however use it by passing the function a table that has the following values defined (random values below):

Code: Select all

spellData = {
	_particleSystem = "fireball",
	_projectileSpeed = 7.5,
	_lightColor = {1.0, 1.0, 4.0},
	_lightBrightness = 15,
	_lightRange = 7,
	_castShadow = true,
	_vOffset = 1.35,
}
projectileAnimator script entity below. It sends the fx object flying from level,x, y towards facing, for a distance tiles, and if destroyFx is true, it destroys it after the distance.

Code: Select all

function animateFxObject(self, level, x, y, facing, distance, destroyFx)
	
	-- Set particle system FX
	local fxId = projectileAnimator.randomId("launchAnimationFx")
	local vOffset = self._vOffset or 1.35
	spawn("fx", level, x, y, facing, fxId):setParticleSystem(self._particleSystem)
	
	local red, green, blue = unpack(self._lightColor)
	local time = 10000
	findEntity(fxId):setLight(red, green, blue, self._lightBrightness, self._lightRange, time, self._castShadow)
	findEntity(fxId):translate(0,vOffset,0)
		
	-- Animate FX with timer
	local dx, dy = getForward(facing)
	local interval = self._projectileSpeed/20
	
	dx = dx * interval
	dy = dy * interval

	local fxTimer = timers:create(projectileAnimator.randomTimerId("fxTimer"))
	fxTimer:setTimerInterval(0.05)
	fxTimer:addCallback(
		function(self, fxId, dx, dy)
			if findEntity(fxId) then
				findEntity(fxId):translate(dx,0,-dy)
			end
		end,
		{fxId, dx, dy}
	)
	fxTimer:setTickLimit(math.ceil((20/(self._projectileSpeed/3))*distance),true)
	fxTimer.fxId = fxId
	fxTimer.destroyFx = destroyFx
	fxTimer.onDeactivate = function(self)
			if self.destroyFx then
				projectileAnimator.delay(0.2, 
					function(self, fxId)
						if findEntity(fxId) then
							findEntity(fxId):destroy()
						end
					end,
					{self.fxId}
				)					
			end
		end
	fxTimer:activate()
	
	return fxId
end

function delay(delay, funct, args)
	local delayId = projectileAnimator.randomTimerId("delay")
	local delayTimer = timers:create(delayId)
	delayTimer:setTimerInterval(delay)
	delayTimer:addCallback(funct,args)
	delayTimer:setTickLimit(1,true)
	delayTimer:activate()
	return delayId
end

function randomId(prefix)
	local numId = math.random(10000,99999)
	while findEntity(prefix.."."..numId) do
		numId = math.random(10000,99999)
	end
	return prefix.."."..numId
end

function randomTimerId(prefix)
	local numId = math.random(10000,99999)
	while timers:find(prefix.."."..numId) do
		numId = math.random(10000,99999)
	end
	return prefix.."."..numId
end
EDIT: If you just want a moving light (no visuals), remove the setParticleSystem bit of code from the function where it spawns the fx.

EDIT2: You can adapt this to create effects of spells flying vertically, diagonally...

EDIT3: Framework required obviously, for timers.
User avatar
Komag
Posts: 3659
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by Komag »

Thanks for your detailed reply! I'm not using your solution but reading through it has give me some clues how to change my setup to run much better, so it has been very very helpful! 8-)

I previously was overlapping multiple fx lights, all slightly more and more offset from an original position, but now I understand that offset if cumulative, so I can just have one light that "moves" instead of adding a new light every time, much more efficient!

I'm able to do what I want quite well now, so thanks again! :)
Finished Dungeons - complete mods to play
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by akroma222 »

Hey Guys,
very useful stuff here, I am also messing around with lights, particles and projectiles...
Just a question Diarmuid - which "framework" do I require to run the code??

Cheers! :)
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by Diarmuid »

The JKos one. (These are functions I extracted from the EXSP framework so that they can function standalone, but if you have exsp you can just call them from there...)
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: possible to raise or lower "ProjectileSpell" light heigh

Post by akroma222 »

Sweet, onto it :D
Thanks again Diarmuid, you have put a lot of work into this!!
Post Reply