001package com.fs.starfarer.api.impl.campaign.intel.bar.events;
002
003import java.awt.Color;
004import java.util.List;
005import java.util.Map;
006import java.util.Set;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.CargoAPI;
011import com.fs.starfarer.api.campaign.FactionAPI;
012import com.fs.starfarer.api.campaign.InteractionDialogAPI;
013import com.fs.starfarer.api.campaign.RepLevel;
014import com.fs.starfarer.api.campaign.RuleBasedDialog;
015import com.fs.starfarer.api.campaign.SectorEntityToken;
016import com.fs.starfarer.api.campaign.TextPanelAPI;
017import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
018import com.fs.starfarer.api.campaign.econ.MarketAPI;
019import com.fs.starfarer.api.campaign.rules.MemoryAPI;
020import com.fs.starfarer.api.characters.PersonAPI;
021import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
022import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
023import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
024import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
025import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
026import com.fs.starfarer.api.impl.campaign.ids.Tags;
027import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
028import com.fs.starfarer.api.impl.campaign.intel.bar.events.BarEventManager.GenericBarEventCreator;
029import com.fs.starfarer.api.impl.campaign.intel.contacts.ContactIntel;
030import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
031import com.fs.starfarer.api.ui.SectorMapAPI;
032import com.fs.starfarer.api.ui.TooltipMakerAPI;
033import com.fs.starfarer.api.util.Misc;
034import com.fs.starfarer.api.util.Misc.Token;
035
036public class TriTachLoanIntel extends BaseIntelPlugin {
037        public static final String NUM_REPAID_LOANS = "$ttli_numRepaidLoans";
038        
039        protected TriTachLoanBarEvent event;
040        protected MarketAPI market;
041
042        protected ReputationAdjustmentResult repResult;
043        protected float daysRemaining = 0f;
044        protected boolean wasExtended = false;
045        
046        protected boolean sentReminder = false;
047        protected boolean loanRepaid = false;
048        
049        protected boolean majorLoan = false;
050        
051        public TriTachLoanIntel(TriTachLoanBarEvent event, MarketAPI market) {
052                this.event = event;
053                this.market = market;
054                
055                daysRemaining = event.getRepaymentDays();
056                Global.getSector().addScript(this);
057                
058                PersonAPI person = getPerson();
059                market.getCommDirectory().addPerson(person);
060                market.addPerson(person);
061                
062                person.getMemoryWithoutUpdate().set("$ttli_isPlayerContact", true);
063                person.getMemoryWithoutUpdate().set("$ttli_eventRef", this);
064                Misc.setFlagWithReason(person.getMemoryWithoutUpdate(),
065                                                          MemFlags.MEMORY_KEY_MISSION_IMPORTANT,
066                                                          "ttli", true, -1);
067        }
068        
069        public TriTachLoanBarEvent getEvent() {
070                return event;
071        }
072
073
074
075        public boolean isMajorLoan() {
076                return majorLoan;
077        }
078
079        public void setMajorLoan(boolean majorLoan) {
080                this.majorLoan = majorLoan;
081                
082                if (majorLoan) {
083                        // do not unset this later, needed to make market interaction after failing to pay work
084                        getPerson().getMemoryWithoutUpdate().set("$ttli_isMajorLoan", true);
085                }
086        }
087
088
089
090        public PersonAPI getPerson() {
091                return event.getPerson();
092        }
093        
094        protected float getExtensionDays() {
095                return event.getRepaymentDays();
096        }
097
098        @Override
099        public boolean callEvent(String ruleId, final InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
100                String action = params.get(0).getString(memoryMap);
101                
102                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
103                CargoAPI cargo = playerFleet.getCargo();
104                
105                //$ttli_repaymentAmount
106                //$ttli_loanWasExtended
107                //$ttli_extensionDays 
108                
109                MemoryAPI memory = getPerson().getMemoryWithoutUpdate();
110                if (action.equals("putValuesInMemory")) {
111                        memory.set("$ttli_repaymentAmount", Misc.getDGSCredits(event.getRepaymentAmount()), 0);
112                        memory.set("$ttli_loanWasExtended", wasExtended, 0);
113                        memory.set("$ttli_daysRemaining", daysRemaining, 0);
114                        if (wasExtended) {
115                                memory.set("$ttli_extensionDays", "" + (int) getExtensionDays(), 0);
116                        }
117                } else if (action.equals("canPay")) {
118                        return cargo.getCredits().get() >= event.getRepaymentAmount();
119                } else if (action.equals("payLoan")) {
120                        endWithPayment(dialog);
121                } else if (action.equals("extendLoan")) {
122                        extendLoan(dialog);
123                } else if (action.equals("applyExtendLoanRepLoss")) {
124                        applyExtendLoanRepLoss(dialog);
125                } else if (action.equals("notPaying")) {
126                        endNoPayment(dialog);
127                } else if (action.equals("noPaymentMessage")) {
128                        noPaymentMessage(dialog);
129                } else if (action.equals("isMajorLoan")) {
130                        return isMajorLoan();
131                }
132                
133                return true;
134        }
135        
136        protected void noPaymentMessage(InteractionDialogAPI dialog) {
137                dialog.getInteractionTarget().setActivePerson(getPerson());
138                ((RuleBasedDialog) dialog.getPlugin()).notifyActivePersonChanged();
139                dialog.getVisualPanel().showPersonInfo(getPerson(), true);
140        }
141        
142        @Override
143        protected void notifyEnding() {
144                super.notifyEnding();
145                
146                PersonAPI person = getPerson();
147                market.getCommDirectory().removePerson(person);
148                market.removePerson(person);
149                person.getMemoryWithoutUpdate().unset("$ttli_isPlayerContact");
150                person.getMemoryWithoutUpdate().unset("$ttli_eventRef");
151                Misc.setFlagWithReason(person.getMemoryWithoutUpdate(),
152                                                          MemFlags.MEMORY_KEY_MISSION_IMPORTANT,
153                                                          "ttli", false, -1);
154        }
155
156        @Override
157        protected void notifyEnded() {
158                super.notifyEnded();
159                Global.getSector().removeScript(this);
160        }
161        
162        protected void extendLoan(InteractionDialogAPI dialog) {
163                wasExtended = true;
164                
165                float extension = event.getRepaymentDays();
166                daysRemaining += extension;
167                event.setRepaymentAmount((int) (event.getLoanAmount() * 2f));
168                
169                GenericBarEventCreator creator = null;
170                for (GenericBarEventCreator c : BarEventManager.getInstance().getCreators()) {
171                        if (isMajorLoan() && c instanceof TriTachMajorLoanBarEventCreator) {
172                                creator = c;
173                                break;
174                        } else if (!isMajorLoan() && c instanceof TriTachLoanBarEventCreator) {
175                                creator = c;
176                                break;
177                        }
178                }
179                
180                if (creator != null) {
181                        BarEventManager.getInstance().getTimeout().add(creator, extension);
182                }
183        }
184        
185        protected void applyExtendLoanRepLoss(InteractionDialogAPI dialog) {
186                CustomRepImpact impact = new CustomRepImpact();
187                impact.delta = -0.05f;
188                if (isMajorLoan()) impact.delta = -0.1f;
189                impact.limit = RepLevel.SUSPICIOUS;
190                repResult = Global.getSector().adjustPlayerReputation(
191                                new RepActionEnvelope(RepActions.CUSTOM, 
192                                                impact, null, dialog != null ? dialog.getTextPanel() : null, true, true),
193                                                event.getPerson());
194                
195                impact = new CustomRepImpact();
196                impact.delta = -0.02f;
197                if (isMajorLoan()) impact.delta = -0.05f;
198                impact.limit = RepLevel.SUSPICIOUS;
199                repResult = Global.getSector().adjustPlayerReputation(
200                                new RepActionEnvelope(RepActions.CUSTOM, 
201                                                impact, null, dialog != null ? dialog.getTextPanel() : null, true, true),
202                                                event.getPerson().getFaction().getId());
203        }
204        
205        
206        protected void endWithPayment(InteractionDialogAPI dialog) {
207                endAfterDelay();
208                
209                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
210                CargoAPI cargo = playerFleet.getCargo();
211                
212                cargo.getCredits().subtract(event.getRepaymentAmount());
213                if (dialog != null) {
214                        TextPanelAPI text = dialog.getTextPanel();
215                        AddRemoveCommodity.addCreditsLossText(event.getRepaymentAmount(), text);
216                }
217                
218                CustomRepImpact impact = new CustomRepImpact();
219                impact.delta = 0.05f;
220                if (isMajorLoan()) impact.delta = 0.1f;
221                repResult = Global.getSector().adjustPlayerReputation(
222                                new RepActionEnvelope(RepActions.CUSTOM, 
223                                                impact, null, dialog != null ? dialog.getTextPanel() : null, true, true),
224                                                event.getPerson());
225                
226                impact = new CustomRepImpact();
227                impact.delta = 0.02f;
228                if (isMajorLoan()) impact.delta = 0.05f;
229                repResult = Global.getSector().adjustPlayerReputation(
230                                new RepActionEnvelope(RepActions.CUSTOM, 
231                                                impact, null, dialog != null ? dialog.getTextPanel() : null, true, true),
232                                                event.getPerson().getFaction().getId());
233                
234                
235                float repaid = Global.getSector().getMemoryWithoutUpdate().getFloat(NUM_REPAID_LOANS);
236                repaid++;
237                Global.getSector().getMemoryWithoutUpdate().set(NUM_REPAID_LOANS, repaid);
238                
239                loanRepaid = true;
240                
241                ContactIntel.addPotentialContact(event.getPerson(), market, dialog.getTextPanel());
242        }
243        
244        
245        protected void endNoPayment(InteractionDialogAPI dialog) {
246                endAfterDelay();
247                
248                CustomRepImpact impact = new CustomRepImpact();
249                impact.delta = -0f;
250                impact.ensureAtBest = RepLevel.HOSTILE;
251                if (isMajorLoan()) impact.ensureAtBest = RepLevel.VENGEFUL;
252                repResult = Global.getSector().adjustPlayerReputation(
253                                new RepActionEnvelope(RepActions.CUSTOM, 
254                                                impact, null, dialog != null ? dialog.getTextPanel() : null, dialog != null, dialog != null),
255                                                event.getPerson().getFaction().getId());
256                
257                if (dialog == null) {
258                        Global.getSector().getMemoryWithoutUpdate().set("$ttli_unpaidEventRef", this, 60f);
259                }
260                
261                if (majorLoan) {
262                        Global.getSector().addScript(new TriTachLoanIncentiveScript(this));
263                }
264                
265        }
266
267        @Override
268        protected void advanceImpl(float amount) {
269                super.advanceImpl(amount);
270                
271                float days = Misc.getDays(amount);
272                daysRemaining -= days;
273                
274                //daysRemaining = 0;
275                
276                if (daysRemaining <= 0) {
277                        endNoPayment(null);
278                        sendUpdateIfPlayerHasIntel(new Object(), false);
279                        return;
280                }
281                
282                if (!sentReminder) {
283                        float dist = Misc.getDistance(Global.getSector().getPlayerFleet().getLocationInHyperspace(), market.getLocationInHyperspace());
284                        float soonDays = dist / 1500 + 10f;
285                        if (soonDays > daysRemaining) {
286                                sentReminder = true;
287                                sendUpdateIfPlayerHasIntel(new Object(), false);
288                                return;
289                        }
290                }
291        }
292
293        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
294                
295                Color h = Misc.getHighlightColor();
296                Color g = Misc.getGrayColor();
297                float pad = 3f;
298                float opad = 10f;
299                
300                float initPad = pad;
301                if (mode == ListInfoMode.IN_DESC) initPad = opad;
302                
303                Color tc = getBulletColorForMode(mode);
304                
305                bullet(info);
306                boolean isUpdate = getListInfoParam() != null;
307                
308                if (!loanRepaid) {
309                        if (daysRemaining > 0) {
310                                if (mode == ListInfoMode.IN_DESC) {
311                                        info.addPara("%s original loan amount", initPad, tc, h, Misc.getDGSCredits(event.getLoanAmount()));
312                                        initPad = 0f;
313                                }
314                                info.addPara("%s owed", initPad, tc, h, Misc.getDGSCredits(event.getRepaymentAmount()));
315                                initPad = 0f;
316                                addDays(info, "left to repay", daysRemaining, tc);
317                        }
318                }
319                
320                if (repResult != null) {
321                        CoreReputationPlugin.addAdjustmentMessage(repResult.delta, event.getPerson().getFaction(), null, 
322                                        null, null, info, tc, isUpdate, initPad);
323                }
324                
325                unindent(info);
326        }
327        
328        @Override
329        public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
330                Color c = getTitleColor(mode);
331                info.addPara(getName(), c, 0f);
332                
333                addBulletPoints(info, mode);
334        }
335        
336        public String getSortString() {
337                return "Loan";
338        }
339        
340        public String getName() {
341                if (loanRepaid) {
342                        return "Loan Repaid";
343                } else if (daysRemaining <= 0) {
344                        return "Loan Repayment - Failed";
345                } else if (sentReminder) {
346                        return "Loan Repayment - Due Soon";
347                }
348                return "Loan Repayment";
349        }
350        
351
352        @Override
353        public FactionAPI getFactionForUIColors() {
354                return event.getPerson().getFaction();
355        }
356
357        public String getSmallDescriptionTitle() {
358                return getName();
359        }
360        
361
362        @Override
363        public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
364                Color h = Misc.getHighlightColor();
365                Color g = Misc.getGrayColor();
366                Color tc = Misc.getTextColor();
367                float pad = 3f;
368                float opad = 10f;
369
370                PersonAPI p = event.getPerson();
371                FactionAPI faction = getFactionForUIColors();
372                info.addImages(width, 128, opad, opad, p.getPortraitSprite(), faction.getCrest());
373
374                if (loanRepaid) {
375                        info.addPara("You've repaid the loan from " + p.getNameString() + " on time.", opad);
376                } else if (daysRemaining > 0) {
377                        info.addPara("You've accepted a loan from " + p.getNameString() + " and must repay it on time, " +
378                                        "or your reputation with " + faction.getDisplayNameWithArticle() + " will be ruined.", opad,
379                                        faction.getBaseUIColor(), faction.getDisplayNameWithArticleWithoutArticle());
380                } else {
381                        info.addPara("You've failed to repay the loan from " + p.getNameString() + " on time.", opad);
382                }
383                
384                addBulletPoints(info, ListInfoMode.IN_DESC);
385                
386                if (daysRemaining > 0 && !loanRepaid) {
387                        info.addPara("You should be able to find " + p.getNameString() + " at " + market.getName() + ".", opad);
388                }
389        }
390        
391        public String getIcon() {
392                return event.getPerson().getPortraitSprite();
393        }
394        
395        public Set<String> getIntelTags(SectorMapAPI map) {
396                Set<String> tags = super.getIntelTags(map);
397                tags.add(Tags.INTEL_ACCEPTED);
398                tags.add(getFactionForUIColors().getId());
399                return tags;
400        }
401
402        @Override
403        public SectorEntityToken getMapLocation(SectorMapAPI map) {
404                return market.getPrimaryEntity();
405        }
406        
407}       
408        
409