001package com.fs.starfarer.api.campaign.impl.items; 002 003import java.awt.Color; 004import java.util.ArrayList; 005import java.util.HashSet; 006import java.util.Iterator; 007import java.util.List; 008import java.util.Random; 009import java.util.Set; 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.WeaponAPI.AIHints; 021import com.fs.starfarer.api.graphics.SpriteAPI; 022import com.fs.starfarer.api.loading.Description; 023import com.fs.starfarer.api.loading.Description.Type; 024import com.fs.starfarer.api.loading.WeaponSpecAPI; 025import com.fs.starfarer.api.ui.TooltipMakerAPI; 026import com.fs.starfarer.api.util.Misc; 027import com.fs.starfarer.api.util.WeightedRandomPicker; 028 029public class WeaponBlueprintItemPlugin extends BaseSpecialItemPlugin implements BlueprintProviderItem { 030 031 protected WeaponSpecAPI weapon; 032 033 @Override 034 public void init(CargoStackAPI stack) { 035 super.init(stack); 036 weapon = Global.getSettings().getWeaponSpec(stack.getSpecialDataIfSpecial().getData()); 037 } 038 039 040 public List<String> getProvidedFighters() { 041 return null; 042 } 043 044 public List<String> getProvidedShips() { 045 return null; 046 } 047 048 public List<String> getProvidedWeapons() { 049 List<String> result = new ArrayList<String>(); 050 result.add(weapon.getWeaponId()); 051 return result; 052 } 053 public List<String> getProvidedIndustries() { 054 return null; 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 - 31f; 064 float blY = cy - 16f; 065 float tlX = cx - 22f; 066 float tlY = cy + 27f; 067 float trX = cx + 23f; 068 float trY = cy + 27f; 069 float brX = cx + 15f; 070 float brY = cy - 19f; 071 072 String weaponId = stack.getSpecialDataIfSpecial().getData(); 073 boolean known = Global.getSector().getPlayerFaction().knowsWeapon(weaponId); 074 075 float mult = 1f; 076 077 Color bgColor = Global.getSector().getPlayerFaction().getDarkUIColor(); 078// if (weapon.getType() == WeaponType.BALLISTIC) { 079// bgColor = Misc.getBallisticMountColor(); 080// } else if (weapon.getType() == WeaponType.ENERGY) { 081// bgColor = Misc.getEnergyMountColor(); 082// } else if (weapon.getType() == WeaponType.MISSILE) { 083// bgColor = Misc.getMissileMountColor(); 084// } 085 //bgColor = new Color(200,0,0); 086 087 bgColor = Misc.setAlpha(bgColor, 255); 088 renderer.renderBGWithCorners(bgColor, blX, blY, tlX, tlY, trX, trY, brX, brY, 089 alphaMult * mult, glowMult * 0.5f * mult, false); 090 //weaponId = "hurricane"; 091 //weaponId = "plasma"; 092 //weaponId = "amblaster"; 093 renderer.renderWeaponWithCorners(weaponId, blX, blY, tlX, tlY, trX, trY, brX, brY, 094 alphaMult * mult, glowMult * 0.5f * mult, !known); 095 096 SpriteAPI overlay = Global.getSettings().getSprite("ui", "bpOverlayWeapon"); 097 overlay.setColor(Color.green); 098 overlay.setColor(Global.getSector().getPlayerFaction().getBrightUIColor()); 099 overlay.setAlphaMult(alphaMult); 100 overlay.setNormalBlend(); 101 renderer.renderScanlinesWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY, alphaMult, false); 102 103 if (known) { 104 renderer.renderBGWithCorners(Color.black, blX, blY, tlX, tlY, trX, trY, brX, brY, 105 alphaMult * 0.5f, 0f, false); 106 } 107 108 //renderer.renderScanlinesWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY, alphaMult, false); 109 110 overlay.renderWithCorners(blX, blY, tlX, tlY, trX, trY, brX, brY); 111 } 112 113 @Override 114 public int getPrice(MarketAPI market, SubmarketAPI submarket) { 115 if (weapon != null) { 116 float base = super.getPrice(market, submarket); 117 return (int)(base + weapon.getBaseValue() * getItemPriceMult()); 118 } 119 return super.getPrice(market, submarket); 120 } 121 122 @Override 123 public String getName() { 124 if (weapon != null) { 125 return weapon.getWeaponName() + " Blueprint"; 126 } 127 return super.getName(); 128 } 129 130 @Override 131 public String getDesignType() { 132 if (weapon != null) { 133 return weapon.getManufacturer(); 134 } 135 return null; 136 } 137 138 @Override 139 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, CargoTransferHandlerAPI transferHandler, Object stackSource) { 140 super.createTooltip(tooltip, expanded, transferHandler, stackSource); 141 142 float pad = 3f; 143 float opad = 10f; 144 float small = 5f; 145 Color h = Misc.getHighlightColor(); 146 Color g = Misc.getGrayColor(); 147 Color b = Misc.getButtonTextColor(); 148 b = Misc.getPositiveHighlightColor(); 149 150 String weaponId = stack.getSpecialDataIfSpecial().getData(); 151 boolean known = Global.getSector().getPlayerFaction().knowsWeapon(weaponId); 152 153 List<String> weapons = new ArrayList<String>(); 154 weapons.add(weaponId); 155 addWeaponList(tooltip, "Weapons:", weapons, 1, opad); 156 157 Description desc = Global.getSettings().getDescription(weapon.getWeaponId(), Type.WEAPON); 158 tooltip.addPara(desc.getText1FirstPara(), opad); 159 160 addCostLabel(tooltip, opad, transferHandler, stackSource); 161 162 if (known) { 163 tooltip.addPara("Already known", g, opad); 164 } else { 165 tooltip.addPara("Right-click to learn", b, opad); 166 } 167 } 168 169 @Override 170 public boolean hasRightClickAction() { 171 return true; 172 } 173 174 @Override 175 public boolean shouldRemoveOnRightClickAction() { 176 String weaponId = stack.getSpecialDataIfSpecial().getData(); 177 return !Global.getSector().getPlayerFaction().knowsWeapon(weaponId); 178 } 179 180 @Override 181 public void performRightClickAction() { 182 String weaponId = stack.getSpecialDataIfSpecial().getData(); 183 184 if (Global.getSector().getPlayerFaction().knowsWeapon(weaponId)) { 185 Global.getSector().getCampaignUI().getMessageDisplay().addMessage( 186 "" + weapon.getWeaponName() + ": blueprint already known");//, 187 } else { 188 Global.getSoundPlayer().playUISound("ui_acquired_blueprint", 1, 1); 189 Global.getSector().getPlayerFaction().addKnownWeapon(weaponId, true); 190 Global.getSector().getCampaignUI().getMessageDisplay().addMessage( 191 "Acquired blueprint: " + weapon.getWeaponName() + "");//, 192 193 } 194 } 195 196 @Override 197 public String resolveDropParamsToSpecificItemData(String params, Random random) throws JSONException { 198 if (params == null || params.isEmpty()) return null; 199 200 if (!params.startsWith("{")) { 201 return params; 202 } 203 204 JSONObject json = new JSONObject(params); 205 206 int tier = json.optInt("tier", -1); 207 Set<String> tags = new HashSet<String>(); 208 if (json.has("tags")) { 209 JSONArray tagsArray = json.getJSONArray("tags"); 210 for (int i = 0; i < tagsArray.length(); i++) { 211 tags.add(tagsArray.getString(i)); 212 } 213 } 214 215 return pickWeapon(tier, tags, random); 216 } 217 218 219 protected String pickWeapon(int tier, Set<String> tags, Random random) { 220 List<WeaponSpecAPI> specs = Global.getSettings().getAllWeaponSpecs(); 221 222 Iterator<WeaponSpecAPI> iter = specs.iterator(); 223 while (iter.hasNext()) { 224 WeaponSpecAPI curr = iter.next(); 225 if (curr.getAIHints().contains(AIHints.SYSTEM)) { 226 iter.remove(); 227 } 228 } 229 230 if (tier >= 0) { 231 iter = specs.iterator(); 232 while (iter.hasNext()) { 233 WeaponSpecAPI curr = iter.next(); 234 if (curr.getTier() != tier) iter.remove(); 235 } 236 } 237 238 if (!tags.isEmpty()) { 239 iter = specs.iterator(); 240 while (iter.hasNext()) { 241 WeaponSpecAPI curr = iter.next(); 242 for (String tag : tags) { 243 boolean not = tag.startsWith("!"); 244 tag = not ? tag.substring(1) : tag; 245 boolean has = curr.hasTag(tag); 246 if (not == has) { 247 iter.remove(); 248 break; 249 } 250 } 251 } 252 } 253 254 WeightedRandomPicker<WeaponSpecAPI> picker = new WeightedRandomPicker<WeaponSpecAPI>(random); 255 for (WeaponSpecAPI spec : specs) { 256 picker.add(spec, 1f * spec.getRarity()); 257 } 258 WeaponSpecAPI pick = picker.pick(); 259 if (pick == null) { 260 return null; 261 } else { 262 return pick.getWeaponId(); 263 } 264 } 265 266} 267 268 269 270 271