LoG Framework (dynamic hooks etc.)

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

@Neikun: You can always deactivate the turn based mode and run away. Press the "rest key" (normally R, but L in your case ) at the beginning of your turn, it will deactivate it. But you must run fast after that because if the monster reaches to attack you again the turn based mode will be activated again.

Edit: or did you mean that the L key isn't working? If not, then it's a bug in LoG.

I get it, you meant that before you knew that you have to press the "rest key" there was no way to continue...
better go to sleep. :)
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
Neikun
Posts: 2457
Joined: Thu Sep 13, 2012 1:06 pm
Location: New Brunswick, Canada
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by Neikun »

Nigh nigh, JKos!
"I'm okay with being referred to as a goddess."
Community Model Request Thread
See what I'm working on right now: Neikun's Workshop
Lead Coordinator for Legends of the Northern Realms Project
  • Message me to join in!
User avatar
Merethif
Posts: 274
Joined: Tue Apr 24, 2012 1:58 pm
Location: Poland

Re: LoG Framework (update: experimental turn based combat)

Post by Merethif »

I've tried turn based combat and it's pretty deadly :-D Backstabbing doesn't work at all. Also I'm unable to kite monsters with ranged weapon.

I love damage dealing doors, illusionary walls and party conversation though :-)
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

Just updated the framework on my google drive.

Added a bunch of features and updated the documetation.

Biggest change: Hook support for - spells, alcoves, blockages, items and item subcategories(see documentation)

Example (item subcategory-hook)

Code: Select all

-- Common hook for all items if food category 
	fw.addHooks('items_food','insectoids_dont_eat_food',{
		onUseItem = function(self,champion)
			if champion:getRace() == 'Insectoid' then
				hudPrint("Yarrrgghh! I dont't "..self:getUIName().." you fool!")
				return false
			end
		end
	})	
Installation documentation also fixed, so it should now work if you want to try this in your own dungeon. It doesn't break anything and can be removed easily if you don't like it :).
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
djoldgames
Posts: 107
Joined: Fri Mar 23, 2012 11:28 pm
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by djoldgames »

Great updates JKos, as usual ;-)
I must try the new hooks...

Only module I use from your stuff is illusion_walls, and there are some some minor updates:

Code: Select all

illusion_walls.activeWalls[wall.id] = wall
This "sort" of storage for object instances in the global variables (tables), on save Game throw well-known error message "cannot serialize table with metatable".
It is necessary to storing only object ID's and next in Deactivate functions using the findEntity(ID).

This was the hard-to-find-bug because the timer value is only 2 seconds :twisted:
and 0.01 in previous versions...

I have small request (for next updates of framework, that I did not change your code again ;-)): it is possible for you to change ID's creation with suffix "_fake" unlike the prefix "fake_" there?

Code: Select all

if not findEntity(wall.id.."_fake") then
     spawn(wall.name.."_fake", wall.level, wall.x, wall.y, wall.facing, wall.id.."_fake")
end
Because in EOB mod we create the object instance names with prefixes "eob_" and wallset "sewers_" with "_fake" suffix (if present) at the end.
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

@djoldgames: Good catch that serialization problem, I thought I had fixed them all, I will fix that one too in next version. Sorry if I caused you grey hairs :D
And you are right, suffix would be better. I will change that too.
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

new version updated to google drive. Changes mentioned in above post are made, and added a new function to help script entity.
I finally understood how iterators work in lua :)

I will post it here, may be helpful to someone.

Code: Select all

-- returns an iterator which iterates all entities at level filtered by names-list. 
-- If level is not defined, entites at party.level are iterated
-- Examples: 
-- for entity in help.iEntitiesByName('snail',1) do
--		print(entity.id)
-- end	
-- 
-- for entity in help.iEntitiesByName({'snail','crowern'}) do ...

function iEntitiesByName (names,level)
	if type(names) == 'string' then names = {names} end
	level = level or party.level
	local allEntsIt = allEntities(level)
	names = help.tableToSet(names)	
	local iter = function()
		local nextEnt = allEntsIt() 
		while nextEnt do 
			if names[nextEnt.name] then
				return nextEnt
			end
			nextEnt = allEntsIt()
		end	
	end
	return iter
end
It is basically a wrapper to allEntities-iterator
It's possible to do this much simpler way by just returning table of entities, but iterators are usually more effective.
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

Bug found: spell-hooks do not work as they can not be cloned by cloneObject, so I will try to find other solution or remove spells hook-namespace completely.
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: LoG Framework (update: experimental turn based combat)

Post by JKos »

Fixed spell support and made 2 spells: hold_monster and magic_missile
When you define spells you don't use defineSpell but createSpell function.

Code: Select all

createSpell(
	{
	   name = "hold_monster",
	   uiName = "Hold monster",
	   skill = "spellcraft",
	   level = 0,
	   runes = "AC",
	   manaCost = 15,
	}
)
createSpell(
	{
	   name = "magic_missile",
	   uiName = "Magic missile",
	   skill = "fire_magic",
	   level = 0,
	   runes = "AD",
	   manaCost = 15,
	}
)
Difference to defineSpell is that you don't define onCast-hook because hooks are defined in script entities.

Here is the fw_spells script entity

Code: Select all

	
activeSpells = {}

