Permalink
Browse files

Fix bugs in qtscript research code. Add trigger for research done.

  • Loading branch information...
1 parent a34be21 commit 58b482c4f5fc08d64e7196e4a1d58cab76c27e5c @perim perim committed Dec 26, 2011
Showing with 125 additions and 99 deletions.
  1. +9 −0 src/qtscript.cpp
  2. +1 −0 src/qtscript.h
  3. +33 −22 src/qtscriptfuncs.cpp
  4. +80 −77 src/research.cpp
  5. +2 −0 src/research.h
View
@@ -539,3 +539,12 @@ bool triggerStructureAttacked(STRUCTURE *psVictim, BASE_OBJECT *psAttacker)
}
return true;
}
+
+bool triggerResearched(STRUCTURE *psStruct)
+{
+ QScriptEngine *engine = scripts.at(psStruct->player);
+ QScriptValueList args;
+ args += convStructure(psStruct, engine);
+ callFunction(engine, "eventResearched", args);
+ return true;
+}
View
@@ -70,6 +70,7 @@ bool triggerEvent(SCRIPT_TRIGGER_TYPE trigger);
// For each trigger with function parameters, a function to trigger it here
bool triggerEventDroidBuilt(DROID *psDroid, STRUCTURE *psFactory);
bool triggerStructureAttacked(STRUCTURE *psVictim, BASE_OBJECT *psAttacker);
+bool triggerResearched(STRUCTURE *psStruct);
// bool triggerEventReachedLocation(ORDER order, DROID *psDroid);
// ...
View
@@ -60,7 +60,6 @@ extern std::vector<Vector2i> derricks;
QScriptValue convResearch(RESEARCH *psResearch, QScriptEngine *engine, int player)
{
- PLAYER_RESEARCH *psPlayerResearch = &asPlayerResList[player][psResearch->index];
QScriptValue value = engine->newObject();
value.setProperty("power", (int)psResearch->researchPower);
value.setProperty("points", (int)psResearch->researchPoints);
@@ -70,12 +69,11 @@ QScriptValue convResearch(RESEARCH *psResearch, QScriptEngine *engine, int playe
if (aiCheckAlliances(player, i) || player == i)
{
int bits = asPlayerResList[i][psResearch->index].ResearchStatus;
- started = started || (bits & STARTED_RESEARCH) || (bits & STARTED_RESEARCH_PENDING);
+ started = started || (bits & STARTED_RESEARCH) || (bits & STARTED_RESEARCH_PENDING) || (bits & RESBITS_PENDING_ONLY);
}
}
value.setProperty("started", started); // including whether an ally has started it
- value.setProperty("done", (bool)psPlayerResearch->ResearchStatus & RESEARCHED);
- value.setProperty("possible", (bool)psPlayerResearch->possible);
+ value.setProperty("available", researchAvailable(psResearch->index, player));
value.setProperty("name", psResearch->pName);
return value;
}
@@ -337,32 +335,37 @@ static QScriptValue js_pursueResearch(QScriptContext *context, QScriptEngine *en
RESEARCH_FACILITY *psResLab = (RESEARCH_FACILITY *)psStruct->pFunctionality;
SCRIPT_ASSERT(context, psResLab->psSubject == NULL, "Research lab not ready");
SCRIPT_ASSERT(context, !(plrRes->ResearchStatus & RESEARCHED), "Research item already completed: %s", psResearch->pName);
- SCRIPT_ASSERT(context, !IsResearchStartedPending(plrRes), "Research item already being researched: %s (%d)",
- psResearch->pName, (int)plrRes->ResearchStatus);
+ if (IsResearchStartedPending(plrRes) || IsResearchCompleted(plrRes))
+ {
+ return QScriptValue(false);
+ }
// Go down the requirements list for the desired tech
QList<RESEARCH *> reslist;
RESEARCH *cur = psResearch;
while (cur)
{
- PLAYER_RESEARCH *curPlr = &asPlayerResList[player][cur->index];
- bool started = false;
- for (int i = 0; i < game.maxPlayers; i++)
+ if (researchAvailable(cur->index, player))
{
- if (aiCheckAlliances(player, i) || i == player)
+ bool started = false;
+ for (int i = 0; i < game.maxPlayers; i++)
{
- int bits = asPlayerResList[i][psResearch->index].ResearchStatus;
- started = started || (bits & STARTED_RESEARCH) || (bits & STARTED_RESEARCH_PENDING);
+ if (aiCheckAlliances(player, i) || i == player)
+ {
+ int bits = asPlayerResList[i][cur->index].ResearchStatus;
+ started = started || (bits & STARTED_RESEARCH) || (bits & STARTED_RESEARCH_PENDING)
+ || (bits & RESBITS_PENDING_ONLY) || (bits & RESEARCHED);
+ }
}
- }
- if (curPlr->possible && !started) // found relevant item on the path?
- {
+ if (!started) // found relevant item on the path?
+ {
#if defined (DEBUG)
- char sTemp[128];
- sendResearchStatus(psStruct, cur->index, player, true);
- sprintf(sTemp, "player:%d starts topic from script: %s", player, cur->pName);
- NETlogEntry(sTemp, SYNC_FLAG, 0);
+ char sTemp[128];
+ sendResearchStatus(psStruct, cur->index, player, true);
+ sprintf(sTemp, "player:%d starts topic from script: %s", player, cur->pName);
+ NETlogEntry(sTemp, SYNC_FLAG, 0);
#endif
- return QScriptValue(true);
+ return QScriptValue(true);
+ }
}
RESEARCH *prev = cur;
cur = NULL;
@@ -394,11 +397,19 @@ static QScriptValue js_getResearch(QScriptContext *context, QScriptEngine *engin
static QScriptValue js_enumResearch(QScriptContext *context, QScriptEngine *engine)
{
+ QList<RESEARCH *> reslist;
int player = engine->globalObject().property("me").toInt32();
- QScriptValue result = engine->newArray(asResearch.size());
for (int i = 0; i < asResearch.size(); i++)
{
- result.setProperty(i, convResearch(&asResearch[i], engine, player));
+ if (!IsResearchCompleted(&asPlayerResList[player][i]))
+ {
+ reslist += &asResearch[i];
+ }
+ }
+ QScriptValue result = engine->newArray(reslist.size());
+ for (int i = 0; i < reslist.size(); i++)
+ {
+ result.setProperty(i, convResearch(reslist[i], engine, player));
}
return result;
}
View
@@ -45,6 +45,7 @@
#include "intimage.h"
#include "multiplay.h"
#include "template.h"
+#include "qtscript.h"
//used to calc the research power
#define RESEARCH_FACTOR 32
@@ -596,106 +597,106 @@ bool loadResearchFunctions(const char *pFunctionData, UDWORD bufferSize)
return true;
}
-/*
-Function to check what can be researched for a particular player at any one
-instant.
-
-A topic can be researched if the playerRes 'possible' flag has been set (by script)
-or if the research pre-req topics have been researched. A check is made for any
-structures that are required to have been built for topics that do not have
-the 'possible' flag set.
-
- **NB** A topic with zero PR's can ONLY be researched once the 'possible' flag
- has been set.
-
-There can only be 'limit' number of entries
-'topic' is the currently researched topic
-*/
-// NOTE by AJL may 99 - skirmish now has it's own version of this, skTopicAvail.
-UWORD fillResearchList(UWORD *plist, UDWORD playerID, UWORD topic, UWORD limit)
+bool researchAvailable(int inc, int playerID)
{
- UWORD inc, count=0;
UDWORD incPR, incS;
bool bPRFound, bStructFound;
- for (inc=0; inc < asResearch.size(); inc++)
+ // if its a cancelled topic - add to list
+ if (IsResearchCancelledPending(&asPlayerResList[playerID][inc]))
{
- //if the inc matches the 'topic' - automatically add to the list
- if (inc == topic)
+ return true;
+ }
+ // if the topic is possible and has not already been researched - add to list
+ if ((IsResearchPossible(&asPlayerResList[playerID][inc])))
+ {
+ if (!IsResearchCompleted(&asPlayerResList[playerID][inc])
+ && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
{
- goto add_research;
+ return true;
}
- //if its a cancelled topic - add to list
- if (IsResearchCancelledPending(&asPlayerResList[playerID][inc]))
+ }
+
+ // if single player mode and key topic, then ignore cos can't do it!
+ if (!bMultiPlayer && asResearch[inc].keyTopic)
+ {
+ return false;
+ }
+
+ // make sure that the research is not completed or started by another researchfac
+ if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
+ {
+ // Research is not completed ... also it has not been started by another researchfac
+
+ // if there aren't any PR's - go to next topic
+ if (asResearch[inc].pPRList.empty())
{
- goto add_research;
+ return false;
}
- //if the topic is possible and has not already been researched - add to list
- if ((IsResearchPossible(&asPlayerResList[playerID][inc])))
+
+ // check for pre-requisites
+ bPRFound = true;
+ for (incPR = 0; incPR < asResearch[inc].pPRList.size(); incPR++)
{
- if (!IsResearchCompleted(&asPlayerResList[playerID][inc])
- && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
+ if (IsResearchCompleted(&(asPlayerResList[playerID][asResearch[inc].pPRList[incPR]]))==0)
{
- goto add_research;
+ // if haven't pre-requisite - quit checking rest
+ bPRFound = false;
+ break;
}
}
+ if (!bPRFound)
+ {
+ // if haven't pre-requisites, skip the rest of the checks
+ return false;
+ }
- //if single player mode and key topic, then ignore cos can't do it!
- if (!bMultiPlayer)
-
+ // check for structure effects
+ bStructFound = true;
+ for (incS = 0; incS < asResearch[inc].pStructList.size(); incS++)
{
- if (asResearch[inc].keyTopic)
+ if (!checkSpecificStructExists(asResearch[inc].pStructList[incS], playerID))
{
- continue;
+ //if not built, quit checking
+ bStructFound = false;
+ break;
}
}
-
- // make sure that the research is not completed or started by another researchfac
- if (!IsResearchCompleted(&asPlayerResList[playerID][inc]) && !IsResearchStartedPending(&asPlayerResList[playerID][inc]))
+ if (!bStructFound)
{
- // Research is not completed ... also it has not been started by another researchfac
+ // if haven't all structs built, skip to next topic
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
- //if there aren't any PR's - go to next topic
- if (asResearch[inc].pPRList.empty())
- {
- continue;
- }
+/*
+Function to check what can be researched for a particular player at any one
+instant.
- //check for pre-requisites
- bPRFound = true;
- for (incPR = 0; incPR < asResearch[inc].pPRList.size(); incPR++)
- {
- if (IsResearchCompleted(&(asPlayerResList[playerID][asResearch[inc].pPRList[incPR]]))==0)
- {
- //if haven't pre-requisite - quit checking rest
- bPRFound = false;
- break;
- }
- }
- if (!bPRFound)
- {
- //if haven't pre-requisites, skip the rest of the checks
- continue;
- }
+A topic can be researched if the playerRes 'possible' flag has been set (by script)
+or if the research pre-req topics have been researched. A check is made for any
+structures that are required to have been built for topics that do not have
+the 'possible' flag set.
- //check for structure effects
- bStructFound = true;
- for (incS = 0; incS < asResearch[inc].pStructList.size(); incS++)
- {
- if (!checkSpecificStructExists(asResearch[inc].pStructList[incS], playerID))
- {
- //if not built, quit checking
- bStructFound = false;
- break;
- }
- }
- if (!bStructFound)
- {
- //if haven't all structs built, skip to next topic
- continue;
- }
+ **NB** A topic with zero PR's can ONLY be researched once the 'possible' flag
+ has been set.
+
+There can only be 'limit' number of entries
+'topic' is the currently researched topic
+*/
+// NOTE by AJL may 99 - skirmish now has it's own version of this, skTopicAvail.
+UWORD fillResearchList(UWORD *plist, UDWORD playerID, UWORD topic, UWORD limit)
+{
+ UWORD inc, count=0;
-add_research: //if passed all the tests - add it to the list
+ for (inc=0; inc < asResearch.size(); inc++)
+ {
+ // if the inc matches the 'topic' - automatically add to the list
+ if (inc == topic || researchAvailable(inc, playerID))
+ {
*plist++ = inc;
count++;
if (count == limit)
@@ -1174,6 +1175,8 @@ void researchResult(UDWORD researchIndex, UBYTE player, bool bDisplay, STRUCTURE
psCBLastResStructure = NULL;
CBResFacilityOwner = -1;
psCBLastResearch = NULL;
+
+ triggerResearched(psResearchFacility);
}
#ifdef DEBUG
View
@@ -149,4 +149,6 @@ void CancelAllResearch(UDWORD pl);
extern bool researchInitVars(void);
+bool researchAvailable(int inc, int playerID);
+
#endif // __INCLUDED_SRC_RESEARCH_H__

0 comments on commit 58b482c

Please sign in to comment.