26_ConsoleInput.lua 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. -- Console input example.
  2. -- This sample demonstrates:
  3. -- - Implementing a crude text adventure game, which accepts input both through the engine console,
  4. -- and standard input.
  5. -- - Disabling default execution of console commands as immediate mode Lua script.
  6. require "LuaScripts/Utilities/Sample"
  7. local gameOn = false
  8. local foodAvailable = false
  9. local eatenLastTurn = false
  10. local numTurns = 0
  11. local hunger = 0
  12. local urhoThreat = 0
  13. -- Hunger level descriptions
  14. local hungerLevels = {
  15. "bursting",
  16. "well-fed",
  17. "fed",
  18. "hungry",
  19. "very hungry",
  20. "starving"
  21. }
  22. -- Urho threat level descriptions
  23. local urhoThreatLevels = {
  24. "Suddenly Urho appears from a dark corner of the fish tank",
  25. "Urho seems to have his eyes set on you",
  26. "Urho is homing in on you mercilessly"
  27. }
  28. function Start()
  29. -- Execute the common startup for samples
  30. SampleStart()
  31. -- Disable default execution of Lua from the console
  32. SetExecuteConsoleCommands(false)
  33. -- Subscribe to console commands and the frame update
  34. SubscribeToEvent("ConsoleCommand", "HandleConsoleCommand")
  35. SubscribeToEvent("Update", "HandleUpdate")
  36. -- Subscribe key down event
  37. SubscribeToEvent("KeyDown", "HandleEscKeyDown")
  38. -- Hide logo to make room for the console
  39. SetLogoVisible(false)
  40. -- Show the console by default, make it large
  41. console.numRows = graphics.height / 16
  42. console.numBufferedRows = 2 * console.numRows;
  43. console.commandInterpreter = "LuaScript";
  44. console.visible = true
  45. -- Show OS mouse cursor
  46. input.mouseVisible = true
  47. -- Open the operating system console window (for stdin / stdout) if not open yet
  48. OpenConsoleWindow()
  49. -- Initialize game and print the welcome message
  50. StartGame()
  51. -- Randomize from system clock
  52. SetRandomSeed(time.systemTime)
  53. end
  54. function HandleConsoleCommand(eventType, eventData)
  55. if eventData:GetString("Id") == "LuaScript" then
  56. HandleInput(eventData:GetString("Command"))
  57. end
  58. end
  59. function HandleUpdate(eventType, eventData)
  60. -- Check if there is input from stdin
  61. local input = GetConsoleInput()
  62. if input:len() > 0 then
  63. HandleInput(input)
  64. end
  65. end
  66. function HandleEscKeyDown(eventType, eventData)
  67. -- Unlike the other samples, exiting the engine when ESC is pressed instead of just closing the console
  68. if eventData:GetInt("Key") == KEY_ESC then
  69. engine:Exit()
  70. end
  71. end
  72. function StartGame()
  73. Print("Welcome to the Urho adventure game! You are the newest fish in the tank your\n" ..
  74. "objective is to survive as long as possible. Beware of hunger and the merciless\n" ..
  75. "predator cichlid Urho, who appears from time to time. Evading Urho is easier\n" ..
  76. "with an empty stomach. Type 'help' for available commands.")
  77. gameOn = true
  78. foodAvailable = false
  79. eatenLastTurn = false
  80. numTurns = 0
  81. hunger = 2
  82. urhoThreat = 0
  83. end
  84. function EndGame(message)
  85. Print(message)
  86. Print("Game over! You survived " .. numTurns .. " turns.\n" ..
  87. "Do you want to play again (Y/N)?")
  88. gameOn = false
  89. end
  90. function Advance()
  91. if urhoThreat > 0 then
  92. urhoThreat = urhoThreat + 1
  93. if urhoThreat > 3 then
  94. EndGame("Urho has eaten you!")
  95. return
  96. end
  97. elseif urhoThreat < 0 then
  98. urhoThreat = urhoThreat + 1
  99. elseif urhoThreat == 0 and Random() < 0.2 then
  100. urhoThreat = urhoThreat + 1
  101. end
  102. if urhoThreat > 0 then
  103. Print(urhoThreatLevels[urhoThreat] .. ".")
  104. end
  105. if (numTurns % 4) == 0 and not eatenLastTurn then
  106. hunger = hunger + 1
  107. if hunger > 5 then
  108. EndGame("You have died from starvation!")
  109. return
  110. else
  111. Print("You are " .. hungerLevels[hunger + 1] .. ".")
  112. end
  113. end
  114. eatenLastTurn = false
  115. if foodAvailable then
  116. Print("The floating pieces of fish food are quickly eaten by other fish in the tank.")
  117. foodAvailable = false
  118. elseif Random() < 0.15 then
  119. Print("The overhead dispenser drops pieces of delicious fish food to the water!")
  120. foodAvailable = true
  121. end
  122. numTurns = numTurns + 1
  123. end
  124. function TrimInput(input)
  125. return input:gsub("^%s*(.-)%s*$", "%1")
  126. end
  127. function HandleInput(input)
  128. local inputLower = TrimInput(input:lower())
  129. if inputLower:len() == 0 then
  130. Print("Empty input given!")
  131. return
  132. end
  133. if inputLower == "quit" or inputLower == "exit" then
  134. engine:Exit()
  135. elseif gameOn then
  136. -- Game is on
  137. if inputLower == "help" then
  138. Print("The following commands are available: 'eat', 'hide', 'wait', 'score', 'quit'.")
  139. elseif inputLower == "score" then
  140. Print("You have survived " .. numTurns .. " turns.")
  141. elseif inputLower == "eat" then
  142. if foodAvailable then
  143. Print("You eat several pieces of fish food.")
  144. foodAvailable = false
  145. eatenLastTurn = true
  146. if hunger > 3 then
  147. hunger = hunger - 2
  148. else
  149. hunger = hunger - 1
  150. end
  151. if hunger < 0 then
  152. EndGame("You have killed yourself by over-eating!")
  153. return
  154. else
  155. Print("You are now " .. hungerLevels[hunger + 1] .. ".")
  156. end
  157. else
  158. Print("There is no food available.")
  159. end
  160. Advance()
  161. elseif inputLower == "wait" then
  162. Print("Time passes...")
  163. Advance()
  164. elseif inputLower == "hide" then
  165. if urhoThreat > 0 then
  166. local evadeSuccess = hunger > 2 or Random() < 0.5
  167. if evadeSuccess then
  168. Print("You hide behind the thick bottom vegetation, until Urho grows bored.")
  169. urhoThreat = -2
  170. else
  171. Print("Your movements are too slow you are unable to hide from Urho.")
  172. end
  173. else
  174. Print("There is nothing to hide from.")
  175. end
  176. Advance()
  177. else
  178. Print("Cannot understand the input '" .. input .. "'.")
  179. end
  180. else
  181. -- Game is over, wait for (y)es or (n)o reply
  182. local c = inputLower:sub(1, 1)
  183. if c == 'y' then
  184. StartGame()
  185. elseif c == 'n' then
  186. engine:Exit()
  187. else
  188. Print("Please answer 'y' or 'n'.")
  189. end
  190. end
  191. end
  192. function Print(input)
  193. -- Logging appears both in the engine console and stdout
  194. Log:WriteRaw(input .. "\n")
  195. end