- .streamsclear re-added. It will remove all followed streams on the server.

- .gifts now have 3 new ✂️ Haircut 🧻 ToiletPaper and 🥀 WiltedRose which **reduce** waifu's value
- Added a new multiplier (waifu.multi.negative_gift_effect default 0.5, changeable via .config gambling or data/gambling.yml)
This commit is contained in:
Kwoth
2021-09-30 08:53:15 +02:00
parent 52c9ec670d
commit ff95b3d00f
12 changed files with 247 additions and 159 deletions

View File

@@ -4,6 +4,15 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
## Unreleased ## Unreleased
### Added
- `.streamsclear` re-added. It will remove all followed streams on the server.
- `.gifts` now have 3 new ✂️ Haircut 🧻 ToiletPaper and 🥀 WiltedRose which **reduce** waifu's value
- They are called negative gifts
- They show up at the end of the `.gifts` page and are marked with a broken heart
- They have a separate multiplier (`waifu.multi.negative_gift_effect` default 0.5, changeable via `.config gambling` or `data/gambling.yml`)
- When gifted, the waifu's price will be reduced by the `price * multiplier`
- Negative gifts don't show up in `.waifuinfo` nor is the record of them kept in the database
## [3.0.6] - 27.09.2021 ## [3.0.6] - 27.09.2021
### Added ### Added

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Cloneable; using Cloneable;
using NadekoBot.Common; using NadekoBot.Common;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
using YamlDotNet.Serialization;
namespace NadekoBot.Modules.Gambling.Common namespace NadekoBot.Modules.Gambling.Common
{ {
@@ -179,7 +180,8 @@ default is 0.02, which is 2%")]
public MultipliersData Multipliers { get; set; } = new MultipliersData(); public MultipliersData Multipliers { get; set; } = new MultipliersData();
[Comment(@"List of items available for gifting.")] [Comment(@"List of items available for gifting.
If negative is true, gift will instead reduce waifu value.")]
public List<WaifuItemModel> Items { get; set; } = new List<WaifuItemModel>(); public List<WaifuItemModel> Items { get; set; } = new List<WaifuItemModel>();
public WaifuConfig() public WaifuConfig()
@@ -260,6 +262,11 @@ Default 1 (meaning no effect)")]
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(@"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%)
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;
} }
[Cloneable] [Cloneable]
@@ -268,19 +275,24 @@ Example: If a waifu is worth 1000, and she receives a gift worth 100, her new va
public string ItemEmoji { get; set; } public string ItemEmoji { get; set; }
public int Price { get; set; } public int Price { get; set; }
public string Name { get; set; } public string Name { get; set; }
[YamlMember(DefaultValuesHandling = DefaultValuesHandling.OmitDefaults)]
public bool Negative { get; set; }
public WaifuItemModel() public WaifuItemModel()
{ {
} }
public WaifuItemModel(string itemEmoji, int price, string name) public WaifuItemModel(string itemEmoji, int price, string name, bool negative = false)
{ {
ItemEmoji = itemEmoji; ItemEmoji = itemEmoji;
Price = price; Price = price;
Name = name; Name = name;
Negative = negative;
} }
public override string ToString() => Name; public override string ToString() => Name;
} }

View File

@@ -1,7 +1,11 @@
using NadekoBot.Common; using System;
using System.Collections.Generic;
using System.Linq;
using NadekoBot.Common;
using NadekoBot.Common.Configs; using NadekoBot.Common.Configs;
using NadekoBot.Modules.Gambling.Common; using NadekoBot.Modules.Gambling.Common;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Gambling.Services namespace NadekoBot.Modules.Gambling.Services
{ {
@@ -34,9 +38,31 @@ namespace NadekoBot.Modules.Gambling.Services
AddParsedProp("waifu.multi.divorce_value", gs => gs.Waifu.Multipliers.DivorceNewValue, decimal.TryParse, ConfigPrinters.ToString, val => val > 0); AddParsedProp("waifu.multi.divorce_value", gs => gs.Waifu.Multipliers.DivorceNewValue, decimal.TryParse, ConfigPrinters.ToString, val => val > 0);
AddParsedProp("waifu.multi.all_gifts", gs => gs.Waifu.Multipliers.AllGiftPrices, decimal.TryParse, ConfigPrinters.ToString, val => val > 0); AddParsedProp("waifu.multi.all_gifts", gs => gs.Waifu.Multipliers.AllGiftPrices, decimal.TryParse, ConfigPrinters.ToString, val => val > 0);
AddParsedProp("waifu.multi.gift_effect", gs => gs.Waifu.Multipliers.GiftEffect, decimal.TryParse, ConfigPrinters.ToString, val => val >= 0); AddParsedProp("waifu.multi.gift_effect", gs => gs.Waifu.Multipliers.GiftEffect, decimal.TryParse, ConfigPrinters.ToString, val => val >= 0);
AddParsedProp("waifu.multi.negative_gift_effect", gs => gs.Waifu.Multipliers.NegativeGiftEffect, decimal.TryParse, ConfigPrinters.ToString, val => val >= 0);
AddParsedProp("decay.percent", gs => gs.Decay.Percent, decimal.TryParse, ConfigPrinters.ToString, val => val >= 0 && val <= 1); AddParsedProp("decay.percent", gs => gs.Decay.Percent, decimal.TryParse, ConfigPrinters.ToString, val => val >= 0 && val <= 1);
AddParsedProp("decay.maxdecay", gs => gs.Decay.MaxDecay, int.TryParse, ConfigPrinters.ToString, val => val >= 0); AddParsedProp("decay.maxdecay", gs => gs.Decay.MaxDecay, int.TryParse, ConfigPrinters.ToString, val => val >= 0);
AddParsedProp("decay.threshold", gs => gs.Decay.MinThreshold, int.TryParse, ConfigPrinters.ToString, val => val >= 0); AddParsedProp("decay.threshold", gs => gs.Decay.MinThreshold, int.TryParse, ConfigPrinters.ToString, val => val >= 0);
Migrate();
}
private readonly IEnumerable<WaifuItemModel> antiGiftSeed = new[]
{
new WaifuItemModel("🥀", 100, "WiltedRose", true),
new WaifuItemModel("✂️", 1000, "Haircut", true),
new WaifuItemModel("🧻", 10000, "ToiletPaper", true),
};
public void Migrate()
{
if (_data.Version < 2)
{
ModifyConfig(c =>
{
c.Waifu.Items = c.Waifu.Items.Concat(antiGiftSeed).ToList();
c.Version = 2;
});
}
} }
} }
} }

