tModLoader Shorter Respawn Time

Discussion in 'Released' started by jopojelly, Jul 2, 2016.

  1. jopojelly

    jopojelly Retinazer

    [​IMG]
    Shorter Respawn

    Latest Download:
    Mod Browser (in-game) - Direct link - Alt download link
    Open source on GitHub


    This mod has been available for a while, but I decided to make a thread for it as it will be a useful example for both teaching how to integrate with both HERO's Mod and Cheat Sheet and teaching how to make a simple single purpose mod.

    This mod, when used alone, brings the Expert mode respawn time down to a much less annoying time, more inline with non-expert mode:
    Non-Expert: 10 seconds
    Non-Expert Boss: 20 seconds
    Expert: 11.25 seconds (down from 15 seconds)
    Expert Boss: 22.5 seconds (down from 30 seconds)

    When used in conjunction with HERO's Mod, an additional "cheat" option is available to players in the Extension Tools menu, provided they have the permissions given to them from the server admin:
    [​IMG]
    When used in conjunction with Cheat Sheet, a similar option is available.

    This cheat, when toggled on, reduces the respawn time to 0 (instant!), which, if you die a whole lot, as you most likely will in Expert mode, (and especially if you are playing with 30x boosted spawn rates....) is a great time saver.

    Here is the cheat setting in action (0 seconds as opposed to the reduced time if this mod is used without Cheat Sheet or HEROs Mod):

    The Code/Tutorial
    The remainder of this thread will detail the whole mod. I've commented the source code to serve as an example of integrating with HERO's/Cheat Sheet, as I hope an example like this will help motivate other modders to code up Extension Tools for HEROs and Cheat Sheet.

    ShorterRespawn.cs
    Code:
    using Terraria.ModLoader;
    using Terraria;
    using System;
    
    namespace ShorterRespawn
    {
        public class ShorterRespawn : Mod
        {
            // A true/false value we'll use for the "cheat" functionality of this mod.
            internal bool instantRespawn = false;
    
            public ShorterRespawn()
            {
                Properties = new ModProperties()
                {
                    Autoload = true, // We need Autoload to be true so our ModPlayer class below will be loaded.
                };
            }
    
            // We integrate with other mods in PostSetupContent.
            public override void PostSetupContent()
            {
                try
                {
                    Mod cheatSheet = ModLoader.GetMod("CheatSheet");
                    Mod herosMod = ModLoader.GetMod("HEROsMod");
                    // Prefer Heros Mod
                    if (herosMod != null)
                    {
                        //ErrorLogger.Log("Integrating with HEROs Mod");
                        SetupHEROsModIntegration(herosMod);
                    }
                    // If Heros isn't available, try ChearSheet
                    else if (cheatSheet != null)
                    {
                        //ErrorLogger.Log("Integrating with Cheat Sheet");
                        SetupCheatSheetIntegration(cheatSheet);
                    }
                    else
                    {
                        //ErrorLogger.Log("No Integration");
                    }
                }
                catch (Exception e)
                {
                    ErrorLogger.Log("ShorterRespawn PostSetupContent Error: " + e.StackTrace + e.Message);
                }
                instantRespawn = false;
            }
    
            // This is the old, not-so-convenient way of doing things, using the Mod.Call method.
            private void SetupCheatSheetIntegration(Mod cheatSheet)
            {
                if (!Main.dedServ)
                {
                    // "AddButton_Test" is a special string, in the future, other strings could represent different types of buttons or behaviors
                    cheatSheet.Call(
                        "AddButton_Test",
                        GetTexture("InstantRespawnButton"),
                        (Action)InstantRespawnButtonPressed,
                        (Func<string>)InstantRespawnTooltip
                    );
                }
                instantRespawn = false;
            }
    
            // The New way in 0.8.2.2
            /*
            private void SetupCheatSheetIntegration(Mod cheatSheet)
            {
                ((CheatSheet.CheatSheet)cheatSheet).RegisterButton(GetTexture("InstantRespawnButton"), InstantRespawnButtonPressed, InstantRespawnTooltip);
            }
            */
    
            private void SetupHEROsModIntegration(Mod herosMod)
            {
                // Add Permissions always.
                herosMod.Call(
                    // Special string
                    "AddPermission",
                    // Permission Name
                    "ModifyPersonalRespawnTime",
                    // Permission Display Name
                    "Modify Personal Respawn Time"
                );
                // Add Buttons only to non-servers (otherwise the server will crash, since textures aren't loaded on servers)
                if (!Main.dedServ)
                {
                    herosMod.Call(
                        // Special string
                        "AddSimpleButton",
                        // Name of Permission governing the availability of the button/tool
                        "ModifyPersonalRespawnTime",
                        // Texture of the button. 38x38 is recommended for HERO's Mod. Also, a white outline on the icon similar to the other icons will look good.
                        GetTexture("InstantRespawnButton"),
                        // A method that will be called when the button is clicked
                        (Action)InstantRespawnButtonPressed,
                        // A method that will be called when the player's permissions have changed
                        (Action<bool>)PermissionChanged,
                        // A method that will be called when the button is hovered, returning the Tooltip
                        (Func<string>)InstantRespawnTooltip
                    );
                }
            }
    
            // This method is called when the cursor is hovering over the button in Heros mod or Cheat Sheet
            public string InstantRespawnTooltip()
            {
                return instantRespawn ? "Disable Instant Respawn" : "Enable Instant Respawn";
            }
    
            // This method is called when the button is pressed using Heros mod or Cheat Sheet
            public void InstantRespawnButtonPressed()
            {
                instantRespawn = !instantRespawn;
            }
    
            // This method is called when Permissions change while using HERO's Mod.
            // We need to make sure to disable instantRespawn when we are no longer allowed to use the tool.
            public void PermissionChanged(bool hasPermission)
            {
                if (!hasPermission)
                {
                    instantRespawn = false;
                }
            }
        }
    
        // This class is the actual mod code that reduces the respawn timer when the player dies.
        public class ShorterRespawnPlayer : ModPlayer
        {
            public override void Kill(double damage, int hitDirection, bool pvp, string deathText)
            {
                // If we are cheating
                if ((mod as ShorterRespawn).instantRespawn)
                {
                    player.respawnTimer = 0;
                    return;
                }
                // otherwise, if we just want the time reduced to a more typical level
                if (Main.expertMode)
                {
                    player.respawnTimer = (int)(player.respawnTimer * .75);
                }
            }
        }
    }
    
    build.txt
    Code:
    author = jopojelly
    version = 0.2.2
    displayName = Shorter Respawn Time
    homepage = http://forums.terraria.org/index.php?threads/shorter-respawn-time.45962/
    hideCode = false
    hideResources = false
    includeSource = true
    //weakReferences = [email protected]   -- This is a 0.8.2.2 feature.
    InstantRespawnButton.png
    InstantRespawnButton.png
    description.txt
    Code:
    Cuts the respawn time after death in Expert Mode to be much closer to Normal Mode times.
    
    When used in conjunction with either HERO's Mod or Cheat Sheet, an toggle button for instant respawns becomes available in the respective menus. When both are loaded, HERO's mod will take precedence since integration with HERO's mod allows for use of the permissions system.
    BTW, the specific respawn time adjustments and the idea for this mod came from @Applevac

    [​IMG]
     
    Last edited: Oct 1, 2018
    Tsintzask, Yune, Flashkirby99 and 4 others like this.
  2. burning_pixel

    burning_pixel Spazmatism

    Could you maybe make another version of the mod where the respawn time from normal mode is also reduced? I'm not that much into modding so I don't know what I would have to change to apply it to normal mode too.
     
  3. jopojelly

    jopojelly Retinazer

    Shorter Respawn Time has been updated to 0.2.3 to show off how to utilize "Weak References" in tModLoader mods.

    Weak References is a method of providing tighter integration with other mods without a strong dependency. For example, prior to tModLoader 0.8.3, interfacing with other mods fell into 2 categories:
    1. A strong reference meaning a parent-child relationship, the child mod could only be loaded if the parent mod was also loaded. This prevented the child mod from being used alone, but it allowed simple access to methods and variables exposed publicly by the parent mod.
    2. A non-existent reference meaning no relationship other than blind interaction through Mod.Call method invocations. This is extremely error prone and not as capable.
    Now, with Weak References, a mod can interface with another mod in a rich manner while avoiding the restrictions imposed by the parent-child relationship.

    Basically it works like this:

    In build.txt, we reference the version of the mod that we are working against:
    Code:
    weakReferences = [email protected]
    Then, we get the Windows.dll from the .tmod file that we wish to interface with by using tModReader and add it as a reference in Visual Studio or your IDE of choice. (Note that hideCode needs to be false or the modder must provide the dll elsewhere.)
    [​IMG]


    Now that the other mod is referenced, we have access to all public variables and methods:
    [​IMG]

    With Cheat Sheet (0.2.5.4 and up) as an example, we can easily add a button to the Mod Extension Menu:
    Code:
    CheatSheet.CheatSheetInterface.RegisterButton(cheatSheet, GetTexture("InstantRespawnButton"), InstantRespawnButtonPressed, InstantRespawnTooltip);
    Note that the same can be done with a strong reference (having "modReferences = CheatSheet" in build.txt), but this method allows the mod to be loaded whether or not Cheat Sheet is loaded or not.

    On the Cheat Sheet side of things, I made everything private or internal except the methods I wanted other modders to see. In this case, I have only exposed this class and method so modders can add buttons:
    Code:
        public static class CheatSheetInterface
        {
            public static void RegisterButton(Mod mod, Texture2D texture, Action buttonClickedAction, Func<string> tooltip)
            {
                if (!Main.dedServ && mod != null && mod is CheatSheet)
                {
                    ((CheatSheet)mod).RegisterButton(texture, buttonClickedAction, tooltip);
                }
            }
        }
    Hopefully this little example will prove useful to others seeking more flexibility in cross-mod integration. The github has been updated so the full code can be studied.

    I'm happy to help you choose what approach you should take towards mod integration.

    Also, attached is the dll so you can test it if you want.
     

    Attached Files:

  4. Redball

    Redball Golem

    Nice litle mod. Saves time to actually play the game:passionate:
     
  5. ImMadNow

    ImMadNow Terrarian

    Mega cancer.
     
  6. Aurora3500

    Aurora3500 Moderator Staff Member Moderator

    @ImMadNow

    If you have nothing to say that helps the Mod Developer to constructively improve their Mod, or to give feedback and discuss this Mod, you are better off not posting.

    Please be respectful when you post. If you think this Mod isn't good, give your reasoning why it isn't good or why you don't support it. Posts such as this don't help anyone.
     
    Tyfyter, CatNoir and Lunatic Lobbyist like this.
  7. HyperHamster

    HyperHamster Terrarian

    Could you please attach the tML v0.9.2.3 version; or indicate whether or not this will work with tML v0.9.2.3?
     
  8. Sword Ace

    Sword Ace The Destroyer

    This is an extremely useful mod for practicing challenges. The time saved really adds up.

    One feature I hope you could add, if it's possible in tModLoader, would be the ability to save the instant respawn time setting when the mod is being used in conjunction with Hero's Mod. It would be very useful to not have to enable instant respawn time every time I start up the game, especially since the UI of Hero's mod is bugged when the GUI zoom is set to higher than 100%. Currently, when I have the UI of Terraria set to 150% and I try to enable instant respawn time, the option does not appear. I have to set the UI zoom to 100% in order for it to appear. Then, once I enable the instant respawn time, there's no way for me to set the game's UI zoom back to precisely 150% without closing the game to set the UI scale to 1.5 in the config.json file. Then, when I re-open the game the instant respawn setting is off again.