001package com.fs.starfarer.api.impl.campaign.missions.cb;
002
003import java.awt.Color;
004import java.util.ArrayList;
005import java.util.List;
006import java.util.Random;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.FactionAPI;
011import com.fs.starfarer.api.campaign.StarSystemAPI;
012import com.fs.starfarer.api.campaign.TextPanelAPI;
013import com.fs.starfarer.api.campaign.econ.MarketAPI;
014import com.fs.starfarer.api.characters.PersonAPI;
015import com.fs.starfarer.api.fleet.FleetMemberAPI;
016import com.fs.starfarer.api.fleet.FleetMemberType;
017import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepRewards;
018import com.fs.starfarer.api.impl.campaign.DebugFlags;
019import com.fs.starfarer.api.impl.campaign.missions.hub.BaseHubMission.Abortable;
020import com.fs.starfarer.api.impl.campaign.missions.hub.BaseHubMission.EntityAdded;
021import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
022import com.fs.starfarer.api.ui.TooltipMakerAPI;
023import com.fs.starfarer.api.util.Misc;
024
025public class BaseCustomBountyCreator implements CustomBountyCreator {
026        public static float DEFAULT_FREQUENCY = 10f;
027        
028        public float getBountyDays() {
029                return CBStats.DEFAULT_DAYS;
030        }
031        
032        public void addTargetLocationAndDescriptionBulletPoint(TooltipMakerAPI info,
033                        Color tc, float pad, HubMissionWithBarEvent mission,
034                        CustomBountyData data) {
035                if (data.system != null) {
036                        info.addPara("Target is in the " + data.system.getNameWithLowercaseTypeShort() + "", tc, pad);
037                }
038        }
039        
040        public void addTargetLocationAndDescription(TooltipMakerAPI info, float width, float height, HubMissionWithBarEvent mission, CustomBountyData data) {
041                float opad = 10f;
042                float pad = 3f;
043                Color h = Misc.getHighlightColor();
044                if (data.system != null) {
045                        info.addPara("The target is located in the " + data.system.getNameWithLowercaseType() + ".", opad);
046                }
047        }
048        
049        public void addIntelAssessment(TextPanelAPI text, HubMissionWithBarEvent mission, CustomBountyData data) {
050                float opad = 10f;
051                List<FleetMemberAPI> list = new ArrayList<FleetMemberAPI>();
052                List<FleetMemberAPI> members = data.fleet.getFleetData().getMembersListCopy();
053                int max = 7;
054                int cols = 7;
055                float iconSize = 440 / cols;
056                Color h = Misc.getHighlightColor();
057                
058                
059                for (FleetMemberAPI member : members) {
060                        if (list.size() >= max) break;
061                        
062                        if (member.isFighterWing()) continue;
063                        
064                        FleetMemberAPI copy = Global.getFactory().createFleetMember(FleetMemberType.SHIP, member.getVariant());
065                        if (member.isFlagship()) {
066                                copy.setCaptain(data.fleet.getCommander());
067                        }
068                        list.add(copy);
069                }
070                
071                if (!list.isEmpty()) {
072                        TooltipMakerAPI info = text.beginTooltip();
073                        info.setParaSmallInsignia();
074                        info.addPara(Misc.ucFirst(mission.getPerson().getHeOrShe()) + " taps a data pad, and " +
075                                                 "an intel assessment shows up on your tripad.", 0f);
076                        info.addShipList(cols, 1, iconSize, data.fleet.getFaction().getBaseUIColor(), list, opad);
077                        
078                        int num = members.size() - list.size();
079                        
080                        if (num < 5) num = 0;
081                        else if (num < 10) num = 5;
082                        else if (num < 20) num = 10;
083                        else num = 20;
084                        
085                        if (num > 1) {
086                                info.addPara("The assessment notes the fleet may contain upwards of %s other ships" +
087                                                " of lesser significance.", opad, h, "" + num);
088                        } else if (num > 0) {
089                                info.addPara("The assessment notes the fleet may contain several other ships" +
090                                                " of lesser significance.", opad);
091                        } else {
092                                info.addPara("It appears to contain complete information about the scope of the assignment.", opad);
093                        }
094                        text.addTooltip();
095                }
096                return;
097        }
098
099        public void addFleetDescription(TooltipMakerAPI info, float width, float height, HubMissionWithBarEvent mission, CustomBountyData data) {
100//              if (hideoutLocation != null) {
101//                      SectorEntityToken fake = hideoutLocation.getContainingLocation().createToken(0, 0);
102//                      fake.setOrbit(Global.getFactory().createCircularOrbit(hideoutLocation, 0, 1000, 100));
103//                      
104//                      String loc = BreadcrumbSpecial.getLocatedString(fake);
105//                      loc = loc.replaceAll("orbiting", "hiding out near");
106//                      loc = loc.replaceAll("located in", "hiding out in");
107//                      String sheIs = "She is";
108//                      if (person.getGender() == Gender.MALE) sheIs = "He is";
109//                      info.addPara(sheIs + " rumored to be " + loc + ".", opad);
110//              }
111                
112                PersonAPI person = data.fleet.getCommander();
113                FactionAPI faction = person.getFaction();
114                int cols = 7;
115                float iconSize = width / cols;
116                float opad = 10f;
117                Color h = Misc.getHighlightColor();
118                
119                if (DebugFlags.PERSON_BOUNTY_DEBUG_INFO) {
120
121                }
122                boolean deflate = false;
123                if (!data.fleet.isInflated()) {
124                        data.fleet.inflateIfNeeded();
125                        deflate = true;
126                }
127                
128                List<FleetMemberAPI> list = new ArrayList<FleetMemberAPI>();
129                Random random = new Random(person.getNameString().hashCode() * 170000);
130                
131                List<FleetMemberAPI> members = data.fleet.getFleetData().getMembersListCopy();
132                int max = 7;
133                for (FleetMemberAPI member : members) {
134                        if (list.size() >= max) break;
135                        
136                        if (member.isFighterWing()) continue;
137                        
138//                      float prob = (float) member.getFleetPointCost() / 20f;
139//                      prob += (float) max / (float) members.size();
140//                      if (member.isFlagship()) prob = 1f;
141//                      //if (members.size() <= max) prob = 1f;
142//                      
143//                      if (random.nextFloat() > prob) continue;
144                        
145                        FleetMemberAPI copy = Global.getFactory().createFleetMember(FleetMemberType.SHIP, member.getVariant());
146                        if (member.isFlagship()) {
147                                copy.setCaptain(person);
148                        }
149                        list.add(copy);
150                }
151                
152                if (!list.isEmpty()) {
153                        info.addPara("The bounty posting contains partial intel on some of the ships in the target fleet.", opad);
154                        info.addShipList(cols, 1, iconSize, faction.getBaseUIColor(), list, opad);
155                        
156                        int num = members.size() - list.size();
157                        //num = Math.round((float)num * (1f + random.nextFloat() * 0.5f));
158                        
159                        if (num < 5) num = 0;
160                        else if (num < 10) num = 5;
161                        else if (num < 20) num = 10;
162                        else num = 20;
163                        
164                        if (num > 1) {
165                                info.addPara("The intel assessment notes the fleet may contain upwards of %s other ships" +
166                                                " of lesser significance.", opad, h, "" + num);
167                        } else if (num > 0) {
168                                info.addPara("The intel assessment notes the fleet may contain several other ships" +
169                                                " of lesser significance.", opad);
170                        }
171                }
172                
173                if (deflate) {
174                        data.fleet.deflate();
175                }
176        }
177
178        public float getFrequency(HubMissionWithBarEvent mission, int difficulty) {
179                PersonAPI person = mission.getPerson();
180                if (!isRepeatableGlobally() && getNumCompletedGlobal() > 0) return 0f;
181                if (!isRepeatablePerPerson() && getNumCompletedForPerson(person) > 0) return 0f;
182                
183                float mult = 1f;
184                if (isReduceFrequencyBasedOnNumberOfCompletions()) {
185                        mult = 1f / (1f + (float) getNumCompletedGlobal() * 0.5f);
186                }
187                return DEFAULT_FREQUENCY * mult;
188        }
189        
190        public String getNumCompletedPerPersonKey() {
191                return "$" + getId() + "_numCompleted";
192        }
193        public String getNumCompletedGlobalKey() {
194                return "$" + getId() + "_numCompleted";
195        }
196        
197        
198        protected boolean isRepeatablePerPerson() {
199                return true;
200        }
201        protected boolean isRepeatableGlobally() {
202                return true;
203        }
204        protected boolean isReduceFrequencyBasedOnNumberOfCompletions() {
205                return false;
206        }
207
208        public String getId() {
209                return getClass().getSimpleName();
210        }
211
212        public boolean systemMatchesRequirement(StarSystemAPI system) {
213                return true;
214        }
215
216        public float getRepFaction() {
217                return RepRewards.TINY;
218        }
219
220        public float getRepPerson() {
221                return RepRewards.MEDIUM;
222        }
223
224        protected static Object STAGE = new Object();
225        protected void beginFleet(HubMissionWithBarEvent mission, CustomBountyData data) {
226                mission.beginStageTrigger(STAGE);
227        }
228        
229        protected CampaignFleetAPI createFleet(HubMissionWithBarEvent mission, CustomBountyData data) {
230                mission.triggerMakeFleetIgnoreOtherFleetsExceptPlayer();
231                mission.triggerFleetOnlyEngageableWhenVisibleToPlayer();
232                mission.endTrigger();
233                
234                List<Abortable> before = new ArrayList<Abortable>(mission.getChanges());
235                List<CampaignFleetAPI> fleets = mission.runStageTriggersReturnFleets(STAGE);
236                if (fleets.isEmpty()) return null;
237                
238                CampaignFleetAPI fleet = fleets.get(0);
239                mission.getChanges().add(new EntityAdded(fleet)); // so it's removed when the mission is abort()ed
240                
241                for (Abortable curr : mission.getChanges()) {
242                        if (!before.contains(curr)) {
243                                data.abortWhenOtherVersionAccepted.add(curr);
244                        }
245                }
246                return fleet;
247        }
248
249        public void notifyCompleted(HubMissionWithBarEvent mission, CustomBountyData data) {
250                PersonAPI person = mission.getPerson();
251                
252                String key = getNumCompletedGlobalKey();
253                Integer num = (Integer) Global.getSector().getMemoryWithoutUpdate().get(key);
254                if (num == null) num = 0;
255                num++;
256                Global.getSector().getMemoryWithoutUpdate().set(key, num);
257                
258                key = getNumCompletedPerPersonKey();
259                num = (Integer) person.getMemoryWithoutUpdate().get(key);
260                if (num == null) num = 0;
261                num++;
262                person.getMemoryWithoutUpdate().set(key, num);
263        }
264
265        public void notifyFailed(HubMissionWithBarEvent mission, CustomBountyData data) {
266                
267        }
268        
269        public int getNumCompletedForPerson(PersonAPI person) {
270                String key = getNumCompletedPerPersonKey();
271                Integer num = (Integer) person.getMemoryWithoutUpdate().get(key);
272                if (num == null) num = 0;
273                return num;
274        }
275        
276        public int getNumCompletedGlobal() {
277                String key = getNumCompletedGlobalKey();
278                Integer num = (Integer) Global.getSector().getMemoryWithoutUpdate().get(key);
279                if (num == null) num = 0;
280                return num;
281        }
282
283
284        public int getMinDifficulty() {
285                return MIN_DIFFICULTY;
286        }
287        
288        public int getMaxDifficulty() {
289                return MAX_DIFFICULTY;
290        }
291
292        public CustomBountyData createBounty(MarketAPI createdAt, HubMissionWithBarEvent mission, int difficulty, Object bountyStage) {
293                return null;
294        }
295        
296        public void notifyAccepted(MarketAPI createdAt, HubMissionWithBarEvent mission, CustomBountyData data) {
297                
298        }
299
300        public StarSystemAPI getSystemWithNoTimeLimit(CustomBountyData data) {
301                return data.system;
302        }
303        
304        public String getBaseBountyName(HubMissionWithBarEvent mission, CustomBountyData data) {
305                return "Bounty";
306        }
307        
308        public String getBountyNamePostfix(HubMissionWithBarEvent mission, CustomBountyData data) {
309                return null;
310        }
311        
312        public void setRepChangesBasedOnDifficulty(CustomBountyData data, int difficulty) {
313                if (difficulty <= 3) {
314                        data.repPerson = RepRewards.SMALL;
315                        data.repFaction = RepRewards.TINY;
316                } else if (difficulty <= 7) {
317                        data.repPerson = RepRewards.MEDIUM;
318                        data.repFaction = RepRewards.SMALL;
319                } else {
320                        data.repPerson = RepRewards.HIGH;
321                        data.repFaction = RepRewards.SMALL;
322                }
323        }
324        
325        public void updateInteractionData(HubMissionWithBarEvent mission, CustomBountyData data) {
326                
327        }
328        public String getIconName() {
329                return null;
330        }
331
332}
333
334
335
336