001package com.fs.starfarer.api.campaign.econ; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.LinkedHashMap; 006import java.util.LinkedList; 007import java.util.List; 008 009import com.fs.starfarer.api.Global; 010import com.fs.starfarer.api.campaign.CargoAPI; 011import com.fs.starfarer.api.campaign.SectorEntityToken; 012import com.fs.starfarer.api.impl.campaign.MonthlyReportNodeTooltipCreator; 013import com.fs.starfarer.api.impl.campaign.ids.Factions; 014import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator; 015 016public class MonthlyReport { 017 018 public static String CREW = "node_id_crew"; 019 public static String MARINES = "node_id_marines"; 020 public static String FLEET = "node_id_fleet"; 021 public static String OUTPOSTS = "node_id_outposts"; 022 public static String PRODUCTION = "node_id_prod"; 023 public static String PRODUCTION_WEAPONS = "node_id_prod_weapons"; 024 //public static String SURPLUS = "node_id_surplus"; 025 public static String OVERHEAD = "node_id_overhead"; 026 public static String STOCKPILING = "node_id_stockpiling"; 027 public static String RESTOCKING = "node_id_restocking"; 028 029 public static String INCENTIVES = "node_id_incentives"; 030 public static String INDUSTRIES = "node_id_industries"; 031 public static String EXPORTS = "node_id_exports"; 032 public static String STORAGE = "node_id_storage"; 033 public static String ADMIN = "node_id_admin"; 034 public static String STORAGE_CARGO = "node_id_storage_cargo"; 035 public static String STORAGE_SHIPS = "node_id_storage_ships"; 036 037 public static String LAST_MONTH_DEBT = "node_id_last_month_debt"; 038 //public static String IMPORTS = "node_id_imports"; 039 040 public static String OFFICERS = "node_id_officers"; 041 042 /** 043 * Financial data node for a monthly income/expenses report. 044 * 045 * <ul> 046 * <li>Represent a node in the monthly report panel.</li> 047 * <li>Example: com.fs.starfarer.api.impl.campaign.tutorial.GalatianAcademyStipend</li> 048 * <li>Example: com.fs.starfarer.api.impl.campaign.CoreScript.reportEconomyTick(int)</li> 049 * </ul> 050 * 051 * <p>Adding custom node to monthly report under storage section</p> 052 * <pre> 053 * <code> 054 * MonthlyReport report = SharedData.getData().getCurrentReport(); 055 * MonthlyReport.FDNode storageNode = report.getNode(MonthlyReport.STORAGE); 056 * //Check if the storageNode has been initialized in order to not override the node. 057 * if(storageNode.name == null) { 058 * storageNode.name = "Storage"; 059 * storageNode.custom = MonthlyReport.STORAGE; 060 * storageNode.tooltipCreator = report.getMonthlyReportTooltip(); 061 * } 062 * //Add in the custom node by getting the storageNode and create a new node from it 063 * MonthlyReport.FDNode anotherNode = report.getNode(storageNode, "A unique ID"); 064 * anotherNode.name = "Another node inside storage node"; 065 * </code> 066 * </pre> 067 * @author Alex Mosolov 068 * 069 * Copyright 2017 Fractal Softworks, LLC 070 * 071 */ 072 public static class FDNode { 073 protected LinkedHashMap<String, FDNode> children; 074 public FDNode parent; 075 //public String sortString; 076 public String name; 077 public String icon; 078 079 public float income; 080 public float upkeep; 081 public float totalIncome; 082 public float totalUpkeep; 083 084 public Object custom; 085 public Object custom2; 086 public SectorEntityToken mapEntity; 087 088 public TooltipCreator tooltipCreator = null; 089 public Object tooltipParam; 090 091 public LinkedHashMap<String, FDNode> getChildren() { 092 if (children == null) return new LinkedHashMap<String, FDNode>(); 093 return children; 094 } 095 096 public int getDepth() { 097 FDNode curr = this; 098 int count = 0; 099 while (curr.parent != null) { 100 curr = curr.parent; 101 count++; 102 } 103 return count; 104 } 105 } 106 107 private FDNode root = new FDNode(); 108 private long timestamp; 109 private int debt = 0; 110 private int previousDebt = 0; 111 112 private MonthlyReportNodeTooltipCreator monthlyReportTooltip; 113 public MonthlyReportNodeTooltipCreator getMonthlyReportTooltip() { 114 if (monthlyReportTooltip == null) { 115 monthlyReportTooltip = new MonthlyReportNodeTooltipCreator(); 116 } 117 return monthlyReportTooltip; 118 } 119 120 public void computeTotals() { 121 computeTotals(root); 122 } 123 124 public long getTimestamp() { 125 return timestamp; 126 } 127 128 public void setTimestamp(long timestamp) { 129 this.timestamp = timestamp; 130 } 131 132 public int getPreviousDebt() { 133 return previousDebt; 134 } 135 136 public void setPreviousDebt(int previousDebt) { 137 this.previousDebt = previousDebt; 138 } 139 140 public int getDebt() { 141 return debt; 142 } 143 144 public void setDebt(int debt) { 145 this.debt = debt; 146 } 147 148 public FDNode getRoot() { 149 return root; 150 } 151 152 protected void computeTotals(FDNode curr) { 153 curr.totalIncome = curr.income; 154 curr.totalUpkeep = curr.upkeep; 155 156 for (FDNode child : curr.getChildren().values()) { 157 computeTotals(child); 158 } 159 160 if (curr.parent != null) { 161 curr.parent.totalIncome += curr.totalIncome; 162 curr.parent.totalUpkeep += curr.totalUpkeep; 163 } 164 } 165 166 public List<FDNode> getAllNodes() { 167 List<FDNode> all = new ArrayList<FDNode>(); 168 getAllNodes(root, all); 169 return all; 170 } 171 172 protected void getAllNodes(FDNode curr, List<FDNode> nodes) { 173 nodes.add(curr); 174 175 for (FDNode child : curr.getChildren().values()) { 176 getAllNodes(child, nodes); 177 } 178 } 179 180 public FDNode getNode(String ... path) { 181 return getNode(root, new LinkedList<String>(Arrays.asList(path))); 182 } 183 184 public FDNode getNode(FDNode from, String ... path) { 185 return getNode(from, new LinkedList<String>(Arrays.asList(path))); 186 } 187 public FDNode getNode(FDNode from, List<String> path) { 188 if (path.isEmpty()) return from; 189 190 String nextId = path.remove(0); 191 FDNode next = from.children == null ? null : from.children.get(nextId); 192 if (next == null) { 193 if (from.children == null) { 194 from.children = new LinkedHashMap<String, FDNode>(); 195 } 196 next = new FDNode(); 197 next.parent = from; 198 from.children.put(nextId, next); 199 } 200 return getNode(next, path); 201 } 202 203 204 public FDNode getColoniesNode() { 205 FDNode marketsNode = getNode(MonthlyReport.OUTPOSTS); 206 if (marketsNode.name == null) { 207 marketsNode.name = "Colonies"; 208 marketsNode.custom = MonthlyReport.OUTPOSTS; 209 marketsNode.tooltipCreator = getMonthlyReportTooltip(); 210 } 211 return marketsNode; 212 } 213 214 public FDNode getMarketNode(MarketAPI market) { 215 FDNode marketsNode = getColoniesNode(); 216 217 FDNode mNode = getNode(marketsNode, market.getId()); 218 if (mNode.name == null) { 219 mNode.name = market.getName() + " (" + market.getSize() + ")"; 220 mNode.custom = market; 221 } 222 return mNode; 223 } 224 225 public FDNode getCounterShortageNode(MarketAPI market) { 226 FDNode mNode = getMarketNode(market); 227 228 FDNode sNode = getNode(mNode, MonthlyReport.STOCKPILING); 229 if (sNode.name == null) { 230 sNode.name = "Stockpiles used to counter shortages"; 231 sNode.custom = MonthlyReport.STOCKPILING; 232 sNode.custom2 = Global.getFactory().createCargo(true); 233 ((CargoAPI)sNode.custom2).initMothballedShips(Factions.PLAYER); 234 sNode.tooltipCreator = getMonthlyReportTooltip(); 235 } 236 return sNode; 237 } 238 239 public FDNode getRestockingNode(MarketAPI market) { 240 //FDNode mNode = getMarketNode(market); 241 242 FDNode mNode = getColoniesNode(); 243 244 FDNode sNode = getNode(mNode, MonthlyReport.RESTOCKING); 245 if (sNode.name == null) { 246 sNode.name = "Stockpiles drawn by your fleet"; 247 sNode.custom = MonthlyReport.RESTOCKING; 248 sNode.custom2 = Global.getFactory().createCargo(true); 249 ((CargoAPI)sNode.custom2).initMothballedShips(Factions.PLAYER); 250 sNode.tooltipCreator = getMonthlyReportTooltip(); 251 } 252 return sNode; 253 } 254 255 public FDNode getDebtNode() { 256 FDNode debtNode = getNode(MonthlyReport.LAST_MONTH_DEBT); 257 if (debtNode.name == null) { 258 debtNode.name = "Last month's debt"; 259 debtNode.custom = MonthlyReport.LAST_MONTH_DEBT; 260 debtNode.icon = Global.getSettings().getSpriteName("income_report", "generic_expense"); 261 debtNode.tooltipCreator = getMonthlyReportTooltip(); 262 } 263 return debtNode; 264 } 265 266 public static void main(String[] args) { 267 MonthlyReport data = new MonthlyReport(); 268 269 data.getNode("test", "test1", "test2").income = 10; 270 271 System.out.println(data); 272 } 273} 274 275 276 277 278