Scripting engine update:

-added new scripting function
-added new callbacks
-added new member variables
-players controlled by AI now receive (and send) multiplayer messages and can process them

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@595 4a71c877-e1ca-e34f-864e-861f7616d084
master
Roman C 2006-08-20 14:48:14 +00:00
parent 8f8c461df4
commit e4883dabb9
15 changed files with 1272 additions and 43 deletions

View File

@ -98,7 +98,7 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize)
// internal type - just store the DWORD value
if (pBuffer != NULL)
{
*((UDWORD *)pPos) = (UDWORD)psVal->v.ival;
*((UDWORD *)pPos) = (UDWORD)psVal->v.ival; //TODO: make it save strings properly
pPos += sizeof(UDWORD);
}

View File

@ -224,7 +224,7 @@ typedef struct _script_code
INTERP_TYPE *pGlobals; // Types of the global variables
INTERP_TYPE **ppsLocalVars; //storage for local vars
INTERP_TYPE **ppsLocalVars; //storage for local vars (type)
UDWORD *numLocalVars; //number of local vars each event has
INTERP_VAL **ppsLocalVarVal; //Values of the local vars used during interpreting process
UDWORD *numParams; //number of arguments this event has

View File

@ -49,7 +49,7 @@ void scriptShutDown(void)
/* Free a SCRIPT_CODE structure */
void scriptFreeCode(SCRIPT_CODE *psCode)
{
UDWORD i;
UDWORD i,j;
FREE(psCode->pCode);
if (psCode->pTriggerTab)
@ -107,19 +107,31 @@ void scriptFreeCode(SCRIPT_CODE *psCode)
/* Free local vars */
for(i=0; i < psCode->numEvents; i++)
{
FREE(psCode->ppsLocalVars[i]);
FREE(psCode->ppsLocalVarVal[i]);
if(psCode->numLocalVars[i] > 0) //only free if any defined
{
//free strings for event i
for(j=0; j < psCode->numLocalVars[i]; j++)
{
if(psCode->ppsLocalVarVal[i][j].type == VAL_STRING); //if a string
{
if(psCode->ppsLocalVarVal[i][j].v.sval != NULL) //doublecheck..
FREE(psCode->ppsLocalVarVal[i][j].v.sval); //free string
}
}
psCode->numParams = 0;
psCode->numLocalVars = 0;
FREE(psCode->numParams);
FREE(psCode->numLocalVars);
FREE(psCode->ppsLocalVars[i]);
FREE(psCode->ppsLocalVarVal[i]); //free pointer to event i local vars
}
}
FREE(psCode->numParams);
FREE(psCode->numLocalVars);
FREE(psCode->ppsLocalVars);
FREE(psCode->ppsLocalVarVal);
psCode->numEvents = 0;
FREE(psCode);
}

View File

