Useful scripts repository

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Fri Sep 14, 2012 2:59 pm

Create a "gambling" setup/machine
(you pay with a certain type of item, then have a chance at winning a good thing or getting damaged)
--------------
example from Shroom:
I created 2 alcoves and a lever

alcove_bet
alcove_win
lever_gamble

Added an lua entity and put this code in it

Code: Select all

function gamble()

   if checkContents(alcove_bet, "torch_everburning") then
      if math.random(100) < math.random(90) then
         hudPrint("You Win")
         playSound("level_up")
         alcove_win:addItem(spawn("boots_valor"))
      else
         hudPrint("You lose")
         spawn("poison_cloud", party.level, party.x, party.y, 0)
      end
   end

   lever_gamble:setLeverState("deactivated")
end

function checkContents(location,item)
   for object in location:containedItems() do

      -- if you want to show the name of items you actually put in the alcove
      -- then uncomment the hudPrint below
      -- hudPrint(object.name)
      if object.name == item then
         --remove object (but havent worked out how yet!)
         return true
      end
   end
   return false
end
click on the lever and add a connector to the lua script - select "gamble" in the last combo box

As you can see, I have used the item "torch_everburning" as this is what the champion has in his hand when you hit preview. Put this in the alcove and pull the lever.

the math.random() dictate the win chances 1-100 vs 1-90, so not in characters favour.

Change these values as you want to, and code for which items etc.

One thing I couldn't see how to do was remove the bet item. If you want I can post a link with an example saved in the editor.
------------
it says:- roll a random number between 1 and 100 and then compare it with another number between 1 and 90.

This makes the 'house' more likely to win - if the numbers are equal then its a nearly even (use <= to make it even)

to break it out

Code: Select all

local playerRoll = math.random(100)
local houseRoll = math.random(90)
hudPrint("Player rolled "..playerRoll.." House rolled "..houseRoll)
if playerRoll < houseRoll then
For some reason I set this to whoever rolls lowest - dont ask me why - maybe thats why it looks wrong
----------------------
FINAL EXAMPLE:
Replacing the gamble() function

Code: Select all

function gamble()

   if checkContents(alcove_bet, "torch_everburning") then
       local playerRoll = math.random(90)
       local houseRoll = math.random(100)
       hudPrint("Player rolled "..playerRoll.." House rolled "..houseRoll)
       if playerRoll > houseRoll then
         hudPrint("You Win")
         playSound("level_up")
         alcove_win:addItem(spawn("boots_valor"))
      else
         hudPrint("You lose")
         spawn("poison_cloud", party.level, party.x, party.y, 0)
      end
   end

   lever_gamble:setLeverState("deactivated")
end
I have changed it round so that the highest roll wins, with the same bias as before though. Take out the hudPrint once your happy, or revert to the old code without the variables


-----
original thread for discussion/questions:
viewtopic.php?f=14&t=3063
Last edited by Komag on Wed Sep 19, 2012 1:03 pm, edited 2 times in total.
Finished Dungeons - complete mods to play

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Fri Sep 14, 2012 3:42 pm

