Page 4 of 16

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

Posted: Mon Oct 08, 2012 10:43 pm
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. :)

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

Posted: Mon Oct 08, 2012 11:03 pm
by Neikun
Nigh nigh, JKos!

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

Posted: Mon Oct 08, 2012 11:18 pm
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 :-)

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

Posted: Wed Oct 10, 2012 11:18 pm
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 :).

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

Posted: Thu Oct 11, 2012 8:42 pm
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.

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

Posted: Thu Oct 11, 2012 9:12 pm
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.

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

Posted: Thu Oct 11, 2012 9:51 pm
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.

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

Posted: Thu Oct 11, 2012 10:45 pm
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.

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

Posted: Sun Oct 14, 2012 6:27 pm
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

Re: LoG Framework - Spells

Posted: Sun Oct 14, 2012 6:50 pm
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.