Added unclaimed waifu decay to gambling.yml

Fixed regular decay. It was doing the opposite of what the comment says. All waifu decays will be reset
This commit is contained in:
Toastie (DCS Team) 2024-08-25 20:12:09 +12:00
parent e324d49cbc
commit d478a6ca72
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
5 changed files with 142 additions and 100 deletions

View file

@ -11,7 +11,7 @@ namespace EllieBot.Modules.Gambling.Common;
public sealed partial class GamblingConfig : ICloneable<GamblingConfig> public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
{ {
[Comment("""DO NOT CHANGE""")] [Comment("""DO NOT CHANGE""")]
public int Version { get; set; } = 2; public int Version { get; set; } = 8;
[Comment("""Currency settings""")] [Comment("""Currency settings""")]
public CurrencyConfig Currency { get; set; } public CurrencyConfig Currency { get; set; }
@ -20,9 +20,9 @@ public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
public int MinBet { get; set; } = 0; public int MinBet { get; set; } = 0;
[Comment(""" [Comment("""
Maximum amount users can bet Maximum amount users can bet
Set 0 for unlimited Set 0 for unlimited
""")] """)]
public int MaxBet { get; set; } = 0; public int MaxBet { get; set; } = 0;
[Comment("""Settings for betflip command""")] [Comment("""Settings for betflip command""")]
@ -35,14 +35,14 @@ public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
public GenerationConfig Generation { get; set; } public GenerationConfig Generation { get; set; }
[Comment(""" [Comment("""
Settings for timely command Settings for timely command
(letting people claim X amount of currency every Y hours) (letting people claim X amount of currency every Y hours)
""")] """)]
public TimelyConfig Timely { get; set; } public TimelyConfig Timely { get; set; }
[Comment("""How much will each user's owned currency decay over time.""")] [Comment("""How much will each user's owned currency decay over time.""")]
public DecayConfig Decay { get; set; } public DecayConfig Decay { get; set; }
[Comment("""What is the bot's cut on some transactions""")] [Comment("""What is the bot's cut on some transactions""")]
public BotCutConfig BotCuts { get; set; } public BotCutConfig BotCuts { get; set; }
@ -53,15 +53,15 @@ public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
public WaifuConfig Waifu { get; set; } public WaifuConfig Waifu { get; set; }
[Comment(""" [Comment("""
Amount of currency selfhosters will get PER pledged dollar CENT. Amount of currency selfhosters will get PER pledged dollar CENT.
1 = 100 currency per $. Used almost exclusively on public ellie. 1 = 100 currency per $. Used almost exclusively on public ellie.
""")] """)]
public decimal PatreonCurrencyPerCent { get; set; } = 1; public decimal PatreonCurrencyPerCent { get; set; } = 1;
[Comment(""" [Comment("""
Currency reward per vote. Currency reward per vote.
This will work only if you've set up VotesApi and correct credentials for topgg and/or discords voting This will work only if you've set up VotesApi and correct credentials for topgg and/or discords voting
""")] """)]
public long VoteReward { get; set; } = 100; public long VoteReward { get; set; } = 100;
[Comment("""Slot config""")] [Comment("""Slot config""")]
@ -91,9 +91,9 @@ public class CurrencyConfig
public string Name { get; set; } = "Ellie Money"; public string Name { get; set; } = "Ellie Money";
[Comment(""" [Comment("""
For how long (in days) will the transactions be kept in the database (curtrs) For how long (in days) will the transactions be kept in the database (curtrs)
Set 0 to disable cleanup (keep transactions forever) Set 0 to disable cleanup (keep transactions forever)
""")] """)]
public int TransactionsLifetime { get; set; } = 0; public int TransactionsLifetime { get; set; } = 0;
} }
@ -101,15 +101,15 @@ public class CurrencyConfig
public partial class TimelyConfig public partial class TimelyConfig
{ {
[Comment(""" [Comment("""
How much currency will the users get every time they run .timely command How much currency will the users get every time they run .timely command
setting to 0 or less will disable this feature setting to 0 or less will disable this feature
""")] """)]
public int Amount { get; set; } = 0; public int Amount { get; set; } = 0;
[Comment(""" [Comment("""
How often (in hours) can users claim currency with .timely command How often (in hours) can users claim currency with .timely command
setting to 0 or less will disable this feature setting to 0 or less will disable this feature
""")] """)]
public int Cooldown { get; set; } = 24; public int Cooldown { get; set; } = 24;
} }
@ -124,10 +124,10 @@ public partial class BetFlipConfig
public partial class BetRollConfig public partial class BetRollConfig
{ {
[Comment(""" [Comment("""
When betroll is played, user will roll a number 0-100. When betroll is played, user will roll a number 0-100.
This setting will describe which multiplier is used for when the roll is higher than the given number. This setting will describe which multiplier is used for when the roll is higher than the given number.
Doesn't have to be ordered. Doesn't have to be ordered.
""")] """)]
public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>(); public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>();
public BetRollConfig() public BetRollConfig()
@ -155,17 +155,17 @@ public partial class BetRollConfig
public partial class GenerationConfig public partial class GenerationConfig
{ {
[Comment(""" [Comment("""
when currency is generated, should it also have a random password when currency is generated, should it also have a random password
associated with it which users have to type after the .pick command associated with it which users have to type after the .pick command
in order to get it in order to get it
""")] """)]
public bool HasPassword { get; set; } = true; public bool HasPassword { get; set; } = true;
[Comment(""" [Comment("""
Every message sent has a certain % chance to generate the currency Every message sent has a certain % chance to generate the currency
specify the percentage here (1 being 100%, 0 being 0% - for example specify the percentage here (1 being 100%, 0 being 0% - for example
default is 0.02, which is 2% default is 0.02, which is 2%
""")] """)]
public decimal Chance { get; set; } = 0.02M; public decimal Chance { get; set; } = 0.02M;
[Comment("""How many seconds have to pass for the next message to have a chance to spawn currency""")] [Comment("""How many seconds have to pass for the next message to have a chance to spawn currency""")]
@ -175,9 +175,9 @@ public partial class GenerationConfig
public int MinAmount { get; set; } = 1; public int MinAmount { get; set; } = 1;
[Comment(""" [Comment("""
Maximum amount of currency that can spawn. Maximum amount of currency that can spawn.
Set to the same value as MinAmount to always spawn the same amount Set to the same value as MinAmount to always spawn the same amount
""")] """)]
public int MaxAmount { get; set; } = 1; public int MaxAmount { get; set; } = 1;
} }
@ -185,9 +185,9 @@ public partial class GenerationConfig
public partial class DecayConfig public partial class DecayConfig
{ {
[Comment(""" [Comment("""
Percentage of user's current currency which will be deducted every 24h. Percentage of user's current currency which will be deducted every 24h.
0 - 1 (1 is 100%, 0.5 50%, 0 disabled) 0 - 1 (1 is 100%, 0.5 50%, 0 disabled)
""")] """)]
public decimal Percent { get; set; } = 0; public decimal Percent { get; set; } = 0;
[Comment("""Maximum amount of user's currency that can decay at each interval. 0 for unlimited.""")] [Comment("""Maximum amount of user's currency that can decay at each interval. 0 for unlimited.""")]
@ -219,15 +219,15 @@ public sealed partial class WaifuConfig
public MultipliersData Multipliers { get; set; } = new(); public MultipliersData Multipliers { get; set; } = new();
[Comment(""" [Comment("""
Settings for periodic waifu price decay. Settings for periodic waifu price decay.
Waifu price decays only if the waifu has no claimer. Waifu price decays only if the waifu has no claimer.
""")] """)]
public WaifuDecayConfig Decay { get; set; } = new(); public WaifuDecayConfig Decay { get; set; } = new();
[Comment(""" [Comment("""
List of items available for gifting. List of items available for gifting.
If negative is true, gift will instead reduce waifu value. If negative is true, gift will instead reduce waifu value.
""")] """)]
public List<WaifuItemModel> Items { get; set; } = []; public List<WaifuItemModel> Items { get; set; } = [];
public WaifuConfig() public WaifuConfig()
@ -274,19 +274,25 @@ public sealed partial class WaifuConfig
public class WaifuDecayConfig public class WaifuDecayConfig
{ {
[Comment(""" [Comment("""
Percentage (0 - 100) of the waifu value to reduce. Percentage (0 - 100) of the waifu value to reduce.
Set 0 to disable Set 0 to disable
For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$) For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$)
""")] """)]
public int Percent { get; set; } = 0; public int UnclaimedDecayPercent { get; set; } = 0;
[Comment("""
Claimed waifus will decay by this percentage (0 - 100).
Default is 0 (disabled)
""")]
public int ClaimedDecayPercent { get; set; } = 0;
[Comment("""How often to decay waifu values, in hours""")] [Comment("""How often to decay waifu values, in hours""")]
public int HourInterval { get; set; } = 24; public int HourInterval { get; set; } = 24;
[Comment(""" [Comment("""
Minimum waifu price required for the decay to be applied. Minimum waifu price required for the decay to be applied.
For example if this value is set to 300, any waifu with the price 300 or less will not experience decay. For example if this value is set to 300, any waifu with the price 300 or less will not experience decay.
""")] """)]
public long MinPrice { get; set; } = 300; public long MinPrice { get; set; } = 300;
} }
} }
@ -295,54 +301,54 @@ public sealed partial class WaifuConfig
public sealed partial class MultipliersData public sealed partial class MultipliersData
{ {
[Comment(""" [Comment("""
Multiplier for waifureset. Default 150. Multiplier for waifureset. Default 150.
Formula (at the time of writing this): Formula (at the time of writing this):
price = (waifu_price * 1.25f) + ((number_of_divorces + changes_of_heart + 2) * WaifuReset) rounded up price = (waifu_price * 1.25f) + ((number_of_divorces + changes_of_heart + 2) * WaifuReset) rounded up
""")] """)]
public int WaifuReset { get; set; } = 150; public int WaifuReset { get; set; } = 150;
[Comment(""" [Comment("""
The minimum amount of currency that you have to pay The minimum amount of currency that you have to pay
in order to buy a waifu who doesn't have a crush on you. in order to buy a waifu who doesn't have a crush on you.
Default is 1.1 Default is 1.1
Example: If a waifu is worth 100, you will have to pay at least 100 * NormalClaim currency to claim her. Example: If a waifu is worth 100, you will have to pay at least 100 * NormalClaim currency to claim her.
(100 * 1.1 = 110) (100 * 1.1 = 110)
""")] """)]
public decimal NormalClaim { get; set; } = 1.1m; public decimal NormalClaim { get; set; } = 1.1m;
[Comment(""" [Comment("""
The minimum amount of currency that you have to pay The minimum amount of currency that you have to pay
in order to buy a waifu that has a crush on you. in order to buy a waifu that has a crush on you.
Default is 0.88 Default is 0.88
Example: If a waifu is worth 100, you will have to pay at least 100 * CrushClaim currency to claim her. Example: If a waifu is worth 100, you will have to pay at least 100 * CrushClaim currency to claim her.
(100 * 0.88 = 88) (100 * 0.88 = 88)
""")] """)]
public decimal CrushClaim { get; set; } = 0.88M; public decimal CrushClaim { get; set; } = 0.88M;
[Comment(""" [Comment("""
When divorcing a waifu, her new value will be her current value multiplied by this number. When divorcing a waifu, her new value will be her current value multiplied by this number.
Default 0.75 (meaning will lose 25% of her value) Default 0.75 (meaning will lose 25% of her value)
""")] """)]
public decimal DivorceNewValue { get; set; } = 0.75M; public decimal DivorceNewValue { get; set; } = 0.75M;
[Comment(""" [Comment("""
All gift prices will be multiplied by this number. All gift prices will be multiplied by this number.
Default 1 (meaning no effect) Default 1 (meaning no effect)
""")] """)]
public decimal AllGiftPrices { get; set; } = 1.0M; public decimal AllGiftPrices { get; set; } = 1.0M;
[Comment(""" [Comment("""
What percentage of the value of the gift will a waifu gain when she's gifted. What percentage of the value of the gift will a waifu gain when she's gifted.
Default 0.95 (meaning 95%) Default 0.95 (meaning 95%)
Example: If a waifu is worth 1000, and she receives a gift worth 100, her new value will be 1095) Example: If a waifu is worth 1000, and she receives a gift worth 100, her new value will be 1095)
""")] """)]
public decimal GiftEffect { get; set; } = 0.95M; public decimal GiftEffect { get; set; } = 0.95M;
[Comment(""" [Comment("""
What percentage of the value of the gift will a waifu lose when she's gifted a gift marked as 'negative'. What percentage of the value of the gift will a waifu lose when she's gifted a gift marked as 'negative'.
Default 0.5 (meaning 50%) Default 0.5 (meaning 50%)
Example: If a waifu is worth 1000, and she receives a negative gift worth 100, her new value will be 950) Example: If a waifu is worth 1000, and she receives a negative gift worth 100, her new value will be 950)
""")] """)]
public decimal NegativeGiftEffect { get; set; } = 0.50M; public decimal NegativeGiftEffect { get; set; } = 0.50M;
} }

