Ask a simple question, get a simple answer

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
minmay
Posts: 2788
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

The way containers are implemented, I doubt UsableItemComponent will help (remember that the party can close containers by simply clicking the 'x' button). Unfortunately I don't think you can do this at all.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
Isaac
Posts: 3188
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

... Also, the actual 'X' key will swap between the equipped hands; closing the container in the process.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Ask a simple question, get a simple answer

Post by akroma222 »

Isaac wrote:the actual 'X' key will swap between the equipped hands; closing the container in the process.
minmay wrote: (remember that the party can close containers by simply clicking the 'x' button)
Nope! Hahaha I didn't actually know the 'x' button did anything... until now ... :lol:
Apparently it does lots of things!
(Ive just discovered the 'x' button will also complicate grand plans & sometimes even ruin otherwise productive days)
Thanks all the same though guys, appreciated as always :)
minmay
Posts: 2788
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

I meant this 'x' button:
Image
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Ask a simple question, get a simple answer

Post by akroma222 »

minmay wrote:I meant this 'x' button:
Image
Ah huh, I see!
(Not properly reading replies from v helpful people can also ruin otherwise productive days :roll: )
This is good news! I think I - may - have a clunky, but workable, solution in that case...
I shall report back if I get it working as intended
Cheers again guys ;)
User avatar
Isaac
Posts: 3188
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

minmay wrote:I meant this 'x' button
... And this is why I mentioned the actual 'X' key; as opposed to the click-able X button. ;)
User avatar
Curunir
Posts: 332
Joined: Fri Mar 30, 2012 11:19 pm

Re: Ask a simple question, get a simple answer

Post by Curunir »

Working on a multiple alcove checker puzzle, I have the rock-paper-scissors script from the base game that I can modify. I just wanted to ask about traits. I want to use the flute in one alcove, which is a trait-less item in the game. Can I simply make a new object definition, cloning the flute, and simply add an arbitrary trait like "instrument" and have the script check for that, or are traits fixed?

Additionally, when the alcove conditions are met, I want to spawn two items on two pedestals. Do I need to do 'spawn' and define level, coordinates and elevation like in the example below, or can I just go entity_name.surface:addItem(item_name.item) for those, as I've already named the pedestal id I want the item to spawn onto?

Here's what I have so far:
SpoilerShow

Code: Select all

function hunterShape()
	local swordFound = false
	for _,i in weaponAlcove.surface:contents() do
		if i:hasTrait("sword") then swordFound = true
		playSound("key_lock_faint") 	end
	end
	
	local readableFound = false
	for _,i in brainAlcove.surface:contents() do
		if i.go.spellscrollitem or i:hasTrait("tome") then readableFound = true
		playSound("key_lock_faint")		end
	end
	
	local food1_Found = false
	for _,i in food1alcove.surface:contents() do
		if i:hasTrait("consumable") then food1_Found = true end
		playSound("key_lock_faint")		end
	end
	
	local food2_Found = false
	for _,i in food2alcove.surface:contents() do
		if i:hasTrait("consumable") then food2_Found = true
		playSound("key_lock_faint")		end
	end
	
	local fluteFound = false
	for _,i in fluteAlcove.surface:contents() do
		if i:hasTrait("instrument") then fluteFound = true
		playSound("key_lock_faint")		end
	end
		
	if swordFound and readableFound and food1_Found and food2_Found and fluteFound then
		reward_pedestal_1.surface:addItem(spawn("REWARD ITEM HERE",map,X,Y,face,elev).item)
		reward_pedestal_2.surface:addItem(spawn("REWARD ITEM HERE",map,X,Y,face,elev).item)
		party.party:getChampion(1,4):gainExp(500)
		hudPrint("The party has gained 500 xp.")
		playSound("secret")
	else
		end
	end
end
Additionally, I have an Indiana Jones type alcove where you need to have something in to "counterbalance" the supposed mechanism, before you take the prize out of the alcove. If you fail to provide a replacement before you take the item, you get zapped. Am I doing this right? Script is triggered by the alcove's onRemoveItem Again, I edited someone else's script for this:
SpoilerShow

Code: Select all

function indyAlcoveCheck(object, item)
   for _, i in indyAlcove1.surface:contents() do
      if i.go.id == item then return true
		else spawn("flame_wave", party.level, party.x, party.y, party.facing, party.elevation)
   end
end
User avatar
Xardas
Posts: 83
Joined: Fri Jul 28, 2017 12:30 am

Re: Ask a simple question, get a simple answer

Post by Xardas »

Hey Curunir,
You can define new traits and add them to objects, but that´s not necessary here.
Checking the item for it´s Name seems much simpler here.
This should do it for the flute:

Code: Select all

fluteFound = false

function checkforflute()
	for _,i in fluteAlcove.surface:contents() do
      if i.go.name == "flute" then fluteFound = true
      	playSound("key_lock_faint") 
	  end
	end
end
Secondly you can add items to surfaces that easy, without taking care of coordinates. I think your Version should work to, but your coordinates don´t matter, because addItem() takes care of the coordinates for you:

Code: Select all

