tModLoader Official tModLoader Help Thread

Makes sense to me. I'll test that as soon as I can, but until then, how would I go about setting the aimPos in other clients? I get the feeling that it's just never updated for others, but I don't know how I'd do that. aimPos is set in a class named ChooPlayer, extending ModPlayer and only contains a public Vector2 aimPos. This is how I update the aimPos in my weapon using right click:

Code:
public override bool UseItem(Player player)
        {
            if (player.altFunctionUse == 2)
            {
                if (player.Equals(Main.player[Main.myPlayer]))
                ((PlayerInfo.ChooPlayer)player.GetModPlayer(mod, "ChooPlayer")).aimPos = Main.MouseWorld;

                ...
                *fancify*
                ...
                return true;
            } else
            {
                return base.UseItem(player);
            }
        }
I suspected that you were using Main.MouseWorld. See, each client only knows the MouseWorld coordinates for their own player, not any other player. So you'll need to send those coordinates yourself. The easiest way is to use the projectiles AI array, though you'll need to use both slots.

However, I don't think that the item has direct access to the projectile it's just shot. You could manually spawn your projectile in your item's Shoot hook and set your coords to your AI there, but I think it would be easier to get the info you need from directly in the projectile itself. Something like the following should work. ( havn't tested it, but I think it'll work)
Code:
        bool doOnce = false;
        public override bool PreAI()
        {
            if (doOnce == false) //will only happen once
            {
                doOnce = true;
                if (Main.myPlayer == projectile.owner && Main.netMode == 1) //only on the client of the owner of this projectile
                {
                    projectile.ai[0] = Main.MouseWorld.X; //set values
                    projectile.ai[1] = Main.MouseWorld.Y;
                    NetMessage.SendData(27, -1, -1, "", projectile.whoAmI); //update this projectile for all clients
                }
            }

            return true;      
        }
Then you can retrieve Main.MouseWorld.X and .Y from projectile.ai[0] and [1] on clients.

The problem with this is that it will be messed up if you want to use the AI array for something else, so your would need to copy those coords out to a Vector2 on clients in a similar way.

----------------------------------------------
Thanks for helping me out with the TagCompound part :D Save() is returning a new TagCompound which looks like this in the example mod:

Code:
public override TagCompound Save(Item item)
{
    return new TagCompound {

             {"score", score}
         };
}

In contrast to this, Load() requires a TagCompound. Now i have two questions. First, can you return a TagCompound which contains multiple values like:

Code:
public override TagCompound Save(Item item)
{
    return new TagCompound {

             {"value1", value1}, {"value2", value2}
         };
}

Second, Load(Item item, TagCompound tag) requires a TagCompound to load the information. But how do i know the identifier of the TagCompound where my data is stored? Because Save() is just returning a TagCompound and i cant see an identifier there. Would it be "score" so i would have to call Load(item, "score")? :confused:
Thanks for your advice

Edit: Dont get me wrong, my goal is to save some values for specific items, which get loaded when you restart the game. But is this even the right way of doing it? Because
as I understood it know, save() works like this:
Code:
TagCompound tag = Save(item);
and then you load it with Load(item, tag). But that doesnt help me with saving the information above the lifespan of the game instance, so you can load them in a new game instance again.
I just ran a quick test on a mod player, and the following seemed to work. I can't see any need for (Item item) in the hook declaration line.
Code:
        int myInt = 0;
        float myFloat = 0;
        public override TagCompound Save()
        {
            return new TagCompound {
                {"text1", myInt},
                {"text2", myFloat}
            };
        }

        public override void Load(TagCompound tag)
        {
            myInt = tag.GetInt("text1");
            myFloat = tag.GetFloat("text2");
        }
It doesn't really matter what you call the tag, as long as you use the same tag to load a value as you saved it with. I'm afraid I don't know what you mean by 'the lifespan of the game instance.'

------------------------------------------------------
Im sorry but there's 171 pages of comments so I dont know if this has been addressed before or not, but when moving player and world files from Vanilla to tmod both the player and world are unusable. I'm unsure if anyone has gotten it to work but I would really appreciate help on this. I apologize if this isnt the correct thread to ask, if so please redirect me?
Normally what you've done would work. The problem is that saves from 1.3.5.x won't work in tModLoader because it's still at 1.3.4.4. Once tMod catches up, you'll be able to transfer saves both ways again.
 
I just ran a quick test on a mod player, and the following seemed to work. I can't see any need for (Item item) in the hook declaration line.
Code:
        int myInt = 0;
        float myFloat = 0;
        public override TagCompound Save()
        {
            return new TagCompound {
                {"text1", myInt},
                {"text2", myFloat}
            };
        }

        public override void Load(TagCompound tag)
        {
            myInt = tag.GetInt("text1");
            myFloat = tag.GetFloat("text2");
        }
It doesn't really matter what you call the tag, as long as you use the same tag to load a value as you saved it with. I'm afraid I don't know what you mean by 'the lifespan of the game instance.'

I am sorry that I've asked you for such a stupid favor, i should have tested this myself :rolleyes: just realized it :sigh:

By "lifespan of the game instance" i meant the time the game is running until the player returns to the main menu. I want to store data for individual items like Terraria does with the prefixes for weapons. E.g if you reforge an item in Terraria it gets a new prefix. It keeps this prefix forever - even if you exit the game - or until you reforge it again.

