Standalone [1.3] tModLoader - A Modding API

How to reduce the volume in a custom sound?

HTML:
using Microsoft.Xna.Framework.Audio;
using Terraria;
using Terraria.ModLoader;

namespace WeaponsMod.Sounds.Items.Weapons.Grenade_Launcher
{
    public class Shoot : ModSound
    {
        public override SoundEffectInstance PlaySound(ref SoundEffectInstance soundInstance, float volume, float pan, SoundType type)
        {
            soundInstance = sound.CreateInstance();
            soundInstance.Volume = volume * .5f;
            soundInstance.Pan = pan;
            soundInstance.Pitch = -1.0f;
            return soundInstance;
        }
    }
}

EDIT: Why adding a custom sound with this method:

HTML:
Main.PlaySound(SoundLoader.customSoundType, projectile.position, mod.GetSoundSlot(SoundType.Custom, "Sounds/Custom/Weapons/Grenade_Launcher/Impact1"));

Only work (play the custom sound) in a folder called "Custom"?
 
Last edited:
Help... I try to compile a mod, but it just comes up with this:

error CS0006: Metadata file 'C:\Program Files (x86)\Steam\steamapps\common\Terraria\ModCompile\tModLoaderMac.exe' could not be found
 
Help... I try to compile a mod, but it just comes up with this:

error CS0006: Metadata file 'C:\Program Files (x86)\Steam\steamapps\common\Terraria\ModCompile\tModLoaderMac.exe' could not be found
Looks like you didn't copy the file tModLoaderMac.exe to the ModCompile folder inside Terraria's folder.
 
Can Someone Help me make this Despawn When Player Leaves or gets killed?




using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Trelamium.NPCs.Worm
{
public class WormHead : ModNPC
{
private static int hellLayer
{
get
{
return Main.maxTilesY - 200;
}
}
public override void SetDefaults()
{
npc.name = "Pyron"; //this is the npc Name
npc.displayName = "Pyron The Great";
npc.lifeMax = 24000; //this is the npc health
npc.damage = 120; //this is the npc damage
npc.defense = 17; //this is the npc defense
npc.knockBackResist = 0f;
npc.width = 92; //this is where you put the npc sprite width. important
npc.height = 90; //this is where you put the npc sprite height. important
npc.boss = true;
npc.lavaImmune = true; //this make the npc immune to lava
npc.noGravity = true; //this make the npc float
npc.noTileCollide = true; //this make the npc go tru walls
npc.HitSound = SoundID.NPCHit4;
npc.behindTiles = true;
npc.DeathSound = SoundID.NPCDeath2;
Main.npcFrameCount[npc.type] = 1;
npc.value = Item.buyPrice(0, 22, 25, 10);
npc.npcSlots = 1f;
npc.netAlways = true;
npc.buffImmune[24] = true;
}
public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
{
bossHeadTexture = "Trelamium/NPCs/Worm/Pryron_BossHead"; //the boss head texture
}
public override void BossLoot(ref string name, ref int potionType)
{
potionType = ItemID.HealingPotion;
Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("PyronBag"));}
public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
{
npc.lifeMax = (int)(npc.lifeMax * 0.579f * bossLifeScale); //boss life scale in expertmode
npc.damage = (int)(npc.damage * 0.6f); //boss damage increase in expermode
}
public override void HitEffect(int hitDirection, double damage)
{
if (npc.life <= 0) //this make so when the npc has 0 life(dead) he will spawn this
{
Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Magma/WormGore1"), 1f); //make sure you put the right folder name where your gores is located and the right name of gores
Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Magma/WormGore2"), 1f); // 1f is the gore sprite size, you can change it but i suggest to keep it to 1f
Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Magma/WormGore3"), 1f);
}
}
public override bool PreAI()
{
if (Main.netMode != 1)
{
if (npc.ai[3] > 0)
npc.realLife = (int)npc.ai[3];
if (npc.target < 0 || npc.target == byte.MaxValue || Main.player[npc.target].dead)
npc.TargetClosest(true);
if (Main.player[npc.target].dead && npc.timeLeft > 100)
npc.timeLeft = 100;
if (npc.ai[3] == 0)
{
// So, here we assing the npc.realLife value.
// The npc.realLife value is mainly used to determine which NPC loses life when we hit this NPC.
// We don't want every single piece of the worm to have its own HP pool, so this is a neat way to fix that.
npc.realLife = npc.whoAmI;
// LatestNPC is going to be used later on and I'll explain it there.
int latestNPC = npc.whoAmI;

// Here we determine the length of the worm.
// In this case the worm will have a length of 10 to 14 body parts.
int randomWormLength = Main.rand.Next(50, 54);
for (int i = 0; i < randomWormLength; ++i)
{
// We spawn a new NPC, setting latestNPC to the newer NPC, whilst also using that same variable
// to set the parent of this new NPC. The parent of the new NPC (may it be a tail or body part)
// will determine the movement of this new NPC.
// Under there, we also set the realLife value of the new NPC, because of what is explained above.
latestNPC = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, mod.NPCType("WormBody"), npc.whoAmI, 0, latestNPC);
Main.npc[(int)latestNPC].realLife = npc.whoAmI;
Main.npc[(int)latestNPC].ai[3] = npc.whoAmI;
}
// When we're out of that loop, we want to 'close' the worm with a tail part!
latestNPC = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, mod.NPCType("WormTail"), npc.whoAmI, 0, latestNPC);
Main.npc[(int)latestNPC].realLife = npc.whoAmI;
Main.npc[(int)latestNPC].ai[3] = npc.whoAmI;

npc.ai[0] = 1;
npc.netUpdate = true;
}
}

