Advertisement
ZoriaRPG

ZScript Beam 'Inglish' Parser v0.2.2

Jan 25th, 2017
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.95 KB | None | 0 0
  1. import "std.zh" //Keyboard.zh is included
  2.  
  3. /* Beam=Style TBA Text Parser
  4.    I hope to support the full Beam 'Inglish' with this, eventually, but
  5.    if not, it should be a modest text parser tor TBA style quests, or even
  6.    normal quests where the developer can read strings to find command keywords and
  7.    act on them.
  8.  
  9.    At present, there is a five WORD stack, and a heap that can support caching
  10.    commands, offsetting them, and acting on them later.
  11.  
  12.    This is not fully-considered, as Beam's 'Inglish' parser supported conjunctions
  13.    and prepositions. Adding those, or at least the logic for those will require a
  14.    larger stack, and some unconventional memory management.
  15.    
  16.    Beam's maximum parse string length was 128-characters.
  17.    
  18.    Command procedure:
  19.    
  20.    User types commands to the commandline[]
  21.    Scan the commands, each time we hit a space, determine what command it is, and
  22.    add its numeric value to the heap.
  23.    When we reach tne edn of the line, scan the heap
  24.    place instructions onto the stack, ignoring preopositions until we hit an AND instruction
  25.    When we hit an AND instruction, process the stack instructions, pop them off
  26.    then return to the heap, and repeat until we are out of instructions.
  27.    
  28.    When we are out of instructions, pop off the stack, clear the heap, and end the turn.
  29. */
  30.  
  31. //int instructions[214747];
  32.  
  33. int GAMERAM[214747]; //Holds values of the game engine.
  34. //need arrays and getptr for each typed array, too.
  35.  
  36. int TURN; //remember to handle rollover
  37.  
  38. void IncrementTurn(){ TURN += 2;}
  39. void BattleTurn(){ TURN++; }
  40. bool PlayerTurn() { return ( TURN % 2 == 0 ); }
  41. bool EnemyTurn() { return  ( TURN % 2 != 0 ) ; }
  42.  
  43.  
  44. int tempbuffer[55];
  45. int outputbuffers[10];
  46.  
  47. void OutputText(int bufferID, int outoutID){
  48.     //copy text from input to output
  49. }
  50.  
  51. void GameText(){
  52.     //string processor
  53.  
  54. }
  55.  
  56. //v0.22, new
  57.  
  58. //Unmeric instruction values to match cases.
  59. int HEAP[32]; //What is the maximum number of instructions with conjunctions?
  60. int STACK[32]; //What is the maximum number of instructions, without conjunctions?
  61. int ram[64]; //RAM
  62.  
  63. //String buffers
  64. int CURWORD[18]; //Current operational instruction WORD, for when converting a word to an instruction.
  65. int commandline[129];//128 chars max on the line, plus NULL.
  66. int commandlineoverlay[129]; //128 + NULL
  67.  
  68. int command[18]; //Holds the present action command. Deprecated by stack procedure.
  69.  
  70. int VARS[256]; //holds code support variables.
  71. int timer = KEY_DELAY; bool cantype = true;
  72. bool ShiftKey; int q;
  73. int temp_q; int cursorblink = 0;
  74. int ram[32];
  75. //int curbuffer = 0;
  76.  
  77. //Vars indices:
  78. const int RAM_q = 0;
  79.  
  80.  
  81.  
  82. /*
  83. int stack[5]; //holds the four possible command components
  84. int heap[32]; //May not need it, but it might be good for something.
  85. int ADJ_NOUN[36]; //buffer for a combined adjective and noun pairing.
  86.     //Used to compare the names of screen items, and enemies.
  87.     //36 chars = 17+17+space+NULL Probably too long for any pair, but that is a minor waste.
  88. */
  89.  
  90. int buffer[214747]; //={CURSOR_POINT_CHAR, CHAR_SPACE};
  91. int bufferoverlay[214747]; //handles the cursor.
  92.  
  93.  
  94. //Perhaps a SAY string?
  95.  
  96. //ASM TYPES
  97. #define INVALID -1;
  98. #define GLOBAL 0; //Pause, Unpause, Save, Load, Inventory, Score, Print, NoPrint
  99.  
  100. #define COMMAND     1;
  101. #define ACTION      1; //Same as COMMAND
  102. #define VERB        2;
  103. #define NOUN        3;
  104. #define OBJECT      3; //Same as NOUN
  105. #define ADJECTIVE   4;
  106. #define NPC         5;
  107. #define ENEMY       6;
  108. #define SPEAK       7;
  109. #define CONJUNCTION     8;
  110. #define PREPOSITION     9;
  111. #define ARTICLE     10;
  112.  
  113. //Parse types, based on number of commands issued
  114. //command noun, command adjective noun
  115. //command article...this probably won;t work.
  116. #define PARSE_COMMAND 1;
  117. #define PARSE_
  118.  
  119. /*  Do we want to allow constructing very complex chains, such as OLD KEY as two
  120.     compinents, or do we want to hardcode OLD KEY or HIDEOUS TROLL as one string?
  121.  
  122.     Clearly, the latter is easier.
  123. */
  124.  
  125. //ASM DEFINE - List priority ( length ) ( alpha ) -- or ( length ) ( common ) ?
  126.  
  127. /*  We sort this based on the number of characters, and then alphabetic, so that we speed up
  128.     parse string compares. Smaller strings compare and resolve faster, and characters
  129.     are checked in sequence, so the sooner it finds a match, the sooner it returns,
  130.     similar to a short-circuit, but code-controlled.
  131. */
  132.  
  133. #define D       1;
  134. #define E       2;
  135. #define I       3;
  136. #define L       4;
  137. #define N       5;
  138. #define S       6;
  139. #define U       7;
  140. #define W       8;
  141.  
  142. #define GO      9;
  143. #define NE      10;
  144. #define NW      11;
  145. #define SE      12;
  146. #define SW      13;
  147. #define UP      14;
  148.  
  149. #define ASK     15;
  150. #define DIG     16;
  151. #define EAT     17;
  152. #define GET         18;
  153. #define PUT     19;
  154. #define SAY     20;
  155. #define TIE     21;
  156. #define USE         22;
  157. #define RUN     23;
  158.  
  159. #define DOWN        24;
  160. #define DROP        25;
  161. #define EAST        26;
  162. #define FILL        27;
  163. #define GIVE        28;
  164. #define HELP        29;
  165. #define KILL        30;
  166. #define LOAD        31;
  167. #define LOCK        32;
  168. #define LOOK        33;
  169. #define OPEN        34;
  170. #define PICK        35;
  171. #define QUIT        36;
  172. #define SAVE        37;
  173. #define SWIM        38;
  174. #define TAKE        39;
  175. #define TURN        40;
  176. #define WAIT        41;
  177. #define WEAR        42;
  178. #define WEST        43;
  179.  
  180. #define BREAK       44;
  181. #define CARRY       45;
  182. #define CLIMB       46;
  183. #define CLOSE       47;
  184. #define CROSS       48;
  185. #define DRINK       49;
  186. #define EMPTY       50;
  187. #define ENTER       51;
  188. #define EQUIP       52;
  189. #define NORTH       53;
  190. #define PAUSE       54;
  191. #define PRINT       55; //output every instruction to allegro.log
  192. #define SCORE       56;
  193. #define SHOOT       57;
  194. #define SOUTH       58;
  195. #define THROW       59;
  196. #define UNTIE       60;
  197.  
  198. #define ATTACK      61;
  199. #define FOLLOW      62;
  200. #define UNLOCK      63;
  201.  
  202. #define EXAMINE     64;
  203. #define NOPRINT     65; //stop sending instructions to allegro.log
  204.  
  205. #define INVENTORY   66;
  206. #define NORTHEAST   67;
  207. #define NORTHWEST   68;
  208. #define SOUTHEAST   69;
  209. #define SOUTHWEST   70;
  210.  
  211. #define DICTIONARY  71;
  212.  
  213. #define MAXCOMMANDS 72;
  214.  
  215.  
  216. //! These need to become defines.
  217. const int SFX_KEYPRESS = 58;           
  218.  
  219. const int LINKTILEOFFSET = -261; const int KEY_DELAY = 65; //Trying this as 6.5 and timer changes as 1.0, using 65 and 10
  220. const int LINE_LENGTH = 54; const int BUFFER_LENGTH = 55;
  221. //int b1[55]; int b2[55]; int b3[55]; int b4[55]; int b5[55];
  222. //int b6[55]; int b7[55]; int b8[55]; int b9[55]; int b10[55];
  223. //int bufptr;
  224.  
  225. const int CHAR_WIDTH = 4;
  226. const int CURSOR_WIDTH = 4;
  227. const int CURSOR_POINT_CHAR = 62;
  228. const int CURSOR_Y_OFFSET = 4;
  229. const int CURSOR_X_OFFSET = 4;
  230. const int BUFFER_OUTPUT_X = 0;
  231. const int BUFFER_OUTPUT_Y = 0;
  232. const int CURSOR_BLINK_DUR = 70;
  233. const int CURSOR_Y_OFS = 1;
  234.  
  235.  
  236. int matchaction(int command){
  237.    
  238.    
  239. }
  240.  
  241. //Returns how many total WORDS are in one instruction set.
  242. int numinstructions(int _buffer){
  243.     ///count the number of spaces in the buffer. THe number of total instructions
  244.     ///equals the number  of spaces, plus onwe
  245.     int spc; int nextchar; bool trailspacedone;
  246.     INSTRUCTIONS_SIZE = SizeOfArray(_buffer);
  247.     for ( int q = SizeOfArray(_buffer); q >= 0; q-- ) {
  248.         //don't count trailing spaces, or contiguous spaces.
  249.         if ( _buffer[q] == CHAR_SPACE ) {
  250.             if ( __buffer[q-1] !isLetter() && !trailspacedone ) {
  251.                 trailspacedone = false; continue;
  252.             }
  253.             else if ( __buffer[q-1] isLetter() && !trailspacedone ) {
  254.                 trailspacedone = true;
  255.                 spc++; continue;
  256.             }
  257.             else if ( __buffer[q-1] !isLetter() && trailspacedone ) continue;
  258.             else if ( __buffer[q-1] isLetter() && trailspacedone ) {
  259.                 spc++;
  260.             }
  261.         }
  262.     }
  263.     //WORDCOUNT[0] = spc+1; //store the total number of words.
  264.     return spc+1;
  265. }
  266.  
  267.  
  268. //Stores the present commands in the text parsing buffer onto the heap
  269. void GetInstructions(int _buffer){
  270.     int wordcount = numinstructions(_buffer);
  271.    
  272.    
  273.     //int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
  274.    
  275.    
  276.     //This time, read the array forward.
  277.     int spc; int nextchar; bool trailspacedone; int curword = 0;
  278.    
  279.     for ( ram[RAM_q] = 0; ram[RAM_q] < INSTRUCTIONS_SIZE; ram[RAM_q]++ ) {
  280.         //don't count trailing spaces, or contiguous spaces.
  281.         if ( curword < wordcount ) {
  282.             //Put the command in CURWORD[]
  283.             do {
  284.                 int ptr = CURWORD; //WORDS[curword];
  285.                 ptr[q] = _buffer[q];
  286.             }
  287.             while ( _buffer[q] != CHAR_SPACE && spc < wordcount );
  288.             //curword++;
  289.             //! Determine what instruction to use
  290.             int command = StringToLabel(WORD); //! This function doe snot yet exist.
  291.             //! Put the word on the heap
  292.             HEAP[HeapPounter] = command;
  293.             HeapPointer++; //The heap pointer +1 will be the number of instructions on the heap.
  294.            
  295.         }
  296.     }
  297.        
  298. }
  299.  
  300. //The current article and preposition.
  301. int ARTICLE; int PREPOSITION;
  302.  
  303. int AdvanceTurn; //Should we advance a turn after executing the stack?
  304.  
  305. void HeapToStack(){
  306.     for ( int q = 0; q < HeapPointer; q++ ) {
  307.         if ( !IsPreposition(HEAP[q]) && !IsConjunction(HEAP[q]) & !IsArticle(HEAP[q]) ) STACK[q] = HEAP[q];
  308.         if ( IsPreposition(HEAP[q]) ) PREPOSITION = HEAP[q];
  309.         if ( IsArticle(HEAP[q] ) ARTICLE = HEAP[q].
  310.         if ( IsConjunction(HEAP[q] ) {
  311.            
  312.             //pop the instructions off thew heap...
  313.             int tempheap[32]; int w;
  314.             //copy the remaining heap into an array
  315.             for ( ; w < 32-q; q++ ) tempheap[w] = HEAP[q];
  316.             //clear the heap
  317.             for ( w = 0; w < 32; e++ ) HEAP[w] = 0;
  318.             //copy the temp back to the heap.
  319.             for ( w = 0; w < 32; w++ ) HEAP[w] = tempheap[w];
  320.             AdvanceTurn = 0; //Do not advance a turn after executing the stack.
  321.             break;
  322.         }
  323.         AdvanceTurn = 1; //After executing the stack, advance a turn.
  324.     }
  325.     //Execute the stack.
  326. }
  327.  
  328. //int WORDS[4];
  329. //holds the indices of each word?
  330.  
  331. #define MAX_WORDS 18; //Max words per instruction. SAY GANDALF GIVE OLD KEY
  332. //Store each word in these buffers.
  333. int WORD_1[18];
  334. int WORD_2[18];
  335. int WORD_3[18];
  336. int WORD_4[18];
  337. int WORD_5[18];
  338. int WordCount; //how many words this time, and the index at which they occur.
  339. int INSTRUCTIONS_SIZE; //Used by functions to minimise loop wastage.
  340.  
  341.  
  342.  
  343. //Add instructions to the 'stack', starting with a COMMAND, then its variables.
  344. void StringToCommand(){
  345.     int counter;
  346.     int buf[3] = "0"; int  buf2[2];
  347.     //one string per command
  348.    
  349.     //command lengths
  350.     //this speeds up matching the string to a command by finding one of the same length
  351.     int commandlengths[]={5, 4, 4, 5, 2, 4, 4, 4, 4, 4, 3, 3, 6, 3}; //list the length of each command in order.
  352.     //match the
  353.    
  354.     //find the command
  355.     //if we encounter a space, increment the counter.
  356.     int legalcommands[]="
  357.         01NORTH
  358.         2EAST
  359.         3WEST
  360.         4SOUTH
  361.         5UP
  362.         6DOWN
  363.         7LOOK
  364.         8TAKE
  365.         9WAIT
  366.         10ASK
  367.         11SAY
  368.         12ATTACK
  369.         13USE
  370.     ";
  371.     //We then check the length of the command
  372.    
  373.     /* We probably don't need a switch for this. Just do:
  374.     */
  375.    
  376.     //Do we want a switch for this?
  377.     //switch (INSTRUCTIONS_SIZE){
  378.     //  case 1:
  379.             //COMMAND only, no verb, no say.
  380.    
  381.     //Parse WORD_1
  382.    
  383.     int curWord = 0;
  384.     int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
  385.    
  386.     //First, the command
  387.     strcpy(WORDS[curWord], temp_command); //store the present word
  388.    
  389.     for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  390.         bool match;
  391.         if ( commandlengths[q] == strlen(temp_command) {
  392.             //if the position of q is < 10, append a leading 0
  393.             if ( q < 10 ) {
  394.                 itoa(q,buf2);
  395.                 strcat(buf2, but);
  396.             }
  397.             //otherwise, just store it
  398.             itoa(q, buf); //overwrite the temp buffer.
  399.            
  400.             //find that number in legal commands
  401.             for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  402.                
  403.                 //! stringparser finds a matching string, and returns its position?
  404.                    
  405.                 //if ( stringparser(buf) ) return q; //if the string matches
  406.                
  407.                 //This is the inverse of the old string parser, so instead, let's do this
  408.                
  409.                 int bufcompare[18];
  410.                 stringparser(q, bufcompare); //copy instruction q into the compare buffer
  411.                 for ( int e = 0; e < strlen(bufcompare); e++ ) {
  412.                     //compare each index
  413.                     if ( temp_command[e] != bufcompare[3] ) {
  414.                         //failed to compare
  415.                         match = false;
  416.                         break;
  417.                     }
  418.                     match = true; //we found the match.
  419.                     //return atoi(buf); //return the command ID.
  420.                    
  421.                    
  422.                    
  423.                     //! no, we want to store the commcomamnd, to parse,
  424.                     //! and add variables to it.
  425.                     stack[curWord] = atoi(buf);
  426.                     break;
  427.                 }
  428.                
  429.                 //the parsed string, thast is its command number.
  430.                 //so, return it.
  431.                  
  432.             }
  433.             break; //if we fail, we fall through.
  434.         }
  435.         if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
  436.         //!! no, put INVALID into the stack.
  437.     }
  438.     curWord++; //Increase the SP.
  439.    
  440.     int legal_variables="
  441.    
  442.    
  443.    
  444.    
  445.    
  446.     ";
  447.    
  448.     //Then, its VARIABLES, if any.
  449.     for ( int q = 1; q < WordCount; q++ ) {
  450.         strcpy(WORDS[curWord], temp_command); //store the present word
  451.    
  452.         for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  453.             bool match;
  454.             if ( commandlengths[q] == strlen(temp_command) {
  455.                 //if the position of q is < 10, append a leading 0
  456.                 if ( q < 10 ) {
  457.                     itoa(q,buf2);
  458.                     strcat(buf2, but);
  459.                 }
  460.                 //otherwise, just store it
  461.                 itoa(q, buf); //overwrite the temp buffer.
  462.                
  463.                 //find that number in legal commands
  464.                 for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  465.                    
  466.                     //! stringparser finds a matching string, and returns its position?
  467.                        
  468.                     //if ( stringparser(buf) ) return q; //if the string matches
  469.                    
  470.                     //This is the inverse of the old string parser, so instead, let's do this
  471.                    
  472.                     int bufcompare[18];
  473.                     stringparser(q, bufcompare); //copy instruction q into the compare buffer
  474.                     for ( int e = 0; e < strlen(bufcompare); e++ ) {
  475.                         //compare each index
  476.                         if ( temp_command[e] != bufcompare[3] ) {
  477.                             //failed to compare
  478.                             match = false;
  479.                             break;
  480.                         }
  481.                         match = true; //we found the match.
  482.                         //return atoi(buf); //return the command ID.
  483.                        
  484.                        
  485.                        
  486.                         //! no, we want to store the commcomamnd, to parse,
  487.                         //! and add variables to it.
  488.                         stack[curWord] = atoi(buf);
  489.                         break;
  490.                     }
  491.                    
  492.                     //the parsed string, thast is its command number.
  493.                     //so, return it.
  494.                      
  495.                 }
  496.                 break; //if we fail, we fall through.
  497.             }
  498.             if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
  499.             //!! no, put INVALID into the stack.
  500.         }
  501.         currWord++; //Increase the SP.
  502.     }
  503. }
  504.        
  505.    
  506. void doaction(int action){
  507.     //get actions off the stack, and pop them
  508.     int tempheap[5]; int command;
  509.     for ( int q = 0; q <= MAX_WORDS; q++ ){
  510.         hempheap[q] = stack[q];
  511.         stack[q] = 0; //popped
  512.     }
  513.    
  514.     switch(NUMWORDS){
  515.         case 1:
  516.            
  517.             //actions only
  518.             command = tempheap[0];
  519.            
  520.             switch(command){
  521.                
  522.                
  523.                
  524.             }
  525.    
  526.        
  527.         case 2:
  528.            
  529.             //action and noun
  530.             int command = tempstack[0];
  531.             int adjective = tempstack[1];
  532.             int noun = tempstack[2];
  533.        
  534.             switch(noun){
  535.                 //find the object by checking for NOUN on screen
  536.                 case 1:
  537.                     switch(command){
  538.                        
  539.                         case 1:
  540.                             //perform action on noun
  541.                     }
  542.                 }
  543.             }
  544.        
  545.         case 3: //command, and two words
  546.             //can be 'command adjective noun'
  547.             int command = tempstack[0];
  548.             int adjective = tempstack[1];
  549.             int noun = tempstack[2];
  550.             //append adjective to ADJECTIVE_NOUN[36]
  551.                         //and append a space
  552.                             //append the noun to the ADCECTIVE_NOUN string
  553.             switch(noun){
  554.                
  555.                 //!!!!!!!
  556.                 //! it might improve performance to do the adjective and noun first, and perform the command
  557.                 //case, on those.
  558.                
  559.                
  560.                     //determine of the noun is an enemy, or an item.
  561.                 case 1:
  562.                 case 2:
  563.                 case 3: //items
  564.                     //item cases go here
  565.                     //check for items matchint the ADJECTIVE_NOUN string by name
  566.                     //if they exist, perform the action on them, if possible
  567.                
  568.                     //if they are not on screen, but are in inventory, perform the action.
  569.                 switch(action){
  570.                     case TAKE:
  571.                         break;
  572.                     case GIVE;
  573.                         break;
  574.                     case USE:
  575.                         break;
  576.                     case EQUIP:
  577.                         break;
  578.                     default:
  579.                         SyntaxErr();
  580.                         break;
  581.                    
  582.                     //Perform the action on the target.
  583.                 }
  584.                 break;
  585.                
  586.                 //enemies
  587.                 case TROLL:
  588.                 case GOBLIN:
  589.                 case GOLLUM:
  590.                 case SMAUG:
  591.                     switch(action){
  592.                         case ATTACK:
  593.                             break;
  594.                         default:
  595.                             SyntaxErr();
  596.                             break;
  597.                     //Perform the action on the target.
  598.                 }
  599.                 break;
  600.                     //Scan the screen for an npc that matches the string ADJECTIVE_NOUN
  601.                    
  602.                 case OTHER:
  603.                     SyntaxErr();
  604.                     break;
  605.                 /*
  606.                 switch(adjective){
  607.                     //narrow the field? Do we ever need to do this?
  608.                    
  609.                     case 1:
  610.                         int noun = tempstack[2];
  611.                         //append adjective to ADJECTIVE_NOUN[36]
  612.                         //and append a space
  613.                         switch(noun){
  614.                             //append the noun to the ADCECTIVE_NOUN string
  615.                             case 1:
  616.                                 //item cases go here
  617.                                 //check for items matchint the ADJECTIVE_NOUN string by name
  618.                                 //if they exist, perform the action on them, if possible
  619.                            
  620.                                 //if they are not on screen, but are in inventory, perform the action.
  621.                         }
  622.                 }
  623.                
  624.                 switch(action){
  625.                    
  626.                     Perform the action on the target.
  627.                 }
  628.                 */
  629.                 default:
  630.                     SyntaxErr();
  631.                     break;
  632.                
  633.                
  634.             }
  635.            
  636.         case 4: //command and three words
  637.             /* this is where things become quite complex, as this includes the SAY
  638.                 instruction. In fact... I believe that 4 must alays be the say instruction.
  639.                 //! Don;t forget 'CARRY'
  640.             */
  641.             int person = tempstack[1];
  642.             int action = tempstack[2];
  643.             int noun = tempstack[3];
  644.        
  645.             switch (command){
  646.                 case SAY:
  647.                     //if the command isn't say, then we're doing something else, likely syntax err.,
  648.                     case (person){
  649.                         //check to see if the person is present.
  650.                         case GANDALF:
  651.                             if ( !isGandalfPresent() ) break;
  652.                         case THORIN:
  653.                             if ( !isThorinPresent() ) break;
  654.                         case ELROND:
  655.                             if ( !isElrondPresent() ) break;
  656.                         case GOLLUM
  657.                             if ( !isTHorinPresent() ) break;
  658.                         case BEORN:
  659.                             if ( !isBeornPresent() ) break;
  660.                         case BARD:
  661.                             if ( !isTHorinPresent() ) break;
  662.                         case SMAUG
  663.                             if ( !isTHorinPresent() ) break;
  664.                        
  665.                             //Each character gets this block, with legal actions and such.
  666.                             switch(action){
  667.                                
  668.                                 case GIVE:
  669.                                     switch(noun){
  670.                                         case 1:
  671.                                             //check objects in inventory
  672.                                             //if we give the object to a character, mark their inventory
  673.                                             //array and remove the object from our own
  674.                                            
  675.                                     }
  676.                                 case ATTACK;
  677.                                     switch(noun){
  678.                                         //check the screen for some creature that matches
  679.                                         //noun by name.
  680.                                         case 1:
  681.                                     }
  682.                             }
  683.                     }
  684.                 default:
  685.                     //not the say command, return an error.
  686.             }
  687.            
  688.         case 5:
  689.             //say, person, action, adjective, noun
  690.         //! Don;t forget 'CARRY'
  691.         switch (command){
  692.                 case SAY:
  693.                     int person = tempstack[1];
  694.                     case (person){
  695.                         case 1:
  696.                             int action = tempstack[2];
  697.                             switch(action){
  698.                                 int adj = tempstack[3];
  699.                                 case 1:
  700.                                     switch(adj){
  701.                                         int noun = tempstack[4];
  702.                                        
  703.                                         case 1:
  704.                                             switch(noun){
  705.                                                 case 1:
  706.                                             }
  707.                                            
  708.                                     }
  709.                             }
  710.                     }
  711.                 default:
  712.                     //not the say command, return an error.
  713.             }
  714.            
  715.     switch(action){
  716.        
  717.         case :
  718.            
  719.         default:
  720.             break;
  721.     }
  722. }
  723.  
  724. int GetCommandID(){
  725.     //format
  726.     int FirstLetter = WORD[0];
  727.     switch(WordLength){
  728.         //check only useful words
  729.         case 1:
  730.             case 'E':
  731.                 if (stringcompare(WORD, "E") return E;
  732.             case 'I':
  733.                 if (stringcompare(WORD, "I") return I;
  734.            
  735.             case
  736.         case 2:
  737.             switch(FirstLetter){
  738.                 //check only instructions that begin with the appropriate letter.
  739.                 case 'G':
  740.                     if (stringcompare(WORD, "GO") return GO;
  741.     //if (stringcompare(WORD, "COMMAND") return COMMAND;
  742. }
  743.  
  744. //order the instructions so that when we act on them, we use a simple ordering system to do it
  745. bool IsCommand(int c){} //Return if the instruction is a command
  746. bool IsNoun(int c){}
  747. bool IsAdjective(int c){}
  748. bool IsNPC(int c){}
  749. bool IsEnemy(int c){}
  750.  
  751. //Store the adjectives and use these to try matching them with the nouns and npcs prvided in the instructions.
  752. int CurAdjective[18]; int CurAdjective1[18]; int CurAdjective2[18]; int CurAdjective3[18]; int CurAdjective4[18];
  753.  
  754. int CurNoun[18]; int CurNPC[18];
  755.  
  756. //Try to match the adjective and noun or enemy to a valid pair on the screen.
  757. int MatchDescription(){
  758. }
  759.  
  760. /* Check how many chars are in the present WORD. Try to determine the type of instruction (command, noun, and such if possible).
  761.     Make a loop var, and parse these arrays.
  762.     Find a starting point by iterating LabelLengths with numbers matching the length of WORD.
  763.     store the position in a new var
  764.     continue parsing umtil we reach the first index that is not the correct length
  765.     once we reach a position with the same length, check LABELS
  766.     copy the current position + WORD length to a buffer.
  767.     Compare the string literal to the buffer.
  768.     If it matches, return LabelID[iteration index].
  769.  
  770.     We only need to check the first letter of an instruction when comparing it, before moving on.
  771.     The comparison function should return false as soon as its internal iterator reaches a letter doesn;t match.
  772. */
  773.  
  774. //Determines if two strings are the same. Returns false as soon as it reaches a character that does not match.
  775. bool MatchLabel(int buffer, int string, int length){
  776.     for ( int q = 0; q <= length; q++ )
  777.         if ( buffer[q] != string[q] ) return false;
  778.     return true;
  779. }
  780.  
  781. int LabelIDs[]= {
  782.     //Commands
  783.     0,
  784.     1, 2, 3, 4, 5, 6, 7, 8,
  785.     9, 10, 11, 12, 13, 14,
  786.     15,16,17,18,19,20,21,22,23,
  787.     24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,
  788.     44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
  789.     61,62,63,
  790.     64,65,
  791.     66,67,68,69,70,
  792.     71,
  793.    
  794. }
  795.  
  796. int Labels[]="
  797. none,
  798. D E I L N S U W
  799. GO NE NW SE SW UP
  800. ASK DIG EAT GET PUT SAY TIE USE RUN
  801. DOWN DROP EAST FILL GIVE HELP KILL LOAD LOCK LOOK OPEN PICK QUIT SAVE SWIM TAKE TURN WAIT WEST WEAR
  802. BREAK CARRY CLIMB CLOSE CROSS DRINK EMPTY ENTER EQUIP NORTH PAUSE PRINT SCORE SHOOT SOUTH THROW UNTIE
  803. ATTACK FOLLOW UNLOCK
  804. EXAMINE NOPRINT
  805. INVENTORY NORTHEAST NORTHWEST SOUTHEAST SOUTHWEST
  806. DICTIONARY
  807.  
  808.  
  809.  
  810.  
  811. "
  812.  
  813. int LabelLengths={
  814.     0,
  815. 1, 1, 1, 1, 1, 1, 1, 1,
  816.     2,2,2,2,2,2,
  817.     3,3,3,3,3,3,3,3,3,
  818.     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  819.     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  820.     6,6,6,
  821.     7,7,
  822.     8,8,8,8,8,
  823.     9,
  824.    
  825.    
  826.    
  827.    
  828.    
  829.    
  830.    
  831. }
  832.  
  833. //ASM VARIABLES
  834.  
  835. //NOUNS
  836.  
  837. //! Do we want these defined in sets? I think they probably need a unique instruction ID per variable, not 1-N per set.
  838.  
  839. /* Any noun that can also be written as another noun, should have the same value. For example, if you want
  840.     to allow the player to say either TAKE THE GOLD or TAKE THE TREASURE, make both GOLD and TREASURE the same
  841.     instruction ID.
  842.  
  843.     I have intentionally placed large gaps in the instruction table to allow expanding it later, while maintaining
  844.     efficiency b y allowing new additions to fall between existing variables, based on number of characters in their
  845.     label, and alphabetic sorting.
  846. */
  847.  
  848. //! UGH, NO, THEY NEED TO BE NUMBERED IN ORDER TO MATCH THE ARRAY POSITIONS.
  849.  
  850.  
  851. //onjunctions
  852. #define AND 200;
  853. #define THEN    201;
  854.  
  855. //Articles
  856. #define A   210;
  857. #define THE     220; //an article, but it is also ignored
  858.  
  859. //Items
  860. #define AXE 300;
  861. #define KEY     310
  862. #define MAP     320;
  863. #define BOX 330;
  864. #define ROD 340;
  865.  
  866. #define FOOD    500;
  867. #define GOLD    520;
  868. #define RING    530;
  869. #define ROPE    540;
  870. #define WINE    550;
  871.  
  872. #define CHEST   700;
  873. #define LUNCH   710;
  874. #define STAFF   720;
  875. #define SWORD   730;
  876. #define TORCH   740;
  877.  
  878. #define BARREL  900;
  879. #define DAGGER  910;
  880.  
  881. #define TREASURE 1100;
  882.  
  883.  
  884. //NPCs (person)
  885. #define ME  1300;  //Because characters can be treated like items, for the CARRY command, they need a special case.
  886.  
  887. #define ELF     1500; //WOOD ELF
  888. #define BARD    1510;
  889. #define WOOD    1520; //WOOD ELF
  890.  
  891. #define BEORN   1700;
  892.  
  893. #define BUTLER  1900;
  894. #define ELROND  1910;
  895. #define THORIN  1920;
  896.  
  897. #define GANDALF 2100;
  898.  
  899. //Enemies
  900. #define EYES    2300; //PALE BULBOUS EYES
  901. #define WARG    2310;
  902. 9
  903. #define SMAUG   2500;
  904. #define TROLL   2510;
  905.  
  906. #define DRAGON  2700; //should be the same as SMAUG in context, but also needs to be an adjective so that THE DRAGON SMAUG is legal.
  907. #define GOBLIN  2710;
  908. #define GOLLUM  2720;
  909.  
  910.  
  911. //ADJECTIVES and ADVERBS
  912. #define OLD     2900;
  913.  
  914. #define PALE    3100;
  915. #define UGLY    3110;
  916.  
  917. #define LARGE   3300;
  918. #define SHORT   3310;
  919. #define SHINY   3320;
  920.  
  921. #define DRAGON  3500;
  922. #define GENTLY  3510;
  923. #define GOLDEN  3520;
  924. #define SOFTLY  3530;
  925.    
  926. #define BULBOUS 3700;
  927. #define CURIOUS 3710;
  928. #define HIDEOUS 3720;
  929. #define MAGICAL 3730;
  930. #define QUICKLY 3740;
  931. #define STRANGE 3750;
  932. #define UNUSUAL 3760;
  933.  
  934. #define CAREFULLY 3900;
  935. #define VICIOUSLY 3910;
  936.  
  937.  
  938. //Prepositions
  939. //! If we scan a perposition, just ignore it. ATTACK GOBLIN WITH THE SHORT SWORD == ATACK GOBLIN SHORT SWORD
  940. //! Prepositions exist only to facilitate natural language, not to be parsd. !!!
  941. //! We **DO** need to store the ACTIVE PREPOSITION somewhere, so that our outut story string USES it to
  942. //! describe the action.
  943. //! if the player says: PUT ROPE IN BARREL
  944. //! We need to respond: THE ROPE IS **IN** THE BARREL, or something of that sort.
  945.  
  946. #define AT  4100;
  947. #define IN  4110;
  948. #define OF  4120;
  949. #define ON  4130;
  950. #define TO  4140;
  951.  
  952. #define OFF 4200;
  953. #define OUT 4210;
  954.  
  955. #define FROM    4500;
  956. #define INTO    4510;
  957. #define WITH    4520;
  958.  
  959. #define ACROSS  4700;
  960.    
  961. #define THROUGH 4900;
  962.  
  963. //UP
  964.  
  965. //Special
  966. int navi[]="HEY LISTEN";
  967.  
  968.  
  969.  
  970. //Constructs
  971. //ACTION
  972. //ACTION NOUN
  973. //ACTION VERB NOUN
  974. //SAY NPC SPEAK
  975.  
  976. /*
  977.  
  978.  
  979. GAME DICTIONARY
  980.  
  981. Movements:
  982. DOWN D, EAST E, NORTH N, NORTHEAST NE, NORTHWEST NW, SOUTH S,
  983. SOUTHEAST SE, SOUTHWEST SW, UP U, WEST W.
  984.  
  985. Special verbs:
  986. EXAMINE, HELP, INVENTORY I, LOAD, LOOK L, NOPRINT, PAUSE, PRINT,
  987. QUIT, SAVE, SCORE.
  988. DICTIONARY
  989.  
  990. Action verbs:
  991. BREAK, CLIMB, CLOSE, CROSS, DIG, DROP, DRINK, EMPTY, ENTER, EAT,
  992. FILL, FOLLOW, GIVE, GO, KILL, LOCK, PICK, PUT, OPEN, RUN, SAY,
  993. SHOOT, SWIM, TIE, TAKE, THROW, TURN, UNLOCK, UNTIE, WEAR.
  994.  
  995. Prepositions:
  996. ACROSS, AT, FROM, IN, INTO, ON, OUT, OFF, THROUGH, TO, UP, WITH
  997.  
  998. Adverbs:
  999. CAREFULLY, GENTLY, QUICKLY, SOFTLY, VICIOUSLY
  1000.  
  1001. */
  1002.  
  1003. //SPEAK
  1004. //ONE WORD
  1005.  
  1006. //TWO WORDS
  1007. //"GIVE" item
  1008.     //item NOUN
  1009.     //item VERB NOUN
  1010. //"CARRY" item, person
  1011.     //item NOUN, person
  1012.     //item VERB NOUN, person
  1013. //"ATTACK"  npc
  1014.     //attack, NPC
  1015.     //attack VERB NPC
  1016.  
  1017.  
  1018.  
  1019. bool Parse(int inputBuffer){
  1020.     int
  1021.    
  1022.    
  1023.    
  1024. /*
  1025.     switch (strlen(temp_command)){
  1026.         int buf[3] = "0"; int  buf2[2];
  1027.        
  1028.         case 3:
  1029.            
  1030.             //check commands with a length of 3...
  1031.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  1032.                 if ( commandlengths[q] == 3 ) {
  1033.                     //if the position of q is < 10, append a leading 0
  1034.                     if ( q < 10 ) {
  1035.                         itoa(q,buf2);
  1036.                         strcat(buf2, but);
  1037.                     }
  1038.                     //otherwise, just store it
  1039.                     itoa(q, buf); //overwrite the temp buffer.
  1040.                    
  1041.                     //find that number in legal commands
  1042.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  1043.                         if ( stringparser(buf) ) return q; //if the string matches
  1044.                             //the parsed string, thast is its command number.
  1045.                         //so, return it.
  1046.                     }
  1047.                     break; //if we fail, we fall through.
  1048.                 }
  1049.                 break; //fall though
  1050.             }
  1051.         case 4:
  1052.             //check commands with a length of 3.
  1053.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  1054.                 if ( commandlengths[q] == 4 ) {
  1055.                     //if the position of q is < 10, append a leading 0
  1056.                     if ( q < 10 ) {
  1057.                         itoa(q,buf2);
  1058.                         strcat(buf2, but);
  1059.                     }
  1060.                     //otherwise, just store it
  1061.                     itoa(q, buf); //overwrite the temp buffer.
  1062.                    
  1063.                     //find that number in legal commands
  1064.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  1065.                         if ( stringparser(buf) ) return q; //if the string matches
  1066.                             //the parsed string, thast is its command number.
  1067.                         //so, return it.
  1068.                     }
  1069.                     break; //if we fail, we fall through.
  1070.                 }
  1071.                 break; //fall though
  1072.             }
  1073.            
  1074.         case 5:
  1075.             //check commands with a length of 3.
  1076.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  1077.                 if ( commandlengths[q] == 4 ) {
  1078.                     //if the position of q is < 10, append a leading 0
  1079.                     if ( q < 10 ) {
  1080.                         itoa(q,buf2);
  1081.                         strcat(buf2, but);
  1082.                     }
  1083.                     //otherwise, just store it
  1084.                     itoa(q, buf); //overwrite the temp buffer.
  1085.                    
  1086.                     //find that number in legal commands
  1087.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  1088.                         if ( stringparser(buf) ) return q; //if the string matches
  1089.                             //the parsed string, thast is its command number.
  1090.                         //so, return it.
  1091.                     }
  1092.                     break; //if we fail, we fall through.
  1093.                 }
  1094.                 break; //fall though
  1095.             }
  1096.            
  1097.         case 6:
  1098.            
  1099.         default:
  1100.             //invalid command.
  1101.     }
  1102.     */
  1103.  
  1104. //Global script for text buffer
  1105. //preliminary
  1106.  
  1107.  
  1108. global script a{
  1109.     void run(){
  1110. //int buffers[]={b1, b2, b3, b4, b5, b6, b7, b8, b9, b10};
  1111.     //bufptr = buffers;
  1112.     //int curbuffer = bufptr[q];
  1113.         int buffersize = SizeOfArray(buffer);
  1114.         Link->Y = 90;
  1115.         //Game->Cheat = 4;
  1116.         while(true){
  1117.             //Link->PressMap = false;
  1118.             Link->InputMap = false;
  1119.             if ( timer ) cantype = false;
  1120.             if ( !timer ) cantype = true;
  1121.             if ( Game->KeyPress[115] || Game->KeyPress[116] ) ShiftKey = true;
  1122.             else ShiftKey = false;
  1123.             if ( timer > 0 ) timer -10;
  1124.             if ( timer <= 0 ) timer = 0;
  1125.             if ( cursorblink > 0 ) cursorblink--;
  1126.             if ( cursorblink <= 0 ) cursorblink = 100;
  1127.             if ( cantype ) {
  1128.                 //if we are not over the arbitrary buffer limit
  1129.                 if ( ram[RAM_q] < buffersize ) {
  1130.                     //int keystroke;
  1131.                     for ( int qq = 1; qq <= KEY_COMMAND; q++ ) {
  1132.                         if ( qq < KEY_DEL ) {
  1133.                             if ( ( buffer[q] = CheckKeyToChar(qq,true) ) != CHAR_BACKSPC ) {
  1134.                                 if ( buffer[q] == CHAR_TAB ) {
  1135.                                     for ( int w = 0; w < 4; w++ ) { buffer[q] = CHAR_SPACE; CursorAdv(RAM_q); temp_q++; if ( SFX_KEYPRESS > 0 ) Game->PlaySound(SFX_KEYPRESS);}
  1136.                                     timer = KEY_DELAY;
  1137.                                 }
  1138.                                 else {
  1139.                                     CursorAdv(RAM_q); temp_q++;
  1140.                                     if ( SFX_KEYPRESS > 0 ) Game->PlaySound(SFX_KEYPRESS);
  1141.                                     timer = KEY_DELAY;
  1142.                                 }
  1143.                                 break;
  1144.                             }
  1145.                         }
  1146.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_BACKSPC ) {
  1147.                             buffer[q] = 0; CursorRev(RAM_q); temp_q--;
  1148.                             if ( SFX_KEYPRESS > 0 ) Game->PlaySound(SFX_KEYPRESS);
  1149.                             timer = KEY_DELAY;
  1150.                             break;
  1151.                         }
  1152.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_DEL ) {
  1153.                             for ( int w = qq; w >=0; w-- ) buffer[w] = 0;
  1154.                             for ( int w = qq; w >=0; w-- ) bufferoverlay[w] = 0;
  1155.                             ram[RAM_q] = 0;
  1156.                             if ( SFX_CLEARBUFFER > 0 ) Game->PlaySound(SFX_CLEARBUFFER);
  1157.                             timer = KEY_DELAY;
  1158.                             break;
  1159.                         }
  1160.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_HOME ) {
  1161.                             //used for tilde and grave, as that key is used by the ZC UI.
  1162.                             if ( (Game->KeyPress[KEY_LSHIFT] || Game->KeyPress[KEY_RSHIFT])){
  1163.                                 buffer[q] = '~'; CursorAdv(RAM_q); temp_q++; if ( SFX_KEYPRESS > 0 ) Game->PlaySound(SFX_KEYPRESS);
  1164.                             }
  1165.                             else {
  1166.                                 buffer[q] = '`'; CursorAdv(RAM_q); temp_q++; if ( SFX_KEYPRESS > 0 ) Game->PlaySound(SFX_KEYPRESS);
  1167.                             }
  1168.                             timer = KEY_DELAY;
  1169.                         }
  1170.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_ARROW_U ) {
  1171.                             Link->PressUp = false; Link->InputUp = false;
  1172.                             LeapInstruction("UP");
  1173.                             break;
  1174.                         }
  1175.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_ARROW_D ) {
  1176.                             Link->PressDown = false; Link->InputDown = false;
  1177.                             LeapInstruction("DOWN");
  1178.                             break;
  1179.                         }
  1180.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_ARROW_L ) {
  1181.                             Link->PressLeft = false; Link->InputLeft = false;
  1182.                             LeapInstruction("LEFT");
  1183.                             break;
  1184.                         }
  1185.                         if ( ( buffer[q] = CheckKeyToChar(qq,true) ) == CHAR_ARROW_R ) {
  1186.                             Link->PressRight = false; Link->InputRight = false;
  1187.                             LeapInstruction("RIGHT");
  1188.                             break;
  1189.                         }
  1190.                         bufferoverlay[q] = '_'; //Cursor
  1191.                     }
  1192.                 }
  1193.             }
  1194.  
  1195.             Screen->DrawString(6,0,0,2, 0x01, -1, 0, GetBuffer(),128);
  1196.             //draw buffer overlay, with blink
  1197.    
  1198.             //We can replace the null char in the loop with something that can be a cursor.
  1199.             //Perhaps something greyed out or translucent, like an underscore, and make it blink?
  1200.             if ( cursorblink > CURSOR_BLINK_DUR ) {
  1201.                 Screen->DrawString(6,0,0+CURSOR_Y_OFS,2, 0x01, -1, 0, GetCursorOverlay(),128); //cursor
  1202.                 /*
  1203.                 Screen->Line(6,
  1204.                     0+0+(q*CHAR_WIDTH),
  1205.                     //BUFFER_OUTPUT_X+CURSOR_X_OFFSET+(q*CHAR_WIDTH),
  1206.                     //BUFFER_OUTPUT_Y+CURSOR_Y_OFFSET,
  1207.                     6,
  1208.                     0+0+(q*CHAR_WIDTH)+4,
  1209.                     //BUFFER_OUTPUT_X+CURSOR_X_OFFSET+(q*CHAR_WIDTH) + CURSOR_WIDTH,
  1210.                     6,
  1211.                     //BUFFER_OUTPUT_Y+CURSOR_Y_OFFSET,
  1212.                     0x01, 1, 0, 0, 0, 128);
  1213.                 */
  1214.             }  
  1215.             Waitdraw(); Waitframe();
  1216.         }
  1217.     }
  1218. }  
  1219. int GetBuffer(){
  1220.     //int ptr = bufptr;
  1221.     //return bufptr[buffer];
  1222.     return buffer;
  1223.    
  1224. }      
  1225.  
  1226. int GetCursorOverlay(){
  1227.     return bufferoverlay;
  1228. }
  1229.  
  1230. //CursorAdv(RAM_q);
  1231. void CursorAdv(int n){
  1232.     bufferoverlay[ram[n]] = CHAR_SPACE;
  1233.     ram[n]++;
  1234.     bufferoverlay[ram[n]] = '_'; //Cursor.
  1235. }
  1236.  
  1237. //CursorRev(RAM_q);
  1238. void CursorRev(int n){
  1239.     bufferoverlay[ram[n]] = 0;
  1240.     ram[n]--;
  1241.     bufferoverlay[ram[n]] = '_'; //Cursor.
  1242. }
  1243.  
  1244. void GetNextWord(int word, int output){}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement