Skip to content

Commit

Permalink
add support for basic NPCs
Browse files Browse the repository at this point in the history
  • Loading branch information
blushiemagic committed Aug 7, 2015
1 parent 9b06672 commit 63d38df
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Terraria.ModLoader/GlobalNPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public virtual bool Autoload(ref string name)
return mod.Properties.Autoload;
}

public virtual void SetDefaults(NPC npc) { }

public virtual bool PreNPCLoot(NPC npc)
{
return true;
Expand Down
78 changes: 78 additions & 0 deletions Terraria.ModLoader/Mod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public ModProperties Properties
internal readonly IDictionary<string, GlobalWall> globalWalls = new Dictionary<string, GlobalWall>();
internal readonly IDictionary<string, ModProjectile> projectiles = new Dictionary<string, ModProjectile>();
internal readonly IDictionary<string, GlobalProjectile> globalProjectiles = new Dictionary<string, GlobalProjectile>();
internal readonly IDictionary<string, ModNPC> npcs = new Dictionary<string, ModNPC>();
internal readonly IDictionary<string, GlobalNPC> globalNPCs = new Dictionary<string, GlobalNPC>();

/*
Expand Down Expand Up @@ -95,6 +96,10 @@ internal void Autoload()
{
AutoloadGlobalProjectile(type);
}
if(type.IsSubclassOf(typeof(ModNPC)))
{
AutoloadNPC(type);
}
if(type.IsSubclassOf(typeof(GlobalNPC)))
{
AutoloadGlobalNPC(type);
Expand Down Expand Up @@ -394,6 +399,7 @@ public void AddProjectile(string name, ModProjectile projectile, string texture)
{
int id = ProjectileLoader.ReserveProjectileID();
projectile.projectile.name = name;
projectile.Name = name;
projectile.projectile.type = id;
projectiles[name] = projectile;
ProjectileLoader.projectiles[id] = projectile;
Expand Down Expand Up @@ -466,6 +472,39 @@ private void AutoloadGlobalProjectile(Type type)
}
}

public void AddNPC(string name, ModNPC npc, string texture)
{
int id = NPCLoader.ReserveNPCID();
npc.npc.name = name;
npc.npc.type = id;
npcs[name] = npc;
NPCLoader.npcs[id] = npc;
npc.texture = texture;
npc.mod = this;
}

public ModNPC GetNPC(string name)
{
if (npcs.ContainsKey(name))
{
return npcs[name];
}
else
{
return null;
}
}

public int NPCType(string name)
{
ModNPC npc = GetNPC(name);
if (npc == null)
{
return 0;
}
return npc.npc.type;
}

public void AddGlobalNPC(string name, GlobalNPC globalNPC)
{
globalNPC.mod = this;
Expand All @@ -486,6 +525,18 @@ public GlobalNPC GetGlobalNPC(string name)
}
}

private void AutoloadNPC(Type type)
{
ModNPC npc = (ModNPC)Activator.CreateInstance(type);
npc.mod = this;
string name = type.Name;
string texture = (type.Namespace + "." + type.Name).Replace('.', '/');
if(npc.Autoload(ref name, ref texture))
{
AddNPC(name, npc, texture);
}
}

private void AutoloadGlobalNPC(Type type)
{
GlobalNPC globalNPC = (GlobalNPC)Activator.CreateInstance(type);
Expand Down Expand Up @@ -530,6 +581,29 @@ internal void SetupContent()
{
globalWall.SetDefaults();
}
foreach(ModProjectile projectile in projectiles.Values)
{
Main.projectileTexture[projectile.projectile.type] = ModLoader.GetTexture(projectile.texture);
projectile.SetDefaults();
}
foreach(ModNPC npc in npcs.Values)
{
Main.npcTexture[npc.npc.type] = ModLoader.GetTexture(npc.texture);
Main.npcName[npc.npc.type] = npc.npc.name;
npc.SetDefaults();
if(npc.npc.lifeMax > 32767 || npc.npc.boss)
{
Main.npcLifeBytes[npc.npc.type] = 4;
}
else if(npc.npc.lifeMax > 127)
{
Main.npcLifeBytes[npc.npc.type] = 2;
}
else
{
Main.npcLifeBytes[npc.npc.type] = 1;
}
}
}

internal void Unload() //I'm not sure why I have this
Expand All @@ -540,6 +614,10 @@ internal void Unload() //I'm not sure why I have this
dusts.Clear();
tiles.Clear();
globalTiles.Clear();
walls.Clear();
globalWalls.Clear();
projectiles.Clear();
globalProjectiles.Clear();
globalNPCs.Clear();
}
}}
1 change: 1 addition & 0 deletions Terraria.ModLoader/ModLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ private static void ResizeArrays(bool unloading = false)
TileLoader.ResizeArrays(unloading);
WallLoader.ResizeArrays(unloading);
ProjectileLoader.ResizeArrays();
NPCLoader.ResizeArrays();
}

internal static string[] FindMods()
Expand Down
42 changes: 42 additions & 0 deletions Terraria.ModLoader/ModNPC.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Terraria.ModLoader {
public class ModNPC
{
//add modNPC property to Terraria.NPC (internal set)
//set modNPC to null at beginning of Terraria.NPC.SetDefaults
public NPC npc
{
get;
internal set;
}
public Mod mod
{
get;
internal set;
}
internal string texture;
public ModNPC()
{
npc = new NPC();
}

public virtual bool Autoload(ref string name, ref string texture)
{
return mod.Properties.Autoload;
}

internal void SetupNPC(NPC npc)
{
ModNPC newNPC = (ModNPC)Activator.CreateInstance(GetType());
newNPC.npc = npc;
npc.modNPC = newNPC;
newNPC.mod = mod;
newNPC.SetDefaults();
}

public virtual void SetDefaults() { }
}}
5 changes: 5 additions & 0 deletions Terraria.ModLoader/ModProjectile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public Mod mod
get;
internal set;
}
public string Name
{
get;
internal set;
}
internal string texture;
public ModProjectile()
{
Expand Down
92 changes: 92 additions & 0 deletions Terraria.ModLoader/NPCLoader.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,107 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;

namespace Terraria.ModLoader {
public static class NPCLoader
{
private static int nextNPC = NPCID.Count;
internal static readonly IDictionary<int, ModNPC> npcs = new Dictionary<int, ModNPC>();
internal static readonly IList<GlobalNPC> globalNPCs = new List<GlobalNPC>();
private static int vanillaSkeletonCount = NPCID.Sets.Skeletons.Count;

internal static int ReserveNPCID()
{
int reserveID = nextNPC;
nextNPC++;
return reserveID;
}

public static ModNPC GetNPC(int type)
{
if(npcs.ContainsKey(type))
{
return npcs[type];
}
else
{
return null;
}
}

internal static void ResizeArrays()
{
Array.Resize(ref Main.NPCLoaded, nextNPC);
Array.Resize(ref Main.nextNPC, nextNPC);
Array.Resize(ref Main.slimeRainNPC, nextNPC);
Array.Resize(ref Main.npcTexture, nextNPC);
Array.Resize(ref Main.npcCatchable, nextNPC);
Array.Resize(ref Main.npcName, nextNPC);
Array.Resize(ref Main.npcFrameCount, nextNPC);
Array.Resize(ref NPC.killCount, nextNPC);
Array.Resize(ref NPCID.Sets.NeedsExpertScaling, nextNPC);
Array.Resize(ref NPCID.Sets.ProjectileNPC, nextNPC);
Array.Resize(ref NPCID.Sets.SavesAndLoads, nextNPC);
Array.Resize(ref NPCID.Sets.TrailCacheLength, nextNPC);
Array.Resize(ref NPCID.Sets.MPAllowedEnemies, nextNPC);
Array.Resize(ref NPCID.Sets.TownCritter, nextNPC);
Array.Resize(ref NPCID.Sets.FaceEmote, nextNPC);
Array.Resize(ref NPCID.Sets.ExtraFramesCount, nextNPC);
Array.Resize(ref NPCID.Sets.AttackFrameCount, nextNPC);
Array.Resize(ref NPCID.Sets.DangerDetectRange, nextNPC);
Array.Resize(ref NPCID.Sets.AttackTime, nextNPC);
Array.Resize(ref NPCID.Sets.AttackAverageChance, nextNPC);
Array.Resize(ref NPCID.Sets.AttackType, nextNPC);
Array.Resize(ref NPCID.Sets.PrettySafe, nextNPC);
Array.Resize(ref NPCID.Sets.MagicAuraColor, nextNPC);
Array.Resize(ref NPCID.Sets.BossHeadTextures, nextNPC);
Array.Resize(ref NPCID.Sets.ExcludedFromDeathTally, nextNPC);
Array.Resize(ref NPCID.Sets.TechnicallyABoss, nextNPC);
Array.Resize(ref NPCID.Sets.MustAlwaysDraw, nextNPC);
for(int k = NPCID.Count; k < nextNPC; k++)
{
Main.NPCLoaded[k] = true;
NPCID.Sets.TrailCacheLength[k] = 10;
NPCID.Sets.DangerDetectRange[k] = -1;
NPCID.Sets.AttackTime[k] = -1;
NPCID.Sets.AttackAverageChance[k] = 1;
NPCID.Sets.AttackType[k] = -1;
NPCID.Sets.PrettySafe[k] = -1;
NPCID.Sets.MagicAuraColor[k] = Color.White;
NPCID.Sets.BossHeadTextures[k] = -1;
}
}

internal static void Unload()
{
npcs.Clear();
nextNPC = NPCID.Count;
globalNPCs.Clear();
while(NPCID.Sets.Skeletons.Count > vanillaSkeletonCount)
{
NPCID.Sets.Skeletons.RemoveAt(NPCID.Sets.Skeletons.Count - 1);
}
}

internal static bool IsModNPC(NPC npc)
{
return npc.type >= NPCID.Count;
}

//in Terraria.NPC.SetDefaults after if else setting properties call NPCLoader.SetupNPC(this);
//in Terraria.NPC.SetDefaults move Lang stuff before SetupNPC
internal static void SetupNPC(NPC npc)
{
if(IsModNPC(npc))
{
GetNPC(npc.type).SetupNPC(npc);
}
foreach(GlobalNPC globalNPC in globalNPCs)
{
globalNPC.SetDefaults(npc);
}
}

//in Terraria.NPC.NPCLoot after hardmode meteor head check add
Expand Down

0 comments on commit 63d38df

Please sign in to comment.