I want to do the exact same thing just instead of a prefix it should save my values for the item, like a higher damage value for example.

I would appreciate any help :(
 
When i downloaded the tmodloader for windows and i pasted it in to the terraria folder but when i opened terraria there was no "mod" selection so i went to this video
and skiped aps half way where he started to show to use tmodloader and in his download he had that cup of tea icon which i didnt have in my download. plz help
 
I am sorry that I've asked you for such a stupid favor, i should have tested this myself :rolleyes: just realized it :sigh:

By "lifespan of the game instance" i meant the time the game is running until the player returns to the main menu. I want to store data for individual items like Terraria does with the prefixes for weapons. E.g if you reforge an item in Terraria it gets a new prefix. It keeps this prefix forever - even if you exit the game - or until you reforge it again.

I want to do the exact same thing just instead of a prefix it should save my values for the item, like a higher damage value for example.

I would appreciate any help :(
Ok, I see what you mean. So you now know how to save a value to an item across play sessions, and you want to know how to increase it's stats by an amount that you've saved.

The easiest way to increase the damage would be to use the OnHitNPC (and OnHitPlayer) to multiply the damage by the value you are saving. (Which ideally would be a float with a default value of 1.) The disadvantage to this is that it won't update the damage value in your inventory.

Another way would be to use the HoldItem hook to increase the damage value. It will update the value in your inventory, but it's more hacky. Here's an example of what I mean.
Code:
        //I'm assuming that the base damage is 20
        int damageModifier = 10;
        //OR
        float damageMultiplier = 1.5f;
        public override void HoldItem(Player player)
        {
            item.damage = 20 + damageModifier; //add your modified value to damage
            //OR
            item.damage = (int)(20f * damageMultiplier); //multiply damage by your multiplier
        }
I hope this helps.
 
Ok, I see what you mean. So you now know how to save a value to an item across play sessions, and you want to know how to increase it's stats by an amount that you've saved.
I hope this helps.

I know how to increase it's stats by an amount i've saved, but i dont know how to save a value to an item across play sessions :D
 
I know how to increase it's stats by an amount i've saved, but i dont know how to save a value to an item across play sessions :D
Didn't this work for you?
Code:
        int myInt = 0;
        float myFloat = 0;
        public override TagCompound Save()
        {
            return new TagCompound {
                {"text1", myInt},
                {"text2", myFloat}
            };
        }

        public override void Load(TagCompound tag)
        {
            myInt = tag.GetInt("text1");
            myFloat = tag.GetFloat("text2");
        }
 
How can I increase throwing speed through an armor bonus like player.meleeSpeed += 0.1f;
But with throwing speed?
player.throwingSpeed... Doesn't work
Nor does player.thrownSpeed.
 
How can I increase throwing speed through an armor bonus like player.meleeSpeed += 0.1f;
But with throwing speed?
player.throwingSpeed... Doesn't work
Nor does player.thrownSpeed.
You would need to make your own custom variable for player in your ModPlayer.
 
Alright, so I was working on my mod's ExamplePlayer thingy and I ended up getting this "error CS1002: expected". Here's what I have in the ExamplePlayer:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;

namespace SomeExtraStuff
{
public class ExamplePlayer : ModPlayer
{
private const int saveVersion = 0;
public bool minionName = false;
public bool Pet - false;
public static bool hasProjectile;

public override void ResetEffects();
{
minionName = false;
Pet - false;
}
}
 
Last edited:
Didn't this work for you?
Code:
        int myInt = 0;
        float myFloat = 0;
        public override TagCompound Save()
        {
            return new TagCompound {
                {"text1", myInt},
                {"text2", myFloat}
            };
        }

        public override void Load(TagCompound tag)
        {
            myInt = tag.GetInt("text1");
            myFloat = tag.GetFloat("text2");
        }

No it worked , but it didn't solve my problem. How do I save values to an item across play sessions with that? I still don't know how to use these functions correctly nor do i know if they even can save values across play sessions :sigh:Did you ever saved values across play sessions yourself? If so, could you tell me which functions you have used and how to use them? If not I realy thank you for your help, but I think I should ask someone else who might has some experience with saving across play sessions then.:D
 
Alright, so I was working on my mod's ExamplePlayer thingy and I ended up getting this "error CS1002: expected". Here's what I have in the ExamplePlayer:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;

namespace SomeExtraStuff
{
public class ExamplePlayer : ModPlayer
{
private const int saveVersion = 0;
public bool minionName = false;
public bool Pet - false;
public static bool hasProjectile;

public override void ResetEffects();
{
minionName = false;
Pet - false;
}
}
You have "-" instead of "="
 
No it worked , but it didn't solve my problem. How do I save values to an item across play sessions with that? I still don't know how to use these functions correctly nor do i know if they even can save values across play sessions :sigh:Did you ever saved values across play sessions yourself? If so, could you tell me which functions you have used and how to use them? If not I realy thank you for your help, but I think I should ask someone else who might has some experience with saving across play sessions then.:D
That is how you save values across play sessions. If you were to change one of those values in the example I gave you, then quit and reload, it would still be what you changed it to. You just need to use the value that you want to save instead of the ones that I used in my example.
 
Back
Top Bottom