int minTilePosX = (int)(npc.position.X / 16.0) - 1;
int maxTilePosX = (int)((npc.position.X + npc.width) / 16.0) + 2;
int minTilePosY = (int)(npc.position.Y / 16.0) - 1;
int maxTilePosY = (int)((npc.position.Y + npc.height) / 16.0) + 2;
if (minTilePosX < 0)
minTilePosX = 0;
if (maxTilePosX > Main.maxTilesX)
maxTilePosX = Main.maxTilesX;
if (minTilePosY < 0)
minTilePosY = 0;
if (maxTilePosY > Main.maxTilesY)
maxTilePosY = Main.maxTilesY;

bool collision = false;
// This is the initial check for collision with tiles.
for (int i = minTilePosX; i < maxTilePosX; ++i)
{
for (int j = minTilePosY; j < maxTilePosY; ++j)
{
if (Main.tile[i, j] != null && (Main.tile[i, j].nactive() && (Main.tileSolid[(int)Main.tile[i, j].type] || Main.tileSolidTop[(int)Main.tile[i, j].type] && (int)Main.tile[i, j].frameY == 0) || (int)Main.tile[i, j].liquid > 64))
{
Vector2 vector2;
vector2.X = (float)(i * 16);
vector2.Y = (float)(j * 16);
if (npc.position.X + npc.width > vector2.X && npc.position.X < vector2.X + 16.0 && (npc.position.Y + npc.height > (double)vector2.Y && npc.position.Y < vector2.Y + 16.0))
{
collision = true;
if (Main.rand.Next(100) == 0 && Main.tile[i, j].nactive())
WorldGen.KillTile(i, j, true, true, false);
}
}
}
}
// If there is no collision with tiles, we check if the distance between this NPC and its target is too large, so that we can still trigger 'collision'.
if (!collision)
{
Rectangle rectangle1 = new Rectangle((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height);
int maxDistance = 1000;
bool playerCollision = true;
for (int index = 0; index < 255; ++index)
{
if (Main.player[index].active)
{
Rectangle rectangle2 = new Rectangle((int)Main.player[index].position.X - maxDistance, (int)Main.player[index].position.Y - maxDistance, maxDistance * 2, maxDistance * 2);
if (rectangle1.Intersects(rectangle2))
{
playerCollision = false;
break;
}
}
}
if (playerCollision)
collision = true;
}

// speed determines the max speed at which this NPC can move.
// Higher value = faster speed.
float speed = 30f;
// acceleration is exactly what it sounds like. The speed at which this NPC accelerates.
float acceleration = 1f;

Vector2 npcCenter = new Vector2(npc.position.X + npc.width * 0.5f, npc.position.Y + npc.height * 0.5f);
float targetXPos = Main.player[npc.target].position.X + (Main.player[npc.target].width / 2);
float targetYPos = Main.player[npc.target].position.Y + (Main.player[npc.target].height / 2);

float targetRoundedPosX = (float)((int)(targetXPos / 16.0) * 16);
float targetRoundedPosY = (float)((int)(targetYPos / 16.0) * 16);
npcCenter.X = (float)((int)(npcCenter.X / 16.0) * 16);
npcCenter.Y = (float)((int)(npcCenter.Y / 16.0) * 16);
float dirX = targetRoundedPosX - npcCenter.X;
float dirY = targetRoundedPosY - npcCenter.Y;

float length = (float)Math.Sqrt(dirX * dirX + dirY * dirY);
// If we do not have any type of collision, we want the NPC to fall down and de-accelerate along the X axis.
if (!collision)
{
npc.TargetClosest(true);
npc.velocity.Y = npc.velocity.Y + 0.11f;
if (npc.velocity.Y > speed)
npc.velocity.Y = speed;
if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.4)
{
if (npc.velocity.X < 0.0)
npc.velocity.X = npc.velocity.X - acceleration * 1.1f;
else
npc.velocity.X = npc.velocity.X + acceleration * 1.1f;
}
else if (npc.velocity.Y == speed)
{
if (npc.velocity.X < dirX)
npc.velocity.X = npc.velocity.X + acceleration;
else if (npc.velocity.X > dirX)
npc.velocity.X = npc.velocity.X - acceleration;
}
else if (npc.velocity.Y > 4.0)
{
if (npc.velocity.X < 0.0)
npc.velocity.X = npc.velocity.X + acceleration * 0.9f;
else
npc.velocity.X = npc.velocity.X - acceleration * 0.9f;
}
}
// Else we want to play some audio (soundDelay) and move towards our target.
else
{
if (npc.soundDelay == 0)
{
float num1 = length / 40f;
if (num1 < 10.0)
num1 = 10f;
if (num1 > 20.0)
num1 = 20f;
npc.soundDelay = (int)num1;
Main.PlaySound(15, (int)npc.position.X, (int)npc.position.Y, 1);
}
float absDirX = Math.Abs(dirX);
float absDirY = Math.Abs(dirY);
float newSpeed = speed / length;
dirX = dirX * newSpeed;
dirY = dirY * newSpeed;
if (npc.velocity.X > 0.0 && dirX > 0.0 || npc.velocity.X < 0.0 && dirX < 0.0 || (npc.velocity.Y > 0.0 && dirY > 0.0 || npc.velocity.Y < 0.0 && dirY < 0.0))
{
if (npc.velocity.X < dirX)
npc.velocity.X = npc.velocity.X + acceleration;
else if (npc.velocity.X > dirX)
npc.velocity.X = npc.velocity.X - acceleration;
if (npc.velocity.Y < dirY)
npc.velocity.Y = npc.velocity.Y + acceleration;
else if (npc.velocity.Y > dirY)
npc.velocity.Y = npc.velocity.Y - acceleration;
if (Math.Abs(dirY) < speed * 0.2 && (npc.velocity.X > 0.0 && dirX < 0.0 || npc.velocity.X < 0.0 && dirX > 0.0))
{
if (npc.velocity.Y > 0.0)
npc.velocity.Y = npc.velocity.Y + acceleration * 2f;
else
npc.velocity.Y = npc.velocity.Y - acceleration * 2f;
}
if (Math.Abs(dirX) < speed * 0.2 && (npc.velocity.Y > 0.0 && dirY < 0.0 || npc.velocity.Y < 0.0 && dirY > 0.0))
{
if (npc.velocity.X > 0.0)
npc.velocity.X = npc.velocity.X + acceleration * 2f;
else
npc.velocity.X = npc.velocity.X - acceleration * 2f;
}
}
else if (absDirX > absDirY)
{
if (npc.velocity.X < dirX)
npc.velocity.X = npc.velocity.X + acceleration * 1.1f;
else if (npc.velocity.X > dirX)
npc.velocity.X = npc.velocity.X - acceleration * 1.1f;
if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.5)
{
if (npc.velocity.Y > 0.0)
npc.velocity.Y = npc.velocity.Y + acceleration;
else
npc.velocity.Y = npc.velocity.Y - acceleration;
}
}
else
{
if (npc.velocity.Y < dirY)
npc.velocity.Y = npc.velocity.Y + acceleration * 1.1f;
else if (npc.velocity.Y > dirY)
npc.velocity.Y = npc.velocity.Y - acceleration * 1.1f;
if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.5)
{
if (npc.velocity.X > 0.0)
npc.velocity.X = npc.velocity.X + acceleration;
else
npc.velocity.X = npc.velocity.X - acceleration;
}
}
}
// Set the correct rotation for this NPC.
npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) + 1.57f;

