[⟵] | [⟶] | [⟵] | [⟶] |
[⟵] | [⟶] | [⟵] | [⟶] | ||
[⟵] | [⟶] | [ ? ] | [ ? ] |
library ArrowKeySequence /* v3.0.1 By IcemanBo
*/ requires /*
*/ SequenceT /* hiveworkshop.com/forums/submissions-414/sequencet-274244/#post2772894
*/ ArrowKeyEvent /* hiveworkshop.com/forums/jass-resources-412/system-arrowkeyevent-205650/
*/
/* What is this?
This code allows you to create an ArrowKeySequence which can be solved by a user.
An ArrowKeySequence is for example: "ArrowUp, ArrowDown, ArrowLeft".
Now, when the user puhses these arrow keys in correct order, it can be seen as solved.
It can be used as kind of a puzzle, or it can also act as
opening mechanism for treasure chests like in the RPG Gothic.
*/
//! novjass
//API
/* At first you need to create at least one
ArrowKeySequence that a user can try to solve.
You need knowledge of the Vector library to create a vector.
You can look in Sequence Demo for an example.
You also have to register a boolexpr as code,
that will run, whenever a user tries to solve a sequence.*/
// struct ArrowKeySequence - constructor
static method create takes IntegerVector vector, boolexpr bx returns thistype
// struct ArrowKeySequence - destructor
For safety the destructor is wrapped into the API function DestroySequence. (see later)
// The registered code will fire whenever a user presses a key while he is about to
// solve a sequence. Within the code function you have access to:
boolean IsSequenceSolved // Is sequence completed
boolean IsKeyCorrect // If current input was correct
integer CurrentSequenceVectorPosition // Current position in sequence
integer ArrowKeyInteger // Read ArrowKeyEvent for info which key it is.
player ArrowKeyUser // User who pressed the arrow key
function EndSequence takes nothing returns nothing
// The current running sequence will end for the user.
function EndSequenceAll takes ArrowKeySequence keySequence, player p returns nothing
// Will end ALL sequences of a type for the user "p".
function DestroySequence takes ArrowKeySequence keySequence returns nothing
// Will end ALL sequences of the type for all players.
// Will completly destroy the sequence so it can't be used anymore. (deallocate)
// Use follwing function to start.
function StartPlayerSequence takes player p, ArrowKeySequence id, integer pos returns nothing
// whichPlayer
// whichSequence
// startPosition (All vectors start with "0". So "0" is the common start value.
// But in case you want, you can manipulate it to your needs.
// It is recommended to read the demo examples.
// That was it. Have fun!
//! endnovjass
// Data of all default sequences (added by user)
struct ArrowKeySequence extends array
implement Alloc
readonly trigger handler
readonly IntegerSequenceType sequence
static method create takes IntegerVector vec, boolexpr bx returns thistype
local thistype this = allocate()
set this.sequence = IntegerSequenceType.create(vec)
set this.handler = CreateTrigger()
call TriggerAddCondition(handler, bx)
return this
endmethod
method destroy takes nothing returns nothing
call this.sequence.destroy()
call DestroyTrigger(this.handler)
set this.handler = null
call this.deallocate()
endmethod
endstruct
//! runtextmacro DEFINE_STRUCT_VECTOR("", "SequenceVector", "IntegerSequence")
//! runtextmacro DEFINE_STRUCT_VECTOR("", "ArrowKeySequenceVector", "ArrowKeySequence")
globals
player ArrowKeyUser
integer ArrowKeyInteger
boolean IsKeyCorrect
private boolean endSequence
private ArrowKeySequence currentArrowKeySequence
private integer max
endglobals
// This handles the sequences of all players.
struct PlayerSequence extends array
private boolean inGame
readonly ArrowKeySequenceVector arrowKeySequence
private SequenceVector sequence
readonly integer sequenceAmount
// Will remove the sequence from given position.
method end takes integer pos returns nothing
call this.arrowKeySequence.erase(pos, 1)
call this.sequence[pos].destroy()
call this.sequence.erase(pos, 1)
set this.sequenceAmount = this.sequenceAmount - 1
endmethod
// Will start a new sequence from vectorPosition[startPos]
method start takes ArrowKeySequence that, integer startPos returns nothing
call this.arrowKeySequence.push(that)
call this.sequence.push(IntegerSequence.create(that, startPos))
set this.sequenceAmount = this.sequenceAmount + 1
endmethod
private method onArrowKeyEvent takes integer arrow, boolean pressed returns nothing
local integer i
local integer currentSequencePosition
if (pressed) then
// Responses
set ArrowKeyUser = Player(this)
set ArrowKeyInteger = arrow
// We need an independant integer as max, to have more control.
// The sequenceAmount is dynamic and can be changed which may lead to bugs.
set max = this.sequenceAmount
set currentSequencePosition = 0
loop
exitwhen currentSequencePosition >= max
set currentArrowKeySequence = this.arrowKeySequence[currentSequencePosition]
call this.sequence[currentSequencePosition].onSequenceEvent(arrow)
set IsKeyCorrect = IsSequenceInputCorrect
if (IsSequenceSolved) then
set i = this.sequenceAmount - 1
loop
exitwhen(i < 0)
if (this.arrowKeySequence[i] == currentArrowKeySequence) then
call this.end(i)
set max = max - 1
endif
set i = i - 1
endloop
endif
set endSequence = false
// Interact with user
call TriggerEvaluate(currentArrowKeySequence.handler)
if (endSequence) then
call this.end(currentSequencePosition)
set max = max - 1
else
set currentSequencePosition = currentSequencePosition + 1
endif
endloop
endif
endmethod
implement ArrowKey
// If a player leaves he doesn't need the vectors anymore
private static method onLeave takes nothing returns boolean
local integer i = GetPlayerId(GetTriggerPlayer())
if (thistype(i).inGame) then
call thistype(i).arrowKeySequence.destroy()
call thistype(i).sequence.destroy()
set thistype(i).sequenceAmount = 0
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
call TriggerAddCondition(t, function thistype.onLeave)
loop
exitwhen (i > 11)
set thistype(i).sequenceAmount = 0
if (GetPlayerController(Player(i)) == MAP_CONTROL_USER) then
set thistype(i).arrowKeySequence = ArrowKeySequenceVector.create()
set thistype(i).sequence = SequenceVector.create()
set thistype(i).inGame = true
call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_LEAVE)
endif
set i = i + 1
endloop
endmethod
endstruct
// API
// Remove all sequences of a type for a player.
function EndSequenceAll takes ArrowKeySequence currentKeySequence, player p returns nothing
local PlayerSequence this = PlayerSequence(GetPlayerId(p))
local integer i = this.sequenceAmount - 1
loop
exitwhen(i < 0)
if (this.arrowKeySequence[i] == currentKeySequence) then
call this.end(i)
set max = max - 1
endif
set i = i - 1
endloop
endfunction
// When a sequence per pe gets destroyed then
// we to run though all player sequences and
// remove the destroyed sequence type.
function DestroySequence takes ArrowKeySequence keySequence returns nothing
local integer i = 0
loop
exitwhen (i > 11)
call EndSequenceAll(keySequence, Player(i))
set i = i + 1
endloop
call keySequence.destroy()
endfunction
function EndSequence takes nothing returns nothing
set endSequence = true
endfunction
function StartPlayerSequence takes player p, ArrowKeySequence id, integer pos returns nothing
call PlayerSequence(GetPlayerId(p)).start(id, pos)
endfunction
endlibrary
v3.0.1 -little documentation changes v3.0-many changes now with usage of SequenceT ....v1.0 - release |