@ -34,6 +34,10 @@
#include "lib/gamelib/gtime.h"
#include "keybind.h"
#include "lib/script/script.h" //Because of "ScriptTabs.h"
#include "scriptTabs.h" //because of CALL_AI_MSG
#include "scriptcb.h" //for console callback
#include "lib/netplay/netplay.h" // the netplay library.
#include "multiplay.h" // warzone net stuff.
#include "multijoin.h" // player management stuff.
@ -59,6 +63,24 @@ MULTIPLAYERINGAME ingame;
BOOL bSendingMap = FALSE; // map broadcasting.
STRING tempString[12];
/////////////////////////////////////
/* multiplayer message stack stuff */
/////////////////////////////////////
#define MAX_MSG_STACK 100
#define MAX_STR 255
char msgStr[MAX_MSG_STACK][MAX_STR];
SDWORD msgPlFrom[MAX_MSG_STACK];
SDWORD msgPlTo[MAX_MSG_STACK];
SDWORD callbackType[MAX_MSG_STACK];
SDWORD locx[MAX_MSG_STACK];
SDWORD locy[MAX_MSG_STACK];
SDWORD msgStackPos = -1; //top element pointer
// ////////////////////////////////////////////////////////////////////////////
// Remote Prototypes
extern BOOL MultiPlayValidTemplate(DROID_TEMPLATE *psTempl); // for templates.
@ -90,6 +112,11 @@ BOOL recvMessage (VOID); // process an incoming message
BOOL SendResearch (UBYTE player,UDWORD index); // send/recv Research issues
BOOL recvResearch (NETMSG *pMsg);
BOOL sendTextMessage (char *pStr,BOOL bcast); // send/recv a text message
BOOL sendAIMessage (char *pStr, SDWORD player, SDWORD to); //send AI message
void displayAIMessage (STRING *pStr, SDWORD from, SDWORD to);
BOOL recvTextMessageAI (NETMSG *pMsg); //AI multiplayer message
BOOL recvTextMessage (NETMSG *pMsg);
BOOL sendTemplate (DROID_TEMPLATE *t); // send/recv Template information
BOOL recvTemplate (NETMSG *pMsg);
@ -674,6 +701,15 @@ BOOL recvMessage(VOID)
case NET_TEXTMSG: // simple text message
recvTextMessage(&msg);
break;
case NET_AITEXTMSG: //multiplayer AI text message
recvTextMessageAI(&msg);
break;
//case NET_BEACONMSG: //beacon (blip) message
// recvBeacon(&msg);
// break;
case NET_BUILD: // a build order has been sent.
recvBuildStarted(&msg);
break;
@ -1099,9 +1135,16 @@ BOOL sendTextMessage(char *pStr,BOOL all)
{
for(i=0;i<MAX_PLAYERS;i++)
{
if(openchannels[i] && isHumanPlayer(i) && (i != selectedPlayer)) //now doesn't send multiplayer msgs to himself (displayed locally in kf_SendTextMessage() )
if(openchannels[i])
{
NETsend(&m,player2dpid[i],FALSE);
if(isHumanPlayer(i) )
{
NETsend(&m,player2dpid[i],FALSE);
}
else //also send to AIs now (non-humans), needed for AI
{
sendAIMessage(&(m.body[4]), selectedPlayer, i);
}
}
}
}
@ -1109,9 +1152,16 @@ BOOL sendTextMessage(char *pStr,BOOL all)
{
for(i=0;i<MAX_PLAYERS;i++)
{
if(sendto[i] && isHumanPlayer(i) && (i != selectedPlayer))
if(sendto[i])
{
NETsend(&m,player2dpid[i],FALSE);
if(isHumanPlayer(i))
{
NETsend(&m,player2dpid[i],FALSE);
}
else //also send to AIs now (non-humans), needed for AI
{
sendAIMessage(&(m.body[4]), selectedPlayer, i);
}
}
}
}
@ -1127,20 +1177,127 @@ BOOL sendTextMessage(char *pStr,BOOL all)
return TRUE;
}
//AI multiplayer message, send from a certain player index to another player index
BOOL sendAIMessage(char *pStr, SDWORD player, SDWORD to)
{
NETMSG m;
SDWORD sendPlayer;
BOOL bEncrypting;
//check if this is one of the local players, don't need net send then
if(to == selectedPlayer || myResponsibility(to)) //(the only) human on this machine or AI on this machine
{
//Just show him the message
displayAIMessage(pStr, player, to);
//Received a console message from a player callback
//store and call later
//-------------------------------------------------
if(!msgStackPush(CALL_AI_MSG,player,to,pStr,-1,-1))
{
debug(LOG_ERROR, "sendAIMessage() - msgStackPush - stack failed");
return FALSE;
}
}
else //not a local player (use multiplayer mode)
{
if(!ingame.localOptionsReceived)
{
return TRUE;
}
bEncrypting = NetPlay.bEncryptAllPackets;
NetPlay.bEncryptAllPackets = FALSE;
NetAdd(m,0,player); //save the actual sender
//save the actual player that is to get this msg on the source machine (source can host many AIs)
NetAdd(m,4,to); //save the actual receiver (might not be the same as the one we are actually sending to, in case of AIs)
memcpy(&(m.body[8]),&(pStr[0]), strlen( &(pStr[0]) )+1); // copy message in.
m.size = (UWORD)( strlen( &(pStr[0]) )+9); // package the message up and send it.
m.type = NET_AITEXTMSG; //new type
//find machine that is hosting this human or AI
sendPlayer = whosResponsible(to);
if(sendPlayer >= MAX_PLAYERS)
{
debug(LOG_ERROR, "sendAIMessage() - sendPlayer >= MAX_PLAYERS");
return FALSE;
}
if(!isHumanPlayer(sendPlayer)) //NETsend can't send to non-humans
{
debug(LOG_ERROR, "sendAIMessage() - player is not human.");
return FALSE;
}
NETsend(&m,player2dpid[sendPlayer],FALSE); //send to the player who is hosting 'to' player (might be himself if human and not AI)
NetPlay.bEncryptAllPackets = bEncrypting;
}
return TRUE;
}
void displayAIMessage(STRING *pStr, SDWORD from, SDWORD to)
{
STRING tmp[255];
if(isHumanPlayer(to)) //display text only if receiver is the (human) host machine itself
{
//addConsoleMessage(pStr,DEFAULT_JUSTIFY);
//console("%d: %s", from, pStr);
sprintf(tmp,"%d",from);
strcat(tmp," : "); // seperator
strcat(tmp,pStr); // add message
addConsoleMessage(tmp,DEFAULT_JUSTIFY);
}
}
// Write a message to the console.
BOOL recvTextMessage(NETMSG *pMsg)
{
DPID dpid;
UDWORD i;
STRING msg[MAX_CONSOLE_STRING_LENGTH];
UDWORD player,j; //console callback - player who sent the message
NetGet(pMsg,0,dpid);
for(i = 0; NetPlay.players[i].dpid != dpid; i++); //findplayer
//console callback - find real number of the player
for(j = 0; i<MAX_PLAYERS;j++)
{
if(dpid == player2dpid[j])
{
player = j;
break;
}
}
/*
strcpy(msg,NetPlay.players[i].name); // name
strcat(msg," : "); // seperator
strncat(msg, &(pMsg->body[4]), MAX_CONSOLE_STRING_LENGTH); // add message
addConsoleMessage((char *)&msg,DEFAULT_JUSTIFY);// display it.
*/
sprintf(msg, "%d", i);
strcat(msg," : "); // seperator
strcat(msg, &(pMsg->body[4])); // add message
addConsoleMessage((char *)&msg,DEFAULT_JUSTIFY);
//multiplayer message callback
//Received a console message from a player, save
//----------------------------------------------
MultiMsgPlayerFrom = player;
MultiMsgPlayerTo = selectedPlayer;
strcpy(MultiplayMsg,&(pMsg->body[4]));
eventFireCallbackTrigger(CALL_AI_MSG);
// make some noise!
if(titleMode == MULTIOPTION || titleMode == MULTILIMIT)
@ -1155,6 +1312,34 @@ BOOL recvTextMessage(NETMSG *pMsg)
return TRUE;
}
//AI multiplayer message - received message from AI (from scripts)
BOOL recvTextMessageAI(NETMSG *pMsg)
{
SDWORD sender, receiver;
STRING msg[MAX_CONSOLE_STRING_LENGTH];
NetGet(pMsg,0,sender);
NetGet(pMsg,4,receiver);
strcpy(msg, &(pMsg->body[8]));
strcat(msg,NetPlay.players[sender].name); // name
//Display the message and make the script callback
displayAIMessage(msg, sender, receiver);
//Received a console message from a player callback
//store and call later
//-------------------------------------------------
if(!msgStackPush(CALL_AI_MSG,sender,receiver,msg,-1,-1))
{
debug(LOG_ERROR, "recvTextMessageAI() - msgStackPush - stack failed");
return FALSE;
}
return TRUE;
}
// ////////////////////////////////////////////////////////////////////////////
// Templates
@ -1518,3 +1703,222 @@ BOOL recvMapFileData(NETMSG *pMsg)
return TRUE;
}
//------------------------------------------------------------------------------------------------//
/* multiplayer message stack */
void msgStackReset(void)
{
msgStackPos = -1; //Beginning of the stack
}
UDWORD msgStackPush(SDWORD CBtype, SDWORD plFrom, SDWORD plTo, STRING *tStr, SDWORD x, SDWORD y)
{
if (msgStackPos >= MAX_MSG_STACK)
{
debug(LOG_ERROR, "msgStackPush() - stack full");
return FALSE;
}
//make point to the last valid element
msgStackPos++;
//remember values
msgPlFrom[msgStackPos] = plFrom;
msgPlTo[msgStackPos] = plTo;
callbackType[msgStackPos] = CBtype;
locx[msgStackPos] = x;
locy[msgStackPos] = y;
strcpy(msgStr[msgStackPos], tStr);
return TRUE;
}
BOOL isMsgStackEmpty()
{
if(msgStackPos == (-1)) return TRUE;
return FALSE;
}
BOOL msgStackGetFrom(SDWORD *psVal)
{
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackGetFrom: msgStackPos < 0");
return FALSE;
}
*psVal = msgPlFrom[0];
return TRUE;
}
BOOL msgStackGetTo(SDWORD *psVal)
{
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackGetTo: msgStackPos < 0");
return FALSE;
}
*psVal = msgPlTo[0];
return TRUE;
}
BOOL msgStackGetCallbackType(SDWORD *psVal)
{
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackGetCallbackType: msgStackPos < 0");
return FALSE;
}
*psVal = callbackType[0];
return TRUE;
}
BOOL msgStackGetXY(SDWORD *psValx, SDWORD *psValy)
{
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackGetXY: msgStackPos < 0");
return FALSE;
}
*psValx = locx[0];
*psValy = locy[0];
return TRUE;
}
BOOL msgStackGetMsg(STRING *psVal)
{
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackGetMsg: msgStackPos < 0");
return FALSE;
}
strcpy(psVal, msgStr[0]);
//*psVal = msgPlTo[msgStackPos];
return TRUE;
}
BOOL msgStackSort()
{
SDWORD i;
//go through all-1 elements (bottom-top)
for(i=0;i<msgStackPos;i++)
{
msgPlFrom[i] = msgPlFrom[i+1];
msgPlTo[i] = msgPlTo[i+1];
callbackType[i] = callbackType[i+1];
locx[i] = locx[i+1];
locy[i] = locy[i+1];
strcpy(msgStr[i], msgStr[i+1]);
}
//erase top element
msgPlFrom[msgStackPos] = -2;
msgPlTo[msgStackPos] = -2;
callbackType[msgStackPos] = -2;
locx[msgStackPos] = -2;
locy[msgStackPos] = -2;
strcpy(msgStr[msgStackPos], "ERROR STRING!!!!!!!!");
msgStackPos--; //since removed the top element
return TRUE;
}
BOOL msgStackPop()
{
if(msgStackPos < 0 || msgStackPos >= MAX_MSG_STACK)
{
debug(LOG_ERROR, "msgStackPop: wrong msgStackPos index");
return FALSE;
}
return msgStackSort(); //move allelements 1 pos lower
}
SDWORD msgStackGetCount()
{
return msgStackPos + 1;
}
BOOL msgStackFireTop()
{
SDWORD _callbackType;
STRING msg[255];
if(msgStackPos < 0)
{
debug(LOG_ERROR, "msgStackFireTop: msgStackPos < 0");
return FALSE;
}
if(!msgStackGetCallbackType(&_callbackType))
return FALSE;
switch(_callbackType)
{
/*
case CALL_BEACON:
if(!msgStackGetXY(&beaconX, &beaconY))
return FALSE;
if(!msgStackGetFrom(&MultiMsgPlayerFrom))
return FALSE;
if(!msgStackGetTo(&MultiMsgPlayerTo))
return FALSE;
if(!msgStackGetMsg(msg))
return FALSE;
strcpy(MultiplayMsg, msg);
eventFireCallbackTrigger(CALL_BEACON);
break;
*/
case CALL_AI_MSG:
if(!msgStackGetFrom(&MultiMsgPlayerFrom))
return FALSE;
if(!msgStackGetTo(&MultiMsgPlayerTo))
return FALSE;
if(!msgStackGetMsg(msg))
return FALSE;
strcpy(MultiplayMsg, msg);
eventFireCallbackTrigger(CALL_AI_MSG);
break;
default:
debug(LOG_ERROR, "msgStackFireTop: unknown callback type");
return FALSE;
break;
}
if(!msgStackPop())
return FALSE;
return TRUE;
}