// Some netupdate stuff (multiplayer compatibility).
if (collision)
{
if (npc.localAI[0] != 1)
npc.netUpdate = true;
npc.localAI[0] = 1f;
}
else
{
if (npc.localAI[0] != 0.0)
npc.netUpdate = true;
npc.localAI[0] = 0.0f;
}
if ((npc.velocity.X > 0.0 && npc.oldVelocity.X < 0.0 || npc.velocity.X < 0.0 && npc.oldVelocity.X > 0.0 || (npc.velocity.Y > 0.0 && npc.oldVelocity.Y < 0.0 || npc.velocity.Y < 0.0 && npc.oldVelocity.Y > 0.0)) && !npc.justHit)
npc.netUpdate = true;

return false;
}

public override bool PreDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Color drawColor)
{
Texture2D texture = Main.npcTexture[npc.type];
Vector2 origin = new Vector2(texture.Width * 0.5f, texture.Height * 0.5f);
Main.spriteBatch.Draw(texture, npc.Center - Main.screenPosition, new Rectangle?(), drawColor, npc.rotation, origin, npc.scale, SpriteEffects.None, 0);
return false;
}
public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
{
scale = 1.9f; //this make the NPC Health Bar biger
return null;
}
}
}
 
So I followed the instructions to a T. Now my worlds don't show up in the menu. Just try again witht eh copy, right? Nope. The executable it uses downloaded it into my main game AND my copy. :\