function stuffonpedestal()
pedestal_1.surface:addItem(spawn("dagger").item)
end
And for your indyAlcove. Your Problem is that there will never spawn a flame wave, because you don´t have any items in your alcove after removing the last one. That´s why Surface:contents() is checking an empty alcove --> function doesn´t go into your for loop.
Here´s a working Version for your Problem:

Code: Select all

function indyAlcoveCheck(self)
local bool = false
   for _, i in indyAlcove1.surface:contents() do
     bool = true
   end
   if bool == false then
     spawn("flame_wave", party.level, party.x, party.y, party.facing, party.elevation)
     self:removeConnector(self:getConnector(1)) --trigger only once
   end 
end
In order to get to the other side of the pit you have to get hit by the fireball and die....
Yep.....moving on!
User avatar
Curunir
Posts: 332
Joined: Fri Mar 30, 2012 11:19 pm

Re: Ask a simple question, get a simple answer

Post by Curunir »

Thank you very much for the answers and fixes!

The flame wave code works just fine. However, I tried changing it to work for the second indyAlcove2 and couldn't get it to work, so I just made another function with the same code, calling the second alcove! :D

How taxing is redundant code on the engine and performance in general? I'm far from getting FPS issues with the mod but loading times seem to slowly creep up.

Also, something is VERY wrong with the 5-alcove puzzle code above. No matter what item I put in the alcoves, I get the click, and once all 5 are in, the items on the alcoves don't spawn and I don't get XP and sound playing.

I have absolutely no idea why this doesn't work... :(
SpoilerShow

Code: Select all

function hunterShape()
   local swordFound = false
   for _,i in swordAlcove.surface:contents() do
      if i:hasTrait("sword") then swordFound = true
      playSound("key_lock_faint")   end
   end
   
   local readableFound = false
   for _,i in scrollAlcove.surface:contents() do
      if i.go.spellscrollitem or i:hasTrait("tome") then readableFound = true
      playSound("key_lock_faint")   end
   end
   
   local food1_Found = false
   for _,i in food1Alcove.surface:contents() do
      if i:hasTrait("consumable") then food1_Found = true end
      playSound("key_lock_faint")   end
   end
   
   local food2_Found = false
   for _,i in food2Alcove.surface:contents() do
      if i:hasTrait("consumable") then food2_Found = true
      playSound("key_lock_faint") else      end
   end
   
   local fluteFound = false
   for _,i in fluteAlcove.surface:contents() do
      if i.go.name == "flute" then fluteFound = true
      playSound("key_lock_faint")      end
   end
      
   if swordFound and readableFound and food1_Found and food2_Found and fluteFound then
      reward_pedestal_1.surface:addItem(dagger.item)
      reward_pedestal_2.surface:addItem(dagger.item)
      party.party:getChampion(1,4):gainExp(500)
      hudPrint("The party has gained 500 xp.")
      playSound("secret")
      end
User avatar
Xardas
Posts: 83
Joined: Fri Jul 28, 2017 12:30 am

Re: Ask a simple question, get a simple answer

Post by Xardas »

Hey Curunir,
Copying your code is always bad. If you can avoid that, you should so.
Here is a version which works for as many alcoves as you want
function indyAlcoveCheck(self)
local bool = false
for _, i in self.go.surface:contents() do
bool = true
end
if bool == false then
spawn("flame_wave", party.level, party.x, party.y, party.facing, party.elevation)
self:removeConnector(self:getConnector(1)) --trigger only once
end
end
And here is a working Version for your puzzle. You have to spawn the daggers, before you can add them to the pedestals. Also i think you got a little mistake with the gain exp function.
function hunterShape()
local swordFound = false
for _,i in swordAlcove.surface:contents() do
if i:hasTrait("sword") then swordFound = true
playSound("key_lock_faint")
end
end

local readableFound = false
for _,i in scrollAlcove.surface:contents() do
if i.go.spellscrollitem or i:hasTrait("tome") then readableFound = true
playSound("key_lock_faint")
end
end

local food1_Found = false
for _,i in food1Alcove.surface:contents() do
if i:hasTrait("consumable") then food1_Found = true
playSound("key_lock_faint")
end
end

local food2_Found = false
for _,i in food2Alcove.surface:contents() do
if i:hasTrait("consumable") then food2_Found = true
playSound("key_lock_faint")
end
end

local fluteFound = false
for _,i in fluteAlcove.surface:contents() do
if i.go.name == "flute" then fluteFound = true
playSound("key_lock_faint")
end
end

if swordFound and readableFound and food1_Found and food2_Found and fluteFound then
reward_pedestal_1.surface:addItem(spawn("dagger").item)
reward_pedestal_2.surface:addItem(spawn("dagger").item)
for k=1,4 do
party.party:getChampion(k):gainExp(500)
end
hudPrint("Each champion has gained 500 xp.")
playSound("secret")
end
end
Note that the key_lock_faint Sound is always played when you insert any item to any of the alcoves, once you got one right item in the right alcove. So this is very irritating. I couldn´t find a fast solution for that Problem, maybe someone else knows a better way to do this whole script, since there is also a lot of copied Code in there.
In order to get to the other side of the pit you have to get hit by the fireball and die....
Yep.....moving on!
Post Reply