cp_team.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.m
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "../client.h" /* cls */
00027 #include "../cl_team.h"
00028 #include "cp_campaign.h"
00029 #include "cp_team.h"
00030 
00038 static item_t CP_AddWeaponAmmo (equipDef_t * ed, item_t item)
00039 {
00040     int i;
00041     objDef_t *type = item.t;
00042 
00043     assert(ed->numItems[type->idx] > 0);
00044     ed->numItems[type->idx]--;
00045 
00046     if (type->weapons[0]) {
00047         /* The given item is ammo or self-contained weapon (i.e. It has firedefinitions. */
00048         if (type->oneshot) {
00049             /* "Recharge" the oneshot weapon. */
00050             item.a = type->ammo;
00051             item.m = item.t; /* Just in case this hasn't been done yet. */
00052             Com_DPrintf(DEBUG_CLIENT, "CL_AddWeaponAmmo: oneshot weapon '%s'.\n", type->id);
00053             return item;
00054         } else {
00055             /* No change, nothing needs to be done to this item. */
00056             return item;
00057         }
00058     } else if (!type->reload) {
00059         /* The given item is a weapon but no ammo is needed,
00060          * so fire definitions are in t (the weapon). Setting equal. */
00061         item.m = item.t;
00062         return item;
00063     } else if (item.a) {
00064         assert(item.m);
00065         /* The item is a weapon and it was reloaded one time. */
00066         if (item.a == type->ammo) {
00067             /* Fully loaded, no need to reload, but mark the ammo as used. */
00068             if (ed->numItems[item.m->idx] > 0) {
00069                 ed->numItems[item.m->idx]--;
00070                 return item;
00071             } else {
00072                 /* Your clip has been sold; give it back. */
00073                 item.a = NONE_AMMO;
00074                 return item;
00075             }
00076         }
00077     }
00078 
00079     /* Check for complete clips of the same kind */
00080     if (item.m && ed->numItems[item.m->idx] > 0) {
00081         ed->numItems[item.m->idx]--;
00082         item.a = type->ammo;
00083         return item;
00084     }
00085 
00086     /* Search for any complete clips. */
00088     for (i = 0; i < csi.numODs; i++) {
00089         objDef_t *od = INVSH_GetItemByIDX(i);
00090         if (INVSH_LoadableInWeapon(od, type)) {
00091             if (ed->numItems[i] > 0) {
00092                 ed->numItems[i]--;
00093                 item.a = type->ammo;
00094                 item.m = od;
00095                 return item;
00096             }
00097         }
00098     }
00099 
00106     /* Failed to find a complete clip - see if there's any loose ammo
00107      * of the same kind; if so, gather it all in this weapon. */
00108     if (item.m && ed->numItemsLoose[item.m->idx] > 0) {
00109         item.a = ed->numItemsLoose[item.m->idx];
00110         ed->numItemsLoose[item.m->idx] = 0;
00111         return item;
00112     }
00113 
00114     /* See if there's any loose ammo */
00116     item.a = NONE_AMMO;
00117     for (i = 0; i < csi.numODs; i++) {
00118         objDef_t *od = INVSH_GetItemByIDX(i);
00119         if (INVSH_LoadableInWeapon(od, type) && ed->numItemsLoose[i] > item.a) {
00120             if (item.a > 0) {
00121                 /* We previously found some ammo, but we've now found other
00122                  * loose ammo of a different (but appropriate) type with
00123                  * more bullets.  Put the previously found ammo back, so
00124                  * we'll take the new type. */
00125                 assert(item.m);
00126                 ed->numItemsLoose[item.m->idx] = item.a;
00127                 /* We don't have to accumulate loose ammo into clips
00128                  * because we did it previously and we create no new ammo */
00129             }
00130             /* Found some loose ammo to load the weapon with */
00131             item.a = ed->numItemsLoose[i];
00132             ed->numItemsLoose[i] = 0;
00133             item.m = od;
00134         }
00135     }
00136     return item;
00137 }
00138 
00153 void CL_CleanupAircraftCrew (aircraft_t *aircraft, equipDef_t * ed)
00154 {
00155     containerIndex_t container;
00156     linkedList_t* l;
00157 
00158     assert(aircraft);
00159 
00160     Com_DPrintf(DEBUG_CLIENT, "CL_CleanupAircraftCrew:aircraft idx: %i, team size: %i\n",
00161         aircraft->idx, AIR_GetTeamSize(aircraft));
00162 
00163     /* Auto-assign weapons to UGVs/Robots if they have no weapon yet. */
00164     for (l = aircraft->acTeam; l != NULL; l = l->next) {
00165         employee_t *employee = (employee_t *)l->data;
00166         character_t *chr = &employee->chr;
00167 
00168         /* This is an UGV */
00169         if (employee->ugv) {
00170             /* Check if there is a weapon and add it if there isn't. */
00171             if (!RIGHT(chr) || !RIGHT(chr)->item.t)
00172                 cls.i.EquipActorRobot(&cls.i, &chr->i, INVSH_GetItemByID(employee->ugv->weapon));
00173         }
00174     }
00175 
00176     for (container = 0; container < csi.numIDs; container++) {
00177         for (l = aircraft->acTeam; l != NULL; l = l->next) {
00178             employee_t *employee = (employee_t *)l->data;
00179             invList_t *ic, *next;
00180             character_t *chr = &employee->chr;
00181 #if 0
00182             /* ignore items linked from any temp container */
00183             if (INVDEF(container)->temp)
00184                 continue;
00185 #endif
00186             for (ic = CONTAINER(chr, container); ic; ic = next) {
00187                 next = ic->next;
00188                 if (ed->numItems[ic->item.t->idx] > 0) {
00189                     ic->item = CP_AddWeaponAmmo(ed, ic->item);
00190                 } else {
00191                     /* Drop ammo used for reloading and sold carried weapons. */
00192                     if (!cls.i.RemoveFromInventory(&cls.i, &chr->i, INVDEF(container), ic))
00193                         Com_Error(ERR_DROP, "Could not remove item from inventory");
00194                 }
00195             }
00196         }
00197     }
00198 }
00199 
00206 void CL_CleanTempInventory (base_t* base)
00207 {
00208     int i, k;
00209 
00210     for (i = 0; i < MAX_EMPLOYEES; i++)
00211         for (k = 0; k < csi.numIDs; k++)
00212             if (INVDEF(k)->temp) {
00213                 /* idFloor and idEquip are temp */
00214                 ccs.employees[EMPL_SOLDIER][i].chr.i.c[k] = NULL;
00215                 ccs.employees[EMPL_ROBOT][i].chr.i.c[k] = NULL;
00216             }
00217 
00218     if (!base)
00219         return;
00220 
00221     cls.i.DestroyInventory(&cls.i, &base->bEquipment);
00222 }
00223 
00231 int CL_UpdateActorAircraftVar (aircraft_t *aircraft, employeeType_t employeeType)
00232 {
00233     int i;
00234     size_t size;
00235     linkedList_t* l;
00236     int numOnAircraft;
00237 
00238     assert(aircraft);
00239 
00240     numOnAircraft = AIR_GetTeamSize(aircraft);
00241     Cvar_Set("mn_hired", va(_("%i of %i"), numOnAircraft, aircraft->maxTeamSize));
00242     Cvar_Set("mn_hirable_count", va("%i", aircraft->maxTeamSize - numOnAircraft));
00243     Cvar_Set("mn_hired_count", va("%i", numOnAircraft));
00244     Cvar_Set("mn_pilotassigned", va("%i", aircraft->pilot != NULL));
00245 
00246     if (aircraft->pilot) {
00247         Cvar_Set("mn_pilot_name", aircraft->pilot->chr.name);
00248         Cvar_Set("mn_pilot_body", CHRSH_CharGetBody(&aircraft->pilot->chr));
00249         Cvar_Set("mn_pilot_head", CHRSH_CharGetHead(&aircraft->pilot->chr));
00250         Cvar_Set("mn_pilot_skin", va("%i", aircraft->pilot->chr.skin));
00251     } else {
00252         Cvar_Set("mn_pilot_name", "");
00253         Cvar_Set("mn_pilot_body", "");
00254         Cvar_Set("mn_pilot_head", "");
00255         Cvar_Set("mn_pilot_skin", "");
00256     }
00257 
00258     size = lengthof(chrDisplayList.chr);
00259 
00260     /* update chrDisplayList list (this is the one that is currently displayed) */
00261     chrDisplayList.num = 0;
00262     for (l = aircraft->acTeam; l != NULL; l = l->next) {
00263         employee_t *empl = (employee_t *)l->data;
00264         if (empl->type != employeeType)
00265             continue;
00266 
00267         assert(chrDisplayList.num < size);
00268         chrDisplayList.chr[chrDisplayList.num] = &empl->chr;
00269 
00270         /* Sanity check(s) */
00271         if (!chrDisplayList.chr[chrDisplayList.num])
00272             Com_Error(ERR_DROP, "CL_UpdateActorAircraftVar: Could not get employee character with idx: %i", chrDisplayList.num);
00273         Com_DPrintf(DEBUG_CLIENT, "add %s to chrDisplayList (pos: %i)\n", chrDisplayList.chr[chrDisplayList.num]->name, chrDisplayList.num);
00274         Cvar_Set(va("mn_name%i", chrDisplayList.num), chrDisplayList.chr[chrDisplayList.num]->name);
00275 
00276         /* Update number of displayed team-members. */
00277         chrDisplayList.num++;
00278     }
00279 
00280     for (i = chrDisplayList.num; i < size; i++)
00281         chrDisplayList.chr[i] = NULL;   /* Just in case */
00282 
00283     return chrDisplayList.num;
00284 }

Generated by  doxygen 1.6.2