How to "merge" sprites in defold

thats my thoughts. But as far as I know not possible in defold…or?
In editor I cant see a way to add a go to a go .

It has to be in a collection to do that. Just drag and drop.

ah ok. for sure.

but then I have to use the collection-factory as well, right? hm… means changing lots of coding I quess…

Right, that’s the drawback. Depending on your code you hopefully only have to change spawning and destroying though.

I guess I remember I already was at that point and dropped it… have to take a closer look (again).
Thanks!

You can use plain GOs too but requires you to build/destroy all GOs of an object and set the correct parenting and relative positioning when you create the tank with the main tank script having reference of all of the tank part GOs.

hm…

using a normal factory I can send to the new go’s script a table like this:

factory.create("main:/gamecontrol" .. self.buildingDefence[i], mapPos, nil, {building = hash(self.buildingDefence[i]), ownerID = GLOBAL.PlayerID})

with a collectionfactory this returns an error. Without the table it dont dropps an error but of cause dont work for me :slight_smile:

collectionfactory.create("main:/gamecontrol" .. self.buildingDefence[i], mapPos, nil, {building = hash(self.buildingDefence[i]), ownerID = GLOBAL.PlayerID})

Error: bad argument #7 to 'create' (hash expected, got string)
there is no way to send a table while spawning?

oh, i guess I found something in the docs…

-- planet.script
--
local props = {}
props[hash("/astronaut")] = { size = 10.0 }
props[hash("/probe1")] = { color = hash("red") }
props[hash("/probe2")] = { color = hash("green") }
local astro = collectionfactory.create("#factory", nil, nil, props, nil)
...

But why this wont work?

local props = {}
props["turret_gun"] = {building = hash("structure_turretgun"), ownerID = GLOBAL.PlayerID}
props["wall"] = {building = hash("structure_wall"), ownerID = GLOBAL.PlayerID}
local result = collectionfactory.create("main:/gamecontrol" .. self.buildingDefence[i], mapPos, nil, props, nil)
pprint(result)

Error
bad argument #8 to 'create' (hash expected, got string)

I think it should be

props[hash("turret_gun")] = ...

etc…

I guess you’re right :roll_eyes:

Its that simple :slight_smile: thanks!

But…
the props are not the “same” like normal factory.create.

if I run the code above at the factory-script the hashs “building” and ownerID are not received.

go.property("building", hash("-nohash-"))
print(self.building)
DEBUG:SCRIPT: hash: [-nohash-]

Are you printing the value in init()? Isolate to a minimal example to ensure that you’re not doing anything wrong.

Hey @britzl.

Ok, here are some more infos…

There is a global list called defenceType which holds all defence-structures (GO): here a part of it:

defenceType = {
	-- TURRET: GUN BASED (collection)
	{
	hash("structure_turretgunbased"),
	sprite = "Unit_Gunnery_Gun",
	spawner = "#cfactory_defence_turretgunbased",
	name = "Turret Gun Based",
	collection = true,
	instanceID = nil,
	ownerID = nil,

	buildtime = 3,
	buildresource = "iron",
	buildcost = 1000,

	mapPosX = 0,
	mapPosY = 0,

	menuMask = 0,

	hitpointsMax = 600,
	hitpoints = 300,
	selfheal = 1,

	xp = 0,
	rank = 0,

	energyMax = 100,
	energy = 0,
	energyReload = 1,

	energyToWork = 0,
	workingSound = "",

	weaponType = hash("twinbullet"),
	weaponReloadTime = 5
	}

The crosshair.script which calls the collectionfactory is like this:
This code is inside 2 for-loops, simple the self.buildingDefence[i] is equal to the spawner-variable above and holds “#cfactory_defence_turretgunbased” in this case!

if GLOBAL.defenceType[b].collection then
  local props = {}
  props[hash("turret_gun")] = {building = hash("structure_turretgun"), ownerID = GLOBAL.PlayerID}
  props[hash("wall")] = {building = hash("structure_wall"), ownerID = GLOBAL.PlayerID}
  local result = collectionfactory.create("main:/gamecontrol" .. self.buildingDefence[i], mapPos, nil, props, nil)
  pprint(result)
else
  factory.create("main:/gamecontrol" .. self.buildingDefence[i], mapPos, nil, {building = hash(self.buildingDefence[i]), ownerID = GLOBAL.PlayerID})
end

Of cause there is a collectionfactory which contains the gameobjects with the right ids:

and finally here is the (init) code for the defence I’ll try to spawn (defence.script is attached to each GO in collection)

GLOBAL = require "main.global_settings"

go.property("building", hash("-nohash-"))
go.property("ownerID", 0)--hash("nobody"))