View File

@ -64,7 +64,11 @@ typedef enum _msgtype
NET_RESEARCHSTATUS, //44 105, research state.
NET_LASSAT, //45 107, lassat firing.
NET_REQUESTMAP //46 107 dont have map, please send it.
NET_REQUESTMAP, //46 107 dont have map, please send it.
NET_AITEXTMSG, //chat between AIs
NET_TEAMS_ON,
NET_BEACONMSG,
NET_SET_TEAMS
} MESSAGE_TYPES;
@ -234,6 +238,7 @@ extern BOOL SendDestroyTemplate (DROID_TEMPLATE *t);
extern BOOL SendResearch (UBYTE player,UDWORD index);
extern BOOL SendDestroyFeature (FEATURE *pF); // send a destruct feature message.
extern BOOL sendTextMessage (char *pStr,BOOL cast); // send a text message
extern BOOL sendAIMessage (char *pStr, SDWORD player, SDWORD to); //send AI message
extern BOOL turnOffMultiMsg (BOOL bDoit);
@ -302,3 +307,15 @@ extern UDWORD averagePing (VOID);
extern VOID modifyResources (POWER_GEN_FUNCTION* psFunction);
extern BOOL sendReseachStatus (STRUCTURE *psBuilding ,UDWORD index, UBYTE player, BOOL bStart);
extern void displayAIMessage (STRING *pStr, SDWORD from, SDWORD to); //make AI process a message
/* for multiplayer message stack */
extern UDWORD msgStackPush(SDWORD plFrom, SDWORD plTo, STRING *tStr);
extern BOOL isMsgStackEmpty();
extern BOOL msgStackGetFrom(SDWORD *psVal);
extern BOOL msgStackGetTo(SDWORD *psVal);
extern BOOL msgStackGetMsg(STRING *psVal);
extern BOOL msgStackPop();
extern SDWORD msgStackGetCount();

View File

@ -49,3 +49,8 @@ extern BOOL recvResearchStatus (NETMSG *pMsg);
extern BOOL recvLasSat (NETMSG *pMsg);
extern BOOL recvMapFileData (NETMSG *pMsg);
extern BOOL recvMapFileRequested (NETMSG *pMsg);
extern BOOL recvTextMessageAI (NETMSG *pMsg); //AI multiplayer message
//extern BOOL recvTeamsOn (NETMSG *pMsg);
//extern BOOL recvSetTeams (NETMSG *pMsg);

View File

