001package com.fs.starfarer.api.impl.campaign.intel;
002
003import java.awt.Color;
004import java.util.Random;
005import java.util.Set;
006
007import org.lwjgl.util.vector.Vector2f;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.FactionAPI;
011import com.fs.starfarer.api.campaign.InteractionDialogAPI;
012import com.fs.starfarer.api.campaign.RepLevel;
013import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
014import com.fs.starfarer.api.campaign.SectorEntityToken;
015import com.fs.starfarer.api.campaign.TextPanelAPI;
016import com.fs.starfarer.api.campaign.econ.MarketAPI;
017import com.fs.starfarer.api.characters.PersonAPI;
018import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
019import com.fs.starfarer.api.impl.campaign.ids.Factions;
020import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
021import com.fs.starfarer.api.impl.campaign.ids.People;
022import com.fs.starfarer.api.impl.campaign.intel.events.PerseanLeagueHostileActivityFactor;
023import com.fs.starfarer.api.impl.campaign.missions.DelayedFleetEncounter;
024import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality;
025import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetSize;
026import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerNum;
027import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality;
028import com.fs.starfarer.api.ui.Alignment;
029import com.fs.starfarer.api.ui.SectorMapAPI;
030import com.fs.starfarer.api.ui.TooltipMakerAPI;
031import com.fs.starfarer.api.util.IntervalUtil;
032import com.fs.starfarer.api.util.Misc;
033
034public class GensHannanMachinations extends BaseIntelPlugin {
035        
036
037        // in $player memory
038        public static String AGREED_TO_PAY_HOUSE_HANNAN_AGAIN = "$agreedToPayHouseHannanAgain";
039        
040        // in $global memory
041        public static String MACHINATIONS_IN_EFFECT = "$houseHannanMachinationsInEffect";
042        
043        public static boolean isMachinationsInEffect() {
044                return Global.getSector().getMemoryWithoutUpdate().getBoolean(MACHINATIONS_IN_EFFECT);
045        }
046        public static boolean isAgreedToPayHouseHannanAgain() {
047                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(AGREED_TO_PAY_HOUSE_HANNAN_AGAIN);
048        }
049        public static void setAgreedToPayHouseHannanAgain(boolean value) {
050                Global.getSector().getPlayerMemoryWithoutUpdate().set(AGREED_TO_PAY_HOUSE_HANNAN_AGAIN, value);
051                if (!value) {
052                        Global.getSector().getPlayerMemoryWithoutUpdate().unset(AGREED_TO_PAY_HOUSE_HANNAN_AGAIN);
053                }
054        }
055        
056        public static boolean canRemakeDealWithHouseHannan() {
057                return !isAgreedToPayHouseHannanAgain() && 
058                                PerseanLeagueMembership.isLeagueMember() &&
059                                isMachinationsInEffect() &&
060                                !PerseanLeagueMembership.isPayingHouseHannan();
061        }
062        
063        public static String KEY = "$plGHMachinations_ref";
064        public static GensHannanMachinations get() {
065                return (GensHannanMachinations) Global.getSector().getMemoryWithoutUpdate().get(KEY);
066        }
067        
068        public static String UPDATE_PARAM_START = "update_param_start";
069        public static String UPDATE_PARAM_MACHINATION = "update_param_machination";
070        
071        public static float PROB_ACTION_TAKEN = 0.5f;
072        public static float PROB_BOUNTY_HUNTER = 0.25f;
073        
074        
075        protected FactionAPI faction = null;
076        protected IntervalUtil interval = new IntervalUtil(10f, 110f);
077        protected Random random = new Random();
078        protected int repDamageRemaining = 100;
079        
080        protected ReputationAdjustmentResult recent = null;
081        protected boolean recentIsBountyHunter = false;
082        protected long recentTimestamp = 0L;
083        
084        public GensHannanMachinations(InteractionDialogAPI dialog) {
085                if (get() != null) return;
086                
087                this.faction = Global.getSector().getFaction(Factions.PERSEAN);
088                
089                setImportant(true);
090                
091                TextPanelAPI text = null;
092                if (dialog != null) text = dialog.getTextPanel();
093                
094                Global.getSector().addScript(this);
095                //Global.getSector().getListenerManager().addListener(this);
096                Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
097                
098                Global.getSector().getMemoryWithoutUpdate().set(MACHINATIONS_IN_EFFECT, true);
099                
100                Global.getSector().getIntelManager().addIntel(this, true);
101                
102                sendUpdateIfPlayerHasIntel(dialog, text);
103        }
104        
105        @Override
106        protected void advanceImpl(float amount) {
107                super.advanceImpl(amount);
108                
109                if (isEnded() || isEnding()) return;
110                
111                
112                float days = Misc.getDays(amount);
113                //days *= 100f;
114                interval.advance(days);
115                
116                if (!interval.intervalElapsed()) return;
117                
118                if (PerseanLeagueHostileActivityFactor.getKazeron(false) == null) {
119                        setImportant(false);
120                        endAfterDelay();
121                        return;
122                }
123                
124                if (random.nextFloat() > PROB_ACTION_TAKEN) return;
125                
126                
127                if (isAgreedToPayHouseHannanAgain() && random.nextFloat() < PROB_BOUNTY_HUNTER) {
128                        sendBountyHunter();
129                        return;
130                }
131                
132                int repLoss = 5 + random.nextInt(11);
133                repLoss = Math.min(repLoss, repDamageRemaining);
134                
135                RepLevel limit = RepLevel.NEUTRAL;
136                if (isAgreedToPayHouseHannanAgain()) {
137                        limit = RepLevel.VENGEFUL;
138                }
139                
140                ReputationAdjustmentResult result = Misc.adjustRep(Factions.PERSEAN,
141                                                                (float)repLoss * -0.01f, limit, null, false, false);
142                
143                repLoss = Math.min(repLoss, (int)Math.abs(Math.round(result.delta * 100f)));
144                
145                if (repLoss > 0) {
146                        repDamageRemaining -= Math.abs(repLoss);
147                        recent = result;
148                        recentTimestamp = Global.getSector().getClock().getTimestamp();
149                        recentIsBountyHunter = false;
150                        
151                        sendUpdateIfPlayerHasIntel(UPDATE_PARAM_MACHINATION, false);
152                }
153                
154                if (repDamageRemaining <= 0f) {
155                        setImportant(false);
156                        endAfterDelay();
157                }
158        }
159        
160        protected void sendBountyHunter() {
161                recent = new ReputationAdjustmentResult(0);
162                recentTimestamp = Global.getSector().getClock().getTimestamp();
163                recentIsBountyHunter = true;
164                
165                DelayedFleetEncounter e = new DelayedFleetEncounter(random, "GensHannanMachinations");
166                e.setDelayShort();
167                //e.setDelayNone();
168                //e.setLocationCoreOnly(true, market.getFactionId());
169                e.setLocationInnerSector(true, Factions.INDEPENDENT);
170                e.beginCreate();
171                e.triggerCreateFleet(FleetSize.HUGE, FleetQuality.SMOD_1, Factions.PERSEAN, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f());
172                e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER);
173                e.triggerSetFleetFaction(Factions.INDEPENDENT);
174                e.triggerMakeNoRepImpact();
175                e.triggerSetStandardAggroInterceptFlags();
176                e.triggerMakeFleetIgnoreOtherFleets();
177                e.triggerSetFleetGenericHailPermanent("GensHannanMachinationsHail");
178                e.endCreate();
179                
180                sendUpdateIfPlayerHasIntel(UPDATE_PARAM_MACHINATION, false);
181        }
182        
183        @Override
184        protected void notifyEnding() {
185                super.notifyEnding();
186                
187                Global.getSector().getMemoryWithoutUpdate().unset(KEY);
188                Global.getSector().getMemoryWithoutUpdate().unset(MACHINATIONS_IN_EFFECT);
189                //Global.getSector().getListenerManager().removeListener(this);
190        }
191        
192        @Override
193        protected void notifyEnded() {
194                Global.getSector().removeScript(this);
195                super.notifyEnded();
196        }
197
198        protected Object readResolve() {
199                return this;
200        }
201        
202        public String getBaseName() {
203                return "Gens Hannan Machinations";
204        }
205
206        public String getName() {
207                String postfix = "";
208                return getBaseName() + postfix;
209        }
210        
211        @Override
212        public FactionAPI getFactionForUIColors() {
213                return faction;
214        }
215
216        public String getSmallDescriptionTitle() {
217                return getName();
218        }
219
220        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
221                Color h = Misc.getHighlightColor();
222                Color g = Misc.getGrayColor();
223                float pad = 3f;
224                float opad = 10f;
225                
226                float initPad = pad;
227                if (mode == ListInfoMode.IN_DESC) initPad = opad;
228                
229                Color tc = getBulletColorForMode(mode);
230                
231                bullet(info);
232                boolean isUpdate = getListInfoParam() != null;
233
234                if (recent != null) {
235                        int days = (int)Global.getSector().getClock().getElapsedDaysSince(recentTimestamp);
236                        if (days > 60f) {
237                                recentTimestamp = 0;
238                                recent = null;
239                                recentIsBountyHunter = false;
240                        } else {
241                                if (recentIsBountyHunter) {
242                                        info.addPara("A bounty hunter was recently hired to eliminate you", tc, initPad);
243                                } else {
244                                        CoreReputationPlugin.addAdjustmentMessage(recent.delta, faction, null, 
245                                                        null, null, info, tc, isUpdate, initPad);
246                                        if (!isUpdate) {
247                                                String daysStr = days == 1 ? "day" : "days";
248                                                info.addPara("%s " + daysStr + " ago", 0f, tc, h, "" + days);
249                                        }
250                                }
251                        }
252                }
253
254        
255                unindent(info);
256        }
257        
258        public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
259                Color h = Misc.getHighlightColor();
260                Color g = Misc.getGrayColor();
261                Color tc = Misc.getTextColor();
262                float pad = 3f;
263                float opad = 10f;
264
265                info.addImage(getFaction().getLogo(), width, 128, opad);
266                
267                info.addPara("You've gone back on a deal with Gens Hannan, and they work behind the scenes"
268                                + "to damage your standing with the Persean League, and worse.", opad,
269                                getFaction().getBaseUIColor(), "Persean League");
270                
271                if (isEnding() || isEnded()) {
272                        info.addPara("You sources indicate that the further action by Gens Hannan "
273                                        + "is unlikely at this time.", opad);
274                } else {
275                        info.addPara("It's likely that at some point this work will become less of a priority, but "
276                                        + "for now, their agents go about ruining your reputation with commendable "
277                                        + "vigor and discretion.", opad);
278                        
279                        if (isAgreedToPayHouseHannanAgain()) {
280                                info.addPara("There is no hope of reconciliation, and the gloves are off. There is a possibility "
281                                                + "of your being brought into active hostility with the League, and of bounty hunters "
282                                                + "being hired and equipped for the job.", opad, Misc.getNegativeHighlightColor(),
283                                                "active hostility with the League", "bounty hunters");
284                        } else {
285                                if (!canRemakeDealWithHouseHannan()) {
286                                        info.addPara("You are not considered trustworthy enough for Gens Hannan to deal with again, and "
287                                                        + "these actions are in the way of setting an example for others.", opad);
288                                } else {
289                                        if (getMapLocation(null) != null) {
290                                                PersonAPI person = People.getPerson(People.REYNARD_HANNAN);
291                                                if (person != null) {
292                                                        TooltipMakerAPI sub = info.beginImageWithText(person.getPortraitSprite(), 64f);
293                                                        sub.addPara("You may be able to negotiate an end to this by going to Kazeron and speaking with "
294                                                                        + "Reynard Hannan.", 0f, h, 
295                                                                        "speaking with Reynard Hannan");
296                                                        info.addImageWithText(opad);
297                                                }
298                                        }
299                                }
300                        }
301                }
302                
303                if (recent != null) {
304                        info.addSectionHeading("Recent events", 
305                                        getFaction().getBaseUIColor(), getFaction().getDarkUIColor(), 
306                                        Alignment.MID, opad);
307                        addBulletPoints(info, ListInfoMode.IN_DESC);
308                }
309        }
310        
311        
312        public String getIcon() {
313                return faction.getCrest();
314        }
315        
316        public Set<String> getIntelTags(SectorMapAPI map) {
317                Set<String> tags = super.getIntelTags(map);
318                //tags.add(Tags.INTEL_AGREEMENTS);
319                tags.add(faction.getId());
320                return tags;
321        }
322        
323        @Override
324        public SectorEntityToken getMapLocation(SectorMapAPI map) {
325                MarketAPI kazeron = PerseanLeagueHostileActivityFactor.getKazeron(false);
326                if (kazeron != null) {
327                        return kazeron.getPrimaryEntity();
328                }
329                return null;
330        }
331
332
333        public FactionAPI getFaction() {
334                return faction;
335        }
336        
337        public void endMachinations(TextPanelAPI text) {
338                if (!isEnded() && !isEnding()) {
339                        setImportant(false);
340                        endImmediately();
341                        //sendUpdate(new Object(), text);
342                }
343        }
344        
345}
346
347
348
349
350
351