View File

@@ -394,19 +394,28 @@ namespace NadekoBot.Modules.Gambling.Services
}); });
} }
w.Items.Add(new WaifuItem() if (!itemObj.Negative)
{ {
Name = itemObj.Name.ToLowerInvariant(), w.Items.Add(new WaifuItem()
ItemEmoji = itemObj.ItemEmoji, {
}); Name = itemObj.Name.ToLowerInvariant(),
ItemEmoji = itemObj.ItemEmoji,
if (w.Claimer?.UserId == from.Id) });
{
w.Price += (int) (itemObj.Price * _gss.Data.Waifu.Multipliers.GiftEffect); if (w.Claimer?.UserId == from.Id)
{
w.Price += (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.GiftEffect);
}
else
{
w.Price += itemObj.Price / 2;
}
} }
else else
{ {
w.Price += itemObj.Price / 2; w.Price -= (int)(itemObj.Price * _gss.Data.Waifu.Multipliers.NegativeGiftEffect);
if (w.Price < 1)
w.Price = 1;
} }
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
@@ -512,7 +521,7 @@ namespace NadekoBot.Modules.Gambling.Services
{ {
var conf = _gss.Data; var conf = _gss.Data;
return conf.Waifu.Items return conf.Waifu.Items
.Select(x => new WaifuItemModel(x.ItemEmoji, (int)(x.Price * conf.Waifu.Multipliers.AllGiftPrices), x.Name)) .Select(x => new WaifuItemModel(x.ItemEmoji, (int)(x.Price * conf.Waifu.Multipliers.AllGiftPrices), x.Name, x.Negative))
.ToList(); .ToList();
} }
} }

