001package com.fs.starfarer.api.impl.campaign.events;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.Map;
006
007import org.apache.log4j.Logger;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.BaseOnMessageDeliveryScript;
011import com.fs.starfarer.api.campaign.CampaignFleetAPI;
012import com.fs.starfarer.api.campaign.CargoAPI;
013import com.fs.starfarer.api.campaign.InteractionDialogAPI;
014import com.fs.starfarer.api.campaign.RepLevel;
015import com.fs.starfarer.api.campaign.comm.CommMessageAPI;
016import com.fs.starfarer.api.campaign.comm.MessagePriority;
017import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
018import com.fs.starfarer.api.campaign.rules.MemoryAPI;
019import com.fs.starfarer.api.characters.PersonAPI;
020import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
021import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
022import com.fs.starfarer.api.impl.campaign.ids.Conditions;
023import com.fs.starfarer.api.impl.campaign.ids.Factions;
024import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
025import com.fs.starfarer.api.impl.campaign.ids.Ranks;
026import com.fs.starfarer.api.util.Misc;
027import com.fs.starfarer.api.util.Misc.Token;
028
029/**
030 * @author Alex Mosolov
031 *
032 * Copyright 2015 Fractal Softworks, LLC
033 */
034public class InvestigationEventSmugglingV2 extends BaseEventPlugin {
035
036        public static final String PERSON_CHECKOUT_REASON = "ISE_investigator";
037        
038        public static class InvSmugglingParams {
039                public float guiltChance;
040                public int bribeAmount;
041
042                public InvSmugglingParams() {
043                }
044        }
045        
046        public static Logger log = Global.getLogger(InvestigationEventSmugglingV2.class);
047        
048        private float elapsedDays = 0f;
049        private float duration = 0f;
050        
051        private InvSmugglingParams params;
052        private boolean bribed = false;
053        private PersonAPI investigator;
054        
055        public void init(String type, CampaignEventTarget eventTarget) {
056                super.init(type, eventTarget);
057                params = new InvSmugglingParams();
058        }
059        
060        public void startEvent() {
061                super.startEvent();
062                
063                if (market == null || market.hasCondition(Conditions.DECIVILIZED)) {
064                        endEvent();
065                        return;
066                }
067                if (market.getFaction().isAtBest(Factions.PLAYER, RepLevel.HOSTILE)) {
068                        endEvent();
069                        return;
070                }
071//              float recentBMTrade = 0;
072//              float recentOpenTrade = 0;
073// 
074//              for (SubmarketAPI sub : market.getSubmarketsCopy()) {
075//                      if (!sub.getPlugin().isParticipatesInEconomy()) continue;
076//                      
077//                      PlayerTradeDataForSubmarket tradeData =  SharedData.getData().getPlayerActivityTracker().getPlayerTradeData(sub);
078//                      
079//                      if (sub.getPlugin().isBlackMarket()) {
080//                              recentBMTrade += tradeData.getRecentBaseTradeValueImpact();
081//                      } else {
082//                              recentOpenTrade += tradeData.getRecentBaseTradeValueImpact();
083//                      }
084//              }
085//              
086//              // 10000 credits of "impact" is 1000 credit of actual trade
087//              if (recentBMTrade > recentOpenTrade * 0.5f && recentBMTrade > 10000f) {
088//                      params.guiltChance = recentBMTrade / Math.min(recentBMTrade * 10f, market.getTradeVolume());
089//                      params.bribeAmount = (int) (params.guiltChance * 100000f);
090//              } else {
091//                      endEvent();
092//                      return;
093//              }
094                
095                params.guiltChance = Math.max(0.1f, Math.min(startProbability, 0.9f));
096                params.bribeAmount = (int) ((10000f + params.guiltChance * 90000f) / 1000f) * 1000;
097
098//              // don't bother with trifling investigations
099//              if (params.guiltChance < .01f) {
100//                      endEvent();
101//                      return;
102//              }
103                
104                
105                
106                duration = 90f + 30f * (float) Math.random();
107                //duration = 5f;
108                
109                log.info(String.format("Starting smuggling investigation at %s", market.getName()));
110                
111                investigator = Global.getSector().getImportantPeople().getPerson(market.getFaction(), market,
112                                                        PERSON_CHECKOUT_REASON, Ranks.CITIZEN, Ranks.POST_INVESTIGATOR).getPerson();
113                market.getCommDirectory().addPerson(investigator);
114
115                investigator.getMemoryWithoutUpdate().set("$ise_eventRef", this, duration);
116                investigator.getMemoryWithoutUpdate().set("$ise_investigator", true, duration);
117                investigator.getMemoryWithoutUpdate().set("$ise_bribeAmount", "" + params.bribeAmount, duration);
118                investigator.getMemoryWithoutUpdate().set("$ise_bribeAmountDGS", Misc.getWithDGS(params.bribeAmount), duration);
119                Misc.setFlagWithReason(investigator.getMemoryWithoutUpdate(), 
120                                MemFlags.MEMORY_KEY_REQUIRES_DISCRETION, "ies",
121                                true, duration);
122                
123                Global.getSector().reportEventStage(this, "start_smuggling", null, MessagePriority.ENSURE_DELIVERY, null);
124        }
125        
126        public void advance(float amount) {
127                if (!isEventStarted()) return;
128                if (isDone()) return;
129                
130                float days = Global.getSector().getClock().convertToDays(amount);
131                elapsedDays += days;
132                
133                if (elapsedDays >= duration) {
134                        if (!bribed && (float) Math.random() < params.guiltChance) {
135                                Global.getSector().reportEventStage(this, "player_guilty_smuggling", null, MessagePriority.ENSURE_DELIVERY,  new BaseOnMessageDeliveryScript() {
136                                        public void beforeDelivery(CommMessageAPI message) {
137                                                Global.getSector().adjustPlayerReputation(
138                                                                new RepActionEnvelope(RepActions.SMUGGLING_INVESTIGATION_GUILTY, null, null, true), 
139                                                                market.getFactionId());
140                                        }
141                                });
142                        } else {
143                                if (bribed) {
144                                        Global.getSector().reportEventStage(this, "clear_smuggling_bribe", null, MessagePriority.ENSURE_DELIVERY, null);
145                                } else {
146                                        Global.getSector().reportEventStage(this, "clear_smuggling", null, MessagePriority.ENSURE_DELIVERY, null);
147                                }
148                        }
149                        endEvent();
150                }
151        }
152        
153        @Override
154        public String getEventName() {
155                if (isDone()) {
156                        return "Smuggling investigation - " + market.getName() + " (over)";
157                }
158                return "Smuggling investigation - " + market.getName();
159        }
160        
161        
162
163        @Override
164        public boolean callEvent(String ruleId, InteractionDialogAPI dialog, 
165                                                        List<Token> params, Map<String, MemoryAPI> memoryMap) {
166                String action = params.get(0).getString(memoryMap);
167                
168                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
169                CargoAPI cargo = playerFleet.getCargo();
170                
171                if (action.equals("paidBribe")) {
172                        return bribed;
173                } else if (action.equals("setBribePaid")) {
174                        bribed = true;
175                        return true;
176                }
177                return true;
178        }
179
180        @Override
181        public Map<String, String> getTokenReplacements() {
182                Map<String, String> map = super.getTokenReplacements();
183                
184                map.put("$InvestigatorPost", Misc.ucFirst(investigator.getPost()));
185                map.put("$investigatorName", investigator.getName().getFullName());
186                if (investigator.isMale()) {
187                        map.put("$invHimOrHer", "him");
188                } else {
189                        map.put("$invHimOrHer", "her");
190                }
191                
192                map.put("$sender", "Unknown");
193                map.put("$duration", Misc.getAtLeastStringForDays((int)duration));
194                
195                return map;
196        }
197        
198        public String[] getHighlights(String stageId) {
199                List<String> result = new ArrayList<String>();
200                addTokensToList(result, "$duration");
201                return result.toArray(new String[0]);
202        }
203
204        private boolean ended = false;
205        protected void endEvent() {
206                if (investigator != null) {
207                        investigator.getMemoryWithoutUpdate().unset("$ise_eventRef");
208                        investigator.getMemoryWithoutUpdate().unset("$ise_investigator");
209                        investigator.getMemoryWithoutUpdate().unset("$ise_bribeAmount");
210                        investigator.getMemoryWithoutUpdate().unset("$ise_bribeAmountDGS");
211                        Misc.setFlagWithReason(investigator.getMemoryWithoutUpdate(), 
212                                        MemFlags.MEMORY_KEY_REQUIRES_DISCRETION, "ies",
213                                        false, 0f);
214                        
215                        Global.getSector().getImportantPeople().returnPerson(investigator, PERSON_CHECKOUT_REASON);
216                        if (!Global.getSector().getImportantPeople().isCheckedOutForAnything(investigator)) {
217                                market.getCommDirectory().removePerson(investigator);
218                        }
219                }
220                
221                ended = true;
222                
223        }
224
225        public boolean isDone() {
226                return ended;
227        }
228
229//      public static float getPlayerRepGuiltMult(FactionAPI faction) {
230//              FactionAPI player = Global.getSector().getFaction(Factions.PLAYER);
231//              //RepLevel level = market.getFaction().getRelationshipLevel(player);
232//              RepLevel level = faction.getRelationshipLevel(player);
233//              switch (level) {
234//              case COOPERATIVE:
235//                      return 0.1f;
236//              case FRIENDLY:
237//                      return 0.2f;
238//              case WELCOMING:
239//                      return 0.3f;
240//              case FAVORABLE:
241//                      return 0.5f;
242//              case NEUTRAL:
243//                      return 1f;
244//              case SUSPICIOUS:
245//                      return 1.5f;
246//              case INHOSPITABLE:
247//                      return 2f;
248//              case HOSTILE:
249//                      return 5f;
250//              case VENGEFUL:
251//                      return 10f;
252//              }
253//              return 1f;
254//      }
255        
256}
257
258
259
260