Only way I can see my saved worlds right now is by starting the terraria app from inside the steam folder, which I can only presume will cause problems of some sort.

Whats going on and how can I fix it?

Thanks in advance.

BTW, it would be a lot easier to figure out what was changed in my files, but the "last modified" info says it was last modified 12/24/16. Does that mean anything...?
 
Last edited:
Hmmm, do you think you can make it such that we can see when was the mod last updated by us with a date? Oh yeah, good job on this, modding made easy for Terraria players.
 
The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Terraria.Initializers.UILinksInitializer.<>c__DisplayClass3_0.<Load>b__58()
at Terraria.UI.Gamepad.UILinkPage.Update()
at Terraria.UI.Gamepad.UILinkPointNavigator.ProcessChanges()
at Terraria.UI.Gamepad.UILinkPointNavigator.Update()
at Terraria.Main.DoUpdate(GameTime gameTime)
at Terraria.Main.Update(GameTime gameTime)


keeps getting this error whenever i connect to a multiplayer server. don't really want to search thru 784 pages of post to see if someone has posted this before.
if someone knows what's causing this please quote me on how i can fix it or something.
 
Little Question.
is there a Option to show what Item is from what Mod?
It is quite hard to Tell if you just throw yourself at a Modpack.
 
I cant seem to access the modbrowser to any extent, in the latest release, it doesnt show anything, and if i load older ones it just crashes terraria - Is there any setup needed to use the Mod Browser?
 
