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"); #endif Index: 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 {