Integration & Compatibility - LeandroTheDev/level_up GitHub Wiki

Introduction

In this section there will be explanations of the classes, events and examples available for you to integrate your mod with LevelUP

LevelUP works mostly on server side, and all events should be running on the EnumAppSide.Server, for security porpuses

Functions will generally have a reference number, so you can easily change and modify the numbers as you wish

Starting: Create your own mod and import the LevelUP.dll in the mod csproj

<ItemGroup>
    <Reference Include="LevelUP">
      <HintPath>$(VINTAGE_STORY)/Mods/LevelUP/LevelUP.dll</HintPath>
      <Private>false</Private>
    </Reference>
  </ItemGroup>

Now you have access to the LevelUP Events, check below

LevelUP.Server.ExperienceEvents

  • OnExperienceIncrease
  • Player receives experience, amount is a reference you can modify it to increase or decrease the quantity received

  • OnExperienceSubIncrease
  • Player receives sub experience, amount is a reference you can modify it to increase or decrease the quantity received

  • OnExperienceReduced
  • Player losed experience, amount is a reference you can modify it to increase or decrease the quantity received

  • OnLevelUp
  • Player leveled up, if is a sublevel that leveled up the type variable will come with a "/": "Smithing/Knife"

LevelUP.Shared.OverwriteDamageInteractionEvents

  • OnPlayerMeleeDoDamageStart
  • Player does damage with meele weapon (before levelup calculations)

  • OnPlayerMeleeDoDamageFinish
  • Player does damage with meele weapon (after levelup calculations)

  • OnPlayerRangedDoDamageStart
  • Player does damage with ranged weapon (before levelup calculations)

  • OnPlayerRangedDoDamageFinish
  • Player does damage with ranged weapon (after levelup calculations)

  • OnPlayerReceiveDamageStart
  • Player receives damage (before levelup calculation, does not include equipped armors)

  • OnPlayerReceiveDamageFinish
  • Player receives damage (after levelup calculations, includes equipped armors, but can be null if the damage does not belong to a entity)

  • OnBowDropChanceRefresh
  • Player arrow drop chance refreshed

  • OnBowAimingRefresh
  • Player bow aiming refreshed

  • OnSpearAimingRefresh
  • Player spear aiming refreshed

  • OnPlayerShieldReceiveDamageStart
  • Player receives damage using shield (before levelup calculation)

  • OnPlayerShieldReceiveDamageFinish
  • Player receives damage using shield (after levelup calculation)

LevelUP.Shared.OverwriteBlockInteractionEvents

  • OnKnifeHarvested
  • Player havested entity with a knife

  • OnHoeTill
  • Player tilled a soil

  • OnBerryForage
  • Player harvested a berry bush

  • OnCookedSingle
  • Player cooked a single type food

  • OnCookedPot
  • Player cooked a pot

  • OnHammerItem
  • Player crafted any item using the hammer on anvil

  • OnHammerSmith
  • Player split the item on anvil

  • OnPanning
  • Player panned

  • OnSmithingItem
  • Player crafted any item

  • OnSmithingArmor
  • Player crafted any armor

  • ExecuteSmithItemCraftedCalculations
  • Execute the smithing craft calculations for a ItemStack and return it

LevelUP.Shared.OverwriteBlockBreakInteractionEvents

  • OnMiningOre
  • Player breaked any ore

  • OnHarvestCrop
  • Player harvested any crop

LevelUP.Server.Experience

  • GetExperience
  • Returns the player experience from a level type

  • GetSubExperience
  • Returns the player sub experience from a level type and sub level type

  • IncreaseExperience
  • Increase a player experience from a level type and action or amount

  • IncreaseSubExperience
  • Increase a player experience from a level type, sub level type and amount

Level Calculations

You can access all levelup calculation by using the class LevelUP.Configuration

Level Loaded Configuration

You can access all levelup saved assets by using the class LevelUP.Configuration

Crafting

LevelUP.Shared.OverwriteBlockInteraction.ExecuteSmithItemCraftedCalculations

This function is called everytime a player craft any item, if for some reason the player use the same item to craft the tool or armor it will be rescaled making it even stronger than should be, for this reason levelup will check the item attribute "repaired" if is true it will be ignored or if the max durability is different from actual durability

LevelUP only changes the durability of item, because if you change the attack power and mining speed it will change for all tools of that type, for example if levelup changes for "game:copper-axe" ALL copper axes will have that status, because of this reason levelup create 2 new attributes for storing this status: attackpower and {key}_miningspeed, now the levelup will handle the damage in CollectibleObject.GetAttackPower and the mining speed on BlockBehavior.GetMiningSpeedModifier and CollectibleObject.GetMiningSpeed (one is for the block break and other for hitting animation)

Watched Attributes

EntityPlayer

LevelUP store some watched attributes so client can easily view their levels. (Changing these watched attributes will have no effect to the server this is only for client visual)

  • LevelUP_{levelType} (long)
  • Stores the experience the player has with the level

  • LevelUP__{levelType}_Sub_{subLevelType} (long)
  • Stores the experience the player has with the sub level

  • LevelUP_Level_{levelType} (int)
  • Stores the current level the player has

  • LevelUP_Level_{levelType}_Sub_{subLevelType} (int)
  • Stores the current sub level the player has

  • LevelUP_{levelType}_MiningSpeed (float)
  • Stores the player LEVEL mining speed increase, so it can handle easily the animation of mining speed