immunityList = {}
immunityList.hold_monster = {
	skeleton_archer=true,
	skeleton_warrior=true
}
	
function activate()	
	addSpell('hold_monster',holdMonster)
	addSpell('magic_missile',magicMissile)
end

function addSpell(spellName,hookFunction)
	fw.addHooks(spellName,'fw_spells',{
			onCast = hookFunction
		}
	)
end

function magicMissile(champ, x, y, direction, skill)
	local dx,dy = getForward(party.facing)
	playSoundAt("fireball_launch",party.level,party.x,party.y)
	shootProjectile('magic_missile', party.level, party.x+dx, party.y+dy, direction, 14, 0, 0, 0, 0, 0, skill*5, nil, true)
	
end

function shootSpell(fx,dir,speed)
 local timer = spawn('timer',party.level,0,0,0)
 
end

function holdMonster(champ, x, y, direction, skill)
	local holdMonster = function() return false end
	
	local monster = help.nextEntityAheadOf(party,3,'monster')
	if not monster then return false end
	if immunityList.hold_monster[monster.name] then return false end
	local timerId = createSpellTimer(monster,10+skill,'holdMonsterDestructor')
	playSoundAt("frostbolt_launch",party.level,party.x,party.y)
	
	fw.debugPrint(monster.id..' held')
       --dynamically add hooks which prevents monster to attack or move	
	-- use spellId as hook-id so the hook can be removed on destructor
	fw.addHooks(monster.id,timerId,{
		onMove = holdMonster,
		onAttack = holdMonster,
		onRangedAttack = holdMonster,
		onTurn = holdMonster
	},
	1)
	return true
end

function holdMonsterDestructor(timer)
	fw.removeHooks(activeSpells[timer.id],timer.id)
	fw.debugPrint(activeSpells[timer.id]..' unheld')
	timer:deactivate()
	timer:destroy()

end

-- creates a  spell timer
-- entity = affected entity, 
-- time = how many seconds spells effect  lasts 
-- destructorName = name of the function which is called when the effect of the spell is worn out.
-- returns id of timer
function createSpellTimer(entity,time,destructorName)
	local timer = spawn('timer',party.level,0,0,0)
	timer:setTimerInterval(time)
	-- store entity.id to table indexed by timer.id so we can access it in spell-destructor
	activeSpells[timer.id] = entity.id
	timer:addConnector('activate','fw_spells',destructorName)
	timer:activate()
	return timer.id
end
Hold monster was surprisingly tough one to code, but i'm pretty happy with it now. Without my hook-framework it would have been much harder to implement. Magic missile was trivial and it can be done without this framework.

Here is item definition and particleSystems for magic missile.

Code: Select all

defineObject{
		name = "magic_missile",
		class = "Item",
		uiName = "Magic missile",
		model = "assets/models/items/quarrel.fbx", --assets/models/items/arrow.fbx
		--ammoType = "arrow",
		gfxIndex = 109,
		attackPower = 1,
		impactSound = "fireball_hit",
		particleEffect = "magic_missile",
		stackable = false,
		sharpProjectile = false,
		projectileRotationY = 90,
		weight = 0.1,
}
defineParticleSystem{
	name = "magic_missile",
	emitters = {
		-- flames
		{
			emissionRate = 50,
			emissionTime = 0,
			maxParticles = 50,
			boxMin = {-0.0, -0.0, 0.0},
			boxMax = { 0.0, 0.0,  -0.0},
			sprayAngle = {0,360},
			velocity = {0.3, 0.3},
			texture = "assets/textures/particles/torch_flame.tga",
			frameRate = 35,
			frameSize = 64,
			frameCount = 16,
			lifetime = {0.8, 0.8},
			colorAnimation = true,
			color0 = {1, 1, 1},
			opacity = 1,
			fadeIn = 0.15,
			fadeOut = 0.3,
			size = {0.125, 0.25},
			gravity = {0,0,0},
			airResistance = 1,
			rotationSpeed = 1,
			blendMode = "Additive",
			objectSpace = true,
		},

		-- glow
		{
			spawnBurst = true,
			emissionRate = 1,
			emissionTime = 0,
			maxParticles = 1,
			boxMin = {0,0,-0.1},
			boxMax = {0,0,-0.1},
			sprayAngle = {0,30},
			velocity = {0,0},
			texture = "assets/textures/particles/glow.tga",
			lifetime = {1000000, 1000000},
			colorAnimation = false,
			color0 = {1, 1, 1},
			opacity = 1,
			fadeIn = 0.1,
			fadeOut = 0.1,
			size = {0.8, 0.8},
			gravity = {0,0,0},
			airResistance = 1,
			rotationSpeed = 2,
			blendMode = "Additive",
			objectSpace = true,
		}
	}
}
You can try it in action by downloading my demo dungeon from google drive
https://docs.google.com/open?id=0B7cR7s ... UN4SGZGNEk
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
User avatar
djoldgames
Posts: 107
Joined: Fri Mar 23, 2012 11:28 pm
Contact:

Re: LoG Framework - Spells

Post by djoldgames »

Excellent work!
Thank you for this spells, especialy hold monster and SpellTimer. Now i must update fw and try them in mod.

Can you recreate more specific spells for our Eye of the Beholder mod from original EOB (AD&D)?
If you want the original manual, where are spells described, let me know.
Post Reply