Index: src/game/inv_shared.c===================================================================--- src/game/inv_shared.c (Revision 10243)+++ src/game/inv_shared.c (Arbeitskopie)@@ -1252,7 +1252,7 @@ /* Abilities -- random within the range */ abilityWindow = maxAbility - minAbility; for (i = 0; i < ABILITY_NUM_TYPES; i++) {- chr->skills[i] = (frand() * abilityWindow) + minAbility;+ chr->skills[i] = (frand() * abilityWindow) + minAbility; /* Reminder: In case if abilityWindow==0 the ability will get set to minAbility. */ } /* Skills -- random within the range then scaled (or not) based on natural ability */@@ -1260,7 +1260,7 @@ for (i = ABILITY_NUM_TYPES; i < SKILL_NUM_TYPES; i++) { /* training is the base for where they fall within the range. */- training = (frand() * skillWindow) + minSkill;+ training = (frand() * skillWindow) + minSkill; /* Reminder: In case if skillWindow==0 the skill will get set to minSkill. */ if (TRAINING_SCALAR > 0) { switch (i) {@@ -1290,12 +1290,14 @@ } /* scale the abilitiy window to the skill window. */- windowScalar = skillWindow / abilityWindow;+ if (abilityWindow > 0 && skillWindow > 0) {+ windowScalar = skillWindow / abilityWindow;++ /* scale the ability numbers to their place in the skill range. */+ ability1 = ((ability1 - minAbility) * windowScalar) + minSkill;+ ability2 = ((ability2 - minAbility) * windowScalar) + minSkill;+ }- /* scale the ability numbers to their place in the skill range. */- ability1 = ((ability1 - minAbility) * windowScalar) + minSkill;- ability2 = ((ability2 - minAbility) * windowScalar) + minSkill;- /* influence the skills, for better or worse, based on the character's natural ability. */ chr->skills[i] = ((TRAINING_SCALAR * training) + ability1 + ability2) / (TRAINING_SCALAR + 2); } else {Index: src/client/cl_team.c===================================================================--- src/client/cl_team.c (Revision 10243)+++ src/client/cl_team.c (Arbeitskopie)@@ -26,6 +26,8 @@ #include "client.h" #include "cl_global.h"+static qboolean display_heavy_equipment_list = qfalse; /**< Used in team assignment screen to tell if we are assigning soldeirs or heavy equipment (ugvs/tanks) */+ static int CL_GetRank(const char* rankID); static void CL_SaveTeamInfo(sizebuf_t * buf, int baseID, int num);@@ -445,7 +447,7 @@ if (newSkin >= NUM_TEAMSKINS || newSkin < 0) newSkin = 0; for (i = 0, p = 0; i < gd.numEmployees[EMPL_SOLDIER]; i++) {- if (AIR_IsInAircraftTeam(aircraft, i)) {+ if (AIR_IsInAircraftTeam(aircraft, i, EMPL_SOLDIER)) { assert(p < MAX_ACTIVETEAM); baseCurrent->curTeam[p]->skin = newSkin; p++;@@ -725,7 +727,7 @@ /* Store hired names. */ Cvar_ForceSet("cl_selected", "0"); for (i = 0, p = 0; i < gd.numEmployees[EMPL_SOLDIER]; i++)- if (CL_SoldierInAircraft(i, aircraft->idx)) {+ if (CL_SoldierInAircraft(i, EMPL_SOLDIER, aircraft->idx)) { assert(p < MAX_ACTIVETEAM); /* maybe we already have soldiers in this aircraft */ baseCurrent->curTeam[p] = E_GetHiredCharacter(baseCurrent, EMPL_SOLDIER, i);@@ -888,6 +890,7 @@ character_t *chr; int num; selectSoldierModes_t mode;+ employeeType_t employeeType; /* check syntax */ if (Cmd_Argc() < 2) {@@ -947,11 +950,15 @@ chr = baseCurrent->curTeam[num]; break; case SELECT_MODE_TEAM:- if (!baseCurrent || num >= E_CountHired(baseCurrent, EMPL_SOLDIER)) {+ employeeType =+ display_heavy_equipment_list+ ? EMPL_ROBOT+ : EMPL_SOLDIER;+ if (!baseCurrent || num >= E_CountHired(baseCurrent, employeeType)) { /*Com_Printf("num: %i / max: %i\n", num, E_CountHired(baseCurrent, EMPL_SOLDIER));*/ return; }- chr = E_GetHiredCharacter(baseCurrent, EMPL_SOLDIER, -(num + 1));+ chr = E_GetHiredCharacter(baseCurrent, employeeType, -(num + 1)); if (!chr) Sys_Error("CL_Select_f: No hired character at pos %i (base: %i)\n", num, baseCurrent->idx); break;@@ -1000,7 +1007,7 @@ * @brief Updates data about teams in aircrafts. * @param[in] *aircraft Pointer to an aircraft for a desired team. */-void CL_UpdateHireVar (aircraft_t *aircraft)+void CL_UpdateHireVar (aircraft_t *aircraft, employeeType_t employeeType) { int i, p; int hired_in_base;@@ -1011,30 +1018,33 @@ base = aircraft->homebase; assert(base);- Cvar_Set("mn_hired", va(_("%i of %i"), base->teamNum[aircraft->idxInBase], aircraft->size));- hired_in_base = E_CountHired(base, EMPL_SOLDIER);+ Cvar_Set("mn_hired", va(_("%i of %i"), *(aircraft->teamSize), aircraft->size));+ hired_in_base = E_CountHired(base, employeeType); /* Uncomment this Com_Printf here for better output in case of problems. */ /* Com_Printf("CL_UpdateHireVar()... aircraft idx: %i, homebase: %s\n", aircraft->idx, base->name); */ /* update curTeam list */ for (i = 0, p = 0; i < hired_in_base; i++) {- employee = E_GetHiredEmployee(base, EMPL_SOLDIER, -(i+1));+ employee = E_GetHiredEmployee(base, employeeType, -(i+1)); if (!employee) Sys_Error("CL_UpdateHireVar: Could not get employee %i\n", i);- if (CL_SoldierInAircraft(employee->idx, aircraft->idx)) {+ if (CL_SoldierInAircraft(employee->idx, employee->type, aircraft->idx)) { base->curTeam[p] = &employee->chr; p++; } }++ /** @todo WARNING temp-disabled because this warning is useless when updating EMPL_ROBOT stuff :(+ * I think checking against aircraft->teamIdxs (and *(aircraft->teamSize)) might be better here if (p != base->teamNum[aircraft->idxInBase]) Sys_Error("CL_UpdateHireVar: SoldiersInBase: %i, teamNum[%i]: %i, p: %i\n", hired_in_base, aircraft->idxInBase, base->teamNum[aircraft->idxInBase], p);-+ */ for (; p < MAX_ACTIVETEAM; p++) base->curTeam[p] = NULL; }@@ -1094,6 +1104,7 @@ } }+ /** * @brief Init the teamlist checkboxes * @sa CL_UpdateHireVar@@ -1103,6 +1114,10 @@ int i, j, k = 0; qboolean alreadyInOtherShip = qfalse; aircraft_t *aircraft;+ employeeType_t employeeType =+ display_heavy_equipment_list+ ? EMPL_ROBOT+ : EMPL_SOLDIER; /* check if we are allowed to be here? */ /* we are only allowed to be here if we already set up a base */@@ -1118,12 +1133,12 @@ } aircraft = &baseCurrent->aircraft[baseCurrent->aircraftCurrent];- CL_UpdateHireVar(aircraft);+ CL_UpdateHireVar(aircraft, employeeType);- for (i = 0; i < gd.numEmployees[EMPL_SOLDIER]; i++) {+ for (i = 0; i < gd.numEmployees[employeeType]; i++) { alreadyInOtherShip = qfalse; /* don't show other base's recruits or none hired ones */- if (!gd.employees[EMPL_SOLDIER][i].hired || gd.employees[EMPL_SOLDIER][i].baseIDHired != baseCurrent->idx)+ if (!gd.employees[employeeType][i].hired || gd.employees[employeeType][i].baseIDHired != baseCurrent->idx) continue; /* search all aircrafts except the current one */@@ -1131,21 +1146,22 @@ if (j == aircraft->idx) continue; /* already on another aircraft */- if (CL_SoldierInAircraft(i, j))+ if (CL_SoldierInAircraft(i, employeeType, j)) alreadyInOtherShip = qtrue; }- Cvar_ForceSet(va("mn_name%i", k), gd.employees[EMPL_SOLDIER][i].chr.name);+ Cvar_ForceSet(va("mn_name%i", k), gd.employees[employeeType][i].chr.name); /* change the buttons */- if (!alreadyInOtherShip && CL_SoldierInAircraft(i, aircraft->idx))+ Cbuf_AddText(va("listdel%i\n", k));+ if (!alreadyInOtherShip && CL_SoldierInAircraft(i, employeeType, aircraft->idx)) Cbuf_AddText(va("listadd%i\n", k)); /* disable the button - the soldier is already on another aircraft */ else if (alreadyInOtherShip) Cbuf_AddText(va("listdisable%i\n", k)); for (j = 0; j < csi.numIDs; j++) {- /* FIXME: Wouldn't it be better here to check for temp containers */- if (j != csi.idFloor && j != csi.idEquip && gd.employees[EMPL_SOLDIER][i].inv.c[j])+ /** @todo FIXME: Wouldn't it be better here to check for temp containers */+ if (j != csi.idFloor && j != csi.idEquip && gd.employees[employeeType][i].inv.c[j]) break; }@@ -1166,31 +1182,50 @@ } /**+ * @brief changes the displayed list from soldiers to heavy equipment (e.g. tanks)+ * @note console command: team_toggle_list+ */+static void CL_ToggleTeamList_f (void)+{+ if (display_heavy_equipment_list) {+ Com_DPrintf("Changing to soldier-list.\n");+ display_heavy_equipment_list = qfalse;+ } else {+ Com_DPrintf("Changing to heavy equipment (tank) list.\n");+ display_heavy_equipment_list = qtrue;+ }+ CL_MarkTeam_f();+ Cbuf_AddText("team_select 0\n");+}++/** * @brief Tells you if a soldier is assigned to an aircraft. * @param[in] employee_idx The index of the soldier in the global list. * @param[in] aircraft_idx The global index of the aircraft. use -1 to check if the soldier is in _any_ aircraft. * @return qboolean qtrue if the soldier was found in the aircraft(s) else: qfalse. * @todo params should be employee_t* and aircraft_t* */-qboolean CL_SoldierInAircraft (int employee_idx, int aircraft_idx)+qboolean CL_SoldierInAircraft (int employee_idx, employeeType_t employeeType, int aircraft_idx) { int i; aircraft_t* aircraft;- if (employee_idx < 0 || employee_idx > gd.numEmployees[EMPL_SOLDIER])+ if (employee_idx < 0 || employee_idx > gd.numEmployees[employeeType]) return qfalse; if (aircraft_idx < 0) { /* Search if he is in _any_ aircraft and return true if it's the case. */ for (i = 0; i < gd.numAircraft; i++) {- if (CL_SoldierInAircraft(employee_idx, i))+ if (CL_SoldierInAircraft(employee_idx, employeeType, i)) return qtrue; } return qfalse; } aircraft = AIR_AircraftGetFromIdx(aircraft_idx);- return AIR_IsInAircraftTeam(aircraft, employee_idx);+ if (!aircraft)+ Com_Printf("CL_SoldierInAircraft: Error No aircraft found for index %i\n", aircraft_idx);+ return AIR_IsInAircraftTeam(aircraft, employee_idx, employeeType); } /**@@ -1212,7 +1247,7 @@ /* for now only soldiers can be assigned to aircrafts */ /* @todo add pilots and 2x2 units */- if (employee->type != EMPL_SOLDIER)+ if (employee->type != EMPL_SOLDIER && employee->type != EMPL_ROBOT) return qfalse; base = &gd.bases[employee->baseIDHired];@@ -1222,7 +1257,7 @@ aircraft = &base->aircraft[i]; assert(aircraft);- if (aircraft->status > AIR_HOME && AIR_IsInAircraftTeam(aircraft, employee->idx))+ if (aircraft->status > AIR_HOME && AIR_IsInAircraftTeam(aircraft, employee->idx, employee->type)) return qtrue; }@@ -1235,7 +1270,7 @@ * @param[in] aircraft_idx The global index of aircraft. Use -1 to remove the soldier from any aircraft. * @param[in] base Pointer to the base where employee is hired. */-void CL_RemoveSoldierFromAircraft (int employee_idx, int aircraft_idx, base_t *base)+void CL_RemoveSoldierFromAircraft (int employee_idx, employeeType_t employeeType, int aircraft_idx, base_t *base) { aircraft_t *aircraft; int i;@@ -1248,7 +1283,7 @@ if (aircraft_idx < 0) { /* Search if he is in _any_ aircraft and set the aircraft_idx if found.. */ for (i = 0; i < gd.numAircraft; i++) {- if (CL_SoldierInAircraft(employee_idx, i) ) {+ if (CL_SoldierInAircraft(employee_idx, employeeType, i) ) { aircraft_idx = i; break; }@@ -1263,8 +1298,8 @@ Com_DPrintf("CL_RemoveSoldierFromAircraft: base: %i - aircraftID: %i - aircraft_idx: %i\n", base->idx, aircraft->idx, aircraft_idx);- INVSH_DestroyInventory(&gd.employees[EMPL_SOLDIER][employee_idx].inv);- AIR_RemoveFromAircraftTeam(aircraft, employee_idx);+ INVSH_DestroyInventory(&gd.employees[employeeType][employee_idx].inv);+ AIR_RemoveFromAircraftTeam(aircraft, employee_idx, employeeType); baseCurrent->teamNum[aircraft->idxInBase]--; }@@ -1287,9 +1322,9 @@ return; /* Counting backwards because teamNum[aircraft->idx] is changed in CL_RemoveSoldierFromAircraft */- for (i = base->teamNum[aircraft->idxInBase]-1; i >= 0; i--) {+ for (i = base->teamNum[aircraft->idxInBase]-1; i > 0; i--) { /* use global aircraft index here */- CL_RemoveSoldierFromAircraft(i, aircraft_idx, base);+ CL_RemoveSoldierFromAircraft(baseCurrent->curTeam[i]->empl_idx, baseCurrent->curTeam[i]->empl_type, aircraft_idx, base); } }@@ -1299,7 +1334,7 @@ * @param[in] aircraft_idx The index of aircraft in the base. * @return returns true if a soldier could be assigned to the aircraft. */-static qboolean CL_AssignSoldierToAircraft (int employee_idx, int aircraft_idx)+static qboolean CL_AssignSoldierToAircraft (int employee_idx, employeeType_t employeeType, int aircraft_idx) { aircraft_t *aircraft = NULL; if (employee_idx < 0 || aircraft_idx < 0)@@ -1310,7 +1345,7 @@ /* Check whether the soldier is already on another aircraft */ Com_DPrintf("CL_AssignSoldierToAircraft: attempting to find idx '%d'\n", employee_idx);- if (CL_SoldierInAircraft(employee_idx, -1)) {+ if (CL_SoldierInAircraft(employee_idx,employeeType, -1)) { Com_DPrintf("CL_AssignSoldierToAircraft: found idx '%d' \n",employee_idx); return qfalse; }@@ -1318,7 +1353,7 @@ /* Assign the soldier to the aircraft. */ if (aircraft->size > baseCurrent->teamNum[aircraft_idx]) { Com_DPrintf("CL_AssignSoldierToAircraft: attemting to add idx '%d' \n",employee_idx);- AIR_AddToAircraftTeam(aircraft, employee_idx);+ AIR_AddToAircraftTeam(aircraft, employee_idx, employeeType); baseCurrent->teamNum[aircraft_idx]++; return qtrue; }@@ -1374,6 +1409,10 @@ int num = -1; employee_t *employee = NULL; aircraft_t *aircraft;+ employeeType_t employeeType =+ display_heavy_equipment_list+ ? EMPL_ROBOT+ : EMPL_SOLDIER; /* check syntax */ if (Cmd_Argc() < 2) {@@ -1383,12 +1422,12 @@ num = atoi(Cmd_Argv(1)); /* baseCurrent is checked here */- if (num >= E_CountHired(baseCurrent, EMPL_SOLDIER) || num >= cl_numnames->integer) {- /*Com_Printf("num: %i, max: %i\n", num, E_CountHired(baseCurrent, EMPL_SOLDIER));*/+ if (num >= E_CountHired(baseCurrent, employeeType) || num >= cl_numnames->integer) {+ /*Com_Printf("num: %i, max: %i\n", num, E_CountHired(baseCurrent, employeeType));*/ return; }- employee = E_GetHiredEmployee(baseCurrent, EMPL_SOLDIER, -(num+1));+ employee = E_GetHiredEmployee(baseCurrent, employeeType, -(num+1)); if (!employee) Sys_Error("CL_AssignSoldier_f: Could not get employee %i\n", num);@@ -1397,21 +1436,21 @@ Com_DPrintf("aircraft->idx: %i - aircraft->idxInBase: %i\n", aircraft->idx, aircraft->idxInBase); assert(aircraft->idxInBase == baseCurrent->aircraftCurrent);- if (CL_SoldierInAircraft(employee->idx, aircraft->idx)) {+ if (CL_SoldierInAircraft(employee->idx, employee->type, aircraft->idx)) { Com_DPrintf("CL_AssignSoldier_f: removing\n"); /* Remove soldier from aircraft/team. */ Cbuf_AddText(va("listdel%i\n", num)); /* use the global aircraft index here */- CL_RemoveSoldierFromAircraft(employee->idx, aircraft->idx, baseCurrent);+ CL_RemoveSoldierFromAircraft(employee->idx, employee->type, aircraft->idx, baseCurrent); Cbuf_AddText(va("listholdsnoequip%i\n", num)); } else { Com_DPrintf("CL_AssignSoldier_f: assigning\n"); /* Assign soldier to aircraft/team if aircraft is not full */- if (CL_AssignSoldierToAircraft(employee->idx, aircraft->idxInBase))+ if (CL_AssignSoldierToAircraft(employee->idx, employee->type, aircraft->idxInBase)) Cbuf_AddText(va("listadd%i\n", num)); } /* Select the desired one anyways. */- CL_UpdateHireVar(aircraft);+ CL_UpdateHireVar(aircraft, employee->type); Cbuf_AddText(va("team_select %i\n", num)); }@@ -1612,7 +1651,7 @@ } for (i = 0, p = 0; i < num; i++)- if (CL_SoldierInAircraft(i, 0))+ if (CL_SoldierInAircraft(i, EMPL_SOLDIER, 0)) gd.bases[0].curTeam[p++] = E_GetHiredCharacter(&gd.bases[0], EMPL_SOLDIER, i); /* gd.bases[0].numHired = p; */@@ -1676,6 +1715,7 @@ Cmd_AddCommand("nextsoldier", CL_NextSoldier_f, _("Toggle to next soldier")); Cmd_AddCommand("saveteamslot", CL_SaveTeamMultiplayerSlot_f, NULL); Cmd_AddCommand("loadteamslot", CL_LoadTeamMultiplayerSlot_f, NULL);+ Cmd_AddCommand("team_toggle_list", CL_ToggleTeamList_f, "Changes between assignment-list for soldiers and heavy equipment (e.g. Tanks)"); #ifdef DEBUG Cmd_AddCommand("teamlist", CL_TeamListDebug_f, "Debug function to show all hired and assigned teammembers"); #endifIndex: src/client/cl_aircraft.c===================================================================--- src/client/cl_aircraft.c (Revision 10243)+++ src/client/cl_aircraft.c (Arbeitskopie)@@ -214,7 +214,7 @@ for (k = 0; k < aircraft->size; k++) if (aircraft->teamIdxs[k] != -1) { Com_Printf("......idx (in global array): %i\n", aircraft->teamIdxs[k]);- chr = E_GetHiredCharacter(base, EMPL_SOLDIER, aircraft->teamIdxs[k]);+ chr = E_GetHiredCharacter(base, aircraft->teamTypes[k] , aircraft->teamIdxs[k]); if (chr) Com_Printf(".........name: %s\n", chr->name); else@@ -596,7 +596,7 @@ baseCurrent->aircraftCurrent = aircraftID; assert(aircraft);- CL_UpdateHireVar(aircraft);+ CL_UpdateHireVar(aircraft, EMPL_SOLDIER); Cvar_SetValue("mn_equipsoldierstate", CL_EquipSoldierState(aircraft)); Cvar_Set("mn_aircraftstatus", AIR_AircraftStatusToName(aircraft));@@ -816,10 +816,11 @@ for (i = 0; i < aircraft->size; i++) { if (aircraft->teamIdxs[i] > -1) {- employee = &(gd.employees[EMPL_SOLDIER][aircraft->teamIdxs[i]]);+ employee = &(gd.employees[aircraft->teamTypes[i]][aircraft->teamIdxs[i]]); assert(employee);- E_DeleteEmployee(employee, EMPL_SOLDIER);+ E_DeleteEmployee(employee, aircraft->teamTypes[i]); aircraft->teamIdxs[i] = -1;+ aircraft->teamTypes[i] = MAX_EMPL; } }@@ -1804,15 +1805,18 @@ void AIR_ResetAircraftTeam (aircraft_t *aircraft) { memset(aircraft->teamIdxs, -1, aircraft->size * sizeof(int));+ memset(aircraft->teamTypes, MAX_EMPL, aircraft->size * sizeof(employeeType_t)); } /** * @brief Adds given employee to given aircraft. * @param[in] *aircraft Pointer to an aircraft, to which we will add employee. * @param[in] employee_idx Index of an employee in global array (?)- * FIXME: is this responsible for adding soldiers to a team in dropship?+ * @todo FIXME: is this responsible for adding soldiers to a team in dropship?+ * ANSWER: yes it seems to be.+ * @todo do we need to update *aircraft->teamSize here as well? */-void AIR_AddToAircraftTeam (aircraft_t *aircraft, int employee_idx)+void AIR_AddToAircraftTeam (aircraft_t *aircraft, int employee_idx, employeeType_t employeeType) { int i;@@ -1821,9 +1825,12 @@ return; } if (*(aircraft->teamSize) < aircraft->size) {+ /* Search for unused place in aircraft and fill it with employee-data. */+ /** @todo do we need to update *aircraft->teamSize here as well? */ for (i = 0; i < aircraft->size; i++) if (aircraft->teamIdxs[i] == -1) { aircraft->teamIdxs[i] = employee_idx;+ aircraft->teamTypes[i] = employeeType; Com_DPrintf("AIR_AddToAircraftTeam: added idx '%d'\n", employee_idx); break; }@@ -1838,17 +1845,22 @@ * @brief Removes given employee to given aircraft. * @param[in] *aircraft Pointer to an aircraft, from which we will remove employee. * @param[in] employee_idx Index of an employee in global array (?)- * FIXME: is this responsible for removing soldiers from a team in dropship?+ * @todo FIXME: is this responsible for removing soldiers from a team in dropship?+ * ANSWER: yes it seems to be.+ * @todo do we need to update *aircraft->teamSize here as well? */-void AIR_RemoveFromAircraftTeam (aircraft_t *aircraft, int employee_idx)+void AIR_RemoveFromAircraftTeam (aircraft_t *aircraft, int employee_idx, employeeType_t employeeType) { int i; assert(aircraft); for (i = 0; i < aircraft->size; i++)- if (aircraft->teamIdxs[i] == employee_idx) {+ /* Search for this exact employee in the aircraft and make his place "unused". */+ /** @todo do we need to update *aircraft->teamSize here as well? */+ if (aircraft->teamIdxs[i] == employee_idx && aircraft->teamTypes[i] == employeeType) { aircraft->teamIdxs[i] = -1;+ aircraft->teamTypes[i] = MAX_EMPL; Com_DPrintf("AIR_RemoveFromAircraftTeam: removed idx '%d' \n", employee_idx); return; }@@ -1864,7 +1876,7 @@ * @param[in] employee_idx deleted employee idx * @sa E_DeleteEmployee */-void AIR_DecreaseAircraftTeamIdxGreaterThan (aircraft_t *aircraft, int employee_idx)+void AIR_DecreaseAircraftTeamIdxGreaterThan (aircraft_t *aircraft, int employee_idx, employeeType_t employeeType) { int i;@@ -1872,7 +1884,7 @@ return; for (i = 0; i < aircraft->size; i++)- if (aircraft->teamIdxs[i] > employee_idx) {+ if (aircraft->teamIdxs[i] > employee_idx && aircraft->teamTypes[i] == employeeType) { aircraft->teamIdxs[i]--; Com_DPrintf("AIR_DecreaseAircraftTeamIdxGreaterThan: decreased idx '%d' \n", aircraft->teamIdxs[i]+1); }@@ -1884,7 +1896,7 @@ * @param[in] employee_idx Employee index in global array. * @return qtrue if an employee with given index is assigned to given aircraft. */-qboolean AIR_IsInAircraftTeam (aircraft_t *aircraft, int employee_idx)+qboolean AIR_IsInAircraftTeam (aircraft_t *aircraft, int employee_idx, employeeType_t employeeType) { int i;@@ -1892,6 +1904,12 @@ Com_DPrintf("AIR_IsInAircraftTeam: No aircraft given\n"); return qfalse; }++ if (employee_idx < 0 || employee_idx > gd.numEmployees[employeeType]) {+ Com_Printf("AIR_IsInAircraftTeam: No valid employee_idx given %i\n", employee_idx);+ return qfalse;+ }+ #ifdef PARANOID else { if (aircraft->homebase)@@ -1899,13 +1917,16 @@ } #endif- for (i = 0; i < aircraft->size; i++)- if (aircraft->teamIdxs[i] == employee_idx) {++ for (i = 0; i < aircraft->size; i++) { + if (aircraft->teamIdxs[i] == employee_idx && aircraft->teamTypes[i] == employeeType) {+ /** @note This also skips the -1 entries in teamIdxs. */ #ifdef DEBUG Com_DPrintf("AIR_IsInAircraftTeam: found idx '%d' (homebase: '%s' - baseCurrent: '%s') \n", employee_idx, aircraft->homebase ? aircraft->homebase->name : "", baseCurrent ? baseCurrent->name : ""); #endif return qtrue; }+ } Com_DPrintf("AIR_IsInAircraftTeam:not found idx '%d' \n", employee_idx); return qfalse; }@@ -2034,7 +2055,7 @@ if (!employee) Sys_Error("AIR_Load()... Could not get employee %i\n", i);- if (CL_SoldierInAircraft(employee->idx, aircraft->idx)) {+ if (CL_SoldierInAircraft(employee->idx, employee->type, aircraft->idx)) { base->curTeam[p] = &employee->chr; p++; }Index: src/client/cl_aircraft.h===================================================================--- src/client/cl_aircraft.h (Revision 10243)+++ src/client/cl_aircraft.h (Arbeitskopie)@@ -194,7 +194,8 @@ int idxInBase; /**< Index in base. See also base_t->numAircraftInBase. */ /* pointer to base->numOnTeam[AIRCRAFT_ID] */ int *teamSize; /**< how many soldiers on board */- int teamIdxs[MAX_ACTIVETEAM]; /**< array of team members on board employee idx*/+ int teamIdxs[MAX_ACTIVETEAM]; /**< array of team members on board (global employee idx) */+ employeeType_t teamTypes[MAX_ACTIVETEAM]; /**< array of team member types on board (employee type) */ aircraftSlot_t weapons[MAX_AIRCRAFTSLOT]; /**< Weapons assigned to aircraft */ int maxWeapons; /**< Total number of weapon slots aboard this aircraft */@@ -255,10 +256,10 @@ void AIR_DestroyAircraft(aircraft_t *aircraft); void AIR_ResetAircraftTeam(aircraft_t *aircraft);-void AIR_AddToAircraftTeam(aircraft_t *aircraft,int idx);-void AIR_RemoveFromAircraftTeam(aircraft_t *aircraft,int idx);-void AIR_DecreaseAircraftTeamIdxGreaterThan(aircraft_t *aircraft,int idx);-qboolean AIR_IsInAircraftTeam(aircraft_t *aircraft,int idx);+void AIR_AddToAircraftTeam(aircraft_t *aircraft, int employee_idx, employeeType_t employeeType);+void AIR_RemoveFromAircraftTeam(aircraft_t *aircraft, int employee_idx, employeeType_t employeeType);+void AIR_DecreaseAircraftTeamIdxGreaterThan(aircraft_t *aircraft, int employee_idx, employeeType_t employeeType);+qboolean AIR_IsInAircraftTeam(aircraft_t *aircraft, int employee_idx, employeeType_t employeeType); void CL_CampaignRunAircraft(int dt); aircraft_t *AIR_GetAircraft(const char *name);Index: src/client/cl_employee.c===================================================================--- src/client/cl_employee.c (Revision 10243)+++ src/client/cl_employee.c (Arbeitskopie)@@ -384,12 +384,12 @@ * @brief Return a given character pointer of a hired employee in the given base of a given type * @param[in] base Which base the employee should be hired in * @param[in] type Which employee type do we search- * @param[in] idx Which employee id (in global employee array)+ * @param[in] employee_idx Which employee idx (index in global employee array) * @return character_t pointer or NULL */-character_t* E_GetHiredCharacter (const base_t* const base, employeeType_t type, int idx)+character_t* E_GetHiredCharacter (const base_t* const base, employeeType_t type, int employee_idx) {- employee_t* employee = E_GetHiredEmployee(base, type, idx); /* Parameter sanity is checked here. */+ employee_t* employee = E_GetHiredEmployee(base, type, employee_idx); /* Parameter sanity is checked here. */ if (employee) return &(employee->chr);@@ -533,8 +533,8 @@ switch (employee->type) { case EMPL_SOLDIER: /* Remove soldier from aircraft/team if he was assigned to one. */- if (CL_SoldierInAircraft(employee->idx, -1)) {- CL_RemoveSoldierFromAircraft(employee->idx, -1, base);+ if (CL_SoldierInAircraft(employee->idx, employee->type, -1)) {+ CL_RemoveSoldierFromAircraft(employee->idx, employee->type, -1, base); } break; case EMPL_WORKER:@@ -686,9 +686,9 @@ if (found) { gd.numEmployees[type]--;- if (type == EMPL_SOLDIER) {- for (i = 0; i < gd.numAircraft; i++)- AIR_DecreaseAircraftTeamIdxGreaterThan(AIR_AircraftGetFromIdx(i),idx);+ if (type == EMPL_SOLDIER || type == EMPL_ROBOT) {+ for (i = 0; i < gd.numAircraft; i++)+ AIR_DecreaseAircraftTeamIdxGreaterThan(AIR_AircraftGetFromIdx(i),idx, EMPL_SOLDIER); } } else { Com_DPrintf("E_DeleteEmployee: Employee wasn't in the global list.\n");Index: src/client/cl_transfer.c===================================================================--- src/client/cl_transfer.c (Revision 10243)+++ src/client/cl_transfer.c (Arbeitskopie)@@ -95,7 +95,7 @@ /* @todo: check capacities also with current personel on transferlist. */ /* Is this a soldier assigned to aircraft? */- if ((employee->type == EMPL_SOLDIER) && CL_SoldierInAircraft(employee->idx, -1)) {+ if ((employee->type == EMPL_SOLDIER) && CL_SoldierInAircraft(employee->idx, employee->type, -1)) { Com_sprintf(popupText, sizeof(popupText), _("%s %s is assigned to aircraft and cannot be\ntransfered to another base.\n"), gd.ranks[employee->chr.rank].shortname, employee->chr.name); MN_Popup(_("Soldier in aircraft"), popupText);Index: src/client/client.h===================================================================--- src/client/client.h (Revision 10243)+++ src/client/client.h (Arbeitskopie)@@ -737,8 +737,8 @@ void CL_SendCurTeamInfo(struct dbuffer * buf, character_t ** team, int num); void CL_AddCarriedToEq(equipDef_t * equip); void CL_ParseCharacterData(struct dbuffer *msg, qboolean updateCharacter);-qboolean CL_SoldierInAircraft(int employee_idx, int aircraft_idx);-void CL_RemoveSoldierFromAircraft(int employee_idx, int aircraft_idx, struct base_s *base);+qboolean CL_SoldierInAircraft(int employee_idx, employeeType_t employeeType, int aircraft_idx);+void CL_RemoveSoldierFromAircraft(int employee_idx, employeeType_t employeeType, int aircraft_idx, struct base_s *base); void CL_RemoveSoldiersFromAircraft(int aircraft_idx, struct base_s *base); /* cl_radar.c */@@ -818,7 +818,7 @@ /* cl_team.c: CL_UpdateHireVar(), CL_ReloadAndRemoveCarried() */ /* cl_team.c should have own header file afterall 24042007 Zenerka */ qboolean CL_SoldierAwayFromBase(employee_t *soldier);-void CL_UpdateHireVar(aircraft_t *aircraft);+void CL_UpdateHireVar(aircraft_t *aircraft, employeeType_t employeeType); void CL_ReloadAndRemoveCarried(aircraft_t *aircraft, equipDef_t * equip); void CL_CleanTempInventory(base_t* base);Index: src/client/cl_campaign.c===================================================================--- src/client/cl_campaign.c (Revision 10243)+++ src/client/cl_campaign.c (Arbeitskopie)@@ -2278,12 +2278,13 @@ Cvar_Set("map_dropship", aircraft->id); /* retrieve the correct team */- for (i = 0, p = 0; i < cl_numnames->integer; i++)- if (CL_SoldierInAircraft(i, aircraft->idx)) {+ for (i = 0, p = 0; i < aircraft->size; i++) {+ if (aircraft->teamIdxs[i] != -1) { assert(p < MAX_ACTIVETEAM);- baseCurrent->curTeam[p] = E_GetHiredCharacter(baseCurrent, EMPL_SOLDIER, i);+ baseCurrent->curTeam[p] = E_GetHiredCharacter(baseCurrent, aircraft->teamTypes[i], aircraft->teamIdxs[i]); p++; }+ } /* manage inventory */ ccs.eMission = baseCurrent->storage; /* copied, including arrays inside! */@@ -2512,8 +2513,9 @@ Com_DPrintf("CL_UpdateCharacterStats: baseCurrent: %s\n", baseCurrent->name);+ /** @todo What about UGVs/Tanks? */ for (i = 0; i < gd.numEmployees[EMPL_SOLDIER]; i++)- if (CL_SoldierInAircraft(i, gd.interceptAircraft) ) {+ if (CL_SoldierInAircraft(i, EMPL_SOLDIER, gd.interceptAircraft) ) { Com_DPrintf("CL_UpdateCharacterStats: searching for soldier: %i\n", i); chr = E_GetHiredCharacter(baseCurrent, EMPL_SOLDIER, -(idx+1)); assert(chr);@@ -2706,7 +2708,7 @@ /* Backward loop because gd.numEmployees[EMPL_SOLDIER] is decremented by E_DeleteEmployee */ for (i = gd.numEmployees[EMPL_SOLDIER] - 1; i >= 0; i--) { /* if employee is marked as dead */- if (CL_SoldierInAircraft(i, gd.interceptAircraft)) /* DEBUG? */+ if (CL_SoldierInAircraft(i, EMPL_SOLDIER, gd.interceptAircraft)) /* DEBUG? */ numberofsoldiers++; Com_DPrintf("CL_GameResults_f - try to get player %i \n", i);Index: base/ufos/menu_team.ufo===================================================================--- base/ufos/menu_team.ufo (Revision 10243)+++ base/ufos/menu_team.ufo (Arbeitskopie)@@ -920,6 +920,16 @@ // ================== // additional stuff // ==================+ pic bt_switch_list+ {+ tooltip "_Toggle between assignment of soldiers and heavy equipment"+ image hud/buttons2+ mousefx true+ pos "880 720"+ texl "0 0"+ texh "64 37"+ click { cmd "team_toggle_list" }+ } pic bt_go {