001package com.fs.starfarer.api.impl.campaign.rulecmd.salvage; 002 003import java.util.List; 004import java.util.Map; 005 006import org.lwjgl.util.vector.Vector2f; 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.OptionPanelAPI; 014import com.fs.starfarer.api.campaign.RepLevel; 015import com.fs.starfarer.api.campaign.SectorEntityToken; 016import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel; 017import com.fs.starfarer.api.campaign.TextPanelAPI; 018import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI; 019import com.fs.starfarer.api.campaign.rules.MemoryAPI; 020import com.fs.starfarer.api.characters.AbilityPlugin; 021import com.fs.starfarer.api.characters.PersonAPI; 022import com.fs.starfarer.api.fleet.FleetMemberAPI; 023import com.fs.starfarer.api.impl.campaign.abilities.DistressCallAbility; 024import com.fs.starfarer.api.impl.campaign.ids.Abilities; 025import com.fs.starfarer.api.impl.campaign.ids.Commodities; 026import com.fs.starfarer.api.impl.campaign.ids.Entities; 027import com.fs.starfarer.api.impl.campaign.ids.Strings; 028import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity; 029import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin; 030import com.fs.starfarer.api.util.Misc; 031import com.fs.starfarer.api.util.Misc.Token; 032 033/** 034 * NotifyEvent $eventHandle <params> 035 * 036 */ 037public class DistressResponse extends BaseCommandPlugin { 038 039 //public static float REP_NORMAL = -0.05f; 040 public static float REP_PER_USE = -0.02f; 041 public static float REP_SCAM = -0.15f; 042 043 protected CampaignFleetAPI playerFleet; 044 protected CampaignFleetAPI fleet; 045 protected SectorEntityToken entity; 046 protected FactionAPI playerFaction; 047 protected FactionAPI entityFaction; 048 protected TextPanelAPI text; 049 protected OptionPanelAPI options; 050 protected CargoAPI playerCargo; 051 protected MemoryAPI memory; 052 protected InteractionDialogAPI dialog; 053 protected Map<String, MemoryAPI> memoryMap; 054 protected PersonAPI person; 055 protected FactionAPI faction; 056 057 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) { 058 059 this.dialog = dialog; 060 this.memoryMap = memoryMap; 061 062 String command = params.get(0).getString(memoryMap); 063 if (command == null) return false; 064 065 memory = getEntityMemory(memoryMap); 066 067 entity = dialog.getInteractionTarget(); 068 text = dialog.getTextPanel(); 069 options = dialog.getOptionPanel(); 070 071 playerFleet = Global.getSector().getPlayerFleet(); 072 playerCargo = playerFleet.getCargo(); 073 074 playerFaction = Global.getSector().getPlayerFaction(); 075 entityFaction = entity.getFaction(); 076 077 person = dialog.getInteractionTarget().getActivePerson(); 078 faction = person.getFaction(); 079 080 fleet = (CampaignFleetAPI) dialog.getInteractionTarget(); 081 082 if (command.equals("playerNeedsHelp")) { 083 return playerNeedsHelp(); 084 } else if (command.equals("didNotNeedHelp")) { 085 didNotNeedHelp(); 086 } 087 else if (command.equals("acceptHelp")) { 088 acceptAid(); 089 } 090 else if (command.equals("neverMind")) { 091 neverMind(); 092 } 093 else if (command.equals("isCargoPodsScam")) { 094 return isCargoPodsScam(); 095 } 096 else if (command.equals("cargoPodsScam")) { 097 cargoPodsScam(); 098 } 099 else if (command.equals("unrespond")) { 100 unrespond(); 101 } 102 else if (command.equals("init")) { 103 init(); 104 } 105 else if (command.equals("pay")) { 106 pay(); 107 } 108 else if (command.equals("thank")) { 109 thank(); 110 } 111 112 return true; 113 } 114 115 protected void init() { 116 person.getMemoryWithoutUpdate().set("$distressUsesLastCycle", getNumUses(), 0); 117 118 int fuel = getNeededFuel(); 119 int supplies = getNeededSupplies(); 120 int maxFuel = getMaxFuel(); 121 int maxSupplies = getMaxSupplies(); 122 123 boolean adequate = fuel <= maxFuel * 1.5f && supplies <= maxSupplies * 1.5f; 124 person.getMemoryWithoutUpdate().set("$distressHelpAdequate", adequate, 0); 125 126 127 int distressPayment = getPayment(); 128 person.getMemoryWithoutUpdate().set("$distressPayment", Misc.getWithDGS(distressPayment), 0); 129 person.getMemoryWithoutUpdate().set("$distressPaymentC", Misc.getWithDGS(distressPayment) + Strings.C, 0); 130 person.getMemoryWithoutUpdate().set("$distressCanAfford", distressPayment <= playerCargo.getCredits().get(), 0); 131 } 132 133 protected int getPayment() { 134 int fuel = getNeededFuel(); 135 int supplies = getNeededSupplies(); 136 int maxFuel = getMaxFuel(); 137 int maxSupplies = getMaxSupplies(); 138 if (fuel > maxFuel) fuel = maxFuel; 139 if (supplies > maxSupplies) supplies = maxSupplies; 140 141 CommoditySpecAPI fuelComm = Global.getSettings().getCommoditySpec(Commodities.FUEL); 142 CommoditySpecAPI suppliesComm = Global.getSettings().getCommoditySpec(Commodities.FUEL); 143 144 float distressPayment = fuel * fuelComm.getBasePrice() + supplies * suppliesComm.getBasePrice(); 145 distressPayment = (float) Math.ceil(distressPayment / 10000f) * 10000f; 146 distressPayment *= 2f; 147 148 return (int) distressPayment; 149 } 150 151 protected int getNumUses() { 152 AbilityPlugin plugin = playerFleet.getAbility(Abilities.DISTRESS_CALL); 153 if (plugin != null) { 154 int uses = ((DistressCallAbility) plugin).getNumUsesInLastPeriod(); 155 return uses; 156 } 157 return 0; 158 } 159 160 protected boolean playerNeedsHelp() { 161 return getNeededFuel() > 0 || getNeededSupplies() > 0; 162 } 163 164 protected void cargoPodsScam() { 165 Misc.adjustRep(REP_SCAM, RepLevel.INHOSPITABLE, fleet.getFaction().getId(), 166 REP_SCAM, RepLevel.INHOSPITABLE, person, text); 167 168 unrespond(); 169 } 170 171 172 protected boolean isCargoPodsScam () { 173 for (SectorEntityToken entity : fleet.getContainingLocation().getAllEntities()) { 174 if (Entities.CARGO_PODS.equals(entity.getCustomEntityType())) { 175 VisibilityLevel level = entity.getVisibilityLevelTo(fleet); 176 if (level == VisibilityLevel.COMPOSITION_DETAILS || 177 level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) { 178 if (entity.getCargo().getFuel() >= 10 || entity.getCargo().getSupplies() >= 10) { 179 return true; 180 } 181 } 182 } 183 } 184 return false; 185 } 186 187 protected int getNeededFuel() { 188 return getNeededFuel(playerFleet); 189 } 190 191 public static int getNeededFuel(CampaignFleetAPI playerFleet) { 192 float returnDistLY = Misc.getDistanceLY(new Vector2f(), playerFleet.getLocationInHyperspace()); 193 int fuel = (int) (returnDistLY * Math.max(1, playerFleet.getLogistics().getFuelCostPerLightYear())); 194 fuel *= 0.75f; 195 if (fuel < 10) fuel = 10; 196 fuel -= playerFleet.getCargo().getFuel(); 197 if (fuel < 0) fuel = 0; 198 199 return fuel; 200 } 201 202 protected int getNeededSupplies() { 203 //int supplies = (int) (playerCargo.getMaxCapacity() * 0.25f); 204 float supplies = 0f; 205 for (FleetMemberAPI member : playerFleet.getFleetData().getMembersListCopy()) { 206 supplies += member.getStats().getSuppliesPerMonth().getModifiedValue(); 207 } 208 //supplies *= 2; 209 210 if (supplies < 5) supplies = 5; 211 supplies -= playerCargo.getSupplies(); 212 if (supplies < 0) supplies = 0; 213 214 return (int) supplies; 215 } 216 217 protected float getRepPenalty() { 218 float uses = getNumUses(); 219 return REP_PER_USE * (uses + 1); 220 } 221 222 protected void didNotNeedHelp() { 223 float penalty = getRepPenalty(); 224 Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(), 225 penalty * 2f, RepLevel.INHOSPITABLE, person, text); 226 227 unrespond(); 228 } 229 230 protected void neverMind() { 231 float penalty = getRepPenalty(); 232 Misc.adjustRep(penalty * 0.5f, RepLevel.INHOSPITABLE, fleet.getFaction().getId(), 233 penalty, RepLevel.INHOSPITABLE, person, text); 234 } 235 236 protected int getMaxFuel() { 237 return (int) Math.max(10, (fleet.getCargo().getMaxFuel() * 0.25f)); 238 } 239 protected int getMaxSupplies() { 240 return (int) Math.max(10, (fleet.getCargo().getMaxCapacity() * 0.1f)); 241 } 242 243 protected void pay() { 244 //int credits = getPayment(); 245 int credits = (int) person.getMemoryWithoutUpdate().getFloat("$distressPayment"); 246 playerCargo.getCredits().subtract(credits); 247 AddRemoveCommodity.addCreditsLossText(credits, text); 248 249 float uses = getNumUses(); 250 if (uses <= 4) { 251 Misc.adjustRep(0.01f, RepLevel.WELCOMING, fleet.getFaction().getId(), 252 0.02f, RepLevel.WELCOMING, person, text); 253 } 254 } 255 256 protected void thank() { 257 float penalty = getRepPenalty(); 258 Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(), 259 penalty * 2f, RepLevel.INHOSPITABLE, person, text); 260 } 261 262 protected void acceptAid() { 263 int fuel = getNeededFuel(); 264 int supplies = getNeededSupplies(); 265 266 int maxFuel = getMaxFuel(); 267 int maxSupplies = getMaxSupplies(); 268 269 if (fuel > maxFuel) fuel = maxFuel; 270 if (supplies > maxSupplies) supplies = maxSupplies; 271 272// float penalty = getRepPenalty(); 273// Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(), 274// penalty * 2f, RepLevel.INHOSPITABLE, person, text); 275 276 if (fuel > 0) { 277 playerCargo.addFuel(fuel); 278 AddRemoveCommodity.addCommodityGainText(Commodities.FUEL, fuel, text); 279 } 280 if (supplies > 0) { 281 playerCargo.addSupplies(supplies); 282 AddRemoveCommodity.addCommodityGainText(Commodities.SUPPLIES, supplies, text); 283 } 284 285 unrespond(); 286 } 287 288 protected void unrespond() { 289 Misc.clearTarget(fleet, true); 290 Misc.makeUnimportant(fleet, "distressResponse"); 291 fleet.getMemoryWithoutUpdate().unset("$distressResponse"); 292 Misc.giveStandardReturnToSourceAssignments(fleet); 293 } 294 295 296 297} 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312