View file

@ -174,7 +174,7 @@ public sealed class GamblingConfigService : ConfigServiceBase<GamblingConfig>
c.Version = 5; c.Version = 5;
}); });
} }
if (data.Version < 6) if (data.Version < 6)
{ {
ModifyConfig(c => ModifyConfig(c =>
@ -190,5 +190,14 @@ public sealed class GamblingConfigService : ConfigServiceBase<GamblingConfig>
c.Version = 7; c.Version = 7;
}); });
} }
if (data.Version < 8)
{
ModifyConfig(c =>
{
c.Version = 8;
c.Waifu.Decay.UnclaimedDecayPercent = 0;
});
}
} }
} }

View file

@ -531,11 +531,18 @@ public class WaifuService : IEService, IReadyExecutor
{ {
try try
{ {
var multi = _gss.Data.Waifu.Decay.Percent / 100f; var decay = _gss.Data.Waifu.Decay;
var minPrice = _gss.Data.Waifu.Decay.MinPrice;
var decayInterval = _gss.Data.Waifu.Decay.HourInterval;
if (multi is < 0f or > 1f || decayInterval < 0) var unclaimedMulti = 1 - (decay.UnclaimedDecayPercent / 100f);
var claimedMulti = 1 - (decay.ClaimedDecayPercent / 100f);
var minPrice = decay.MinPrice;
var decayInterval = decay.HourInterval;
if (decayInterval <= 0)
continue;
if ((unclaimedMulti < 0 || unclaimedMulti > 1) && (claimedMulti < 0 || claimedMulti > 1))
continue; continue;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
@ -554,14 +561,28 @@ public class WaifuService : IEService, IReadyExecutor
await _cache.AddAsync(_waifuDecayKey, nowB); await _cache.AddAsync(_waifuDecayKey, nowB);
await using var uow = _db.GetDbContext(); if (unclaimedMulti is > 0 and <= 1)
{
await using var uow = _db.GetDbContext();
await uow.GetTable<WaifuInfo>() await uow.GetTable<WaifuInfo>()
.Where(x => x.Price > minPrice && x.ClaimerId == null) .Where(x => x.Price > minPrice && x.ClaimerId == null)
.UpdateAsync(old => new() .UpdateAsync(old => new()
{ {
Price = (long)(old.Price * multi) Price = (long)(old.Price * unclaimedMulti)
}); });
}
if (claimedMulti is > 0 and <= 1)
{
await using var uow = _db.GetDbContext();
await uow.GetTable<WaifuInfo>()
.Where(x => x.Price > minPrice && x.ClaimerId == null)
.UpdateAsync(old => new()
{
Price = (long)(old.Price * claimedMulti)
});
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -63,6 +63,8 @@ public static class WaifuExtensions
public static async Task<WaifuInfoStats> GetWaifuInfoAsync(this DbContext ctx, ulong userId) public static async Task<WaifuInfoStats> GetWaifuInfoAsync(this DbContext ctx, ulong userId)
{ {
await ctx.EnsureUserCreatedAsync(userId);
await ctx.Set<WaifuInfo>() await ctx.Set<WaifuInfo>()
.ToLinqToDBTable() .ToLinqToDBTable()
.InsertOrUpdateAsync(() => new() .InsertOrUpdateAsync(() => new()
@ -78,7 +80,8 @@ public static class WaifuExtensions
WaifuId = ctx.Set<DiscordUser>().Where(x => x.UserId == userId).Select(x => x.Id).First() WaifuId = ctx.Set<DiscordUser>().Where(x => x.UserId == userId).Select(x => x.Id).First()
}); });
var toReturn = ctx.Set<WaifuInfo>().AsQueryable() var toReturn = ctx.Set<WaifuInfo>()
.AsQueryable()
.Where(w => w.WaifuId .Where(w => w.WaifuId
== ctx.Set<DiscordUser>() == ctx.Set<DiscordUser>()
.AsQueryable() .AsQueryable()

View file

@ -1,5 +1,5 @@
# DO NOT CHANGE # DO NOT CHANGE
version: 7 version: 8
# Currency settings # Currency settings
currency: currency:
# What is the emoji/character which represents the currency # What is the emoji/character which represents the currency
@ -128,7 +128,10 @@ waifu:
# Percentage (0 - 100) of the waifu value to reduce. # Percentage (0 - 100) of the waifu value to reduce.
# Set 0 to disable # Set 0 to disable
# For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$) # For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$)
percent: 0 unclaimedDecayPercent: 0
# Claimed waifus will decay by this percentage (0 - 100).
# Default is 0 (disabled)
claimedDecayPercent: 0
# How often to decay waifu values, in hours # How often to decay waifu values, in hours
hourInterval: 24 hourInterval: 24
# Minimum waifu price required for the decay to be applied. # Minimum waifu price required for the decay to be applied.