001package com.fs.starfarer.api.impl.campaign.intel.bar.events; 002 003import java.awt.Color; 004import java.util.Map; 005import java.util.Random; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.CargoAPI; 009import com.fs.starfarer.api.campaign.InteractionDialogAPI; 010import com.fs.starfarer.api.campaign.OptionPanelAPI; 011import com.fs.starfarer.api.campaign.PersonImportance; 012import com.fs.starfarer.api.campaign.TextPanelAPI; 013import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI; 014import com.fs.starfarer.api.campaign.econ.MarketAPI; 015import com.fs.starfarer.api.campaign.rules.MemoryAPI; 016import com.fs.starfarer.api.characters.PersonAPI; 017import com.fs.starfarer.api.characters.FullName.Gender; 018import com.fs.starfarer.api.impl.campaign.ids.Commodities; 019import com.fs.starfarer.api.impl.campaign.ids.Ranks; 020import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity; 021import com.fs.starfarer.api.ui.LabelAPI; 022import com.fs.starfarer.api.util.Misc; 023import com.fs.starfarer.api.util.WeightedRandomPicker; 024 025public abstract class BaseGetCommodityBarEvent extends BaseBarEvent { 026 public static final String OPTION_CONFIRM = "confirm"; 027 public static final String OPTION_CANCEL = "cancel"; 028 public static final String OPTION_CONTINUE = "continue"; 029 030 protected long seed; 031 protected PersonAPI person; 032 protected int quantity; 033 protected int unitPrice; 034 protected String commodity; 035 036 public BaseGetCommodityBarEvent() { 037 seed = Misc.random.nextLong(); 038 } 039 040 protected transient Random random; 041 042 protected MarketAPI market = null; 043 044 protected void regen(MarketAPI market) { 045 if (this.market == market) return; 046 this.market = market; 047 048 random = new Random(seed + market.getId().hashCode()); 049 050 commodity = getCommodityId(); 051 if (commodity == null) return; 052 053 person = createPerson(); 054 quantity = computeQuantity(); 055 056 057 float price = market.getSupplyPrice(commodity, 1, true); 058 unitPrice = (int) (price * getPriceMult()); 059 if (unitPrice > 50) { 060 unitPrice = unitPrice / 10 * 10; 061 } 062 if (unitPrice < 1 && unitPrice > 0) { 063 unitPrice = 1; 064 } 065 } 066 067 protected PersonAPI createPerson() { 068 PersonAPI person = Global.getSector().getFaction(getPersonFaction()).createRandomPerson(random); 069 person.setRankId(getPersonRank()); 070 person.setPostId(getPersonPost()); 071 adjustPerson(person); 072 return person; 073 } 074 075 076 077 protected float getPriceMult() { 078 return 0.75f; 079 } 080 protected String getCommodityId() { 081 return commodity != null ? commodity : Commodities.FOOD; 082 } 083 protected int computeQuantity() { 084 int quantity = 50 + 10 * random.nextInt(6); 085 086 int size = market.getSize(); 087 //quantity *= BaseIndustry.getSizeMult(size); 088 quantity *= Math.max(1, size - 2); 089 return quantity; 090 } 091 protected void adjustPerson(PersonAPI person) { 092 093 } 094 protected String getPersonFaction() { 095 return market.getFactionId(); 096 } 097 protected String getPersonRank() { 098 return Ranks.CITIZEN; 099 } 100 protected String getPersonPost() { 101 return Ranks.CITIZEN; 102 } 103 104 protected String getManOrWoman() { 105 String manOrWoman = "man"; 106 if (person.getGender() == Gender.FEMALE) manOrWoman = "woman"; 107 return manOrWoman; 108 } 109 110 protected String getHeOrShe() { 111 String heOrShe = "he"; 112 if (person.getGender() == Gender.FEMALE) { 113 heOrShe = "she"; 114 } 115 return heOrShe; 116 } 117 118 protected String getHimOrHer() { 119 String himOrHer = "him"; 120 if (person.getGender() == Gender.FEMALE) { 121 himOrHer = "her"; 122 } 123 return himOrHer; 124 } 125 126 protected String getHimOrHerself() { 127 String himOrHer = "himself"; 128 if (person.getGender() == Gender.FEMALE) { 129 himOrHer = "herself"; 130 } 131 return himOrHer; 132 } 133 134 protected String getHisOrHer() { 135 String hisOrHer = "his"; 136 if (person.getGender() == Gender.FEMALE) { 137 hisOrHer = "her"; 138 } 139 return hisOrHer; 140 } 141 142 @Override 143 public void addPromptAndOption(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) { 144 super.addPromptAndOption(dialog, memoryMap); 145 146 regen(dialog.getInteractionTarget().getMarket()); 147 148 TextPanelAPI text = dialog.getTextPanel(); 149 text.addPara(getPrompt()); 150 151 dialog.getOptionPanel().addOption(getOptionText(), this); 152 } 153 154 protected abstract String getPrompt(); 155 protected abstract String getOptionText(); 156 157 protected abstract String getConfirmText(); 158 protected abstract String getCancelText(); 159 160 protected abstract String getMainText(); 161 protected String [] getMainTextTokens() { return null; }; 162 protected Color [] getMainTextColors() { return null; }; 163 164 protected String getMainText2() { return null; }; 165 protected String [] getMainText2Tokens() { return null; }; 166 protected Color [] getMainText2Colors() { return null; }; 167 168 protected String getAcceptText() { return null; }; 169 protected String [] getAcceptTextTokens() { return null; }; 170 protected Color [] getAcceptTextColors() { return null; }; 171 172 protected String getDeclineText() { return null; }; 173 protected String [] getDeclineTextTokens() { return null; }; 174 protected Color [] getDeclineTextColors() { return null; }; 175 176 @Override 177 public void init(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) { 178 super.init(dialog, memoryMap); 179 180 done = false; 181 182 dialog.getVisualPanel().showPersonInfo(person, true); 183 184 TextPanelAPI text = dialog.getTextPanel(); 185 if (getMainTextTokens() != null) { 186 LabelAPI main = text.addPara(getMainText(), Misc.getHighlightColor(), getMainTextTokens()); 187 main.setHighlightColors(getMainTextColors()); 188 main.setHighlight(getMainTextTokens()); 189 } else { 190 text.addPara(getMainText()); 191 } 192 193 if (getMainText2() == null) { 194 showTotalAndOptions(); 195 } else { 196 OptionPanelAPI options = dialog.getOptionPanel(); 197 options.clearOptions(); 198 options.addOption("Continue", OPTION_CONTINUE); 199 } 200 } 201 202 protected boolean showCargoCap() { 203 return true; 204 } 205 206 protected void showTotalAndOptions() { 207 Color h = Misc.getHighlightColor(); 208 Color n = Misc.getNegativeHighlightColor(); 209 210 TextPanelAPI text = dialog.getTextPanel(); 211 212 boolean canAccept = canAccept(); 213 214 if (showCargoCap() && commodity != null && quantity > 0) { 215 CommoditySpecAPI spec = Global.getSettings().getCommoditySpec(commodity); 216 CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo(); 217 String str = ""; 218 int cap = 0; 219 if (spec.isFuel()) { 220 cap = cargo.getFreeFuelSpace(); 221 if (cap > 1) { 222 str += "Your fleet's fuel tanks can hold an additional %s units of fuel."; 223 } else { 224 str += "Your fleet's fuel tanks are currently full."; 225 } 226 } else if (spec.isPersonnel()) { 227 cap = cargo.getFreeCrewSpace(); 228 if (cap > 1) { 229 str += "Your fleet's crew quarters can accommodate an additional %s personnel."; 230 } else { 231 str += "Your fleet's crew berths are currently full."; 232 } 233 } else { 234 cap = (int) cargo.getSpaceLeft(); 235 if (cap > 1) { 236 str += "Your fleet's holds can accommodate an additional %s units of cargo."; 237 } else { 238 str += "Your fleet's cargo holds are currently full."; 239 } 240 } 241 text.addPara(str, h, Misc.getWithDGS(cap)); 242 } 243 244 float credits = Global.getSector().getPlayerFleet().getCargo().getCredits().get(); 245 int price = unitPrice * quantity; 246 if (price > 0) { 247 LabelAPI label = text.addPara("The total price is %s. You have %s available.", 248 h, 249 Misc.getDGSCredits(price), 250 Misc.getDGSCredits(credits)); 251 label.setHighlightColors(canAccept ? h : n, h); 252 label.setHighlight(Misc.getDGSCredits(price), Misc.getDGSCredits(credits)); 253 } 254 255 256 OptionPanelAPI options = dialog.getOptionPanel(); 257 options.clearOptions(); 258 options.addOption(getConfirmText(), OPTION_CONFIRM); 259 if (!canAccept) { 260 options.setEnabled(OPTION_CONFIRM, false); 261 String tooltip = getCanNotAcceptTooltip(); 262 if (tooltip != null) { 263 options.setTooltip(OPTION_CONFIRM, tooltip); 264 } 265 } 266 if (canAccept) { 267 addStoryOption(); 268 } 269 options.addOption(getCancelText(), OPTION_CANCEL); 270 //options.setShortcut(OPTION_CANCEL, Keyboard.KEY_ESCAPE, false, false, false, true); 271 } 272 273 protected void addStoryOption() { 274 275 } 276 277 protected boolean canAccept() { 278 float credits = Global.getSector().getPlayerFleet().getCargo().getCredits().get(); 279 int price = unitPrice * quantity; 280 boolean canAfford = credits >= price; 281 return canAfford; 282 } 283 284 protected String getCanNotAcceptTooltip() { 285 return "You don't have enough credits."; 286 } 287 288 289 290 protected void doExtraConfirmActions() { 291 292 } 293 294 295 protected void doConfirmActionsPreAcceptText() { 296 297 } 298 protected void doStandardConfirmActions() { 299 int price = unitPrice * quantity; 300 CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo(); 301 if (price > 0) cargo.getCredits().subtract(price); 302 cargo.addCommodity(commodity, quantity); 303 304 TextPanelAPI text = dialog.getTextPanel(); 305 306 if (price > 0) AddRemoveCommodity.addCreditsLossText(price, text); 307 AddRemoveCommodity.addCommodityGainText(commodity, quantity, text); 308 } 309 310 @Override 311 public void optionSelected(String optionText, Object optionData) { 312 if (optionData == OPTION_CONTINUE) { 313 TextPanelAPI text = dialog.getTextPanel(); 314 if (getMainText2Tokens() != null) { 315 LabelAPI main = text.addPara(getMainText2(), Misc.getHighlightColor(), getMainText2Tokens()); 316 main.setHighlightColors(getMainText2Colors()); 317 main.setHighlight(getMainText2Tokens()); 318 } else { 319 text.addPara(getMainText2()); 320 } 321 showTotalAndOptions(); 322 } else if (optionData == OPTION_CONFIRM) { 323 done = true; 324 BarEventManager.getInstance().notifyWasInteractedWith(this); 325 326 doConfirmActionsPreAcceptText(); 327 TextPanelAPI text = dialog.getTextPanel(); 328 String acceptStr = getAcceptText(); 329 if (acceptStr != null) { 330 if (getAcceptTextTokens() != null) { 331 LabelAPI accept = text.addPara(acceptStr, Misc.getHighlightColor(), getAcceptTextTokens()); 332 accept.setHighlightColors(getAcceptTextColors()); 333 accept.setHighlight(getAcceptTextTokens()); 334 } else { 335 text.addPara(acceptStr); 336 } 337 } 338 339 doStandardConfirmActions(); 340 doExtraConfirmActions(); 341 342 } else if (optionData == OPTION_CANCEL) { 343 344 TextPanelAPI text = dialog.getTextPanel(); 345 String declineStr = getDeclineText(); 346 if (declineStr != null) { 347 if (getDeclineTextTokens() != null) { 348 LabelAPI decline = text.addPara(declineStr, Misc.getHighlightColor(), getAcceptTextTokens()); 349 decline.setHighlightColors(getDeclineTextColors()); 350 decline.setHighlight(getDeclineTextTokens()); 351 } else { 352 text.addPara(declineStr); 353 } 354 } else { 355 noContinue = true; 356 } 357 done = true; 358 } 359// else if (optionText == getStoryOptionId() && getStoryOptionId() != null) { 360// 361// } 362 } 363 364 @Override 365 public boolean isDialogFinished() { 366 return done; 367 } 368 369 public PersonAPI getPerson() { 370 return person; 371 } 372 373 public MarketAPI getMarket() { 374 return market; 375 } 376 377 378 public PersonImportance pickImportance() { 379 WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random); 380 picker.add(PersonImportance.VERY_LOW, 1f); 381 picker.add(PersonImportance.LOW, 5f); 382 picker.add(PersonImportance.MEDIUM, 10f); 383 picker.add(PersonImportance.HIGH, 5f); 384 picker.add(PersonImportance.VERY_HIGH, 1f); 385 return picker.pick(); 386 } 387 public PersonImportance pickMediumImportance() { 388 WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random); 389 picker.add(PersonImportance.LOW, 5f); 390 picker.add(PersonImportance.MEDIUM, 10f); 391 picker.add(PersonImportance.HIGH, 5f); 392 return picker.pick(); 393 } 394 public PersonImportance pickHighImportance() { 395 WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random); 396 picker.add(PersonImportance.MEDIUM, 10f); 397 picker.add(PersonImportance.HIGH, 5f); 398 picker.add(PersonImportance.VERY_HIGH, 1f); 399 return picker.pick(); 400 } 401 public PersonImportance pickLowImportance() { 402 WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random); 403 picker.add(PersonImportance.VERY_LOW, 10f); 404 picker.add(PersonImportance.LOW, 5f); 405 picker.add(PersonImportance.MEDIUM, 1f); 406 return picker.pick(); 407 } 408 409 410 public String pickOne(String ... options) { 411 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(random); 412 for (String option : options) { 413 picker.add(option); 414 } 415 return picker.pick(); 416 } 417 418} 419 420 421 422