@ -24,6 +24,7 @@
#include "research.h"
#include "gateway.h"
#include "multiplay.h"
#include "Action.h" //because of .action
#include "power.h"
#include "geometry.h"
@ -1979,6 +1980,113 @@ BOOL scrSkFireLassat(void)
return TRUE;
}
//-----------------------
// New functions
//-----------------------
BOOL scrActionDroidObj(void)
{
DROID *psDroid;
SDWORD action;
BASE_OBJECT *psObj;
if (!stackPopParams(3, ST_DROID, &psDroid, VAL_INT, &action, ST_BASEOBJECT, &psObj))
{
debug(LOG_ERROR, "scrActionDroidObj: failed to pop");
return FALSE;
}
ASSERT((PTRVALID(psDroid, sizeof(DROID)),
"scrOrderUnitObj: Invalid unit pointer"));
ASSERT((PTRVALID(psObj, sizeof(BASE_OBJECT)),
"scrOrderUnitObj: Invalid object pointer"));
if (psDroid == NULL || psObj == NULL)
{
return FALSE;
}
if (action != DACTION_DROIDREPAIR)
{
debug(LOG_ERROR, "scrActionDroidObj: this action is not supported");
return FALSE;
}
actionDroidObj(psDroid, action, psObj);
return TRUE;
}
//<script function - improved version
// variables for the group iterator
DROID_GROUP *psScrIterateGroupB[MAX_PLAYERS];
DROID *psScrIterateGroupDroidB[MAX_PLAYERS];
// initialise iterating a groups members
BOOL scrInitIterateGroupB(void)
{
DROID_GROUP *psGroup;
SDWORD bucket;
if (!stackPopParams(2, ST_GROUP, &psGroup, VAL_INT, &bucket))
{
debug(LOG_ERROR, "scrInitIterateGroupB: stackPopParams failed");
return FALSE;
}
ASSERT((PTRVALID(psGroup, sizeof(DROID_GROUP)),
"scrInitIterateGroupB: invalid group pointer"));
ASSERT((bucket < MAX_PLAYERS,
"scrInitIterateGroupB: invalid bucket"));
psScrIterateGroupB[bucket] = psGroup;
psScrIterateGroupDroidB[bucket] = psGroup->psList;
return TRUE;
}
//script function - improved version
// iterate through a groups members
BOOL scrIterateGroupB(void)
{
DROID_GROUP *psGroup;
DROID *psDroid;
SDWORD bucket;
if (!stackPopParams(2, ST_GROUP, &psGroup, VAL_INT, &bucket))
{
debug(LOG_ERROR, "scrIterateGroupB: stackPopParams failed");
return FALSE;
}
ASSERT((bucket < MAX_PLAYERS,
"scrIterateGroupB: invalid bucket"));
if (psGroup != psScrIterateGroupB[bucket])
{
ASSERT((FALSE, "scrIterateGroupB: invalid group, InitGroupIterateB not called?"));
return FALSE;
}
if (psScrIterateGroupDroidB[bucket] != NULL)
{
psDroid = psScrIterateGroupDroidB[bucket];
psScrIterateGroupDroidB[bucket] = psScrIterateGroupDroidB[bucket]->psGrpNext;
}
else
{
psDroid = NULL;
}
if (!stackPushResult(ST_DROID, (SDWORD)psDroid))
{
debug(LOG_ERROR, "scrIterateGroupB: stackPushResult failed");
return FALSE;
}
return TRUE;
}
// ********************************************************************************************
// Give a Droid a build order
/*BOOL scrSkOrderDroidLineBuild(void)

View File

@ -32,6 +32,16 @@ BASE_OBJECT *psScrCBAttacker, *psScrCBTarget;
// alliance details
UDWORD CBallFrom,CBallTo;
//console callback stuff
//---------------------------
#define MAXSTRLEN 255
SDWORD ConsolePlayer = -2;
SDWORD MultiMsgPlayerTo = -2;
SDWORD beaconX = -1, beaconY = -1;
SDWORD MultiMsgPlayerFrom = -2;
char ConsoleMsg[MAXSTRLEN]="ERROR!!!\0"; //Last console message
char MultiplayMsg[MAXSTRLEN]; //Last multiplayer message
BOOL scrCBDroidTaken(void)
{
DROID **ppsDroid;
@ -580,6 +590,59 @@ BOOL scrCBTransporterLanded( void )
return TRUE;
}
BOOL scrCBTransporterLandedB( void )
{
SDWORD player;
DROID_GROUP *psGroup;
DROID *psTransporter, *psDroid, *psNext;
BOOL retval;
DROID **ppsTransp;
if (!stackPopParams(3, ST_GROUP, &psGroup, VAL_INT, &player,
VAL_REF|ST_DROID, &ppsTransp))
{
debug(LOG_ERROR, "scrCBTransporterLandedB(): stack failed");
return FALSE;
}
psTransporter = transporterGetScriptCurrent();
if ( (psTransporter == NULL) ||
(psTransporter->player != (UDWORD)player) )
{
retval = FALSE;
}
else
{
*ppsTransp = psTransporter; //return landed transporter
/* if not selectedPlayer unload droids */
//if ( (UDWORD)player != selectedPlayer )
//{
/* transfer droids from transporter group to current group */
for(psDroid=psTransporter->psGroup->psList; psDroid; psDroid=psNext)
{
psNext = psDroid->psGrpNext;
if ( psDroid != psTransporter )
{
grpLeave( psTransporter->psGroup, psDroid );
grpJoin(psGroup, psDroid);
}
}
//}
retval = TRUE;
}
if (!stackPushResult(VAL_BOOL, retval))
{
debug(LOG_ERROR, "scrCBTransporterLandedB: push landed");
return FALSE;
}
return TRUE;
}
// tell the scripts when a cluster is no longer valid
SDWORD scrCBEmptyClusterID;
@ -708,3 +771,219 @@ BOOL scrCBAllianceOffer(void)
return TRUE;
}
//------------------------------------------------------------------------------------------------
/* New callbacks */
//console callback
//---------------------------
BOOL scrCallConsole(void)
{
SDWORD *player;
STRING **ConsoleText = NULL;
if (!stackPopParams(2, VAL_REF | VAL_INT, &player, VAL_REF | VAL_STRING, &ConsoleText) )
{
debug(LOG_ERROR, "scrCallConsole(): stack failed");
return FALSE;
}
if(*ConsoleText == NULL)
{
debug(LOG_ERROR, "scrCallConsole(): passed string was not initialized");
return FALSE;
}
strcpy(*ConsoleText,ConsoleMsg);
*player = ConsolePlayer;
if (!stackPushResult(VAL_BOOL, TRUE))
{
debug(LOG_ERROR, "scrCallConsole(): stackPushResult failed");
return FALSE;
}
return TRUE;
}
//multiplayer beacon
//---------------------------
/*
BOOL scrCallBeacon(void)
{
SDWORD *playerFrom, playerTo;
STRING **BeaconText = NULL;
SDWORD *locX,*locY;
if (!stackPopParams(5, VAL_INT, &playerTo, VAL_REF | VAL_INT, &playerFrom,
VAL_REF | VAL_INT, &locX, VAL_REF | VAL_INT, &locY,
VAL_REF | VAL_STRING, &BeaconText))
{
MessageBox(frameGetWinHandle(), "scrCallBeacon() failed to pop parameters.", "failed", MB_OK);
return FALSE;
}
//DbgMsg("x=%d,y=%d",locX >> TILE_SHIFT,locY >> TILE_SHIFT);
if(*BeaconText == NULL)
{
MessageBox(frameGetWinHandle(), "scrCallBeacon(): passed string was not initialized", "failed", MB_OK);
return FALSE;
}
//DbgMsg("scrCallMultiMsg");
//if(MultiMsgPlayerTo == playerTo)
if(MultiMsgPlayerTo >= 0 && MultiMsgPlayerFrom >= 0 && MultiMsgPlayerTo < MAX_PLAYERS && MultiMsgPlayerFrom < MAX_PLAYERS)
{
//DbgMsg("(%d - %d), %d", MultiMsgPlayerTo, playerTo, MultiMsgPlayerFrom);
if(MultiMsgPlayerTo == playerTo)
{
//DbgMsg("triggered!!!!!!!!!!!");
strcpy(*BeaconText,MultiplayMsg);
*playerFrom = MultiMsgPlayerFrom;
*locX = beaconX;
*locY = beaconY;
if (!stackPushResult(VAL_BOOL, TRUE)) //triggered
{
DbgMsg("scrCallBeacon - faled to push");
return FALSE;
}
return TRUE;
}
}
else
{
DbgMsg("scrCallBeacon() - player indexes failed: %d - %d", MultiMsgPlayerFrom, MultiMsgPlayerTo);
if (!stackPushResult(VAL_BOOL, FALSE)) //not triggered
{
return FALSE;
}
return TRUE;
}
//return "not triggered"
if (!stackPushResult(VAL_BOOL, FALSE))
{
return FALSE;
}
return TRUE;
}
*/
//multiplayer message callback
//----------------------------
BOOL scrCallMultiMsg(void)
{
SDWORD *player, playerTo;
STRING **ConsoleText = NULL;
if (!stackPopParams(3, VAL_INT, &playerTo, VAL_REF | VAL_INT, &player, VAL_REF | VAL_STRING, &ConsoleText) )
{
debug(LOG_ERROR, "scrCallMultiMsg() failed to pop parameters.");
return FALSE;
}
if(*ConsoleText == NULL)
{
debug(LOG_ERROR, "scrCallMultiMsg(): passed string was not initialized");
return FALSE;
}
if(MultiMsgPlayerTo >= 0 && MultiMsgPlayerFrom >= 0 && MultiMsgPlayerTo < MAX_PLAYERS && MultiMsgPlayerFrom < MAX_PLAYERS)
{
if(MultiMsgPlayerTo == playerTo)
{
strcpy(*ConsoleText,MultiplayMsg);
*player = MultiMsgPlayerFrom;
if (!stackPushResult(VAL_BOOL, TRUE)) //triggered
{
debug(LOG_ERROR, "scrCallMultiMsg(): stackPushResult failed");
return FALSE;
}
return TRUE;
}
}
else
{
debug(LOG_ERROR, "scrCallMultiMsg() - player indexes failed: %d - %d", MultiMsgPlayerFrom, MultiMsgPlayerTo);
if (!stackPushResult(VAL_BOOL, FALSE)) //not triggered
{
return FALSE;
}
return TRUE;
}
//return "not triggered"
if (!stackPushResult(VAL_BOOL, FALSE))
{
debug(LOG_ERROR, "scrCallMultiMsg: stackPushResult failed");
return FALSE;
}
return TRUE;
}
STRUCTURE *psScrCBNewStruct = NULL; //for scrCBStructBuilt callback
DROID *psScrCBNewStructTruck = NULL;
//structure built callback
//------------------------------
BOOL scrCBStructBuilt(void)
{
SDWORD player;
STRUCTURE **ppsStructure;
BOOL triggered = FALSE;
DROID **ppsDroid;
if (!stackPopParams(3, VAL_INT, &player, VAL_REF|ST_DROID, &ppsDroid, VAL_REF|ST_STRUCTURE, &ppsStructure) )
{
debug(LOG_ERROR, "scrCBStructBuilt() failed to pop parameters.");
return FALSE;
}
if (psScrCBNewStruct == NULL)
{
debug(LOG_ERROR, "scrCBStructBuilt: no structure has been set");
ASSERT((FALSE, "scrCBStructBuilt: no structure has been set"));
triggered = FALSE;
*ppsStructure = NULL;
*ppsDroid = NULL;
}
else if(psScrCBNewStructTruck == NULL)
{
debug(LOG_ERROR, "scrCBStructBuilt: no builder has been set");
ASSERT((FALSE, "scrCBStructBuilt: no builder has been set"));
triggered = FALSE;
*ppsStructure = NULL;
*ppsDroid = NULL;
}
else if (psScrCBNewStruct->player == (UDWORD)player)
{
triggered = TRUE;
*ppsStructure = psScrCBNewStruct; //pass to script
*ppsDroid = psScrCBNewStructTruck;
}
if (!stackPushResult(VAL_BOOL, triggered))
{
debug(LOG_ERROR, "scrCBStructBuilt: push failed");
return FALSE;
}
return TRUE;
}