Steal an item being held or equiped by a party member
(such as removing the torch from Contar Stoneskull's left hand)

example from petri:
Assuming Contar is the first champion in the party:

Code: Select all

party:getChampion(1):removeItem(7)
7 is the slot number of the left hand, defined in Champion:insertItem()'s documentation.

-----
original thread for discussion/questions:
viewtopic.php?f=14&t=3272
Last edited by Komag on Wed Sep 19, 2012 1:03 pm, edited 1 time in total.
Finished Dungeons - complete mods to play

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Fri Sep 14, 2012 8:52 pm

EDIT - with update BETA 1.2.8 - you can now connect thing between levels, so the scripts below are largely unnecessary, but could still be used if wanted
---------------------------------
Connecting things between different levels

Normally you cannot make a button on floor 1 open a door on floor 2 (if you try to make the connection, the "Action" is blank and nothing will happen). But scripts work anywhere on any floor, so you can do the following:

example by Magus

Code: Select all

-- Lever in level01 opens the door in level02
function sdoor01()
   if lever01:getLeverState() == "activated" then
      door01:setDoorState("open")
   else
      door01:setDoorState("closed")
   end
end
The lever or button and the script must be in the same level. The door can be in a lower level.
You need to rename door01 and lever01 if you want to use this.
---------------------

more from Komag:

here is an alternative script if you:
- want to use a button
- don't need the door to ever close
- want it to open normally instead of being instantly open

Code: Select all

-- Button in level01 opens the door in level02
function openmydoor()
    door01:open()
end
- connect the button to the script (both on same floor)(it will have "openmydoor" as the Action)
- replace "door01" with the ID of the door on the different floor you want opened
(you could also have the button activate a teleporter to teleport you in front of the door so you can witness it opening normally)

-----
original thread for discussion/questions:
viewtopic.php?f=14&t=3112
Last edited by Komag on Wed Sep 19, 2012 1:04 pm, edited 5 times in total.
Finished Dungeons - complete mods to play

ikki
Posts: 4
Joined: Fri Sep 14, 2012 6:14 pm

Re: Useful scripts repository

Post by ikki » Sat Sep 15, 2012 4:08 pm

Iterator for champion backbag

Code: Select all

function championBackbagIterator(t)
	local i = 10
	local n = 31
	return function ()
		i = i + 1
		while i <= n and t:getItem(i) == nul do
			i = i + 1
		end
		if i <= n then return t:getItem(i) end
	end
end
Now it can be used in a for loop. For example to check if the first champion has blueberry pie stashed:

Code: Select all

for item in championBackbagIterator(party:getChampion(1)) do
	if item.name = "blueberry_pie" then
		eatPie()
	end
end

User avatar
Billick
Posts: 201
Joined: Thu Apr 19, 2012 9:28 pm

Re: Useful scripts repository

Post by Billick » Sat Sep 15, 2012 6:38 pm

A couple of script functions I wrote to check if anybody in your party is carrying a particular type of item:

Code: Select all

function checkForItemParty(item)
	local i = 1
	repeat
		if checkForItem(party:getChampion(i), item)
			then return true
		end
		i = i + 1
	until i == 5
	return false
end

function checkForItem(champion, item)
	local i = 1
	repeat
		local itemObj = champion:getItem(i)
		if itemObj ~= nil then
			if itemObj.name == item
				then return true
			end
		end
		i = i+1
		until i == 32
	return false
end
The first function calls the second function. Pass in the name of the item you want to check for into checkForItemParty. You would use it like this:

Code: Select all

if checkForItemParty("torch")
 then print("We have a torch")
 else print("We don't have a torch")
end
Edit: fixed invalid function names
Last edited by Billick on Sat Sep 15, 2012 11:33 pm, edited 1 time in total.
Halls of Barrian - current version 1.0.3 - Steam Nexus
Me Grimrock no bozo!

VaeVictis
Posts: 1
Joined: Sat Sep 15, 2012 7:26 pm

Re: Useful scripts repository

Post by VaeVictis » Sat Sep 15, 2012 7:36 pm

I see we've all been working on our own ItemCheck functions :mrgreen:

My turn to share the code:

Code: Select all

function itemCheck(thisItem)
	local thisPlayer = 1
	local itemSlot = 1
	local currItem
	
	for thisPlayer=1,4,1 do
		for itemSlot=1,31,1 do
			if party:getChampion(thisPlayer):getItem(itemSlot) ~= nil then 
				currItem = party:getChampion(thisPlayer):getItem(itemSlot).name
				if currItem == thisItem then
					return true
				end
			end	
		itemSlot = itemSlot + 1
		end
	thisPlayer = thisPlayer + 1		
	end	
end
Use this function call to check for the itemID in everyone's inventory slot:

Code: Select all

function checkInventory()
	if itemCheck("dagger") then
		--found it!
        else
      --no such item in inventory.
	end 
end 
Glad to see so many modders already active. Just started yesterday and I'm liking what I'm seeing in the editor.

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Sat Sep 15, 2012 11:26 pm

To require two pressure plates to be down before a door will open:

this was already shown in a different way earlier, but here is another example

(and once again, for this simple example you could just use a counter, but seeing the sample script can help when you need an advanced version that counters can't handle)

example by Shroom:

Code: Select all

function platedown()
    if plate1:isDown() and plate2:isDown() then
        door1:open()
    else
        door1:close()
    end
end
Last edited by Komag on Sun Sep 16, 2012 4:36 am, edited 1 time in total.
Finished Dungeons - complete mods to play

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Sat Sep 15, 2012 11:29 pm

Make a script work once (such as at the start of a map) and print something:

example by Magus:

Code: Select all

function exampleLua()
   print("This code runs once.")
end
exampleLua()
this script sets a function and then immediately does it.
You could also just do this:

Code: Select all

print("This code runs once.")
-----
original thread for discussion/questions:
viewtopic.php?f=14&t=3142
Last edited by Komag on Wed Sep 19, 2012 1:44 pm, edited 3 times in total.
Finished Dungeons - complete mods to play

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Sat Sep 15, 2012 11:33 pm

Temporarily boost max hit points and add hit points
(then restore the previous settings)
(this would allow the party to fall down many pits and not die, for example)

example by Musabb:

At the very beginning I run the following:

Code: Select all

-- Bump up hitpoints
   for x = 1, 4, 1 do
     party:getChampion(x):modifyStatCapacity("health",120)
     party:getChampion(x):modifyStat("health",120)
   end
And then once they fall the whole distance and take damage (but live) I execute the following via a hidden pressure plate.

Code: Select all

function resethits()
   -- Bump down hitpoints
    for x = 1, 4, 1 do
       party:getChampion(x):modifyStatCapacity("health",-120)
    end
end
----------------------------------------------------------------------------
Temporarily disable all party members, to avoid damage
(to survive a multi-level pit fall)

second and more efficient example by Isaac:
-------------------------
I do this a different way. The method I designed uses a timer, a script, and a hidden pressure plate to trigger both.

Try this: Create rooms above and below and place your pit.
Add a timer, a hidden pressure plate and a lua script.
Set the timer to 1.5; paste the following into the script.

Code: Select all

function tempImmunity()
     for i = 1,4 do
	pitImmunity = party:getChampion(i)
	pitImmunity:setEnabled(false)
     end
end

function immunityRovoke()
  for i = 1,4 do
    pitImmunity = party:getChampion(i)
    pitImmunity:setEnabled(true)
  end
end


Set a pressure plate connection to trigger the tempImmunity() function; set another to trigger the timer.
Connect the timer to trigger the immunityRevoked() function.

Place the plate on the same cell as the pit.
--------------------

Test it out by falling down the pit. ;)
(While testing...it might be a good idea to put a teleporter downstairs that leads upstairs.)

** You tweak the timer value to allow falls of greater than one floor down.

-----
original thread for discussion/questions:
viewtopic.php?f=14&t=3141
Last edited by Komag on Wed Sep 19, 2012 1:45 pm, edited 1 time in total.
Finished Dungeons - complete mods to play

User avatar
Komag
Posts: 3637
Joined: Sat Jul 28, 2012 4:55 pm
Location: Boston, USA

Re: Useful scripts repository

Post by Komag » Sun Sep 16, 2012 4:11 am

Adding NPC traders to your dungeon - buy stuff! use Alcoves:

example by Akatana

First of all you need to create a new monster

Code: Select all

cloneObject{
   name = "npcGoromorg",
   baseObject = "goromorg",
   evasion = 100000,
   onAttack = function(self, dir)
      return false
   end,
   onMove = function(self, dir)
      return false
   end,
}
Just copy it into your mod_assets/scripts/monster.lua

- created 2 alcoves and a button
- write a short lua script and connect the checkAlcoveForItems() function with the button

Code: Select all

-- to add some dialogue :)
traded = false
function Merchant1()
   if traded == false then
      hudPrint("Hello traveler!")
      hudPrint("I'm a merchant and I would really like to trade with you.")
      hudPrint("If you give me your torch I will give you nice loot!")
   else
      hudPrint("At the moment I have nothing to offer")
   end
