1package com.fs.starfarer.api.characters;
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.LinkedHashMap;
6import java.util.LinkedHashSet;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.characters.MutableCharacterStatsAPI.SkillLevelAPI;
13import com.fs.starfarer.api.fleet.FleetMemberAPI;
14import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
15import com.fs.starfarer.api.impl.campaign.ids.Stats;
16import com.fs.starfarer.api.impl.campaign.plog.OfficerSkillGainRecord;
17import com.fs.starfarer.api.impl.campaign.plog.PlaythroughLog;
18import com.fs.starfarer.api.ui.Alignment;
19import com.fs.starfarer.api.ui.ButtonAPI;
20import com.fs.starfarer.api.ui.TooltipMakerAPI;
21import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
22import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipLocation;
23import com.fs.starfarer.api.util.Misc;
27 public static class OfficerEffectData {
30 List<String> removeSkills =
new ArrayList<String>();
31 List<String> removeElite =
new ArrayList<String>();
33 boolean unusable =
false;
34 boolean makeMercenary;
39 public boolean hasChanges() {
41 !removeSkills.isEmpty() || !removeElite.isEmpty() || makeMercenary;
45 public static class OfficerDataMap {
48 public void setMap(OfficerDataMap map, Map<String, Object> dataMap) {
49 String key = getClass().getSimpleName();
50 dataMap.put(key, map);
52 public OfficerDataMap
getMap(Map<String, Object> dataMap) {
53 String key = getClass().getSimpleName();
54 OfficerDataMap map = (OfficerDataMap)dataMap.get(key);
56 map =
new OfficerDataMap();
57 dataMap.put(key, map);
76 if (sl.getLevel() >= 2f) {
84 OfficerDataMap result =
new OfficerDataMap();
90 Map<OfficerDataAPI, FleetMemberAPI> members =
new LinkedHashMap<OfficerDataAPI, FleetMemberAPI>();
91 Set<OfficerDataAPI> unusable =
new LinkedHashSet<OfficerDataAPI>();
92 if (maxOfficersPre > maxOfficersPost) {
99 if (count > maxOfficersPost && !merc) {
100 unusable.add(officer);
107 if (member.getCaptain() == officer.getPerson()) {
108 members.put(officer, member);
131 OfficerEffectData effect =
new OfficerEffectData();
135 if (members.containsKey(data)) {
136 effect.member = members.get(data);
138 if (unusable.contains(data)) {
139 effect.unusable =
true;
142 if (stats.
getLevel() > maxLevelPost && maxLevelPost < maxLevelPre) {
143 final List<String> skillsInOrderOfGain =
new ArrayList<String>();
145 if (rec.getPersonId().equals(person.
getId()) && !rec.isElite() &&
147 skillsInOrderOfGain.add(rec.getSkillId());
150 Collections.reverse(skillsInOrderOfGain);
155 int skillsToRemove = stats.
getLevel() - maxLevelPost;
156 for (
int i = 0; i < skillsToRemove && !skillsInOrderOfGain.isEmpty(); i++) {
157 effect.removeSkills.add(skillsInOrderOfGain.remove(0));
159 if (!effect.removeSkills.isEmpty()) {
160 effect.newLevel = maxLevelPost;
165 if (numElite > maxElitePost && maxElitePost < maxElitePre) {
166 final List<String> eliteInOrderOfGain =
new ArrayList<String>();
168 if (rec.getPersonId().equals(person.
getId()) && rec.isElite() &&
170 !effect.removeSkills.contains(rec.getSkillId())) {
171 eliteInOrderOfGain.add(rec.getSkillId());
174 Collections.reverse(eliteInOrderOfGain);
176 int eliteToRemove = numElite - maxElitePost;
177 for (
int i = 0; i < eliteToRemove && !eliteInOrderOfGain.isEmpty(); i++) {
178 effect.removeElite.add(eliteInOrderOfGain.remove(0));
183 if (effect.hasChanges()) {
184 result.map.put(person, effect);
211 info.
addPara(
"Officers whose skills that exceed the new limits will have their excess skills removed, or become mercenaries on a temporary contract. "
212 +
"Officers that already had those kinds of skills when acquired will not be affected.", opad,
214 "excess skills removed");
215 float initPad = opad;
216 for (
final OfficerEffectData data : map.map.values()) {
217 final PersonAPI person = data.data.getPerson();
219 if (data.member ==
null) {
220 str +=
", unassigned, will...";
222 str +=
", commanding the " + data.member.getShipName() +
223 " (" + data.member.getHullSpec().getHullNameWithDashClass() +
"), will...";
226 String mercText =
"Become a mercenary, drawing higher pay on a new contract";
227 String otherText =
"";
229 if (data.unusable && data.removeElite.isEmpty() && data.removeSkills.isEmpty()) {
230 if (data.member ==
null) {
231 otherText =
"Become unable to be assigned command of a ship";
233 otherText =
"Be relieved of command, and unable to be assigned command of a ship";
238 part1 =
"Be relieved of command, and";
241 if (!data.removeElite.isEmpty() && data.removeSkills.isEmpty()) {
242 part2 =
" lose excess elite skill effects";
243 }
else if (data.removeElite.isEmpty() && !data.removeSkills.isEmpty()) {
244 part2 =
" lose excess skills";
246 part2 =
" lose excess skills and elite skill effects";
248 if (part1.isEmpty()) {
249 part2 = part2.trim();
252 otherText = part1 + part2;
263 public boolean isTooltipExpandable(Object tooltipParam) {
266 public float getTooltipWidth(Object tooltipParam) {
269 public void createTooltip(
TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
272 tooltip.
addPara(
"This officer has the following skills:", 0f);
275 if (!data.removeSkills.isEmpty()) {
276 tooltip.
addPara(
"They will lose the following skills:", opad);
278 for (String skillId : data.removeSkills) {
283 if (!data.removeElite.isEmpty()) {
284 tooltip.
addPara(
"They will lose the elite effects of the following skills:", opad);
286 for (String skillId : data.removeElite) {
292 }, TooltipLocation.RIGHT);
297 data.buttonMerc.setChecked(
false);
300 public boolean isTooltipExpandable(Object tooltipParam) {
303 public float getTooltipWidth(Object tooltipParam) {
306 public void createTooltip(
TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
310 tooltip.
addPara(
"This officer's pay will be increased from %s to %s per month,"
311 +
" and they will want to leave after %s days, when their contract expires.", 0f,
317 tooltip.
addPara(
"Extending the contract beyond that will require a %s.", 10f,
320 }, TooltipLocation.RIGHT);
328 OfficerDataMap map =
getMap(dataMap);
330 for (OfficerEffectData data : map.map.values()) {
331 if (data.buttonMerc == button) {
332 data.makeMercenary =
true;
333 data.buttonMerc.setChecked(
true);
334 data.buttonOther.setChecked(
false);
336 }
else if (data.buttonOther == button) {
337 data.makeMercenary =
false;
338 data.buttonMerc.setChecked(
false);
339 data.buttonOther.setChecked(
true);
347 OfficerDataMap map =
getMap(dataMap);
349 for (OfficerEffectData data : map.map.values()) {
350 if (data.makeMercenary) {
354 if (data.unusable && data.member !=
null) {
358 for (String
id : data.removeElite) {
362 for (String
id : data.removeSkills) {
367 if (data.newLevel != stats.
getLevel()) {
static SettingsAPI getSettings()
static FactoryAPI getFactory()
static SectorAPI getSector()
int getNumEliteSkills(PersonAPI person)
void infoButtonPressed(ButtonAPI button, Object param, Map< String, Object > dataMap)
void setMap(OfficerDataMap map, Map< String, Object > dataMap)
OfficerDataMap getEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to)
boolean hasEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to)
OfficerDataMap getMap(Map< String, Object > dataMap)
void printEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, TooltipMakerAPI info, Map< String, Object > dataMap)
void applyEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, Map< String, Object > dataMap)
int getMaxEliteSkills(MutableCharacterStatsAPI stats)
int getMaxLevel(MutableCharacterStatsAPI stats)
float computeEffective(float baseValue)
static final String EXCEPTIONAL_SLEEPER_POD_OFFICER
static final String OFFICER_MAX_ELITE_SKILLS_MOD
static final String OFFICER_MAX_LEVEL_MOD
void removeOfficerSkillRecord(String personId, String skillId, boolean elite)
static PlaythroughLog getInstance()
List< OfficerSkillGainRecord > getOfficerSkillsLearned()
static Color getStoryOptionColor()
static String getDGSCredits(float num)
static String ucFirst(String str)
static boolean isMercenary(PersonAPI person)
static Color getNegativeHighlightColor()
static Color getHighlightColor()
static void setMercHiredNow(PersonAPI person)
static void setMercenary(PersonAPI person, boolean mercenary)
static float getOfficerSalary(PersonAPI officer)
float getFloat(String key)
FleetDataAPI getFleetData()
List< OfficerDataAPI > getOfficersCopy()
List< FleetMemberAPI > getMembersListCopy()
CampaignFleetAPI getPlayerFleet()
boolean getBoolean(String key)
DynamicStatsAPI getDynamic()
List< SkillLevelAPI > getSkillsCopy()
MutableStat getOfficerNumber()
void setSkillLevel(String id, float level)
float getSkillLevel(String id)
MutableCharacterStatsAPI getStats()
MemoryAPI getMemoryWithoutUpdate()
PositionAPI setXAlignOffset(float xAlignOffset)
PositionAPI getPosition()
StatBonus getMod(String id)