Terraria ModLoader  0.11.7.5
A mod to make and play Terraria mods
ModInternals.cs
Go to the documentation of this file.
1 using Microsoft.Xna.Framework.Audio;
2 using Microsoft.Xna.Framework.Graphics;
3 using MP3Sharp;
4 using NVorbis;
5 using ReLogic.Graphics;
6 using ReLogic.Utilities;
7 using System;
8 using System.Collections.Generic;
9 using System.IO;
10 using System.Linq;
11 using System.Threading.Tasks;
12 using Terraria.GameContent.Liquid;
13 using Terraria.ID;
14 using Terraria.Localization;
17 using Terraria.ModLoader.IO;
18 using Terraria.ModLoader.UI;
19 using Terraria.Utilities;
20 
21 namespace Terraria.ModLoader
22 {
23  partial class Mod
24  {
25  internal bool loading;
26  private readonly Queue<Task> AsyncLoadQueue = new Queue<Task>();
27  internal readonly IDictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();
28  internal readonly IDictionary<string, SoundEffect> sounds = new Dictionary<string, SoundEffect>();
29  internal readonly IDictionary<string, Music> musics = new Dictionary<string, Music>();
30  internal readonly IDictionary<string, DynamicSpriteFont> fonts = new Dictionary<string, DynamicSpriteFont>();
31  internal readonly IDictionary<string, Effect> effects = new Dictionary<string, Effect>();
32  internal readonly IList<ModRecipe> recipes = new List<ModRecipe>();
33  internal readonly IDictionary<string, ModItem> items = new Dictionary<string, ModItem>();
34  internal readonly IDictionary<string, GlobalItem> globalItems = new Dictionary<string, GlobalItem>();
35  internal readonly IDictionary<Tuple<string, EquipType>, EquipTexture> equipTextures = new Dictionary<Tuple<string, EquipType>, EquipTexture>();
36  internal readonly IDictionary<string, ModPrefix> prefixes = new Dictionary<string, ModPrefix>();
37  internal readonly IDictionary<string, ModDust> dusts = new Dictionary<string, ModDust>();
38  internal readonly IDictionary<string, ModTile> tiles = new Dictionary<string, ModTile>();
39  internal readonly IDictionary<string, GlobalTile> globalTiles = new Dictionary<string, GlobalTile>();
40  internal readonly IDictionary<string, ModTileEntity> tileEntities = new Dictionary<string, ModTileEntity>();
41  internal readonly IDictionary<string, ModWall> walls = new Dictionary<string, ModWall>();
42  internal readonly IDictionary<string, GlobalWall> globalWalls = new Dictionary<string, GlobalWall>();
43  internal readonly IDictionary<string, ModProjectile> projectiles = new Dictionary<string, ModProjectile>();
44  internal readonly IDictionary<string, GlobalProjectile> globalProjectiles = new Dictionary<string, GlobalProjectile>();
45  internal readonly IDictionary<string, ModNPC> npcs = new Dictionary<string, ModNPC>();
46  internal readonly IDictionary<string, GlobalNPC> globalNPCs = new Dictionary<string, GlobalNPC>();
47  internal readonly IDictionary<string, ModPlayer> players = new Dictionary<string, ModPlayer>();
48  internal readonly IDictionary<string, ModMountData> mountDatas = new Dictionary<string, ModMountData>();
49  internal readonly IDictionary<string, ModBuff> buffs = new Dictionary<string, ModBuff>();
50  internal readonly IDictionary<string, GlobalBuff> globalBuffs = new Dictionary<string, GlobalBuff>();
51  internal readonly IDictionary<string, ModWorld> worlds = new Dictionary<string, ModWorld>();
52  internal readonly IDictionary<string, ModUgBgStyle> ugBgStyles = new Dictionary<string, ModUgBgStyle>();
53  internal readonly IDictionary<string, ModSurfaceBgStyle> surfaceBgStyles = new Dictionary<string, ModSurfaceBgStyle>();
54  internal readonly IDictionary<string, GlobalBgStyle> globalBgStyles = new Dictionary<string, GlobalBgStyle>();
55  internal readonly IDictionary<string, ModWaterStyle> waterStyles = new Dictionary<string, ModWaterStyle>();
56  internal readonly IDictionary<string, ModWaterfallStyle> waterfallStyles = new Dictionary<string, ModWaterfallStyle>();
57  internal readonly IDictionary<string, GlobalRecipe> globalRecipes = new Dictionary<string, GlobalRecipe>();
58  internal readonly IDictionary<string, ModTranslation> translations = new Dictionary<string, ModTranslation>();
59 
60  private void LoadTexture(string path, Stream stream, bool rawimg) {
61  try {
62  var texTask = rawimg
63  ? ImageIO.RawToTexture2DAsync(Main.instance.GraphicsDevice, new BinaryReader(stream))
64  : ImageIO.PngToTexture2DAsync(Main.instance.GraphicsDevice, stream);
65 
66  AsyncLoadQueue.Enqueue(texTask.ContinueWith(t => {
67  if (t.Exception != null)
68  throw new ResourceLoadException(
69  Language.GetTextValue("tModLoader.LoadErrorTextureFailedToLoad", path), t.Exception);
70 
71  var tex = t.Result;
72  tex.Name = Name + "/" + path;
73  lock (textures)
74  textures[path] = tex;
75  }));
76  }
77  catch (Exception e) {
78  throw new ResourceLoadException(Language.GetTextValue("tModLoader.LoadErrorTextureFailedToLoad", path), e);
79  }
80  finally {
81  stream.Close();
82  }
83  }
84 
85  private SoundEffect LoadSound(Stream stream, int length, string extension) {
86  switch (extension) {
87  case ".wav":
88  if (!stream.CanSeek)
89  stream = new MemoryStream(stream.ReadBytes(length));
90  return SoundEffect.FromStream(stream);
91  case ".mp3":
92  using (var mp3Stream = new MP3Stream(stream))
93  using (var ms = new MemoryStream()) {
94  mp3Stream.CopyTo(ms);
95  return new SoundEffect(ms.ToArray(), mp3Stream.Frequency, (AudioChannels)mp3Stream.ChannelCount);
96  }
97  case ".ogg":
98  using (var reader = new VorbisReader(stream, true)) {
99  var buffer = new byte[reader.TotalSamples * 2 * reader.Channels];
100  var floatBuf = new float[buffer.Length / 2];
101  reader.ReadSamples(floatBuf, 0, floatBuf.Length);
102  MusicStreamingOGG.Convert(floatBuf, buffer);
103  return new SoundEffect(buffer, reader.SampleRate, (AudioChannels)reader.Channels);
104  }
105  }
106  throw new ResourceLoadException("Unknown sound extension "+extension);
107  }
108 
109  private Music LoadMusic(string path, string extension) {
110  path = "tmod:"+Name+'/'+path+extension;
111  switch (extension) {
112  case ".wav": return new MusicStreamingWAV(path);
113  case ".mp3": return new MusicStreamingMP3(path);
114  case ".ogg": return new MusicStreamingOGG(path);
115  }
116  throw new ResourceLoadException("Unknown music extension "+extension);
117  }
118 
119  internal void SetupContent() {
120  foreach (ModItem item in items.Values) {
121  ItemLoader.SetDefaults(item.item, false);
122  item.AutoStaticDefaults();
123  item.SetStaticDefaults();
124  }
125  foreach (ModPrefix prefix in prefixes.Values) {
126  prefix.AutoDefaults();
127  prefix.SetDefaults();
128  }
129  foreach (ModDust dust in dusts.Values) {
130  dust.SetDefaults();
131  }
132  foreach (ModTile tile in tiles.Values) {
133  Main.tileTexture[tile.Type] = ModContent.GetTexture(tile.texture);
134  TileLoader.SetDefaults(tile);
135  if (TileID.Sets.HasOutlines[tile.Type]) {
136  Main.highlightMaskTexture[tile.Type] = ModContent.GetTexture(tile.HighlightTexture);
137  }
138  if (!string.IsNullOrEmpty(tile.chest)) {
139  TileID.Sets.BasicChest[tile.Type] = true;
140  }
141  }
142  foreach (GlobalTile globalTile in globalTiles.Values) {
143  globalTile.SetDefaults();
144  }
145  foreach (ModWall wall in walls.Values) {
146  Main.wallTexture[wall.Type] = ModContent.GetTexture(wall.texture);
147  wall.SetDefaults();
148  }
149  foreach (GlobalWall globalWall in globalWalls.Values) {
150  globalWall.SetDefaults();
151  }
152  foreach (ModProjectile projectile in projectiles.Values) {
153  ProjectileLoader.SetDefaults(projectile.projectile, false);
154  projectile.AutoStaticDefaults();
155  projectile.SetStaticDefaults();
156  }
157  foreach (ModNPC npc in npcs.Values) {
158  NPCLoader.SetDefaults(npc.npc, false);
159  npc.AutoStaticDefaults();
160  npc.SetStaticDefaults();
161  }
162  foreach (ModMountData modMountData in mountDatas.Values) {
163  var mountData = modMountData.mountData;
164  mountData.modMountData = modMountData;
165  MountLoader.SetupMount(mountData);
166  Mount.mounts[modMountData.Type] = mountData;
167  }
168  foreach (ModBuff buff in buffs.Values) {
169  Main.buffTexture[buff.Type] = ModContent.GetTexture(buff.texture);
170  buff.SetDefaults();
171  }
172  foreach (ModWaterStyle waterStyle in waterStyles.Values) {
173  LiquidRenderer.Instance._liquidTextures[waterStyle.Type] = ModContent.GetTexture(waterStyle.texture);
174  Main.liquidTexture[waterStyle.Type] = ModContent.GetTexture(waterStyle.blockTexture);
175  }
176  foreach (ModWaterfallStyle waterfallStyle in waterfallStyles.Values) {
177  Main.instance.waterfallManager.waterfallTexture[waterfallStyle.Type]
178  = ModContent.GetTexture(waterfallStyle.texture);
179  }
180  }
181 
182  internal void UnloadContent() {
183  Unload();
184  recipes.Clear();
185  items.Clear();
186  globalItems.Clear();
187  equipTextures.Clear();
188  prefixes.Clear();
189  dusts.Clear();
190  tiles.Clear();
191  globalTiles.Clear();
192  tileEntities.Clear();
193  walls.Clear();
194  globalWalls.Clear();
195  players.Clear();
196  projectiles.Clear();
197  globalProjectiles.Clear();
198  npcs.Clear();
199  globalNPCs.Clear();
200  buffs.Clear();
201  globalBuffs.Clear();
202  mountDatas.Clear();
203  worlds.Clear();
204  ugBgStyles.Clear();
205  surfaceBgStyles.Clear();
206  globalBgStyles.Clear();
207  waterStyles.Clear();
208  waterfallStyles.Clear();
209  globalRecipes.Clear();
210  translations.Clear();
211  if (!Main.dedServ) {
212  // Manually Dispose IDisposables to free up unmanaged memory immediately
213  /* Skip this for now, too many mods don't unload properly and run into exceptions.
214  foreach (var sound in sounds)
215  {
216  sound.Value.Dispose();
217  }
218  foreach (var effect in effects)
219  {
220  effect.Value.Dispose();
221  }
222  foreach (var texture in textures)
223  {
224  texture.Value.Dispose();
225  }
226  */
227  }
228  sounds.Clear();
229  effects.Clear();
230  foreach (var tex in textures.Values)
231  tex?.Dispose();
232  textures.Clear();
233  musics.Clear();
234  fonts.Clear();
235  }
236 
237  internal void Autoload() {
238  if (Code == null)
239  return;
240 
241  Interface.loadMods.SubProgressText = Language.GetTextValue("tModLoader.MSFinishingResourceLoading");
242  while (AsyncLoadQueue.Count > 0)
243  AsyncLoadQueue.Dequeue().Wait();
244 
245  AutoloadLocalization();
246  IList<Type> modGores = new List<Type>();
247  IList<Type> modSounds = new List<Type>();
248  foreach (Type type in Code.GetTypes().OrderBy(type => type.FullName, StringComparer.InvariantCulture)) {
249  if (type.IsAbstract || type.GetConstructor(new Type[0]) == null)//don't autoload things with no default constructor
250  {
251  continue;
252  }
253  if (type.IsSubclassOf(typeof(ModItem))) {
254  AutoloadItem(type);
255  }
256  else if (type.IsSubclassOf(typeof(GlobalItem))) {
257  AutoloadGlobalItem(type);
258  }
259  else if (type.IsSubclassOf(typeof(ModPrefix))) {
260  AutoloadPrefix(type);
261  }
262  else if (type.IsSubclassOf(typeof(ModDust))) {
263  AutoloadDust(type);
264  }
265  else if (type.IsSubclassOf(typeof(ModTile))) {
266  AutoloadTile(type);
267  }
268  else if (type.IsSubclassOf(typeof(GlobalTile))) {
269  AutoloadGlobalTile(type);
270  }
271  else if (type.IsSubclassOf(typeof(ModTileEntity))) {
272  AutoloadTileEntity(type);
273  }
274  else if (type.IsSubclassOf(typeof(ModWall))) {
275  AutoloadWall(type);
276  }
277  else if (type.IsSubclassOf(typeof(GlobalWall))) {
278  AutoloadGlobalWall(type);
279  }
280  else if (type.IsSubclassOf(typeof(ModProjectile))) {
281  AutoloadProjectile(type);
282  }
283  else if (type.IsSubclassOf(typeof(GlobalProjectile))) {
284  AutoloadGlobalProjectile(type);
285  }
286  else if (type.IsSubclassOf(typeof(ModNPC))) {
287  AutoloadNPC(type);
288  }
289  else if (type.IsSubclassOf(typeof(GlobalNPC))) {
290  AutoloadGlobalNPC(type);
291  }
292  else if (type.IsSubclassOf(typeof(ModPlayer))) {
293  AutoloadPlayer(type);
294  }
295  else if (type.IsSubclassOf(typeof(ModBuff))) {
296  AutoloadBuff(type);
297  }
298  else if (type.IsSubclassOf(typeof(GlobalBuff))) {
299  AutoloadGlobalBuff(type);
300  }
301  else if (type.IsSubclassOf(typeof(ModMountData))) {
302  AutoloadMountData(type);
303  }
304  else if (type.IsSubclassOf(typeof(ModGore))) {
305  modGores.Add(type);
306  }
307  else if (type.IsSubclassOf(typeof(ModSound))) {
308  modSounds.Add(type);
309  }
310  else if (type.IsSubclassOf(typeof(ModWorld))) {
311  AutoloadModWorld(type);
312  }
313  else if (type.IsSubclassOf(typeof(ModUgBgStyle))) {
314  AutoloadUgBgStyle(type);
315  }
316  else if (type.IsSubclassOf(typeof(ModSurfaceBgStyle))) {
317  AutoloadSurfaceBgStyle(type);
318  }
319  else if (type.IsSubclassOf(typeof(GlobalBgStyle))) {
320  AutoloadGlobalBgStyle(type);
321  }
322  else if (type.IsSubclassOf(typeof(ModWaterStyle))) {
323  AutoloadWaterStyle(type);
324  }
325  else if (type.IsSubclassOf(typeof(ModWaterfallStyle))) {
326  AutoloadWaterfallStyle(type);
327  }
328  else if (type.IsSubclassOf(typeof(GlobalRecipe))) {
329  AutoloadGlobalRecipe(type);
330  }
331  else if (type.IsSubclassOf(typeof(ModCommand))) {
332  AutoloadCommand(type);
333  }
334  }
335  if (Properties.AutoloadGores) {
336  AutoloadGores(modGores);
337  }
338  if (Properties.AutoloadSounds) {
339  AutoloadSounds(modSounds);
340  }
341  if (Properties.AutoloadBackgrounds) {
342  AutoloadBackgrounds();
343  }
344  }
345 
346  private void AutoloadItem(Type type) {
347  ModItem item = (ModItem)Activator.CreateInstance(type);
348  item.mod = this;
349  string name = type.Name;
350  if (item.Autoload(ref name)) {
351  AddItem(name, item);
352  var autoloadEquip = type.GetAttribute<AutoloadEquip>();
353  if (autoloadEquip != null)
354  foreach (var equip in autoloadEquip.equipTypes)
355  AddEquipTexture(item, equip, item.Name, item.Texture + '_' + equip,
356  item.Texture + "_Arms", item.Texture + "_FemaleBody");
357  }
358  }
359 
360  private void AutoloadGlobalItem(Type type) {
361  GlobalItem globalItem = (GlobalItem)Activator.CreateInstance(type);
362  globalItem.mod = this;
363  string name = type.Name;
364  if (globalItem.Autoload(ref name)) {
365  AddGlobalItem(name, globalItem);
366  }
367  }
368 
369  private void AutoloadPrefix(Type type) {
370  ModPrefix prefix = (ModPrefix)Activator.CreateInstance(type);
371  prefix.mod = this;
372  string name = type.Name;
373  if (prefix.Autoload(ref name)) {
374  AddPrefix(name, prefix);
375  }
376  }
377 
378  private void AutoloadDust(Type type) {
379  ModDust dust = (ModDust)Activator.CreateInstance(type);
380  dust.mod = this;
381  string name = type.Name;
382  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
383  if (dust.Autoload(ref name, ref texture)) {
384  AddDust(name, dust, texture);
385  }
386  }
387 
388  private void AutoloadTile(Type type) {
389  ModTile tile = (ModTile)Activator.CreateInstance(type);
390  tile.mod = this;
391  string name = type.Name;
392  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
393  if (tile.Autoload(ref name, ref texture)) {
394  AddTile(name, tile, texture);
395  }
396  }
397 
398  private void AutoloadGlobalTile(Type type) {
399  GlobalTile globalTile = (GlobalTile)Activator.CreateInstance(type);
400  globalTile.mod = this;
401  string name = type.Name;
402  if (globalTile.Autoload(ref name)) {
403  AddGlobalTile(name, globalTile);
404  }
405  }
406 
407  private void AutoloadTileEntity(Type type) {
408  ModTileEntity tileEntity = (ModTileEntity)Activator.CreateInstance(type);
409  tileEntity.mod = this;
410  string name = type.Name;
411  if (tileEntity.Autoload(ref name)) {
412  AddTileEntity(name, tileEntity);
413  }
414  }
415 
416  private void AutoloadWall(Type type) {
417  ModWall wall = (ModWall)Activator.CreateInstance(type);
418  wall.mod = this;
419  string name = type.Name;
420  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
421  if (wall.Autoload(ref name, ref texture)) {
422  AddWall(name, wall, texture);
423  }
424  }
425 
426  private void AutoloadGlobalWall(Type type) {
427  GlobalWall globalWall = (GlobalWall)Activator.CreateInstance(type);
428  globalWall.mod = this;
429  string name = type.Name;
430  if (globalWall.Autoload(ref name)) {
431  AddGlobalWall(name, globalWall);
432  }
433  }
434 
435  private void AutoloadProjectile(Type type) {
436  ModProjectile projectile = (ModProjectile)Activator.CreateInstance(type);
437  projectile.mod = this;
438  string name = type.Name;
439  if (projectile.Autoload(ref name)) {
440  AddProjectile(name, projectile);
441  }
442  }
443 
444  private void AutoloadGlobalProjectile(Type type) {
445  GlobalProjectile globalProjectile = (GlobalProjectile)Activator.CreateInstance(type);
446  globalProjectile.mod = this;
447  string name = type.Name;
448  if (globalProjectile.Autoload(ref name)) {
449  AddGlobalProjectile(name, globalProjectile);
450  }
451  }
452 
453  private void AutoloadNPC(Type type) {
454  ModNPC npc = (ModNPC)Activator.CreateInstance(type);
455  npc.mod = this;
456  string name = type.Name;
457  if (npc.Autoload(ref name)) {
458  AddNPC(name, npc);
459  var autoloadHead = type.GetAttribute<AutoloadHead>();
460  if (autoloadHead != null) {
461  string headTexture = npc.HeadTexture;
462  AddNPCHeadTexture(npc.npc.type, headTexture);
463  }
464  var autoloadBossHead = type.GetAttribute<AutoloadBossHead>();
465  if (autoloadBossHead != null) {
466  string headTexture = npc.BossHeadTexture;
467  AddBossHeadTexture(headTexture, npc.npc.type);
468  }
469  }
470  }
471 
472  private void AutoloadGlobalNPC(Type type) {
473  GlobalNPC globalNPC = (GlobalNPC)Activator.CreateInstance(type);
474  globalNPC.mod = this;
475  string name = type.Name;
476  if (globalNPC.Autoload(ref name)) {
477  AddGlobalNPC(name, globalNPC);
478  }
479  }
480 
481  private void AutoloadPlayer(Type type) {
482  ModPlayer player = (ModPlayer)Activator.CreateInstance(type);
483  player.mod = this;
484  string name = type.Name;
485  if (player.Autoload(ref name)) {
486  AddPlayer(name, player);
487  }
488  }
489 
490  private void AutoloadBuff(Type type) {
491  ModBuff buff = (ModBuff)Activator.CreateInstance(type);
492  buff.mod = this;
493  string name = type.Name;
494  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
495  if (buff.Autoload(ref name, ref texture)) {
496  AddBuff(name, buff, texture);
497  }
498  }
499 
500  private void AutoloadGlobalBuff(Type type) {
501  GlobalBuff globalBuff = (GlobalBuff)Activator.CreateInstance(type);
502  globalBuff.mod = this;
503  string name = type.Name;
504  if (globalBuff.Autoload(ref name)) {
505  AddGlobalBuff(name, globalBuff);
506  }
507  }
508 
509  private void AutoloadMountData(Type type) {
510  ModMountData mount = (ModMountData)Activator.CreateInstance(type);
511  mount.mod = this;
512  string name = type.Name;
513  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
514  var extraTextures = new Dictionary<MountTextureType, string>();
515  foreach (MountTextureType textureType in Enum.GetValues(typeof(MountTextureType))) {
516  extraTextures[textureType] = texture + "_" + textureType.ToString();
517  }
518  if (mount.Autoload(ref name, ref texture, extraTextures)) {
519  AddMount(name, mount, texture, extraTextures);
520  }
521  }
522 
523  private void AutoloadModWorld(Type type) {
524  ModWorld modWorld = (ModWorld)Activator.CreateInstance(type);
525  modWorld.mod = this;
526  string name = type.Name;
527  if (modWorld.Autoload(ref name)) {
528  AddModWorld(name, modWorld);
529  }
530  }
531 
532  private void AutoloadBackgrounds() {
533  foreach (string texture in textures.Keys.Where(t => t.StartsWith("Backgrounds/"))) {
534  AddBackgroundTexture(Name + '/' + texture);
535  }
536  }
537 
538  private void AutoloadUgBgStyle(Type type) {
539  ModUgBgStyle ugBgStyle = (ModUgBgStyle)Activator.CreateInstance(type);
540  ugBgStyle.mod = this;
541  string name = type.Name;
542  if (ugBgStyle.Autoload(ref name)) {
543  AddUgBgStyle(name, ugBgStyle);
544  }
545  }
546 
547  private void AutoloadSurfaceBgStyle(Type type) {
548  ModSurfaceBgStyle surfaceBgStyle = (ModSurfaceBgStyle)Activator.CreateInstance(type);
549  surfaceBgStyle.mod = this;
550  string name = type.Name;
551  if (surfaceBgStyle.Autoload(ref name)) {
552  AddSurfaceBgStyle(name, surfaceBgStyle);
553  }
554  }
555 
556  private void AutoloadGlobalBgStyle(Type type) {
557  GlobalBgStyle globalBgStyle = (GlobalBgStyle)Activator.CreateInstance(type);
558  globalBgStyle.mod = this;
559  string name = type.Name;
560  if (globalBgStyle.Autoload(ref name)) {
561  AddGlobalBgStyle(name, globalBgStyle);
562  }
563  }
564 
565  private void AutoloadWaterStyle(Type type) {
566  ModWaterStyle waterStyle = (ModWaterStyle)Activator.CreateInstance(type);
567  waterStyle.mod = this;
568  string name = type.Name;
569  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
570  string blockTexture = texture + "_Block";
571  if (waterStyle.Autoload(ref name, ref texture, ref blockTexture)) {
572  AddWaterStyle(name, waterStyle, texture, blockTexture);
573  }
574  }
575 
576  private void AutoloadWaterfallStyle(Type type) {
577  ModWaterfallStyle waterfallStyle = (ModWaterfallStyle)Activator.CreateInstance(type);
578  waterfallStyle.mod = this;
579  string name = type.Name;
580  string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
581  if (waterfallStyle.Autoload(ref name, ref texture)) {
582  AddWaterfallStyle(name, waterfallStyle, texture);
583  }
584  }
585 
586  private void AutoloadGores(IList<Type> modGores) {
587  var modGoreNames = modGores.ToDictionary(t => t.Namespace + "." + t.Name);
588  foreach (var texture in textures.Keys.Where(t => t.StartsWith("Gores/"))) {
589  ModGore modGore = null;
590  Type t;
591  if (modGoreNames.TryGetValue(Name + "." + texture.Replace('/', '.'), out t))
592  modGore = (ModGore)Activator.CreateInstance(t);
593 
594  AddGore(Name + '/' + texture, modGore);
595  }
596  }
597 
598  private void AutoloadSounds(IList<Type> modSounds) {
599  var modSoundNames = modSounds.ToDictionary(t => t.Namespace + "." + t.Name);
600  foreach (var sound in sounds.Keys.Where(t => t.StartsWith("Sounds/"))) {
601  string substring = sound.Substring("Sounds/".Length);
602  SoundType soundType = SoundType.Custom;
603  if (substring.StartsWith("Item/")) {
604  soundType = SoundType.Item;
605  }
606  else if (substring.StartsWith("NPCHit/")) {
607  soundType = SoundType.NPCHit;
608  }
609  else if (substring.StartsWith("NPCKilled/")) {
610  soundType = SoundType.NPCKilled;
611  }
612  ModSound modSound = null;
613  Type t;
614  if (modSoundNames.TryGetValue((Name + '/' + sound).Replace('/', '.'), out t))
615  modSound = (ModSound)Activator.CreateInstance(t);
616 
617  AddSound(soundType, Name + '/' + sound, modSound);
618  }
619  foreach (var music in musics.Keys.Where(t => t.StartsWith("Sounds/"))) {
620  string substring = music.Substring("Sounds/".Length);
621  if (substring.StartsWith("Music/")) {
622  AddSound(SoundType.Music, Name + '/' + music);
623  }
624  }
625  }
626 
627  private void AutoloadGlobalRecipe(Type type) {
628  GlobalRecipe globalRecipe = (GlobalRecipe)Activator.CreateInstance(type);
629  globalRecipe.mod = this;
630  string name = type.Name;
631  if (globalRecipe.Autoload(ref name)) {
632  AddGlobalRecipe(name, globalRecipe);
633  }
634  }
635 
636  private void AutoloadCommand(Type type) {
637  var mc = (ModCommand)Activator.CreateInstance(type);
638  mc.mod = this;
639  var name = type.Name;
640  if (mc.Autoload(ref name))
641  AddCommand(name, mc);
642  }
643 
647  private void AutoloadLocalization() {
648  var modTranslationDictionary = new Dictionary<string, ModTranslation>();
649  foreach (var translationFile in File.Where(entry => Path.GetExtension(entry.Name) == ".lang")) {
650  // .lang files need to be UTF8 encoded.
651  string translationFileContents = System.Text.Encoding.UTF8.GetString(File.GetBytes(translationFile));
652  GameCulture culture = GameCulture.FromName(Path.GetFileNameWithoutExtension(translationFile.Name));
653 
654  using (StringReader reader = new StringReader(translationFileContents)) {
655  string line;
656  while ((line = reader.ReadLine()) != null) {
657  int split = line.IndexOf('=');
658  if (split < 0)
659  continue; // lines witout a = are ignored
660  string key = line.Substring(0, split).Trim().Replace(" ", "_");
661  string value = line.Substring(split + 1); // removed .Trim() since sometimes it is desired.
662  if (value.Length == 0) {
663  continue;
664  }
665  value = value.Replace("\\n", "\n");
666  // TODO: Maybe prepend key with filename: en.US.ItemName.lang would automatically assume "ItemName." for all entries.
667  //string key = key;
668  if (!modTranslationDictionary.TryGetValue(key, out ModTranslation mt))
669  modTranslationDictionary[key] = mt = CreateTranslation(key);
670  mt.AddTranslation(culture, value);
671  }
672  }
673  }
674 
675  foreach (var value in modTranslationDictionary.Values) {
676  AddTranslation(value);
677  }
678  }
679  }
680 }
void AutoloadGlobalBuff(Type type)
int Type
The index of this ModMountData in the Mount.mounts array.
Definition: ModMountData.cs:37
virtual void AutoStaticDefaults()
Automatically sets certain static defaults. Override this if you do not want the properties to be set...
Definition: ModNPC.cs:189
virtual void SetStaticDefaults()
This is where you set all your item&#39;s static properties, such as names/translations and the arrays in...
Definition: ModItem.cs:169
A ModPlayer instance represents an extension of a Player instance. You can store fields in the ModPla...
Definition: ModPlayer.cs:15
This class represents a type of tile that can be added by a mod. Only one instance of this class will...
Definition: ModTile.cs:12
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalBuff instead of using Mod.AddGlobalBuff. Return true to allo...
Definition: GlobalBuff.cs:31
This class serves as a place for you to place all your properties and hooks for each NPC...
Definition: ModNPC.cs:14
Each background style determines in its own way how exactly the background is drawn. This class serves as a collection of functions for above-ground backgrounds.
void AutoloadTile(Type type)
Mod mod
The mod which has added this type of ModTile.
Definition: ModTile.cs:17
void AutoloadTileEntity(Type type)
This serves as the central class from which projectile-related functions are carried out...
Mod mod
The mod that added this style of waterfall.
SoundEffect LoadSound(Stream stream, int length, string extension)
Definition: ModInternals.cs:85
Mod mod
The mod to which this GlobalWall belongs.
Definition: GlobalWall.cs:13
Tile Entities are Entities tightly coupled with tiles, allowing the possibility of tiles to exhibit c...
void AutoloadGlobalItem(Type type)
static Texture2D GetTexture(string name)
Gets the texture with the specified name. The name is in the format of "ModFolder/OtherFolders/FileNa...
Definition: ModContent.cs:72
void AutoloadSounds(IList< Type > modSounds)
Mod mod
That mod that added this global background style.
void AutoloadGlobalTile(Type type)
void AutoloadGlobalWall(Type type)
This class allows you to modify the behavior of any tile in the game. Create an instance of an overri...
Definition: GlobalTile.cs:10
virtual bool Autoload(ref string name, ref string texture)
Allows you to automatically add a type of dust without having to use Mod.AddDust. By default returns ...
Definition: ModDust.cs:118
void AutoloadItem(Type type)
virtual bool Autoload(ref string name, ref string texture, ref string blockTexture)
Allows you to automatically add a ModWaterStyle instead of using Mod.AddWaterStyle. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name, and texture is initialized to the namespace and overriding class name with periods replaced with slashes. BlockTexture is initialized to texture with "_Block" added at the end. Use this to either force or stop an autoload, change the name that identifies this type of ModWaterStyle, and/or change the texture paths used by this ModWaterStyle.
virtual string HeadTexture
The file name of this NPC&#39;s head texture file, to be used in autoloading.
Definition: ModNPC.cs:61
void AutoloadNPC(Type type)
Mod mod
The mod that added this ModBuff.
Definition: ModBuff.cs:11
void AutoloadGlobalProjectile(Type type)
Mod mod
The mod that added this ModNPC.
Definition: ModNPC.cs:29
virtual bool Autoload(ref string name)
Definition: ModPrefix.cs:126
This serves as a place for you to program behaviors of equipment textures. This is useful for equipme...
Definition: EquipTexture.cs:8
void LoadTexture(string path, Stream stream, bool rawimg)
Definition: ModInternals.cs:60
Mod mod
The mod to which this GlobalTile belongs to.
Definition: GlobalTile.cs:15
virtual void SetDefaults()
Allows you to set this ModDust&#39;s updateType field and modify the Terraria.GameContent.ChildSafety.SafeDust array.
Definition: ModDust.cs:125
Item item
The item object that this ModItem controls.
Definition: ModItem.cs:26
virtual bool Autoload(ref string name)
Allows you to automatically add a ModUgBgStyle instead of using Mod.AddUgBgStyle. Return true to allo...
void AutoloadModWorld(Type type)
void AutoloadWaterStyle(Type type)
virtual string HighlightTexture
The highlight texture used when this tile is selected by smart interact. Defaults to adding "_Highlig...
Definition: ModTile.cs:42
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalNPC instead of using Mod.AddGlobalNPC. Return true to allow ...
Definition: GlobalNPC.cs:37
void AutoloadSurfaceBgStyle(Type type)
void AutoloadCommand(Type type)
This serves as the central class from which tile-related functions are supported and carried out...
Definition: TileLoader.cs:14
virtual void AutoStaticDefaults()
Automatically sets certain static defaults. Override this if you do not want the properties to be set...
Definition: ModItem.cs:175
Mod mod
The mod to which this GlobalItem belongs.
Definition: GlobalItem.cs:20
virtual void SetDefaults()
Allows you to set the prefix&#39;s name/translations and to set its category.
Definition: ModPrefix.cs:138
virtual bool Autoload(ref string name)
Allows you to automatically add a GlobalBgStyle instead of using Mod.AddGlobalBgStyle. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name. Use this to either force or stop an autoload, or change the name that identifies this type of GlobalBgStyle.
virtual void SetDefaults()
This is where all buff related assignments go. For example: Main.buffName[Type] = "Display Name"; Mai...
Definition: ModBuff.cs:72
virtual bool Autoload(ref string name, ref string texture)
Allows you to automatically load a buff instead of using Mod.AddBuff. Return true to allow autoloadin...
Definition: ModBuff.cs:57
Mod mod
The mod that added this type of dust.
Definition: ModDust.cs:39
virtual void SetDefaults()
Allows you to modify the properties of any tile in the game. Most properties are stored as arrays thr...
Definition: GlobalTile.cs:77
ushort Type
The internal ID of this type of wall.
Definition: ModWall.cs:33
This class allows you to customize the behavior of a custom gore. Create a new instance of this and p...
Definition: ModGore.cs:12
virtual bool Autoload(ref string name, ref string texture)
Allows you to modify the name and texture path of this wall when it is autoloaded. Return true to autoload this wall. When a wall is autoloaded, that means you do not need to manually call Mod.AddWall. By default returns the mod&#39;s autoload property.
Definition: ModWall.cs:123
Music LoadMusic(string path, string extension)
NPC npc
The NPC object that this ModNPC controls.
Definition: ModNPC.cs:21
Mod mod
The mod which has added this ModMountData.
Definition: ModMountData.cs:29
void AutoloadWaterfallStyle(Type type)
This class serves to collect functions that operate on any kind of background style, without being specific to one single background style.
virtual bool Autoload(ref string name)
Allows you to automatically add a ModWorld instead of using Mod.AddModWorld. Return true to allow aut...
Definition: ModWorld.cs:32
Mod mod
The mod that added this type of ModPlayer.
Definition: ModPlayer.cs:20
void AutoloadDust(Type type)
Represents a style of water that gets drawn, based on factors such as the background. This is used to determine the color of the water, as well as other things as determined by the hooks below.
Definition: ModWaterStyle.cs:8
Mod mod
The mod that added this style of water.
Manages content added by mods. Liasons between mod content and Terraria&#39;s arrays and oversees the Loa...
Definition: ModContent.cs:26
Mod mod
The mod which has added this type of ModWall.
Definition: ModWall.cs:17
Projectile projectile
The projectile object that this ModProjectile controls.
This class allows you to modify the behavior of any wall in the game (although admittedly walls don&#39;t...
Definition: GlobalWall.cs:8
Mod mod
The mod object that this ModProjectile originates from.
This class allows you to modify and use hooks for all items, including vanilla items. Create an instance of an overriding class then call Mod.AddGlobalItem to use this.
Definition: GlobalItem.cs:15
Mod mod
Gets the mod.
Definition: ModItem.cs:37
virtual void SetStaticDefaults()
Allows you to set all your NPC&#39;s static properties, such as names/translations and the arrays in NPCI...
Definition: ModNPC.cs:183
This class allows you to customize how a sound you add is played. To use this, pass an instance to Mo...
Definition: ModSound.cs:8
virtual bool Autoload(ref string name)
Allows you to automatically add a ModSurfaceBgStyle instead of using Mod.AddSurfaceBgStyle. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name. Use this to either force or stop an autoload, or change the name that identifies this type of ModSurfaceBgStyle.
static Task< Texture2D > RawToTexture2DAsync(GraphicsDevice graphicsDevice, BinaryReader r)
Definition: ImageIO.cs:94
virtual bool Autoload(ref string name)
Allows you to automatically load an item instead of using Mod.AddItem. Return true to allow autoloadi...
Definition: ModItem.cs:99
void AutoloadGlobalNPC(Type type)
virtual bool Autoload(ref string name)
Allows you to automatically load an NPC instead of using Mod.AddNPC. Return true to allow autoloading...
Definition: ModNPC.cs:121
void AutoloadMountData(Type type)
Mod mod
The mod to which this GlobalNPC belongs.
Definition: GlobalNPC.cs:16
This class represents a type of wall that can be added by a mod. Only one instance of this class will...
Definition: ModWall.cs:12
This serves as the central class from which item-related functions are carried out. It also stores a list of mod items by ID.
Definition: ItemLoader.cs:21
virtual string Texture
The file name of this item&#39;s texture file in the mod loader&#39;s file space.
Definition: ModItem.cs:69
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalRecipe instead of using Mod.AddGlobalRecipe. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name. Use this method to either force or stop an autoload, and to change the default internal name.
Definition: GlobalRecipe.cs:27
virtual void SetDefaults()
Allows you to modify the properties of any wall in the game. Most properties are stored as arrays thr...
Definition: GlobalWall.cs:36
This class serves as a place for you to place all your properties and hooks for each mount...
Definition: ModMountData.cs:14
This class allows you to modify and use hooks for all NPCs, including vanilla mobs. Create an instance of an overriding class then call Mod.AddGlobalNPC to use this.
Definition: GlobalNPC.cs:11
ushort Type
The internal ID of this type of tile.
Definition: ModTile.cs:33
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalWall instead of using Mod.AddGlobalWall. Return true to allo...
Definition: GlobalWall.cs:29
Represents a style of waterfalls that gets drawn. This is mostly used to determine the color of the w...
virtual string BossHeadTexture
This file name of this NPC&#39;s boss head texture file, to be used in autoloading.
Definition: ModNPC.cs:65
void AutoloadGlobalBgStyle(Type type)
int Type
The ID of this waterfall style.
MountTextureType
This is an enum of all possible types of extra mount textures for custom mounts. Use these as keys in...
This class serves as a place for you to define a new buff and how that buff behaves.
Definition: ModBuff.cs:6
void AutoloadGores(IList< Type > modGores)
SoundType
This is an enum of the types of sound you can add to the game. This is used for determining whether a...
Definition: SoundType.cs:12
virtual bool Autoload(ref string name)
Allows you to automatically add a ModPlayer instead of using Mod.AddPlayer. Return true to allow auto...
Definition: ModPlayer.cs:67
virtual bool Autoload(ref string name)
Allows you to automatically load a projectile instead of using Mod.AddProjectile. Return true to allo...
void AutoloadProjectile(Type type)
void AutoloadLocalization()
Loads .lang files
void AutoloadUgBgStyle(Type type)
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalItem instead of using Mod.AddGlobalItem. Return true to allo...
Definition: GlobalItem.cs:39
void AutoloadBuff(Type type)
virtual string Name
Stores the name of the mod. This name serves as the mod&#39;s identification, and also helps with saving ...
Definition: Mod.cs:42
This serves as the central class from which NPC-related functions are carried out. It also stores a list of mod NPCs by ID.
Definition: NPCLoader.cs:19
Mod mod
The mod that added this type of ModWorld.
Definition: ModWorld.cs:16
This class serves as a place for you to place all your properties and hooks for each projectile...
string chest
The default name of this chest that is displayed when this 2x2 chest is open. Defaults to the empty s...
Definition: ModTile.cs:94
A ModWorld instance represents an extension of a World. You can store fields in the ModWorld classes ...
Definition: ModWorld.cs:11
Mount.MountData mountData
The vanilla MountData object that is controlled by this ModMountData.
Definition: ModMountData.cs:21
Mod mod
The mod to which this GlobalProjectile belongs.
This class represents a chat or console command. Use the CommandType to specify the scope of the comm...
Definition: ModCommand.cs:41
This class allows you to modify the behavior of any buff in the game.
Definition: GlobalBuff.cs:10
virtual bool Autoload(ref string name, ref string texture)
Allows you to automatically add a ModWaterfallStyle instead of using Mod.AddWaterfallStyle. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name, and texture is initialized to the namespace and overriding class name with periods replaced with slashes. Use this to either force or stop an autoload, change the name that identifies this type of ModWaterStyle, or change the texture path used by this ModWaterfallStyle.
virtual void AutoStaticDefaults()
Automatically sets certain static defaults. Override this if you do not want the properties to be set...
This class provides hooks that control all recipes in the game.
Definition: GlobalRecipe.cs:6
This class serves as a place for you to place all your properties and hooks for each item...
Definition: ModItem.cs:16
void AutoloadPlayer(Type type)
virtual bool Autoload(ref string name)
Allows you to automatically load a tile entity instead of using Mod.AddTileEntity. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name. Use this method to either force or stop an autoload, or change the default display name.
This class represents a type of dust that is added by a mod. Only one instance of this class will eve...
Definition: ModDust.cs:13
void AutoloadGlobalRecipe(Type type)
Mod mod
The mod which added this GlobalRecipe.
Definition: GlobalRecipe.cs:11
virtual void SetDefaults()
Allows you to set the properties of this wall. Many properties are stored as arrays throughout Terrar...
Definition: ModWall.cs:130
int Type
The buff id of this buff.
Definition: ModBuff.cs:27
Mod mod
The mod that added this ModTileEntity.
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalProjectile instead of using Mod.AddGlobalProjectile. Return true to allow autoloading; by default returns the mod&#39;s autoload property. Name is initialized to the overriding class name. Use this method to either force or stop an autoload or to control the internal name.
Mod mod
The mod that added this surface background style.
Mod mod
The mod that added this underground background style.
void AutoloadWall(Type type)
virtual void SetStaticDefaults()
Allows you to set all your projectile&#39;s static properties, such as names/translations and the arrays ...
virtual void AutoDefaults()
Definition: ModPrefix.cs:130
This class allows you to modify and use hooks for all projectiles, including vanilla projectiles...
string Name
The internal name of this ModItem.
Definition: ModItem.cs:45
This serves as the central place from which mounts are stored and mount-related functions are carried...
Definition: MountLoader.cs:13
Mod mod
The mod to which this GlobalBuff belongs.
Definition: GlobalBuff.cs:15
int Type
The ID of the water style.
Each background style determines in its own way how exactly the background is drawn. This class serves as a collection of functions for underground backgrounds.
void AutoloadPrefix(Type type)
virtual bool Autoload(ref string name)
Allows you to automatically load a GlobalTile instead of using Mod.AddGlobalTile. Return true to allo...
Definition: GlobalTile.cs:70
static Task< Texture2D > PngToTexture2DAsync(GraphicsDevice graphicsDevice, Stream stream)
Definition: ImageIO.cs:103
virtual bool Autoload(ref string name, ref string texture)
Allows you to modify the name and texture path of this tile when it is autoloaded. Return true to autoload this tile. When a tile is autoloaded, that means you do not need to manually call Mod.AddTile. By default returns the mod&#39;s autoload property.
Definition: ModTile.cs:222
static void Convert(float[] floatBuf, byte[] buffer)