Wrapping my head around declaring string variables in Solarus (example)

Started by DementedKirby, July 30, 2015, 06:11:28 AM

Previous topic - Next topic
Okay, so thanks to several members (particularly Maxs) I've been able to do some steady progress with items. I think I'm getting the hang of how all of this works. Here's an example:

I'm working on making the Book of Mudora. So far I've been able to get the hero to take the book out and read it with this code:

function item:on_using()
   item:get_map():get_entity("hero"):set_animation("book")
   game:start_dialog("book.test", nil, function ()
   item:set_finished()
   end)
end


However, we all know that the book only works in front of places written in Hylian script in order to translate. So what I'd really like the code to do is to just give an error sound when used in an inappropriate place. Simple enough. I can simply do that instead of doing what's done in the previous function. However, I do want it to be used when translating Hylian text. Now, with items, you can use them when in contact with certain npcs thanks to 'item:on_npc_interaction_item(npc,item)'. So this is what I came up with:

local sign = item:get_map():get_entity():get_name()

function item:on_npc_interaction_item(sign,item)
   if sign == "ForestSign" then
      item:get_map():get_entity("hero"):set_animation("book")
      game:start_dialog("book.translation", nil, function ()
      item:set_finished()
      end)
   end
end


However, I get this error:
QuoteError: In items/book: [string "items/book.lua"]:4: bad argument #1 to 'get_map' (sol.item expected, got no value)

So I'm pretty lost as to what to do, lol. As long as I erase the 'sign' variable declaration and the function that interacts with npcs, I get no error. So I know it's in that part of the script.

First, you have to put a name in the get_entity method ( http://www.solarus-games.org/doc/latest/lua_api_map.html#lua_api_map_get_entity ). In fact, I don't understand your first line. You should just test the sign name inside the method on_npc_interaction_item, like that :


function item:on_npc_interaction_item(sign,item)
   if sign:get_name() == "ForestSign" then
      item:get_map():get_entity("hero"):set_animation("book")
      game:start_dialog("book.translation", nil, function ()
          item:set_finished()
      end)
   end
end


Secondly, can you post all your item code please ? When you code, you always have to show the context of the code. If I show you a problem with "print(something)" but something is never declared, the error will show on this line, but it will never be found by helpers because they can't know something doesn't exist :)

Well, I gave everything except the "header", lol. Here's the whole code:

local item = ...
local map = ...
local game = item:get_game()

function item:on_created() 
   self:set_savegame_variable("possession_book")
   self:set_assignable(true)
end
     
function item:on_using()
   item:get_map():get_entity("hero"):set_animation("book")
   game:start_dialog("book.test", nil, function ()
   item:set_finished()
   end)
end

function item:on_npc_interaction_item(sign,item)
   if sign:get_name() == "ForestSign" then
      item:get_map():get_entity("hero"):set_animation("book")
      game:start_dialog("book.translation", nil, function ()
          item:set_finished()
      end)
   end
end


It works wonderfully. However, I can't have it both ways. What do I mean:
Okay, so the sign is supposed to read gibberish when not using the book. Then, if you use the book in front of it, you get a translated message. However, you can't have an entity on top of the other because then you get the error of trying to retrieve two dialogs at once (which is what I tried: a spriteless npc on top of the sign (one gave the untranslated message with the action and the other the translation when using the book)).

Does the engine have any way around this?

You don't need to have two npc, just change the dialog id when you interact with it from the map script. You have an example of this behaviour (change the dialog id) with zsdx and the bottle. Try to inspire your code from it. But right now, I don't know what is not working with your script. Still having the same error message ?

Actually, I found that the error message is not due to having 2 npcs overlapping but because the item.lua has two different dialogues. The engine thinks it's an error but it's actually doing what I want it to. What I need to happen is one of two different things:
If the hero hits action to activate the sign, it reads untranslated.
If the hero uses the book in front of the sign, it reads translated.
If I try to read the sign nomally (with the action key), nothing happens; the untranslated message should happen. However, it only happens with the book and it only reads the translated message. If I place one npc above the other, then the sign with the action key works and not the sign requiring the book.
I want the same effect as the Book of Mudora in ALttP. You should be able to read the sign normally but get an untranslated message. If you use the book in front of the same sign you should get the translated sign.