void requestAlliance(uint8_t from, uint8_t to, BOOL prop, BOOL allowAudio) { alliances[from][to] = ALLIANCE_REQUESTED; // We've asked alliances[to][from] = ALLIANCE_INVITATION; // They've been invited CBallFrom = from; CBallTo = to; eventFireCallbackTrigger((TRIGGER_TYPE) CALL_ALLIANCEOFFER); if (to == selectedPlayer) { CONPRINTF(ConsoleString,(ConsoleString,_("%s Requests An Alliance With You"),getPlayerName(from))); if (allowAudio) { audio_QueueTrack(ID_ALLIANCE_OFF); } } else if (from == selectedPlayer) { CONPRINTF(ConsoleString,(ConsoleString,_("You Invite %s To Form An Alliance"),getPlayerName(to))); if (allowAudio) { audio_QueueTrack(ID_ALLIANCE_OFF); } } if (prop) { sendAlliance(from, to, ALLIANCE_REQUESTED, false); } }
void requestAlliance(uint8_t from, uint8_t to, bool prop, bool allowAudio) { if (prop && bMultiMessages) { sendAlliance(from, to, ALLIANCE_REQUESTED, false); return; // Wait for our message. } syncDebug("Request alliance %d %d", from, to); alliances[from][to] = ALLIANCE_REQUESTED; // We've asked alliances[to][from] = ALLIANCE_INVITATION; // They've been invited CBallFrom = from; CBallTo = to; eventFireCallbackTrigger((TRIGGER_TYPE) CALL_ALLIANCEOFFER); if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Requests An Alliance With You"), getPlayerName(from))); if (allowAudio) { audio_QueueTrack(ID_ALLIANCE_OFF); } } else if (from == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("You Invite %s To Form An Alliance"), getPlayerName(to))); if (allowAudio) { audio_QueueTrack(ID_ALLIANCE_OFF); } } }
void breakAlliance(uint8_t p1, uint8_t p2, BOOL prop, BOOL allowAudio) { char tm1[128]; if (alliances[p1][p2] == ALLIANCE_FORMED) { sstrcpy(tm1, getPlayerName(p1)); CONPRINTF(ConsoleString,(ConsoleString,_("%s Breaks The Alliance With %s"),tm1,getPlayerName(p2) )); if (allowAudio && (p1 == selectedPlayer || p2 == selectedPlayer)) { audio_QueueTrack(ID_ALLIANCE_BRO); } } alliances[p1][p2] = ALLIANCE_BROKEN; alliances[p2][p1] = ALLIANCE_BROKEN; alliancebits[p1] &= ~(1 << p2); alliancebits[p2] &= ~(1 << p1); if (prop) { sendAlliance(p1, p2, ALLIANCE_BROKEN, false); } }
// //////////////////////////////////////////////////////////////////////////// // give Power void giftPower(uint8_t from, uint8_t to, BOOL send) { UDWORD gifval; uint32_t dummy = 0; if (from == ANYPLAYER) { gifval = OILDRUM_POWER; } else { // Give 1/3 of our power away gifval = getPower(from) / 3; usePower(from, gifval); } addPower(to, gifval); if (send) { uint8_t giftType = POWER_GIFT; NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&dummy); NETend(); } else if (to == selectedPlayer) { CONPRINTF(ConsoleString,(ConsoleString,_("%s Gives You %u Power"),getPlayerName(from),gifval)); } }
// /////////////////////////////////////////////////////////////// void giftArtifact(UDWORD owner, UDWORD x, UDWORD y) { PLAYER_RESEARCH *pR = asPlayerResList[selectedPlayer]; if (owner < MAX_PLAYERS) { PLAYER_RESEARCH *pO = asPlayerResList[owner]; int topic; for (topic = numResearch - 1; topic >= 0; topic--) { if (IsResearchCompleted(&pO[topic]) && !IsResearchPossible(&pR[topic])) { // Make sure the topic can be researched if (asResearch[topic].researchPower && asResearch[topic].researchPoints) { MakeResearchPossible(&pR[topic]); CONPRINTF(ConsoleString,(ConsoleString,_("You Discover Blueprints For %s"), getName(asResearch[topic].pName))); break; } // Invalid topic else { debug(LOG_WARNING, "%s is a invalid research topic?", getName(asResearch[topic].pName)); } } } } }
// /////////////////////////////////////////////////////////////// bool pickupArtefact(int toPlayer, int fromPlayer) { if (fromPlayer < MAX_PLAYERS && bMultiPlayer) { for (int topic = asResearch.size() - 1; topic >= 0; topic--) { if (IsResearchCompleted(&asPlayerResList[fromPlayer][topic]) && !IsResearchPossible(&asPlayerResList[toPlayer][topic])) { // Make sure the topic can be researched if (asResearch[topic].researchPower && asResearch[topic].researchPoints) { MakeResearchPossible(&asPlayerResList[toPlayer][topic]); if (toPlayer == selectedPlayer) { CONPRINTF(ConsoleString,(ConsoleString,_("You Discover Blueprints For %s"), getName(asResearch[topic].pName))); } break; } // Invalid topic else { debug(LOG_WARNING, "%s is a invalid research topic?", getName(asResearch[topic].pName)); } } } audio_QueueTrack(ID_SOUND_ARTIFACT_RECOVERED); return true; } return false; }
void formAlliance(uint8_t p1, uint8_t p2, bool prop, bool allowAudio, bool allowNotification) { DROID *psDroid; char tm1[128]; if (bMultiMessages && prop) { sendAlliance(p1, p2, ALLIANCE_FORMED, false); return; // Wait for our message. } // Don't add message if already allied if (bMultiPlayer && alliances[p1][p2] != ALLIANCE_FORMED && allowNotification) { sstrcpy(tm1, getPlayerName(p1)); CONPRINTF(ConsoleString, (ConsoleString, _("%s Forms An Alliance With %s"), tm1, getPlayerName(p2))); } syncDebug("Form alliance %d %d", p1, p2); triggerEventAllianceAccepted(p1, p2); alliances[p1][p2] = ALLIANCE_FORMED; alliances[p2][p1] = ALLIANCE_FORMED; if (bMultiPlayer && alliancesSharedVision(game.alliance)) // this is for shared vision only { alliancebits[p1] |= 1 << p2; alliancebits[p2] |= 1 << p1; } if (allowAudio && (p1 == selectedPlayer || p2 == selectedPlayer)) { audio_QueueTrack(ID_ALLIANCE_ACC); } // Not campaign and alliances are transitive if (bMultiPlayer && alliancesSharedVision(game.alliance)) { giftRadar(p1, p2, false); giftRadar(p2, p1, false); } // Clear out any attacking orders for (psDroid = apsDroidLists[p1]; psDroid; psDroid = psDroid->psNext) // from -> to { if (psDroid->order.type == DORDER_ATTACK && psDroid->order.psObj && psDroid->order.psObj->player == p2) { orderDroid(psDroid, DORDER_STOP, ModeImmediate); } } for (psDroid = apsDroidLists[p2]; psDroid; psDroid = psDroid->psNext) // to -> from { if (psDroid->order.type == DORDER_ATTACK && psDroid->order.psObj && psDroid->order.psObj->player == p1) { orderDroid(psDroid, DORDER_STOP, ModeImmediate); } } }
// //////////////////////////////////////////////////////////////////////////// // give technologies. static void giftResearch(uint8_t from, uint8_t to, bool send) { int i; uint32_t dummy = 0; if (send) { uint8_t giftType = RESEARCH_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&dummy); NETend(); } else if (alliancesCanGiveResearchAndRadar(game.alliance)) { if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You Technology Documents"), getPlayerName(from))); } // For each topic for (i = 0; i < asResearch.size(); i++) { // If they have it and we don't research it if (IsResearchCompleted(&asPlayerResList[from][i]) && !IsResearchCompleted(&asPlayerResList[to][i])) { MakeResearchCompleted(&asPlayerResList[to][i]); researchResult(i, to, false, NULL, true); } } } }
static void giftAutoGame(uint8_t from, uint8_t to, bool send) { uint32_t dummy = 0; if (send) { uint8_t subType = AUTOGAME_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&subType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&dummy); NETend(); debug(LOG_SYNC, "We (%d) are telling %d we want to enable/disable a autogame", from, to); } // If we are recieving the "gift" else { if (to == selectedPlayer) { NetPlay.players[from].autoGame = !NetPlay.players[from].autoGame ; CONPRINTF(ConsoleString, (ConsoleString, "%s has %s the autoGame command", getPlayerName(from), NetPlay.players[from].autoGame ? "Enabled" : "Disabled")); debug(LOG_SYNC, "We (%d) are being told that %d has %s autogame", selectedPlayer, from, NetPlay.players[from].autoGame ? "Enabled" : "Disabled"); } } }
// //////////////////////////////////////////////////////////////////////////// // give radar information void giftRadar(uint8_t from, uint8_t to, bool send) { uint32_t dummy = 0; if (send) { uint8_t subType = RADAR_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&subType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&dummy); NETend(); } // If we are recieving the gift else { hqReward(from, to); if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You A Visibility Report"), getPlayerName(from))); } } }
void breakAlliance(uint8_t p1, uint8_t p2, bool prop, bool allowAudio) { char tm1[128]; if (prop && bMultiMessages) { sendAlliance(p1, p2, ALLIANCE_BROKEN, false); return; // Wait for our message. } if (alliances[p1][p2] == ALLIANCE_FORMED) { sstrcpy(tm1, getPlayerName(p1)); CONPRINTF(ConsoleString, (ConsoleString, _("%s Breaks The Alliance With %s"), tm1, getPlayerName(p2))); if (allowAudio && (p1 == selectedPlayer || p2 == selectedPlayer)) { audio_QueueTrack(ID_ALLIANCE_BRO); } } syncDebug("Break alliance %d %d", p1, p2); alliances[p1][p2] = ALLIANCE_BROKEN; alliances[p2][p1] = ALLIANCE_BROKEN; alliancebits[p1] &= ~(1 << p2); alliancebits[p2] &= ~(1 << p1); }
/** print out information about a general component * \param psStats the component to print the info for */ static void printComponentInfo(const COMPONENT_STATS *psStats) { CONPRINTF(ConsoleString, (ConsoleString, "%s ref %d\n" " bPwr %d bPnts %d wt %d bdy %d imd %p\n", getName(psStats), psStats->ref, psStats->buildPower, psStats->buildPoints, psStats->weight, psStats->pBase->hitpoints, psStats->pIMD)); }
// sendGiftDroids() // We give selected droid(s) as a gift to another player. // // \param from :player that sent us the droid // \param to :player that should be getting the droid static void sendGiftDroids(uint8_t from, uint8_t to) { DROID *next, *psD; uint8_t giftType = DROID_GIFT; uint8_t totalToSend; if (apsDroidLists[from] == NULL) { return; } /* * Work out the number of droids to send. As well as making sure they are * selected we also need to make sure they will NOT put the receiving player * over their droid limit. */ for (totalToSend = 0, psD = apsDroidLists[from]; psD && getNumDroids(to) + totalToSend < getMaxDroids(to) && totalToSend != UINT8_MAX; psD = psD->psNext) { if (psD->selected) ++totalToSend; } /* * We must send one droid at a time, due to the fact that giftSingleDroid() * does its own net calls. */ for (psD = apsDroidLists[from]; psD && totalToSend != 0; psD = next) { // Store the next droid in the list as the list may change next = psD->psNext; if (psD->droidType == DROID_TRANSPORTER && !transporterIsEmpty(psD)) { CONPRINTF(ConsoleString, (ConsoleString, _("Tried to give away a non-empty %s - but this is not allowed."), psD->aName)); continue; } if (psD->selected) { NETbeginEncode(NET_GIFT, NET_ALL_PLAYERS); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); // Add the droid to the packet NETuint32_t(&psD->id); NETend(); // Hand over the droid on our sidde giftSingleDroid(psD, to); // Decrement the number of droids left to send --totalToSend; } } }
// sendGiftDroids() // We give selected droid(s) as a gift to another player. // // \param from :player that sent us the droid // \param to :player that should be getting the droid static void sendGiftDroids(uint8_t from, uint8_t to) { DROID *psD; uint8_t giftType = DROID_GIFT; uint8_t totalToSend; if (apsDroidLists[from] == nullptr) { return; } /* * Work out the number of droids to send. As well as making sure they are * selected we also need to make sure they will NOT put the receiving player * over their droid limit. */ for (totalToSend = 0, psD = apsDroidLists[from]; psD && getNumDroids(to) + totalToSend < getMaxDroids(to) && totalToSend != UINT8_MAX; psD = psD->psNext) { if (psD->selected) { ++totalToSend; } } /* * We must send one droid at a time, due to the fact that giftSingleDroid() * does its own net calls. */ for (psD = apsDroidLists[from]; psD && totalToSend != 0; psD = psD->psNext) { if (isTransporter(psD) && !transporterIsEmpty(psD)) { CONPRINTF(ConsoleString, (ConsoleString, _("Tried to give away a non-empty %s - but this is not allowed."), psD->aName)); continue; } if (psD->selected) { NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); // Add the droid to the packet NETuint32_t(&psD->id); NETend(); // Decrement the number of droids left to send --totalToSend; } } }
/* Sends a particular key mapping to the console */ static void keyShowMapping(KEY_MAPPING *psMapping) { char asciiSub[20], asciiMeta[20]; bool onlySub; onlySub = true; if (psMapping->metaKeyCode != KEY_IGNORE) { keyScanToString(psMapping->metaKeyCode, (char *)&asciiMeta, 20); onlySub = false; } keyScanToString(psMapping->subKeyCode, (char *)&asciiSub, 20); if (onlySub) { CONPRINTF(ConsoleString, (ConsoleString, "%s - %s", asciiSub, _(psMapping->name.c_str()))); } else { CONPRINTF(ConsoleString, (ConsoleString, "%s and %s - %s", asciiMeta, asciiSub, _(psMapping->name.c_str()))); } debug(LOG_INPUT, "Received %s from Console", ConsoleString); }
// recvGiftDroid() // We received a droid gift from another player. // NOTICE: the packet is already set-up for decoding via recvGift() // // \param from :player that sent us the droid // \param to :player that should be getting the droid static void recvGiftDroids(uint8_t from, uint8_t to, uint32_t droidID) { DROID *psDroid; if (IdToDroid(droidID, from, &psDroid)) { giftSingleDroid(psDroid, to); if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives you a %s"), getPlayerName(from), psDroid->aName)); } } else { debug(LOG_ERROR, "Bad droid id %u, from %u to %u", droidID, from, to); } }
// NOTICE: the packet is already set-up for decoding via recvGift() static void recvGiftStruct(uint8_t from, uint8_t to, uint32_t structID) { STRUCTURE *psStruct = IdToStruct(structID, from); if (psStruct) { syncDebugStructure(psStruct, '<'); giftSingleStructure(psStruct, to, false); syncDebugStructure(psStruct, '>'); if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives you a %s"), getPlayerName(from), objInfo(psStruct))); } } else { debug(LOG_ERROR, "Bad structure id %u, from %u to %u", structID, from, to); } }
// //////////////////////////////////////////////////////////////////////////// // give Power void giftPower(uint8_t from, uint8_t to, uint32_t amount, bool send) { if (send) { uint8_t giftType = POWER_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&amount); NETend(); } else { int value = 0; if (from == ANYPLAYER && !NetPlay.bComms) { // basically cheating power, so we check that we are not in multiplayer addPower(to, amount); } else if (from == ANYPLAYER && NetPlay.bComms) { debug(LOG_WARNING, "Someone tried to cheat power in multiplayer - ignored!"); } else if (amount == 0) // the GUI option { value = getPower(from) / 3; usePower(from, value); addPower(to, value); } else // for scripts etc that can give precise amounts { value = MIN(getPower(from), amount); usePower(from, value); addPower(to, value); } if (from != ANYPLAYER && to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You %d Power"), getPlayerName(from), value)); } } }
/*find the last research topic of importance that the losing player did and 'give' the results to the reward player*/ void researchReward(UBYTE losingPlayer, UBYTE rewardPlayer) { UDWORD topicIndex = 0, researchPoints = 0, rewardID = 0; STRUCTURE *psStruct; RESEARCH_FACILITY *psFacility; //look through the losing players structures to find a research facility for (psStruct = apsStructLists[losingPlayer]; psStruct != NULL; psStruct = psStruct->psNext) { if (psStruct->pStructureType->type == REF_RESEARCH) { psFacility = (RESEARCH_FACILITY *)psStruct->pFunctionality; if (psFacility->psBestTopic) { topicIndex = ((RESEARCH *)psFacility->psBestTopic)->ref - REF_RESEARCH_START; if (topicIndex) { //if it cost more - it is better (or should be) if (researchPoints < asResearch[topicIndex].researchPoints) { //store the 'best' topic researchPoints = asResearch[topicIndex].researchPoints; rewardID = topicIndex; } } } } } //if a topic was found give the reward player the results of that research if (rewardID) { researchResult(rewardID, rewardPlayer, true, NULL, true); if (rewardPlayer == selectedPlayer) { //name the actual reward CONPRINTF(ConsoleString, (ConsoleString, "%s :- %s", _("Research Award"), getName(&asResearch[rewardID]))); } } }
/** print out information about a base object * \param psObj the object to print the info for */ static void printBaseObjInfo(const BASE_OBJECT* psObj) { const char *pType; switch (psObj->type) { case OBJ_DROID: pType = "UNIT"; break; case OBJ_STRUCTURE: pType = "STRUCT"; break; case OBJ_FEATURE: pType = "FEAT"; break; default: pType = "UNKNOWN TYPE"; break; } CONPRINTF( ConsoleString, (ConsoleString, "%s id %d at (%d,%d,%d) dpr (%hu,%hu,%hu)\n", pType, psObj->id, psObj->pos.x, psObj->pos.y, psObj->pos.z, psObj->rot.direction, psObj->rot.pitch, psObj->rot.roll)); }
// //////////////////////////////////////////////////////////////////////////// // give technologies. static void giftResearch(uint8_t from, uint8_t to, BOOL send) { PLAYER_RESEARCH *pR, *pRto; int i; uint32_t dummy = 0; if (send) { uint8_t giftType = RESEARCH_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&dummy); NETend(); } else { if (to == selectedPlayer) { CONPRINTF(ConsoleString, (ConsoleString, _("%s Gives You Technology Documents"), getPlayerName(from))); } pR = asPlayerResList[from]; pRto = asPlayerResList[to]; // For each topic for (i = 0; i < numResearch; i++) { // If they have it and we don't research it if (IsResearchCompleted(&pR[i]) && !IsResearchCompleted(&pRto[i])) { MakeResearchCompleted(&pRto[i]); researchResult(i, to, false, NULL, true); } } } }
// //////////////////////////////////////////////////////////////////////////// // give Power void giftPower(uint8_t from, uint8_t to, uint32_t amount, bool send) { if (send) { uint8_t giftType = POWER_GIFT; NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT); NETuint8_t(&giftType); NETuint8_t(&from); NETuint8_t(&to); NETuint32_t(&amount); NETend(); } else { uint32_t gifval; if (from == ANYPLAYER || amount != 0) { gifval = amount; } else { // Give 1/3 of our power away gifval = getPower(from) / 3; usePower(from, gifval); } addPower(to, gifval); if (from != ANYPLAYER && to == selectedPlayer) { CONPRINTF(ConsoleString,(ConsoleString,_("%s Gives You %u Power"),getPlayerName(from),gifval)); } } }
/* Updates the camera position/angle along with the object movement */ bool processWarCam( void ) { BASE_OBJECT *foundTarget; bool Status = true; /* Get out if the camera isn't active */ if(trackingCamera.status == CAM_INACTIVE) { return(true); } /* Ensure that the camera only ever flips state within this routine! */ switch(trackingCamera.status) { case CAM_REQUEST: /* See if we can find the target to follow */ foundTarget = camFindTarget(); if(foundTarget && !foundTarget->died) { /* We've got one, so store away info */ camAllignWithTarget(foundTarget); /* We're now into tracking status */ trackingCamera.status = CAM_TRACKING; /* Inform via console */ if(foundTarget->type == OBJ_DROID) { if(getWarCamStatus()) { CONPRINTF(ConsoleString,(ConsoleString,"WZ/CAM - %s",droidGetName((DROID*)foundTarget))); } } } else { /* We've requested a track with no droid selected */ trackingCamera.status = CAM_INACTIVE; } break; case CAM_TRACKING: /* Track the droid unless routine comes back false */ if(!camTrackCamera()) { /* Camera track came back false, either because droid died or is no longer selected, so reset to old values */ foundTarget = camFindTarget(); if(foundTarget && !foundTarget->died) { trackingCamera.status = CAM_REQUEST; } else { trackingCamera.status = CAM_RESET; } } processLeaderSelection(); break; case CAM_RESET: /* Reset camera to pre-droid tracking status */ if( (trackingCamera.target==NULL) ||(trackingCamera.target->type!=OBJ_TARGET)) { camSwitchOff(); } /* Switch to inactive mode */ trackingCamera.status = CAM_INACTIVE; Status = false; break; case CAM_INACTIVE: case CAM_TRACK_OBJECT: case CAM_TRACK_LOCATION: ASSERT(false, "Unexpected status for tracking camera"); break; } return Status; }
/** print out weapon information * \param psStats the weapon to print the info for */ static void printWeaponInfo(const WEAPON_STATS *psStats) { const char *pWC, *pWSC, *pMM; switch (psStats->weaponClass) { case WC_KINETIC: //bullets etc pWC = "WC_KINETIC"; break; case WC_HEAT: //laser etc pWC = "WC_HEAT"; break; default: pWC = "UNKNOWN CLASS"; break; } switch (psStats->weaponSubClass) { case WSC_MGUN: pWSC = "WSC_MGUN"; break; case WSC_CANNON: pWSC = "WSC_CANNON"; break; case WSC_MORTARS: pWSC = "WSC_MORTARS"; break; case WSC_MISSILE: pWSC = "WSC_MISSILE"; break; case WSC_ROCKET: pWSC = "WSC_ROCKET"; break; case WSC_ENERGY: pWSC = "WSC_ENERGY"; break; case WSC_GAUSS: pWSC = "WSC_GAUSS"; break; case WSC_FLAME: pWSC = "WSC_FLAME"; break; case WSC_HOWITZERS: pWSC = "WSC_HOWITZERS"; break; case WSC_ELECTRONIC: pWSC = "WSC_ELECTRONIC"; break; case WSC_AAGUN: pWSC = "WSC_AAGUN"; break; case WSC_SLOWMISSILE: pWSC = "WSC_SLOWMISSILE"; break; case WSC_SLOWROCKET: pWSC = "WSC_SLOWROCKET"; break; case WSC_LAS_SAT: pWSC = "WSC_LAS_SAT"; break; case WSC_BOMB: pWSC = "WSC_BOMB"; break; case WSC_COMMAND: pWSC = "WSC_COMMAND"; break; case WSC_EMP: pWSC = "WSC_EMP"; break; default: pWSC = "UNKNOWN SUB CLASS"; break; } switch (psStats->movementModel) { case MM_DIRECT: pMM = "MM_DIRECT"; break; case MM_INDIRECT: pMM = "MM_INDIRECT"; break; case MM_HOMINGDIRECT: pMM = "MM_HOMINGDIRECT"; break; case MM_HOMINGINDIRECT: pMM = "MM_HOMINGINDIRECT"; break; default: pMM = "UNKNOWN MOVE MODEL"; break; } CONPRINTF(ConsoleString, (ConsoleString, "Weapon: ")); printComponentInfo((COMPONENT_STATS *)psStats); CONPRINTF(ConsoleString, (ConsoleString, " lRng %d mRng %d %s\n" " lHt %d pause %d dam %d\n", proj_GetLongRange(psStats, selectedPlayer), psStats->upgrade[selectedPlayer].minRange, proj_Direct(psStats) ? "direct" : "indirect", weaponLongHit(psStats, selectedPlayer), weaponFirePause(psStats, selectedPlayer), weaponDamage(psStats, selectedPlayer))); CONPRINTF(ConsoleString, (ConsoleString, " rad %d radDam %d\n" " inTime %d inDam %d inRad %d\n", psStats->upgrade[selectedPlayer].radius, psStats->upgrade[selectedPlayer].radiusDamage, psStats->upgrade[selectedPlayer].periodicalDamageTime, psStats->upgrade[selectedPlayer].periodicalDamage, psStats->upgrade[selectedPlayer].periodicalDamageRadius)); CONPRINTF(ConsoleString, (ConsoleString, " flSpd %d %s\n", psStats->flightSpeed, psStats->fireOnMove ? "fireOnMove" : "not fireOnMove")); CONPRINTF(ConsoleString, (ConsoleString, " %s %s %s\n", pWC, pWSC, pMM)); CONPRINTF(ConsoleString, (ConsoleString, " %srotate recoil %d\n" " radLife %d\n", psStats->rotate ? "" : "not ", psStats->recoilValue, psStats->radiusLife)); }
/** print out weapon information * \param psStats the weapon to print the info for */ static void printWeaponInfo(const WEAPON_STATS* psStats) { const char *pWC, *pWSC, *pMM; switch (psStats->weaponClass) { case WC_KINETIC: //bullets etc pWC = "WC_KINETIC"; break; //case WC_EXPLOSIVE: //rockets etc // pWC = "WC_EXPLOSIVE"; // break; case WC_HEAT: //laser etc pWC = "WC_HEAT"; break; //case WC_MISC: //others we haven't thought of! // pWC = "WC_MISC"; // break; default: pWC = "UNKNOWN CLASS"; break; } switch (psStats->weaponSubClass) { case WSC_MGUN: pWSC = "WSC_MGUN"; break; case WSC_CANNON: pWSC = "WSC_CANNON"; break; /*case WSC_ARTILLARY: pWSC = "WSC_ARTILLARY"; break;*/ case WSC_MORTARS: pWSC = "WSC_MORTARS"; break; case WSC_MISSILE: pWSC = "WSC_MISSILE"; break; case WSC_ROCKET: pWSC = "WSC_ROCKET"; break; case WSC_ENERGY: pWSC = "WSC_ENERGY"; break; case WSC_GAUSS: pWSC = "WSC_GAUSS"; break; case WSC_FLAME: pWSC = "WSC_FLAME"; break; /*case WSC_CLOSECOMBAT: pWSC = "WSC_CLOSECOMBAT"; break;*/ case WSC_HOWITZERS: pWSC = "WSC_HOWITZERS"; break; case WSC_ELECTRONIC: pWSC = "WSC_ELECTRONIC"; break; case WSC_AAGUN: pWSC = "WSC_AAGUN"; break; case WSC_SLOWMISSILE: pWSC = "WSC_SLOWMISSILE"; break; case WSC_SLOWROCKET: pWSC = "WSC_SLOWROCKET"; break; case WSC_LAS_SAT: pWSC = "WSC_LAS_SAT"; break; case WSC_BOMB: pWSC = "WSC_BOMB"; break; case WSC_COMMAND: pWSC = "WSC_COMMAND"; break; case WSC_EMP: pWSC = "WSC_EMP"; break; default: pWSC = "UNKNOWN SUB CLASS"; break; } switch (psStats->movementModel) { case MM_DIRECT: pMM = "MM_DIRECT"; break; case MM_INDIRECT: pMM = "MM_INDIRECT"; break; case MM_HOMINGDIRECT: pMM = "MM_HOMINGDIRECT"; break; case MM_HOMINGINDIRECT: pMM = "MM_HOMINGINDIRECT"; break; case MM_ERRATICDIRECT: pMM = "MM_ERRATICDIRECT"; break; case MM_SWEEP: pMM = "MM_SWEEP"; break; default: pMM = "UNKNOWN MOVE MODEL"; break; } CONPRINTF(ConsoleString,(ConsoleString,"Weapon: ")); printComponentInfo((COMPONENT_STATS *)psStats); CONPRINTF(ConsoleString,(ConsoleString," sRng %d lRng %d mRng %d %s\n" " sHt %d lHt %d pause %d dam %d\n", psStats->shortRange, proj_GetLongRange(psStats), psStats->minRange, proj_Direct(psStats) ? "direct" : "indirect", //psStats->shortHit, psStats->longHit, psStats->firePause, psStats->damage)); weaponShortHit(psStats,(UBYTE)selectedPlayer), weaponLongHit(psStats, (UBYTE)selectedPlayer), weaponFirePause(psStats,(UBYTE)selectedPlayer), weaponDamage(psStats, (UBYTE)selectedPlayer))); CONPRINTF(ConsoleString,(ConsoleString," rad %d radHt %d radDam %d\n" " inTime %d inDam %d inRad %d\n", psStats->radius, psStats->radiusHit, psStats->radiusDamage, psStats->incenTime, psStats->incenDamage, psStats->incenRadius)); CONPRINTF(ConsoleString,(ConsoleString," flSpd %d %s\n", psStats->flightSpeed, psStats->fireOnMove ? "fireOnMove" : "not fireOnMove")); CONPRINTF(ConsoleString,(ConsoleString," %s %s %s\n", pWC, pWSC, pMM)); CONPRINTF(ConsoleString,(ConsoleString," %srotate recoil %d\n" " dLife %d radLife %d\n", psStats->rotate ? "" : "not ", psStats->recoilValue, psStats->directLife, psStats->radiusLife)); }
/** print out information about a droid and it's components * \param psDroid the droid to print the info for */ void printDroidInfo(const DROID* psDroid) { unsigned int i; BODY_STATS *psBdyStats; PROPULSION_STATS *psPropStats; ECM_STATS *psECMStats; SENSOR_STATS *psSensStats; CONSTRUCT_STATS *psConstStats; REPAIR_STATS *psRepairStats; printBaseObjInfo((BASE_OBJECT *)psDroid); CONPRINTF(ConsoleString,(ConsoleString," wt %d bSpeed %d sRng %d ECM %d bdy %d\n", psDroid->weight, psDroid->baseSpeed, droidSensorRange(psDroid), droidConcealment(psDroid), psDroid->body)); if (psDroid->asWeaps[0].nStat > 0) { printWeaponInfo(asWeaponStats + psDroid->asWeaps[0].nStat); } for (i = 0; i < COMP_NUMCOMPONENTS; ++i) { switch (i) { case COMP_UNKNOWN: break; case COMP_BODY: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"Body: ")); psBdyStats = asBodyStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psBdyStats); } else { CONPRINTF(ConsoleString,(ConsoleString,"ZNULL BODY\n")); } break; case COMP_BRAIN: break; case COMP_PROPULSION: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"Prop: ")); psPropStats = asPropulsionStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psPropStats); } else { CONPRINTF(ConsoleString,(ConsoleString,"ZNULL PROPULSION\n")); } break; case COMP_ECM: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"ECM: ")); psECMStats = asECMStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psECMStats); CONPRINTF(ConsoleString,(ConsoleString," range %d loc %d imd %p\n", //psECMStats->power, psECMStats->location, psECMStats->pMountGraphic)); ecmRange(psECMStats, psDroid->player), psECMStats->location, psECMStats->pMountGraphic)); } else { CONPRINTF(ConsoleString,(ConsoleString,"ZNULL ECM\n")); } break; case COMP_SENSOR: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"Sensor: ")); psSensStats = asSensorStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psSensStats); CONPRINTF(ConsoleString,(ConsoleString," rng %d loc %d imd %p\n", sensorRange(psSensStats,psDroid->player), psSensStats->location, psSensStats->pMountGraphic)); } else { CONPRINTF(ConsoleString,(ConsoleString,"ZNULL SENSOR\n")); } break; case COMP_CONSTRUCT: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"Construct: ")); psConstStats = asConstructStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psConstStats); CONPRINTF(ConsoleString,(ConsoleString," cPnts %d imd %p\n", //psConstStats->constructPoints, psConstStats->pMountGraphic)); constructorPoints(psConstStats, psDroid->player), psConstStats->pMountGraphic)); } break; case COMP_REPAIRUNIT: if (psDroid->asBits[i].nStat > 0) { CONPRINTF(ConsoleString,(ConsoleString,"Repair: ")); psRepairStats = asRepairStats + psDroid->asBits[i].nStat; printComponentInfo((COMPONENT_STATS *)psRepairStats); CONPRINTF(ConsoleString,(ConsoleString," repPnts %d loc %d imd %p\n", //psRepairStats->repairPoints, psRepairStats->location, repairPoints(psRepairStats, psDroid->player), psRepairStats->location, psRepairStats->pMountGraphic)); } break; case COMP_WEAPON: default: break; } } }
// //////////////////////////////////////////////////////////////////////////// // receive droid creation information from other players BOOL recvDroid(NETQUEUE queue) { DROID_TEMPLATE* pT; DROID* psDroid; uint8_t player; uint32_t id; Position pos; uint32_t templateID; BOOL haveInitialOrders; INITIAL_DROID_ORDERS initialOrders; NETbeginDecode(queue, GAME_DROID); { NETuint8_t(&player); NETuint32_t(&id); NETPosition(&pos); NETuint32_t(&templateID); NETbool(&haveInitialOrders); if (haveInitialOrders) { NETuint32_t(&initialOrders.secondaryOrder); NETint32_t(&initialOrders.moveToX); NETint32_t(&initialOrders.moveToY); NETuint32_t(&initialOrders.factoryId); // For making scripts happy. } pT = IdToTemplate(templateID, player); } NETend(); ASSERT( player < MAX_PLAYERS, "invalid player %u", player); debug(LOG_LIFE, "<=== getting Droid from %u id of %u ",player,id); if ((pos.x == 0 && pos.y == 0) || pos.x > world_coord(mapWidth) || pos.y > world_coord(mapHeight)) { debug(LOG_ERROR, "Received bad droid position (%d, %d) from %d about p%d (%s)", (int)pos.x, (int)pos.y, queue.index, player, isHumanPlayer(player) ? "Human" : "AI"); return false; } // If we can not find the template ask for the entire droid instead if (!pT) { debug(LOG_ERROR, "Packet from %d refers to non-existent template %u, [%s : p%d]", queue.index, templateID, isHumanPlayer(player) ? "Human" : "AI", player); return false; } // Create that droid on this machine. psDroid = reallyBuildDroid(pT, pos.x, pos.y, player, false); // If we were able to build the droid set it up if (psDroid) { psDroid->id = id; addDroid(psDroid, apsDroidLists); if (haveInitialOrders) { psDroid->secondaryOrder = initialOrders.secondaryOrder; orderDroidLoc(psDroid, DORDER_MOVE, initialOrders.moveToX, initialOrders.moveToY, ModeImmediate); cbNewDroid(IdToStruct(initialOrders.factoryId, ANYPLAYER), psDroid); } } else { debug(LOG_ERROR, "Packet from %d cannot create droid for p%d (%s)!", queue.index, player, isHumanPlayer(player) ? "Human" : "AI"); #ifdef DEBUG CONPRINTF(ConsoleString, (ConsoleString, "MULTIPLAYER: Couldn't build a remote droid, relying on checking to resync")); #endif return false; } return true; }
void GetOrdiText ( const char *textname, char *messagename, Font *pRadioFont, int sizeX ) { // ouverture du fichier texte char filename [128]; sprintf ( filename, TEXT_FILE_PATH ); // char messagename [62]; sprintf ( messagename, textname ); FILE *myfile = fopen ( filename, "r" ); if ( myfile == NULL ) { CONPRINTF ("\\\nORDITXT : impossible d'ouvrir %s\n\\\n", filename ); return; } char cscan [128]; char messagetext [ORDI_STRING_LEN]; int startoffset = 0; int stopoffset = 0; while ( 1 ) { // titre SCANNE_CHAR; if ( strcmp ( cscan, messagename ) != 0 ) continue; // point d'entrée SCANNE_CHAR; if ( strcmp ( cscan, "{" ) != 0 ) continue; // offsets de départ et d'arrivée int startoffset = (int)ftell ( myfile ) + 2; while ( 1 ) { SCANNE_CHAR; if ( strcmp ( cscan, "}" ) != 0 ) continue; break; } int stopoffset = (int)ftell ( myfile ); // récupération du texte fseek ( myfile, startoffset, SEEK_SET ); for ( int i=0; i<(int)(stopoffset-startoffset); i++ ) { char copie = getc ( myfile ); if ( copie == '}' ) { messagetext [i-1] = '\0'; break; } messagetext [i] = copie; } messagetext [i] = '\0'; } // fermeture du fichier texte fclose ( myfile ); // mise en forme int curseurX = 0; int curseurY = 0; int rien; char source [ORDI_STRING_LEN]; char dest [ORDI_STRING_LEN]; sprintf ( source, messagetext ); sprintf ( dest, "" ); int i; for ( i=0; i<(int)strlen(source); i++ ) { if ( source[i] != '\n' ) break; } for ( i=i; i<(int)strlen(source); i++ ) { if (source[i] == '\0' ) continue; if ( i == 0 && source[i] == '\n' ) continue; // peut-on caser le mot dans l'espace qu'il nous reste int wordlen = 0; int lettres = 0; if (source[i] != ' ' && source[i] != '\n' ) { while ( source[i+lettres] != ' ' ) { if (source[i+lettres] == '\n' ) break; if (source[i+lettres] == '\0' ) break; //wordlen += gHUD.m_scrinfo.charWidths[ source[i+lettres] ]; char caractere [2]; sprintf ( caractere, "%c", source[i+lettres] ); int len = 0; pRadioFont->getTextSize ( caractere, len, rien ); wordlen += len; lettres ++; } } else if ( source[i] == '\n' ) { curseurX = 0; strcat ( dest, "\n" ); continue; } else { // wordlen = gHUD.m_scrinfo.charWidths[' ']; char caractere [2]; sprintf ( caractere, "%c", ' ' ); int len = 0; pRadioFont->getTextSize ( caractere, len, rien ); wordlen = len; lettres = 1; } if ( curseurX + wordlen > sizeX ) { // curseurY += gHUD.m_scrinfo.iCharHeight; // retour à la ligne curseurX = 0; strcat ( dest, "\n" ); } // dessin des lettres for ( int j=0; j<lettres; j++ ) { char cat [2]; sprintf ( cat, "" ); sprintf ( cat, "%c", source[i+j] ); strcat ( dest, cat ); char caractere [2]; sprintf ( caractere, "%c", source[i+j] ); int len = 0; pRadioFont->getTextSize ( caractere, len, rien ); curseurX += len; } i += lettres - 1; } sprintf ( messagename, dest ); return; }
/* Selects the units of a given player according to given criteria. It is also possible to request whether the units be onscreen or not. */ unsigned int selDroidSelection(unsigned int player, SELECTION_CLASS droidClass, SELECTIONTYPE droidType, bool bOnScreen) { /* So far, we haven't selected any */ unsigned int retVal = 0; /* Establish the class of selection */ switch (droidClass) { case DS_ALL_UNITS: retVal = selSelectUnitsIf(player, selTrue, bOnScreen); break; case DS_BY_TYPE: switch (droidType) { case DST_VTOL: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_LIFT, bOnScreen); break; case DST_VTOL_ARMED: retVal = selSelectUnitsIf(player, selPropArmed, PROPULSION_TYPE_LIFT, bOnScreen); break; case DST_HOVER: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_HOVER, bOnScreen); break; case DST_WHEELED: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_WHEELED, bOnScreen); break; case DST_TRACKED: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_TRACKED, bOnScreen); break; case DST_HALF_TRACKED: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_HALF_TRACKED, bOnScreen); break; case DST_CYBORG: retVal = selSelectUnitsIf(player, selProp, PROPULSION_TYPE_LEGGED, bOnScreen); break; case DST_ENGINEER: retVal = selSelectUnitsIf(player, selType, DROID_CYBORG_CONSTRUCT, bOnScreen); break; case DST_MECHANIC: retVal = selSelectUnitsIf(player, selType, DROID_CYBORG_REPAIR, bOnScreen); break; case DST_TRANSPORTER: retVal = selSelectUnitsIf(player, selTransporter, bOnScreen); break; case DST_REPAIR_TANK: retVal = selSelectUnitsIf(player, selType, DROID_REPAIR, bOnScreen); break; case DST_SENSOR: retVal = selSelectUnitsIf(player, selType, DROID_SENSOR, bOnScreen); break; case DST_TRUCK: retVal = selSelectUnitsIf(player, selType, DROID_CONSTRUCT, bOnScreen); break; case DST_ALL_COMBAT: retVal = selSelectUnitsIf(player, selCombat, bOnScreen); break; case DST_ALL_COMBAT_LAND: retVal = selSelectUnitsIf(player, selCombatLand, bOnScreen); break; case DST_ALL_COMBAT_CYBORG: retVal = selSelectUnitsIf(player, selCombatCyborg, bOnScreen); break; case DST_ALL_DAMAGED: retVal = selSelectUnitsIf(player, selDamaged, bOnScreen); break; case DST_ALL_SAME: retVal = selSelectAllSame(player, bOnScreen); break; default: ASSERT(false, "Invalid selection type"); } break; default: ASSERT(false, "Invalid selection attempt"); break; } CONPRINTF(ConsoleString, (ConsoleString, ngettext("%u unit selected", "%u units selected", retVal), retVal)); return retVal; }
/* Updates the camera position/angle along with the object movement */ BOOL processWarCam( void ) { BASE_OBJECT *foundTarget; BOOL Status = true; /* Get out if the camera isn't active */ if(trackingCamera.status == CAM_INACTIVE) { return(true); } /* Ensure that the camera only ever flips state within this routine! */ switch(trackingCamera.status) { case CAM_REQUEST: /* See if we can find the target to follow */ foundTarget = camFindTarget(); if(foundTarget && !foundTarget->died) { /* We've got one, so store away info */ camAllignWithTarget(foundTarget); /* We're now into tracking status */ trackingCamera.status = CAM_TRACKING; /* Inform via console */ if(foundTarget->type == OBJ_DROID) { if(getWarCamStatus()) { CONPRINTF(ConsoleString,(ConsoleString,"WZ/CAM - %s",droidGetName((DROID*)foundTarget))); } } else { // CONPRINTF(ConsoleString,(ConsoleString,"DROID-CAM V0.1 Enabled - Now tracking new location")); } } else { /* We've requested a track with no droid selected */ // addConsoleMessage("Droid-CAM V0.1 ERROR - No targets(s) selected",DEFAULT_JUSTIFY,SYSTEM_MESSAGE); trackingCamera.status = CAM_INACTIVE; } break; case CAM_TRACKING: /* Track the droid unless routine comes back false */ if(!camTrackCamera()) { /* Camera track came back false, either because droid died or is no longer selected, so reset to old values */ foundTarget = camFindTarget(); if(foundTarget && !foundTarget->died) { trackingCamera.status = CAM_REQUEST; } else { trackingCamera.status = CAM_RESET; } } processLeaderSelection(); break; case CAM_RESET: /* Reset camera to pre-droid tracking status */ if( (trackingCamera.target==NULL) ||(trackingCamera.target->type!=OBJ_TARGET)) { camSwitchOff(); } /* Switch to inactive mode */ trackingCamera.status = CAM_INACTIVE; // addConsoleMessage("Droid-CAM V0.1 Disabled",DEFAULT_JUSTIFY,SYSTEM_MESSAGE); Status = false; break; default: debug( LOG_FATAL, "Weirdy status for tracking Camera" ); abort(); break; } return Status; }