View File

@ -7,6 +7,19 @@
#ifndef _scriptcb_h
#define _scriptcb_h
//console callback stuff
//---------------------------
#define MAXSTRLEN 255
extern SDWORD ConsolePlayer;
extern SDWORD MultiMsgPlayerTo;
extern SDWORD MultiMsgPlayerFrom;
extern SDWORD beaconX;
extern SDWORD beaconY;
extern char ConsoleMsg[MAXSTRLEN]; //Last console message
extern char MultiplayMsg[MAXSTRLEN]; //Last multiplayer message
extern STRUCTURE *psScrCBNewStruct; //for scrCBStructBuilt callback
extern DROID *psScrCBNewStructTruck; //for scrCBStructBuilt callback
// The pointer to the droid that was just built for a CALL_NEWDROID
extern DROID *psScrCBDroidTaken;
@ -98,6 +111,13 @@ extern BOOL scrCBPlayerLeft(void);
extern BOOL scrCBAllianceOffer(void);
extern UDWORD CBallFrom,CBallTo;
//Console callback
extern BOOL scrCallConsole(void);
extern BOOL scrCBStructBuilt(void);
extern BOOL scrCallMultiMsg(void);
//extern BOOL scrCallBeacon(void);
extern BOOL scrCBTransporterLandedB(void);
#endif

View File

@ -6343,6 +6343,137 @@ BOOL scrTutorialTemplates(void)
}
//-----------------------------------------
//New functions
//-----------------------------------------
//compare two strings (0 means they are different)
BOOL scrStrcmp(void)
{
STRING *ssval1=NULL;
STRING *ssval2=NULL;
if (!stackPopParams(2, VAL_STRING, &ssval1, VAL_STRING, &ssval2))
{
debug(LOG_ERROR, "scrStrcmp(): stack failed");
return FALSE;
}
if (!stackPushResult(VAL_BOOL, !strcmp(ssval1, ssval2)))
{
debug(LOG_ERROR, "scrStrcmp: failed to push result");
return FALSE;
}
return TRUE;
}
/* Output a string to console */
BOOL scrConsole(void)
{
STRING *ssval=NULL;
if (!stackPopParams(1, VAL_STRING, &ssval))
{
debug(LOG_ERROR, "scrConsole(): stack failed");
return FALSE;
}
addConsoleMessage(ssval,DEFAULT_JUSTIFY);
return TRUE;
}
BOOL scrDebug[MAX_PLAYERS];
//turn on debug messages
BOOL scrDbgMsgOn(void)
{
BOOL bOn;
SDWORD player;
if (!stackPopParams(2, VAL_INT, &player, VAL_BOOL, &bOn))
{
debug(LOG_ERROR, "scrDbgMsgOn(): stack failed");
return FALSE;
}
if (player < 0 || player >= MAX_PLAYERS)
{
debug(LOG_ERROR, "scrDbgMsgOn(): wrong player number");
return FALSE;
}
scrDebug[player] = bOn;
return TRUE;
}
BOOL scrMsg(void)
{
SDWORD playerTo,playerFrom;
STRING *ssval=NULL;
STRING tmp[255];
if (!stackPopParams(3, VAL_STRING, &ssval, VAL_INT, &playerFrom, VAL_INT, &playerTo))
{
debug(LOG_ERROR, "scrMsg(): stack failed");
return FALSE;
}
if(playerFrom < 0 || playerFrom >= MAX_PLAYERS)
{
debug(LOG_ERROR, "scrMsg(): playerFrom out of range");
return FALSE;
}
if(playerTo < 0 || playerTo >= MAX_PLAYERS)
{
debug(LOG_ERROR, "scrMsg(): playerTo out of range");
return FALSE;
}
//sendAIMessage(ssval, playerFrom, playerTo); //TODO: implement multiplayer messages
//show the message we sent on our local console as well (even in skirmish, if player plays as this AI)
if(playerFrom == selectedPlayer)
{
sprintf(tmp,"[%d-%d] : %s",playerFrom, playerTo, ssval); // add message
addConsoleMessage(tmp, RIGHT_JUSTIFY);
}
return TRUE;
}
BOOL scrDbg(void)
{
STRING *ssval=NULL;
SDWORD player;
if (!stackPopParams(2, VAL_STRING, &ssval, VAL_INT, &player))
{
debug(LOG_ERROR, "scrDbg(): stack failed");
return FALSE;
}
if(scrDebug[player])
{
STRING *sTmp;
sTmp = (char*)MALLOC(255);
sprintf(sTmp,"%d) %s",player,ssval);
addConsoleMessage(sTmp,DEFAULT_JUSTIFY);
}
return TRUE;
}
static UDWORD playerToEnumDroid;
static UDWORD playerVisibleDroid;
static UDWORD enumDroidCount;
@ -6400,40 +6531,57 @@ BOOL scrEnumDroid(void)
// push NULLDROID, since didn't find any
if (!stackPushResult((INTERP_TYPE)ST_DROID, (UDWORD)NULL))
{
debug(LOG_ERROR, "scrEnumDroid() - push failed");
return FALSE;
}
return TRUE;
}
//-----------------------------------------
//New functions
//-----------------------------------------
//compare two strings (0 means they are different)
BOOL scrStrcmp(void)
//Return the template factory is currently building
BOOL scrFactoryGetTemplate(void)
{
STRING *ssval1=NULL;
STRING *ssval2=NULL;
SDWORD structure;
STRUCTURE *psStructure = NULL;
DROID_TEMPLATE *psTemplate = NULL;
debug(LOG_SCRIPT,"scrStrcmp");
if (!stackPopParams(2, VAL_STRING, &ssval1, VAL_STRING, &ssval2))
if (!stackPopParams(1, ST_STRUCTURE, &structure))
{
debug(LOG_ERROR, "scrStrcmp(): stack failed");
debug(LOG_ERROR, "scrFactoryGetTemplate() - stackPopParams failed");
return FALSE;
}
debug(LOG_SCRIPT,"scrStrcmp 1");
if (!stackPushResult(VAL_BOOL, !strcmp(ssval1, ssval2)))
psStructure = (STRUCTURE *)structure;
if (psStructure == NULL)
{
debug(LOG_ERROR, "scrStrcmp: failed to push result");
ASSERT((FALSE, "scrFactoryGetTemplate: NULL factory object"));
return FALSE;
}
debug(LOG_SCRIPT,"scrStrcmp 2");
ASSERT((PTRVALID(psStructure, sizeof(STRUCTURE)),
"scrFactoryGetTemplate: Invalid structure pointer"));
ASSERT(((psStructure->pStructureType->type == REF_FACTORY OR
psStructure->pStructureType->type == REF_CYBORG_FACTORY OR
psStructure->pStructureType->type == REF_VTOL_FACTORY),
"scrFactoryGetTemplate: structure is not a factory"));
if(!StructIsFactory(psStructure))
{
debug(LOG_ERROR, "scrFactoryGetTemplate: structure not a factory.");
return FALSE;
}
psTemplate = (DROID_TEMPLATE *)((FACTORY*)psStructure->pFunctionality)->psSubject;
ASSERT((PTRVALID(psTemplate, sizeof(DROID_TEMPLATE)),
"scrFactoryGetTemplate: Invalid template pointer"));
if (!stackPushResult(ST_TEMPLATE, (UDWORD)psTemplate))
{
debug(LOG_ERROR, "scrFactoryGetTemplate: stackPushResult failed");
return FALSE;
}
return TRUE;
}