end

function checkAlcoveForItems()
   -- Offer
   local itemName = "torch_everburning"
   -- offer alcove
   local alcoveID = alcove_offer
   -- checks if the offer alcove has an item
   if alcoveID:getItemCount() == 0 then
      hudPrint("First you have to place an item into the alcove!")
   end
 
   -- checks if the offer is equal to the item you want
   for i in alcoveID:containedItems() do
      if i.name == itemName then
           hudPrint("The trade was successful!")
           -- spawns the item which you will get
           alcove_win:addItem(spawn("boots_valor"))
           -- spawns a secret door in front of the offer alcove so that you cant get the offer back
           spawn("dungeon_secret_door", party.level, 14, 14, 0)
           traded = true
      else
           hudPrint("The trade was not successful!")
      end
   end
end
- Of course you have to change the items and the alcove ID's


********************************************************************************************

by Emciel » Sun Sep 16, 2012 8:14 am
nice, i was thinking of how npc traders could work in this game, this way could work =)
i wonder if there would be another way of triggering the merchant dialogue other than hidden pressure plate... hmm

-----

by Akatana » Sun Sep 16, 2012 9:21 am
You may start the dialogue when you hit the monster but then you need a different monster for every dialogue you want...

Code: Select all

cloneObject{
   name = "npcGoromorg",
   baseObject = "goromorg",
   onAttack = function(self, dir)
      return false
   end,
   onMove = function(self, dir)
      return false
   end,
   onDamage = function(self, dir)
        hudPrint("Hello traveler!")
        hudPrint("I'm a merchant and I would really like to trade with you.")
        hudPrint("If you give me your torch I will give you nice loot!")
      return false
   end,
}
-----

by Emciel » Sun Sep 16, 2012 9:28 am
yeh, also that would require you to actually damage them, which wouldn't be a nice way to start off a conversation =)

-----

by Akatana » Sun Sep 16, 2012 9:34 am
Nope you dont damage them because return false cancels the damage event so they dont get any damage


-----
original threads for discussion/questions:
viewtopic.php?f=14&t=3147
viewtopic.php?f=14&t=3080
viewtopic.php?f=14&t=3135
Last edited by Komag on Wed Sep 19, 2012 1:45 pm, edited 1 time in total.
Finished Dungeons - complete mods to play

Post Reply