76 if (random ==
null) random = Misc.random;
77 FactionAPI faction = fleet.getFaction();
78 FactionDoctrineAPI doctrine = faction.getDoctrine();
79 if (!
derelictMode && params !=
null && params.doctrineOverride !=
null) {
80 doctrine = params.doctrineOverride;
82 List<FleetMemberAPI> members = fleet.getFleetData().getMembersListCopy();
83 if (members.isEmpty())
return;
85 Map<String, AICoreOfficerPlugin> plugins =
new HashMap<String, AICoreOfficerPlugin>();
87 plugins.put(Commodities.OMEGA_CORE, Misc.getAICoreOfficerPlugin(Commodities.OMEGA_CORE));
88 plugins.put(Commodities.ALPHA_CORE, Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE));
89 plugins.put(Commodities.BETA_CORE, Misc.getAICoreOfficerPlugin(Commodities.BETA_CORE));
90 plugins.put(Commodities.GAMMA_CORE, Misc.getAICoreOfficerPlugin(Commodities.GAMMA_CORE));
91 String nothing =
"nothing";
94 for (FleetMemberAPI member : members) {
95 fleetFP += member.getFleetPointCost();
97 boolean allowAlphaAnywhere = fleetFP > 150f;
98 boolean allowBetaAnywhere = fleetFP > 75f;
101 boolean integrate = params !=
null && !params.doNotIntegrateAICores;
104 int numCommanderSkills = 0;
105 if (allowBetaAnywhere) numCommanderSkills++;
106 if (allowAlphaAnywhere) numCommanderSkills++;
107 if (params !=
null && params.noCommanderSkills !=
null && params.noCommanderSkills) numCommanderSkills = 0;
117 int minCores = (int) (fleetFP / fpPerCore * (params !=
null ? params.officerNumberMult : 1f));
118 if (params !=
null) {
119 minCores += params.officerNumberBonus;
121 if (minCores < 1) minCores = 1;
123 boolean debug =
true;
126 WeightedRandomPicker<FleetMemberAPI> withOfficers =
new WeightedRandomPicker<FleetMemberAPI>(random);
129 for (FleetMemberAPI member : members) {
130 if (member.isFighterWing())
continue;
131 if (member.isCivilian())
continue;
132 int size = member.getHullSpec().getHullSize().ordinal();
133 if (size > maxSize) {
138 List<FleetMemberAPI> allWithOfficers =
new ArrayList<FleetMemberAPI>();
140 for (FleetMemberAPI member : members) {
142 if (member.isCivilian())
continue;
143 if (member.isFighterWing())
continue;
145 float fp = member.getFleetPointCost();
147 WeightedRandomPicker<String> picker =
new WeightedRandomPicker<String>(random);
149 if (params !=
null && params.aiCores == OfficerQuality.AI_GAMMA) {
150 picker.add(Commodities.GAMMA_CORE, fp);
151 }
else if (params !=
null && params.aiCores == OfficerQuality.AI_BETA) {
152 picker.add(Commodities.BETA_CORE, fp);
153 }
else if (params !=
null && params.aiCores == OfficerQuality.AI_ALPHA) {
154 picker.add(Commodities.ALPHA_CORE, fp);
155 }
else if (params !=
null && params.aiCores == OfficerQuality.AI_OMEGA) {
156 picker.add(Commodities.OMEGA_CORE, fp);
157 }
else if (params !=
null && params.aiCores == OfficerQuality.AI_BETA_OR_GAMMA) {
158 if (member.isCapital() || member.isCruiser()) {
159 picker.add(Commodities.BETA_CORE, fp);
160 }
else if (allowAlphaAnywhere) {
161 picker.add(Commodities.BETA_CORE, fp);
163 picker.add(Commodities.BETA_CORE, fp/2f);
165 picker.add(Commodities.GAMMA_CORE, fp);
168 picker.add(Commodities.GAMMA_CORE, fp);
170 if (member.isCapital() || member.isCruiser()) {
171 picker.add(Commodities.ALPHA_CORE, fp);
172 }
else if (allowAlphaAnywhere) {
173 picker.add(Commodities.ALPHA_CORE, fp);
176 if (member.isCruiser() || member.isDestroyer()) {
177 picker.add(Commodities.BETA_CORE, fp/2f);
178 }
else if (allowBetaAnywhere && member.isFrigate()) {
179 picker.add(Commodities.BETA_CORE, fp);
182 if (member.isDestroyer() || member.isFrigate()) {
183 picker.add(Commodities.GAMMA_CORE, fp);
188 if (addedCores >= minCores) {
189 picker.add(nothing, 10f * picker.getTotal()/fp);
192 String pick = picker.pick();
194 System.out.println(
"Picked [" + pick +
"] for " + member.getHullId());
196 AICoreOfficerPlugin plugin = plugins.get(pick);
197 if (plugin !=
null) {
200 PersonAPI person = plugin.createPerson(pick, fleet.getFaction().getId(), random);
201 member.setCaptain(person);
206 if (!member.isFighterWing() && !member.isCivilian()) {
207 withOfficers.add(member, fp);
210 allWithOfficers.add(member);
213 if (addedCores > 0 && params !=
null && params.officerNumberMult <= 0) {
218 if (withOfficers.isEmpty() && !allWithOfficers.isEmpty()) {
219 withOfficers.add(allWithOfficers.get(0), 1f);
223 FleetMemberAPI flagship = withOfficers.pick();
225 PersonAPI commander = flagship.getCaptain();
226 commander.setRankId(Ranks.SPACE_COMMANDER);
227 commander.setPostId(Ranks.POST_FLEET_COMMANDER);
228 fleet.setCommander(commander);
229 fleet.getFleetData().setFlagship(flagship);
235 PersonAPI person = member.getCaptain();
236 if (!person.isAICore())
return;
238 person.getStats().setLevel(person.getStats().getLevel() + 1);
240 person.getStats().setSkipRefresh(
true);
249 if (member.getVariant() !=
null && member.getVariant().getWeaponGroups() !=
null) {
252 float missileWeight = 0f;
253 for (String slotId : member.getVariant().getFittedWeaponSlots()) {
254 WeaponSpecAPI spec = member.getVariant().getWeaponSpec(slotId);
255 if (spec ==
null)
continue;
257 if (spec.getSize() == WeaponSize.MEDIUM) w = 2f;
258 if (spec.getSize() == WeaponSize.LARGE) w = 4f;
260 if (spec.getAIHints().contains(AIHints.PD)) {
263 if (spec.getType() == WeaponType.MISSILE) {
269 float decks = member.getNumFlightDecks();
271 weight += decks * 4f;
272 pdWeight += decks * 4f;
275 boolean hasUsefulPD = pdWeight > weight * 0.25f;
276 boolean hasEnoughMissiles = missileWeight > weight * 0.2f;
279 if (hasUsefulPD && !hasEnoughMissiles) {
280 person.getStats().setSkillLevel(Skills.POINT_DEFENSE, 2);
281 person.getStats().setSkipRefresh(
false);
287 if (member.getHullSpec() !=
null && member.getHullSpec().hasTag(Factions.DERELICT) &&
288 person.getStats().getSkillLevel(Skills.BALLISTIC_MASTERY) <= 0) {
289 person.getStats().setSkillLevel(Skills.BALLISTIC_MASTERY, 2);
291 if (person.getStats().getSkillLevel(Skills.ENERGY_WEAPON_MASTERY) <= 0) {
292 person.getStats().setSkillLevel(Skills.ENERGY_WEAPON_MASTERY, 2);
294 person.getStats().setSkillLevel(Skills.MISSILE_SPECIALIZATION, 2);
298 if (member.isCapital() || member.isStation()) {
299 if (person.getStats().getSkillLevel(Skills.POLARIZED_ARMOR) <= 0) {
300 person.getStats().setSkillLevel(Skills.COMBAT_ENDURANCE, 0);
301 person.getStats().setSkillLevel(Skills.POLARIZED_ARMOR, 2);
306 person.getStats().setSkipRefresh(
false);
326 public static void addCommanderSkills(PersonAPI commander, CampaignFleetAPI fleet, FleetParamsV3 params,
int numSkills, Random random) {
327 if (random ==
null) random =
new Random();
328 if (numSkills <= 0)
return;
330 MutableCharacterStatsAPI stats = commander.getStats();
332 FactionDoctrineAPI doctrine = fleet.getFaction().getDoctrine();
333 if (params !=
null && params.doctrineOverride !=
null) {
334 doctrine = params.doctrineOverride;
337 List<String> skills =
new ArrayList<String>(doctrine.getCommanderSkills());
338 if (skills.isEmpty())
return;
340 if (random.nextFloat() < doctrine.getCommanderSkillsShuffleProbability()) {
341 Collections.shuffle(skills, random);
344 stats.setSkipRefresh(
true);
346 boolean debug =
true;
348 if (debug) System.out.println(
"Generating commander skills, person level " + stats.getLevel() +
", skills: " + numSkills);
350 for (String skillId : skills) {
351 if (debug) System.out.println(
"Selected skill: [" + skillId +
"]");
352 stats.setSkillLevel(skillId, 1);
354 if (picks >= numSkills) {
358 if (debug) System.out.println(
"Done generating commander skills\n");
360 stats.setSkipRefresh(
false);
361 stats.refreshCharacterStatsEffects();