View File

@ -5,10 +5,7 @@
*
*/
#ifndef _scriptfuncs_h
#define _scriptfuncs_h
extern BOOL scrInitEnumDroids(void);
extern BOOL scrEnumDroid(void);
#define _scriptfuncs_h
// not used in scripts, but used in code.
extern BOOL objectInRange(BASE_OBJECT *psList, SDWORD x, SDWORD y, SDWORD range);
@ -501,6 +498,17 @@ extern BOOL scrSkFireLassat(void);
//-----------------------------------------
extern BOOL scrStrcmp(void);
extern BOOL scrConsole(void);
extern BOOL scrDbgMsgOn(void);
extern BOOL scrDbg(void);
extern BOOL scrMsg(void);
extern BOOL scrActionDroidObj(void);
extern BOOL scrInitEnumDroids(void);
extern BOOL scrEnumDroid(void);
extern BOOL scrInitIterateGroupB(void);
extern BOOL scrIterateGroupB(void);
extern BOOL scrFactoryGetTemplate(void);
#endif

View File

@ -39,18 +39,21 @@ BOOL scrBaseObjGet(UDWORD index)
if (!stackPopParams(1, ST_BASEOBJECT, &psObj))
{
debug(LOG_ERROR, "scrBaseObjGet: stackPopParams failed");
return FALSE;
}
// Check this is a valid pointer
if (psObj == NULL )
{
debug(LOG_ERROR, "scrBaseObjGet: was passed an invalid pointer");
ASSERT((FALSE, "scrBaseObjGet: was passed an invalid pointer"));
return FALSE;
}
// Check this is a valid pointer
if (psObj->type != OBJ_DROID && psObj->type != OBJ_STRUCTURE && psObj->type != OBJ_FEATURE)
{
debug(LOG_ERROR, "scrBaseObjGet: invalid object");
ASSERT((FALSE, "scrBaseObjGet: invalid object"));
return FALSE;
}
@ -85,6 +88,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_ORDER:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: order only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: order only valid for a droid"));
return FALSE;
}
@ -95,9 +99,46 @@ BOOL scrBaseObjGet(UDWORD index)
val = DORDER_NONE;
}
break;
//new member variable
case OBJID_ACTION:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: action only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: action only valid for a droid"));
return FALSE;
}
type = VAL_INT;
val = (SDWORD)((DROID *)psObj)->action;
break;
//new member variable - if droid is selected (humans only)
case OBJID_SELECTED:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: selected only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: selected only valid for a droid"));
return FALSE;
}
type = VAL_BOOL;
val = (SDWORD)((DROID *)psObj)->selected;
break;
case OBJID_STRUCTSTATTYPE:
if (psObj->type == OBJ_STRUCTURE)
{
type = VAL_INT;
val = ((STRUCTURE *)psObj)->pStructureType->type;
}
else
{
debug(LOG_ERROR, ".stattype is only supported by Structures");
return FALSE;
}
break;
case OBJID_ORDERX:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: order only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: order only valid for a droid"));
return FALSE;
}
@ -107,6 +148,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_ORDERY:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: order only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: order only valid for a droid"));
return FALSE;
}
@ -116,6 +158,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_DROIDTYPE:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: droidType only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: droidType only valid for a droid"));
return FALSE;
}
@ -125,6 +168,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_CLUSTERID:
if (psObj->type == OBJ_FEATURE)
{
debug(LOG_ERROR, "scrBaseObjGet: clusterID not valid for features");
ASSERT((FALSE,"scrBaseObjGet: clusterID not valid for features"));
return FALSE;
}
@ -164,6 +208,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_BODY:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: body only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: body only valid for a droid"));
return FALSE;
}
@ -173,6 +218,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_PROPULSION:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: propulsion only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: propulsion only valid for a droid"));
return FALSE;
}
@ -182,6 +228,7 @@ BOOL scrBaseObjGet(UDWORD index)
case OBJID_WEAPON:
if (psObj->type != OBJ_DROID)
{
debug(LOG_ERROR, "scrBaseObjGet: weapon only valid for a droid");
ASSERT((FALSE,"scrBaseObjGet: weapon only valid for a droid"));
return FALSE;
}
@ -196,16 +243,55 @@ BOOL scrBaseObjGet(UDWORD index)
val = ((DROID *)psObj)->asWeaps[0].nStat;
}
break;
case OBJID_STRUCTSTAT:
if (psObj->type != OBJ_STRUCTURE)
//droid.stat - now returns the type of structure a truck is building for droids
if (psObj->type == OBJ_STRUCTURE)
{
ASSERT((FALSE,"scrBaseObjGet: stat only valid for a structure"));
type = ST_STRUCTURESTAT;
val = ((STRUCTURE *)psObj)->pStructureType - asStructureStats;
}
else if (psObj->type == OBJ_DROID)
{
//psStructStats = (STRUCTURE_STATS*)psDroid->psTarStats;
type = ST_STRUCTURESTAT;
val = (SDWORD)((STRUCTURE_STATS *)(((DROID *)psObj)->psTarStats) - asStructureStats);
}
else //Nothing else supported
{
debug(LOG_ERROR, "scrBaseObjGet(): .stat only valid for structures and droids");
ASSERT((FALSE,"scrBaseObjGet(): .stat only valid for structures and droids"));
return FALSE;
}
type = (INTERP_TYPE)ST_STRUCTURESTAT;
val = ((STRUCTURE *)psObj)->pStructureType - asStructureStats;
break;
case OBJID_TARGET:
//added object->psTarget
if (psObj->type == OBJ_STRUCTURE)
{
type = ST_BASEOBJECT;
val = (SDWORD)((STRUCTURE *)psObj)->psTarget;
}
else if (psObj->type == OBJ_DROID)
{
//psStructStats = (STRUCTURE_STATS*)psDroid->psTarStats;
type = ST_BASEOBJECT;
val = (SDWORD)(((DROID *)psObj)->psTarget);
}
else //Nothing else supported
{
debug(LOG_ERROR, "scrBaseObjGet(): .target only valid for structures and droids");
ASSERT((FALSE,"scrBaseObjGet(): .target only valid for structures and droids"));
return FALSE;
}
break;
default:
debug(LOG_ERROR, "scrBaseObjGet: unknown variable index");
ASSERT((FALSE, "scrBaseObjGet: unknown variable index"));
return FALSE;
break;
@ -214,6 +300,7 @@ BOOL scrBaseObjGet(UDWORD index)
// Return the value
if (!stackPushResult(type, val))
{
debug(LOG_ERROR, "scrBaseObjGet: stackPushResult() failed");
return FALSE;
}