I cant seem to access the modbrowser to any extent, in the latest release, it doesnt show anything, and if i load older ones it just crashes terraria - Is there any setup needed to use the Mod Browser?
Currently the mod browser is offline and awaiting fix.
[doublepost=1487440064,1487439476][/doublepost]
Hmmm, do you think you can make it such that we can see when was the mod last updated by us with a date? Oh yeah, good job on this, modding made easy for Terraria players.
Do you mean filtering mods based on their update date in the mod browser?
[doublepost=1487440131][/doublepost]
I've narrowed the pick up glitch (for me) down to either basic elemtal additions or elemental weapon enhancements, idk about the projectiles yet
Yeah don't use EWE (elemental weapon enhancements) I haven't touched it in a long time now lol.
[doublepost=1487440257][/doublepost]
I am trying to make a fruit that when you eat it i get a debuff saying i am full and i also want it to heal 35 life. how would i make that happen? (i also want to not be able to eat the fruit if the full debuff is active)
To heal you could set item.heal = 35 in its SetDefaults, you can do player.AddBuff() in the UseItem hook to add your buff.
 
can some one help me make this NPC spawn in a certain biome/ every time i try it says:


c:\Users\Student\Documents\My Games\Terraria\ModLoader\Mod Sources\Trelamium\NPCs\Spectre\SpectreEye.cs(43,24) : error CS0029: Cannot implicitly convert type 'bool' to 'float'
and heres the code:

using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Trelamium.NPCs.Spectre
{
public class SpectreEye : ModNPC
{
public override void SetDefaults()
{
npc.name = "SpectreEye";
npc.displayName = "Spectre Eye";
npc.width = 32;
npc.height = 22;
npc.damage = 30;
npc.defense = 6;
npc.lifeMax = 90;
npc.HitSound = SoundID.NPCHit1;
npc.DeathSound = SoundID.NPCDeath1;
npc.value = 60f;
npc.knockBackResist = 0.3f;
npc.aiStyle = 2;
Main.npcFrameCount[npc.type] = Main.npcFrameCount[NPCID.DemonEye];
aiType = NPCID.DemonEye;
animationType = NPCID.DemonEye;
}
public override void HitEffect(int hitDirection, double damage)
{
if (npc.life <= 0)
{
Gore.NewGore(npc.position, npc.velocity, mod.GetGoreSlot("Gores/Spectre/EyeGore1"), 1f);
}
}

public override float CanSpawn(NPCSpawnInfo spawnInfo)
{
if (Main.hardMode == true)
{
return 1f;
}
else if (Main.hardMode == false)
{
return false;
}
}
}
}
 
i had that mod installed and i deleted it. my game now works. THANK YOU OH SO MUCH!
I am very glad to help lol, and I think the mod that caused projectiles not to work was imksushi but I'm not positive.
[doublepost=1487475435,1487475344][/doublepost]
Where exactly are stored the mods that you install?
On windows go, My documents > my games > Terraria and it should have a mods folder
[doublepost=1487475573][/doublepost]
Currently the mod browser is offline and awaiting fix.
[doublepost=1487440064,1487439476][/doublepost]
Do you mean filtering mods based on their update date in the mod browser?
[doublepost=1487440131][/doublepost]
Yeah don't use EWE (elemental weapon enhancements) I haven't touched it in a long time now lol.
[doublepost=1487440257][/doublepost]
To heal you could set item.heal = 35 in its SetDefaults, you can do player.AddBuff() in the UseItem hook to add your buff.
You should really update ewe and it's counterpart, they were one of my favorite mods
 
Back
Top Bottom