setmouseitem crash

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Shloogorgh
Posts: 45
Joined: Sat Sep 22, 2012 12:24 am

setmouseitem crash

Post by Shloogorgh »

I was making a sacrificial dagger as a consumable item. Basically it kills your champion when you click it against their portrait. I wanted another version of the dagger to appear in its place when it was used, exactly like how a potion becomes an empty flask, but it crashes the game. Am I using the setMouseItem script correctly? Is there an alternative method I could use? Or is this a bug?

Code: Select all

cloneObject{
	name = "sacrificial_dagger",
	baseObject = "assassin_dagger",
	uiName = "Sacrificial Dagger",
	description = "Dark energy emanates from this ritualistic blade",
	gameEffect = "Place against a comrade's throat to complete the dark ritual",
	consumable = true,
	onUseItem = function(self, champion)
		playSound("party_crushed")
		champion:damage(10000, "physical")
		hudPrint(champion:getName().." has been sacrificed.")
		setMouseItem("sacrificial_dagger_used")
		return true
	end,
	weight = 1.0,
}

cloneObject{
	name = "sacrificial_dagger__used",
	baseObject = "assassin_dagger",
	uiName = "Sacrificial Dagger",
	description = "The essence of your comrade pulses within the blade",
	weight = 1.0,
}
Note that the dagger worked as expected until I added the setMouseItem line
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: setmouseitem crash

Post by Montis »

I think you need to use

Code: Select all

setMouseItem(spawn("sacrificial_dagger_used"))
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Shloogorgh
Posts: 45
Joined: Sat Sep 22, 2012 12:24 am

Re: setmouseitem crash

Post by Shloogorgh »

Montis wrote:I think you need to use

Code: Select all

setMouseItem(spawn("sacrificial_dagger_used"))
it still crashes, even with that
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: setmouseitem crash

Post by Montis »

No clue, I would have to try that myself.
It might also be a bug, there's a similar bug already known in here: viewtopic.php?f=14&t=3232
- if you give setMouseItem() an item that's placed already somewhere on the level, and then player tries to place that item on the ground, the game crashes "item is already placed".
Edit: looking a second time at your script, your used dagger has an underscore too much, that's probably the reason for the crash :idea:
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Shloogorgh
Posts: 45
Joined: Sat Sep 22, 2012 12:24 am

Re: setmouseitem crash

Post by Shloogorgh »

Ah, good catch. Unfortunately that didn't solve the problem. If I use my script it still crashes, and if I use yours it spawns no new dagger nor puts it in the mouse
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: setmouseitem crash

Post by Montis »

The following connected to a pressure plate works for me:

Code: Select all

function spawnonmouse()
	setMouseItem(spawn("torch"))
end
If I use setMouseItem("torch"), it will break out of the preview with "item expected, got string". So

Code: Select all

setMouseItem(spawn("sacrificial_dagger_used"))
is definitely the way to go.



You also might want to relay the onUseItem to a script entity for quicker and easier debugging, see below. I edited the script a bit to account for when you already have something held by the mouse.

Code: Select all

   onUseItem = function(self, champion)
      return sacrificial_dagger_script.sacrifice(self, champion)
   end,
script entity sacrificial_dagger_script

Code: Select all

function sacrifice(self, champion)
      playSound("party_crushed")
      champion:damage(10000, "physical")
      hudPrint(champion:getName().." has been sacrificed.")
      if getMouseItem() == nil then
            setMouseItem(spawn("sacrificial_dagger_used"))
      else
            spawn("sacrificial_dagger_used", party.level, party.x, party.y, party.facing)
      end
      return true
end
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Shloogorgh
Posts: 45
Joined: Sat Sep 22, 2012 12:24 am

Re: setmouseitem crash

Post by Shloogorgh »

Woo-hoo!

Thanks for your help!

Your script stopped it from crashing, and all I had to do was add the line setMouseItem() before running the script entity to ensure that any mouse item was destroyed. That stopped it from just spawning on the ground.

Code: Select all

onUseItem = function(self, champion)
		setMouseItem()
		return sacrificial_dagger_script.sacrifice(self,champion)
	end,
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: setmouseitem crash

Post by Montis »

Well, the spawning on the ground was intentional since you can use the item when you're holding a different one. So if you hold a dungeon key and then use the dagger, the key will get destroyed when you use your script.
I guess the way you did it was holding the dagger in the mouse and then right clicking on the character, which would be the only way that I can think of reproducing this behaviour.

You might probably want to use the following approach (also delete your added line from the object):

Code: Select all

function sacrifice(self, champion)
      playSound("party_crushed")
      champion:damage(10000, "physical")
      hudPrint(champion:getName().." has been sacrificed.")
      if getMouseItem() ~= nil then
            if getMouseItem().name == "sacrificial_dagger" then
                  setMouseItem(spawn("sacrificial_dagger_used"))
            else
                  spawn("sacrificial_dagger_used", party.level, party.x, party.y, party.facing)
            end
      else
            setMouseItem(spawn("sacrificial_dagger_used"))
      end
      return true
end
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Shloogorgh
Posts: 45
Joined: Sat Sep 22, 2012 12:24 am

Re: setmouseitem crash

Post by Shloogorgh »

Huh, I hadn't considered what would happen if you were holding another item.

But this brings up a new error- if you consume the dagger while holding another item, the dagger stays in your inventory while also spawning the used version (actually, now on testing, this happens if you right click the dagger in your inventory even when not holding another item... not good)

So I either have to disable right clicking the item and have it only work by dragging it onto your character's portrait (which is its intended use anyway)

Or I need to figure out why it doesn't destroy the original dagger when consumed that way
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: setmouseitem crash

Post by Montis »

It might have something to do with the returning of the return value... I have to test this myself, brb.

Edit: this doesn't happen for me... I'm guessing you did something wrong somewhere. Complete script:

file items.lua
SpoilerShow

Code: Select all

cloneObject{
	name = "sacrificial_dagger",
	baseObject = "assassin_dagger",
	uiName = "Sacrificial Dagger",
	description = "Dark energy emanates from this ritualistic blade",
	gameEffect = "Place against a comrade's throat to complete the dark ritual",
	consumable = true,
	onUseItem = function(self, champion)
		return sacrificial_dagger_script.sacrifice(self,champion)
	end,
	weight = 1.0,
	requiredLevel = 0,
}

cloneObject{
	name = "sacrificial_dagger_used",
	baseObject = "assassin_dagger",
	uiName = "Sacrificial Dagger",
	description = "The essence of your comrade pulses within the blade",
	weight = 1.0,
	requiredLevel = 0,
}
script_entity sacrificial_dagger_script
SpoilerShow

Code: Select all

function sacrifice(self, champion)
      playSound("party_crushed")
      champion:damage(10000, "physical")
      hudPrint(champion:getName().." has been sacrificed.")
      if getMouseItem() ~= nil then
            if getMouseItem().name == "sacrificial_dagger" then
                  setMouseItem(spawn("sacrificial_dagger_used"))
            else
                  spawn("sacrificial_dagger_used", party.level, party.x, party.y, party.facing)
            end
      else
            setMouseItem(spawn("sacrificial_dagger_used"))
      end
      return true
end
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
Post Reply