/* This file is part of Warzone 2100. Copyright (C) 1999-2004 Eidos Interactive Copyright (C) 2005-2007 Warzone Resurrection Project Warzone 2100 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Warzone 2100 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Warzone 2100; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * CmdDroid.c * * Code for command droids * */ #include "lib/framework/frame.h" #include "objects.h" #include "cmddroiddef.h" #include "cmddroid.h" #include "lib/gamelib/gtime.h" #include "group.h" #include "order.h" #include "multiplay.h" extern UDWORD selectedPlayer; // the current command droid target designator for IDF structures DROID *apsCmdDesignator[MAX_PLAYERS]; // whether experience should be boosted due to a multi game BOOL bMultiExpBoost = FALSE; // Initialise the command droids BOOL cmdDroidInit(void) { memset(apsCmdDesignator, 0, sizeof(DROID *)*MAX_PLAYERS); return TRUE; } // ShutDown the command droids void cmdDroidShutDown(void) { } // Make new command droids available void cmdDroidAvailable(BRAIN_STATS *psBrainStats, SDWORD player) { } // update the command droids void cmdDroidUpdate(void) { SDWORD i; for(i=0; idied) { apsCmdDesignator[i] = NULL; } } } // add a droid to a command group void cmdDroidAddDroid(DROID *psCommander, DROID *psDroid) { DROID_GROUP *psGroup; if (psCommander->psGroup == NULL) { if (!grpCreate(&psGroup)) { return; } grpJoin(psGroup, psCommander); psDroid->group = UBYTE_MAX; } if (grpNumMembers(psCommander->psGroup) < cmdDroidMaxGroup(psCommander)) { grpJoin(psCommander->psGroup, psDroid); psDroid->group = UBYTE_MAX; // set the secondary states for the unit secondarySetState(psDroid, DSO_ATTACK_RANGE, psCommander->secondaryOrder & DSS_ARANGE_MASK); secondarySetState(psDroid, DSO_REPAIR_LEVEL, psCommander->secondaryOrder & DSS_REPLEV_MASK); secondarySetState(psDroid, DSO_ATTACK_LEVEL, psCommander->secondaryOrder & DSS_ALEV_MASK); secondarySetState(psDroid, DSO_HALTTYPE, psCommander->secondaryOrder & DSS_HALT_MASK); orderDroidObj(psDroid, DORDER_GUARD, (BASE_OBJECT *)psCommander); } // if(bMultiPlayer && myResponsibility(psDroid->player) ) // { // sendCommandDroid(psCommander,psDroid); // } } // return the current target designator for a player DROID *cmdDroidGetDesignator(UDWORD player) { return apsCmdDesignator[player]; } // set the current target designator for a player void cmdDroidSetDesignator(DROID *psDroid) { if (psDroid->droidType != DROID_COMMAND) { return; } apsCmdDesignator[psDroid->player] = psDroid; } // set the current target designator for a player void cmdDroidClearDesignator(UDWORD player) { apsCmdDesignator[player] = NULL; } // get the index of the command droid SDWORD cmdDroidGetIndex(DROID *psCommander) { SDWORD index = 1; DROID *psCurr; if (psCommander->droidType != DROID_COMMAND) { return 0; } for(psCurr=apsDroidLists[psCommander->player]; psCurr; psCurr=psCurr->psNext) { if (psCurr->droidType == DROID_COMMAND && psCurr->id < psCommander->id) { index += 1; } } return index; } // note that commander experience should be increased void cmdDroidMultiExpBoost(BOOL bDoit) { bMultiExpBoost = bDoit; } // get the experience level of a command droid SDWORD cmdDroidGetLevel(DROID *psCommander) { SDWORD numKills = psCommander->numKills; // commanders do not need as much experience in multiplayer if (bMultiExpBoost) { numKills *= 2; } if (numKills > 2047) { return 8; } else if (numKills > 1023) { return 7; } else if (numKills > 511) { return 6; } else if (numKills > 255) { return 5; } else if (numKills > 127) { return 4; } else if (numKills > 63) { return 3; } else if (numKills > 32) { return 2; } else if (numKills > 15) { return 1; } return 0; } // get the maximum group size for a command droid SDWORD cmdDroidMaxGroup(DROID *psCommander) { return cmdDroidGetLevel(psCommander) * 2 + 6; } // update the kills of a command droid if psKiller is in a command group void cmdDroidUpdateKills(DROID *psKiller) { DROID *psCommander; ASSERT( PTRVALID(psKiller, sizeof(DROID)), "cmdUnitUpdateKills: invalid Unit pointer" ); if ( (psKiller->psGroup != NULL) && (psKiller->psGroup->type == GT_COMMAND) ) { psCommander = psKiller->psGroup->psCommander; psCommander->numKills += 1; } } // get the level of a droids commander, if any SDWORD cmdGetCommanderLevel(DROID *psDroid) { DROID *psCommander; ASSERT( PTRVALID(psDroid, sizeof(DROID)), "cmdGetCommanderLevel: invalid droid pointer" ); if ( (psDroid->psGroup != NULL) && (psDroid->psGroup->type == GT_COMMAND) ) { psCommander = psDroid->psGroup->psCommander; return cmdDroidGetLevel(psCommander); } return 0; } // Selects all droids for a given commander void cmdSelectSubDroids(DROID *psDroid) { DROID *psCurr; for (psCurr = apsDroidLists[selectedPlayer]; psCurr; psCurr = psCurr->psNext) { if( (psCurr->psGroup!=NULL) && (psCurr->psGroup->type == GT_COMMAND) ) { if(psCurr->psGroup->psCommander == psDroid) { // psCurr->selected = TRUE; SelectDroid(psCurr); } } } }