Weird glitch between hooks and script_entity objects

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Weird glitch between hooks and script_entity objects

Post by nichg »

In order to try to keep my code clean and without too much duplication, I've been trying to make script_entity objects that have various useful functions to call from my hooks. However, I've found that this is kind of hit or miss. If I call a function this way that has no arguments, it seems to work fine (though I have to use something like script_library.function() instead of script_library:function()). On the other hand, when I pass arguments it seems like they get all messed up. For instance, I have a function that I was going to use to check equipment, but I just turned it into a bugtest for now:

Code: Select all

function champEquipped(champ, itemname)
   hudPrint(champ.name)
end
This is in the script entity script_library. I then make an onDamage hook for the party:

Code: Select all

onDamage = function(champ, dmg, dmgtype)
   if script_library.champEquipped(champ, "senvelor_shield") then
      hudPrint("Yep, its equipped.")
  end
end
The output of this is invariably 'script_entity' for champ.name, which seems wrong. Furthermore, the game crashes whenever I try to use any champion functions off of it.
User avatar
Komag
Posts: 3654
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Weird glitch between hooks and script_entity objects

Post by Komag »

champEquipped needs to be set up to return either "true" or "false" depending on what you want it to look for, so that your hook script will make sense - the part about:

Code: Select all

if script_library.champEquipped(champ, "senvelor_shield")
really means:

Code: Select all

if script_library.champEquipped(champ, "senvelor_shield") == "true"
but in the script you don't have any way for it to "return true"
Here is the example "check alcove for item" script by petri that illustrates it for me

Code: Select all

-- This function returns true if the entity contains a given item.
-- It works for any entity that implements the containedItems() method.
function containsItem(entity, item)
   for i in entity:containedItems() do
      if i.name == item then
         return true
      end
   end
   -- if we get here the item was not found
   return false
end

-- example usage
if containsItem(my_alcove, "dagger") then
   my_door:open()
else
   my_door:close()
end
Finished Dungeons - complete mods to play
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Weird glitch between hooks and script_entity objects

Post by nichg »

I agree that champEquipped needs to return true or false, but even if I do that there is still the bug that when I pass something to it from the party's onDamage hook, the argument seems to be getting scrambled or overridden somehow.

Edit: I'm wondering if it is inserting an implicit first 'called by' argument or something, like what happens when you call a script with a Connector, since I'm getting a script_entity as the first argument. I'll go test that, see if it helps.
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Weird glitch between hooks and script_entity objects

Post by nichg »

Update:

Its not passing an implicit caller argument. In fact, when I pass strings to the scripts it seems to work fine (I can retrieve 'senvelor_shield' for example). No, it seems like the real problem is in the champion argument of onDamage!

if I have an onDamage hook:

Code: Select all

onDamage = function(champ, dmg, dmgtype)
   if champ ~= nil then
      hudPrint(champ.name)
   end
end
this crashes Grimrock when the party takes damage. So its not even that champ is somehow being set to nil, it seems like its garbled somehow (since all entities are supposed to have a name, the only way I can think that this would mess up like this is that champ is a pointer to junk data). Unless I'm doing something really silly like getting the order of the arguments wrong, it looks like this is a real bug.
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Weird glitch between hooks and script_entity objects

Post by JKos »

Champion doesn't have name property. Use getOrdinal instead.
- 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
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Weird glitch between hooks and script_entity objects

Post by nichg »

Alright, I've tried with getOrdinal(), still inside the onDamage hook. It still crashes. For a sanity check:

Code: Select all

if champ ~= nil then
-- do nothing
end
does not crash.
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Weird glitch between hooks and script_entity objects

Post by Montis »

nichg wrote:Alright, I've tried with getOrdinal(), still inside the onDamage hook. It still crashes. For a sanity check:

Code: Select all

if champ ~= nil then
-- do nothing
end
does not crash.
maybe try the following:

Code: Select all

if champ ~= nil then
   hudPrint(champ:getName())
end
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Weird glitch between hooks and script_entity objects

Post by nichg »

That also crashes. I found the error log:

Code: Select all

mod_assets/scripts/init.lua:82: bad self
stack traceback:
	[C]: in function 'error'
	[string "ScriptInterface.lua"]: in function 'getName'
	mod_assets/scripts/init.lua:82: in function 'onDamage'
	[string "Champion.lua"]: in function 'damage'
	[string "Monster.lua"]: in function 'dealDamage'
	[string "Monster.lua"]: in function 'update'
	[string "Map.lua"]: in function 'updateEntities'
	[string "Dungeon.lua"]: in function 'updateLevels'
	[string "GameMode.lua"]: in function 'update'
	[string "DungeonEditor.lua"]: in main chunk
	[C]: in function 'xpcall'
	[string "DungeonEditor.lua"]: in function 'preview'
	[string "DungeonEditor.lua"]: in function 'update'
	[string "Grimrock.lua"]: in main chunk
stack traceback:
	[C]: in function 'error'
	[string "DungeonEditor.lua"]: in function 'handleError'
	[string "DungeonEditor.lua"]: in function 'preview'
	[string "DungeonEditor.lua"]: in function 'update'
	[string "Grimrock.lua"]: in main chunk

OS Version 6.1

OEM ID: 0
Number of processors: 4
Page size: 4096
Processor type: 586

Total memory: 3891 MB
Free memory: 1910 MB

Display device 0:
  Device name: \\.\DISPLAY1
  Device string: Intel(R) Graphics Media Accelerator HD
  State flags: 00000005

Display device 1:
  Device name: \\.\DISPLAY2
  Device string: Intel(R) Graphics Media Accelerator HD
  State flags: 08000000

Display device 2:
  Device name: \\.\DISPLAYV1
  Device string: RDPDD Chained DD
  State flags: 00000008

Display device 3:
  Device name: \\.\DISPLAYV2
  Device string: RDP Encoder Mirror Driver
  State flags: 00200008

Display device 4:
  Device name: \\.\DISPLAYV3
  Device string: RDP Reflector Display Driver
  State flags: 00200008
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Weird glitch between hooks and script_entity objects

Post by nichg »

Correction to what I just said. champ:getName() seems to work. I was doing champ.getName(), which crashes. champ:getOrdinal() still crashes though. However, this seems to be because hudPrint doesn't like a numerical argument. If I just use print, it works.

Okay, so the end result seems to be that passing an object from a hook is screwed up, but you can pass the identifiers of that object necessary to grab it again inside a script_entity script. So at this point, I think I can make my stuff work.
User avatar
zalewapl
Posts: 45
Joined: Sun Apr 22, 2012 12:39 am

Re: Weird glitch between hooks and script_entity objects

Post by zalewapl »

There seems to be a bug with passing parameters from the object hooks to level scripts. I tried to subtract certain integer values from script variable each time when party receives damage. This is how my scripts look like:

Object hook:

Code: Select all

-- mod_assets/scripts/party.lua
-- This file is included in init.lua as the first thing after standard_assets.lua
cloneObject{
	name = "party",
	baseObject = "party",

	onDamage = function(champion, damage, type) 
		-- 34 is a magic number for testing purposes only.
		-- In the end I want to be able to pass 'damage' here.
		scoreLua:addScore(34)
		return true
	end,
}
Dungeon script:

Code: Select all

-- scoreLua defined within the first level of the dungeon
score = 100000
function addScore(dummy, val)
	print("Printing")
	print(dummy) -- prints "table 0xmemory-address"
	print(val) -- prints correct value passed from the hook (34 in this case)
end
Now, all would be ok because it actually allows to pass the number from the hook to the dungeon function. Unfortunately this function can be called only once, or twice if I get lucky. The next call will crash the game. What's even worse is that the crash window is the standard Windows CTD and not the neat LUA stack trace.

I think we're dealing here with either a bug in the game engine or with LUA engine limitation. I hope it's the first one.

EDIT:
I was wrong about CTDs. See my post which is after the next one.
Last edited by zalewapl on Mon Oct 29, 2012 1:23 am, edited 1 time in total.
Post Reply