View File

@@ -317,10 +317,14 @@ namespace NadekoBot.Modules.Gambling
.WithOkColor(); .WithOkColor();
waifuItems waifuItems
.OrderBy(x => x.Price) .OrderBy(x => x.Negative)
.ThenBy(x => x.Price)
.Skip(9 * cur) .Skip(9 * cur)
.Take(9) .Take(9)
.ForEach(x => embed.AddField($"{x.ItemEmoji} {x.Name}", x.Price, true)); .ForEach(x => embed
.AddField($"{(!x.Negative ? string.Empty : "\\💔")} {x.ItemEmoji} {x.Name}",
Format.Bold(x.Price.ToString()) + _config.Currency.Sign,
true));
return embed; return embed;
}, waifuItems.Count, 9); }, waifuItems.Count, 9);

View File

@@ -73,7 +73,6 @@ namespace NadekoBot.Modules.Games.Hangman
return new(output); return new(output);
} }
// todo lock
public State Guess(string guess) public State Guess(string guess)
{ {
if (CurrentPhase != Phase.Running) if (CurrentPhase != Phase.Running)

View File

@@ -14,6 +14,8 @@ using NadekoBot.Extensions;
using StackExchange.Redis; using StackExchange.Redis;
using Discord; using Discord;
using Discord.WebSocket; using Discord.WebSocket;
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Common.Collections; using NadekoBot.Common.Collections;
using NadekoBot.Common.Replacements; using NadekoBot.Common.Replacements;
using NadekoBot.Db; using NadekoBot.Db;
@@ -342,19 +344,18 @@ namespace NadekoBot.Modules.Searches.Services
return Task.CompletedTask; return Task.CompletedTask;
} }
public int ClearAllStreams(ulong guildId) public async Task<int> ClearAllStreams(ulong guildId)
{ {
// todo future clear streams using var uow = _db.GetDbContext();
int count; var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FollowedStreams));
using (var uow = _db.GetDbContext()) uow.RemoveRange(gc.FollowedStreams);
{
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FollowedStreams));
count = gc.FollowedStreams.Count;
gc.FollowedStreams.Clear();
uow.SaveChanges();
}
return count; foreach (var s in gc.FollowedStreams)
await PublishUnfollowStream(s);
uow.SaveChanges();
return gc.FollowedStreams.Count;
} }
public async Task<FollowedStream> UnfollowStreamAsync(ulong guildId, int index) public async Task<FollowedStream> UnfollowStreamAsync(ulong guildId, int index)

View File

