001package com.fs.starfarer.api.impl.campaign.intel; 002 003import java.awt.Color; 004import java.util.Set; 005 006import org.lwjgl.input.Keyboard; 007 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.campaign.FactionAPI; 010import com.fs.starfarer.api.campaign.InteractionDialogAPI; 011import com.fs.starfarer.api.campaign.SectorEntityToken; 012import com.fs.starfarer.api.campaign.TextPanelAPI; 013import com.fs.starfarer.api.campaign.econ.EconomyAPI.EconomyUpdateListener; 014import com.fs.starfarer.api.campaign.econ.MarketAPI; 015import com.fs.starfarer.api.impl.campaign.ids.Conditions; 016import com.fs.starfarer.api.impl.campaign.ids.Factions; 017import com.fs.starfarer.api.impl.campaign.ids.Tags; 018import com.fs.starfarer.api.ui.ButtonAPI; 019import com.fs.starfarer.api.ui.IntelUIAPI; 020import com.fs.starfarer.api.ui.LabelAPI; 021import com.fs.starfarer.api.ui.SectorMapAPI; 022import com.fs.starfarer.api.ui.TooltipMakerAPI; 023import com.fs.starfarer.api.util.Misc; 024 025public class TriTachyonDeal extends BaseIntelPlugin implements EconomyUpdateListener { 026 027 public static enum AgreementEndingType { 028 BROKEN, 029 } 030 031 // in $player memory 032 public static final String HAS_TRI_TACH_DEAL = "$hasTriTachDeal"; 033 public static final String BROKE_TRI_TACH_DEAL = "$brokeTriTachDeal"; 034 035 public static float REP_FOR_BREAKING_DEAL = 0.5f; 036 037 public static float MARKET_SIZE_TO_ACCESSIBILITY = 0.01f; 038 039 public static boolean hasDeal() { 040 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(HAS_TRI_TACH_DEAL); 041 } 042 public static void setHasDeal(boolean deal) { 043 Global.getSector().getPlayerMemoryWithoutUpdate().set(HAS_TRI_TACH_DEAL, deal); 044 } 045 public static boolean brokeDeal() { 046 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(BROKE_TRI_TACH_DEAL); 047 } 048 public static void setBrokeDeal(boolean broke) { 049 Global.getSector().getPlayerMemoryWithoutUpdate().set(BROKE_TRI_TACH_DEAL, broke); 050 } 051 052 053 public static String KEY = "$triTachDeal_ref"; 054 public static TriTachyonDeal get() { 055 return (TriTachyonDeal) Global.getSector().getMemoryWithoutUpdate().get(KEY); 056 } 057 058 public static String BUTTON_END = "End"; 059 060 public static String UPDATE_PARAM_ACCEPTED = "update_param_accepted"; 061 062 protected FactionAPI faction = null; 063 protected AgreementEndingType endType = null; 064 065 public TriTachyonDeal(InteractionDialogAPI dialog) { 066 this.faction = Global.getSector().getFaction(Factions.TRITACHYON); 067 068 setImportant(true); 069 setHasDeal(true); 070 071 TextPanelAPI text = null; 072 if (dialog != null) text = dialog.getTextPanel(); 073 074 //Global.getSector().getListenerManager().addListener(this); 075 Global.getSector().getEconomy().addUpdateListener(this); 076 Global.getSector().getMemoryWithoutUpdate().set(KEY, this); 077 078 Global.getSector().getIntelManager().addIntel(this, true); 079 080 economyUpdated(); // apply the modifier right away 081 082 sendUpdate(UPDATE_PARAM_ACCEPTED, text); 083 } 084 085 @Override 086 protected void notifyEnding() { 087 super.notifyEnding(); 088 089 setHasDeal(false); 090 091 Global.getSector().getMemoryWithoutUpdate().unset(KEY); 092 //Global.getSector().getListenerManager().removeListener(this); 093 Global.getSector().getEconomy().removeUpdateListener(this); 094 095 unapplyAccessModifier(); 096 } 097 098 @Override 099 protected void notifyEnded() { 100 super.notifyEnded(); 101 } 102 103 protected Object readResolve() { 104 return this; 105 } 106 107 public String getBaseName() { 108 return "Tri-Tachyon Strategic Partnership"; 109 } 110 111 public String getAcceptedPostfix() { 112 return "Accepted"; 113 } 114 115 public String getBrokenPostfix() { 116 return "Dissolved"; 117 118 } 119 120 public String getName() { 121 String postfix = ""; 122 if (isEnding() && endType != null) { 123 switch (endType) { 124 case BROKEN: 125 postfix = " - " + getBrokenPostfix(); 126 break; 127 } 128 } 129 if (isSendingUpdate() && getListInfoParam() == UPDATE_PARAM_ACCEPTED) { 130 postfix = " - " + getAcceptedPostfix(); 131 } 132 return getBaseName() + postfix; 133 } 134 135 @Override 136 public FactionAPI getFactionForUIColors() { 137 return faction; 138 } 139 140 public String getSmallDescriptionTitle() { 141 return getName(); 142 } 143 144 protected float computeColonySize(String factionId) { 145 float size = 0f; 146 for (MarketAPI curr : Global.getSector().getEconomy().getMarketsCopy()) { 147 if (factionId.equals(curr.getFactionId())) { 148 if (curr.hasCondition(Conditions.DECIVILIZED)) continue; 149 size += curr.getSize(); 150 } 151 } 152 return size; 153 } 154 155 protected float computeAccessibilityBonusPlayer() { 156 float size = computeColonySize(Factions.TRITACHYON); 157 return size * MARKET_SIZE_TO_ACCESSIBILITY; 158 } 159 protected float computeAccessibilityBonusTriTach() { 160 float size = computeColonySize(Factions.PLAYER); 161 return size * MARKET_SIZE_TO_ACCESSIBILITY; 162 } 163 164 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) { 165 Color h = Misc.getHighlightColor(); 166 Color g = Misc.getGrayColor(); 167 float pad = 3f; 168 float opad = 10f; 169 170 float initPad = pad; 171 if (mode == ListInfoMode.IN_DESC) initPad = opad; 172 173 Color tc = getBulletColorForMode(mode); 174 175 bullet(info); 176 boolean isUpdate = getListInfoParam() != null; 177 178// if (getListInfoParam() == UPDATE_PARAM_ACCEPTED) { 179// return; 180// } 181 182 int accessPlayer = (int)Math.round(computeAccessibilityBonusPlayer() * 100f); 183 int accessTriTach = (int)Math.round(computeAccessibilityBonusTriTach() * 100f); 184 185 if (!isEnded() && !isEnding()) { 186 String fName = Global.getSector().getPlayerFaction().getDisplayName(); 187 LabelAPI label; 188 label = info.addPara(fName + " colonies receive %s accessibility", initPad, tc, h, "+" + accessPlayer + "%"); 189 label.setHighlight(fName, "+" + accessPlayer + "%"); 190 label.setHighlightColors(Misc.getBasePlayerColor(), h); 191 initPad = 0f; 192 193 fName = faction.getDisplayName(); 194 label = info.addPara(fName + " colonies receive %s accessibility", initPad, tc, h, "+" + accessTriTach + "%"); 195 label.setHighlight(fName, "+" + accessTriTach + "%"); 196 label.setHighlightColors(faction.getBaseUIColor(), h); 197 } 198 199 unindent(info); 200 } 201 202 203 public void createSmallDescription(TooltipMakerAPI info, float width, float height) { 204 Color h = Misc.getHighlightColor(); 205 Color g = Misc.getGrayColor(); 206 Color tc = Misc.getTextColor(); 207 float pad = 3f; 208 float opad = 10f; 209 210 info.addImage(getFaction().getLogo(), width, 128, opad); 211 212 if (isEnding() || isEnded()) { 213 info.addPara("Your agreement with the Tri-Tachyon Corporation is no longer in force.", opad); 214 return; 215 } 216 217 info.addPara("A partnership with the %s that allows you to leverage your combined market power " 218 + "for mutual benefit.", opad, faction.getBaseUIColor(), faction.getDisplayNameLong()); 219 220 addBulletPoints(info, ListInfoMode.IN_DESC); 221 222 info.addPara("Each partner's accessibility bonus is based " 223 + "on the total size of the colonies of the other partner.", opad); 224 225 info.addPara("The contract is carefully worded to survive even in the face of open hostilities, and is, " 226 + "from a legal perspective, perpetually binding.", opad); 227 228 info.addPara("You can of course decide to end this partnership unilaterally, but there " 229 + "would be no possibility of re-negotiating a similar deal after displaying such a lack of respect " 230 + "for your contractual obligations.", opad); 231 232 ButtonAPI button = info.addButton("End the partnership", BUTTON_END, 233 getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(), 234 (int)(width), 20f, opad * 1f); 235 button.setShortcut(Keyboard.KEY_U, true); 236 237 } 238 239 240 public String getIcon() { 241 return faction.getCrest(); 242 } 243 244 public Set<String> getIntelTags(SectorMapAPI map) { 245 Set<String> tags = super.getIntelTags(map); 246 tags.add(Tags.INTEL_AGREEMENTS); 247 tags.add(faction.getId()); 248 return tags; 249 } 250 251 @Override 252 public String getImportantIcon() { 253 return Global.getSettings().getSpriteName("intel", "important_accepted_mission"); 254 } 255 256 @Override 257 public SectorEntityToken getMapLocation(SectorMapAPI map) { 258 return null; 259 } 260 261 262 public FactionAPI getFaction() { 263 return faction; 264 } 265 266 public void endAgreement(AgreementEndingType type, InteractionDialogAPI dialog) { 267 if (!isEnded() && !isEnding()) { 268 endType = type; 269 setImportant(false); 270 //endAfterDelay(); 271 endImmediately(); 272 273 if (dialog != null) { 274 sendUpdate(new Object(), dialog.getTextPanel()); 275 } 276 277 if (type == AgreementEndingType.BROKEN) { 278 setBrokeDeal(true); 279 Misc.incrUntrustwortyCount(); 280 TextPanelAPI text = dialog == null ? null : dialog.getTextPanel(); 281 Misc.adjustRep(Factions.TRITACHYON, -REP_FOR_BREAKING_DEAL, text); 282 } 283 } 284 } 285 286 287 @Override 288 public void buttonPressConfirmed(Object buttonId, IntelUIAPI ui) { 289 if (buttonId == BUTTON_END) { 290 endAgreement(AgreementEndingType.BROKEN, null); 291 } 292 super.buttonPressConfirmed(buttonId, ui); 293 } 294 295 296 @Override 297 public void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt) { 298 if (buttonId == BUTTON_END) { 299 prompt.addPara("You can decide to end this partnership unilaterally, but taking this action would " 300 + "hurt your standing with %s, and there " 301 + "would be no possibility of re-negotiating a similar deal after displaying such a lack of respect " 302 + "for your contractual obligations.", 0f, 303 faction.getBaseUIColor(), faction.getDisplayName()); 304 } 305 306 } 307 308 @Override 309 public boolean doesButtonHaveConfirmDialog(Object buttonId) { 310 if (buttonId == BUTTON_END) { 311 return true; 312 } 313 return super.doesButtonHaveConfirmDialog(buttonId); 314 } 315 316 public void commodityUpdated(String commodityId) { 317 } 318 319 public static String ACCESS_MOD_ID = "ttDeal_access"; 320 public void economyUpdated() { 321 float player = computeAccessibilityBonusPlayer(); 322 float triTach = computeAccessibilityBonusTriTach(); 323 String descPlayer = "Strategic partnership with " + faction.getDisplayName(); 324 String descTriTach = "Strategic partnership with " + Global.getSector().getPlayerFaction().getDisplayName(); 325 for (MarketAPI curr : Global.getSector().getEconomy().getMarketsCopy()) { 326 float mod = 0f; 327 String desc = null; 328 if (Factions.TRITACHYON.equals(curr.getFactionId())) { 329 mod = triTach; 330 desc = descTriTach; 331 } else if (Factions.PLAYER.equals(curr.getFactionId())) { 332 mod = player; 333 desc = descPlayer; 334 } 335 if (mod != 0) { 336 curr.getAccessibilityMod().modifyFlat(ACCESS_MOD_ID, mod, desc); 337 } else { 338 curr.getAccessibilityMod().unmodifyFlat(ACCESS_MOD_ID); 339 } 340 } 341 } 342 343 public void unapplyAccessModifier() { 344 for (MarketAPI curr : Global.getSector().getEconomy().getMarketsCopy()) { 345 curr.getAccessibilityMod().unmodifyFlat(ACCESS_MOD_ID); 346 } 347 } 348 349 public boolean isEconomyListenerExpired() { 350 return isEnding() || isEnded(); 351 } 352 353 354} 355 356 357 358 359 360