001package com.fs.starfarer.api.campaign.impl.items; 002 003import java.util.ArrayList; 004import java.util.HashSet; 005import java.util.Iterator; 006import java.util.List; 007import java.util.Random; 008import java.util.Set; 009 010import java.awt.Color; 011 012import org.json.JSONArray; 013import org.json.JSONException; 014import org.json.JSONObject; 015 016import com.fs.starfarer.api.Global; 017import com.fs.starfarer.api.campaign.CargoStackAPI; 018import com.fs.starfarer.api.campaign.CargoTransferHandlerAPI; 019import com.fs.starfarer.api.campaign.econ.MarketAPI; 020import com.fs.starfarer.api.campaign.econ.SubmarketAPI; 021import com.fs.starfarer.api.combat.ShipHullSpecAPI; 022import com.fs.starfarer.api.graphics.SpriteAPI; 023import com.fs.starfarer.api.loading.Description; 024import com.fs.starfarer.api.loading.Description.Type; 025import com.fs.starfarer.api.ui.TooltipMakerAPI; 026import com.fs.starfarer.api.util.Misc; 027import com.fs.starfarer.api.util.WeightedRandomPicker; 028 029public class ShipBlueprintItemPlugin extends BaseSpecialItemPlugin implements BlueprintProviderItem { 030 031 protected ShipHullSpecAPI ship; 032 033 @Override 034 public void init(CargoStackAPI stack) { 035 super.init(stack); 036 ship = Global.getSettings().getHullSpec(stack.getSpecialDataIfSpecial().getData()); 037 } 038 039 public List<String> getProvidedFighters() { 040 return null; 041 } 042 043 public List<String> getProvidedShips() { 044 List<String> result = new ArrayList<String>(); 045 result.add(ship.getHullId()); 046 return result; 047 } 048 049 public List<String> getProvidedWeapons() { 050 return null; 051 } 052 public List<String> getProvidedIndustries() { 053 return null; 054 } 055 056 057 @Override 058 public void render(float x, float y, float w, float h, float alphaMult, 059 float glowMult, SpecialItemRendererAPI renderer) { 060 float cx = x + w/2f; 061 float cy = y + h/2f; 062 063 float blX = cx - 30f; 064 float blY = cy - 15f; 065 float tlX = cx - 20f; 066 float tlY = cy + 26f; 067 float trX = cx + 23f; 068 float trY = cy + 26f; 069 float brX = cx + 15f; 070 float brY = cy - 18f; 071 072 String hullId = stack.getSpecialDataIfSpecial().getData(); 073 074 boolean known = Global.getSector().getPlayerFaction().knowsShip(hullId); 075 076 float mult = 1f; 077 //if (known) mult = 0.5f; 078 079 Color bgColor = Global.getSector().getPlayerFaction().getDarkUIColor(); 080 bgColor = Misc.setAlpha(bgColor, 255); 081 082 //float b = Global.getSector().getCampaignUI().getSharedFader().getBrightness() * 0.25f; 083 renderer.renderBGWithCorners(bgColor, blX, blY, tlX, tlY, trX, trY, brX, brY, 084 alphaMult * mult, glowMult * 0.5f * mult, false); 085 renderer.renderShipWithCorners(hullId, null, blX, blY, tlX, tlY, trX, trY, brX, brY, 086 alphaMult * mult, glowMult * 0.5f * mult, !known); 087 088 089 SpriteAPI overlay = Global.getSettings().getSprite("ui", "bpOverlayShip"); 090 overlay.setColor(Color.green); 091 overlay.setColor(Global.getSector().getPlayerFaction().getBrightUIColor()); 092 overlay.setAlphaMult(alphaMult); 093 overlay.setNormalBlend(); 094 renderer.renderScanlinesWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY, alphaMult, false); 095 096 097 if (known) { 098 renderer.renderBGWithCorners(Color.black, blX, blY, tlX, tlY, trX, trY, brX, brY, 099 alphaMult * 0.5f, 0f, false); 100 } 101 102 103 overlay.renderWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY); 104 } 105 106 @Override 107 public int getPrice(MarketAPI market, SubmarketAPI submarket) { 108 if (ship != null) { 109 //float base = super.getPrice(market, submarket); 110 float base = 0; 111 switch (ship.getHullSize()) { 112 case CAPITAL_SHIP: 113 base = Global.getSettings().getFloat("blueprintBasePriceCapital");; 114 break; 115 case CRUISER: 116 base = Global.getSettings().getFloat("blueprintBasePriceCruiser");; 117 break; 118 case DESTROYER: 119 base = Global.getSettings().getFloat("blueprintBasePriceDestroyer");; 120 break; 121 case FRIGATE: 122 case FIGHTER: 123 base = Global.getSettings().getFloat("blueprintBasePriceFrigate");; 124 break; 125 } 126 return (int)(base + ship.getBaseValue() * getItemPriceMult()); 127 } 128 return super.getPrice(market, submarket); 129 } 130 131 @Override 132 protected float getItemPriceMult() { 133 return Global.getSettings().getFloat("blueprintPriceOriginalShipMult"); 134 } 135 136 @Override 137 public String getName() { 138 if (ship != null) { 139 //return ship.getHullName() + " Blueprint"; 140 return ship.getNameWithDesignationWithDashClass() + " Blueprint"; 141 } 142 return super.getName(); 143 } 144 145 @Override 146 public String getDesignType() { 147 if (ship != null) { 148 return ship.getManufacturer(); 149 } 150 return null; 151 } 152 153 @Override 154 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, CargoTransferHandlerAPI transferHandler, Object stackSource) { 155 super.createTooltip(tooltip, expanded, transferHandler, stackSource); 156 157 float pad = 3f; 158 float opad = 10f; 159 float small = 5f; 160 Color h = Misc.getHighlightColor(); 161 Color g = Misc.getGrayColor(); 162 Color b = Misc.getButtonTextColor(); 163 b = Misc.getPositiveHighlightColor(); 164 165 166 String hullId = stack.getSpecialDataIfSpecial().getData(); 167 boolean known = Global.getSector().getPlayerFaction().knowsShip(hullId); 168 169 List<String> hulls = new ArrayList<String>(); 170 hulls.add(hullId); 171 addShipList(tooltip, "Ship hulls:", hulls, 1, opad); 172 Description desc = Global.getSettings().getDescription(ship.getDescriptionId(), Type.SHIP); 173 174 String prefix = ""; 175 if (ship.getDescriptionPrefix() != null) { 176 prefix = ship.getDescriptionPrefix() + "\n\n"; 177 } 178 tooltip.addPara(prefix + desc.getText1FirstPara(), opad); 179 180 addCostLabel(tooltip, opad, transferHandler, stackSource); 181 182 if (known) { 183 tooltip.addPara("Already known", g, opad); 184 } else { 185 tooltip.addPara("Right-click to learn", b, opad); 186 } 187 } 188 189 @Override 190 public boolean hasRightClickAction() { 191 return true; 192 } 193 194 @Override 195 public boolean shouldRemoveOnRightClickAction() { 196 String hullId = stack.getSpecialDataIfSpecial().getData(); 197 return !Global.getSector().getPlayerFaction().knowsShip(hullId); 198 } 199 200 @Override 201 public void performRightClickAction() { 202 String hullId = stack.getSpecialDataIfSpecial().getData(); 203 204// ShipHullSpecAPI spec = Global.getSettings().getHullSpec(hullId); 205// if (spec != null && spec.hasTag(Tags.CODEX_UNLOCKABLE)) { 206// String baseId = CodexDataV2.getBaseHullId(spec); 207// SharedUnlockData.get().reportPlayerAwareOfShip(baseId, true); 208// } 209 210 if (Global.getSector().getPlayerFaction().knowsShip(hullId)) { 211 Global.getSector().getCampaignUI().getMessageDisplay().addMessage( 212 "" + ship.getNameWithDesignationWithDashClass() + ": blueprint already known");//, 213 } else { 214 Global.getSoundPlayer().playUISound("ui_acquired_blueprint", 1, 1); 215 Global.getSector().getPlayerFaction().addKnownShip(hullId, true); 216 217 Global.getSector().getCampaignUI().getMessageDisplay().addMessage( 218 "Acquired blueprint: " + ship.getNameWithDesignationWithDashClass() + "");//, 219 220 } 221 } 222 223 @Override 224 public String resolveDropParamsToSpecificItemData(String params, Random random) throws JSONException { 225 if (params == null || params.isEmpty()) return null; 226 227 if (!params.startsWith("{")) { 228 return params; 229 } 230 231 JSONObject json = new JSONObject(params); 232 233 Set<String> tags = new HashSet<String>(); 234 if (json.has("tags")) { 235 JSONArray tagsArray = json.getJSONArray("tags"); 236 for (int i = 0; i < tagsArray.length(); i++) { 237 tags.add(tagsArray.getString(i)); 238 } 239 } 240 241 return pickShip(tags, random); 242 } 243 244 245 public static String pickShip(Set<String> tags, Random random) { 246 List<ShipHullSpecAPI> specs = Global.getSettings().getAllShipHullSpecs(); 247 248 Iterator<ShipHullSpecAPI> iter = specs.iterator(); 249// while (iter.hasNext()) { 250// ShipHullSpecAPI curr = iter.next(); 251// if (curr.getHints().contains(ShipTypeHints.UNBOARDABLE) { 252// iter.remove(); 253// } 254// } 255 256// if (tier >= 0) { 257// iter = specs.iterator(); 258// while (iter.hasNext()) { 259// ShipHullSpecAPI curr = iter.next(); 260// if (curr.getTier() != tier) iter.remove(); 261// } 262// } 263 264 if (!tags.isEmpty()) { 265 iter = specs.iterator(); 266 while (iter.hasNext()) { 267 ShipHullSpecAPI curr = iter.next(); 268 for (String tag : tags) { 269 boolean not = tag.startsWith("!"); 270 tag = not ? tag.substring(1) : tag; 271 boolean has = curr.hasTag(tag); 272 if (not == has) { 273 iter.remove(); 274 break; 275 } 276 } 277 } 278 } 279 280 WeightedRandomPicker<ShipHullSpecAPI> picker = new WeightedRandomPicker<ShipHullSpecAPI>(random); 281 for (ShipHullSpecAPI spec : specs) { 282 picker.add(spec, 1f * spec.getRarity()); 283 } 284 ShipHullSpecAPI pick = picker.pick(); 285 if (pick == null) { 286 return null; 287 } else { 288 return pick.getHullId(); 289 } 290 } 291 292} 293 294 295 296 297