1+ package com .etheller .warsmash .parsers .w3x .objectdata ;
2+
3+ import java .io .IOException ;
4+ import java .util .ArrayList ;
5+ import java .util .HashMap ;
6+ import java .util .Iterator ;
7+ import java .util .List ;
8+ import java .util .Map ;
9+ import java .util .Map .Entry ;
10+
11+ import com .etheller .warsmash .datasources .DataSource ;
12+ import com .etheller .warsmash .units .DataTable ;
13+ import com .etheller .warsmash .units .ObjectData ;
14+ import com .etheller .warsmash .units .StandardObjectData ;
15+ import com .etheller .warsmash .units .StandardObjectData .WarcraftData ;
16+ import com .etheller .warsmash .units .collapsed .CollapsedObjectData ;
17+ import com .etheller .warsmash .units .custom .ObjectDataChangeEntry ;
18+ import com .etheller .warsmash .units .custom .WTS ;
19+ import com .etheller .warsmash .units .custom .WTSFile ;
20+ import com .etheller .warsmash .units .custom .War3ObjectDataChangeset ;
21+ import com .etheller .warsmash .units .manager .MutableObjectData .WorldEditorDataType ;
22+ import com .etheller .warsmash .util .War3ID ;
23+ import com .etheller .warsmash .util .WorldEditStrings ;
24+ import com .google .common .io .LittleEndianDataInputStream ;
25+
26+ public final class Warcraft3MapRuntimeObjectData {
27+ private final ObjectData units ;
28+ private final ObjectData items ;
29+ private final ObjectData destructibles ;
30+ private final ObjectData doodads ;
31+ private final ObjectData abilities ;
32+ private final ObjectData buffs ;
33+ private final ObjectData upgrades ;
34+ private final DataTable standardUpgradeEffectMeta ;
35+ private final List <ObjectData > datas ;
36+ private transient Map <WorldEditorDataType , ObjectData > typeToData = new HashMap <>();
37+ private final WTS wts ;
38+
39+ public Warcraft3MapRuntimeObjectData (final ObjectData units , final ObjectData items , final ObjectData destructibles ,
40+ final ObjectData doodads , final ObjectData abilities , final ObjectData buffs , final ObjectData upgrades ,
41+ final DataTable standardUpgradeEffectMeta , final WTS wts ) {
42+ this .units = units ;
43+ this .items = items ;
44+ this .destructibles = destructibles ;
45+ this .doodads = doodads ;
46+ this .abilities = abilities ;
47+ this .buffs = buffs ;
48+ this .upgrades = upgrades ;
49+ this .standardUpgradeEffectMeta = standardUpgradeEffectMeta ;
50+ this .datas = new ArrayList <>();
51+ this .datas .add (units );
52+ this .typeToData .put (WorldEditorDataType .UNITS , units );
53+ this .datas .add (items );
54+ this .typeToData .put (WorldEditorDataType .ITEM , items );
55+ this .datas .add (destructibles );
56+ this .typeToData .put (WorldEditorDataType .DESTRUCTIBLES , destructibles );
57+ this .datas .add (doodads );
58+ this .typeToData .put (WorldEditorDataType .DOODADS , doodads );
59+ this .datas .add (abilities );
60+ this .typeToData .put (WorldEditorDataType .ABILITIES , abilities );
61+ this .datas .add (buffs );
62+ this .typeToData .put (WorldEditorDataType .BUFFS_EFFECTS , buffs );
63+ this .datas .add (upgrades );
64+ this .typeToData .put (WorldEditorDataType .UPGRADES , upgrades );
65+ for (final ObjectData data : this .datas ) {
66+ }
67+ this .wts = wts ;
68+ }
69+
70+ public ObjectData getDataByType (final WorldEditorDataType type ) {
71+ return this .typeToData .get (type );
72+ }
73+
74+ public ObjectData getUnits () {
75+ return this .units ;
76+ }
77+
78+ public ObjectData getItems () {
79+ return this .items ;
80+ }
81+
82+ public ObjectData getDestructibles () {
83+ return this .destructibles ;
84+ }
85+
86+ public ObjectData getDoodads () {
87+ return this .doodads ;
88+ }
89+
90+ public ObjectData getAbilities () {
91+ return this .abilities ;
92+ }
93+
94+ public ObjectData getBuffs () {
95+ return this .buffs ;
96+ }
97+
98+ public ObjectData getUpgrades () {
99+ return this .upgrades ;
100+ }
101+
102+ public DataTable getStandardUpgradeEffectMeta () {
103+ return this .standardUpgradeEffectMeta ;
104+ }
105+
106+ public List <ObjectData > getDatas () {
107+ return this .datas ;
108+ }
109+
110+ public WTS getWts () {
111+ return this .wts ;
112+ }
113+
114+ private static WTS loadWTS (final DataSource dataSource , final String name ) throws IOException {
115+ final WTS wts = dataSource .has (name ) ? new WTSFile (dataSource .getResourceAsStream (name )) : WTS .DO_NOTHING ;
116+ return wts ;
117+ }
118+
119+ public static WTS loadWTS (final DataSource dataSource ) throws IOException {
120+ return loadWTS (dataSource , "war3map.wts" );
121+ }
122+
123+ public static WTS loadCampaignWTS (final DataSource dataSource ) throws IOException {
124+ return loadWTS (dataSource , "war3campaign.wts" );
125+ }
126+
127+ public static Warcraft3MapRuntimeObjectData load (final DataSource dataSource , final boolean inlineWTS )
128+ throws IOException {
129+ final WTS wts = loadWTS (dataSource );
130+ return load (dataSource , inlineWTS , wts );
131+ }
132+
133+ public static Warcraft3MapRuntimeObjectData load (final DataSource dataSource , final boolean inlineWTS ,
134+ final WTS wts ) throws IOException {
135+ final WTS campaignWTS = loadCampaignWTS (dataSource );
136+ return load (dataSource , inlineWTS , wts , campaignWTS );
137+ }
138+
139+ public static Warcraft3MapRuntimeObjectData load (final DataSource dataSource , final boolean inlineWTS ,
140+ final WTS wts , final WTS campaignWTS ) throws IOException {
141+
142+ final StandardObjectData standardObjectData = new StandardObjectData (dataSource );
143+ final WarcraftData standardUnits = standardObjectData .getStandardUnits ();
144+ final WarcraftData standardItems = standardObjectData .getStandardItems ();
145+ final WarcraftData standardDoodads = standardObjectData .getStandardDoodads ();
146+ final WarcraftData standardDestructables = standardObjectData .getStandardDestructables ();
147+ final WarcraftData abilities = standardObjectData .getStandardAbilities ();
148+ final WarcraftData standardAbilityBuffs = standardObjectData .getStandardAbilityBuffs ();
149+ final WarcraftData standardUpgrades = standardObjectData .getStandardUpgrades ();
150+
151+ final DataTable standardUnitMeta = standardObjectData .getStandardUnitMeta ();
152+ final DataTable standardDoodadMeta = standardObjectData .getStandardDoodadMeta ();
153+ final DataTable standardDestructableMeta = standardObjectData .getStandardDestructableMeta ();
154+ final DataTable abilityMeta = standardObjectData .getStandardAbilityMeta ();
155+ final DataTable standardAbilityBuffMeta = standardObjectData .getStandardAbilityBuffMeta ();
156+ final DataTable standardUpgradeMeta = standardObjectData .getStandardUpgradeMeta ();
157+ final DataTable standardUpgradeEffectMeta = standardObjectData .getStandardUpgradeEffectMeta ();
158+
159+ final War3ObjectDataChangeset unitChangeset = new War3ObjectDataChangeset ('u' );
160+ final War3ObjectDataChangeset itemChangeset = new War3ObjectDataChangeset ('t' );
161+ final War3ObjectDataChangeset doodadChangeset = new War3ObjectDataChangeset ('d' );
162+ final War3ObjectDataChangeset destructableChangeset = new War3ObjectDataChangeset ('b' );
163+ final War3ObjectDataChangeset abilityChangeset = new War3ObjectDataChangeset ('a' );
164+ final War3ObjectDataChangeset buffChangeset = new War3ObjectDataChangeset ('h' );
165+ final War3ObjectDataChangeset upgradeChangeset = new War3ObjectDataChangeset ('q' );
166+
167+ if (dataSource .has ("war3map.w3u" )) {
168+ unitChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3u" )), wts ,
169+ inlineWTS );
170+ // push unit changes to items.... as a Reign of Chaos support...
171+ Iterator <Entry <War3ID , ObjectDataChangeEntry >> entryIterator = unitChangeset .getOriginal ().iterator ();
172+ while (entryIterator .hasNext ()) {
173+ final Entry <War3ID , ObjectDataChangeEntry > entry = entryIterator .next ();
174+ final String rawcodeString = entry .toString ();
175+ final String oldIdString = entry .getValue ().getOldId ().toString ();
176+ if ((standardUnits .get (oldIdString ) == null ) && (standardItems .get (oldIdString ) != null )) {
177+ itemChangeset .getOriginal ().put (entry .getKey (), entry .getValue ());
178+ entryIterator .remove ();
179+ }
180+ }
181+ entryIterator = unitChangeset .getCustom ().iterator ();
182+ while (entryIterator .hasNext ()) {
183+ final Entry <War3ID , ObjectDataChangeEntry > entry = entryIterator .next ();
184+ final String rawcodeString = entry .toString ();
185+ final String oldIdString = entry .getValue ().getOldId ().toString ();
186+ if ((standardUnits .get (oldIdString ) == null ) && (standardItems .get (oldIdString ) != null )) {
187+ itemChangeset .getCustom ().put (entry .getKey (), entry .getValue ());
188+ entryIterator .remove ();
189+ }
190+ }
191+ }
192+ if (dataSource .has ("war3mapSkin.w3u" )) {
193+ unitChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3u" )), wts ,
194+ inlineWTS );
195+ }
196+ if (dataSource .has ("war3campaign.w3u" )) {
197+ unitChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3u" )),
198+ campaignWTS , inlineWTS );
199+ }
200+ // ================== REMOVE LATER =====================
201+ if (dataSource .has ("war3mod.w3u" )) {
202+ unitChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mod.w3u" )), wts ,
203+ inlineWTS );
204+ }
205+ // =====================================================
206+ if (dataSource .has ("war3map.w3t" )) {
207+ itemChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3t" )), wts ,
208+ inlineWTS );
209+ }
210+ if (dataSource .has ("war3mapSkin.w3t" )) {
211+ itemChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3t" )), wts ,
212+ inlineWTS );
213+ }
214+ if (dataSource .has ("war3campaign.w3t" )) {
215+ itemChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3t" )),
216+ campaignWTS , inlineWTS );
217+ }
218+ if (dataSource .has ("war3map.w3d" )) {
219+ doodadChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3d" )), wts ,
220+ inlineWTS );
221+ }
222+ if (dataSource .has ("war3campaign.w3d" )) {
223+ doodadChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3d" )),
224+ campaignWTS , inlineWTS );
225+ }
226+ if (dataSource .has ("war3map.w3b" )) {
227+ destructableChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3b" )),
228+ wts , inlineWTS );
229+ }
230+ if (dataSource .has ("war3mapSkin.w3b" )) {
231+ destructableChangeset .load (
232+ new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3b" )), wts , inlineWTS );
233+ }
234+ if (dataSource .has ("war3campaign.w3b" )) {
235+ destructableChangeset .load (
236+ new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3b" )), campaignWTS ,
237+ inlineWTS );
238+ }
239+ if (dataSource .has ("war3map.w3a" )) {
240+ abilityChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3a" )), wts ,
241+ inlineWTS );
242+ }
243+ if (dataSource .has ("war3mapSkin.w3a" )) {
244+ abilityChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3a" )),
245+ wts , inlineWTS );
246+ }
247+ if (dataSource .has ("war3campaign.w3a" )) {
248+ abilityChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3a" )),
249+ campaignWTS , inlineWTS );
250+ }
251+ if (dataSource .has ("war3map.w3h" )) {
252+ buffChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3h" )), wts ,
253+ inlineWTS );
254+ }
255+ if (dataSource .has ("war3mapSkin.w3h" )) {
256+ buffChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3h" )), wts ,
257+ inlineWTS );
258+ }
259+ if (dataSource .has ("war3campaign.w3h" )) {
260+ buffChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3h" )),
261+ campaignWTS , inlineWTS );
262+ }
263+ if (dataSource .has ("war3map.w3q" )) {
264+ upgradeChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3map.w3q" )), wts ,
265+ inlineWTS );
266+ }
267+ if (dataSource .has ("war3mapSkin.w3q" )) {
268+ upgradeChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3mapSkin.w3q" )),
269+ wts , inlineWTS );
270+ }
271+ if (dataSource .has ("war3campaign.w3q" )) {
272+ upgradeChangeset .load (new LittleEndianDataInputStream (dataSource .getResourceAsStream ("war3campaign.w3q" )),
273+ campaignWTS , inlineWTS );
274+ }
275+
276+ final WorldEditStrings worldEditStrings = standardObjectData .getWorldEditStrings ();
277+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .UNITS , standardUnits , standardUnitMeta ,
278+ unitChangeset );
279+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .ITEM , standardItems , standardUnitMeta ,
280+ itemChangeset );
281+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .DOODADS , standardDoodads , standardDoodadMeta ,
282+ doodadChangeset );
283+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .DESTRUCTIBLES , standardDestructables ,
284+ standardDestructableMeta , destructableChangeset );
285+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .ABILITIES , abilities , abilityMeta ,
286+ abilityChangeset );
287+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .BUFFS_EFFECTS , standardAbilityBuffs ,
288+ standardAbilityBuffMeta , buffChangeset );
289+ CollapsedObjectData .apply (worldEditStrings , WorldEditorDataType .UPGRADES , standardUpgrades , standardUpgradeMeta ,
290+ upgradeChangeset );
291+
292+ return new Warcraft3MapRuntimeObjectData (standardUnits , standardItems , standardDestructables , standardDoodads ,
293+ abilities , standardAbilityBuffs , standardUpgrades , standardUpgradeEffectMeta , wts );
294+ }
295+ }
0 commit comments