function init(self)

	-- define defence and get it from table
	for v,i in ipairs(GLOBAL.defenceType) do
		print(GLOBAL.defenceType[v].spawner)
		if self.building == hash(GLOBAL.defenceType[v].spawner) then
			self.defence = deepcopy(GLOBAL.defenceType[v])
			break
		end
	end

	print("DEFENCE TYPE ")
	print(self.building)
	pprint(self.defence)

	-- store some vars
	self.circlecount = 0
	self.pos = go.get_position() + vmath.vector3(GLOBAL.TILESIZE / 2, GLOBAL.TILESIZE / 2, 0) -- match to grid
	go.set_position(self.pos)
	self.initTime = 0
	self.reloadTimer = 0
	self.inconstruction = true
	self.isbuilding = false
	self.active = false
	self.defence.instanceID = go.get_id()
	self.defence.mapPosX = math.floor(self.pos.x / GLOBAL.TILESIZE)
	self.defence.mapPosY = math.floor(self.pos.y / GLOBAL.TILESIZE)
	self.defence.ownerID = self.ownerID

	self.refreshTimer = os.clock()

	-- INSERT new defence in global table units()
	table.insert(GLOBAL.defences, {id = go.get_id(), ownerID = self.ownerID, name = self.name, pos = self.pos, hp = self.defence.hitpoints}) -- store new unit in table
	-- store own position in table
	self.posIndefences = #GLOBAL.defences

	-- change graphics to UNDER CONSTRUCTION until buildtime is over
	msg.post("#sprite", "play_animation", {id = hash("Structure_underconstruction_small")})

	-- initiate UNIT-BARS (energy + hp)
	msg.post("main:/ingamegui#ingame", "unit_bar", {
		create = true,
		unitid = go.get_id(),
		pos = self.pos + vmath.vector3(-16, 16, 0),
		energy = GLOBAL.TILESIZE / self.defence.energyMax * self.defence.energy,
		health = GLOBAL.TILESIZE / self.defence.hitpointsMax * self.defence.hitpoints,
		busy = self.reloadTimer
	})

	-- add to player defences
	GLOBAL.PlayerStructures = GLOBAL.PlayerStructures+1

	print("-- SPAWN defence: " .. self.defence.name .. " buildtime=" .. self.defence.buildtime .." factory: " .. tostring(self.building) .. " MapPos: " .. self.defence.mapPosX .."x" .. self.defence.mapPosY)

	-- disable wide radars
	--msg.post("#collisionobject_radar_1", "disable")
	msg.post("#collisionobject_radar_2", "disable")
	msg.post("#collisionobject_radar_3", "disable")

	-- tint RED if enemy
	if self.ownerID ~= GLOBAL.PlayerID then
		sprite.set_constant("#sprite", "tint", GLOBAL.COLOR_RED)
	end

	-- table which stores all enemies in range/radar
	self.enemyInRange = {}

	-- DEBUG
	if GLOBAL.debugMode then
		self.defence.buildtime = 3
	end
end

In the init after spawning I’ll let the new defence-GO define “itself” (dont know a better way in lua to get all the values needed like hitpoints etc). I’ll do it with sending the factory-spawned GO a hash-value with the type of defence and parse the global list of defences (first list in this post). Maybe there is a better way?

Simply: Spawning a unit/defence/structure (defence in this example) via factory and give a hash-value with it containing a kind of class/type-hash like “turret-gun”. in the init the new-spawned GO parses the global list of defences which holds all the important variables. If found, all values are stored in the self.defence table to use for.