/*----------------------------------------------------------------------------- Name : rmTechRequiredForShip Description : This function returns the number of research topics required to build the ship specified Inputs : player and shiptype Outputs : number of research topics required Return : sdword ----------------------------------------------------------------------------*/ sdword rmTechRequiredForShip(Player *player, ShipType type) { sdword i, numtech=0; udword techneeded, temp; temp = player->researchinfo.techstat->TechNeededToBuildShip[type]; techneeded = temp; for (i=0; i<NumTechnologies; i++) { if (bitTest(temp, TechToBit(i))) { techneeded |= rmAllTechRequiredforTech(player, i); } } techneeded &= (~player->researchinfo.HasTechnology); for (i=0; i<NumTechnologies; i++) { if (bitTest(techneeded, TechToBit(i))) { numtech++; } } return (numtech); }
/*----------------------------------------------------------------------------- Name : rmGiveTechToPlayerByType Description : Gives player technology 'techName' and all previous technologies needed to get it Inputs : player - player to get tech techName - name of technology as defined in Outputs : Return : ----------------------------------------------------------------------------*/ void rmGiveTechToPlayerByType(struct Player *player, TechnologyType techtype) { TechnologyType techCanGet; PlayerResearchInfo *research; research = &player->researchinfo; while(1) { techCanGet = rmTechRequiredForTech(player, techtype); if(techCanGet == 0) { //no more dependant tech to give //so give main tech and return; research->HasTechnology |= TechToBit(techtype); return; } research->HasTechnology |= TechToBit(techCanGet); } }
/*----------------------------------------------------------------------------- Name : rmRemoveUnneededTech Description : Removes any technology that when researched gives nothing! Inputs : Pointer to the TechStatics to be modified. Outputs : void Return : none ----------------------------------------------------------------------------*/ void rmRemoveUnneededTech(TechStatics *techstat) { udword i,j,k, tech, techtmp; bool notneeded; // for (i=0; i < STD_LAST_SHIP; i++) // for all ships { tech = techstat->TechNeededToBuildShip[i]; if (bitTest(tech,RM_Disabled)) // is ship disabled ? { for (j=0; j < NumTechnologies; j++) // for all technologies needed to build this ship. { notneeded = TRUE; if (bitTest(tech,TechToBit(j))) { for (k=0; k < STD_LAST_SHIP; k ++) { techtmp = techstat->TechNeededToBuildShip[k]; if ((!(bitTest(techtmp,RM_Disabled))) &&(k != i)) { if (bitTest(techtmp,TechToBit(j))) { notneeded = FALSE; } } } if (notneeded) { techstat->TechNeededToResearch[j] |= RM_Disabled; } } } } } }
/*----------------------------------------------------------------------------- Name : rmSetTechDependCB Description : sets the technology dependancies based on a list of strings Inputs : standard callback inputs Outputs : none Return : void ----------------------------------------------------------------------------*/ void rmSetTechDependCB(char *directory, char *field, void *dataToFillIn) { sdword index; char temp[64]; TechnologyType techtype, techset; udword mask=0; for (index=0; *field != ' '; index++,field++) { temp[index]=*field; } temp[index]=0; while ((*field == ' ') && (*field != 0)) field++; if (*field == 0) return; if (*field != 0) { RemoveCommasFromString(field); techset = StrToTechType(temp); dbgAssert(techset!=-1); while (*field != 0) { for (index=0; (*field != ' ')&&(*field != 0); index++,field++) { temp[index]=*field; } temp[index]=0; techtype = StrToTechType(temp); dbgAssert(techtype != -1); mask |= TechToBit(techtype); while (*field == ' ') field++; } } ((udword *)dataToFillIn)[techset] = mask; }
/*----------------------------------------------------------------------- Name : rmAllTechRequiredforTech Description : Returns all of the technology needed to research a tech Inputs : player techtype Outputs : technology bitmask Parameters : Player *player, TechnologyType type Return : udword -----------------------------------------------------------------------*/ udword rmAllTechRequiredforTech(Player *player, TechnologyType type) { udword i, numtech=0; udword techdepend,temp; techdepend = temp = player->researchinfo.techstat->TechNeededToResearch[type]; for (i=0; i<NumTechnologies; i--) { if (bitTest(temp, TechToBit(i))) { techdepend |= rmAllTechRequiredforTech(player, i); } } return (techdepend); }
udword rmTechRequiredForTech(Player *player, TechnologyType type) { sdword i, numtech=0; udword techdepend, temp; temp=player->researchinfo.techstat->TechNeededToResearch[type]; techdepend = temp & player->researchinfo.HasTechnology; techdepend ^= temp; for (i=NumTechnologies; i>=0; i--) { if (bitTest(techdepend, TechToBit(i))) { return (i); } } return (0); }
/*----------------------------------------------------------------------------- Name : rmResearchTechForShip Description : This function researches technology required to build a ship. Inputs : player and shiptype Outputs : none Return : void ----------------------------------------------------------------------------*/ bool rmResearchTechForShip(struct Player *player, ShipType type) { udword techforship = player->researchinfo.techstat->TechNeededToBuildShip[type]; udword numtech, techneeded; sdword freelab; sdword techtoresearch = -1; sdword i; bool researching = FALSE; numtech = rmTechRequiredForShip(player, type); if (numtech > 0) { techneeded = rmAllTechRequredForShip(player, type); for (i=0; i<NumTechnologies; i++) { if (bitTest(techneeded, TechToBit((udword)i))) { if ((player->researchinfo.techstat->TechNeededToResearch[i]&(~player->researchinfo.HasTechnology)) == 0) { techtoresearch = i; freelab = rmFindFreeLab(player); if (freelab != -1) { rmAssignPlayersLabToResearch(player,freelab, techtoresearch); researching = TRUE; } } } } } if (techtoresearch != -1) { while ((freelab = rmFindFreeLab(player))!=-1) { rmAssignPlayersLabToResearch(player,freelab, techtoresearch); researching = TRUE; } } return researching; }
/*----------------------------------------------------------------------------- Name : tmAcceptOffer Description : Callback function to accept the offered technologies Inputs : Outputs : Get the technologies Return : ----------------------------------------------------------------------------*/ void tmAcceptOffer(char *string, featom *atom) { udword price; if (tmTechSelected == -1) return; price = (tmTechPrice[tmTechSelected] * tmPriceScale) / 100; #if TM_VERBOSE_LEVEL >= 1 dbgMessagef("Received the technologies..."); #endif //if the player can't afford the technology selected, bugger out. if (price > universe.curPlayerPtr->resourceUnits) { tmDialogPhrase = DialogCantAffordThat; tmDirtyTechInfo(); return; } universe.curPlayerPtr->resourceUnits -= price; tmTechForSale[tmTechSelected] = TM_TECH_IS_ALREADY_OWNED; //rmAddTechToPlayer(universe.curPlayerPtr, tmTechSelected); universe.curPlayerPtr->researchinfo.HasTechnology |= TechToBit(tmTechSelected); tmtechinfo = -1; tmTechSelected = -1; if (tmStuffToBuy) { tmDialogPhrase = DialogPurchaseMade; //"want some more?" } else { tmDialogPhrase = DialogCantAffordAnything; //"bye!" } tmDirtyTechInfo(); }
sdword rmNumTechRequiredForTech(Player *player, TechnologyType type) { sdword i, numtech=0; udword techdepend, temp; temp=player->researchinfo.techstat->TechNeededToResearch[type]; techdepend = temp & player->researchinfo.HasTechnology; techdepend ^= temp; for (i=0; i<NumTechnologies; i++) { if (bitTest(techdepend, TechToBit(i))) { if ((temp=player->researchinfo.techstat->TechNeededToResearch[i])!=0) { numtech += rmNumTechRequiredForTech(player, i); } numtech ++; } } return (numtech); }
/*----------------------------------------------------------------------------- Name : rmUpdateResearch Description : updates all research Inputs : none Outputs : none Return : void ----------------------------------------------------------------------------*/ void rmUpdateResearch(void) { sdword index, labindex, i; ResearchLab *lab; PlayerResearchInfo *research; ResearchTopic *topic; Node *walk; LinkedList deletelist; bool shipcanbuild[STD_LAST_SHIP]; listInit(&deletelist); // search through list of players for (index=0; index<universe.numPlayers; index++) { research = &universe.players[index].researchinfo; if (research->CanDoResearch) { walk = research->listoftopics.head; // walk through list of topics being researched while (walk != NULL) { topic = (ResearchTopic *)listGetStructOfNode(walk); topic->timeleft -= labdec[topic->numlabsresearching]; if (topic->timeleft < 0) { for (i = 0; i < STD_LAST_SHIP; i++) { shipcanbuild[i] = rmCanBuildShip(&(universe.players[index]), i); } // Insert sound for technology completed if (universe.players[index].race == R1) { speechEventFleet(STAT_F_Research_R1_Completed, topic->techresearch, index); } else if (universe.players[index].race == R2) { speechEventFleet(STAT_F_Research_R2_Completed, topic->techresearch, index); } topic->timeleft = 0; research->HasTechnology |= TechToBit(topic->techresearch); listRemoveNode(&topic->link); listAddNode(&deletelist,&topic->link,topic); for (labindex=0; labindex<NUM_RESEARCHLABS; labindex++) { lab = &research->researchlabs[labindex]; if (lab->topic==topic) { lab->labstatus = LS_NORESEARCHITEM; lab->topic = NULL; if (rmGUIActive) rmClearLab(labindex); } } for (i = 0; i < STD_LAST_SHIP; i++) { if (shipcanbuild[i] != rmCanBuildShip(&(universe.players[index]), i)) { speechEventFleet(STAT_F_Research_CompletedShip, i, index); if (cmActive) { cmUpdateShipsAvailable(); } } } if (singlePlayerGame && (index == 0)) { tmTechForSale[topic->techresearch] = TM_TECH_IS_ALREADY_OWNED; } if (rmGUIActive) rmUpdateTechList(); } walk = walk->next; } listDeleteAll(&deletelist); } } }