-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
420 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
mod/Gangs.SpecialDayColorPerk/Gangs.SpecialDayColorPerk.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.260" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Reference Include="GangsAPI"> | ||
<HintPath>..\..\public\Jailbreak.Public\Mixin\GangsAPI.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Gangs.BaseImpl\Gangs.BaseImpl.csproj" /> | ||
<ProjectReference Include="..\Gangs.BombIconPerk\Gangs.BombIconPerk.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System.Drawing; | ||
using CounterStrikeSharp.API.Modules.Utils; | ||
|
||
namespace Gangs.SpecialDayColorPerk; | ||
|
||
[Flags] | ||
public enum SDColor { | ||
RED = 1 << 0, | ||
ORANGE = 1 << 1, | ||
YELLOW = 1 << 2, | ||
GREEN = 1 << 3, | ||
CYAN = 1 << 4, | ||
BLUE = 1 << 5, | ||
PURPLE = 1 << 6, | ||
DEFAULT = 1 << 7, | ||
RANDOM = 1 << 8 | ||
} | ||
|
||
public static class SmokeColorExtensions { | ||
public static int GetCost(this SDColor color) { | ||
return color switch { | ||
SDColor.RED => 2000, | ||
SDColor.ORANGE => 1000, | ||
SDColor.YELLOW => 1000, | ||
SDColor.GREEN => 2000, | ||
SDColor.CYAN => 5000, | ||
SDColor.BLUE => 4000, | ||
SDColor.PURPLE => 2000, | ||
SDColor.DEFAULT => 1000, | ||
SDColor.RANDOM => 10000, | ||
_ => 0 | ||
}; | ||
} | ||
|
||
public static Color? GetColor(this SDColor color) { | ||
return color switch { | ||
SDColor.RED => Color.Red, | ||
SDColor.ORANGE => Color.Orange, | ||
SDColor.YELLOW => Color.Yellow, | ||
SDColor.GREEN => Color.Green, | ||
SDColor.CYAN => Color.Cyan, | ||
SDColor.BLUE => Color.Blue, | ||
SDColor.PURPLE => Color.Purple, | ||
SDColor.DEFAULT => null, | ||
SDColor.RANDOM => null, | ||
_ => Color.White | ||
}; | ||
} | ||
|
||
public static char GetChatColor(this SDColor color) { | ||
return color switch { | ||
SDColor.RED => ChatColors.Red, | ||
SDColor.ORANGE => ChatColors.Orange, | ||
SDColor.YELLOW => ChatColors.Yellow, | ||
SDColor.GREEN => ChatColors.Green, | ||
SDColor.CYAN => ChatColors.LightBlue, | ||
SDColor.BLUE => ChatColors.Blue, | ||
SDColor.PURPLE => ChatColors.Purple, | ||
SDColor.DEFAULT => ChatColors.White, | ||
SDColor.RANDOM => ChatColors.White, | ||
_ => ChatColors.White | ||
}; | ||
} | ||
|
||
public static Color? PickRandom(this SDColor color) { | ||
var n = new Random().Next(Enum.GetValues<SDColor>().Length); | ||
var available = Enum.GetValues<SDColor>() | ||
.Where(c => color.HasFlag(c) && c.GetColor() != null) | ||
.ToList(); | ||
|
||
// Gang bought the random perk, but no colors, sillies! | ||
if (available.Count == 0) return null; | ||
|
||
return available[n % available.Count].GetColor(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using GangsAPI.Services; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Gangs.SpecialDayColorPerk; | ||
|
||
public class SDColorBootstrap { | ||
public SDColorBootstrap(IServiceProvider collection) { | ||
new SDColorCommand(collection).Start(); | ||
collection.GetRequiredService<IPerkManager>() | ||
.Perks.Add(new SDColorPerk(collection)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
using Gangs.BombIconPerk; | ||
using GangsAPI; | ||
using GangsAPI.Data; | ||
using GangsAPI.Data.Command; | ||
using GangsAPI.Exceptions; | ||
using GangsAPI.Extensions; | ||
using GangsAPI.Perks; | ||
using GangsAPI.Permissions; | ||
using GangsAPI.Services; | ||
using GangsAPI.Services.Commands; | ||
using GangsAPI.Services.Gang; | ||
using GangsAPI.Services.Menu; | ||
using GangsAPI.Services.Player; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Localization; | ||
using Stats.Perk.Smoke; | ||
|
||
namespace Gangs.SpecialDayColorPerk; | ||
|
||
public class SDColorCommand(IServiceProvider provider) : ICommand { | ||
private readonly ICommandManager commands = | ||
provider.GetRequiredService<ICommandManager>(); | ||
|
||
private readonly IEcoManager eco = provider.GetRequiredService<IEcoManager>(); | ||
|
||
private readonly IGangChatPerk? gangChat = | ||
provider.GetService<IGangChatPerk>(); | ||
|
||
private readonly IGangManager gangs = | ||
provider.GetRequiredService<IGangManager>(); | ||
|
||
private readonly IGangStatManager gangStats = | ||
provider.GetRequiredService<IGangStatManager>(); | ||
|
||
private readonly IStringLocalizer localizer = | ||
provider.GetRequiredService<IStringLocalizer>(); | ||
|
||
private readonly IMenuManager menus = | ||
provider.GetRequiredService<IMenuManager>(); | ||
|
||
private readonly IPlayerManager players = | ||
provider.GetRequiredService<IPlayerManager>(); | ||
|
||
private readonly IRankManager ranks = | ||
provider.GetRequiredService<IRankManager>(); | ||
|
||
public string Name => "css_sdcolor"; | ||
public string[] Usage => ["<color>"]; | ||
|
||
public void Start() { commands.RegisterCommand(this); } | ||
|
||
public async Task<CommandResult> Execute(PlayerWrapper? executor, | ||
CommandInfoWrapper info) { | ||
if (executor == null) return CommandResult.PLAYER_ONLY; | ||
var player = await players.GetPlayer(executor.Steam) | ||
?? throw new PlayerNotFoundException(executor.Steam); | ||
if (player.GangId == null) { | ||
info.ReplySync(localizer.Get(MSG.NOT_IN_GANG)); | ||
return CommandResult.SUCCESS; | ||
} | ||
|
||
var gang = await gangs.GetGang(player.GangId.Value) | ||
?? throw new GangNotFoundException(player.GangId.Value); | ||
|
||
var (success, data) = | ||
await gangStats.GetForGang<SDColorData>(gang, SDColorPerk.STAT_ID); | ||
|
||
if (!success || data == null) data = new SDColorData(); | ||
|
||
if (info.ArgCount == 1) { | ||
var menu = new SDColorMenu(provider, data); | ||
await menus.OpenMenu(executor, menu); | ||
return CommandResult.SUCCESS; | ||
} | ||
|
||
SDColor color; | ||
var query = string.Join('_', info.Args.Skip(1)).ToUpper(); | ||
if (!int.TryParse(info[1], out var iconInt) || iconInt < 0) { | ||
if (!Enum.TryParse(query, out color)) { | ||
info.ReplySync(localizer.Get(MSG.COMMAND_INVALID_PARAM, info[1], | ||
"a positive integer")); | ||
return CommandResult.SUCCESS; | ||
} | ||
} else { color = (SDColor)iconInt; } | ||
|
||
if (!data.Unlocked.HasFlag(color)) { | ||
var (canPurchase, minRank) = await ranks.CheckRank(player, | ||
Perm.PURCHASE_PERKS); | ||
|
||
if (!canPurchase) { | ||
info.ReplySync(localizer.Get(MSG.GENERIC_NOPERM_RANK, minRank.Name)); | ||
return CommandResult.SUCCESS; | ||
} | ||
|
||
var cost = color.GetCost(); | ||
if (await eco.TryPurchase(executor, cost, | ||
item: "Bomb Icon: " + color.ToString().ToTitleCase()) < 0) | ||
return CommandResult.SUCCESS; | ||
|
||
data.Unlocked |= color; | ||
data.Equipped = color; | ||
|
||
await gangStats.SetForGang(gang, SDColorPerk.STAT_ID, data); | ||
|
||
if (gangChat == null) return CommandResult.SUCCESS; | ||
|
||
await gangChat.SendGangChat(player, gang, | ||
localizer.Get(MSG.PERK_PURCHASED, color.ToString())); | ||
return CommandResult.SUCCESS; | ||
} | ||
|
||
if (data.Equipped == color) return CommandResult.SUCCESS; | ||
|
||
var (canManage, required) = | ||
await ranks.CheckRank(player, Perm.MANAGE_PERKS); | ||
if (!canManage) { | ||
info.ReplySync(localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); | ||
return CommandResult.SUCCESS; | ||
} | ||
|
||
data.Equipped = color; | ||
await gangStats.SetForGang(gang, BombPerk.STAT_ID, data); | ||
|
||
if (gangChat == null) return CommandResult.SUCCESS; | ||
|
||
await gangChat.SendGangChat(player, gang, | ||
localizer.Get(MSG.GANG_THING_SET, "SD Color", | ||
color.ToString().ToTitleCase())); | ||
return CommandResult.SUCCESS; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using CounterStrikeSharp.API.Modules.Commands; | ||
using CounterStrikeSharp.API.Modules.Utils; | ||
using Gangs.SpecialDayColorPerk; | ||
using GangsAPI.Data; | ||
using GangsAPI.Extensions; | ||
using GangsAPI.Menu; | ||
using GangsAPI.Services.Commands; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Stats.Perk.Smoke; | ||
|
||
public class SDColorMenu(IServiceProvider provider, SDColorData data) | ||
: AbstractPagedMenu<SDColor>(provider, NativeSenders.Chat) { | ||
private readonly ICommandManager commands = | ||
provider.GetRequiredService<ICommandManager>(); | ||
|
||
// Method to sort smoke colors | ||
private int CompareSmokeColors(SDColor a, SDColor b) { | ||
// If the icon is equipped, it should be first | ||
if (a == data.Equipped) return -1; | ||
if (b == data.Equipped) return 1; | ||
|
||
// If icon is unlocked, it should be next | ||
// If both are unlocked, sort by cost (highest first) | ||
if (data.Unlocked.HasFlag(a)) { | ||
if (data.Unlocked.HasFlag(b)) return a.GetCost().CompareTo(b.GetCost()); | ||
return -1; | ||
} | ||
|
||
// If both are locked, sort by cost (lowest first) | ||
if (data.Unlocked.HasFlag(b)) return 1; | ||
return a.GetCost().CompareTo(b.GetCost()); | ||
} | ||
|
||
|
||
override protected Task<List<SDColor>> GetItems(PlayerWrapper player) { | ||
var list = Enum.GetValues<SDColor>().ToList(); | ||
list.Sort(CompareSmokeColors); | ||
list.Insert(0, 0); | ||
return Task.FromResult(list); | ||
} | ||
|
||
override protected Task HandleItemSelection(PlayerWrapper player, | ||
List<SDColor> items, int selectedIndex) { | ||
commands.ProcessCommand(player, CommandCallingContext.Chat, "css_sdcolor", | ||
items[selectedIndex].ToString()); | ||
Close(player); | ||
return Task.CompletedTask; | ||
} | ||
|
||
override protected Task<string> FormatItem(PlayerWrapper player, int index, | ||
SDColor item) { | ||
var name = item.ToString().ToTitleCase(); | ||
if (item == 0) | ||
return Task.FromResult( | ||
$" {ChatColors.DarkBlue}Gang Perks: {ChatColors.LightBlue}Special Day Colors"); | ||
if (item == data.Equipped) | ||
return Task.FromResult( | ||
$"{index}. {item.GetChatColor()}{name} {ChatColors.Green}({ChatColors.Lime}Equipped{ChatColors.Green})"); | ||
if (data.Unlocked.HasFlag(item)) | ||
return Task.FromResult( | ||
$"{index}. {item.GetChatColor()}{name} {ChatColors.Green}({ChatColors.Grey}Unlocked{ChatColors.Green})"); | ||
return Task.FromResult( | ||
$"{index}. {item.GetChatColor()}{name} {ChatColors.DarkRed}({ChatColors.LightRed}{item.GetCost()}{ChatColors.DarkRed})"); | ||
} | ||
} |
Oops, something went wrong.