View File

@ -25,8 +25,12 @@ enum _objids
OBJID_PROPULSION, // the propulsion component
OBJID_WEAPON, // the weapon component
OBJID_STRUCTSTAT, // the stat of a structure
OBJID_STRUCTSTATTYPE,//new
OBJID_ORDERX, // order coords.106
OBJID_ORDERY,
OBJID_ACTION,
OBJID_SELECTED, //if droid is selected (humans only)
OBJID_TARGET, //added object->psTarget
};
// id's for group variables

View File

@ -26,6 +26,7 @@
//#include "mission.h"
#include "levels.h"
#include "order.h"
#include "Action.h" //new member variable - .action
#include "lib/gamelib/gtime.h"
#include "mission.h"
@ -703,6 +704,48 @@ FUNC_SYMBOL asFuncTable[] =
{ "strcmp", scrStrcmp, VAL_BOOL,
2, { VAL_STRING, VAL_STRING} },
{ "console", scrConsole, VAL_VOID,
1, { VAL_STRING } },
//{ "MsgBox", scrMsgBox, VAL_VOID,
// 1, { VAL_STRING } },
{ "dbgMsgOn", scrDbgMsgOn, VAL_VOID,
2, { VAL_INT, VAL_BOOL } },
{ "dbg", scrDbg, VAL_VOID,
2, { VAL_STRING, VAL_INT } },
{ "msg", scrMsg, VAL_VOID, //multiplayer msg
3, { VAL_STRING, VAL_INT, VAL_INT } },
//{ "addHelpMsg", scrAddHelpMsg, VAL_VOID,
// 6, { VAL_STRING, VAL_INT, VAL_INT, VAL_INT, VAL_INT, VAL_INT } },
//{ "removeHelpMessage", scrRemoveHelpMessage, VAL_VOID,
// 2, { VAL_INT, VAL_INT } },
//droid functions
//-----------------------------------
{ "actionDroidObj", scrActionDroidObj, VAL_VOID,
3, { ST_DROID, VAL_INT, ST_BASEOBJECT } },
{ "InitEnumDroids", scrInitEnumDroids, VAL_VOID,
2, { VAL_INT, VAL_INT } },
{ "EnumDroid", scrEnumDroid, ST_DROID,
0, { VAL_VOID } },
{ "initIterateGroupB", scrInitIterateGroupB, VAL_VOID,
2, { ST_GROUP, VAL_INT } },
{ "iterateGroupB", scrIterateGroupB, ST_DROID,
2, { ST_GROUP, VAL_INT } },
//{ "closestDamagedGroupDroid", scrClosestDamagedGroupDroid, ST_DROID,
// 6, { VAL_INT, ST_GROUP, VAL_INT, VAL_INT, VAL_INT, VAL_INT } },
{ "factoryGetTemplate", scrFactoryGetTemplate, ST_TEMPLATE,
1, { ST_STRUCTURE } },
/* END new functions */
@ -833,8 +876,9 @@ VAR_SYMBOL asObjTable[] =
scrBaseObjGet, NULL },
// structure variables
{ "stat", (INTERP_TYPE)ST_STRUCTURESTAT, (INTERP_TYPE)ST_OBJECT, (INTERP_TYPE)ST_STRUCTURE, OBJID_STRUCTSTAT,
scrBaseObjGet, NULL },
//{ "stat", (INTERP_TYPE)ST_STRUCTURESTAT, (INTERP_TYPE)ST_OBJECT, (INTERP_TYPE)ST_STRUCTURE, OBJID_STRUCTSTAT,
// scrBaseObjGet, NULL },
// group variables
{ "x", VAL_INT, (INTERP_TYPE)ST_OBJECT, (INTERP_TYPE)ST_GROUP, GROUPID_POSX,
@ -846,7 +890,26 @@ VAR_SYMBOL asObjTable[] =
{ "health", VAL_INT, (INTERP_TYPE)ST_OBJECT, (INTERP_TYPE)ST_GROUP, GROUPID_HEALTH,
scrGroupObjGet, NULL },
/* new member variables */
//similiar to .order
{ "action", VAL_INT, (INTERP_TYPE)ST_OBJECT, ST_DROID, OBJID_ACTION,
scrBaseObjGet, NULL },
//.stat - now supports droids, ST_STRUCTURE became ST_BASEOBJECT
{ "stat", ST_STRUCTURESTAT, (INTERP_TYPE)ST_OBJECT, ST_BASEOBJECT, OBJID_STRUCTSTAT,
scrBaseObjGet, NULL },
//object->psTarget
{ "target", ST_BASEOBJECT, (INTERP_TYPE)ST_OBJECT, ST_BASEOBJECT, OBJID_TARGET,
scrBaseObjGet, NULL },
//returns psStruct->pStructureType->type
{ "stattype", VAL_INT, (INTERP_TYPE)ST_OBJECT, ST_STRUCTURE, OBJID_STRUCTSTATTYPE,
scrBaseObjGet, NULL },
//returns if this unit is currently selected by a player (usually human)
{ "selected", VAL_BOOL, (INTERP_TYPE)ST_OBJECT, ST_DROID, OBJID_SELECTED,
scrBaseObjGet, NULL },
/* This entry marks the end of the variable list */
{ NULL, VAL_VOID, (INTERP_TYPE)ST_OBJECT, VAL_VOID, 0, NULL, NULL }
@ -988,6 +1051,52 @@ CONST_SYMBOL asConstantTable[] =
{ "DORDER_EMBARK", VAL_INT, 0, DORDER_EMBARK, 0 },
{ "DORDER_DISEMBARK", VAL_INT, 0, DORDER_DISEMBARK, 0 },
{ "DORDER_SCOUT", VAL_INT, 0, DORDER_SCOUT, 0 },
{ "DORDER_DROIDREPAIR", VAL_INT, 0, DORDER_DROIDREPAIR, 0 }, //new one
//new member varialbe - constants for .action
//-----------------------------------------------------------
{ "DACTION_NONE", VAL_INT, 0, DACTION_NONE, 0 },
{ "DACTION_MOVE", VAL_INT, 0, DACTION_MOVE, 0 },
{ "DACTION_BUILD", VAL_INT, 0, DACTION_BUILD, 0 },
{ "DACTION_BUILD_FOUNDATION", VAL_INT, 0, DACTION_BUILD_FOUNDATION, 0 },
{ "DACTION_DEMOLISH", VAL_INT, 0, DACTION_DEMOLISH, 0 },
{ "DACTION_REPAIR", VAL_INT, 0, DACTION_REPAIR, 0 },
{ "DACTION_ATTACK", VAL_INT, 0, DACTION_ATTACK, 0 },
{ "DACTION_OBSERVE", VAL_INT, 0, DACTION_OBSERVE, 0 },
{ "DACTION_FIRESUPPORT", VAL_INT, 0, DACTION_FIRESUPPORT, 0 },
{ "DACTION_SULK", VAL_INT, 0, DACTION_SULK, 0 },
{ "DACTION_DESTRUCT", VAL_INT, 0, DACTION_DESTRUCT, 0 },
{ "DACTION_TRANSPORTOUT", VAL_INT, 0, DACTION_TRANSPORTOUT, 0 },
{ "DACTION_TRANSPORTWAITTOFLYIN", VAL_INT, 0, DACTION_TRANSPORTWAITTOFLYIN, 0 },
{ "DACTION_TRANSPORTIN", VAL_INT, 0, DACTION_TRANSPORTIN, 0 },
{ "DACTION_DROIDREPAIR", VAL_INT, 0, DACTION_DROIDREPAIR, 0 },
{ "DACTION_RESTORE", VAL_INT, 0, DACTION_RESTORE, 0 },
{ "DACTION_MOVEFIRE", VAL_INT, 0, DACTION_MOVEFIRE, 0 },
{ "DACTION_MOVETOBUILD", VAL_INT, 0, DACTION_MOVETOBUILD, 0 },
{ "DACTION_MOVETODEMOLISH", VAL_INT, 0, DACTION_MOVETODEMOLISH, 0 },
{ "DACTION_MOVETOREPAIR", VAL_INT, 0, DACTION_MOVETOREPAIR, 0 },
{ "DACTION_BUILDWANDER", VAL_INT, 0, DACTION_BUILDWANDER, 0 },
{ "DACTION_FOUNDATION_WANDER", VAL_INT, 0, DACTION_FOUNDATION_WANDER, 0 },
{ "DACTION_MOVETOATTACK", VAL_INT, 0, DACTION_MOVETOATTACK, 0 },
{ "DACTION_ROTATETOATTACK", VAL_INT, 0, DACTION_ROTATETOATTACK, 0 },
{ "DACTION_MOVETOOBSERVE", VAL_INT, 0, DACTION_MOVETOOBSERVE, 0 },
{ "DACTION_WAITFORREPAIR", VAL_INT, 0, DACTION_WAITFORREPAIR, 0 },
{ "DACTION_MOVETOREPAIRPOINT", VAL_INT, 0, DACTION_MOVETOREPAIRPOINT, 0 },
{ "DACTION_WAITDURINGREPAIR", VAL_INT, 0, DACTION_WAITDURINGREPAIR, 0 },
{ "DACTION_MOVETODROIDREPAIR", VAL_INT, 0, DACTION_MOVETODROIDREPAIR, 0 },
{ "DACTION_MOVETORESTORE", VAL_INT, 0, DACTION_MOVETORESTORE, 0 },
{ "DACTION_MOVETOREARM", VAL_INT, 0, DACTION_MOVETOREARM, 0 },
{ "DACTION_WAITFORREARM", VAL_INT, 0, DACTION_WAITFORREARM, 0 },
{ "DACTION_MOVETOREARMPOINT", VAL_INT, 0, DACTION_MOVETOREARMPOINT, 0 },
{ "DACTION_WAITDURINGREARM", VAL_INT, 0, DACTION_WAITDURINGREARM, 0 },
{ "DACTION_VTOLATTACK", VAL_INT, 0, DACTION_VTOLATTACK, 0 },
{ "DACTION_CLEARREARMPAD", VAL_INT, 0, DACTION_CLEARREARMPAD, 0 },
{ "DACTION_RETURNTOPOS", VAL_INT, 0, DACTION_RETURNTOPOS, 0 },
{ "DACTION_FIRESUPPORT_RETREAT", VAL_INT, 0, DACTION_FIRESUPPORT_RETREAT, 0 },
// secondary orders
{ "DSO_ATTACK_RANGE", VAL_INT, 0, DSO_ATTACK_RANGE, 0 },
@ -1263,6 +1372,29 @@ CALLBACK_SYMBOL asCallbackTable[] =
{ "CALL_ALLIANCEOFFER", (TRIGGER_TYPE)CALL_ALLIANCEOFFER, scrCBAllianceOffer,
2, { VAL_REF|VAL_INT,VAL_REF|VAL_INT }},
// new callbacks
//-------------------------------------------------------------------------------
//console callback
{ "CALL_CONSOLE", (TRIGGER_TYPE)CALL_CONSOLE, scrCallConsole,
2, { VAL_REF|VAL_INT,VAL_REF|VAL_STRING }},
//59
{ "CALL_AI_MSG", (TRIGGER_TYPE)CALL_AI_MSG, scrCallMultiMsg,
3, { VAL_INT, VAL_REF|VAL_INT,VAL_REF|VAL_STRING }},
//59
//{ "CALL_BEACON", (TRIGGER_TYPE)CALL_BEACON, scrCallBeacon,
// 5, { VAL_INT, VAL_REF|VAL_INT, VAL_REF|VAL_INT,
// VAL_REF|VAL_INT, VAL_REF|VAL_STRING }},
{ "CALL_STRUCTBUILT", (TRIGGER_TYPE)CALL_STRUCTBUILT, scrCBStructBuilt,
3, { VAL_INT, VAL_REF|ST_DROID, VAL_REF|ST_STRUCTURE } },
//new transporter landed callback
{ "CALL_TRANSPORTER_LANDED_B", (TRIGGER_TYPE)CALL_TRANSPORTER_LANDED_B, scrCBTransporterLandedB,
3, { ST_GROUP, VAL_INT, VAL_REF|ST_DROID } },
/* This entry marks the end of the callback list */
{ "CALLBACK LIST END", 0 }
};

View File

@ -75,6 +75,11 @@ typedef enum _scr_callback_types
CALL_UNITTAKEOVER,
CALL_PLAYERLEFT,
CALL_ALLIANCEOFFER,
CALL_CONSOLE, //Gets fired when user types something in the console and presses enter
CALL_AI_MSG, //player received msg from another player
CALL_STRUCTBUILT, //gets fired when a structure is built for a certain player, returns structure
CALL_TRANSPORTER_LANDED_B,
CALL_BEACON, //beacon help (blip) msg received
} SCR_CALLBACK_TYPES;
// The table of user types for the compiler