Skip to content

Commit

Permalink
Merge pull request #83 from Macoron/continue-bounties
Browse files Browse the repository at this point in the history
Bounty Contracts updates
  • Loading branch information
Cheackraze committed Jul 27, 2023
2 parents 4a77a96 + f99e9f5 commit 27e62f4
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

<!-- New Contract Details -->
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
<BoxContainer Orientation="Horizontal" Margin="4,4,4,4">
<Label Text="{Loc 'bounty-contracts-ui-create-category'}" MinWidth="80"/>
<OptionButton Name="CategorySelector" HorizontalExpand="True" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="4,4,4,4">
<Label Text="{Loc 'bounty-contracts-ui-create-name'}" MinWidth="80"/>
<OptionButton Name="NameSelector" HorizontalExpand="True"/>
Expand All @@ -13,7 +17,7 @@
<Button Name="CustomNameButton" Text="{Loc 'bounty-contracts-ui-create-custom'}"
ToggleMode="True"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="4,4,4,4">
<BoxContainer Name="DnaBox" Orientation="Horizontal" Margin="4,4,4,4">
<Label Text="{Loc 'bounty-contracts-ui-create-dna'}" MinWidth="80"/>
<Label Name="DnaLabel" Text="{Loc 'bounty-contracts-ui-create-dna-unknown'}"
HorizontalExpand="True"/>
Expand Down Expand Up @@ -41,7 +45,7 @@
<PanelContainer StyleClasses="LowDivider" />
</BoxContainer>
<RichTextLabel Name="DisclaimerLabel" Margin="4,4,4,4"
HorizontalExpand="True"/>
HorizontalExpand="True" Visible="False"/>
</BoxContainer>

<!-- Footer -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,23 @@ public sealed partial class BountyContractUiFragmentCreate : Control
public BountyContractUiFragmentCreate()
{
RobustXamlLoader.Load(this);
NameSelector.OnItemSelected += (opt) => OnNameSelected(opt.Id);
VeselSelector.OnItemSelected += (opt) => OnVesselSelected(opt.Id);
CategorySelector.OnItemSelected += opt => OnCategorySelected(opt.Id);
NameSelector.OnItemSelected += opt => OnNameSelected(opt.Id);
VeselSelector.OnItemSelected += opt => OnVesselSelected(opt.Id);

CustomNameButton.OnToggled += OnCustomNameToggle;
CustomVeselButton.OnToggled += OnCustomVeselToggle;
CustomNameButton.OnToggled += args => OnCustomNameToggle(args.Pressed);
CustomVeselButton.OnToggled += args => OnCustomVeselToggle(args.Pressed);
NameEdit.OnTextChanged += NameEditOnTextChanged;
RewardEdit.OnTextChanged += OnPriceChanged;

var descPlaceholder = Loc.GetString("bounty-contracts-ui-create-description-placeholder");
DescriptionEdit.Placeholder = new Rope.Leaf(descPlaceholder);
RewardEdit.Text = SharedBountyContractSystem.MinimalReward.ToString();
RewardEdit.Text = SharedBountyContractSystem.DefaultReward.ToString();

CreateButton.OnPressed += _ => OnCreatePressed?.Invoke(GetBountyContract());
CancelButton.OnPressed += _ => OnCancelPressed?.Invoke();

FillCategories();
UpdateDisclaimer();
}

Expand Down Expand Up @@ -84,9 +86,25 @@ public void SetVessels(List<string> vessels)
OnVesselSelected(0);
}

private void FillCategories()
{
foreach (var (id, meta) in SharedBountyContractSystem.CategoriesMeta)
{
var name = Loc.GetString(meta.Name);
CategorySelector.AddItem(name, (byte) id);
}
}

private void UpdateDna(string? dnaStr)
{
DnaLabel.Text = dnaStr ?? Loc.GetString("bounty-contracts-ui-create-dna-unknown");
if (string.IsNullOrEmpty(dnaStr))
{
DnaBox.Visible = false;
return;
}

DnaBox.Visible = true;
DnaLabel.Text = dnaStr;
}

