Starsector API
Loading...
Searching...
No Matches
OfficerManagerEvent.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.events;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.HashSet;
6import java.util.Iterator;
7import java.util.List;
8import java.util.Map;
9import java.util.Random;
10import java.util.Set;
11
12import java.awt.Color;
13
14import org.apache.log4j.Logger;
15
16import com.fs.starfarer.api.EveryFrameScript;
17import com.fs.starfarer.api.Global;
18import com.fs.starfarer.api.campaign.CampaignClockAPI;
19import com.fs.starfarer.api.campaign.CampaignFleetAPI;
20import com.fs.starfarer.api.campaign.CargoAPI;
21import com.fs.starfarer.api.campaign.FactionAPI;
22import com.fs.starfarer.api.campaign.InteractionDialogAPI;
23import com.fs.starfarer.api.campaign.PlayerMarketTransaction;
24import com.fs.starfarer.api.campaign.TextPanelAPI;
25import com.fs.starfarer.api.campaign.econ.MarketAPI;
26import com.fs.starfarer.api.campaign.listeners.ColonyInteractionListener;
27import com.fs.starfarer.api.campaign.rules.MemoryAPI;
28import com.fs.starfarer.api.characters.AdminData;
29import com.fs.starfarer.api.characters.FullName.Gender;
30import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
31import com.fs.starfarer.api.characters.MutableCharacterStatsAPI.SkillLevelAPI;
32import com.fs.starfarer.api.characters.OfficerDataAPI;
33import com.fs.starfarer.api.characters.PersonAPI;
34import com.fs.starfarer.api.characters.SkillSpecAPI;
35import com.fs.starfarer.api.impl.campaign.ids.Factions;
36import com.fs.starfarer.api.impl.campaign.ids.Personalities;
37import com.fs.starfarer.api.impl.campaign.ids.Ranks;
38import com.fs.starfarer.api.impl.campaign.ids.Skills;
39import com.fs.starfarer.api.impl.campaign.ids.Stats;
40import com.fs.starfarer.api.impl.campaign.ids.Tags;
41import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
42import com.fs.starfarer.api.impl.campaign.rulecmd.CallEvent.CallableEvent;
43import com.fs.starfarer.api.plugins.OfficerLevelupPlugin;
44import com.fs.starfarer.api.util.IntervalUtil;
45import com.fs.starfarer.api.util.Misc;
46import com.fs.starfarer.api.util.Misc.Token;
47import com.fs.starfarer.api.util.TimeoutTracker;
48import com.fs.starfarer.api.util.WeightedRandomPicker;
49
58public class OfficerManagerEvent extends BaseEventPlugin implements CallableEvent, ColonyInteractionListener, EveryFrameScript {
59
60 public static class AvailableOfficer {
61 public PersonAPI person;
62 public String marketId;
63 public int hiringBonus;
64 public int salary;
65 public float timeRemaining = 0f;
66 public AvailableOfficer(PersonAPI person, String marketId, int hiringBonus, int salary) {
67 this.person = person;
68 this.marketId = marketId;
69 this.hiringBonus = hiringBonus;
70 this.salary = salary;
71 }
72
73 }
74
75 public static Logger log = Global.getLogger(OfficerManagerEvent.class);
76
77 protected IntervalUtil removeTracker = new IntervalUtil(1f, 3f);
78
79 protected List<AvailableOfficer> available = new ArrayList<AvailableOfficer>();
80 protected List<AvailableOfficer> availableAdmins = new ArrayList<AvailableOfficer>();
81
83
84 protected long seed = 0;
85
87 readResolve();
89 }
90
91 Object readResolve() {
92 if (availableAdmins == null) {
93 availableAdmins = new ArrayList<AvailableOfficer>();
94 }
95 if (recentlyChecked == null) {
97 }
98 if (seed == 0) {
99 seed = Misc.random.nextLong();
100 }
101// Global.getSector().getListenerManager().addListener(this);
102 return this;
103 }
104
106
108 if (recentlyChecked.contains(market.getId())) return;
109
111 if (market.getFaction().isNeutralFaction()) return;
112 if (!market.isInEconomy()) return;
114
115
117
122 //adminProb = 1f;
123
124 log.info("Spawning officers/admins at " + market.getId());
125 log.info(" officerProb: " + officerProb);
126 log.info(" additionalProb: " + additionalProb);
127 log.info(" mercProb: " + mercProb);
128 log.info(" adminProb: " + adminProb);
129 log.info("");
130
131
133 long mult = clock.getCycle() * 12L + clock.getMonth();
134
135 //Random random = new Random(seed + market.getId().hashCode() * mult);
136 Random random = Misc.getRandom(seed + market.getId().hashCode() * mult, 11);
137 //random = new Random();
138
139 float dur = getOfficerDuration(random);
140 recentlyChecked.add(market.getId(), dur * 0.5f);
141
142 if (random.nextFloat() < officerProb) {
143 boolean merc = random.nextFloat() < mercProb;
144 AvailableOfficer officer = createOfficer(merc, market, random);
145 //officer.person.setPortraitSprite(pickPortraitPreferNonDuplicate(officer.person.getFaction(), officer.person.getGender()));
146 // always independent at this point
148 officer.timeRemaining = dur;
149 addAvailable(officer);
150 log.info("Added officer at " + officer.marketId + "");
151
152 if (random.nextFloat() < officerProb * additionalProb) {
153 merc = random.nextFloat() < mercProb;
154 officer = createOfficer(merc, market, random);
155 //officer.person.setPortraitSprite(pickPortraitPreferNonDuplicate(officer.person.getFaction(), officer.person.getGender()));
157 officer.timeRemaining = dur;
158 addAvailable(officer);
159 log.info("Added officer at [" + officer.marketId + "]");
160 }
161 }
162
163 if (random.nextFloat() < adminProb) {
164 AvailableOfficer officer = createAdmin(market, random);
165 officer.timeRemaining = dur;
166 //officer.person.setPortraitSprite(pickPortraitPreferNonDuplicate(officer.person.getFaction(), officer.person.getGender()));
168 addAvailableAdmin(officer);
169 log.info("Added admin at [" + officer.marketId + "]");
170 }
171 }
172
173 protected float getOfficerDuration(Random random) {
174 return 60f + 60f * random.nextFloat();
175 }
176
177 public void advance(float amount) {
178 float days = Global.getSector().getClock().convertToDays(amount);
179
180 recentlyChecked.advance(days);
181
182// if (!Global.getSector().getListenerManager().hasListener(this)) {
183// Global.getSector().getListenerManager().addListener(this);
184// }
185
187 if (removeTracker.intervalElapsed()) {
189
190 float interval = removeTracker.getIntervalDuration();
191
192 for (AvailableOfficer curr : new ArrayList<AvailableOfficer>(available)) {
193 curr.timeRemaining -= interval;
194 if (curr.timeRemaining <= 0) {
195 removeAvailable(curr);
196 log.info("Removed officer from [" + curr.marketId + "]");
197 }
198 }
199 for (AvailableOfficer curr : new ArrayList<AvailableOfficer>(availableAdmins)) {
200 curr.timeRemaining -= interval;
201 if (curr.timeRemaining <= 0) {
202 removeAvailable(curr);
203 log.info("Removed freelance admin from [" + curr.marketId + "]");
204 }
205 }
206 }
207
208 }
209
211 for (AvailableOfficer curr : new ArrayList<AvailableOfficer>(available)) {
212 if (Global.getSector().getEconomy().getMarket(curr.marketId) == null) {
213 removeAvailable(curr);
214 }
215 }
216 for (AvailableOfficer curr : new ArrayList<AvailableOfficer>(availableAdmins)) {
217 if (Global.getSector().getEconomy().getMarket(curr.marketId) == null) {
218 removeAvailable(curr);
219 }
220 }
221 }
222
223 public void addAvailable(AvailableOfficer officer) {
224 if (officer == null) return;
225
226 available.add(officer);
227
229 }
230
231 public void addAvailableAdmin(AvailableOfficer officer) {
232 if (officer == null) return;
233
234 availableAdmins.add(officer);
235
237 }
238
239 protected void setEventDataAndAddToMarket(AvailableOfficer officer) {
240 MarketAPI market = Global.getSector().getEconomy().getMarket(officer.marketId);
241 if (market == null) return;
242 market.getCommDirectory().addPerson(officer.person);
243 market.addPerson(officer.person);
244
245 officer.person.getMemoryWithoutUpdate().set("$ome_hireable", true);
246 officer.person.getMemoryWithoutUpdate().set("$ome_eventRef", this);
247 officer.person.getMemoryWithoutUpdate().set("$ome_hiringBonus", Misc.getWithDGS(officer.hiringBonus));
248 officer.person.getMemoryWithoutUpdate().set("$ome_salary", Misc.getWithDGS(officer.salary));
249 }
250
251 public void removeAvailable(AvailableOfficer officer) {
252 if (officer == null) return;
253
254 available.remove(officer);
255 availableAdmins.remove(officer);
256
257 MarketAPI market = Global.getSector().getEconomy().getMarket(officer.marketId);
258 if (market != null) {
259 market.getCommDirectory().removePerson(officer.person);
260 market.removePerson(officer.person);
261 }
262
263 officer.person.getMemoryWithoutUpdate().unset("$ome_hireable");
264 officer.person.getMemoryWithoutUpdate().unset("$ome_eventRef");
265 officer.person.getMemoryWithoutUpdate().unset("$ome_hiringBonus");
266 officer.person.getMemoryWithoutUpdate().unset("$ome_salary");
267 }
268
269 public static String pickPortraitPreferNonDuplicate(FactionAPI faction, Gender gender) {
270 if (faction == null) {
272 }
275
276 Set<String> exclude = new HashSet<String>();
278 if (Global.getSector().getPlayerFleet() != null) {
280 exclude.add(od.getPerson().getPortraitSprite());
281 }
282 }
284 exclude.add(ad.getPerson().getPortraitSprite());
285 }
286 for (String p : all.getItems()) {
287 if (exclude.contains(p)) continue;
288 picker.add(p);
289 }
290 if (picker.isEmpty()) {
291 picker = all;
292 }
293 return picker.pick();
294 }
295
296 protected AvailableOfficer createAdmin(MarketAPI market, Random random) {
297// WeightedRandomPicker<MarketAPI> marketPicker = new WeightedRandomPicker<MarketAPI>();
298// for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
299// marketPicker.add(market, market.getSize());
300// }
301// MarketAPI market = marketPicker.pick();
302 if (market == null) return null;
303
305 tierPicker.add(0, 60);
306 tierPicker.add(1, 40);
307
308 int tier = tierPicker.pick();
309
310 PersonAPI person = createAdmin(market.getFaction(), tier, random);
312
313 String hireKey = "adminHireTier" + tier;
314 int hiringBonus = Global.getSettings().getInt(hireKey);
315
316 int salary = (int) Misc.getAdminSalary(person);
317
318 AvailableOfficer result = new AvailableOfficer(person, market.getId(), hiringBonus, salary);
319 return result;
320 }
321
322 public static PersonAPI createAdmin(FactionAPI faction, int tier, Random random) {
323 if (random == null) random = new Random();
324 PersonAPI person = faction.createRandomPerson(random);
325
326 person.getStats().setSkipRefresh(true);
328 List<String> allSkillIds = Global.getSettings().getSortedSkillIds();
329 for (String skillId : allSkillIds) {
330 SkillSpecAPI skill = Global.getSettings().getSkillSpec(skillId);
331 if (skill.hasTag(Skills.TAG_DEPRECATED)) continue;
332 if (skill.hasTag(Skills.TAG_PLAYER_ONLY)) continue;
333 if (skill.hasTag(Skills.TAG_AI_CORE_ONLY)) continue;
334 if (skill.isAdminSkill()) {
335 picker.add(skillId);
336 }
337 }
338
339 for (int i = 0; i < tier && !picker.isEmpty(); i++) {
340 String pick = picker.pickAndRemove();
341 person.getStats().setSkillLevel(pick, 3);
342 }
343
344 person.getMemoryWithoutUpdate().set("$ome_isAdmin", true);
345 person.getMemoryWithoutUpdate().set("$ome_adminTier", tier);
346
347
348 person.setRankId(Ranks.CITIZEN);
350
351
352 WeightedRandomPicker<String> personalityPicker = faction.getPersonalityPicker().clone();
353
354 String personality = personalityPicker.pick();
355 person.setPersonality(personality);
356
357 person.getStats().setSkipRefresh(false);
359
360 //person.setPortraitSprite(pickPortrait(person.getFaction(), person.getGender()));
361
362 return person;
363 }
364
365
366 protected AvailableOfficer createOfficer(boolean isMerc, MarketAPI market, Random random) {
367// WeightedRandomPicker<MarketAPI> marketPicker = new WeightedRandomPicker<MarketAPI>();
368// for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
369// marketPicker.add(market, market.getSize());
370// }
371// MarketAPI market = marketPicker.pick();
372 if (market == null) return null;
373
374 //FactionAPI faction = Global.getSector().getFaction(Factions.INDEPENDENT);
375
376 int level = 1;
377 if ((float) Math.random() > 0.75f) level = 2;
378
379 float payMult = 1f;
380
381 PersonAPI person = null;
382 if (isMerc) {
383 payMult = Global.getSettings().getFloat("officerMercPayMult");
384
385 int minLevel = Global.getSettings().getInt("officerMercMinLevel");
386 int maxLevel = Global.getSettings().getInt("officerMercMaxLevel");
387 level = minLevel + Misc.random.nextInt(maxLevel + 1 - minLevel);
388
389 int numElite = 1;
390 if (level == maxLevel) numElite = 2;
391 person = createMercInternal(market.getFaction(), level, numElite, true, random);
392
395 Misc.setMercenary(person, true);
396 } else {
397 person = createOfficerInternal(market.getFaction(), level, true, random);
399 }
400
402
403
404
405 int salary = (int) Misc.getOfficerSalary(person);
406 AvailableOfficer result = new AvailableOfficer(person, market.getId(),
407 (int) (person.getStats().getLevel() * 2000* payMult), salary);
408 return result;
409 }
410
411 public static PersonAPI createOfficerInternal(FactionAPI faction, int level, boolean allowNonDoctrinePersonality, Random random) {
412 return createOfficer(faction, level, SkillPickPreference.ANY, allowNonDoctrinePersonality,
413 null, false, false, -1, random);
414 }
415
416 public static PersonAPI createMercInternal(FactionAPI faction, int level, int numElite, boolean allowNonDoctrinePersonality, Random random) {
417// SkillPickPreference pref = SkillPickPreference.GENERIC;
418// float f = (float) Math.random();
419// if (f < 0.05f) {
420// pref = SkillPickPreference.ANY;
421// } else if (f < 0.1f) {
422// pref = SkillPickPreference.PHASE;
423// } else if (f < 0.25f) {
424// pref = SkillPickPreference.CARRIER;
425// }
426 SkillPickPreference pref = SkillPickPreference.ANY;
427 return createOfficer(faction, level, pref, allowNonDoctrinePersonality,
428 null, true, true, numElite, random);
429 }
430
431
432 public static enum SkillPickPreference {
433 @Deprecated CARRIER,
434 @Deprecated GENERIC,
435 @Deprecated PHASE,
436
441 YES_ENERGY_YES_BALLISTIC_YES_MISSILE_YES_DEFENSE,
442 YES_ENERGY_YES_BALLISTIC_NO_MISSILE_YES_DEFENSE,
443 YES_ENERGY_YES_BALLISTIC_YES_MISSILE_NO_DEFENSE,
444 YES_ENERGY_YES_BALLISTIC_NO_MISSILE_NO_DEFENSE,
445 YES_ENERGY_NO_BALLISTIC_YES_MISSILE_YES_DEFENSE,
446 YES_ENERGY_NO_BALLISTIC_NO_MISSILE_YES_DEFENSE,
447 YES_ENERGY_NO_BALLISTIC_YES_MISSILE_NO_DEFENSE,
448 YES_ENERGY_NO_BALLISTIC_NO_MISSILE_NO_DEFENSE,
449 NO_ENERGY_YES_BALLISTIC_YES_MISSILE_YES_DEFENSE,
450 NO_ENERGY_YES_BALLISTIC_NO_MISSILE_YES_DEFENSE,
451 NO_ENERGY_YES_BALLISTIC_YES_MISSILE_NO_DEFENSE,
452 NO_ENERGY_YES_BALLISTIC_NO_MISSILE_NO_DEFENSE,
453 NO_ENERGY_NO_BALLISTIC_YES_MISSILE_YES_DEFENSE,
454 NO_ENERGY_NO_BALLISTIC_NO_MISSILE_YES_DEFENSE,
455 NO_ENERGY_NO_BALLISTIC_YES_MISSILE_NO_DEFENSE,
456 NO_ENERGY_NO_BALLISTIC_NO_MISSILE_NO_DEFENSE,
457 ANY,
458 }
459
460 public static PersonAPI createOfficer(FactionAPI faction, int level) {
461 return createOfficer(faction, level, false);
462 }
463 public static PersonAPI createOfficer(FactionAPI faction, int level, boolean allowNonDoctrinePersonality) {
464 return createOfficer(faction, level, SkillPickPreference.ANY, allowNonDoctrinePersonality,
465 null, false, true, -1, null);
466 }
467 public static PersonAPI createOfficer(FactionAPI faction, int level, SkillPickPreference pref, Random random) {
468 return createOfficer(faction, level, pref, false, null, false, true, -1, random);
469 }
470
471 public static boolean DEBUG = false;
472 public static PersonAPI createOfficer(FactionAPI faction, int level,
473 SkillPickPreference pref, boolean allowNonDoctrinePersonality,
474 CampaignFleetAPI fleet, boolean allowAnyLevel,
475 boolean withEliteSkills, int eliteSkillsNumOverride, Random random) {
476 if (random == null) random = new Random();
477
478 //DEBUG = true;
479
480 PersonAPI person = faction.createRandomPerson(random);
481 person.setFleet(fleet);
483
484 if (!allowAnyLevel) {
485 if (level > plugin.getMaxLevel(person)) level = plugin.getMaxLevel(person);
486 }
487
488 person.getStats().setSkipRefresh(true);
489
490 if (DEBUG) System.out.println("Generating officer\n");
491
492 List<String> fixedSkills = new ArrayList<String>(faction.getDoctrine().getOfficerSkills());
493 Iterator<String> iter = fixedSkills.iterator();
494 while (iter.hasNext()) {
495 String id = iter.next();
497 if (spec != null && spec.hasTag(Skills.TAG_PLAYER_ONLY)) {
498 iter.remove();
499 }
500 }
501
502 if (random.nextFloat() < faction.getDoctrine().getOfficerSkillsShuffleProbability()) {
503 Collections.shuffle(fixedSkills, random);
504 }
505
506 int numSpec = 0;
507 for (int i = 0; i < 1; i++) {
508 List<String> skills = plugin.pickLevelupSkills(person, random);
509 String skillId = pickSkill(person, skills, pref, numSpec, random);
510 if (!fixedSkills.isEmpty()) {
511 skillId = fixedSkills.remove(0);
512 }
513 if (skillId != null) {
514 if (DEBUG) System.out.println("Picking initial skill: " + skillId);
515 person.getStats().increaseSkill(skillId);
517 if (spec.hasTag(Skills.TAG_SPEC)) numSpec++;
518
519 }
520 }
521
522// level = 20;
523// pref = SkillPickPreference.NON_CARRIER;
524
525 long xp = plugin.getXPForLevel(level);
526 OfficerDataAPI officerData = Global.getFactory().createOfficerData(person);
527 officerData.addXP(xp, null, false);
528
529 //DEBUG = true;
530
531 officerData.makeSkillPicks(random);
532
533 while (officerData.canLevelUp(allowAnyLevel)) {
534 String skillId = pickSkill(officerData.getPerson(), officerData.getSkillPicks(), pref, numSpec, random);
535 if (!fixedSkills.isEmpty()) {
536 skillId = fixedSkills.remove(0);
537 }
538 if (skillId != null) {
539 if (DEBUG) System.out.println("Leveling up " + skillId);
540 officerData.levelUp(skillId, random);
542 if (spec.hasTag(Skills.TAG_SPEC)) numSpec++;
543
544 if (allowAnyLevel && officerData.getSkillPicks().isEmpty()) {
545 officerData.makeSkillPicks(random);
546 }
547 } else {
548 break;
549 }
550 }
551
552 if (withEliteSkills && eliteSkillsNumOverride != 0) {
553 int num = eliteSkillsNumOverride;
554 if (num < 0) {
555 num = plugin.getMaxEliteSkills(person);
556 if (num > 1 && faction != null && faction.getId().startsWith("tri")) {
557 //System.out.println("32fwefwe");
558 num = plugin.getMaxEliteSkills(person);
559 }
560 }
561 addEliteSkills(person, num, random);
562 }
563
564 if (DEBUG) System.out.println("Done\n");
565
568
569
570 WeightedRandomPicker<String> personalityPicker = faction.getPersonalityPicker().clone();
571 if (allowNonDoctrinePersonality) {
572 personalityPicker.add(Personalities.TIMID, 4f);
573 personalityPicker.add(Personalities.CAUTIOUS, 4f);
574 personalityPicker.add(Personalities.STEADY, 4f);
575 personalityPicker.add(Personalities.AGGRESSIVE, 4f);
576 personalityPicker.add(Personalities.RECKLESS, 4f);
577 }
578
579 String personality = personalityPicker.pick();
580 person.setPersonality(personality);
581
582
583 person.getStats().setSkipRefresh(false);
585
586 return person;
587 }
588
589 public static void addEliteSkills(PersonAPI person, int num, Random random) {
590 if (num <= 0) return;
591
593 for (SkillLevelAPI sl : person.getStats().getSkillsCopy()) {
594 if (sl.getSkill().hasTag(Skills.TAG_ELITE_PLAYER_ONLY)) continue;
595 if (sl.getSkill().isAptitudeEffect()) continue;
596 if (!sl.getSkill().isCombatOfficerSkill()) continue;
597 picker.add(sl.getSkill().getId(), 1f);
598 }
599
600 for (int i = 0; i < num && !picker.isEmpty(); i++) {
601 String id = picker.pickAndRemove();
602 if (id != null) {
603 if (DEBUG) System.out.println("Making skill elite: " + id);
604 person.getStats().increaseSkill(id);
605 }
606 }
607 }
608
609 public static String pickSkill(PersonAPI person, List<String> skills, SkillPickPreference pref, int numSpec, Random random) {
610 if (random == null) random = new Random();
611
613 List<String> generic = new ArrayList<String>();
614
615 boolean energy = pref.name().contains("YES_ENERGY"); // lol
616 boolean ballistic = pref.name().contains("YES_BALLISTIC");
617 boolean missile = pref.name().contains("YES_MISSILE");
618 boolean defense = pref.name().contains("YES_DEFENSE");
619
620
621 for (String id : skills) {
623// boolean carrierSkill = spec.hasTag(Skills.TAG_CARRIER);
624// boolean phaseSkill = spec.hasTag(Skills.TAG_PHASE);
625// boolean specSkill = spec.hasTag(Skills.TAG_SPEC);
626
627 boolean energySkill = spec.hasTag(Skills.TAG_ENERGY_WEAPONS);
628 boolean ballisticSkill = spec.hasTag(Skills.TAG_BALLISTIC_WEAPONS);
629 boolean missileSkill = spec.hasTag(Skills.TAG_MISSILE_WEAPONS);
630 boolean defenseSkill = spec.hasTag(Skills.TAG_ACTIVE_DEFENSES);
631
632 boolean preferred = true;
633
634 if (pref != SkillPickPreference.ANY) {
635 if (!energy && energySkill) preferred = false;
636 if (!ballistic && ballisticSkill) preferred = false;
637 if (!missile && missileSkill) preferred = false;
638 if (!defense && defenseSkill) preferred = false;
639 }
640
641// preferred |= pref == SkillPickPreference.ANY;
642// preferred |= pref == SkillPickPreference.CARRIER && carrierSkill;
643// preferred |= pref == SkillPickPreference.PHASE && phaseSkill;
644// preferred |= pref == SkillPickPreference.GENERIC && !phaseSkill && !carrierSkill;
645
646// if (specSkill && !carrierSkill && !phaseSkill && numSpec >= 1) {
647// preferred = false;
648// }
649 if (spec.hasTag(Skills.TAG_PLAYER_ONLY)) {
650 preferred = false;
651 }
652
653 if (preferred) {
654 picker.add(id);
655 } else {
656 generic.add(id);
657 }
658
659 //if ((!specSkill || numSpec < 1) && !carrierSkill && !phaseSkill) {
660 //}
661 }
662 if (picker.isEmpty()) {
663 picker.addAll(generic);
664 if (picker.isEmpty()) {
665 picker.addAll(skills);
666 }
667 }
668
669 return picker.pick();
670 }
671
672
673 public boolean callEvent(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
674 String action = params.get(0).getString(memoryMap);
675
677 CargoAPI cargo = playerFleet.getCargo();
678
679 if (action.equals("printSkills")) {
680 String personId = params.get(1).getString(memoryMap);
681 AvailableOfficer officer = getOfficer(personId);
682 boolean admin = false;
683 int adminTier = 0;
684 if (officer == null) {
685 officer = getAdmin(personId);
686 admin = true;
687 if (officer != null) {
688 adminTier = (int) officer.person.getMemoryWithoutUpdate().getFloat("$ome_adminTier");
689 }
690 }
691
692 if (officer != null) {
693 MutableCharacterStatsAPI stats = officer.person.getStats();
694 TextPanelAPI text = dialog.getTextPanel();
695
696 Color hl = Misc.getHighlightColor();
697 Color red = Misc.getNegativeHighlightColor();
698
699 //text.addParagraph("-----------------------------------------------------------------------------");
700
701// if (!admin) {
702// text.addParagraph("Level: " + (int) stats.getLevel());
703// text.highlightInLastPara(hl, "" + (int) stats.getLevel());
704// }
705// for (String skillId : Global.getSettings().getSortedSkillIds()) {
706// int level = (int) stats.getSkillLevel(skillId);
707// if (level > 0) {
708// SkillSpecAPI spec = Global.getSettings().getSkillSpec(skillId);
709// String skillName = spec.getName();
710// if (spec.isAptitudeEffect()) {
711// skillName += " Aptitude";
712// }
713//
714// if (level <= 1) {
715// text.addParagraph(skillName);
716// } else {
717// text.addParagraph(skillName + " (Elite)");
718// }
719// //text.highlightInLastPara(hl, "" + level);
720// }
721// }
722
723 text.addSkillPanel(officer.person, admin);
724
726
727 if (!admin) {
728 String personality = Misc.lcFirst(officer.person.getPersonalityAPI().getDisplayName());
729 text.addParagraph("Personality: " + personality + ", level: " + stats.getLevel());
730 text.highlightInLastPara(hl, personality, "" + stats.getLevel());
731 text.addParagraph(officer.person.getPersonalityAPI().getDescription());
732 }
733
734 //text.addParagraph("-----------------------------------------------------------------------------");
735
736 text.setFontInsignia();
737 }
738 } else if (action.equals("hireOfficer")) {
739 String personId = params.get(1).getString(memoryMap);
740 AvailableOfficer officer = getOfficer(personId);
741 boolean admin = false;
742 if (officer == null) {
743 officer = getAdmin(personId);
744 if (officer != null) {
745 officer.person.setPostId(Ranks.POST_ADMINISTRATOR);
746 }
747 admin = true;
748 }
749 if (officer != null) {
750 removeAvailable(officer);
751 if (admin) {
752 Global.getSector().getCharacterData().addAdmin(officer.person);
753 } else {
754 playerFleet.getFleetData().addOfficer(officer.person);
755 if (Misc.isMercenary(officer.person)) {
756 Misc.setMercHiredNow(officer.person);
757 } else {
758 officer.person.setPostId(Ranks.POST_OFFICER);
759 }
760 }
761 AddRemoveCommodity.addCreditsLossText(officer.hiringBonus, dialog.getTextPanel());
762 if (admin) {
763 AddRemoveCommodity.addAdminGainText(officer.person, dialog.getTextPanel());
764 } else {
765 AddRemoveCommodity.addOfficerGainText(officer.person, dialog.getTextPanel());
766 }
767 playerFleet.getCargo().getCredits().subtract(officer.hiringBonus);
768 if (playerFleet.getCargo().getCredits().get() <= 0) {
769 playerFleet.getCargo().getCredits().set(0);
770 }
771 }
772 } else if (action.equals("atLimit")) {
773 //int max = (int) Global.getSettings().getFloat("officerPlayerMax");
774 String personId = params.get(1).getString(memoryMap);
775 AvailableOfficer officer = getOfficer(personId);
776 boolean admin = false;
777 if (officer == null) {
778 officer = getAdmin(personId);
779 admin = true;
780 }
781 int max = playerFleet.getCommander().getStats().getOfficerNumber().getModifiedInt();
782 if (admin) {
783 max = playerFleet.getCommander().getStats().getAdminNumber().getModifiedInt();
784 return Global.getSector().getCharacterData().getAdmins().size() >= max;
785 }
786
787 // can hire more than max number of admins, just can't assign to govern w/o penalty
788 //if (admin) return false;
789
790 return Misc.getNumNonMercOfficers(playerFleet) >= max;
791
792 //return playerFleet.getFleetData().getOfficersCopy().size() >= max;
793 } else if (action.equals("canAfford")) {
794 String personId = params.get(1).getString(memoryMap);
795 AvailableOfficer officer = getOfficer(personId);
796 if (officer == null) {
797 officer = getAdmin(personId);
798 }
799 if (officer != null) {
800 return playerFleet.getCargo().getCredits().get() >= officer.hiringBonus;
801 } else {
802 return false;
803 }
804 }
805
806 return true;
807 }
808
809 public AvailableOfficer getOfficer(String personId) {
810 for (AvailableOfficer officer: available) {
811 if (officer.person.getId().equals(personId)) {
812 return officer;
813 }
814 }
815 return null;
816 }
817
818 public AvailableOfficer getAdmin(String personId) {
819 for (AvailableOfficer officer: availableAdmins) {
820 if (officer.person.getId().equals(personId)) {
821 return officer;
822 }
823 }
824 return null;
825 }
826
828
829 }
830
834
835 public boolean runWhilePaused() {
836 return false;
837 }
838
839 public boolean isDone() {
840 return false;
841 }
842}
843
844
845
846
847
848
849
850
851
852
static SettingsAPI getSettings()
Definition Global.java:57
static FactoryAPI getFactory()
Definition Global.java:41
static Logger getLogger(Class c)
Definition Global.java:32
static SectorAPI getSector()
Definition Global.java:65
float computeEffective(float baseValue)
void reportPlayerMarketTransaction(PlayerMarketTransaction transaction)
boolean callEvent(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
static String pickSkill(PersonAPI person, List< String > skills, SkillPickPreference pref, int numSpec, Random random)
static String pickPortraitPreferNonDuplicate(FactionAPI faction, Gender gender)
static PersonAPI createOfficer(FactionAPI faction, int level, SkillPickPreference pref, Random random)
static PersonAPI createAdmin(FactionAPI faction, int tier, Random random)
static PersonAPI createOfficer(FactionAPI faction, int level, boolean allowNonDoctrinePersonality)
static PersonAPI createOfficerInternal(FactionAPI faction, int level, boolean allowNonDoctrinePersonality, Random random)
AvailableOfficer createOfficer(boolean isMerc, MarketAPI market, Random random)
AvailableOfficer createAdmin(MarketAPI market, Random random)
static PersonAPI createOfficer(FactionAPI faction, int level)
static PersonAPI createMercInternal(FactionAPI faction, int level, int numElite, boolean allowNonDoctrinePersonality, Random random)
static PersonAPI createOfficer(FactionAPI faction, int level, SkillPickPreference pref, boolean allowNonDoctrinePersonality, CampaignFleetAPI fleet, boolean allowAnyLevel, boolean withEliteSkills, int eliteSkillsNumOverride, Random random)
static void addEliteSkills(PersonAPI person, int num, Random random)
static final String OFFICER_IS_MERC_PROB_MOD
Definition Stats.java:40
static final String OFFICER_ADDITIONAL_PROB_MULT_MOD
Definition Stats.java:39
static final String MARKET_NO_OFFICER_SPAWN
Definition Tags.java:111
static void addAdminGainText(PersonAPI admin, TextPanelAPI text)
static void addOfficerGainText(PersonAPI officer, TextPanelAPI text)
static void addCreditsLossText(int credits, TextPanelAPI text)
static String getWithDGS(float num)
Definition Misc.java:1381
static String lcFirst(String str)
Definition Misc.java:565
static boolean isMercenary(PersonAPI person)
Definition Misc.java:5454
static Color getNegativeHighlightColor()
Definition Misc.java:802
static Random getRandom(long seed, int level)
Definition Misc.java:2973
static float getAdminSalary(PersonAPI admin)
Definition Misc.java:4409
static Color getHighlightColor()
Definition Misc.java:792
static void setMercHiredNow(PersonAPI person)
Definition Misc.java:5459
static void setMercenary(PersonAPI person, boolean mercenary)
Definition Misc.java:5468
static int getNumNonMercOfficers(CampaignFleetAPI fleet)
Definition Misc.java:5223
static float getOfficerSalary(PersonAPI officer)
Definition Misc.java:4416
OfficerDataAPI createOfficerData(PersonAPI person)
SkillSpecAPI getSkillSpec(String skillId)
List< String > getSortedSkillIds()
WeightedRandomPicker< String > getPersonalityPicker()
WeightedRandomPicker< String > getPortraits(Gender gender)
List< OfficerDataAPI > getOfficersCopy()
FactionAPI getFaction(String factionId)
ListenerManagerAPI getListenerManager()
void addSkillPanel(PersonAPI person, boolean admin)
void highlightInLastPara(Color color, String ...strings)
void set(String key, Object value)
void setPortraitSprite(String portraitSprite)
void setFleet(CampaignFleetAPI fleet)
MutableCharacterStatsAPI getStats()
void setPersonality(String personality)
List< String > pickLevelupSkills(PersonAPI person, Random random)