LevelUP.Server.Instance

  • CommunicationChannel
  • Communication channel used to send data to the client

  • UpdatePlayerLevels
  • Force refresh player levels and status

  • ResetPlayerLevels
  • Reduce all player levels, reduce only the level progress, overwriteLose indicates the progress lose calculation: 0.2 -> 80% lose rate, 0.5 -> 50% loserate, 0.8 -> 20% loserate

Custom Level

Register your new level

LevelUP.Configuration.RegisterNewLevelTypeEXP("MyCustomLevel", (exp) =>
{
    Console.WriteLine("My custom level calculation");
    return 0;
});
LevelUP.Configuration.RegisterNewMaxLevelByLevelTypeEXP("MyCustomLevel", 999);
foreach (string playerClass in LevelUP.Configuration.ClassExperience.Keys)
    LevelUP.Configuration.RegisterNewClassLevel(playerClass, "MyCustomLevel", 1.0f);

Now you can use the function LevelUP.Server.Experience.IncreaseExperience(player, "MyCustomLevel", amount) to increase player experience

Examples

  • Force reduce all experience
public override void StartServerSide(ICoreServerAPI api)
{
    LevelUP.Server.ExperienceEvents.OnExperienceIncrease += LevelUPOnExperienceIncreased;
}

private void LevelUPOnExperienceIncreased(IPlayer player, string type, ref ulong amount)
{
    amount = (ulong)Math.Round(amount * 0.5);
}
  • Notification when player level up
public override void StartServerSide(ICoreServerAPI api)
{
    LevelUP.Server.ExperienceEvents.OnLevelUp += LevelUPOnLevelUp;
}

private void LevelUPOnLevelUp(IPlayer player, string type, ulong exp, int level)
{
    if (player is IServerPlayer serverPlayer)
    {
        serverPlayer.SendMessage(0, "Congratulations another levelup notification", EnumChatType.Notification);
    }
}
  • Shenanigans cannot do melee damage
public override void StartServerSide(ICoreServerAPI api)
{
    LevelUP.Shared.OverwriteDamageInteractionEvents.OnPlayerMeleeDoDamageFinish += LevelUPOnPlayerMeleeDoDamageFinish
}

private void LevelUPOnPlayerMeleeDoDamageFinish(IPlayer player, DamageSource damageSource, ref float damage)
{
    if (player.PlayerName == "Shenanigans")
    {
        damage = 0;
    }
}
  • Disable axe levels when a player reach 1000 blocks
private static ICoreServerAPI serverAPI;
public override void StartServerSide(ICoreServerAPI api)
{
    serverAPI = api
    LevelUP.Server.ExperienceEvents.OnExperienceIncrease += LevelUPOnExperienceIncreased;
}

private void LevelUPOnExperienceIncreased(IPlayer player, string type, ref ulong amount)
{
    var posX = player.Entity.Pos.X - serverAPI.World.DefaultSpawnPosition.X;
    var posZ = player.Entity.Pos.X - serverAPI.World.DefaultSpawnPosition.Z;

    if (posX > 1000)
        LevelUP.Configuration.enableLevelAxe = false;
    if (posZ > 1000)
        LevelUP.Configuration.enableLevelAxe = false;
}
  • Custom Level
public static int GlobalGetLevelByEXP(ulong exp)
{
    double baseExp = 100.0;
    double multiplier = 0.1;

    if (multiplier <= 1.0)
    {
        return (int)(exp / baseExp);
    }

    double expDouble = exp;

    double level = Math.Log((expDouble * (multiplier - 1) / baseExp) + 1) / Math.Log(multiplier);

    return Math.Max(0, (int)Math.Floor(level));
}

public override void StartServerSide(ICoreServerAPI api)
{

    foreach (string playerClass in LevelUP.Configuration.ClassExperience.Keys)
        LevelUP.Configuration.RegisterNewClassLevel(playerClass, "Global", 1.0f);
    LevelUP.Configuration.RegisterNewLevelTypeEXP("Global", GlobalGetLevelByEXP);
    LevelUP.Configuration.RegisterNewMaxLevelByLevelTypeEXP("Global", 999);
    LevelUP.Server.ExperienceEvents.OnExperienceIncrease += LevelUPOnPlayerExperienceIncrease;
}

private void LevelUPOnPlayerExperienceIncrease(IPlayer player, string type, ref ulong amount)
{
    if (type != "Global")
    {
        // Increase global levels
        LevelUP.Server.Experience.IncreaseExperience(player, "Global", amount);

        // Check if player level up
        int previousLevel = player.Entity.WatchedAttributes.GetInt("LevelUP_Level_Global");
        ulong exp = LevelUP.Server.Experience.GetExperience(player, "Global");
        int nextLevel = Configuration.GlobalGetLevelByEXP(exp);

        // Update global for level up
        player.Entity.WatchedAttributes.SetLong("LevelUP_Global", (long)exp);
        player.Entity.WatchedAttributes.SetInt("LevelUP_Level_Global", nextLevel);
        // Update global for rpg overlay
        player.Entity.WatchedAttributes.SetInt("RPGOverlayEntityLevel", nextLevel);

        // Send message if player level up
        if (previousLevel < nextLevel && player is IServerPlayer serverPlayer)
            LevelUP.Server.Instance.CommunicationChannel.SendPacket(new LevelUP.ServerMessage() { message = $"playerlevelup&{nextLevel}&{"Global"}" }, serverPlayer);
    }
}
⚠️ **GitHub.com Fallback** ⚠️