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