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.FactionAPI;
014import com.fs.starfarer.api.campaign.InteractionDialogAPI;
015import com.fs.starfarer.api.campaign.RepLevel;
016import com.fs.starfarer.api.campaign.comm.CommMessageAPI;
017import com.fs.starfarer.api.campaign.comm.MessagePriority;
018import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
019import com.fs.starfarer.api.campaign.rules.MemoryAPI;
020import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
021import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
022import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
023import com.fs.starfarer.api.impl.campaign.ids.Factions;
024import com.fs.starfarer.api.util.Misc;
025import com.fs.starfarer.api.util.Misc.Token;
026
027/**
028 * @author Alex Mosolov
029 *
030 * Copyright 2015 Fractal Softworks, LLC
031 */
032public class FactionHostilityEvent extends BaseEventPlugin {
033        
034        public static final float HOSTILITY_PENALTY = 0.2f;
035        
036        public static class FactionHostilityPairKey {
037                protected FactionAPI one;
038                protected FactionAPI two;
039                public FactionHostilityPairKey(FactionAPI one, FactionAPI two) {
040                        this.one = one;
041                        this.two = two;
042                        if (one.getId().compareTo(two.getId()) > 0) {
043                                FactionAPI temp = one;
044                                one = two;
045                                two = temp;
046                        }
047                }
048                public FactionHostilityPairKey(String one, String two) {
049                        this(Global.getSector().getFaction(one), Global.getSector().getFaction(two));
050                }
051                public FactionAPI getOne() {
052                        return one;
053                }
054                public FactionAPI getTwo() {
055                        return two;
056                }
057                
058                @Override
059                public int hashCode() {
060                        final int prime = 31;
061                        int result = 1;
062                        result = prime * result
063                                        + ((one == null) ? 0 : one.hashCode());
064                        result = prime * result + ((two == null) ? 0 : two.hashCode());
065                        return result;
066                }
067                @Override
068                public boolean equals(Object obj) {
069                        if (this == obj)
070                                return true;
071                        if (obj == null)
072                                return false;
073                        if (getClass() != obj.getClass())
074                                return false;
075                        FactionHostilityPairKey other = (FactionHostilityPairKey) obj;
076                        if (one == null) {
077                                if (other.one != null)
078                                        return false;
079                        } else if (one != other.one)
080                                return false;
081                        if (this.two == null) {
082                                if (other.two != null)
083                                        return false;
084                        } else if (this.two != other.two)
085                                return false;
086                        return true;
087                }
088        }
089        
090        
091        public static Logger log = Global.getLogger(FactionHostilityEvent.class);
092        
093        protected float elapsedDays = 0f;
094        protected float duration = 0f;
095        
096        protected FactionHostilityPairKey target = null;
097        protected FactionAPI one, two;
098        protected boolean ended = false;
099        protected float prevRel = 0f;
100        
101        protected float prevRelOne = 0f;
102        protected float prevRelTwo = 0f;
103        
104        public void init(String type, CampaignEventTarget eventTarget) {
105                super.init(type, eventTarget, false);
106        }
107        
108        public void startEvent() {
109                super.startEvent(true);
110                
111                if (!(eventTarget.getCustom() instanceof FactionHostilityPairKey)) {
112                        endEvent();
113                        return;
114                }
115                target = (FactionHostilityPairKey) eventTarget.getCustom();
116                one = target.one;
117                two = target.two;
118                
119                duration = 365f * (0.5f + 0.5f * (float) Math.random());
120                
121                log.info(String.format("Starting hostility event: %s -> %s", one.getDisplayName(), two.getDisplayName()));
122                
123                FactionAPI commFac = Misc.getCommissionFaction();
124                if (commFac != null && (commFac == one || commFac == two)) {
125                        Global.getSector().reportEventStage(this, "warning", Global.getSector().getPlayerFleet(), MessagePriority.ENSURE_DELIVERY, null);
126                }
127        }
128        
129        protected void startHostilities() {
130                log.info(String.format("Making factions hostile: %s -> %s", one.getDisplayName(), two.getDisplayName()));
131                prevRel = one.getRelationship(two.getId());
132                one.setRelationship(two.getId(), RepLevel.HOSTILE);
133                
134                prevRelOne = one.getRelationship(Factions.PLAYER);
135                prevRelTwo = two.getRelationship(Factions.PLAYER);
136                
137                final FactionAPI commFac = Misc.getCommissionFaction();
138                if (commFac != null && (commFac == one || commFac == two)) {
139                        Global.getSector().reportEventStage(this, "start", Global.getSector().getPlayerFleet(), 
140                                        MessagePriority.ENSURE_DELIVERY, new BaseOnMessageDeliveryScript() {
141                                public void beforeDelivery(CommMessageAPI message) {
142                                        Global.getSector().adjustPlayerReputation(
143                                                        new RepActionEnvelope(RepActions.MAKE_HOSTILE_AT_BEST, null, null, true), 
144                                                        (commFac == one ? two : one).getId());                                  
145                                }
146                        });
147                } else {
148                        Global.getSector().reportEventStage(this, "start", Global.getSector().getPlayerFleet(), MessagePriority.ENSURE_DELIVERY, null);
149                }
150        }
151        
152        //protected boolean started = false;
153        
154        public void advance(float amount) {
155                if (!isEventStarted()) return;
156                if (isDone()) return;
157                
158                float days = Global.getSector().getClock().convertToDays(amount);
159                elapsedDays += days;
160                
161                if (!started && elapsedDays > 10f) {
162                        startHostilities();
163                        started = true;
164                }
165                
166                if (elapsedDays >= duration) {
167                        endEvent();
168                }
169        }
170        
171        protected void endEvent() {
172                if (ended) return;
173                
174                ended = true;
175                
176                one.setRelationship(two.getId(), Math.max(0f, prevRel));
177                
178                Global.getSector().reportEventStage(this, "end", Global.getSector().getPlayerFleet(), MessagePriority.ENSURE_DELIVERY, new BaseOnMessageDeliveryScript() {
179                        public void beforeDelivery(CommMessageAPI message) {
180                                FactionAPI commFac = Misc.getCommissionFaction();
181                                if (commFac == null) return;
182                                if (commFac != one && commFac != two) return;
183                                
184                                FactionAPI other = one;
185                                float prevRel = prevRelOne;
186                                if (other == commFac) {
187                                        other = two;
188                                        prevRel = prevRelTwo;
189                                }
190                                
191                                float currRel = other.getRelationship(Factions.PLAYER);
192                                CustomRepImpact impact = new CustomRepImpact();
193                                impact.delta = (prevRel - currRel - HOSTILITY_PENALTY);
194                                if (impact.delta < 0) impact.delta = 0;
195                                Global.getSector().adjustPlayerReputation(
196                                                new RepActionEnvelope(RepActions.CUSTOM, impact, null, true), 
197                                                                                          other.getId());
198                        }
199                });
200        }
201        
202        @Override
203        public String getEventName() {
204                String postfix = " hostilities";
205                if (isDone()) {
206                        postfix = " hostilities - over";
207                }
208                //return "Hostilities: " + Misc.ucFirst(one.getDisplayName()) + " / " + Misc.ucFirst(two.getDisplayName()) + postfix;
209                return Misc.ucFirst(one.getDisplayName()) + " / " + Misc.ucFirst(two.getDisplayName()) + postfix;
210        }
211        
212        
213
214        @Override
215        public boolean callEvent(String ruleId, InteractionDialogAPI dialog, 
216                                                        List<Token> params, Map<String, MemoryAPI> memoryMap) {
217                String action = params.get(0).getString(memoryMap);
218                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
219                CargoAPI cargo = playerFleet.getCargo();
220                
221                if (action.equals("TODO")) {
222                } 
223                return true;
224        }
225
226        @Override
227        public Map<String, String> getTokenReplacements() {
228                Map<String, String> map = super.getTokenReplacements();
229                
230
231                addFactionNameTokens(map, "one", one);
232                addFactionNameTokens(map, "two", two);
233                
234                FactionAPI commFac = Misc.getCommissionFaction();
235                if (commFac != null && (commFac == one || commFac == two)) {
236                        map.put("$sender", commFac.getDisplayName());
237                        addFactionNameTokens(map, "commission", commFac);
238                        addFactionNameTokens(map, "other", commFac == one ? two : one);
239                }
240                
241                //map.put("$sender", "Unknown");
242                return map;
243        }
244        
245        public String[] getHighlights(String stageId) {
246                List<String> result = new ArrayList<String>();
247                //addTokensToList(result, "$duration");
248                return result.toArray(new String[0]);
249        }
250
251        public boolean isDone() {
252                return ended;
253        }
254
255}
256
257
258
259
260
261
262