Do tasks in a certain order to open a door or whatever

Started by Max, November 03, 2019, 06:44:11 PM

Previous topic - Next topic
Hey, a while ago someone asked me about something like this on the discord, and just now I figured out a decent script for this so I thought I'd share it in case anyone else needs to do this.

This is some simple code for one of those situations where you want the player to press a number of switches (or talk to a number of NPCs, kill a number of enemies, etc.) in a certain order. This code allows you to just write the names of those entities (switches, npcs, enemies, whatever) into an array in that order:

Code (lua) Select

local switch_index = 1
local switches = {"ordered_entity_2", "ordered_entity_4", "ordered_entity_3", "ordered_entity_1"} --I had several NPCs that you needed to interact with in a certain order

for entity in map:get_entities("ordered_entity_") do
  function entity:on_interaction() --or, entity:on_dead() for enemies, entity:on_activated() for switches, etc.
    map:process_switch(self:get_name())
  end
end

function map:process_switch(name)
  if switches[switch_index] == name then
    switch_index = switch_index + 1
    --show some feedback here so they player knows they did something
    sol.audio.play_sound"switch"
    if switch_index == (#switches + 1) then
      --do whatever happens when you do all the things in the right order:
      sol.audio.play_sound"switch"
      map:open_doors("skull_door")
    end
  else
    --if the player hits one out of order:
    sol.audio.play_sound"wrong"
    switch_index = 1
  end
end

Awesome idea  ;D

I'll mention that this is intended to be a map script in case that is not obvious.

It could be improved by deactivating the puzzle once the player has solved it. This could be done simply by setting switch_index to nil once solved, then checking it at the beginning of the map:process_switch() method:
Code (lua) Select
function map:process_switch(name)
  if switch_index then --add this line
    if switches[switch_index] == name then --unchanged (for context)
      --lines in between unchanged
    end --unchanged
  end --add this line
end


Also could be useful to save the state of the solved puzzle as a savegame variable so that the player doesn't have to solve it again when revisiting the map later. Simply save the savegame variable once the puzzle is complete:
Code (lua) Select
game:set_value("puzzle_complete", true)
Then change the first line of the script to the following:
Code (lua) Select
local switch_index = not game:get_value("puzzle_complete") and 1