From f30c15bf20fd277279904e2eab7a59ebe234e029 Mon Sep 17 00:00:00 2001 From: Per Inge Mathisen Date: Sat, 22 Jan 2011 14:00:13 +0100 Subject: [PATCH] New script function BASEOBJ getDerrick(int) that returns indexed derrick objects. Can be iterated until it returns a NULLOBJECT. Modify semperfi to use this function for attacks of opportunity against undefended oil derricks. --- data/base/multiplay/skirmish/semperfi.slo | 28 ++++++++++++++++- src/game.cpp | 8 +++++ src/scriptfuncs.cpp | 37 +++++++++++++++++++++++ src/scriptfuncs.h | 3 ++ src/scripttabs.cpp | 4 +++ 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/data/base/multiplay/skirmish/semperfi.slo b/data/base/multiplay/skirmish/semperfi.slo index eb317ad74..538349cb6 100644 --- a/data/base/multiplay/skirmish/semperfi.slo +++ b/data/base/multiplay/skirmish/semperfi.slo @@ -2413,7 +2413,31 @@ event findEnemy(attackStuffTr) // send attack team out to cause trouble near things scout found. event attackStuff(attackStuffTr) { - if( idleGroup(attackGroup) >= (attackGroup.members / 2)) + local int i, x, y; + local BASEOBJ result, best; + + // Attacks of opportunity + i = 0; + result = getDerrick(i); + best = NULLOBJECT; + while (result != NULLOBJECT) + { + if (result.type == OBJ_STRUCTURE and result.player != me and safeDest(me, result.x, result.y)) + { + best = result; // easy pickings + } + i++; + result = getDerrick(i); + } + if (best != NULLOBJECT) + { + dbgPlr("MOVEMENT OF OPPORTUNITY"); + orderGroupLoc(attackGroup, DORDER_SCOUT, best.x, best.y); + exit; + } + + // Regular attacks + if (idleGroup(attackGroup) >= (attackGroup.members / 2)) { if( (attackObj != NULLOBJECT) and (not helpingAlly()) ) { @@ -2445,7 +2469,9 @@ event doAllOutAttack(allOutAttackTr) { if (getDroidCount(me) > 40) // plenty of units. { + dbgPlr("ALL OUT ATTACK!"); orderGroupObj(attackGroup, DORDER_ATTACK, allOutAttack); + orderGroupObj(defendGroup, DORDER_ATTACK, allOutAttack); orderGroupLoc(scoutGroup, DORDER_SCOUT, allOutAttack.x, allOutAttack.y); } } diff --git a/src/game.cpp b/src/game.cpp index e86b639fe..5a56c867f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -6204,6 +6204,10 @@ BOOL loadSaveStructureV7(char *pFileData, UDWORD filesize, UDWORD numStructures) { scriptSetStartPos(psSaveStructure->player, psStructure->pos.x, psStructure->pos.y); } + else if (psStructure->pStructureType->type == REF_RESOURCE_EXTRACTOR) + { + scriptSetDerrickPos(psStructure->pos.x, psStructure->pos.y); + } //if not a save game, don't want to overwrite any of the stats so continue if (gameType != GTYPE_SAVE_START) @@ -7215,6 +7219,10 @@ BOOL loadSaveFeatureV14(char *pFileData, UDWORD filesize, UDWORD numFeatures, UD debug(LOG_ERROR, "Unable to create feature %s", psSaveFeature->name); continue; } + if (pFeature->psStats->subType == FEAT_OIL_RESOURCE) + { + scriptSetDerrickPos(pFeature->pos.x, pFeature->pos.y); + } //restore values pFeature->id = psSaveFeature->id; pFeature->rot.direction = DEG(psSaveFeature->direction); diff --git a/src/scriptfuncs.cpp b/src/scriptfuncs.cpp index 7ebf2bb38..cb752a87c 100644 --- a/src/scriptfuncs.cpp +++ b/src/scriptfuncs.cpp @@ -112,6 +112,7 @@ static DROID_TEMPLATE* scrCheckTemplateExists(SDWORD player, DROID_TEMPLATE *psT /// Hold the previously assigned player static Vector2i positions[MAX_PLAYERS]; +std::vector derricks; void scriptSetStartPos(int position, int x, int y) { @@ -120,6 +121,12 @@ void scriptSetStartPos(int position, int x, int y) debug(LOG_SCRIPT, "Setting start position %d to (%d, %d)", position, x, y); } +void scriptSetDerrickPos(int x, int y) +{ + Vector2i pos(x, y); + derricks.push_back(pos); +} + BOOL scriptInit() { int i; @@ -128,6 +135,8 @@ BOOL scriptInit() { scriptSetStartPos(i, 0, 0); } + derricks.clear(); + derricks.reserve(8 * MAX_PLAYERS); return true; } @@ -175,6 +184,34 @@ BOOL scrGetPlayer() return true; } +BOOL scrGetDerrick() +{ + int x, y, i; + + if (!stackPopParams(1, VAL_INT, &i)) + { + debug(LOG_ERROR, "stack failed"); + return false; + } + scrFunctionResult.v.oval = NULL; + if (i < (int)derricks.size()) + { + x = derricks[i].x; + y = derricks[i].y; + MAPTILE *psTile = worldTile(x, y); + if (psTile) + { + scrFunctionResult.v.oval = psTile->psObject; + } + } + if (!stackPushResult((INTERP_TYPE)ST_STRUCTURE, &scrFunctionResult)) + { + ASSERT(false, "Failed to push result"); + return false; + } + return true; +} + Vector2i getPlayerStartPosition(int player) { return positions[player]; diff --git a/src/scriptfuncs.h b/src/scriptfuncs.h index bb1f28db5..ef5d5c244 100644 --- a/src/scriptfuncs.h +++ b/src/scriptfuncs.h @@ -36,7 +36,10 @@ struct DROID; extern BOOL scriptInit(void); extern void scriptSetStartPos(int position, int x, int y); +extern void scriptSetDerrickPos(int x, int y); + extern BOOL scrGetPlayer(void); +extern BOOL scrGetDerrick(); extern BOOL scrGetDifficulty(void); extern BOOL scrScavengersActive(void); extern BOOL scrGetPlayerStartPosition(void); diff --git a/src/scripttabs.cpp b/src/scripttabs.cpp index 0487c20ef..3ae7b285c 100644 --- a/src/scripttabs.cpp +++ b/src/scripttabs.cpp @@ -1459,6 +1459,10 @@ FUNC_SYMBOL asFuncTable[] = 1, { VAL_INT }, false, 0, NULL, 0, 0, NULL, NULL }, + { "getDerrick", scrGetDerrick, (INTERP_TYPE)ST_BASEOBJECT, + 1, { VAL_INT }, + false, 0, NULL, 0, 0, NULL, NULL }, + /* This final entry marks the end of the function list */ { "FUNCTION LIST END", NULL, VAL_VOID, 0, { VAL_VOID }, 0, 0, NULL, 0, 0, NULL, NULL } };