northwood-studios/NwPluginAPI

About HP & AHP

Closed this issue · 4 comments

I want to change the value Player.Health to make the character look more durable. However, the damage calculation is affected by Player.MaxHealth. This performance is reflected in the same way as Player.ArtificialHealth. The damage is not calculated according to the set value. Pls how should I implement custom role HP, AHP management. Thanks.

Create a custom Player something like this

 public class CerberusPlayerFactory : PlayerFactory
    {
        public override Type BaseType { get; } = typeof(CerberusPlayer);
        public override Player Create(IGameComponent component) => new CerberusPlayer(component);
    }
 /// <summary>
  /// Represents a custom player.
  /// Extends the base Player class.
  /// </summary>
  public class CerberusPlayer : Player
  {
      private CustomHealthStat healthStat; // Player's custom health stats.
      private CustomStaminaStat staminaStat; // Player's custom stamina stats.

      /// <summary>
      /// Gets a list of all <see cref="CerberusPlayer"/> in the server.
      /// </summary>
      public static List<CerberusPlayer> List = new();

      /// <summary>
      /// Constructor for CerberusPlayer class.
      /// Initializes a new instance of CerberusPlayer.
      /// </summary>
      /// <param name="component">The game component associated with the player.</param>
      public CerberusPlayer(IGameComponent component) : base(component)
      {
          // Assigning custom health statistics to the player.
          healthStat = new CustomHealthStat { Hub = ReferenceHub };
          ReferenceHub.playerStats._dictionarizedTypes[typeof(HealthStat)] = ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = healthStat;

          // Assigning custom stamina statistics to the player.
          staminaStat = new CustomStaminaStat { Hub = ReferenceHub };
          ReferenceHub.playerStats._dictionarizedTypes[typeof(StaminaStat)] = ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(StaminaStat))] = staminaStat;

          // Initialize the stamina statistics for the player.
          staminaStat.Init(ReferenceHub);

          // Initialize the health statistics for the player.
          healthStat.Init(ReferenceHub);

          if(!List.Contains(this))
              List.Add(this);
      }
      
      
      /// <summary>
      /// Gets or sets the player's maximum health.
      /// </summary>
      public new float MaxHealth
      {
          get => healthStat.MaxValue;
          set => healthStat.CustomMaxValue = value;
      }

      /// <summary>
      /// Gets or sets the player's health.
      /// If the health is greater than the <see cref="MaxHealth"/>, the MaxHealth will also be changed to match the health.
      /// </summary>
      public new float Health
      {
          get => healthStat.CurValue;
          set
          {
              if (value > MaxHealth)
                  MaxHealth = value;

              healthStat.CurValue = value;
          }
      }

Note you need to Register un playerfactory in the EntroyPoint of the plugin

        [PluginPriority(LoadPriority.Lowest)]
        [PluginEntryPoint("Cerberus.Tweaks", Version, "Plugin principal de Cerberus", "SrLicht & Imurx")]
        public void OnEnabled()
        {
            Instance = this;

            if (!Config.IsEnabled)
            {
                Log.Warning($"Cerberus.Tweaks is disabled by config.");
                return;
            }
             FactoryManager.RegisterPlayerFactory(this, new CerberusPlayerFactory());
          }

and you just need to use

var cbPlayer = CerberusPlayer.Get(Player);
cbPlayer.MaxHealth= 9999

You need to implement your own GET methods

imagen

image

Question01: My compiler tells me that some methods are inaccessible. Is it my PluginAPI.dll version issue? This is taken from Steam.

Question02: Can I see the code content in CustomHealthStat? I don't know if it's a direct inheritance? PlayerStatsSystem.Health

Question03: I want to override SPC-106's health and maxHealth instead of the game character defaults. Is this the only way to do it?

Thanks again for the answer.

  public class CerberusPlayer : Player
  {
      private CustomHealthStat healthStat; // Player's custom health stats.

      /// <summary>
      /// Constructor for CerberusPlayer class.
      /// Initializes a new instance of CerberusPlayer.
      /// </summary>
      /// <param name="component">The game component associated with the player.</param>
      public CerberusPlayer(IGameComponent component) : base(component)
      {
          // Assigning custom health statistics to the player.
          healthStat = new CustomHealthStat { Hub = ReferenceHub };
          ReferenceHub.playerStats._dictionarizedTypes[typeof(HealthStat)] = ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = healthStat;

          // Initialize the health statistics for the player.
          healthStat.Init(ReferenceHub);
      }

image

Question01: My compiler tells me that some methods are inaccessible. Is it my PluginAPI.dll version issue? This is taken from Steam.

Question02: Can I see the code content in CustomHealthStat? I don't know if it's a direct inheritance? PlayerStatsSystem.Health

Question03: I want to override SPC-106's health and maxHealth instead of the game character defaults. Is this the only way to do it?

Thanks again for the answer.

  public class CerberusPlayer : Player
  {
      private CustomHealthStat healthStat; // Player's custom health stats.

      /// <summary>
      /// Constructor for CerberusPlayer class.
      /// Initializes a new instance of CerberusPlayer.
      /// </summary>
      /// <param name="component">The game component associated with the player.</param>
      public CerberusPlayer(IGameComponent component) : base(component)
      {
          // Assigning custom health statistics to the player.
          healthStat = new CustomHealthStat { Hub = ReferenceHub };
          ReferenceHub.playerStats._dictionarizedTypes[typeof(HealthStat)] = ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = healthStat;

          // Initialize the health statistics for the player.
          healthStat.Init(ReferenceHub);
      }

Sorry I was busy.

  1. You have to enable the non-secure code in visual studio. You have to use Assembly-CSharp-Publicized.dll instead of Assembly-CSharp.dll, ask on discord server they will be better to answer that.

 /// <summary>
    /// A custom version of <see cref="HealthStat"/> which allows the player's max amount of health to be changed.
    /// </summary>
    public class CustomHealthStat : HealthStat
    {
        /// <inheritdoc/>
        public override float MaxValue => CustomMaxValue == default ? base.MaxValue : CustomMaxValue;

        /// <summary>
        /// Gets or sets the maximum amount of health the player will have.
        /// </summary>
        public float CustomMaxValue { get; set; }
    }
  1. Yes this would work for that, an example
public void OnRoleChanged(PlayerChangeRole ev)
{
   // This will make only the change affect Scp106 and if CerberusPlayer is successfully extracted from the reference hub
   if(ev.NewRole != RoleType.Scp106 || CerberusPlayer.TryGet(ev.Player, out CerberusPlayer cb))
     return;

     cb.MaxHealth = 999999;
}

Thanks for your patience, I've been able to get SCP-106 strong again :)