Skip to content

en Override System

HoCha113 edited this page Jun 21, 2026 · 4 revisions

中文版本

Override System

Three Override base classes (Item / Player / NPC): singleton behavior overrides by TargetID without editing vanilla code.


Overview

Override is built on VaultType<T> and binds via TargetID. Compared to tModLoader GlobalItem / GlobalNPC:

  • Precise ID matching: Bind to specific items/NPCs via TargetID
  • Universal override: TargetID = -1 applies to all objects
  • Dual-layer hooks: Standard hooks plus On_ prefix hooks; the latter can interrupt the rest of the chain
  • Query system: TryFetchByID / GetOverride<T>() for quick instance retrieval
Component Base Class Purpose
ItemOverride VaultType<ItemOverride> Override item behavior (SetDefaults, Shoot, ModifyTooltips…)
PlayerOverride VaultType<PlayerOverride> Override player behavior (damage modification, hit, death…)
NPCOverride VaultType<NPCOverride> Override NPC behavior (AI, draw, death, loot…)

ItemOverride — Item Override

Quick Start

using InnoVault.GameSystem;
using Terraria;
using Terraria.ID;

public class WoodenSwordOverride : ItemOverride
{
    // Bind to Wooden Sword
    public override int TargetID => ItemID.WoodenSword;

    // Modify item default properties
    public override void SetDefaults(Item item) {
        item.damage = 50;
        item.useTime = 10;
    }

    // Modify item tooltips
    public override void ModifyTooltips(Item item, List<TooltipLine> tooltips) {
        tooltips.Add(new TooltipLine(Mod, "CustomLine", "Modified by Override!"));
    }
}

TargetID and Universal Override

TargetID Value Behavior
> 0 Only applies to that item ID, registered to the ByID dictionary
= -1 Applies to all items, registered to UniversalInstances
= 0 (ItemID.None) Not registered, no effect

Prefix Control Dictionaries

The following static dictionaries can be modified in SetStaticDefaults to control prefixes:

// Allow/disallow all prefixes
ItemOverride.ItemAllowPrefixDic[ItemID.WoodenSword] = true;

// Allow/disallow melee prefixes
ItemOverride.ItemMeleePrefixDic[ItemID.WoodenSword] = false;

// Allow/disallow ranged prefixes
ItemOverride.ItemRangedPrefixDic[ItemID.WoodenSword] = null; // null = default logic

On_ Dual-Layer Hook Mechanism

Most ItemOverride hooks provide two versions simultaneously:

Standard Hook On_ Hook Difference
ModifyHitNPC(...) On_ModifyHitNPC(...) On_ version can return bool? to control execution chain
ModifyTooltips(...) On_ModifyTooltips(...) On_ version can return bool? to control execution chain
Shoot(...) On_Shoot(...) On_ version can return bool? to control execution chain
CanUseItem(...) On_CanUseItem(...) On_ version can return bool? to control execution chain

On_ hook return value rules:

  • null — Continue executing all subsequent methods (original ModItem + GlobalItem)
  • true — Only execute the original ModItem method, block GlobalItem's additional logic
  • false — Block all subsequent logic

Common Hooks Overview

Hook Description
SetDefaults(Item) Set properties when item is created
ModifyName(Item, ref string) Modify item logical name (affects search)
ModifyAffixName(Item, ref string) Modify item display name (affects UI)
CanUseItem(Item, Player) Control whether item can be used
Shoot(Item, Player, source, pos, vel, type, dmg, kb) Shoot hook
ModifyShootStats(Item, Player, ref pos, ref vel, ref type, ref dmg, ref kb) Modify shoot parameters
ModifyHitNPC(Item, Player, NPC, ref modifiers) Modify hit damage
OnHitNPC(Item, Player, NPC, hit, damageDone) Post-hit callback
ModifyTooltips(Item, List<TooltipLine>) Modify item tooltips
ModifyWeaponDamage(Item, Player, ref StatModifier) Modify weapon damage
ModifyWeaponCrit(Item, Player, ref float) Modify weapon crit
UpdateAccessory(Item, Player, bool) Accessory equip update
UpdateEquip(Item, Player) Equipment effect update
UpdateArmorByHead(Player, Item body, Item legs) Set bonus effects
PreDrawInInventory(...) / PostDrawInInventory(...) Draw in inventory
PreShimmering(Item) / PostShimmering(Item) Before/after shimmer transform
SaveData(Item, TagCompound) / LoadData(Item, TagCompound) Item data persistence
HoldItem(Item, Player) Held behavior
RightClick(Item, Player) Right-click event
AddRecipe(Item) / ModifyRecipe(...) Recipe system

Querying Instances

// Find all overrides by ID
if (ItemOverride.TryFetchByID(ItemID.WoodenSword, out var overrides)) {
    foreach (var ov in overrides.Values) { /* ... */ }
}

// Find single override by ID
if (ItemOverride.TryFetchByID(ItemID.WoodenSword, out ItemOverride singleOv)) {
    // Use singleOv
}

// Generic retrieval
var myOverride = ItemOverride.GetOverride<WoodenSwordOverride>();

PlayerOverride — Player Override

Quick Start

using InnoVault.GameSystem;
using Terraria;

public class MyPlayerOverride : PlayerOverride
{
    // Set default properties
    public override void SetDefaults() {
        // Initialize
    }

    // Per-frame update
    public override void PostUpdate() {
        Player.statDefense += 10;
    }

    // Reset effects
    public override void ResetEffects() {
        // Reset per-frame data
    }
}

