cloneObject for LoG2 (update: modifyObjects)

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

cloneObject for LoG2 (update: modifyObjects)

Post by JKos » Fri Nov 21, 2014 9:00 pm

CHANGE LOG:
30.11.2014: Everyone should update the script, it had a pretty serious bug which modified the baseObject's values instead of the clone's values. (thanks cromcrom for the bug report)
03.12.2014: added modifyObjects function and changed installation method so that clone_object.lua must be included before standard_assets.lua. (before this you had to replace standard_assets.lua with clone_object.lua)


Hello,

Inspired by JohnWordsworth's asset definition scraper I wrote a cloneObject-function for LoG 2

save this to mod_assets/scripts/clone_object.lua

Code: Select all


oldDefineObject = defineObject;
defines = { };

defineObject = function(data) 
	defines[data.name] = data;
	oldDefineObject(data);
	
	if type(onDefineObject) == 'function' then
		onDefineObject(data)
	end
end

function mergeTableValues(source,target)
	for key,val in pairs(source) do
		if key ~= 'components' and target[key] == nil then
			target[key] = val
		end
	end
end

function findComponent(def,name)
	if def.components == nil then return false end
	for _,component in ipairs(def.components) do
		if component.name == name or (component.class and string.lower(component.class) == name) then
			return component
		end
	end
	return false
end

function cloneObject(data)
	local baseObjectName = data.baseObject or data.name
	local baseObj = defines[baseObjectName]
	if not baseObj then
		print('WARNING (cloneObject): Invalid base object '..baseObjectName)
		return
	end

	-- copy components from the base object to the new object
	if baseObj.components then
		if data.components == nil then 
			data.components = {}
		end
		for _,baseComponent in ipairs(baseObj.components) do
			local name = baseComponent.name or string.lower(baseComponent.class)
			local newComponent = findComponent(data,name)
			if not newComponent then
				newComponent = {}
				table.insert(data.components,newComponent)
			end
			mergeTableValues(baseComponent,newComponent)
		end
	end
	mergeTableValues(baseObj,data)
	defineObject(data)
end

function modify_object_cleanup()
	defines = nil
end

function copy(obj, seen)
  if type(obj) ~= 'table' then return obj end
  if seen and seen[obj] then return seen[obj] end
  local s = seen or {}
  local res = {}
  s[obj] = res
  for k, v in pairs(obj) do res[copy(k, s)] = copy(v, s) end
  return res
end

function modifyObjects(def)
	local filter = def.filter.hasComponents

	for name,obj in pairs(defines) do
		local ok = true
		for _,filterComponent in ipairs(filter) do
			local c = findComponent(obj,filterComponent)
			if not c then 
				ok = false 
				break 
			end
		end
		
		if ok then
			local modifyDef = copy(def)
			modifyDef.filter = nil
			modifyDef.name = obj.name
			cloneObject(modifyDef)
		end
	end

end
and include it to your init.lua like this
import "mod_assets/scripts/clone_object.lua"
BEFORE the line
import "assets/scripts/standard_assets.lua"



It works like cloneObject in LoG1 so you can just override one or multiple properties of the component, instead of defining all values like with defineObject.

for example:

Code: Select all

cloneObject{
	name = 'ratling1_test',
        baseObject = 'ratling1',
	components = {
		{
			name = "monster",
			onPerformAction = function(self,action) print(action) end
		}
	},
}
if you simply want to modify a specific object you can just leave the baseObject out from definition.

Code: Select all

cloneObject{
	name = 'ratling1',
	components = {
		{
			name = "monster",
			onPerformAction = function(self,action) print(action) end
		}
	},
}
Don't know if this is necessary but just in case you should call
modify_object_cleanup()
at the end of your init.lua, it just clears object definitions from memory.

Please post here if you notice any problems with this.
Last edited by JKos on Wed Dec 03, 2014 11:44 pm, edited 11 times in total.
- 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: cloneObject for LoG2

Post by JKos » Fri Nov 21, 2014 9:31 pm

Just for clarification: with defineObject you have do that example like this:

Code: Select all

defineObject{
	name = 'ratling1',
	baseObject='ratling1',
	components = {
		{
			hitSound = "ratling_hit",
			protection = 3,
			health = 250,
			class = "Monster",
			evasion = 6,
			meshName = "ratling_mesh",
			footstepSound = "ratling_footstep",
			exp = 150,
			hitEffect = "hit_blood_small",
			capsuleRadius = 0.7,
			dieSound = "ratling_die",
			name = "monster",
			capsuleHeight = 0.2,
			onPerformAction = function(self,action) print(action) end
		}
	}
}
- 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

NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: cloneObject for LoG2

Post by NutJob » Fri Nov 21, 2014 9:33 pm

Invaluable! Thank you very much for this.

User avatar
msyblade
Posts: 792
Joined: Fri Oct 12, 2012 4:40 am
Location: New Mexico, USA
Contact:

Re: cloneObject for LoG2

Post by msyblade » Sat Nov 22, 2014 12:54 am

Great work. . .Just. . .Great work Jkos. Thanks!
Currently conspiring with many modders on the "Legends of the Northern Realms"project.

"You have been captured by a psychopathic diety who needs a new plaything to torture."
Hotel Hades

Grimfan
Posts: 369
Joined: Wed Jan 02, 2013 7:48 am

Re: cloneObject for LoG2

Post by Grimfan » Sat Nov 22, 2014 1:33 am

Now this is an invaluable addition to the modding armory.

Great work as always Jkos (and John for his inspiration). :D

User avatar
Drakkan
Posts: 1317
Joined: Mon Dec 31, 2012 12:25 am

Re: cloneObject for LoG2

Post by Drakkan » Sat Nov 22, 2014 2:05 am

that could really save lots of time, thanks !
Breath from the unpromising waters.
Eye of the Atlantis

User avatar
Aisuu
Posts: 61
Joined: Fri Oct 31, 2014 2:07 pm

Re: cloneObject for LoG2

Post by Aisuu » Sat Nov 22, 2014 10:16 am

Oh, my JKos :)

I got problem with install :cry:
clone_object.lua:35: bad argument #1 to 'lower' (string expected, got nil)

User avatar
Doridion
Posts: 256
Joined: Tue Jun 10, 2014 9:23 pm

Re: cloneObject for LoG2

Post by Doridion » Sat Nov 22, 2014 12:23 pm

Excellent work JKos ^^ Sticked in the superthread !

User avatar
strangely
Posts: 25
Joined: Mon Oct 29, 2012 2:28 am
Location: Tucson, AZ

Re: cloneObject for LoG2

Post by strangely » Sat Nov 22, 2014 7:44 pm

I used the cloneObject script as a basis for a cloneSkill script I made.
Details here:
viewtopic.php?p=85615#p85615

User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: cloneObject for LoG2

Post by JKos » Sun Nov 23, 2014 10:18 pm

Updated: Added support for new components. So you can now also add new components, not only modify existing ones. (Maybe this fixes Aisuu's problem 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

Post Reply