Scripting:
-allow creation of unit templates on the fly -allow direct access to major weapon stats from within scripts git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5014 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
f5cac3bfc5
commit
3d2dc99003
|
@ -3651,6 +3651,14 @@ return_exp: expression
|
|||
{
|
||||
RULE( "return_exp: objexp");
|
||||
|
||||
/* Just pass the code up the tree */
|
||||
/* $1->type = */
|
||||
$$ = $1;
|
||||
}
|
||||
| userexp /* templates, bodies etc */
|
||||
{
|
||||
RULE( "return_exp: userexp");
|
||||
|
||||
/* Just pass the code up the tree */
|
||||
/* $1->type = */
|
||||
$$ = $1;
|
||||
|
@ -5373,6 +5381,8 @@ userexp: VAR
|
|||
}
|
||||
| user_array_var
|
||||
{
|
||||
RULE("userexp: user_array_var");
|
||||
|
||||
codeRet = scriptCodeArrayGet($1, &psCurrBlock);
|
||||
CHECK_CODE_ERROR(codeRet);
|
||||
|
||||
|
@ -5386,6 +5396,63 @@ userexp: VAR
|
|||
CHECK_CODE_ERROR(codeRet);
|
||||
|
||||
/* Return the code block */
|
||||
$$ = psCurrBlock;
|
||||
}
|
||||
| USER_FUNC_CUST '(' param_list ')'
|
||||
{
|
||||
UDWORD line,paramNumber;
|
||||
char *pDummy;
|
||||
|
||||
if($3->numParams != $1->numParams)
|
||||
{
|
||||
debug(LOG_ERROR, "Wrong number of arguments for function call: '%s'. Expected %d parameters instead of %d.", $1->pIdent, $1->numParams, $3->numParams);
|
||||
scr_error("Wrong number of arguments in function call");
|
||||
return CE_PARSE;
|
||||
}
|
||||
|
||||
if(!$1->bFunction)
|
||||
{
|
||||
debug(LOG_ERROR, "'%s' is not a function", $1->pIdent);
|
||||
scr_error("Can't call an event");
|
||||
return CE_PARSE;
|
||||
}
|
||||
|
||||
/* check if right parameters were passed */
|
||||
paramNumber = checkFuncParamTypes($1, $3);
|
||||
if(paramNumber > 0)
|
||||
{
|
||||
debug(LOG_ERROR, "Parameter mismatch in function call: '%s'. Mismatch in parameter %d.", $1->pIdent, paramNumber);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
/* Allocate the code block */
|
||||
ALLOC_BLOCK(psCurrBlock, $3->size + 1 + 1); //Params + Opcode + event index
|
||||
|
||||
ALLOC_DEBUG(psCurrBlock, 1);
|
||||
ip = psCurrBlock->pCode;
|
||||
|
||||
if($3->numParams > 0) /* if any parameters declared */
|
||||
{
|
||||
/* Copy in the code for the parameters */
|
||||
PUT_BLOCK(ip, $3);
|
||||
FREE_PBLOCK($3);
|
||||
}
|
||||
|
||||
/* Store the instruction */
|
||||
PUT_OPCODE(ip, OP_FUNC);
|
||||
PUT_EVENT(ip,$1->index); //Put event index
|
||||
|
||||
/* Add the debugging information */
|
||||
if (genDebugInfo)
|
||||
{
|
||||
psCurrBlock->psDebug[0].offset = 0;
|
||||
scriptGetErrorData((SDWORD *)&line, &pDummy);
|
||||
psCurrBlock->psDebug[0].line = line;
|
||||
}
|
||||
|
||||
/* remember objexp type for further stuff, like myVar = objFunc(); to be able to check type equivalency */
|
||||
psCurrBlock->type = $1->retType;
|
||||
|
||||
$$ = psCurrBlock;
|
||||
}
|
||||
| TRIG_SYM
|
||||
|
@ -5562,6 +5629,14 @@ objexp_dot: objexp '.'
|
|||
{
|
||||
RULE( "objexp_dot: objexp '.', type=%d", $1->type);
|
||||
|
||||
// Store the object type for the variable lookup
|
||||
objVarContext = $1->type;
|
||||
}
|
||||
|
|
||||
userexp '.'
|
||||
{
|
||||
RULE( "objexp_dot: userexp '.', type=%d", $1->type);
|
||||
|
||||
// Store the object type for the variable lookup
|
||||
objVarContext = $1->type;
|
||||
}
|
||||
|
@ -5699,6 +5774,8 @@ obj_array_var: OBJ_ARRAY array_index_list
|
|||
|
||||
user_array_var: VAR_ARRAY array_index_list
|
||||
{
|
||||
RULE("user_array_var: VAR_ARRAY array_index_list");
|
||||
|
||||
codeRet = scriptCodeArrayVariable($2, $1, &psCurrArrayBlock);
|
||||
CHECK_CODE_ERROR(codeRet);
|
||||
|
||||
|
|
26
src/design.c
26
src/design.c
|
@ -335,7 +335,7 @@ static void intSetPropulsionStats(PROPULSION_STATS *psStats);
|
|||
/* Set the shadow bar graphs for the Propulsion stats */
|
||||
static void intSetPropulsionShadowStats(PROPULSION_STATS *psStats);
|
||||
/* Check whether a droid template is valid */
|
||||
static BOOL intValidTemplate(DROID_TEMPLATE *psTempl);
|
||||
BOOL intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName);
|
||||
/* General display window for the design form */
|
||||
void intDisplayDesignForm(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours);
|
||||
/* Sets the Design Power Bar for a given Template */
|
||||
|
@ -1331,7 +1331,7 @@ intChooseSystemStats( DROID_TEMPLATE *psTemplate )
|
|||
/* set SHOWTEMPLATENAME to 0 to show template components in edit box */
|
||||
#define SHOWTEMPLATENAME 0
|
||||
|
||||
static const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate)
|
||||
const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate)
|
||||
{
|
||||
COMP_BASE_STATS *psStats = NULL;
|
||||
|
||||
|
@ -3367,7 +3367,7 @@ static void intSetPropulsionShadowStats(PROPULSION_STATS *psStats)
|
|||
|
||||
|
||||
/* Check whether a droid template is valid */
|
||||
static BOOL intValidTemplate(DROID_TEMPLATE *psTempl)
|
||||
BOOL intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName)
|
||||
{
|
||||
UDWORD i;
|
||||
|
||||
|
@ -3444,8 +3444,8 @@ static BOOL intValidTemplate(DROID_TEMPLATE *psTempl)
|
|||
//set the droidtype
|
||||
psTempl->droidType = droidTemplateType(psTempl);
|
||||
|
||||
/* copy current name into template */
|
||||
sstrcpy(sCurrDesign.aName, aCurrName);
|
||||
/* copy name into template */
|
||||
sstrcpy(psTempl->aName, newName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3864,7 +3864,7 @@ void intProcessDesign(UDWORD id)
|
|||
intSetEditBoxTextFromTemplate( &sCurrDesign );
|
||||
|
||||
/* flash next button if design not complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == false )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == false )
|
||||
{
|
||||
/* reset button states */
|
||||
widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, 0);
|
||||
|
@ -4191,7 +4191,7 @@ void intProcessDesign(UDWORD id)
|
|||
|
||||
#ifdef FLASH_BUTTONS
|
||||
/* lock button if design complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == true )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == true )
|
||||
{
|
||||
widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, WBUT_CLICKLOCK);
|
||||
widgSetButtonState(psWScreen, IDDES_BODYBUTTON, 0);
|
||||
|
@ -4229,7 +4229,7 @@ void intProcessDesign(UDWORD id)
|
|||
|
||||
#ifdef FLASH_BUTTONS
|
||||
/* lock button if design complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == true )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == true )
|
||||
{
|
||||
widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, 0);
|
||||
widgSetButtonState(psWScreen, IDDES_BODYBUTTON, 0);
|
||||
|
@ -4268,7 +4268,7 @@ void intProcessDesign(UDWORD id)
|
|||
|
||||
#ifdef FLASH_BUTTONS
|
||||
/* lock button if design complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == true )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == true )
|
||||
{
|
||||
//Watermelon:enable the 2nd turret button
|
||||
widgSetButtonState(psWScreen, IDDES_WPBBUTTON, WBUT_CLICKLOCK);
|
||||
|
@ -4291,7 +4291,7 @@ void intProcessDesign(UDWORD id)
|
|||
|
||||
#ifdef FLASH_BUTTONS
|
||||
/* lock button if design complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == true )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == true )
|
||||
{
|
||||
widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, 0);
|
||||
widgSetButtonState(psWScreen, IDDES_BODYBUTTON, WBUT_CLICKLOCK);
|
||||
|
@ -4311,7 +4311,7 @@ void intProcessDesign(UDWORD id)
|
|||
|
||||
#ifdef FLASH_BUTTONS
|
||||
/* lock button if design complete */
|
||||
if ( intValidTemplate( &sCurrDesign ) == true )
|
||||
if ( intValidTemplate( &sCurrDesign, aCurrName ) == true )
|
||||
{
|
||||
widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, 0);
|
||||
widgSetButtonState(psWScreen, IDDES_BODYBUTTON, 0);
|
||||
|
@ -4368,7 +4368,7 @@ void intProcessDesign(UDWORD id)
|
|||
widgReveal( psWScreen, IDDES_STATSFORM );
|
||||
|
||||
/* switch automatically to next component type if initial design */
|
||||
if ( !intValidTemplate( &sCurrDesign ) )
|
||||
if ( !intValidTemplate( &sCurrDesign, aCurrName ) )
|
||||
{
|
||||
/* show next component design screen */
|
||||
switch ( desCompMode )
|
||||
|
@ -4668,7 +4668,7 @@ static BOOL saveTemplate(void)
|
|||
}
|
||||
}
|
||||
|
||||
if ( bTemplateFound == true && intValidTemplate( &sCurrDesign ) )
|
||||
if ( bTemplateFound == true && intValidTemplate( &sCurrDesign, aCurrName ) )
|
||||
{
|
||||
/* create new template if button is NULL,
|
||||
* else store changes to existing template */
|
||||
|
|
|
@ -153,4 +153,8 @@ extern void resetDesignPauseState(void);
|
|||
|
||||
extern void reverseTemplateList(DROID_TEMPLATE **ppsList);
|
||||
|
||||
extern const char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate);
|
||||
|
||||
extern BOOL intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName);
|
||||
|
||||
#endif // __INCLUDED_SRC_DESIGN_H__
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#include "lib/script/chat_processing.h"
|
||||
#include "keymap.h"
|
||||
#include "visibility.h"
|
||||
#include "design.h"
|
||||
|
||||
static INTERP_VAL scrFunctionResult; //function return value to be pushed to stack
|
||||
|
||||
|
@ -102,6 +103,10 @@ static char strParam1[MAXSTRLEN], strParam2[MAXSTRLEN]; //these should be used
|
|||
|
||||
static BOOL structHasModule(STRUCTURE *psStruct);
|
||||
|
||||
static DROID_TEMPLATE* scrCheckTemplateExists(SDWORD player, DROID_TEMPLATE *psTempl);
|
||||
|
||||
extern UDWORD objID; // unique ID creation thing..
|
||||
|
||||
/******************************************************************************************/
|
||||
/* Check for objects in areas */
|
||||
|
||||
|
@ -11438,3 +11443,312 @@ BOOL scrCheckVisibleTile(void)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Assembles a template from components and returns it */
|
||||
BOOL scrAssembleWeaponTemplate(void)
|
||||
{
|
||||
SDWORD player,bodyIndex,weapIndex,propIndex;
|
||||
DROID_TEMPLATE *pNewTemplate = NULL;
|
||||
|
||||
if (!stackPopParams(4, VAL_INT, &player, ST_BODY, &bodyIndex,
|
||||
ST_PROPULSION, &propIndex, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pNewTemplate = malloc(sizeof(DROID_TEMPLATE));
|
||||
if (pNewTemplate == NULL)
|
||||
{
|
||||
debug(LOG_ERROR, "pNewTemplate: Out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(pNewTemplate, 0, sizeof(DROID_TEMPLATE));
|
||||
|
||||
// set template body
|
||||
pNewTemplate->asParts[COMP_BODY] = bodyIndex;
|
||||
|
||||
// set template propulsion
|
||||
pNewTemplate->asParts[COMP_PROPULSION] = propIndex;
|
||||
|
||||
// set template weapon (only one)
|
||||
pNewTemplate->asParts[COMP_WEAPON] = weapIndex;
|
||||
pNewTemplate->asWeaps[0] = weapIndex;
|
||||
pNewTemplate->numWeaps = 1;
|
||||
|
||||
// set default components
|
||||
pNewTemplate->asParts[COMP_SENSOR] = 0;
|
||||
pNewTemplate->asParts[COMP_ECM] = 0;
|
||||
pNewTemplate->asParts[COMP_CONSTRUCT] = 0;
|
||||
pNewTemplate->asParts[COMP_REPAIRUNIT] = 0;
|
||||
pNewTemplate->asParts[COMP_BRAIN] = 0;
|
||||
|
||||
// set droid type
|
||||
pNewTemplate->droidType = DROID_WEAPON;
|
||||
|
||||
// finalize template and set its name
|
||||
if(!intValidTemplate(pNewTemplate, GetDefaultTemplateName(pNewTemplate)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure we have a valid weapon
|
||||
if(!checkValidWeaponForProp(pNewTemplate))
|
||||
{
|
||||
scrFunctionResult.v.oval = NULL; // failure
|
||||
}
|
||||
else
|
||||
{
|
||||
DROID_TEMPLATE *tempTemplate = NULL;
|
||||
|
||||
// check if an identical template already exists for this player
|
||||
tempTemplate = scrCheckTemplateExists(player, pNewTemplate);
|
||||
if(tempTemplate == NULL)
|
||||
{
|
||||
// set template id
|
||||
pNewTemplate->multiPlayerID = (objID<<3)|player;
|
||||
objID++;
|
||||
|
||||
// add template to player template list
|
||||
pNewTemplate->psNext = apsDroidTemplates[player];
|
||||
apsDroidTemplates[player] = pNewTemplate; //apsTemplateList?
|
||||
|
||||
if (bMultiPlayer)
|
||||
{
|
||||
sendTemplate(pNewTemplate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// free resources
|
||||
free(pNewTemplate);
|
||||
|
||||
// already exists, so return it
|
||||
pNewTemplate = tempTemplate;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.oval = pNewTemplate; // succes
|
||||
}
|
||||
|
||||
// return template to scripts
|
||||
if (!stackPushResult(ST_TEMPLATE, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Checks if template already exists, returns it if yes */
|
||||
static DROID_TEMPLATE* scrCheckTemplateExists(SDWORD player, DROID_TEMPLATE *psTempl)
|
||||
{
|
||||
DROID_TEMPLATE *psCurrent;
|
||||
UDWORD compType,weaponSlot;
|
||||
bool bEqual = true;
|
||||
|
||||
psCurrent = apsDroidTemplates[player];
|
||||
|
||||
while(psCurrent != NULL)
|
||||
{
|
||||
// compare components
|
||||
bEqual = true;
|
||||
for(compType = 0; bEqual && compType < DROID_MAXCOMP; compType++)
|
||||
{
|
||||
if(psTempl->asParts[compType] != psCurrent->asParts[compType])
|
||||
{
|
||||
bEqual = false;
|
||||
}
|
||||
}
|
||||
|
||||
// compare weapon count
|
||||
if(bEqual && (psTempl->numWeaps != psCurrent->numWeaps))
|
||||
{
|
||||
bEqual = false;;
|
||||
}
|
||||
|
||||
// compare all weapons separately
|
||||
for(weaponSlot = 0; bEqual && (weaponSlot < psTempl->numWeaps); weaponSlot++)
|
||||
{
|
||||
if(psTempl->asWeaps[weaponSlot] != psCurrent->asWeaps[weaponSlot])
|
||||
{
|
||||
bEqual = false;
|
||||
}
|
||||
}
|
||||
|
||||
// they are equal, so return the current template
|
||||
if(bEqual)
|
||||
{
|
||||
return psCurrent;
|
||||
}
|
||||
|
||||
// try next one
|
||||
psCurrent = psCurrent->psNext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL scrWeaponShortHitUpgrade(void)
|
||||
{
|
||||
SDWORD player,weapIndex;
|
||||
const WEAPON_STATS *psWeapStats;
|
||||
|
||||
if (!stackPopParams(2, VAL_INT, &player, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
psWeapStats = &asWeaponStats[weapIndex];
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponUpgrade[player][psWeapStats->weaponSubClass].shortHit;
|
||||
if (!stackPushResult(VAL_INT, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL scrWeaponLongHitUpgrade(void)
|
||||
{
|
||||
SDWORD player,weapIndex;
|
||||
const WEAPON_STATS *psWeapStats;
|
||||
|
||||
if (!stackPopParams(2, VAL_INT, &player, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
psWeapStats = &asWeaponStats[weapIndex];
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponUpgrade[player][psWeapStats->weaponSubClass].longHit;
|
||||
if (!stackPushResult(VAL_INT, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BOOL scrWeaponDamageUpgrade(void)
|
||||
{
|
||||
SDWORD player,weapIndex;
|
||||
const WEAPON_STATS *psWeapStats;
|
||||
|
||||
if (!stackPopParams(2, VAL_INT, &player, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
psWeapStats = &asWeaponStats[weapIndex];
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponUpgrade[player][psWeapStats->weaponSubClass].damage;
|
||||
if (!stackPushResult(VAL_INT, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL scrWeaponFirePauseUpgrade(void)
|
||||
{
|
||||
SDWORD player,weapIndex;
|
||||
const WEAPON_STATS *psWeapStats;
|
||||
|
||||
if (!stackPopParams(2, VAL_INT, &player, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
psWeapStats = &asWeaponStats[weapIndex];
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponUpgrade[player][psWeapStats->weaponSubClass].firePause;
|
||||
if (!stackPushResult(VAL_INT, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BOOL scrIsComponentAvailable(void)
|
||||
{
|
||||
SDWORD player;
|
||||
BOOL bAvailable = false;
|
||||
INTERP_VAL sVal;
|
||||
|
||||
if (!stackPop(&sVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stackPopParams(1, VAL_INT, &player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player >= MAX_PLAYERS)
|
||||
{
|
||||
ASSERT( false, "player number is too high" );
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (sVal.type)
|
||||
{
|
||||
case ST_BODY:
|
||||
bAvailable = (apCompLists[player][COMP_BODY][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_PROPULSION:
|
||||
bAvailable = (apCompLists[player][COMP_PROPULSION][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_ECM:
|
||||
bAvailable = (apCompLists[player][COMP_ECM][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_SENSOR:
|
||||
bAvailable = (apCompLists[player][COMP_SENSOR][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_CONSTRUCT:
|
||||
bAvailable = (apCompLists[player][COMP_CONSTRUCT][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_WEAPON:
|
||||
bAvailable = (apCompLists[player][COMP_WEAPON][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_REPAIR:
|
||||
bAvailable = (apCompLists[player][COMP_REPAIRUNIT][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
case ST_BRAIN:
|
||||
bAvailable = (apCompLists[player][COMP_BRAIN][sVal.v.ival] == AVAILABLE);
|
||||
break;
|
||||
default:
|
||||
ASSERT( false, "unknown component type" );
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.bval = bAvailable;
|
||||
if (!stackPushResult(VAL_BOOL, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL scrGetBodySize(void)
|
||||
{
|
||||
SDWORD bodyIndex;
|
||||
|
||||
if (!stackPopParams(1,ST_BODY, &bodyIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = asBodyStats[bodyIndex].size;
|
||||
if (!stackPushResult(VAL_INT, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -645,6 +645,13 @@ extern BOOL scrGetDroidLevel(void);
|
|||
extern BOOL scrMoveDroidStopped(void);
|
||||
extern BOOL scrUpdateVisibleTiles(void);
|
||||
extern BOOL scrCheckVisibleTile(void);
|
||||
extern BOOL scrAssembleWeaponTemplate(void);
|
||||
extern BOOL scrWeaponShortHitUpgrade(void);
|
||||
extern BOOL scrWeaponLongHitUpgrade(void);
|
||||
extern BOOL scrWeaponDamageUpgrade(void);
|
||||
extern BOOL scrWeaponFirePauseUpgrade(void);
|
||||
extern BOOL scrIsComponentAvailable(void);
|
||||
extern BOOL scrGetBodySize(void);
|
||||
|
||||
|
||||
extern BOOL beingResearchedByAlly(SDWORD resIndex, SDWORD player);
|
||||
|
|
306
src/scriptobj.c
306
src/scriptobj.c
|
@ -58,7 +58,6 @@ BOOL scrBaseObjGet(UDWORD index)
|
|||
DROID *psDroid;
|
||||
STRUCTURE *psStruct;
|
||||
FEATURE *psFeature;
|
||||
SDWORD temp;
|
||||
|
||||
if (!stackPopParams(1, ST_BASEOBJECT, &psObj))
|
||||
{
|
||||
|
@ -314,229 +313,7 @@ BOOL scrBaseObjGet(UDWORD index)
|
|||
type = (INTERP_TYPE)ST_GROUP;
|
||||
scrFunctionResult.v.oval = ((DROID *)psObj)->psGroup;
|
||||
break;
|
||||
case OBJID_WEAP_SHORT_RANGE:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat].shortRange;
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat].shortRange;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortRange: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_LONG_RANGE:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat].longRange;
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat].longRange;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortRange: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_SHORT_HIT:
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponShortHit(&asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponShortHit(&asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_LONG_HIT:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponLongHit(&asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponLongHit(&asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_DAMAGE:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponDamage(&asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponDamage(&asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_FIRE_PAUSE:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponFirePause(&asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = weaponFirePause(&asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat], psObj->player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_RELOAD_TIME:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat].reloadTime;
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat].reloadTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_WEAP_NUM_ROUNDS:
|
||||
|
||||
type = VAL_INT;
|
||||
temp = -1; // in case object has no weapon return -1
|
||||
|
||||
if (psObj->type == OBJ_STRUCTURE)
|
||||
{
|
||||
if(((STRUCTURE *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((STRUCTURE *)psObj)->asWeaps[0].nStat].numRounds;
|
||||
}
|
||||
}
|
||||
else if (psObj->type == OBJ_DROID)
|
||||
{
|
||||
if(((DROID *)psObj)->asWeaps[0].nStat > 0)
|
||||
{
|
||||
temp = asWeaponStats[((DROID *)psObj)->asWeaps[0].nStat].numRounds;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_ERROR, "scrBaseObjGet(): shortHit: features don't have weapons");
|
||||
return false;
|
||||
}
|
||||
|
||||
scrFunctionResult.v.ival = temp;
|
||||
|
||||
break;
|
||||
case OBJID_HITPOINTS:
|
||||
|
||||
type = VAL_INT;
|
||||
|
@ -686,6 +463,89 @@ BOOL scrObjToFeature(void)
|
|||
// to speed up access
|
||||
static SDWORD lgX,lgY, lgMembers, lgHealth;
|
||||
|
||||
// Get values from a weapon
|
||||
BOOL scrWeaponObjGet(UDWORD index)
|
||||
{
|
||||
INTERP_TYPE type;
|
||||
SDWORD weapIndex;
|
||||
|
||||
if (!stackPopParams(1, ST_WEAPON, &weapIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case WEAPID_SHORT_RANGE:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].shortRange;
|
||||
|
||||
break;
|
||||
case WEAPID_LONG_RANGE:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].longRange;
|
||||
|
||||
break;
|
||||
case WEAPID_SHORT_HIT:
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].shortHit;
|
||||
|
||||
break;
|
||||
case WEAPID_LONG_HIT:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].longHit;
|
||||
|
||||
break;
|
||||
case WEAPID_DAMAGE:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].damage;
|
||||
|
||||
break;
|
||||
case WEAPID_FIRE_PAUSE:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].firePause;
|
||||
|
||||
break;
|
||||
case WEAPID_RELOAD_TIME:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].reloadTime;
|
||||
|
||||
break;
|
||||
case WEAPID_NUM_ROUNDS:
|
||||
|
||||
type = VAL_INT;
|
||||
|
||||
scrFunctionResult.v.ival = asWeaponStats[weapIndex].numRounds;
|
||||
|
||||
break;
|
||||
default:
|
||||
ASSERT( false, "unknown variable index" );
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the value
|
||||
if (!stackPushResult(type, &scrFunctionResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get values from a group
|
||||
BOOL scrGroupObjGet(UDWORD index)
|
||||
{
|
||||
|
|
|
@ -48,14 +48,14 @@ enum _objids
|
|||
OBJID_SELECTED, // if droid is selected (humans only)
|
||||
OBJID_TARGET, // added object->psTarget
|
||||
OBJID_GROUP, // group a droid belongs to
|
||||
OBJID_WEAP_SHORT_RANGE, // short range of a weapon
|
||||
OBJID_WEAP_LONG_RANGE, // short range of a weapon
|
||||
OBJID_WEAP_SHORT_HIT, // weapon's chance to hit in the short range
|
||||
OBJID_WEAP_LONG_HIT, // weapon's chance to hit in the long range
|
||||
OBJID_WEAP_FIRE_PAUSE, // weapon's fire pause
|
||||
OBJID_WEAP_RELOAD_TIME, // weapon's reload time
|
||||
OBJID_WEAP_NUM_ROUNDS, // num of weapon's rounds (salvo fire)
|
||||
OBJID_WEAP_DAMAGE, // weapon's damage
|
||||
WEAPID_SHORT_RANGE, // short range of a weapon
|
||||
WEAPID_LONG_RANGE, // short range of a weapon
|
||||
WEAPID_SHORT_HIT, // weapon's chance to hit in the short range
|
||||
WEAPID_LONG_HIT, // weapon's chance to hit in the long range
|
||||
WEAPID_FIRE_PAUSE, // weapon's fire pause
|
||||
WEAPID_RELOAD_TIME, // weapon's reload time
|
||||
WEAPID_NUM_ROUNDS, // num of weapon's rounds (salvo fire)
|
||||
WEAPID_DAMAGE, // weapon's damage
|
||||
OBJID_HITPOINTS, // doid's health left
|
||||
OBJID_ORIG_HITPOINTS, // original health of a droid (when not damaged)
|
||||
};
|
||||
|
@ -92,6 +92,9 @@ extern BOOL scrObjToFeature(void);
|
|||
// Get values from a group
|
||||
extern BOOL scrGroupObjGet(UDWORD index);
|
||||
|
||||
// Get values from a weapon
|
||||
extern BOOL scrWeaponObjGet(UDWORD index);
|
||||
|
||||
// default value save routine
|
||||
extern BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize);
|
||||
|
||||
|
|
|
@ -1430,6 +1430,34 @@ FUNC_SYMBOL asFuncTable[] =
|
|||
3, { VAL_INT, VAL_INT, VAL_INT },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "assembleWeaponTemplate", scrAssembleWeaponTemplate, ST_TEMPLATE,
|
||||
4, { VAL_INT, (INTERP_TYPE)ST_BODY, (INTERP_TYPE)ST_PROPULSION, (INTERP_TYPE)ST_WEAPON },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "weaponShortHitUpgrade", scrWeaponShortHitUpgrade, VAL_INT,
|
||||
2, { VAL_INT, (INTERP_TYPE)ST_WEAPON },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "weaponLongHitUpgrade", scrWeaponLongHitUpgrade, VAL_INT,
|
||||
2, { VAL_INT, (INTERP_TYPE)ST_WEAPON },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "weaponDamageUpgrade", scrWeaponDamageUpgrade, VAL_INT,
|
||||
2, { VAL_INT, (INTERP_TYPE)ST_WEAPON },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "weaponFirePauseUpgrade", scrWeaponFirePauseUpgrade, VAL_INT,
|
||||
2, { VAL_INT, (INTERP_TYPE)ST_WEAPON },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "isComponentAvailable", scrIsComponentAvailable, VAL_BOOL,
|
||||
2, { VAL_INT, (INTERP_TYPE)ST_COMPONENT },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
{ "getBodySize", scrGetBodySize, VAL_INT,
|
||||
1, { (INTERP_TYPE)ST_BODY },
|
||||
0, 0, NULL, 0, 0, NULL, NULL },
|
||||
|
||||
/* END new functions */
|
||||
|
||||
/* This final entry marks the end of the function list */
|
||||
|
@ -1600,38 +1628,39 @@ VAR_SYMBOL asObjTable[] =
|
|||
{ "selected", VAL_BOOL, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_DROID, OBJID_SELECTED, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
/* Weapon Stats */
|
||||
|
||||
//weapon short range
|
||||
{ "shortRange", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_SHORT_RANGE, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_SHORT_RANGE, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon long range
|
||||
{ "longRange", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_LONG_RANGE, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_LONG_RANGE, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon short hit chance
|
||||
{ "shortHit", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_SHORT_HIT, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_SHORT_HIT, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon long hit chance
|
||||
{ "longHit", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_LONG_HIT, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_LONG_HIT, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon damage
|
||||
{ "damage", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_DAMAGE, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_DAMAGE, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon fire pause
|
||||
{ "firePause", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_FIRE_PAUSE, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_FIRE_PAUSE, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//weapon reload time
|
||||
{ "reloadTime", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_RELOAD_TIME, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_RELOAD_TIME, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
//num of weapon's rounds (salvo fire)
|
||||
{ "numRounds", VAL_INT, ST_OBJECT,
|
||||
(INTERP_TYPE)ST_BASEOBJECT, OBJID_WEAP_NUM_ROUNDS, scrBaseObjGet, NULL, 0, {0}, NULL },
|
||||
(INTERP_TYPE)ST_WEAPON, WEAPID_NUM_ROUNDS, scrWeaponObjGet, NULL, 0, {0}, NULL },
|
||||
|
||||
/* This entry marks the end of the variable list */
|
||||
{ NULL, VAL_VOID, (INTERP_TYPE)ST_OBJECT, VAL_VOID, 0, NULL, NULL, 0, {0}, NULL }
|
||||
|
|
Loading…
Reference in New Issue