Features

  • Per-player instances: Each player has an independent PlayerOverride cloned instance
  • Player property automatically points to the owning player
  • TargetItemID: If set to non-ItemID.None, related item hooks only apply to that item

Hooks Overview

Hook Description
SetDefaults() Initialize on load
ResetEffects() Reset per frame
PostUpdate() Per-frame update (runs last)
On_ModifyHitNPCWithItem(Item, NPC, ref modifiers) Item hit modification
On_ModifyHitNPCWithProj(Proj, NPC, ref modifiers) Projectile hit modification
On_OnHitNPC(NPC, hit, damageDone) Post-hit callback
On_Hurt(ref HurtState) Hurt processing
On_PreKill(damage, hitDir, pvp, ...) Pre-death intercept, return false to prevent death
CanSwitchWeapon() Whether weapon switching is allowed
CanUseItem(Item) Whether item can be used
ItemShoot(Item, source, pos, vel, type, dmg, kb) Item shoot override
On_CanBeHitByProjectile(Projectile) Whether hit by projectile
On_PreEmitUseVisuals(Item, ref Rectangle) Before item use visual effects
PreDrawPlayers(ref Camera, ref players) Before player draw
PreIsSceneEffectActive(ModSceneEffect) Scene effect override

Querying Instances

// Get from player
if (PlayerOverride.TryFetchByPlayer(player, out var overrides)) {
    foreach (var ov in overrides.Values) { /* ... */ }
}

// Generic retrieval (prototype instance, not per-player)
var prototype = PlayerOverride.GetOverride<MyPlayerOverride>();

// Get specific player's instance
var myOv = player.GetOverride<MyPlayerOverride>();

NPCOverride — NPC Override

Quick Start

using InnoVault.GameSystem;
using Terraria;
using Terraria.ID;

public class ZombieOverride : NPCOverride
{
    public override int TargetID => NPCID.Zombie;

    // Initialize instance data
    public override void SetProperty() {
        ai[0] = 100f; // Custom AI data
    }

    // Override AI
    public override bool AI() {
        // Custom behavior...
        ai[0] -= 1;
        if (ai[0] <= 0) {
            npc.life = 0;
        }
        return false; // Block vanilla AI
    }

    // Post-AI processing
    public override void PostAI() {
        // Processing after AI runs
    }
}

Features

  • Per-NPC instances: Each NPC has an independent cloned instance
  • Built-in 12-slot ai[] and localAI[] arrays
  • OverrideID: Globally unique number for network sync identification
  • npc property automatically points to the associated NPC

AI and Lifecycle Hooks

Hook Return Description
SetProperty() void Initialize when NPC is created
AI() bool false blocks subsequent AI
PostAI() void After AI runs
On_PreKill() bool? Non-null blocks death logic
CheckDead() bool? Non-null blocks death check
SpecialOnKill() bool? Non-null blocks kill event
CheckActive() bool Active check

Combat Hooks

Hook Description
On_ModifyIncomingHit(NPC, ref modifiers) Override hit damage formula
On_OnHitByProjectile(NPC, Projectile, hit, dmg) Hit by projectile
On_OnHitByItem(Player, Item, hit, dmg) Hit by item
ModifyHitByItem(Player, Item, ref modifiers) Modify item hit damage
ModifyHitByProjectile(Projectile, ref modifiers) Modify projectile hit damage
CanBeHitByItem/NPC/Projectile(...) Whether can be hit

Draw and UI Hooks

Hook Description
Draw(SpriteBatch, screenPos, drawColor) Override draw
PostDraw(SpriteBatch, screenPos, drawColor) Post-draw
FindFrame(frameHeight) Frame animation update
BossHeadSlot(ref index) Map boss icon
DrawHealthBar(hbPos, ref scale, ref pos) Health bar draw
ModifyDrawNPCHeadBoss(...) Boss head portrait data

NPC Interaction Hooks

Hook Description
GetChat(ref string) Modify chat content
SetChatButtons(ref btn1, ref btn2) Chat button names
PreChatButtonClicked(firstButton) Pre-button click intercept
OnChatButtonClicked(firstButton) Button click callback
ModifyActiveShop(shopName, items) Modify shop inventory
ModifyNPCLoot(NPC, NPCLoot) Modify loot table

Data Persistence

public override bool NeedSaving() => true; // Enable saving

public override void SaveData(TagCompound tag) {
    tag["customHP"] = ai[0];
}

public override void LoadData(TagCompound tag) {
    ai[0] = tag.GetFloat("customHP");
}

Network Synchronization

NPCOverride provides multiple network sync mechanisms:

// 1. ai[] auto-sync: set npc.netUpdate = true
npc.netUpdate = true;

// 2. Additional data sync: set NetOtherWorkSend (server-side only)
NetOtherWorkSend = true;

// 3. Override custom network data
public override void OtherNetWorkSend(ModPacket netMessage) {
    netMessage.Write(localAI[0]);
}

public override void OtherNetWorkReceive(BinaryReader reader) {
    localAI[0] = reader.ReadSingle();
}

// 4. Client-initiated send (bidirectional sync)
SendNetworkData();

ai[] uses bitmask optimization, only sending non-zero slots to reduce bandwidth.


CanOverride Validation

All Override types support the CanOverride() method for dynamically enabling/disabling overrides at runtime:

public override bool CanOverride() {
    // Only takes effect under certain conditions
    return SomeCondition;
}

TryFetchByID automatically filters out instances where CanOverride() returns false.


Navigation

Previous Home Next
SaveContent Save System Home SyncVar Network Sync

Clone this wiki locally