Skip to content

Commit

Permalink
Add special day color perk
Browse files Browse the repository at this point in the history
  • Loading branch information
MSWS committed Sep 18, 2024
1 parent b8a606d commit 8fafbc3
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 5 deletions.
7 changes: 7 additions & 0 deletions Jailbreak.sln
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gangs.Boostrap", "mod\Gangs
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gangs", "Gangs", "{069A4F54-AE2A-4FDF-A5A8-F550B254C2A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gangs.SpecialDayColorPerk", "mod\Gangs.SpecialDayColorPerk\Gangs.SpecialDayColorPerk.csproj", "{17AD9AA2-6014-47E3-B39D-4C9942C619DD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -142,6 +144,10 @@ Global
{214E54DB-DD70-4B61-BFFC-596C2717E333}.Debug|Any CPU.Build.0 = Debug|Any CPU
{214E54DB-DD70-4B61-BFFC-596C2717E333}.Release|Any CPU.ActiveCfg = Release|Any CPU
{214E54DB-DD70-4B61-BFFC-596C2717E333}.Release|Any CPU.Build.0 = Release|Any CPU
{17AD9AA2-6014-47E3-B39D-4C9942C619DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17AD9AA2-6014-47E3-B39D-4C9942C619DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17AD9AA2-6014-47E3-B39D-4C9942C619DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17AD9AA2-6014-47E3-B39D-4C9942C619DD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9135CCC9-66C5-4A9C-AE3C-91475B5F0437} = {177DA48D-8306-4102-918D-992569878581}
Expand All @@ -166,5 +172,6 @@ Global
{4035945A-80FA-49E7-A9BF-069FEA3213E5} = {069A4F54-AE2A-4FDF-A5A8-F550B254C2A9}
{80F8E8F7-6976-414D-AFC0-17E1E3ABD746} = {069A4F54-AE2A-4FDF-A5A8-F550B254C2A9}
{214E54DB-DD70-4B61-BFFC-596C2717E333} = {069A4F54-AE2A-4FDF-A5A8-F550B254C2A9}
{17AD9AA2-6014-47E3-B39D-4C9942C619DD} = {069A4F54-AE2A-4FDF-A5A8-F550B254C2A9}
EndGlobalSection
EndGlobal
5 changes: 2 additions & 3 deletions mod/Gangs.BombIconPerk/BombIconBootstrap.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using CounterStrikeSharp.API.Core;
using GangsAPI.Services;
using GangsAPI.Services;
using Microsoft.Extensions.DependencyInjection;

namespace Gangs.BombIconPerk;

public class BombIconBootstrap {
public BombIconBootstrap(IServiceProvider collection, BasePlugin plugin) {
public BombIconBootstrap(IServiceProvider collection) {
new BombIconCommand(collection).Start();
collection.GetRequiredService<IPerkManager>()
.Perks.Add(new BombPerk(collection));
Expand Down
1 change: 1 addition & 0 deletions mod/Gangs.BombIconPerk/BombIconCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public async Task<CommandResult> Execute(PlayerWrapper? executor,
return CommandResult.SUCCESS;

data.Unlocked |= icon;
data.Equipped = icon;

await gangStats.SetForGang(gang, BombPerk.STAT_ID, data);

Expand Down
2 changes: 1 addition & 1 deletion mod/Gangs.Boostrap/GangsServiceExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public void Start(BasePlugin basePlugin) {
var services = API.Gangs?.Services;
if (services == null) return;

_ = new BombIconBootstrap(services, basePlugin);
_ = new BombIconBootstrap(services);
}
}
24 changes: 24 additions & 0 deletions mod/Gangs.SpecialDayColorPerk/Gangs.SpecialDayColorPerk.csproj
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>
76 changes: 76 additions & 0 deletions mod/Gangs.SpecialDayColorPerk/SDColor.cs
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();
}
}
12 changes: 12 additions & 0 deletions mod/Gangs.SpecialDayColorPerk/SDColorBootstrap.cs
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));
}
}
131 changes: 131 additions & 0 deletions mod/Gangs.SpecialDayColorPerk/SDColorCommand.cs
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;
}
}
66 changes: 66 additions & 0 deletions mod/Gangs.SpecialDayColorPerk/SDColorMenu.cs
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})");
}
}
Loading

0 comments on commit 8fafbc3

Please sign in to comment.