Page 1 of 4

cloneObject for LoG2 (update: modifyObjects)

Posted: Fri Nov 21, 2014 9:00 pm
by JKos
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.

Re: cloneObject for LoG2

Posted: Fri Nov 21, 2014 9:31 pm
by JKos
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
		}
	}
}

Re: cloneObject for LoG2

Posted: Fri Nov 21, 2014 9:33 pm
by NutJob
Invaluable! Thank you very much for this.

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 12:54 am
by msyblade
Great work. . .Just. . .Great work Jkos. Thanks!

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 1:33 am
by Grimfan
Now this is an invaluable addition to the modding armory.

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

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 2:05 am
by Drakkan
that could really save lots of time, thanks !

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 10:16 am
by Aisuu
Oh, my JKos :)

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

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 12:23 pm
by Doridion
Excellent work JKos ^^ Sticked in the superthread !

Re: cloneObject for LoG2

Posted: Sat Nov 22, 2014 7:44 pm
by strangely
I used the cloneObject script as a basis for a cloneSkill script I made.
Details here:
viewtopic.php?p=85615#p85615

Re: cloneObject for LoG2

Posted: Sun Nov 23, 2014 10:18 pm
by JKos
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?)