Adding call_handlers

Heloo! I’m trying to get a call_handler to work, so I can add items to a world through the console (call…) I think I have put the call handler in the manifest.json fine, but I’m not so sure about the actual lua file, or maybe it is the manifest.json.

Anywho, here are the files:

manifest.json:

{
  "info": {
    "name": "Command Item Spawner",
    "version": 1
  },

  "functions": {
    "create_item_iconic": {
      "controller": "file(call_handlers/item_spawn_handler.lua)",
      "endpoint": "server"
    },
    "create_item": {
      "controller": "file(call_handlers/item_spawn_handler.lua)",
      "endpoint": "server"
    },
    "create_item_other": {
      "controller": "file(call_handlers/item_spawn_handler.lua)",
      "endpoint": "server"
    }
  }
}

call_handlers/item_spawn_handler.lua:

local Point3 = _radiant.csg.Point3
local log = radiant.log.create_logger('item_spawn_call_logger')

local ItemSpawnHandler = class()

function ItemSpawnHandler:create_item_iconic(session, response, item, x, y, z)
	local entity = radiant.entities.create_entity(item)
	radiant.terrain.place_entity(entity, Point3(x, y, z), {force_iconic = true})

	return true
end

function ItemSpawnHandler:create_item(session, response, item, x, y, z)
	local entity = radiant.entities.create_entity(item)
	radiant.terrain.place_entity(entity, Point3(x, y, z), { })
end

function ItemSpawnHandler:create_item_other(session, response, item, x, y, z, iconic, owner)
	local entity = radiant.entities.create_entity(item)
	
	if owner ~= 'none':
		entity:add_component('unit_info'):set_player_id(owner)
	
	radiant.terrain.place_entity(entity, Point3(x, y, z), { force_iconic = iconic })
end

return ItemSpawnHandler

I haven’t tested it, but it looks okay. You should be able to do call create_item_iconic alias x y z, but I haven’t tested call at all yet. If you wanted to make your life easier, I would recommend my console mod, which makes the console a lot more usable.

With Jelly.Console+, you could re-write your first function as

jelly_console.add_command('create_item_iconic', function(cmd, args)
  local alias, x, y, z = unpack(args)
  local entity = radiant.entities.create_entity(alias)
  radiant.terrain.place_entity(entity, Point3(x, y, z), { force_iconic = true })
end)

and then simply call it in the console using create_item_iconic.

Ok. I have tries some things, and it seems it was a couple problems:

  1. The .smod wasn’t zipped correctly
  2. I had a few lua errors (I like python!)

It works well now, but now i’m trying to get stonehearth.selection to work with this code:

function ItemSpawnHandler:create_item_iconic(session, response, item, x, y, z)

	

	local entity = radiant.entities.create_entity(item)
	stonehearth.selection = LocationSelector()
	stonehearth.selection:select_location():set_cursor_entity(entity):done(

		function(selector, location, rotation)
			radiant.terrain.place_entity(entity, Point3(location.x, location.y, location.z), {force_iconic = true})
			selector.destroy()
		end):fail(
		function(selector)
			seletor.destroy()
		end):go()
	
	

	

	return true
end

I’m not 100% certain, but I think the cursor entity is destroyed after the selection was completed. Create a new entity at the location that you get instead of trying to set the cursor.

The cursor isn’t actually loading, its just throwing a cannot index stonehearth.selection

Oh. Of course. Selection stuff needs to be on the client, while creating the entity needs to happen on the server. You’ll need to have two call handlers; one to start the selection, another to spawn the entity. That sounds like something that could be useful for jelly_console too.

So anyway: Your selection code needs to be in a clientside call handler; in the selected callback you then need to _radiant.call into the server side to place your entity.

Oh… Ok. That makes some sense. I’ll try it now.

And so you know, I’m going to add a ui frontend when i figure out how to, so no console needed. I’m just starting with a console based system.

Also, what are the arguments for .call()?

Use the edit function of Discourse instead of writing multiple posts right after each other.

I would highly recommend you look at other code. I would recommend the newgame callhandler as it’s basically doing what you want to do with the town banner. The arguments to _radiant.call are the same ones as in JavaScript; callhandler_name, [... args]. In your case I guess _radiant.call('my_mod:create_server_item', item_alias, x, y, z).

Well, I’ve got a selector “working”, but when I click it just says “attempt to index self, a nil value” in stonehearth.smod/services/client/location_selector.luac

And here’s the contents of my .smod as a zip:

Plus, if you wish to replicate this, I use this command:

call itemspawn:select_location_item_iconic stonehearth:furniture:comfy_bed

It’s selector:destroy, not selector.destroy. I really recommend checking out stonehearth/call_handlers/new_game_call_handler.lua, especially NewGameCallHandler:choose_camp_location and its serverside counterpart NewGameCallHandler:create_camp.

Ok. I was looking at create_workshop_handler.luac, and I guess I didn’t see that. Oops.

(I’m still new to lua, I know : is indexing, but I have no clue what the . means)

But I’ll go try that now, and take a peek at new_game_call_handler.luac.

EDIT:

Ok, I’ve got the selector to stop erroring out, but the other call_handler isn’t doing anything or isn’t running.

Code:

foo:bar(1, 2, 3) is equal to foo.bar(foo, 1, 2, 3). function Foo.bar(self, a, b, c) is equal to function Foo:bar(a, b, c). It’s effectively syntax sugar for pseudo-OOP.

I can’t download your smod from dropbox right now. Is there any error in the stonehearth.log? Can you maybe upload your call handlers somewhere (pastebin, gist, something like that)?

I sure can!

http://pastebin.com/WuSAqfYC

EDIT:

There wasn’t any error in stonehearth.log.