From 0770df9855781afe111f452f82d3d43d2ac33e9b Mon Sep 17 00:00:00 2001 From: Per Inge Mathisen Date: Sun, 1 Jan 2012 15:09:34 +0100 Subject: [PATCH] semperi js: Now builds cyborgs and VTOLs, and sort of defends itself. --- data/base/multiplay/skirmish/rules.js | 23 +++++++ data/base/multiplay/skirmish/semperfi.js | 88 ++++++++++++++++++++++-- src/qtscriptfuncs.cpp | 22 ++++-- 3 files changed, 122 insertions(+), 11 deletions(-) diff --git a/data/base/multiplay/skirmish/rules.js b/data/base/multiplay/skirmish/rules.js index 548be87b204..aee7efd578e 100644 --- a/data/base/multiplay/skirmish/rules.js +++ b/data/base/multiplay/skirmish/rules.js @@ -17,6 +17,29 @@ function eventGameInit() enableStructure("A0ResourceExtractor", playnum); enableStructure("A0PowerGenerator", playnum); enableStructure("A0ResearchFacility", playnum); + + // We need to enable these in order for scripts to be able to generate their templates. + // Cyborg legs is a research that is never researched. The rest are not even present in + // the research system. They should be there as results, along with the bodies. + makeComponentAvailable("CyborgLegs", playnum); + makeComponentAvailable("Cyb-Wpn-Atmiss", playnum); + makeComponentAvailable("CyborgCannon", playnum); + makeComponentAvailable("CyborgChaingun", playnum); + makeComponentAvailable("CyborgFlamer01", playnum); + makeComponentAvailable("Cyb-Wpn-Grenade", playnum); + makeComponentAvailable("Cyb-Hvywpn-A-T", playnum); + makeComponentAvailable("Cyb-Hvywpn-Acannon", playnum); + makeComponentAvailable("Cyb-Hvywpn-HPV", playnum); + makeComponentAvailable("Cyb-Hvywpn-Mcannon", playnum); + makeComponentAvailable("Cyb-Hvywpn-PulseLsr", playnum); + makeComponentAvailable("Cyb-Hvywpn-RailGunner", playnum); + makeComponentAvailable("Cyb-Hvywpn-TK", playnum); + makeComponentAvailable("Cyb-Wpn-Laser", playnum); + makeComponentAvailable("Cyb-Wpn-Rail1", playnum); + makeComponentAvailable("CyborgRocket", playnum); + makeComponentAvailable("CyborgRotMG", playnum); + makeComponentAvailable("Cyb-Wpn-Thermite", playnum); + makeComponentAvailable("CyborgFlamer01", playnum); setStructureLimits("A0LightFactory", 5, playnum); // set structure limits setStructureLimits("A0PowerGenerator", 8, playnum); diff --git a/data/base/multiplay/skirmish/semperfi.js b/data/base/multiplay/skirmish/semperfi.js index 811e23216de..5bef25ce8ba 100644 --- a/data/base/multiplay/skirmish/semperfi.js +++ b/data/base/multiplay/skirmish/semperfi.js @@ -10,6 +10,9 @@ const playerHQ = "A0CommandCentre"; const vtolPad = "A0VtolPad"; const vtolFactory = "A0VTolFactory1"; const sensorTower = "Sys-SensoTower02"; +const powModule = "A0PowMod1"; +const facModule = "A0FacMod1"; +const resModule = "A0ResearchModule1"; // --- utility functions @@ -48,6 +51,41 @@ function buildTruck(struct) } } +function buildCyborg(struct) +{ + // Cyborg templates are special -- their bodies, legs and weapons are linked. We should fix this one day... + if (!buildDroid(struct, "Cyborg Thermite", "Cyb-Bod-Thermite", "CyborgLegs", "", DROID_CYBORG, "Cyb-Wpn-Thermite")) + { + if (!buildDroid(struct, "Cyborg Flamer", "CyborgFlamerGrd", "CyborgLegs", "", DROID_CYBORG, "CyborgFlamer01")) + { + if (!buildDroid(struct, "Cyborg MG", "CyborgChain1Ground", "CyborgLegs", "", DROID_CYBORG, "CyborgChaingun")) + { + debug("Failed to construct new cyborg"); + } + } + } +} + +function buildVTOL(struct) +{ + var bomblist = [ + "Bomb3-VTOL-LtINC", // phosphor bomb + "Bomb4-VTOL-HvyINC", // thermite bomb + "Bomb5-VTOL-Plasmite", // plasmite bomb + ]; + var bodylist = [ + "Body7ABT", // retribution + "Body8MBT", // scorpion + "Body5REC", // cobra + "Body4ABT", // bug + "Body1REC", // viper + ]; + if (!buildDroid(struct, "Bomber", bodylist, "V-Tol", "", DROID_WEAPON, bomblist)) + { + debug("Failed to construct new VTOL"); + } +} + // If positive, there are oil derricks that unused due to lack of power generators. // If negative, we have too many power generator (usually not a problem in itself). function numUnusedDerricks() @@ -210,13 +248,31 @@ function eventStructureBuilt(struct, droid) { eventDroidBuilt(null, struct); } + else if (struct.stattype == POWER_GEN && droid) + { + if (isStructureAvailable(powModule, me)) // Immediately upgrade it, if possible + { + orderDroidStatsLoc(droid, DORDER_BUILD, powModule, struct.x, struct.y); + } + } } function eventDroidBuilt(droid, struct) { if (struct) { - buildTruck(struct); + if (struct.stattype == FACTORY) + { + buildTruck(struct); + } + else if (struct.stattype == CYBORG_FACTORY) + { + buildCyborg(struct); + } + else if (struct.stattype == VTOL_FACTORY) + { + buildVTOL(struct); + } } } @@ -226,21 +282,43 @@ function eventGameInit() function eventAttacked(victim, attacker) { + // TBD, for now -- SEND EVERYONE!!! + if (attacker) + { + var i; + var defenders = enumDroid(me, DROID_WEAPON); + for (i = 0; i < defenders.length; i++) + { + orderDroidObj(defenders[i], DORDER_ATTACK, attacker); + } + var cyborgs = enumDroid(me, DROID_CYBORG); + for (i = 0; i < cyborgs.length; i++) + { + orderDroidObj(cyborgs[i], DORDER_ATTACK, attacker); + } + } } function eventStartLevel() { - queue("conDroids"); - queue("eventResearched"); + // Pretend like all buildings were just produced, to initiate productions + var structlist = enumStruct(me); + for (var i = 0; i < structlist.length; i++) + { + eventStructureBuilt(structlist[i]); + } + + // Make missing buildings queue("buildFundamentals"); + /* if (numFactories() > 1 && isStructureAvailable(defStructs[0], me) && playerData[me].difficulty > MEDIUM) { dbgPlr("TRUCK RUSH!"); - next("truckRush"); + queue("truckRush"); } else { - next("buildFundamentals"); + queue("buildFundamentals"); }*/ } diff --git a/src/qtscriptfuncs.cpp b/src/qtscriptfuncs.cpp index 73001d28831..07eeab7ecec 100644 --- a/src/qtscriptfuncs.cpp +++ b/src/qtscriptfuncs.cpp @@ -146,17 +146,22 @@ QScriptValue convFeature(FEATURE *psFeature, QScriptEngine *engine) //;; \item[DORDER_REPAIR] Order a droid to repair something. //;; \item[DORDER_RETREAT] Order a droid to retreat back to HQ. //;; \item[DORDER_PATROL] Order a droid to patrol. -//;; \item[DORDER_BUILDMODULE] Order a droid to build a module. //;; \end{description} //;; \item[action] The current action of the droid. This is how it intends to carry out its plan. The //;; C++ code may change the action frequently as it tries to carry out its order. You never want to set //;; the action directly, but it may be interesting to look at what it currently is. +//;; \item[group] The group this droid is member of. This is a numerical ID. If not a member of any group, +//;; this value is not set. Always check if set before use. //;; \end{description} QScriptValue convDroid(DROID *psDroid, QScriptEngine *engine) { QScriptValue value = convObj(psDroid, engine); value.setProperty("action", (int)psDroid->action, QScriptValue::ReadOnly); value.setProperty("order", (int)psDroid->order.type, QScriptValue::ReadOnly); + if (psDroid->psGroup) + { + value.setProperty("group", (int)psDroid->psGroup->id, QScriptValue::ReadOnly); + } return value; } @@ -185,7 +190,7 @@ QScriptValue convObj(BASE_OBJECT *psObj, QScriptEngine *engine) value.setProperty("player", psObj->player, QScriptValue::ReadOnly); value.setProperty("type", psObj->type, QScriptValue::ReadOnly); value.setProperty("selected", psObj->selected, QScriptValue::ReadOnly); - value.setProperty("name", objInfo(psObj)); + value.setProperty("name", objInfo(psObj), QScriptValue::ReadOnly); return value; } @@ -382,7 +387,7 @@ static QScriptValue js_enumGroup(QScriptContext *context, QScriptEngine *engine) } //-- \subsection{newGroup()} -//-- Allocate a new group. +//-- Allocate a new group. Returns its numerical ID. static QScriptValue js_newGroup(QScriptContext *, QScriptEngine *) { DROID_GROUP *newGrp = grpCreate(); @@ -587,10 +592,16 @@ static QScriptValue js_buildDroid(QScriptContext *context, QScriptEngine *engine memset(psTemplate->asParts, 0, sizeof(psTemplate->asParts)); // reset to defaults memset(psTemplate->asWeaps, 0, sizeof(psTemplate->asWeaps)); int body = get_first_available_component(player, context->argument(2), COMP_BODY); + if (body < 0) + { + debug(LOG_SCRIPT, "Wanted to build %s at %s, but body type all unavailable", + templName.toUtf8().constData(), objInfo(psStruct)); + return QScriptValue(false); // no component available + } int prop = get_first_available_component(player, context->argument(3), COMP_PROPULSION); - if (body < 0 || prop < 0) + if (prop < 0) { - debug(LOG_SCRIPT, "Wanted to build %s at %s, but component type all unavailable", + debug(LOG_SCRIPT, "Wanted to build %s at %s, but propulsion type all unavailable", templName.toUtf8().constData(), objInfo(psStruct)); return QScriptValue(false); // no component available } @@ -1544,7 +1555,6 @@ bool registerFunctions(QScriptEngine *engine) engine->globalObject().setProperty("DORDER_REPAIR", DORDER_REPAIR, QScriptValue::ReadOnly | QScriptValue::Undeletable); engine->globalObject().setProperty("DORDER_RETREAT", DORDER_RETREAT, QScriptValue::ReadOnly | QScriptValue::Undeletable); engine->globalObject().setProperty("DORDER_PATROL", DORDER_PATROL, QScriptValue::ReadOnly | QScriptValue::Undeletable); - engine->globalObject().setProperty("DORDER_BUILDMODULE", DORDER_BUILDMODULE, QScriptValue::ReadOnly | QScriptValue::Undeletable); engine->globalObject().setProperty("COMMAND", IDRET_COMMAND, QScriptValue::ReadOnly | QScriptValue::Undeletable); engine->globalObject().setProperty("OPTIONS", IDRET_COMMAND, QScriptValue::ReadOnly | QScriptValue::Undeletable); engine->globalObject().setProperty("BUILD", IDRET_BUILD, QScriptValue::ReadOnly | QScriptValue::Undeletable);