770 lines
20 KiB
Plaintext
770 lines
20 KiB
Plaintext
/*
|
|
This file is part of Warzone 2100.
|
|
Copyright (C) 2006-2008 Roman
|
|
Copyright (C) 2006-2009 Warzone Resurrection Project
|
|
|
|
Warzone 2100 is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Warzone 2100 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Warzone 2100; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
%{
|
|
/*
|
|
* chat_parser.y
|
|
*
|
|
* yacc grammar for multiplayer chat messages
|
|
*
|
|
*/
|
|
#include "lib/framework/frame.h"
|
|
#include "lib/framework/string_ext.h"
|
|
|
|
#include "lib/framework/frameresource.h"
|
|
#include "lib/script/chat_processing.h"
|
|
|
|
#define MAX_CHAT_ARGUMENTS 10
|
|
|
|
/* Holds information about a processed player chat message */
|
|
CHAT_MSG chat_msg;
|
|
|
|
// Parameter variable
|
|
static INTERP_VAL scrParameter;
|
|
|
|
extern int chat_lex(void);
|
|
|
|
// Store extracted command for use in scripts
|
|
static void chat_store_command(const char *command);
|
|
|
|
/* Return value of the chat parsing - to be used in scripts */
|
|
static BOOL chat_store_parameter(INTERP_VAL *parameter);
|
|
|
|
// Store players that were addressed in a command
|
|
static void chat_store_player(SDWORD cmdIndex, SDWORD playerIndex);
|
|
|
|
// Reset a command
|
|
static void chat_reset_command(SDWORD cmdIndex);
|
|
|
|
// Information extracted from message and available for scripts
|
|
//static int numMsgParams=0; //number of parameters currently extracted/stored
|
|
//static INTERP_VAL msgParams[MAX_CHAT_ARGUMENTS];
|
|
|
|
/* Store command parameter extracted from the message */
|
|
static BOOL chat_store_parameter(INTERP_VAL *cmdParam)
|
|
{
|
|
SDWORD numCmdParams, numCommands;
|
|
|
|
//console("chat_store_parameter: new parameter");
|
|
|
|
/* Make sure we have no overflow */
|
|
//if(numMsgParams >= MAX_CHAT_ARGUMENTS)
|
|
if(chat_msg.numCommands >= MAX_CHAT_COMMANDS)
|
|
{
|
|
ASSERT(false, "chat_store_parameter: too many commands in a message");
|
|
return false;
|
|
}
|
|
|
|
numCommands = chat_msg.numCommands;
|
|
numCmdParams = chat_msg.cmdData[numCommands].numCmdParams;
|
|
|
|
/* Make sure we still have room for more parameters */
|
|
if(numCmdParams >= MAX_CHAT_CMD_PARAMS)
|
|
{
|
|
ASSERT(false, "chat_store_parameter: out of parameters for command %d", numCommands);
|
|
return false;
|
|
}
|
|
|
|
/* Store parameter for command we are currently processing */
|
|
//memcpy(&(msgParams[numMsgParams]), parameter, sizeof(INTERP_VAL));
|
|
memcpy(&(chat_msg.cmdData[numCommands].parameter[numCmdParams]), cmdParam, sizeof(INTERP_VAL));
|
|
|
|
chat_msg.cmdData[numCommands].numCmdParams++;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Store extracted command for use in scripts
|
|
static void chat_store_command(const char *command)
|
|
{
|
|
SDWORD numCmdParams, numCommands;
|
|
|
|
//console("chat_store_command: new command: %s", command);
|
|
|
|
/* Make sure we have no overflow */
|
|
if(chat_msg.numCommands >= MAX_CHAT_COMMANDS)
|
|
{
|
|
ASSERT(false, "chat_store_command: too many commands in a message");
|
|
return;
|
|
}
|
|
|
|
numCommands = chat_msg.numCommands;
|
|
numCmdParams = chat_msg.cmdData[numCommands].numCmdParams;
|
|
|
|
/* Make sure we still have room for more parameters */
|
|
if(numCmdParams >= MAX_CHAT_CMD_PARAMS)
|
|
{
|
|
ASSERT(false, "chat_store_command: out of parameters for command %d", numCommands);
|
|
return;
|
|
}
|
|
|
|
/* Store command */
|
|
chat_msg.cmdData[numCommands].pCmdDescription = command;
|
|
|
|
chat_msg.numCommands++;
|
|
}
|
|
|
|
// Store players that were addressed in a command
|
|
static void chat_store_player(SDWORD cmdIndex, SDWORD playerIndex)
|
|
{
|
|
SDWORD i;
|
|
|
|
//console("chat_store_player: player %d addressd in command %d", playerIndex, cmdIndex);
|
|
|
|
/* Make sure we have no overflow */
|
|
if(cmdIndex < 0 || cmdIndex >= MAX_CHAT_COMMANDS)
|
|
{
|
|
ASSERT(false, "chat_store_player: command message out of bounds: %d", cmdIndex);
|
|
return;
|
|
}
|
|
|
|
if(playerIndex == -1) //no player specified means all players addressed
|
|
{
|
|
/* Ally players addressed */
|
|
for(i=0; i<MAX_PLAYERS; i++)
|
|
{
|
|
chat_msg.cmdData[cmdIndex].bPlayerAddressed[i] = true;
|
|
}
|
|
}
|
|
else if(playerIndex >= 0 && playerIndex < MAX_PLAYERS)
|
|
{
|
|
chat_msg.cmdData[cmdIndex].bPlayerAddressed[playerIndex] = true;
|
|
}
|
|
else /* Wrong player index */
|
|
{
|
|
ASSERT(false, "chat_store_player: wrong player index: %d", playerIndex);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void chat_reset_command(SDWORD cmdIndex)
|
|
{
|
|
SDWORD i;
|
|
|
|
ASSERT(cmdIndex >= 0 && cmdIndex < MAX_CHAT_COMMANDS,
|
|
"chat_reset_command: command index out of bounds: %d", cmdIndex);
|
|
|
|
chat_msg.cmdData[cmdIndex].numCmdParams = 0;
|
|
|
|
for(i=0; i<MAX_PLAYERS; i++)
|
|
{
|
|
chat_msg.cmdData[cmdIndex].bPlayerAddressed[i] = false;
|
|
}
|
|
}
|
|
|
|
static void yyerror(const char* msg);
|
|
|
|
%}
|
|
|
|
%name-prefix="chat_"
|
|
|
|
%union {
|
|
BOOL bval;
|
|
SDWORD ival;
|
|
}
|
|
|
|
/* Start symbol */
|
|
%start R_PHRASE
|
|
|
|
/* keywords */
|
|
%token BRACKET_OPEN
|
|
%token BRACKET_CLOSE
|
|
%token SQ_BRACKET_OPEN
|
|
%token SQ_BRACKET_CLOSE
|
|
%token PIPE
|
|
%token T_WORD
|
|
|
|
%token R_POSSESSION
|
|
%token _T_QM
|
|
%token _T_EM
|
|
%token _T_FULLSTOP
|
|
%token _T_COLON
|
|
%token _T_SEMICOLON
|
|
%token _T_COMMA
|
|
|
|
%token _T_A
|
|
%token _T_AFFIRMATIVE
|
|
%token _T_AFTER
|
|
%token _T_ALLY
|
|
%token _T_AM
|
|
%token _T_AN
|
|
%token _T_AND
|
|
%token _T_ANY
|
|
%token _T_ATTACK
|
|
%token _T_ATTACKING
|
|
%token _T_ARMY
|
|
%token _T_BEACON
|
|
%token _T_BUILDING
|
|
%token _T_CANT
|
|
%token _T_CENTER
|
|
%token _T_DEAD
|
|
%token _T_DERRICK
|
|
%token _T_DO
|
|
%token _T_DROP
|
|
%token _T_FINE
|
|
%token _T_FOR
|
|
%token _T_FORCE
|
|
%token _T_GET
|
|
%token _T_GETTING
|
|
%token _T_GO
|
|
%token _T_GOING
|
|
%token _T_GONNA
|
|
%token _T_GOT
|
|
%token _T_GREAT
|
|
%token _T_HAVE
|
|
%token _T_HAS
|
|
%token _T_HELP
|
|
%token _T_HOLD
|
|
%token _T_I
|
|
%token _T_IM
|
|
%token _T_IS
|
|
%token _T_LASSAT
|
|
%token _T_LETS
|
|
%token _T_ME
|
|
%token _T_MORE
|
|
%token _T_NEED
|
|
%token _T_NO
|
|
%token _T_NOW
|
|
%token _T_OFCOURSE
|
|
%token _T_OK
|
|
%token _T_ON
|
|
%token _T_PLACE
|
|
%token _T_POSSESSION
|
|
%token _T_POWER
|
|
%token _T_PUMPING
|
|
%token _T_PUT
|
|
%token _T_READY
|
|
%token _T_REQUIRE
|
|
%token _T_ROGER
|
|
%token _T_RUSH
|
|
%token _T_SEC
|
|
%token _T_SEE
|
|
%token _T_SOME
|
|
%token _T_STATUS
|
|
%token _T_STOP
|
|
%token _T_SURE
|
|
%token _T_THANK_YOU
|
|
%token _T_THANKS
|
|
%token _T_THE
|
|
%token _T_U
|
|
%token _T_UNITS
|
|
%token _T_VTOLS
|
|
%token _T_WAIT
|
|
%token _T_WHERE
|
|
%token _T_YES
|
|
%token _T_YOU
|
|
%token _T_EOF 0
|
|
|
|
/* Typed Keywords */
|
|
%token <ival> R_PLAYER
|
|
%token <ival> R_INTEGER
|
|
|
|
/* Rules */
|
|
%type <ival> R_PLAYER_POSSESSION
|
|
|
|
%%
|
|
|
|
/* The top-level rule, consists of
|
|
* one or more sentences: commands or addressed commands
|
|
* or unrecognized messages (handled in R_COMMAND)
|
|
*/
|
|
R_PHRASE: R_ADDRESSED_COMMAND
|
|
| R_COMMAND
|
|
{
|
|
chat_store_player(chat_msg.numCommands - 1, -1); /* No player list means current command is addressed to everyone */
|
|
}
|
|
| R_PHRASE R_ADDRESSED_COMMAND
|
|
| R_PHRASE R_COMMAND
|
|
{
|
|
chat_store_player(chat_msg.numCommands - 1, -1);
|
|
}
|
|
| error
|
|
{
|
|
//console("-unrecognized phrase");
|
|
|
|
/* Reset current command */
|
|
chat_reset_command(chat_msg.numCommands);
|
|
}
|
|
;
|
|
|
|
/* A command addressed to one or more players
|
|
*/
|
|
R_ADDRESSED_COMMAND: R_PLAYER_LIST _T_COLON R_COMMAND /* "Red, Black: attack yellow" */
|
|
//{console("RULE: player list: command");}
|
|
| R_PLAYER_LIST _T_SEMICOLON R_COMMAND /* "Red, Black; attack yellow" */
|
|
//{console("RULE: player list; command");}
|
|
| R_PLAYER_LIST _T_COMMA R_COMMAND /* "Red, Black, attack yellow" */
|
|
//{console("RULE: player list, command");}
|
|
| R_PLAYER_LIST R_COMMAND /* No delimeter: "Red, Black attack yellow" */
|
|
//{console("RULE: player list command");}
|
|
;
|
|
|
|
|
|
/* Any of the recognizable commands -
|
|
* since there can't be any player list at this stage,
|
|
* should address all players receiving this message by default:
|
|
* EXAMPLE:
|
|
* 1) "Help me!" - addresses all players receiving the message
|
|
* 2) "Black and Red, help me!" - addresses players 'Black' and 'red' only
|
|
*/
|
|
R_COMMAND: R_ALLY_OFFER /* ally me */
|
|
{
|
|
chat_store_command("ally me"); /* Store current command */
|
|
}
|
|
| R_ASK_READINESS /* go? */
|
|
{
|
|
chat_store_command("go?");
|
|
}
|
|
| R_INITIATE_ACTION /* go ! */
|
|
{
|
|
chat_store_command("go!");
|
|
}
|
|
| R_DEMAND_BEACON /* drop a beacon */
|
|
{
|
|
chat_store_command("drop a beacon");
|
|
}
|
|
| R_MEET_CENTER /* go center */
|
|
{
|
|
chat_store_command("go center");
|
|
}
|
|
| R_ASK_STATUS /* status? */
|
|
{
|
|
chat_store_command("status?");
|
|
}
|
|
| R_BUILDING_UNITS /* pumping units */
|
|
{
|
|
chat_store_command("pumping units");
|
|
}
|
|
| R_STOP /* stop! */
|
|
{
|
|
chat_store_command("stop");
|
|
}
|
|
| R_WONDER_IF_HAVE_POWER /* Ask if player has power */
|
|
{
|
|
chat_store_command("got power?");
|
|
}
|
|
| R_DEMAND_HELP /* help me! */
|
|
{
|
|
chat_store_command("help me");
|
|
}
|
|
| R_REPORT_SAFETY /* i'm ok */
|
|
{
|
|
chat_store_command("i'm ok");
|
|
}
|
|
| R_AFFIRMATIVE /* roger! */
|
|
{
|
|
chat_store_command("roger");
|
|
}
|
|
| R_ALLY_PLAYER /* ally blue */
|
|
{
|
|
chat_store_command("ally player");
|
|
}
|
|
| R_ATTACK_PLAYER /* attack blue */
|
|
{
|
|
chat_store_command("attack player");
|
|
}
|
|
| R_ATTACKING_PLAYER /* attacking blue */
|
|
{
|
|
chat_store_command("attacking player?");
|
|
}
|
|
| R_PLAYER_HAS_VTOLS /* blue has VTOLS */
|
|
{
|
|
chat_store_command("player has vtols");
|
|
}
|
|
| R_GETTING_ENEMY_DERRICK /* gonna get blue's derrick */
|
|
{
|
|
chat_store_command("getting player oil");
|
|
}
|
|
| R_LASSAT_PLAYER /* lassat red */
|
|
{
|
|
chat_store_command("lassat player");
|
|
}
|
|
| R_WAIT_FOR_ME /* wait for me */
|
|
{
|
|
chat_store_command("wait for me");
|
|
}
|
|
| R_RUSH_INITIATION /* rush? */
|
|
{
|
|
chat_store_command("rush");
|
|
}
|
|
;
|
|
|
|
/* A reference to certain players: "yellow, help me"
|
|
*/
|
|
R_PLAYER_LIST: R_PLAYER
|
|
{
|
|
chat_store_player(chat_msg.numCommands, $1); /* Remember this player was addressed in current command */
|
|
}
|
|
| R_PLAYER_LIST R_PLAYER /* without any delimeters: "yellow black red" */
|
|
{
|
|
chat_store_player(chat_msg.numCommands, $2);
|
|
}
|
|
| R_PLAYER_LIST _T_COMMA R_PLAYER /* "yellow, black, red" */
|
|
{
|
|
chat_store_player(chat_msg.numCommands, $3);
|
|
}
|
|
| R_PLAYER_LIST _T_AND R_PLAYER /* "yellow, black and red" */
|
|
{
|
|
chat_store_player(chat_msg.numCommands, $3);
|
|
}
|
|
;
|
|
|
|
R_PLAYER_POSSESSION: R_PLAYER R_POSSESSION /* blue's */
|
|
{
|
|
$$ = $1; // just pass player index
|
|
}
|
|
;
|
|
|
|
/* A Article or nothing
|
|
*/
|
|
R_A_OR_EMPTY: /* Empty */
|
|
| _T_A
|
|
| _T_AN
|
|
| _T_THE
|
|
;
|
|
|
|
/* Punctuation mark */
|
|
R_PUNCTUATION_MARK: _T_QM
|
|
| _T_EM
|
|
| R_PUNCTUATION_MARK _T_QM /* ?????!!!!??! */
|
|
| R_PUNCTUATION_MARK _T_EM /* ?????!!!!??! */
|
|
;
|
|
|
|
/* Full stop or end of file
|
|
* (a 'virtual' rule)
|
|
*/
|
|
R_FULLSTOP_OR_EOF: /* Empty */ /* Needed for other rules */
|
|
| _T_EOF /* End of input */
|
|
| _T_FULLSTOP /* . */
|
|
;
|
|
|
|
/* End of a declarative sentence
|
|
* can't be a question
|
|
*/
|
|
R_EOD: _T_EM /* !!!! */
|
|
| R_FULLSTOP_OR_EOF
|
|
;
|
|
|
|
/* End of a question
|
|
* can't end with an exclamation mark
|
|
*/
|
|
R_EOQ: _T_QM
|
|
| R_FULLSTOP_OR_EOF
|
|
;
|
|
|
|
/* (any possible) end of the sentence - similar
|
|
* to "End of a declarative sentence",
|
|
* but can additionally end with a question.
|
|
*/
|
|
R_EOS: R_EOD /* End of a declarative sentence */
|
|
| R_PUNCTUATION_MARK /* ???!!?!?!?!? */
|
|
;
|
|
|
|
/* Express attack intention */
|
|
R_ATTACKING: _T_ATTACKING
|
|
| _T_GOING
|
|
| _T_GOING _T_AFTER
|
|
;
|
|
|
|
/* Attack */
|
|
R_INITIATE_ATTACK: _T_ATTACK
|
|
| _T_GET
|
|
;
|
|
|
|
R_PUT_DOWN: _T_PUT | _T_DROP | _T_PLACE; /* put */
|
|
|
|
R_CONSTRUCTING: _T_PUMPING /* pumping/getting */
|
|
| _T_GETTING
|
|
| _T_BUILDING
|
|
;
|
|
|
|
R_YOU: _T_YOU
|
|
| _T_U /* u */
|
|
;
|
|
|
|
/* 'You' - pronoun for questions */
|
|
R_DO_YOU: R_YOU /* like in "you got any..." */
|
|
| _T_DO R_YOU /* do you */
|
|
;
|
|
|
|
/* Used in questions */
|
|
R_POSSESSION_Q: _T_HAVE
|
|
| _T_GOT
|
|
;
|
|
|
|
R_POSSESSES: _T_HAS
|
|
| _T_GOT
|
|
;
|
|
|
|
|
|
R_QUANTITY: _T_ANY
|
|
| _T_SOME
|
|
;
|
|
|
|
R_DO_YOU_HAVE_ANY: R_DO_YOU R_POSSESSION_Q R_QUANTITY
|
|
| R_DO_YOU R_POSSESSION_Q
|
|
| R_POSSESSION_Q R_QUANTITY /* got any.. */
|
|
| R_POSSESSION_Q /* got <substantive>? */
|
|
| R_QUANTITY /* any <substantive>? */
|
|
;
|
|
|
|
R_CONFIDENCE_EXPRESSION: _T_SURE
|
|
| _T_OFCOURSE
|
|
;
|
|
|
|
R_AGREEMENT_EXPRESSION: _T_YES
|
|
| _T_FINE
|
|
| _T_OK
|
|
;
|
|
|
|
R_AFFIRMATIVE_FORMS: R_AGREEMENT_EXPRESSION
|
|
| R_CONFIDENCE_EXPRESSION
|
|
| _T_ROGER /* roger */
|
|
| _T_AFFIRMATIVE
|
|
;
|
|
|
|
/* Need */
|
|
R_NEED: _T_NEED
|
|
| _T_REQUIRE
|
|
;
|
|
|
|
R_RUSH_INITIATION: _T_RUSH R_EOS /* rush? */
|
|
| _T_LETS _T_RUSH R_EOS /* let's rush */
|
|
;
|
|
|
|
|
|
/*******************************************/
|
|
/* FINAL RULES, SHOULD BE PART OF R_PHRASE */
|
|
/*******************************************/
|
|
|
|
/* Ask a player to ally myself */
|
|
R_ALLY_OFFER: _T_ALLY _T_ME R_EOS /* ally me */
|
|
| _T_ALLY R_EOS /* "ally" at the end (otherwise breaks "ally me") */
|
|
/* | _T_ALLY */
|
|
;
|
|
|
|
/* Chech if player is willing
|
|
* to initiate some actions
|
|
*/
|
|
R_ASK_READINESS: _T_GO _T_QM /* go? */
|
|
| _T_READY R_EOS /* "ready!" or "ready?" */
|
|
| _T_IM _T_READY R_EOS /* I'm ready! */
|
|
;
|
|
|
|
/* Tell to start some action */
|
|
R_INITIATE_ACTION: _T_GO R_EOD; /* go!! */
|
|
|
|
/* Tell to drop a beacon */
|
|
R_DEMAND_BEACON: R_PUT_DOWN R_A_OR_EMPTY _T_BEACON; /* put a beacon */
|
|
|
|
/* Tell to meet in the center of the map */
|
|
R_MEET_CENTER: _T_GO _T_CENTER R_EOS; /* go center */
|
|
|
|
/* Ask for the current status */
|
|
R_ASK_STATUS: _T_STATUS R_EOS; /* status? */
|
|
|
|
/* Units */
|
|
R_UNIT_ARMY: R_A_OR_EMPTY _T_FORCE
|
|
| R_A_OR_EMPTY _T_ARMY
|
|
;
|
|
|
|
/* Player is building units */
|
|
R_BUILDING_UNITS: R_CONSTRUCTING _T_UNITS R_EOD /* pumping units */
|
|
| R_CONSTRUCTING _T_MORE _T_UNITS R_EOD /* pumping more units */
|
|
| R_CONSTRUCTING R_UNIT_ARMY R_EOD /* building army */
|
|
;
|
|
|
|
/* Stop command */
|
|
R_STOP: _T_STOP R_EOD; /* stop */
|
|
|
|
/* Ask if player has power */
|
|
R_WONDER_IF_HAVE_POWER: R_DO_YOU_HAVE_ANY _T_POWER R_EOQ; /* do you have power? */
|
|
|
|
/* Ask for help */
|
|
R_DEMAND_HELP: _T_HELP _T_ME R_EOS /* help me!!!!! */
|
|
| _T_HELP R_EOS /* help!?!? */
|
|
| _T_I R_DEMAND_HELP /* I need help */
|
|
| R_NEED _T_HELP R_EOS /* need help */
|
|
| R_NEED R_QUANTITY _T_HELP R_EOS /* need some help */
|
|
;
|
|
|
|
R_GRATITUDE: _T_THANK_YOU
|
|
| _T_THANKS
|
|
;
|
|
|
|
/* Tell player i'm safe - no danger anymore */
|
|
R_REPORT_SAFETY: _T_IM _T_OK R_EOD /* i'm ok */
|
|
| _T_IM _T_FINE R_EOD
|
|
| R_REPORT_SAFETY _T_NOW R_EOD
|
|
| R_REPORT_SAFETY R_GRATITUDE R_EOD
|
|
| R_REPORT_SAFETY _T_COMMA R_GRATITUDE R_EOD
|
|
| R_GRATITUDE R_REPORT_SAFETY R_EOD
|
|
| R_GRATITUDE _T_COMMA R_REPORT_SAFETY R_EOD
|
|
| R_GRATITUDE R_GRATITUDE R_EOD
|
|
;
|
|
|
|
|
|
/* Positive order feedback */
|
|
R_AFFIRMATIVE: R_AFFIRMATIVE_FORMS R_EOD /* yes, roger etc */
|
|
| R_AFFIRMATIVE R_AFFIRMATIVE_FORMS R_EOD /* accept repetitions: "yes yes yeah" */
|
|
// | R_AFFIRMATIVE /* can also be emotional: "yea!!! yeah! yes!!!!" */
|
|
;
|
|
|
|
/* Ask to ally a player */
|
|
R_ALLY_PLAYER: _T_ALLY R_PLAYER R_EOD /* ally blue */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $2;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
/* Ask to start attack a player */
|
|
R_ATTACK_PLAYER: R_INITIATE_ATTACK R_PLAYER R_EOD /* attack blue */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $2;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
| _T_GO R_PLAYER R_EOD /* go blue */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $2;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
/* Notify i'm attacking player */
|
|
R_ATTACKING_PLAYER: R_ATTACKING R_PLAYER R_EOD /* attacking blue */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $2;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
/* Notify about player using VTOLs */
|
|
R_PLAYER_HAS_VTOLS: R_PLAYER R_POSSESSES _T_VTOLS R_EOD /* blue has VTOLS */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $1;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
R_GETTING_ENEMY_DERRICK: _T_GONNA R_INITIATE_ATTACK R_PLAYER_POSSESSION _T_DERRICK R_EOD /* gonna get blue's derrick */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $3;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
R_LASSAT_PLAYER: _T_LASSAT R_PLAYER R_EOD /* gonna get blue's derrick */
|
|
{
|
|
/* Store for scripts */
|
|
scrParameter.type = VAL_INT;
|
|
scrParameter.v.ival = $2;
|
|
if(!chat_store_parameter(&scrParameter))
|
|
{
|
|
yyerror("chat command: Too many parameters in the message");
|
|
}
|
|
}
|
|
;
|
|
|
|
R_WAIT_FOR_ME: _T_WAIT R_EOD /* wait */
|
|
| _T_SEC R_EOD /* sec... */
|
|
| _T_WAIT _T_FOR _T_ME R_EOD /* wait for me */
|
|
| _T_HOLD _T_ON R_EOD /* hold on */
|
|
;
|
|
%%
|
|
|
|
/* Initialize Bison and start chat processing */
|
|
BOOL chatLoad(char *pData, UDWORD size)
|
|
{
|
|
SDWORD cmdIndex,parseResult;
|
|
|
|
/* Don't parse the same message again for a different player */
|
|
if(strcmp(pData, &(chat_msg.lastMessage[0])) == 0) //just parsed this message for some other player
|
|
{
|
|
return true; //keep all the parsed data unmodified
|
|
}
|
|
|
|
/* Tell bison what to parse */
|
|
chatSetInputBuffer(pData, size);
|
|
|
|
/* Reset previous chat processing */
|
|
chat_msg.numCommands = 0;
|
|
|
|
/* Initialize command data */
|
|
for(cmdIndex=0; cmdIndex<MAX_CHAT_COMMANDS; cmdIndex++)
|
|
{
|
|
chat_reset_command(cmdIndex);
|
|
}
|
|
|
|
/* Invoke bison and parse */
|
|
parseResult = chat_parse();
|
|
|
|
/* Remember last message we parsed */
|
|
sstrcpy(chat_msg.lastMessage, pData);
|
|
|
|
/* See if we were successful parsing */
|
|
if (parseResult != 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* A simple error reporting routine */
|
|
static void yyerror(const char* msg)
|
|
{
|
|
int line;
|
|
char *pText;
|
|
|
|
chatGetErrorData(&line, &pText);
|
|
//debug(LOG_WARNING, "multiplayer message parse error: %s at line %d, token: %d, text: '%s'",
|
|
// msg, line, chat_char, pText);
|
|
}
|