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.FactionAPI;
011import com.fs.starfarer.api.campaign.OnMessageDeliveryScript;
012import com.fs.starfarer.api.campaign.RepLevel;
013import com.fs.starfarer.api.campaign.comm.MessagePriority;
014import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
015import com.fs.starfarer.api.impl.campaign.ids.Conditions;
016import com.fs.starfarer.api.impl.campaign.ids.Factions;
017import com.fs.starfarer.api.util.WeightedRandomPicker;
018
019/**
020 * Should only be used if started directly (not via probability), as that's the only
021 * way the investigation parameters can be set.
022 * 
023 * If using event probability, should subclass this for a new event instead,
024 * and set the parameters in startEvent() of the subclass. See SmugglingInvestigationEvent as example.
025 *  
026 * @author Alex Mosolov
027 *
028 * Copyright 2014 Fractal Softworks, LLC
029 */
030public class InvestigationEvent extends BaseEventPlugin {
031
032        public static Logger log = Global.getLogger(InvestigationEvent.class);
033        
034//      public static final String START = "start";
035//      public static final String CLEAR = "clear";
036//      public static final String PLAYER_GUILTY = "player_guilty";
037//      public static final String PLAYER_GUILTY_FALSE = "player_false";
038//      public static final String OTHER_GUILTY = "other_guilty";
039        
040        public static class InvestigationResult {
041                public String stageName;
042                public float weight = 0;
043                public MessagePriority priority = MessagePriority.SECTOR;
044                public OnMessageDeliveryScript onDelivery = null;
045                public InvestigationResult(String stage, MessagePriority priority) {
046                        this.stageName = stage;
047                        this.priority = priority;
048                }
049        }
050        
051        public static class InvestigationEventParams {
052                public String name;
053                public String startStage;
054                public String warningSender = null;
055                public MessagePriority warningPriority = MessagePriority.SECTOR;
056                public List<InvestigationResult> results = new ArrayList<InvestigationResult>();
057                public float minInitialDelay = 1f; 
058                public float maxInitialDelay = 6f;
059                public float minDuration = 10f; 
060                public float maxDuration = 15f;
061                public InvestigationEventParams(String name, String startStage) {
062                        this.name = name;
063                        this.startStage = startStage;
064                }
065                
066        }
067        
068        private float elapsedDays = 0f;
069        private float initialDelay = 0f;
070        private float duration = 0f;
071        
072        private InvestigationEventParams params;
073        
074        public void init(String type, CampaignEventTarget eventTarget) {
075                super.init(type, eventTarget);
076        }
077        
078        @Override
079        public void setParam(Object param) {
080                params = (InvestigationEventParams) param;
081        }
082
083        public void startEvent() {
084                super.startEvent();
085                
086                if (market != null && market.hasCondition(Conditions.DECIVILIZED)) {
087                        endEvent();
088                        return;
089                }
090                
091                initialDelay = params.minInitialDelay + (params.maxInitialDelay - params.minInitialDelay) * (float) Math.random();
092                duration = params.minDuration + (params.maxDuration - params.minDuration) * (float) Math.random();
093                
094                log.info(String.format("Starting investigation with suffix \"%s\" at %s. Delay: %f, dur: %f", 
095                                                                params.startStage, getTargetName(), initialDelay, duration));
096        }
097        
098        private int stage = 0;
099        public void advance(float amount) {
100                if (!isEventStarted()) return;
101                if (isDone()) return;
102                
103                float days = Global.getSector().getClock().convertToDays(amount);
104                elapsedDays += days;
105                
106                if (elapsedDays >= initialDelay && stage == 0) {
107                        stage++;
108                        log.info("Reporting investigation stage " + params.startStage + " at priority " + params.warningPriority.name());
109                        Global.getSector().reportEventStage(this, params.startStage, params.warningPriority);
110                }
111                
112                if (elapsedDays >= initialDelay + duration && stage == 1) {
113                        WeightedRandomPicker<InvestigationResult> picker = new WeightedRandomPicker<InvestigationResult>();
114                        
115                        for (InvestigationResult result : params.results) {
116                                picker.add(result, result.weight);
117                        }
118                        InvestigationResult result = picker.pick();
119                        if (result.stageName != null) {
120                                Global.getSector().reportEventStage(this, result.stageName, null, result.priority, result.onDelivery);
121                                log.info("Investigation outcome: " + result.stageName + " at priority " + result.priority);
122                        }
123                        
124                        endEvent();
125                }
126        }
127        
128        
129        @Override
130        public String getEventName() {
131                return params.name;
132        }
133        
134        
135
136        @Override
137        public Map<String, String> getTokenReplacements() {
138                Map<String, String> map = super.getTokenReplacements();
139                if (params.warningSender != null) {
140                        map.put("$sender", params.warningSender);
141                }
142                return map;
143        }
144
145        private boolean ended = false;
146        protected void endEvent() {
147                ended = true;
148        }
149
150        public boolean isDone() {
151                return ended;
152        }
153
154        public static float getPlayerRepGuiltMult(FactionAPI faction) {
155                FactionAPI player = Global.getSector().getFaction(Factions.PLAYER);
156                //RepLevel level = market.getFaction().getRelationshipLevel(player);
157                RepLevel level = faction.getRelationshipLevel(player);
158                switch (level) {
159                case COOPERATIVE:
160                        return 0.1f;
161                case FRIENDLY:
162                        return 0.2f;
163                case WELCOMING:
164                        return 0.3f;
165                case FAVORABLE:
166                        return 0.5f;
167                case NEUTRAL:
168                        return 1f;
169                case SUSPICIOUS:
170                        return 1.5f;
171                case INHOSPITABLE:
172                        return 2f;
173                case HOSTILE:
174                        return 5f;
175                case VENGEFUL:
176                        return 10f;
177                }
178                return 1f;
179        }
180        
181}
182
183
184
185