001package com.fs.starfarer.api.loading;
002
003import java.util.HashSet;
004import java.util.Set;
005
006import org.json.JSONException;
007import org.json.JSONObject;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.PersonImportance;
011import com.fs.starfarer.api.campaign.RepLevel;
012import com.fs.starfarer.api.impl.campaign.missions.hub.BaseHubMission;
013import com.fs.starfarer.api.impl.campaign.missions.hub.HubMission;
014import com.fs.starfarer.api.util.Misc;
015
016/**
017 * Note: if person id, tagsAll, tagsAny, and tagsNotAny are all blank, 
018 * the mission will not be offered by any contact without specific 
019 * scripting to make it so (via BeginMission, etc). 
020 * 
021 * Otherwise, the mission may be offered by any contact that 
022 * meets the conditions specified by these columns.
023 * 
024 * @author Alex
025 *
026 * Copyright 2021 Fractal Softworks, LLC
027 */
028public class PersonMissionSpec {
029        
030        //mission id    person id       tagsAny tagsAll tagsNotAny
031        //freq  min timeout     max timeout     minRep  maxRep  importance      plugin
032        
033        protected String missionId;
034        protected String personId;
035        
036        protected Set<String> tags = new HashSet<String>();
037        protected Set<String> tagsAny = new HashSet<String>();
038        protected Set<String> tagsAll = new HashSet<String>();
039        protected Set<String> tagsNotAny = new HashSet<String>();
040        
041        protected Set<String> reqMissionAny = new HashSet<String>();
042        protected Set<String> reqMissionAll = new HashSet<String>();
043        protected Set<String> reqMissionNone = new HashSet<String>();
044        
045        protected RepLevel min;
046        protected RepLevel max;
047        
048        protected float freq;
049        protected float minTimeout;
050        protected float maxTimeout;
051        
052        //protected float importance;
053        protected PersonImportance importance;
054        
055        protected String pluginClass;
056        protected String icon;
057        
058        
059        public PersonMissionSpec(JSONObject row) throws JSONException {
060                
061                missionId = row.getString("mission id");
062                personId = row.optString("person id", null);
063                if (personId != null && personId.isEmpty()) personId = null;
064                
065//              min = Misc.mapToEnum(row, "minRep", RepLevel.class, null, false);
066//              max = Misc.mapToEnum(row, "maxRep", RepLevel.class, null, false);
067                min = Misc.mapToEnum(row, "min rep", RepLevel.class, RepLevel.VENGEFUL);
068                max = Misc.mapToEnum(row, "max rep", RepLevel.class, RepLevel.COOPERATIVE);
069                
070                freq = (float)row.optDouble("freq", 10f);
071                minTimeout = (float)row.optDouble("min timeout", 10f);
072                maxTimeout = (float)row.optDouble("max timeout", 10f);
073                //importance = (float)row.optDouble("importance", 0f);
074                importance = Misc.mapToEnum(row, "importance", PersonImportance.class, PersonImportance.VERY_LOW);
075                
076                pluginClass = row.getString("plugin");
077                
078                icon = row.optString("icon");
079                if (icon == null || icon.isEmpty()) {
080                        icon = null;
081                }
082                
083                String requiresAllStr = row.optString("tagsAll", null);
084                if (requiresAllStr != null) {
085                        String [] split = requiresAllStr.split(",");
086                        for (String tag : split) {
087                                tag = tag.trim();
088                                if (tag.isEmpty()) continue;
089                                tagsAll.add(tag);
090                        }
091                }
092                
093                String requiresAnyStr = row.optString("tagsAny", null);
094                if (requiresAnyStr != null) {
095                        String [] split = requiresAnyStr.split(",");
096                        for (String tag : split) {
097                                tag = tag.trim();
098                                if (tag.isEmpty()) continue;
099                                tagsAny.add(tag);
100                        }
101                }
102                
103                String requiresNotAny = row.optString("tagsNotAny", null);
104                if (requiresNotAny != null) {
105                        String [] split = requiresNotAny.split(",");
106                        for (String tag : split) {
107                                tag = tag.trim();
108                                if (tag.isEmpty()) continue;
109                                tagsNotAny.add(tag);
110                        }
111                }
112                
113                String tagsStr = row.optString("tags", null);
114                if (tagsStr != null) {
115                        String [] split = tagsStr.split(",");
116                        for (String tag : split) {
117                                tag = tag.trim();
118                                if (tag.isEmpty()) continue;
119                                tags.add(tag);
120                        }
121                }
122                
123                //reqMissionAny reqMissionAll   reqMissionNone
124                String reqs = row.optString("reqMissionAny", null);
125                if (reqs != null) {
126                        String [] split = reqs.split(",");
127                        for (String tag : split) {
128                                tag = tag.trim();
129                                if (tag.isEmpty()) continue;
130                                reqMissionAny.add(tag);
131                        }
132                }
133                
134                reqs = row.optString("reqMissionAll", null);
135                if (reqs != null) {
136                        String [] split = reqs.split(",");
137                        for (String tag : split) {
138                                tag = tag.trim();
139                                if (tag.isEmpty()) continue;
140                                reqMissionAll.add(tag);
141                        }
142                }
143                
144                reqs = row.optString("reqMissionNone", null);
145                if (reqs != null) {
146                        String [] split = reqs.split(",");
147                        for (String tag : split) {
148                                tag = tag.trim();
149                                if (tag.isEmpty()) continue;
150                                reqMissionNone.add(tag);
151                        }
152                }
153        }
154        
155        public String getIcon() {
156                return icon;
157        }
158
159        public void setIcon(String icon) {
160                this.icon = icon;
161        }
162
163        public Set<String> getReqMissionAny() {
164                return reqMissionAny;
165        }
166
167        public Set<String> getReqMissionAll() {
168                return reqMissionAll;
169        }
170
171        public Set<String> getReqMissionNone() {
172                return reqMissionNone;
173        }
174
175
176
177        public String getMissionId() {
178                return missionId;
179        }
180
181        public void setMissionId(String missionId) {
182                this.missionId = missionId;
183        }
184
185        public String getPersonId() {
186                return personId;
187        }
188
189        public void setPersonId(String personId) {
190                this.personId = personId;
191        }
192
193        public RepLevel getMinRep() {
194                return min;
195        }
196
197        public void setMinRep(RepLevel min) {
198                this.min = min;
199        }
200
201        public RepLevel getMaxRep() {
202                return max;
203        }
204
205        public void setMaxRep(RepLevel max) {
206                this.max = max;
207        }
208
209        public float getFreq() {
210                return freq;
211        }
212
213        public void setFreq(float freq) {
214                this.freq = freq;
215        }
216
217        public float getMinTimeout() {
218                return minTimeout;
219        }
220
221        public void setMinTimeout(float minTimeout) {
222                this.minTimeout = minTimeout;
223        }
224
225        public float getMaxTimeout() {
226                return maxTimeout;
227        }
228
229        public void setMaxTimeout(float maxTimeout) {
230                this.maxTimeout = maxTimeout;
231        }
232
233        public PersonImportance getImportance() {
234                return importance;
235        }
236
237        public void setImportance(PersonImportance importance) {
238                this.importance = importance;
239        }
240
241        public String getPluginClass() {
242                return pluginClass;
243        }
244
245        public void setPluginClass(String pluginClass) {
246                this.pluginClass = pluginClass;
247        }
248        
249        public Set<String> getTagsAny() {
250                return tagsAny;
251        }
252
253        public Set<String> getTagsAll() {
254                return tagsAll;
255        }
256
257        public Set<String> getTagsNotAny() {
258                return tagsNotAny;
259        }
260
261        public HubMission createMission() {
262                HubMission mission = (HubMission) Global.getSettings().getInstanceOfScript(pluginClass);
263                mission.setMissionId(missionId);
264                if (icon != null && mission instanceof BaseHubMission) {
265                        BaseHubMission bhm = (BaseHubMission) mission;
266                        bhm.setIconName(icon);
267                }
268                return mission;
269        }
270        
271        public Set<String> getTags() {
272                return tags;
273        }
274        
275        public void addTag(String tag) {
276                tags.add(tag);
277        }
278
279        public boolean hasTag(String tag) {
280                return tags.contains(tag);
281        }
282        
283        
284        public boolean tagsMatch(Set<String> tags) {
285                
286                boolean foundAll = true;
287                for (String tag : getTagsAll()) {
288                        if (!tags.contains(tag)) {
289                                foundAll = false;
290                                break;
291                        }
292                }
293                if (!foundAll && !getTagsAll().isEmpty()) return false;
294                
295
296                boolean foundOne = false;
297                for (String tag : getTagsAny()) {
298                        if (tags.contains(tag)) {
299                                foundOne = true;
300                                break;
301                        }
302                }
303                if (!foundOne && !getTagsAny().isEmpty()) return false;
304                
305                
306                foundOne = false;
307                for (String tag : getTagsNotAny()) {
308                        if (tags.contains(tag)) {
309                                foundOne = true;
310                                break;
311                        }
312                }
313                if (foundOne) return false;
314                
315                return true;
316        }
317        
318        public boolean completedMissionsMatch(Set<String> completed) {
319                
320                boolean foundAll = true;
321                for (String id : getReqMissionAll()) {
322                        if (!completed.contains(id)) {
323                                foundAll = false;
324                                break;
325                        }
326                }
327                if (!foundAll && !getReqMissionAll().isEmpty()) return false;
328                
329
330                boolean foundOne = false;
331                for (String id : getReqMissionAny()) {
332                        if (completed.contains(id)) {
333                                foundOne = true;
334                                break;
335                        }
336                }
337                if (!foundOne && !getReqMissionAny().isEmpty()) return false;
338                
339                
340                foundOne = false;
341                for (String tag : getReqMissionNone()) {
342                        if (completed.contains(tag)) {
343                                foundOne = true;
344                                break;
345                        }
346                }
347                if (foundOne) return false;
348                
349                return true;
350        }
351}
352
353
354
355
356
357