Untitled

 avatar
unknown
plain_text
a year ago
8.5 kB
8
Indexable
public class BleedEffect
{
    public int InitialDamage { get; set; }
    public int DamageIncreasePerSecond {get; set;}
    public string DamageType {get; set; }
    public DateTime StartTime { get; set; }
    public MobileEntity _source;

    public BleedEffect(int initialDamage, int damageIncreasePerSecond, MobileEntity source, string damageType)
    {
        InitialDamage = initialDamage;
        DamageIncreasePerSecond = damageIncreasePerSecond;
        StartTime = DateTime.Now;
        DamageType = damageType;
        _source = source;
    }

    public int CurrentDamage()
    {
        var elapsed = DateTime.Now - StartTime;
        var elapsedTicks = elapsed.TotalSeconds; 

        var currentDamage = InitialDamage - elapsedTicks;
        return (int)Math.Max(currentDamage, 0);
    }
    
    
}

public class BleedStatusEffect
{
    private static object _lock = new object();
    private static Timer _timer;
    
    public static void ApplyBleedEffect(MobileEntity target, MobileEntity source, int initialDamage, string damageType = "Health")
    {
        if (target is null || source is null)
        {
            return;
        }
      
        lock (_lock)
        {         
            if (!BleedEffects.ContainsKey(target))
            {
                BleedEffects[target] = new List<BleedEffect>();
            }
    
            // Only add a new BleedEffect if there are less than 3 for the target
            if (BleedEffects[target] != null && BleedEffects[target].Count < 3)
            {
                BleedEffects[target].Add(new BleedEffect(initialDamage,0,source,damageType));
            }
   
         }
         
            // Start the timer if it's not already running, it turns off when it's not needed.
            if (_timer is null || !_timer.Running)
            {
                _timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), 86400, GameTick);
            }
    }
    public static void ApplyIncreasingBleedEffect(MobileEntity target, MobileEntity source, string damageType = "Increasing")
    {
        lock (_lock)
        {
            if (!BleedEffects.ContainsKey(target))
            {
                BleedEffects[target] = new List<BleedEffect>();
            }

            // Check if there is an existing increasing bleed effect
            if (!BleedEffects[target].Any(x => x.DamageIncreasePerSecond > 0))
            {
                // Add a new BleedEffect with initial damage of 0 and damage increase per second of 1
                BleedEffects[target].Add(new BleedEffect(0, 1, source, damageType));
            }
        }

        // Start the timer if it's not already running
        if (_timer is null || !_timer.Running)
        {
            _timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), 86400, GameTick);
        }
    }
    
    public static void ApplyBleedDamage(MobileEntity player, MobileEntity source, int damage, string damageType = "Health")
    {
       try
       {
       
           if (player is null || damage <= 0 || source is null)
            {
               return;  
            }
            
            if (!player.IsAlive && BleedEffects.ContainsKey(player))
                BleedEffects[player].Clear();
          
            switch (damageType)
            {
                case "Health":
                if (player.IsAlive)
                {
                    player.RegisterIncomingDamage(source, damage, true);
                    if (source is not null)
                        source.RegisterOutgoingDamage(player, damage, true);    
                    player.ApplyDamage(source, damage);
                    
                    if (player is PlayerEntity && (_timer.Count % 3) == 0)
                        player.SendMessage(Color.Yellow,$"You have taken damage from your bleeding wounds.");
                }
                return;
                case "Mana":
                player.Mana -= damage;
                return;
                case "Stamina":
                player.Stamina -=damage;
                return; 
                case "Increasing":
                if (player.IsAlive)
                {
                    player.RegisterIncomingDamage(source, damage, true);
                    if (source is not null)
                        source.RegisterOutgoingDamage(player, damage, true);    
                    player.ApplyDamage(source, damage);
                    
                    if (player is PlayerEntity && (_timer.Count % 3) == 0)
                    {
                        var playersAround = player.GetBeheldInLOS(1).OfType<PlayerGroup>().SelectMany(x => x.Members).ToList();

                        if (damage <= 10)
                            player.SendMessage(Color.Yellow,$"You cough, and shiver... maybe you're getting sick.");
                        else if (damage > 10 && damage <= 25)
                            player.SendMessage(Color.Yellow,$"You shiver uncontrollably, sweat pours from your brow.");
                        else if (damage > 25 && damage <= 50)
                        {
                            player.SendMessage(Color.Yellow,$"You vomit uncontrollably.");
                            foreach (var friend in playersAround)
                            {
                                if (friend != null &&friend.IsAlive)
                                    BleedStatusEffect.ApplyIncreasingBleedEffect(friend,player);
                            }
                        }   
                        else if (damage > 50)
                        {
                            player.SendMessage(Color.Yellow,$"You are bleeding uncontrollably from every orifice.");
                            foreach (var friend in playersAround)
                            {
                                if (friend != null &&friend.IsAlive)
                                    BleedStatusEffect.ApplyIncreasingBleedEffect(friend,player);
                            }
                        }    
                    }
                }
                return;
            }
        }
        catch (Exception ex)
        {
            if (source is PlayerEntity)
            source.SendMessage(Color.Red,$"Debug: {ex.ToString()}.");
            
            if (player is PlayerEntity)
            player.SendMessage(Color.Red,$"Debug: {ex.ToString()}.");
        }
    }
    
    public static void CureBleed(MobileEntity player)
    {
        if (BleedEffects is null || player is null)
            return;
        
        if (BleedEffects.ContainsKey(player))
        {
            BleedEffects[player].Clear();
        }
    }
    public static void GameTick()
    {
       
        lock (_lock)
        {
            foreach (var playerEffects in BleedEffects)
            {
                if (playerEffects.Key is null || !playerEffects.Key.IsAlive || playerEffects.Value is null)
                {
                    continue;
                }
                
                foreach (var effect in playerEffects.Value)
                {
                    if (playerEffects.Key is null || effect._source is null || effect is null)
                        continue;
                    
                    if (effect.DamageIncreasePerSecond > 0)
                    {
                        effect.InitialDamage += effect.DamageIncreasePerSecond;
                        ApplyBleedDamage(playerEffects.Key,effect._source,effect.InitialDamage);
                    }
                    else
                        ApplyBleedDamage(playerEffects.Key,effect._source,effect.CurrentDamage());
                }
    
    
                playerEffects.Value.RemoveAll(effect => effect.CurrentDamage() <= 0);
                
                if (BleedEffects.All(kvp => kvp.Value.Count == 0))
                {  
                    _timer.Stop();
                    _timer = null;
                }
            }
        }
    }
    
    public static bool HasBleedStatus(MobileEntity entity, out List<BleedEffect> bleedStatus)
    {
        if (BleedEffects.ContainsKey(entity))
        {
            bleedStatus = BleedEffects[entity];
            return true;
        }
        else
        {
            bleedStatus = null;
            return false;
        }
    }
}
Editor is loading...
Leave a Comment