[script]How to make testing easier by scripting

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

[script]How to make testing easier by scripting

Post by JKos »

I finally started to create my own dungeon, but I found the testing part too tedious and time consuming so I ended up to write some scripts to help out the testing process.
Here are the results:

Code: Select all

	modifyChampion{
		 id=1,
		 levelUp = 1,
		 items = {
			[1]=peasant_cap_1,
			[2]=peasant_tunic_1,
			[4]='nomad_boots',
			[14]='rock*3',
			
		 },
		 statsUp = {
			dexterity=1
		 },
		 skillsUp = {
			swords=4
		 }
	}
This script will do the following magic:
- Level up champion 1
- Add the peasant_cap_1 to head slot and remove it from dungeon
- Add the peasant_tunic_1 to torso slot and remove it from dungeon
- Spawn 'nomad_boots' to feet slot
- Spawn 3 rocks to inventory slot 14
- Raise dexterity by 1 point
- Train swords skill by 4 points

But there is more: the function can be called multiple times. So if I add this below the previous function call:

Code: Select all

	modifyChampion{
		 id=1,
		 levelUp = 1,
		 items = {
			[1]=leather_cap_1,
			[14]=false,
         }			
		 skillsUp = {
			axes=4
		 }		 
	}
It will do the following things:
- Level up another level (to level 3)
- Replace peasant_cap_1 with leather_cap_1
- Remove rocks from slot 14
- Train axes skill by 4 points more


Sources:
Copy paste to some script entity (eg. testing)

Code: Select all

--[[
slots: 
1 (head), 2 (torso), 3 (legs), 4 (feet), 5 (cloak), 6 (neck), 
7 (left hand), 8 (right hand), 9 (gaunlets), 10 (bracers), 11-31 (backpack slots).
]]
function modifyChampion(def)
	local champ = party:getChampion(def.id)
	if def.items then
		for slot,item in pairs(def.items) do
			
			champ:removeItem(slot)
			
			if type(item) == 'string' then 
				local parts = split(item,'*')
				item = spawn(parts[1])
				if parts[2] then
					item:setStackSize(0+parts[2])
				end
				champ:insertItem(slot,item)
			elseif type(item) == 'table' then
			   
				item = recreateItem(item)
				if item then
					champ:insertItem(slot,item)
				end
			end
		end
	end
	if def.levelUp then
		for i=1,def.levelUp do
			champ:levelUp()
		end
	end
	if def.statsUp then
		for stat,valueUp in pairs(def.statsUp) do
			champ:modifyStat(stat,valueUp)
		end	
	end
	if def.skillsUp then
		for skill,valueUp in pairs(def.skillsUp) do
		    if champ:getSkillPoints() < valueUp then 
				valueUp = champ:getSkillPoints() 
			end
			champ:trainSkill(skill,valueUp,false)
		end	
	end	
	
end
-- remove existing item from dungeon and recreate it with same id
function recreateItem(item)
	if item == nil then 
		print('item not found')
		return  
	end
	local id = item.id
	local name = item.name
	local scrollText = item:getScrollText()
	local fuel = item:getFuel()
	local charges = item:getCharges()
	local stack = item:getStackSize()
	item:destroy()
	item = spawn(name,nil,nil,nil,nil,id)
	if scrollText then item:setScrollText(scrollText) end
	if fuel > 0 then item:setFuel(fuel) end
	if charges > 0 then item:setCharges(charges) end
	if stack > 0 then item:setStackSize(stack) end
	return item
end

-- splits string by delimeter
-- Example: help.split('split.me.ok','.')
function split(p,d)
  local t, ll
  t={}
  ll=0
  if(#p == 1) then return {p} end
    while true do
      l=string.find(p,d,ll,true) -- find the next d in the string
      if l~=nil then -- if "not not" found then..
        table.insert(t, string.sub(p,ll,l-1)) -- Save it in our array.
        ll=l+1 -- save just after where we found it for searching next time.
      else
        table.insert(t, string.sub(p,ll)) -- Save what's left in our array.
        break -- Break at end, as it should be, according to the lua manual.
      end
    end
  return t
end
Longer example from my dungeon. It also shows the method that I use to control the spawning location of the party while testing.
Idea is that the tests are stackable so I don't have to modify the previously defined tests when I want to test a new dungeon location, I just write a new one.

Code: Select all

function activate()
	local level,x,y
	level,x,y = test1()
	level,x,y = test2()

	local portal = spawn('teleporter',party.level,party.x,party.y,party.facing,'test_teleport')
	portal:setTriggeredByMonster(false)
	portal:setTriggeredByItem(false)
	portal:setTeleportTarget(x,y,1,level)
	portal:setInvisible(true)
end

-- location 1 test
function test1()
	testing.modifyChampion{
		 id=1,
		 levelUp = 1,
		 items = {
			[1]=peasant_cap_1,
			[2]=peasant_tunic_1,
			[4]='nomad_boots',
			[8]='legionary_shield',
			[14]='rock*3',
			
		 },
		 statsUp = {
			dexterity=1
		 },
		 skillsUp = {
			swords=4
		 }
	}
	testing.modifyChampion{
		 id=2,
		 levelUp = 1,
		 items = {
			[1]=leather_cap_1,
			[7]=hand_axe_1,
		 },
		 skillsUp = {
			axes=4
		 }
	}	
	testing.modifyChampion{
		 id=3,
		 levelUp = 1,
		 items = {
			[7]='legionary_spear',
		 },
		 skillsUp = {
			assassination=4
		 }
	}	
	testing.modifyChampion{
		 id=4,
		 levelUp = 1,
		 items = {
			[7]=note_1,
		 },
		 skillsUp = {
			air_magic=4
		 }
	}			
	return 1,20,11
end

-- location 2 test
function test2()
	testing.modifyChampion{
		 id=1,
		 levelUp = 1,
		 skillsUp={swords=2,armors=2}
	}	
	testing.modifyChampion{
		 id=2,
		 levelUp = 1,
		 skillsUp={axes=4}
	}	
	testing.modifyChampion{
		 id=3,
		 levelUp = 1,
		 skillsUp={assassination=4}
	}	
	testing.modifyChampion{
		 id=4,
		 levelUp = 1,
		 skillsUp={fire_magic=4}
	}				
	return 1,13,21
end
I hope you find it useful :) I spent the whole evening writing 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
Komag
Posts: 3658
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: [script]How to make testing easier by scripting

Post by Komag »

This can be very useful for advanced users with larger complex dungeons, thanks! Superthreaded!
Finished Dungeons - complete mods to play
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: [script]How to make testing easier by scripting

Post by JKos »

Thanks Komag. I think there could be other uses too, for example as a party setup tool. And for altering inventories and stats more easily than using native functions.
- 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
SnowyOwl47
Posts: 148
Joined: Fri Sep 12, 2014 10:41 pm

Re: [script]How to make testing easier by scripting

Post by SnowyOwl47 »

Very useful
Post Reply