private void OnNameSelected(int itemIndex)
Expand All @@ -112,19 +130,28 @@ private void OnVesselSelected(int itemIndex)
VeselSelector.SelectId(itemIndex);
}

private void OnCustomNameToggle(BaseButton.ButtonToggledEventArgs customToggle)
private void OnCategorySelected(int objId)
{
var cat = (BountyContractCategory) objId;
CustomNameButton.Pressed = cat != BountyContractCategory.Criminal;
OnCustomNameToggle(CustomNameButton.Pressed);

CategorySelector.SelectId(objId);
}

private void OnCustomNameToggle(bool isPressed)
{
NameSelector.Visible = !customToggle.Pressed;
NameEdit.Visible = customToggle.Pressed;
NameSelector.Visible = !isPressed;
NameEdit.Visible = isPressed;

UpdateDna(GetTargetDna());
UpdateDisclaimer();
}

private void OnCustomVeselToggle(BaseButton.ButtonToggledEventArgs customToggle)
private void OnCustomVeselToggle(bool isPressed)
{
VeselSelector.Visible = !customToggle.Pressed;
VeselEdit.Visible = customToggle.Pressed;
VeselSelector.Visible = !isPressed;
VeselEdit.Visible = isPressed;

OnVesselSelected(0);
}
Expand All @@ -133,10 +160,9 @@ private void UpdateDisclaimer()
{
// check if reward is valid
var reward = GetReward();
if (reward < SharedBountyContractSystem.MinimalReward)
if (reward == null || reward < 0)
{
var err = Loc.GetString("bounty-contracts-ui-create-error-too-cheap",
("reward", SharedBountyContractSystem.MinimalReward));
var err = Loc.GetString("bounty-contracts-ui-create-error-invalid-price");
DisclaimerLabel.SetMessage(err);
CreateButton.Disabled = true;
return;
Expand All @@ -157,10 +183,10 @@ private void UpdateDisclaimer()
CreateButton.Disabled = false;
}

public int GetReward()
public int? GetReward()
{
var priceStr = RewardEdit.Text;
return int.TryParse(priceStr, out var price) ? price : 0;
return int.TryParse(priceStr, out var price) ? price : null;
}

public BountyContractTargetInfo? GetTargetInfo()
Expand Down Expand Up @@ -214,15 +240,21 @@ public string GetVessel()
return vessel;
}

public BountyContractCategory GetCategory()
{
return (BountyContractCategory) CategorySelector.SelectedId;
}

