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