@@ -69,14 +69,14 @@ namespace NadekoBot.Modules.Searches
fs.Type)); fs.Type));
} }
// [NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
// [RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
// [UserPerm(GuildPerm.Administrator)] [UserPerm(GuildPerm.Administrator)]
// public async Task StreamsClear() public async Task StreamsClear()
// { {
// var count = _service.ClearAllStreams(ctx.Guild.Id); var count = _service.ClearAllStreams(ctx.Guild.Id);
// await ReplyErrorLocalizedAsync(strs.streams_cleared(count))); await ReplyConfirmLocalizedAsync(strs.streams_cleared);
// } }
[NadekoCommand, Aliases] [NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@@ -532,6 +532,9 @@ streamadd:
streamremove: streamremove:
- streamremove - streamremove
- strm - strm
streamsclear:
- streamsclear
- stclear
streamlist: streamlist:
- streamlist - streamlist
- stl - stl

View File

@@ -1,5 +1,5 @@
# DO NOT CHANGE # DO NOT CHANGE
version: 1 version: 2
# Currency settings # Currency settings
currency: currency:
# What is the emoji/character which represents the currency # What is the emoji/character which represents the currency
@@ -21,12 +21,12 @@ betRoll:
# 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.
pairs: pairs:
- whenAbove: 99 - whenAbove: 99
multiplyBy: 10 multiplyBy: 10
- whenAbove: 90 - whenAbove: 90
multiplyBy: 4 multiplyBy: 4
- whenAbove: 66 - whenAbove: 66
multiplyBy: 2 multiplyBy: 2
# Automatic currency generation settings. # Automatic currency generation settings.
generation: generation:
# when currency is generated, should it also have a random password # when currency is generated, should it also have a random password
@@ -68,14 +68,14 @@ decay:
wheelOfFortune: wheelOfFortune:
# Self-Explanatory. Has to have 8 values, otherwise the command won't work. # Self-Explanatory. Has to have 8 values, otherwise the command won't work.
multipliers: multipliers:
- 1.7 - 1.7
- 1.5 - 1.5
- 0.2 - 0.2
- 0.1 - 0.1
- 0.3 - 0.3
- 0.5 - 0.5
- 1.2 - 1.2
- 2.4 - 2.4
# Settings related to waifus # Settings related to waifus
waifu: waifu:
# Minimum price a waifu can have # Minimum price a waifu can have
@@ -107,116 +107,133 @@ waifu:
# 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)
giftEffect: 0.95 giftEffect: 0.95
# 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%)
# Example: If a waifu is worth 1000, and she receives a negative gift worth 100, her new value will be 950)
negativeGiftEffect: 0.50
# List of items available for gifting. # List of items available for gifting.
# If negative is true, gift will instead reduce waifu value.
items: items:
- itemEmoji: "🥔" - itemEmoji: "🥔"
price: 5 price: 5
name: Potato name: Potato
- itemEmoji: "🍪" - itemEmoji: "🍪"
price: 10 price: 10
name: Cookie name: Cookie
- itemEmoji: "🥖" - itemEmoji: "🥖"
price: 20 price: 20
name: Bread name: Bread
- itemEmoji: "🍭" - itemEmoji: "🍭"
price: 30 price: 30
name: Lollipop name: Lollipop
- itemEmoji: "🌹" - itemEmoji: "🌹"
price: 50 price: 50
name: Rose name: Rose
- itemEmoji: "🍺" - itemEmoji: "🍺"
price: 70 price: 70
name: Beer name: Beer
- itemEmoji: "🌮" - itemEmoji: "🌮"
price: 85 price: 85
name: Taco name: Taco
- itemEmoji: "💌" - itemEmoji: "💌"
price: 100 price: 100
name: LoveLetter name: LoveLetter
- itemEmoji: "🥛" - itemEmoji: "🥛"
price: 125 price: 125
name: Milk name: Milk
- itemEmoji: "🍕" - itemEmoji: "🍕"
price: 150 price: 150
name: Pizza name: Pizza
- itemEmoji: "🍫" - itemEmoji: "🍫"
price: 200 price: 200
name: Chocolate name: Chocolate
- itemEmoji: "🍦" - itemEmoji: "🍦"
price: 250 price: 250
name: Icecream name: Icecream
- itemEmoji: "🍣" - itemEmoji: "🍣"
price: 300 price: 300
name: Sushi name: Sushi
- itemEmoji: "🍚" - itemEmoji: "🍚"
price: 400 price: 400
name: Rice name: Rice
- itemEmoji: "🍉" - itemEmoji: "🍉"
price: 500 price: 500
name: Watermelon name: Watermelon
- itemEmoji: "🍱" - itemEmoji: "🍱"
price: 600 price: 600
name: Bento name: Bento
- itemEmoji: "🎟" - itemEmoji: "🎟"
price: 800 price: 800
name: MovieTicket name: MovieTicket
- itemEmoji: "🍰" - itemEmoji: "🍰"
price: 1000 price: 1000
name: Cake name: Cake
- itemEmoji: "📔" - itemEmoji: "📔"
price: 1500 price: 1500
name: Book name: Book
- itemEmoji: "🐱" - itemEmoji: "🐱"
price: 2000 price: 2000
name: Cat name: Cat
- itemEmoji: "🐶" - itemEmoji: "🐶"
price: 2001 price: 2001
name: Dog name: Dog
- itemEmoji: "🐼" - itemEmoji: "🐼"
price: 2500 price: 2500
name: Panda name: Panda
- itemEmoji: "💄" - itemEmoji: "💄"
price: 3000 price: 3000
name: Lipstick name: Lipstick
- itemEmoji: "👛" - itemEmoji: "👛"
price: 3500 price: 3500
name: Purse name: Purse
- itemEmoji: "📱" - itemEmoji: "📱"
price: 4000 price: 4000
name: iPhone name: iPhone
- itemEmoji: "👗" - itemEmoji: "👗"
price: 4500 price: 4500
name: Dress name: Dress
- itemEmoji: "💻" - itemEmoji: "💻"
price: 5000 price: 5000
name: Laptop name: Laptop
- itemEmoji: "🎻" - itemEmoji: "🎻"
price: 7500 price: 7500
name: Violin name: Violin
- itemEmoji: "🎹" - itemEmoji: "🎹"
price: 8000 price: 8000
name: Piano name: Piano
- itemEmoji: "🚗" - itemEmoji: "🚗"
price: 9000 price: 9000
name: Car name: Car
- itemEmoji: "💍" - itemEmoji: "💍"
price: 10000 price: 10000
name: Ring name: Ring
- itemEmoji: "🛳" - itemEmoji: "🛳"
price: 12000 price: 12000
name: Ship name: Ship
- itemEmoji: "🏠" - itemEmoji: "🏠"
price: 15000 price: 15000
name: House name: House
- itemEmoji: "🚁" - itemEmoji: "🚁"
price: 20000 price: 20000
name: Helicopter name: Helicopter
- itemEmoji: "🚀" - itemEmoji: "🚀"
price: 30000 price: 30000
name: Spaceship name: Spaceship
- itemEmoji: "🌕" - itemEmoji: "🌕"
price: 50000 price: 50000
name: Moon name: Moon
- itemEmoji: "🥀"
price: 100
name: WiltedRose
negative: true
- itemEmoji: ✂️
price: 1000
name: Haircut
negative: true
- itemEmoji: "🧻"
price: 10000
name: ToiletPaper
negative: true
# 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 nadeko. # 1 = 100 currency per $. Used almost exclusively on public nadeko.
patreonCurrencyPerCent: 1 patreonCurrencyPerCent: 1

View File

@@ -902,6 +902,10 @@ streamadd:
desc: "Notifies this channel when the stream on the specified URL goes online or offline. Offline notifications will only show if you enable `{0}streamoff`. Maximum 10 per server." desc: "Notifies this channel when the stream on the specified URL goes online or offline. Offline notifications will only show if you enable `{0}streamoff`. Maximum 10 per server."
args: args:
- "twitch.tv/someguy" - "twitch.tv/someguy"
streamsclear:
desc: "Removes all followed streams on this server."
args:
- ""
streamremove: streamremove:
desc: "Stops following the stream on the specified index. (use `{0}stl` to see indexes)" desc: "Stops following the stream on the specified index. (use `{0}stl` to see indexes)"
args: args:
@@ -1433,7 +1437,10 @@ waifutransfer:
args: args:
- "@ExWaifu @NewOwner" - "@ExWaifu @NewOwner"
waifugift: waifugift:
desc: "Gift an item to someone. This will increase their waifu value by 50% of the gifted item's value if they are not your waifu, or 95% if they are. Provide no parameters to see a list of items that you can gift." desc: -|
Gift an item to someone. This will increase their waifu value by a percentage of the gift's value.
Negative gifts will not show up in waifuinfo.
Provide no parameters to see a list of items that you can gift.
args: args:
- "" - ""
- "Rose @Himesama" - "Rose @Himesama"

View File

@@ -507,6 +507,7 @@
"streamer_online": "Streamer {0} is online with {1} viewers.", "streamer_online": "Streamer {0} is online with {1} viewers.",
"streams_follow_title": "Streams you're following", "streams_follow_title": "Streams you're following",
"streams_none": "You are not following any streams on this server.", "streams_none": "You are not following any streams on this server.",
"streams_cleared": "All streams followed on this server have been removed.",
"stream_no": "No such stream.", "stream_no": "No such stream.",
"stream_off_enabled": "Stream notifications will now show when a stream goes offline.", "stream_off_enabled": "Stream notifications will now show when a stream goes offline.",
"stream_off_disabled": "Stream notifications will no longer show when a stream goes offline.", "stream_off_disabled": "Stream notifications will no longer show when a stream goes offline.",