001package com.fs.starfarer.api.campaign.impl.items;
002
003import java.util.HashSet;
004import java.util.Iterator;
005import java.util.List;
006import java.util.Random;
007import java.util.Set;
008
009import java.awt.Color;
010
011import org.json.JSONArray;
012import org.json.JSONException;
013import org.json.JSONObject;
014
015import com.fs.starfarer.api.Global;
016import com.fs.starfarer.api.campaign.CargoStackAPI;
017import com.fs.starfarer.api.campaign.CargoTransferHandlerAPI;
018import com.fs.starfarer.api.campaign.econ.MarketAPI;
019import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
020import com.fs.starfarer.api.combat.HullModEffect;
021import com.fs.starfarer.api.combat.ShipAPI.HullSize;
022import com.fs.starfarer.api.graphics.SpriteAPI;
023import com.fs.starfarer.api.impl.campaign.DebugFlags;
024import com.fs.starfarer.api.impl.campaign.ids.Tags;
025import com.fs.starfarer.api.loading.HullModSpecAPI;
026import com.fs.starfarer.api.ui.Alignment;
027import com.fs.starfarer.api.ui.TooltipMakerAPI;
028import com.fs.starfarer.api.util.Misc;
029import com.fs.starfarer.api.util.WeightedRandomPicker;
030
031public class ModSpecItemPlugin extends BaseSpecialItemPlugin {
032        private String modId;
033        private HullModSpecAPI modSpec;
034        //private SpriteAPI sprite;
035
036        @Override
037        public void init(CargoStackAPI stack) {
038                super.init(stack);
039                modId = stack.getSpecialDataIfSpecial().getData();
040                modSpec = Global.getSettings().getHullModSpec(modId);
041                
042                //sprite = Global.getSettings().getSprite(modSpec.getSpriteName());
043        }
044
045        @Override
046        public void render(float x, float y, float w, float h, float alphaMult,
047                                           float glowMult, SpecialItemRendererAPI renderer) {
048                float cx = x + w/2f;
049                float cy = y + h/2f;
050                
051                cx -= 2;
052                cy -= 1;
053                
054                x = (int) x;
055                y = (int) y;
056                w = (int) w;
057                h = (int) h;
058                
059                boolean known = Global.getSector().getCharacterData().knowsHullMod(modId);
060                float mult = 1f;
061                if (known) {
062                        mult = 0.5f;
063                }
064                
065                SpriteAPI sprite = Global.getSettings().getSprite(modSpec.getSpriteName());
066                
067//              sprite.setNormalBlend();
068//              sprite.setAlphaMult(alphaMult * mult);
069//              
070//              sprite.renderAtCenter(cx, cy);
071//              
072//              if (glowMult > 0) {
073//                      sprite.setAlphaMult(alphaMult * glowMult * 0.5f * mult);
074//                      sprite.renderAtCenter(cx, cy);
075//              }
076//              
077//              renderer.renderScanlines(sprite, cx, cy, alphaMult);
078//              if (!known) {
079//                      renderer.renderSchematic(sprite, cx, cy, alphaMult * 0.67f);
080//              }
081//              
082//              if (true) return;
083                
084                
085                w = sprite.getWidth() * 1.5f + 5;
086                h = sprite.getHeight() * 1.5f;
087//              x = cx - w / 2f;
088//              y = cy - h / 2f;
089                
090                x = cx;
091                y = cy;
092                
093//              float blX = x - w / 2f;
094//              float blY = y - h / 2f + 7;
095//              float tlX = x - w / 2f + 10;
096//              float tlY = y + h / 2f - 7;
097//              float trX = x + w / 2f;
098//              float trY = y + h / 2f;
099//              float brX = x + w / 2f - 10;
100//              float brY = y - h / 2f;
101                
102// modspec.png
103//              float blX = -23f;
104//              float blY = -10f;
105//              float tlX = -14f;
106//              float tlY = 21f;
107//              float trX = 25f;
108//              float trY = 20f;
109//              float brX = 23f;
110//              float brY = -10f;
111
112// modspec2.png
113                float blX = -23f;
114                float blY = -10f;
115                float tlX = -18f;
116                float tlY = 24f;
117                float trX = 24f;
118                float trY = 24f;
119                float brX = 23f;
120                float brY = -10f;
121                
122//              float tilt = 5;
123//              float b = Global.getSector().getCampaignUI().getSharedFader().getBrightness();
124//              tilt = 20f * b - 10f;
125//              w = 100;
126//              h = 100;
127//              tilt = 10;
128                
129                sprite.setAlphaMult(alphaMult * mult);
130                sprite.setNormalBlend();
131                sprite.renderWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY);
132                
133                
134                if (glowMult > 0) {
135                        sprite.setAlphaMult(alphaMult * glowMult * 0.5f * mult);
136                        //sprite.renderAtCenter(cx, cy);
137                        sprite.setAdditiveBlend();
138                        sprite.renderWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY);
139                }
140                
141                //renderer.renderScanlines(sprite, cx, cy, alphaMult);
142                renderer.renderScanlinesWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY, alphaMult, false);
143                if (!known) {
144                        //renderer.renderSchematic(sprite, cx, cy, alphaMult * 0.67f);
145                        renderer.renderSchematicWithCorners(sprite, null, blX, blY, tlX, tlY, trX, trY, brX, brY, alphaMult * 0.67f);
146                }
147        }
148
149        @Override
150        public int getPrice(MarketAPI market, SubmarketAPI submarket) {
151                if (modSpec != null) return (int) modSpec.getBaseValue();
152                return super.getPrice(market, submarket);
153        }
154        
155        @Override
156        public String getName() {
157                return modSpec.getDisplayName() + " - Modspec";
158        }
159
160        
161        @Override
162        public String getDesignType() {
163                if (modSpec != null) {
164                        return modSpec.getManufacturer();
165                }
166                return null;
167        }
168        
169        @Override
170        public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, CargoTransferHandlerAPI transferHandler, Object stackSource) {
171                //super.createTooltip(tooltip, expanded, transferHandler, stackSource);
172                
173                // not needed, done in core code that calls this
174//              if (spec.hasTag(Tags.CODEX_UNLOCKABLE)) {
175//                      SharedUnlockData.get().reportPlayerAwareOfHullmod(spec.getId(), true);
176//              }
177                
178                float pad = 3f;
179                float opad = 10f;
180                float small = 5f;
181                Color h = Misc.getHighlightColor();
182                Color g = Misc.getGrayColor();
183                Color b = Misc.getButtonTextColor();
184                b = Misc.getPositiveHighlightColor();
185
186                tooltip.addTitle(getName());
187                
188                String design = getDesignType();
189                Misc.addDesignTypePara(tooltip, design, 10f);
190                
191                if (!spec.getDesc().isEmpty()) {
192                        tooltip.addPara(spec.getDesc(), Misc.getGrayColor(), opad);
193                }
194                
195                tooltip.addSectionHeading("Effect", Alignment.MID, opad * 1f);
196                
197                HullModEffect e = modSpec.getEffect();
198                HullSize size = HullSize.CAPITAL_SHIP;
199                if (e.shouldAddDescriptionToTooltip(size, null, true)) {
200                        final String [] params = new String [] { 
201                                         e.getDescriptionParam(0, size, null),
202                                         e.getDescriptionParam(1, size, null),
203                                         e.getDescriptionParam(2, size, null),
204                                         e.getDescriptionParam(3, size, null),
205                                         e.getDescriptionParam(4, size, null),
206                                         e.getDescriptionParam(5, size, null),
207                                         e.getDescriptionParam(6, size, null),
208                                         e.getDescriptionParam(7, size, null),
209                                         e.getDescriptionParam(8, size, null),
210                                         e.getDescriptionParam(9, size, null)
211                                };
212                        
213                        tooltip.addPara(modSpec.getDescription(size).replaceAll("\\%", "%%"), opad, h, params);
214                        //e.getDescriptionParam(0, size);
215                }
216                
217                e.addPostDescriptionSection(tooltip, size, null, getTooltipWidth(), true);
218                
219                if (e.hasSModEffectSection(size, null, false)) {
220                        e.addSModSection(tooltip, size, null, getTooltipWidth(), true, false);
221                }
222                
223                e.addRequiredItemSection(tooltip, null, null, null, getTooltipWidth(), true);
224                
225                addCostLabel(tooltip, opad, transferHandler, stackSource);
226                
227                //if (CampaignEngine.getInstance().getCharacterData().getPerson().getStats().isHullModAvailable(id)) {
228                //tooltip.setParaSmallOrbitron();
229                
230                boolean known = Global.getSector().getCharacterData().knowsHullMod(modId);
231                if (known) {
232                        //tooltip.addPara("Already known", g, pad).setAlignment(Alignment.MID);
233                        tooltip.addPara("Already known", g, opad);
234                } else {
235                        //tooltip.addPara("Right-click to learn", b, pad).setAlignment(Alignment.MID);
236                        tooltip.addPara("Right-click to learn", b, opad);
237                }
238        }
239
240        @Override
241        public float getTooltipWidth() {
242                return super.getTooltipWidth();
243        }
244        
245        @Override
246        public boolean isTooltipExpandable() {
247                return false;
248        }
249        
250        @Override
251        public boolean hasRightClickAction() {
252                return true;
253        }
254
255        @Override
256        public boolean shouldRemoveOnRightClickAction() {
257                return !Global.getSector().getCharacterData().knowsHullMod(modId);
258        }
259
260        @Override
261        public void performRightClickAction() {
262                if (Global.getSector().getCharacterData().knowsHullMod(modId)) {
263                        Global.getSector().getCampaignUI().getMessageDisplay().addMessage(
264                                        "" + modSpec.getDisplayName() + ": already known");//,
265                } else {
266                        Global.getSoundPlayer().playUISound("ui_acquired_hullmod", 1, 1);
267                        Global.getSector().getCharacterData().addHullMod(modId);
268                        Global.getSector().getCampaignUI().getMessageDisplay().addMessage(
269                                        "Acquired hull mod: " + modSpec.getDisplayName() + "");
270                }
271        }
272
273        @Override
274        public String resolveDropParamsToSpecificItemData(String params, Random random) throws JSONException {
275                if (params == null || params.isEmpty()) return null;
276                
277                
278                JSONObject json = new JSONObject(params);
279                
280                int tier = json.optInt("tier", -1);
281                Set<String> tags = new HashSet<String>();
282                if (json.has("tags")) {
283                        JSONArray tagsArray = json.getJSONArray("tags");
284                        for (int i = 0; i < tagsArray.length(); i++) {
285                                tags.add(tagsArray.getString(i));
286                        }
287                }
288                
289                List<HullModSpecAPI> specs = Global.getSettings().getAllHullModSpecs();
290                
291                Iterator<HullModSpecAPI> iter = specs.iterator();
292                while (iter.hasNext()) {
293                        HullModSpecAPI curr = iter.next();
294                        boolean known = Global.getSector().getPlayerFaction().knowsHullMod(curr.getId());
295                        if (DebugFlags.ALLOW_KNOWN_HULLMOD_DROPS) known = false;
296                        if (known || curr.isHidden() || curr.isHiddenEverywhere() || curr.hasTag(Tags.HULLMOD_NO_DROP)) {
297                                iter.remove();
298                                continue;
299                        }
300                }
301                
302                if (tier >= 0) {
303                        iter = specs.iterator();
304                        while (iter.hasNext()) {
305                                HullModSpecAPI curr = iter.next();
306                                if (curr.getTier() != tier) iter.remove();
307                        }
308                }
309                
310                if (!tags.isEmpty()) {
311                        iter = specs.iterator();
312                        while (iter.hasNext()) {
313                                HullModSpecAPI curr = iter.next();
314                                for (String tag : tags) {
315                                        boolean not = tag.startsWith("!");
316                                        tag = not ? tag.substring(1) : tag;
317                                        boolean has = curr.hasTag(tag);
318                                        if (not == has) {
319                                                iter.remove();
320                                                break;
321                                        }
322                                }
323                        }
324                }
325                
326                WeightedRandomPicker<HullModSpecAPI> picker = new WeightedRandomPicker<HullModSpecAPI>(random);
327                for (HullModSpecAPI spec : specs) {
328                        picker.add(spec, 1f * spec.getRarity());
329                }
330                HullModSpecAPI pick = picker.pick();
331                if (pick == null) {
332                        return null;
333                } else {
334                        return pick.getId(); 
335                }
336        }
337
338        public String getModId() {
339                return modId;
340        }
341
342        
343        
344}
345
346
347
348
349