public BountyContractRequest GetBountyContract()
{
var info = new BountyContractRequest
{
Category = GetCategory(),
Name = GetTargetName(),
DNA = GetTargetDna(),
Vessel = GetVessel(),
Description = Rope.Collapse(DescriptionEdit.TextRope),
Reward = GetReward()
Reward = GetReward() ?? 0
};
return info;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<Control xmlns="https://spacestation14.io">
<PanelContainer Margin="8,8,8,8" StyleClasses="AngleRect" >
<BoxContainer Orientation="Vertical">
<PanelContainer Name="BountyPanel" Margin="8" StyleClasses="AngleRect" >
<BoxContainer Orientation="Vertical" Margin="4" >
<BoxContainer Orientation="Horizontal">
<Label Name="BountyName" HorizontalExpand="True" />
<Label Name="BountyReward" HorizontalExpand="True"
HorizontalAlignment="Right"/>
</BoxContainer>
<PanelContainer StyleClasses="HighDivider" />
<Label Name="BountyCategory" StyleClasses="WindowFooterText"/>
<BoxContainer HorizontalExpand="True">
<RichTextLabel Name="BountyDescription" StyleClasses="LabelSubText"/>
</BoxContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,14 @@ public BountyContractUiFragmentListEntry(BountyContract contract, bool canRemove
// remove button
RemoveButton.OnPressed += _ => OnRemoveButtonPressed?.Invoke(contract);
RemoveButton.Disabled = !canRemoveContracts;

// color
var meta = SharedBountyContractSystem.CategoriesMeta[contract.Category];
BountyPanel.ModulateSelfOverride = meta.UiColor;

// category
var category = Loc.GetString(meta.Name);
BountyCategory.Text = Loc.GetString("bounty-contracts-ui-list-category",
("category", category));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,8 @@ private void OnTryCreateContract(EntityUid uid, CartridgeLoaderComponent compone
return;

var c = args.Contract;
if (c.Reward < MinimalReward)
return;

var author = GetContractAuthor(args.Entity);
CreateBountyContract(c.Name, c.Reward, c.Description, c.Vessel, c.DNA, author);
CreateBountyContract(c.Category, c.Name, c.Reward, c.Description, c.Vessel, c.DNA, author);

CartridgeOpenListUi(args.Entity);
}
Expand Down
6 changes: 4 additions & 2 deletions Content.Server/_NF/BountyContracts/BountyContractSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ private void OnRoundStarting(RoundStartingEvent ev)
/// <summary>
/// Try to create a new bounty contract and put it in bounties list.
/// </summary>
/// <param name="category">Bounty contract category (bounty head, construction, etc.)</param>
/// <param name="name">IC name for the contract bounty head. Can be players IC name or custom string.</param>
/// <param name="reward">Cash reward for completing bounty. Can be zero.</param>
/// <param name="description">IC description of players crimes, details, etc.</param>
Expand All @@ -67,7 +68,8 @@ private void OnRoundStarting(RoundStartingEvent ev)
/// <param name="author">Optional bounty poster IC name.</param>
/// <param name="postToRadio">Should radio message about contract be posted in general radio channel?</param>
/// <returns>New bounty contract. Null if contract creation failed.</returns>
public BountyContract? CreateBountyContract(string name, int reward,
public BountyContract? CreateBountyContract(BountyContractCategory category,
string name, int reward,
string? description = null, string? vessel = null,
string? dna = null, string? author = null,
bool postToRadio = true)
Expand All @@ -78,7 +80,7 @@ private void OnRoundStarting(RoundStartingEvent ev)

// create a new contract
var contractId = data.LastId++;
var contract = new BountyContract(contractId, name, reward,
var contract = new BountyContract(contractId, category, name, reward,
dna, vessel, description, author);

// try to save it
Expand Down
57 changes: 53 additions & 4 deletions Content.Shared/_NF/BountyContracts/SharedBountyContractSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

namespace Content.Shared._NF.BountyContracts;

[Serializable, NetSerializable]
public enum BountyContractCategory : byte
{
Criminal,
Vacancy,
Construction,
Service,
Other
}

[Serializable, NetSerializable]
public struct BountyContractCategoryMeta
{
public string Name;
public Color UiColor;
}

[NetSerializable, Serializable]
public struct BountyContractTargetInfo
{
Expand All @@ -27,6 +44,7 @@ public override int GetHashCode()
[NetSerializable, Serializable]
public struct BountyContractRequest
{
public BountyContractCategory Category;
public string Name;
public string? DNA;
public string Vessel;
Expand All @@ -38,17 +56,19 @@ public struct BountyContractRequest
public sealed class BountyContract
{
public readonly uint ContractId;
public readonly BountyContractCategory Category;
public readonly string Name;
public readonly int Reward;
public readonly string? DNA;
public readonly string? Vessel;
public readonly string? Description;
public readonly string? Author;

public BountyContract(uint contractId, string name, int reward,
string? dna, string? vessel, string? description, string? author)
public BountyContract(uint contractId, BountyContractCategory category, string name,
int reward, string? dna, string? vessel, string? description, string? author)
{
ContractId = contractId;
Category = category;
Name = name;
Reward = reward;
DNA = dna;
Expand Down Expand Up @@ -129,6 +149,35 @@ public BountyContractTryCreateMsg(BountyContractRequest contract)

public abstract class SharedBountyContractSystem : EntitySystem
{
// TODO: Cvar?
public const int MinimalReward = 10000;
public const int DefaultReward = 5000;

// TODO: move this to prototypes?
public static readonly Dictionary<BountyContractCategory, BountyContractCategoryMeta> CategoriesMeta = new()
{
[BountyContractCategory.Criminal] = new BountyContractCategoryMeta
{
Name = "bounty-contracts-category-criminal",
UiColor = Color.FromHex("#520c0c")
},
[BountyContractCategory.Vacancy] = new BountyContractCategoryMeta
{
Name = "bounty-contracts-category-vacancy",
UiColor = Color.FromHex("#003866")
},
[BountyContractCategory.Construction] = new BountyContractCategoryMeta
{
Name = "bounty-contracts-category-construction",
UiColor = Color.FromHex("#664a06")
},
[BountyContractCategory.Service] = new BountyContractCategoryMeta
{
Name = "bounty-contracts-category-service",
UiColor = Color.FromHex("#01551e")
},
[BountyContractCategory.Other] = new BountyContractCategoryMeta
{
Name = "bounty-contracts-category-other",
UiColor = Color.FromHex("#474747")
},
};
}
24 changes: 16 additions & 8 deletions Resources/Locale/en-US/_NF/bounty-contracts/bounty-contracts.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,47 @@ bounty-contracts-author = {$name} ({$job})
bounty-contracts-unknown-author-name = Unknown
bounty-contracts-unknown-author-job = Unknown
# Caregories
bounty-contracts-category-criminal = Wanted Criminal
bounty-contracts-category-vacancy = Job Vacancy
bounty-contracts-category-construction = Construction
bounty-contracts-category-service = Service
bounty-contracts-category-other = Other
# Cartridge
bounty-contracts-program-name = Bounty Contracts
## Radio Announcements
bounty-contracts-radio-name = Bounty Contracts Service
bounty-contracts-radio-create = New bounty placed for {$target}. Reward: {$reward}$.
bounty-contracts-radio-create = New bounty placed for "{$target}". Reward: {$reward}$.
## UI - List contracts
bounty-contracts-ui-list-no-contracts = No bounties posted yet...
bounty-contracts-ui-list-no-description = No additional description provided...
bounty-contracts-ui-list-create = New Contract
bounty-contracts-ui-list-create = New Bounty
bounty-contracts-ui-list-refresh = Refresh
bounty-contracts-ui-list-vessel = Last Known Vessel: {$vessel}
bounty-contracts-ui-list-category = Category: {$category}
bounty-contracts-ui-list-vessel = Vessel: {$vessel}
bounty-contracts-ui-list-author = Posted by: {$author}
bounty-contracts-ui-list-remove = Remove
## UI - Create contract
bounty-contracts-ui-create-category = Category:{" "}
bounty-contracts-ui-create-name = Name:{" "}
bounty-contracts-ui-create-custom = Custom
bounty-contracts-ui-create-name-placeholder = Target name...
bounty-contracts-ui-create-name-placeholder = Bounty name...
bounty-contracts-ui-create-dna = DNA:{" "}
bounty-contracts-ui-create-dna-unknown = N/A
bounty-contracts-ui-create-vessel = Vessel:{" "}
bounty-contracts-ui-create-vessel-unknown = Unknown
bounty-contracts-ui-create-vessel-placeholder = Vessel name...
bounty-contracts-ui-create-reward = Reward:{" "}
bounty-contracts-ui-create-reward-currency = $
bounty-contracts-ui-create-description = Description:
bounty-contracts-ui-create-description-placeholder = Crimes, additional details...
bounty-contracts-ui-create-description-placeholder = Additional details...
bounty-contracts-ui-create-button-cancel = Cancel
bounty-contracts-ui-create-button-create = Create
bounty-contracts-ui-create-error-too-cheap = Error: Invalid price! Minimal contract reward is {$reward}$.
bounty-contracts-ui-create-error-no-name = Error: Invalid bounty target name!
bounty-contracts-ui-create-error-invalid-price = Error: Invalid price!
bounty-contracts-ui-create-error-no-name = Error: Invalid bounty name!
bounty-contracts-ui-create-ready = Your contract is ready to be published!

0 comments on commit 27e62f4

Please sign in to comment.