Antag preferences and antag prototype (#1264)
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.GameObjects.Components;
|
using Content.Client.GameObjects.Components;
|
||||||
@@ -6,6 +6,7 @@ using Content.Client.Interfaces;
|
|||||||
using Content.Client.Utility;
|
using Content.Client.Utility;
|
||||||
using Content.Shared;
|
using Content.Shared;
|
||||||
using Content.Shared.Jobs;
|
using Content.Shared.Jobs;
|
||||||
|
using Content.Shared.Antags;
|
||||||
using Content.Shared.Preferences;
|
using Content.Shared.Preferences;
|
||||||
using Robust.Client.Graphics.Drawing;
|
using Robust.Client.Graphics.Drawing;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
@@ -42,6 +43,7 @@ namespace Content.Client.UserInterface
|
|||||||
private readonly FacialHairStylePicker _facialHairPicker;
|
private readonly FacialHairStylePicker _facialHairPicker;
|
||||||
private readonly List<JobPrioritySelector> _jobPriorities;
|
private readonly List<JobPrioritySelector> _jobPriorities;
|
||||||
private readonly OptionButton _preferenceUnavailableButton;
|
private readonly OptionButton _preferenceUnavailableButton;
|
||||||
|
private readonly List<AntagPreferenceSelector> _antagPreferences;
|
||||||
|
|
||||||
private bool _isDirty;
|
private bool _isDirty;
|
||||||
public int CharacterSlot;
|
public int CharacterSlot;
|
||||||
@@ -320,6 +322,52 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Antags
|
||||||
|
|
||||||
|
{
|
||||||
|
var antagList = new VBoxContainer();
|
||||||
|
|
||||||
|
var antagVBox = new VBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new ScrollContainer
|
||||||
|
{
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
antagList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tabContainer.AddChild(antagVBox);
|
||||||
|
|
||||||
|
tabContainer.SetTabTitle(2, Loc.GetString("Antags"));
|
||||||
|
|
||||||
|
_antagPreferences = new List<AntagPreferenceSelector>();
|
||||||
|
|
||||||
|
foreach (var antag in prototypeManager.EnumeratePrototypes<AntagPrototype>().OrderBy(a => a.Name))
|
||||||
|
{
|
||||||
|
if(!antag.SetPreference)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var selector = new AntagPreferenceSelector(antag);
|
||||||
|
antagList.AddChild(selector);
|
||||||
|
_antagPreferences.Add(selector);
|
||||||
|
|
||||||
|
selector.PreferenceChanged += preference =>
|
||||||
|
{
|
||||||
|
Profile = Profile.WithAntagPreference(antag.ID, preference);
|
||||||
|
IsDirty = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
var rightColumn = new VBoxContainer();
|
var rightColumn = new VBoxContainer();
|
||||||
middleContainer.AddChild(rightColumn);
|
middleContainer.AddChild(rightColumn);
|
||||||
|
|
||||||
@@ -466,6 +514,7 @@ namespace Content.Client.UserInterface
|
|||||||
UpdateHairPickers();
|
UpdateHairPickers();
|
||||||
UpdateSaveButton();
|
UpdateSaveButton();
|
||||||
UpdateJobPriorities();
|
UpdateJobPriorities();
|
||||||
|
UpdateAntagPreferences();
|
||||||
|
|
||||||
_preferenceUnavailableButton.SelectId((int) Profile.PreferenceUnavailable);
|
_preferenceUnavailableButton.SelectId((int) Profile.PreferenceUnavailable);
|
||||||
}
|
}
|
||||||
@@ -533,5 +582,51 @@ namespace Content.Client.UserInterface
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateAntagPreferences()
|
||||||
|
{
|
||||||
|
foreach (var preferenceSelector in _antagPreferences)
|
||||||
|
{
|
||||||
|
var antagId = preferenceSelector.Antag.ID;
|
||||||
|
|
||||||
|
var preference = Profile.AntagPreferences.Contains(antagId);
|
||||||
|
|
||||||
|
preferenceSelector.Preference = preference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AntagPreferenceSelector : Control
|
||||||
|
{
|
||||||
|
public AntagPrototype Antag { get; }
|
||||||
|
private readonly CheckBox _checkBox;
|
||||||
|
|
||||||
|
public bool Preference
|
||||||
|
{
|
||||||
|
get => _checkBox.Pressed;
|
||||||
|
set => _checkBox.Pressed = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<bool> PreferenceChanged;
|
||||||
|
|
||||||
|
public AntagPreferenceSelector(AntagPrototype antag)
|
||||||
|
{
|
||||||
|
Antag = antag;
|
||||||
|
|
||||||
|
_checkBox = new CheckBox {Text = $"{antag.Name}"};
|
||||||
|
_checkBox.OnToggled += OnCheckBoxToggled;
|
||||||
|
|
||||||
|
AddChild(new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
_checkBox
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
PreferenceChanged?.Invoke(Preference);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
185
Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs
generated
Normal file
185
Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs
generated
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Content.Server.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Postgres
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PostgresPreferencesDbContext))]
|
||||||
|
[Migration("20200706172726_Antags")]
|
||||||
|
partial class Antags
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.4")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AntagId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<string>("AntagName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("AntagId");
|
||||||
|
|
||||||
|
b.HasIndex("HumanoidProfileId", "AntagName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Antag");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<int>("Age")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("CharacterName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("EyeColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("FacialHairColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("FacialHairName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("HairColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("HairName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("PreferenceUnavailable")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("PrefsId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("SkinColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("Slot")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("SlotName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("HumanoidProfileId");
|
||||||
|
|
||||||
|
b.HasIndex("PrefsId");
|
||||||
|
|
||||||
|
b.HasIndex("Slot", "PrefsId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("HumanoidProfile");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Job", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("JobId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("Priority")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("ProfileHumanoidProfileId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("JobId");
|
||||||
|
|
||||||
|
b.HasIndex("ProfileHumanoidProfileId");
|
||||||
|
|
||||||
|
b.ToTable("Job");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Prefs", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrefsId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<int>("SelectedCharacterSlot")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("PrefsId");
|
||||||
|
|
||||||
|
b.HasIndex("Username")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Preferences");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Antags")
|
||||||
|
.HasForeignKey("HumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
||||||
|
.WithMany("HumanoidProfiles")
|
||||||
|
.HasForeignKey("PrefsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Job", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Jobs")
|
||||||
|
.HasForeignKey("ProfileHumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Postgres
|
||||||
|
{
|
||||||
|
public partial class Antags : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Antag",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
AntagId = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
HumanoidProfileId = table.Column<int>(nullable: false),
|
||||||
|
AntagName = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Antag", x => x.AntagId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Antag_HumanoidProfile_HumanoidProfileId",
|
||||||
|
column: x => x.HumanoidProfileId,
|
||||||
|
principalTable: "HumanoidProfile",
|
||||||
|
principalColumn: "HumanoidProfileId",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Antag_HumanoidProfileId_AntagName",
|
||||||
|
table: "Antag",
|
||||||
|
columns: new[] { "HumanoidProfileId", "AntagName" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Antag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,28 @@ namespace Content.Server.Database.Migrations.Postgres
|
|||||||
.HasAnnotation("ProductVersion", "3.1.4")
|
.HasAnnotation("ProductVersion", "3.1.4")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AntagId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<string>("AntagName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("AntagId");
|
||||||
|
|
||||||
|
b.HasIndex("HumanoidProfileId", "AntagName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Antag");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("HumanoidProfileId")
|
b.Property<int>("HumanoidProfileId")
|
||||||
@@ -129,6 +151,15 @@ namespace Content.Server.Database.Migrations.Postgres
|
|||||||
b.ToTable("Preferences");
|
b.ToTable("Preferences");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Antags")
|
||||||
|
.HasForeignKey("HumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
||||||
|
|||||||
178
Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs
generated
Normal file
178
Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs
generated
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Content.Server.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Sqlite
|
||||||
|
{
|
||||||
|
[DbContext(typeof(SqlitePreferencesDbContext))]
|
||||||
|
[Migration("20200706172741_Antags")]
|
||||||
|
partial class Antags
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.4");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AntagId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AntagName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("AntagId");
|
||||||
|
|
||||||
|
b.HasIndex("HumanoidProfileId", "AntagName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Antag");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Age")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("CharacterName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("EyeColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("FacialHairColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("FacialHairName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("HairColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("HairName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("PreferenceUnavailable")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PrefsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("SkinColor")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Slot")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SlotName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("HumanoidProfileId");
|
||||||
|
|
||||||
|
b.HasIndex("PrefsId");
|
||||||
|
|
||||||
|
b.HasIndex("Slot", "PrefsId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("HumanoidProfile");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Job", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("JobId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Priority")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ProfileHumanoidProfileId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("JobId");
|
||||||
|
|
||||||
|
b.HasIndex("ProfileHumanoidProfileId");
|
||||||
|
|
||||||
|
b.ToTable("Job");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Prefs", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrefsId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SelectedCharacterSlot")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("PrefsId");
|
||||||
|
|
||||||
|
b.HasIndex("Username")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Preferences");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Antags")
|
||||||
|
.HasForeignKey("HumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
||||||
|
.WithMany("HumanoidProfiles")
|
||||||
|
.HasForeignKey("PrefsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Job", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Jobs")
|
||||||
|
.HasForeignKey("ProfileHumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Content.Server.Database.Migrations.Sqlite
|
||||||
|
{
|
||||||
|
public partial class Antags : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Antag",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
AntagId = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
HumanoidProfileId = table.Column<int>(nullable: false),
|
||||||
|
AntagName = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Antag", x => x.AntagId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Antag_HumanoidProfile_HumanoidProfileId",
|
||||||
|
column: x => x.HumanoidProfileId,
|
||||||
|
principalTable: "HumanoidProfile",
|
||||||
|
principalColumn: "HumanoidProfileId",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Antag_HumanoidProfileId_AntagName",
|
||||||
|
table: "Antag",
|
||||||
|
columns: new[] { "HumanoidProfileId", "AntagName" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Antag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,27 @@ namespace Content.Server.Database.Migrations
|
|||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.4");
|
.HasAnnotation("ProductVersion", "3.1.4");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AntagId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AntagName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("HumanoidProfileId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("AntagId");
|
||||||
|
|
||||||
|
b.HasIndex("HumanoidProfileId", "AntagName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Antag");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("HumanoidProfileId")
|
b.Property<int>("HumanoidProfileId")
|
||||||
@@ -123,6 +144,15 @@ namespace Content.Server.Database.Migrations
|
|||||||
b.ToTable("Preferences");
|
b.ToTable("Preferences");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Content.Server.Database.Antag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
|
||||||
|
.WithMany("Antags")
|
||||||
|
.HasForeignKey("HumanoidProfileId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
b.HasOne("Content.Server.Database.Prefs", "Prefs")
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ namespace Content.Server.Database
|
|||||||
modelBuilder.Entity<HumanoidProfile>()
|
modelBuilder.Entity<HumanoidProfile>()
|
||||||
.HasIndex(p => new {p.Slot, p.PrefsId})
|
.HasIndex(p => new {p.Slot, p.PrefsId})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<Antag>()
|
||||||
|
.HasIndex(p => new {p.HumanoidProfileId , p.AntagName})
|
||||||
|
.IsUnique();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +94,7 @@ namespace Content.Server.Database
|
|||||||
public string EyeColor { get; set; } = null!;
|
public string EyeColor { get; set; } = null!;
|
||||||
public string SkinColor { get; set; } = null!;
|
public string SkinColor { get; set; } = null!;
|
||||||
public List<Job> Jobs { get; } = new List<Job>();
|
public List<Job> Jobs { get; } = new List<Job>();
|
||||||
|
public List<Antag> Antags { get; } = new List<Antag>();
|
||||||
public DbPreferenceUnavailableMode PreferenceUnavailable { get; set; }
|
public DbPreferenceUnavailableMode PreferenceUnavailable { get; set; }
|
||||||
|
|
||||||
public int PrefsId { get; set; }
|
public int PrefsId { get; set; }
|
||||||
@@ -114,6 +119,15 @@ namespace Content.Server.Database
|
|||||||
High = 3
|
High = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Antag
|
||||||
|
{
|
||||||
|
public int AntagId { get; set; }
|
||||||
|
public HumanoidProfile Profile { get; set; } = null!;
|
||||||
|
public int HumanoidProfileId { get; set; }
|
||||||
|
|
||||||
|
public string AntagName { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
public enum DbPreferenceUnavailableMode
|
public enum DbPreferenceUnavailableMode
|
||||||
{
|
{
|
||||||
// These enum values HAVE to match the ones in PreferenceUnavailableMode in Shared.
|
// These enum values HAVE to match the ones in PreferenceUnavailableMode in Shared.
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ namespace Content.Server.Database
|
|||||||
{
|
{
|
||||||
return await _prefsCtx
|
return await _prefsCtx
|
||||||
.Preferences
|
.Preferences
|
||||||
.Include(p => p.HumanoidProfiles)
|
.Include(p => p.HumanoidProfiles).ThenInclude(h => h.Jobs)
|
||||||
.ThenInclude(h => h.Jobs)
|
.Include(p => p.HumanoidProfiles).ThenInclude(h => h.Antags)
|
||||||
.SingleOrDefaultAsync(p => p.Username == username);
|
.SingleOrDefaultAsync(p => p.Username == username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ namespace Content.Server.Database
|
|||||||
{
|
{
|
||||||
return await _prefsCtx.HumanoidProfile
|
return await _prefsCtx.HumanoidProfile
|
||||||
.Include(p => p.Jobs)
|
.Include(p => p.Jobs)
|
||||||
|
.Include(a => a.Antags)
|
||||||
.Join(_prefsCtx.Preferences,
|
.Join(_prefsCtx.Preferences,
|
||||||
profile => new {profile.Slot, profile.PrefsId},
|
profile => new {profile.Slot, profile.PrefsId},
|
||||||
prefs => new {Slot = prefs.SelectedCharacterSlot, prefs.PrefsId},
|
prefs => new {Slot = prefs.SelectedCharacterSlot, prefs.PrefsId},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
|
using Content.Shared.Preferences;
|
||||||
|
|
||||||
namespace Content.Server.GameTicking
|
namespace Content.Server.GameTicking
|
||||||
{
|
{
|
||||||
@@ -11,5 +12,6 @@ namespace Content.Server.GameTicking
|
|||||||
public abstract bool Start(IReadOnlyList<IPlayerSession> readyPlayers, bool force = false);
|
public abstract bool Start(IReadOnlyList<IPlayerSession> readyPlayers, bool force = false);
|
||||||
public virtual string ModeTitle => "Sandbox";
|
public virtual string ModeTitle => "Sandbox";
|
||||||
public virtual string Description => "Secret!";
|
public virtual string Description => "Secret!";
|
||||||
|
public Dictionary<string, HumanoidCharacterProfile> readyProfiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
using System;
|
using Content.Server.GameTicking.GameRules;
|
||||||
using System.Collections.Generic;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.GameTicking.GameRules;
|
|
||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
using Content.Server.Interfaces.GameTicking;
|
using Content.Server.Interfaces.GameTicking;
|
||||||
using Content.Server.Mobs.Roles;
|
using Content.Server.Mobs.Roles;
|
||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
using Content.Server.Sandbox;
|
using Content.Shared.Antags;
|
||||||
using NFluidsynth;
|
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Logger = Robust.Shared.Log.Logger;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Shared.Preferences;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Content.Server.GameTicking.GamePresets
|
namespace Content.Server.GameTicking.GamePresets
|
||||||
{
|
{
|
||||||
@@ -21,11 +27,14 @@ namespace Content.Server.GameTicking.GamePresets
|
|||||||
[Dependency] private readonly IChatManager _chatManager;
|
[Dependency] private readonly IChatManager _chatManager;
|
||||||
[Dependency] private readonly IGameTicker _gameTicker;
|
[Dependency] private readonly IGameTicker _gameTicker;
|
||||||
[Dependency] private readonly IRobustRandom _random;
|
[Dependency] private readonly IRobustRandom _random;
|
||||||
|
[Dependency] private IPrototypeManager _prototypeManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public int MinPlayers { get; set; } = 5;
|
public int MinPlayers { get; set; } = 5;
|
||||||
public int MinTraitors { get; set; } = 2;
|
public int MinTraitors { get; set; } = 2;
|
||||||
public int PlayersPerTraitor { get; set; } = 5;
|
public int PlayersPerTraitor { get; set; } = 5;
|
||||||
|
private static string TraitorID = "SuspicionTraitor";
|
||||||
|
private static string InnocentID = "SuspicionInnocent";
|
||||||
|
|
||||||
public override bool Start(IReadOnlyList<IPlayerSession> readyPlayers, bool force = false)
|
public override bool Start(IReadOnlyList<IPlayerSession> readyPlayers, bool force = false)
|
||||||
{
|
{
|
||||||
@@ -36,20 +45,48 @@ namespace Content.Server.GameTicking.GamePresets
|
|||||||
}
|
}
|
||||||
|
|
||||||
var list = new List<IPlayerSession>(readyPlayers);
|
var list = new List<IPlayerSession>(readyPlayers);
|
||||||
|
var prefList = new List<IPlayerSession>();
|
||||||
|
|
||||||
|
foreach (var player in list)
|
||||||
|
{
|
||||||
|
if (!readyProfiles.ContainsKey(player.Name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var profile = readyProfiles[player.Name];
|
||||||
|
if (profile.AntagPreferences.Contains(_prototypeManager.Index<AntagPrototype>(TraitorID).Name))
|
||||||
|
{
|
||||||
|
prefList.Add(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var numTraitors = Math.Clamp(readyPlayers.Count % PlayersPerTraitor,
|
var numTraitors = Math.Clamp(readyPlayers.Count % PlayersPerTraitor,
|
||||||
MinTraitors, readyPlayers.Count);
|
MinTraitors, readyPlayers.Count);
|
||||||
|
|
||||||
for (var i = 0; i < numTraitors; i++)
|
for (var i = 0; i < numTraitors; i++)
|
||||||
{
|
{
|
||||||
var traitor = _random.PickAndTake(list);
|
IPlayerSession traitor;
|
||||||
|
if(prefList.Count() == 0)
|
||||||
|
{
|
||||||
|
traitor = _random.PickAndTake(list);
|
||||||
|
Logger.InfoS("preset", "Insufficient preferred traitors, picking at random.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traitor = _random.PickAndTake(prefList);
|
||||||
|
list.Remove(traitor);
|
||||||
|
Logger.InfoS("preset", "Selected a preferred traitor.");
|
||||||
|
}
|
||||||
var mind = traitor.Data.ContentData().Mind;
|
var mind = traitor.Data.ContentData().Mind;
|
||||||
mind.AddRole(new SuspicionTraitorRole(mind));
|
var antagPrototype = _prototypeManager.Index<AntagPrototype>(TraitorID);
|
||||||
|
mind.AddRole(new SuspicionTraitorRole(mind, antagPrototype));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var player in list)
|
foreach (var player in list)
|
||||||
{
|
{
|
||||||
var mind = player.Data.ContentData().Mind;
|
var mind = player.Data.ContentData().Mind;
|
||||||
mind.AddRole(new SuspicionInnocentRole(mind));
|
var antagPrototype = _prototypeManager.Index<AntagPrototype>(InnocentID);
|
||||||
|
mind.AddRole(new SuspicionInnocentRole(mind, antagPrototype));
|
||||||
}
|
}
|
||||||
|
|
||||||
_gameTicker.AddGameRule<RuleSuspicion>();
|
_gameTicker.AddGameRule<RuleSuspicion>();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
@@ -38,8 +39,6 @@ namespace Content.Server.GameTicking.GameRules
|
|||||||
|
|
||||||
public override void Added()
|
public override void Added()
|
||||||
{
|
{
|
||||||
_chatManager.DispatchServerAnnouncement("There are traitors on the station! Find them, and kill them!");
|
|
||||||
|
|
||||||
_entityManager.EventBus.SubscribeEvent<MobDamageStateChangedMessage>(EventSource.Local, this, _onMobDamageStateChanged);
|
_entityManager.EventBus.SubscribeEvent<MobDamageStateChangedMessage>(EventSource.Local, this, _onMobDamageStateChanged);
|
||||||
|
|
||||||
Timer.SpawnRepeating(DeadCheckDelay, _checkWinConditions, _checkTimerCancel.Token);
|
Timer.SpawnRepeating(DeadCheckDelay, _checkWinConditions, _checkTimerCancel.Token);
|
||||||
@@ -86,7 +85,6 @@ namespace Content.Server.GameTicking.GameRules
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerSession.ContentData().Mind.HasRole<SuspicionTraitorRole>())
|
if (playerSession.ContentData().Mind.HasRole<SuspicionTraitorRole>())
|
||||||
traitorsAlive++;
|
traitorsAlive++;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -267,12 +267,12 @@ namespace Content.Server.GameTicking
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Time to start the preset.
|
// Time to start the preset.
|
||||||
var preset = MakeGamePreset();
|
var preset = MakeGamePreset(profiles);
|
||||||
|
|
||||||
if (!preset.Start(assignedJobs.Keys.ToList(), force))
|
if (!preset.Start(assignedJobs.Keys.ToList(), force))
|
||||||
{
|
{
|
||||||
SetStartPreset(_configurationManager.GetCVar<string>("game.fallbackpreset"));
|
SetStartPreset(_configurationManager.GetCVar<string>("game.fallbackpreset"));
|
||||||
var newPreset = MakeGamePreset();
|
var newPreset = MakeGamePreset(profiles);
|
||||||
_chatManager.DispatchServerAnnouncement(
|
_chatManager.DispatchServerAnnouncement(
|
||||||
$"Failed to start {preset.ModeTitle} mode! Defaulting to {newPreset.ModeTitle}...");
|
$"Failed to start {preset.ModeTitle} mode! Defaulting to {newPreset.ModeTitle}...");
|
||||||
if (!newPreset.Start(readyPlayers, force))
|
if (!newPreset.Start(readyPlayers, force))
|
||||||
@@ -306,7 +306,7 @@ namespace Content.Server.GameTicking
|
|||||||
|
|
||||||
//Tell every client the round has ended.
|
//Tell every client the round has ended.
|
||||||
var roundEndMessage = _netManager.CreateNetMessage<MsgRoundEndMessage>();
|
var roundEndMessage = _netManager.CreateNetMessage<MsgRoundEndMessage>();
|
||||||
roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle;
|
roundEndMessage.GamemodeTitle = MakeGamePreset(null).ModeTitle;
|
||||||
|
|
||||||
//Get the timespan of the round.
|
//Get the timespan of the round.
|
||||||
roundEndMessage.RoundDuration = IoCManager.Resolve<IGameTiming>().RealTime.Subtract(_roundStartTimeSpan);
|
roundEndMessage.RoundDuration = IoCManager.Resolve<IGameTiming>().RealTime.Subtract(_roundStartTimeSpan);
|
||||||
@@ -318,13 +318,13 @@ namespace Content.Server.GameTicking
|
|||||||
var mind = ply.ContentData().Mind;
|
var mind = ply.ContentData().Mind;
|
||||||
if (mind != null)
|
if (mind != null)
|
||||||
{
|
{
|
||||||
var antag = mind.AllRoles.Any(role => role.Antag);
|
var antag = mind.AllRoles.Any(role => role.Antagonist);
|
||||||
var playerEndRoundInfo = new RoundEndPlayerInfo()
|
var playerEndRoundInfo = new RoundEndPlayerInfo()
|
||||||
{
|
{
|
||||||
PlayerOOCName = ply.Name,
|
PlayerOOCName = ply.Name,
|
||||||
PlayerICName = mind.CurrentEntity.Name,
|
PlayerICName = mind.CurrentEntity.Name,
|
||||||
Role = antag
|
Role = antag
|
||||||
? mind.AllRoles.First(role => role.Antag).Name
|
? mind.AllRoles.First(role => role.Antagonist).Name
|
||||||
: mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"),
|
: mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"),
|
||||||
Antag = antag
|
Antag = antag
|
||||||
};
|
};
|
||||||
@@ -805,7 +805,7 @@ namespace Content.Server.GameTicking
|
|||||||
var mindComponent = mob.GetComponent<MindComponent>();
|
var mindComponent = mob.GetComponent<MindComponent>();
|
||||||
if (mindComponent.HasMind) //Redundancy checks.
|
if (mindComponent.HasMind) //Redundancy checks.
|
||||||
{
|
{
|
||||||
if (mindComponent.Mind.AllRoles.Any(role => role.Antag)) //Give antags a new uplinkaccount.
|
if (mindComponent.Mind.AllRoles.Any(role => role.Antagonist)) //Give antags a new uplinkaccount.
|
||||||
{
|
{
|
||||||
var uplinkAccount =
|
var uplinkAccount =
|
||||||
new UplinkAccount(mob.Uid,
|
new UplinkAccount(mob.Uid,
|
||||||
@@ -883,8 +883,8 @@ namespace Content.Server.GameTicking
|
|||||||
|
|
||||||
private string GetInfoText()
|
private string GetInfoText()
|
||||||
{
|
{
|
||||||
var gmTitle = MakeGamePreset().ModeTitle;
|
var gmTitle = MakeGamePreset(null).ModeTitle;
|
||||||
var desc = MakeGamePreset().Description;
|
var desc = MakeGamePreset(null).Description;
|
||||||
return _localization.GetString(@"Hi and welcome to [color=white]Space Station 14![/color]
|
return _localization.GetString(@"Hi and welcome to [color=white]Space Station 14![/color]
|
||||||
|
|
||||||
The current game mode is: [color=white]{0}[/color].
|
The current game mode is: [color=white]{0}[/color].
|
||||||
@@ -898,9 +898,11 @@ The current game mode is: [color=white]{0}[/color].
|
|||||||
_netManager.ServerSendToMany(infoMsg, _playersInLobby.Keys.Select(p => p.ConnectedClient).ToList());
|
_netManager.ServerSendToMany(infoMsg, _playersInLobby.Keys.Select(p => p.ConnectedClient).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private GamePreset MakeGamePreset()
|
private GamePreset MakeGamePreset(Dictionary<string, HumanoidCharacterProfile> readyProfiles)
|
||||||
{
|
{
|
||||||
return _dynamicTypeFactory.CreateInstance<GamePreset>(_presetType ?? typeof(PresetSandbox));
|
var preset = _dynamicTypeFactory.CreateInstance<GamePreset>(_presetType ?? typeof(PresetSandbox));
|
||||||
|
preset.readyProfiles = readyProfiles;
|
||||||
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace Content.Server.Mobs
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this role should be considered antagonistic or not.
|
/// Whether this role should be considered antagonistic or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract bool Antag { get; }
|
public abstract bool Antagonist { get; }
|
||||||
|
|
||||||
protected Role(Mind mind)
|
protected Role(Mind mind)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Content.Server.Mobs.Roles
|
|||||||
public JobPrototype Prototype { get; }
|
public JobPrototype Prototype { get; }
|
||||||
|
|
||||||
public override string Name { get; }
|
public override string Name { get; }
|
||||||
public override bool Antag => false;
|
public override bool Antagonist => false;
|
||||||
|
|
||||||
public string StartingGear => Prototype.StartingGear;
|
public string StartingGear => Prototype.StartingGear;
|
||||||
|
|
||||||
|
|||||||
@@ -2,24 +2,32 @@ using Content.Server.GameObjects;
|
|||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using Content.Shared.Antags;
|
||||||
|
|
||||||
namespace Content.Server.Mobs.Roles
|
namespace Content.Server.Mobs.Roles
|
||||||
{
|
{
|
||||||
public class SuspicionInnocentRole : Role
|
public class SuspicionInnocentRole : Role
|
||||||
{
|
{
|
||||||
public SuspicionInnocentRole(Mind mind) : base(mind)
|
public AntagPrototype Prototype { get; }
|
||||||
|
|
||||||
|
public SuspicionInnocentRole(Mind mind, AntagPrototype antagPrototype) : base(mind)
|
||||||
{
|
{
|
||||||
|
Prototype = antagPrototype;
|
||||||
|
Name = antagPrototype.Name;
|
||||||
|
Antagonist = antagPrototype.Antagonist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Innocent";
|
public override string Name { get; }
|
||||||
public override bool Antag => false;
|
public string Objective => Prototype.Objective;
|
||||||
|
public override bool Antagonist { get; }
|
||||||
|
|
||||||
public override void Greet()
|
public override void Greet()
|
||||||
{
|
{
|
||||||
base.Greet();
|
base.Greet();
|
||||||
|
|
||||||
var chat = IoCManager.Resolve<IChatManager>();
|
var chat = IoCManager.Resolve<IChatManager>();
|
||||||
chat.DispatchServerMessage(Mind.Session, "You're an innocent!");
|
chat.DispatchServerMessage(Mind.Session, $"You're a {Name}!");
|
||||||
|
chat.DispatchServerMessage(Mind.Session, $"Objective: {Objective}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,33 @@
|
|||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using Content.Shared.Antags;
|
||||||
|
|
||||||
namespace Content.Server.Mobs.Roles
|
namespace Content.Server.Mobs.Roles
|
||||||
{
|
{
|
||||||
public sealed class SuspicionTraitorRole : Role
|
public sealed class SuspicionTraitorRole : Role
|
||||||
{
|
{
|
||||||
public SuspicionTraitorRole(Mind mind) : base(mind)
|
public AntagPrototype Prototype { get; }
|
||||||
|
|
||||||
|
public SuspicionTraitorRole(Mind mind, AntagPrototype antagPrototype) : base(mind)
|
||||||
{
|
{
|
||||||
|
Prototype = antagPrototype;
|
||||||
|
Name = antagPrototype.Name;
|
||||||
|
Antagonist = antagPrototype.Antagonist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Traitor";
|
public override string Name { get; }
|
||||||
public override bool Antag => true;
|
public string Objective => Prototype.Objective;
|
||||||
|
public override bool Antagonist { get; }
|
||||||
|
|
||||||
public override void Greet()
|
public override void Greet()
|
||||||
{
|
{
|
||||||
base.Greet();
|
base.Greet();
|
||||||
|
|
||||||
var chat = IoCManager.Resolve<IChatManager>();
|
var chat = IoCManager.Resolve<IChatManager>();
|
||||||
chat.DispatchServerMessage(Mind.Session, "You're a traitor!");
|
chat.DispatchServerMessage(Mind.Session, $"You're a {Name}!");
|
||||||
|
chat.DispatchServerMessage(Mind.Session, $"Objective: {Objective}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Content.Server.PDA
|
|||||||
var entity = _entityManager.GetEntity(acc.AccountHolder);
|
var entity = _entityManager.GetEntity(acc.AccountHolder);
|
||||||
if (entity.TryGetComponent(out MindComponent mindComponent))
|
if (entity.TryGetComponent(out MindComponent mindComponent))
|
||||||
{
|
{
|
||||||
if (mindComponent.Mind.AllRoles.Any(role => !role.Antag))
|
if (mindComponent.Mind.AllRoles.Any(role => !role.Antagonist))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,10 @@ namespace Content.Server.Preferences
|
|||||||
.Where(j => j.Value != JobPriority.Never)
|
.Where(j => j.Value != JobPriority.Never)
|
||||||
.Select(j => new Job {JobName = j.Key, Priority = (DbJobPriority) j.Value})
|
.Select(j => new Job {JobName = j.Key, Priority = (DbJobPriority) j.Value})
|
||||||
);
|
);
|
||||||
|
entity.Antags.AddRange(
|
||||||
|
humanoid.AntagPreferences
|
||||||
|
.Select(a => new Antag {AntagName = a})
|
||||||
|
);
|
||||||
await _prefsDb.SaveCharacterSlotAsync(username, entity);
|
await _prefsDb.SaveCharacterSlotAsync(username, entity);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -140,6 +144,7 @@ namespace Content.Server.Preferences
|
|||||||
private static HumanoidCharacterProfile ConvertProfiles(HumanoidProfile profile)
|
private static HumanoidCharacterProfile ConvertProfiles(HumanoidProfile profile)
|
||||||
{
|
{
|
||||||
var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority);
|
var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority);
|
||||||
|
var antags = profile.Antags.Select(a => a.AntagName);
|
||||||
return new HumanoidCharacterProfile(
|
return new HumanoidCharacterProfile(
|
||||||
profile.CharacterName,
|
profile.CharacterName,
|
||||||
profile.Age,
|
profile.Age,
|
||||||
@@ -154,7 +159,8 @@ namespace Content.Server.Preferences
|
|||||||
Color.FromHex(profile.SkinColor)
|
Color.FromHex(profile.SkinColor)
|
||||||
),
|
),
|
||||||
jobs,
|
jobs,
|
||||||
(PreferenceUnavailableMode) profile.PreferenceUnavailable
|
(PreferenceUnavailableMode) profile.PreferenceUnavailable,
|
||||||
|
antags.ToList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Shared.Antags;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Preferences
|
namespace Content.Shared.Preferences
|
||||||
@@ -9,6 +12,7 @@ namespace Content.Shared.Preferences
|
|||||||
public class HumanoidCharacterProfile : ICharacterProfile
|
public class HumanoidCharacterProfile : ICharacterProfile
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, JobPriority> _jobPriorities;
|
private readonly Dictionary<string, JobPriority> _jobPriorities;
|
||||||
|
private readonly List<string> _antagPreferences;
|
||||||
public static int MinimumAge = 18;
|
public static int MinimumAge = 18;
|
||||||
public static int MaximumAge = 90;
|
public static int MaximumAge = 90;
|
||||||
|
|
||||||
@@ -18,7 +22,8 @@ namespace Content.Shared.Preferences
|
|||||||
Sex sex,
|
Sex sex,
|
||||||
HumanoidCharacterAppearance appearance,
|
HumanoidCharacterAppearance appearance,
|
||||||
Dictionary<string, JobPriority> jobPriorities,
|
Dictionary<string, JobPriority> jobPriorities,
|
||||||
PreferenceUnavailableMode preferenceUnavailable)
|
PreferenceUnavailableMode preferenceUnavailable,
|
||||||
|
List<string> antagPreferences)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Age = age;
|
Age = age;
|
||||||
@@ -26,6 +31,7 @@ namespace Content.Shared.Preferences
|
|||||||
Appearance = appearance;
|
Appearance = appearance;
|
||||||
_jobPriorities = jobPriorities;
|
_jobPriorities = jobPriorities;
|
||||||
PreferenceUnavailable = preferenceUnavailable;
|
PreferenceUnavailable = preferenceUnavailable;
|
||||||
|
_antagPreferences = antagPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile(
|
public HumanoidCharacterProfile(
|
||||||
@@ -34,9 +40,10 @@ namespace Content.Shared.Preferences
|
|||||||
Sex sex,
|
Sex sex,
|
||||||
HumanoidCharacterAppearance appearance,
|
HumanoidCharacterAppearance appearance,
|
||||||
IReadOnlyDictionary<string, JobPriority> jobPriorities,
|
IReadOnlyDictionary<string, JobPriority> jobPriorities,
|
||||||
PreferenceUnavailableMode preferenceUnavailable)
|
PreferenceUnavailableMode preferenceUnavailable,
|
||||||
|
IReadOnlyList<string> antagPreferences)
|
||||||
: this(name, age, sex, appearance, new Dictionary<string, JobPriority>(jobPriorities),
|
: this(name, age, sex, appearance, new Dictionary<string, JobPriority>(jobPriorities),
|
||||||
preferenceUnavailable)
|
preferenceUnavailable, new List<string>(antagPreferences))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +53,7 @@ namespace Content.Shared.Preferences
|
|||||||
new Dictionary<string, JobPriority>
|
new Dictionary<string, JobPriority>
|
||||||
{
|
{
|
||||||
{SharedGameTicker.OverflowJob, JobPriority.High}
|
{SharedGameTicker.OverflowJob, JobPriority.High}
|
||||||
}, PreferenceUnavailableMode.StayInLobby);
|
}, PreferenceUnavailableMode.StayInLobby, new List<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
@@ -55,26 +62,27 @@ namespace Content.Shared.Preferences
|
|||||||
public ICharacterAppearance CharacterAppearance => Appearance;
|
public ICharacterAppearance CharacterAppearance => Appearance;
|
||||||
public HumanoidCharacterAppearance Appearance { get; }
|
public HumanoidCharacterAppearance Appearance { get; }
|
||||||
public IReadOnlyDictionary<string, JobPriority> JobPriorities => _jobPriorities;
|
public IReadOnlyDictionary<string, JobPriority> JobPriorities => _jobPriorities;
|
||||||
|
public IReadOnlyList<string> AntagPreferences => _antagPreferences;
|
||||||
public PreferenceUnavailableMode PreferenceUnavailable { get; }
|
public PreferenceUnavailableMode PreferenceUnavailable { get; }
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithName(string name)
|
public HumanoidCharacterProfile WithName(string name)
|
||||||
{
|
{
|
||||||
return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithAge(int age)
|
public HumanoidCharacterProfile WithAge(int age)
|
||||||
{
|
{
|
||||||
return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithSex(Sex sex)
|
public HumanoidCharacterProfile WithSex(Sex sex)
|
||||||
{
|
{
|
||||||
return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance)
|
public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance)
|
||||||
{
|
{
|
||||||
return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable);
|
return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithJobPriorities(IReadOnlyDictionary<string, JobPriority> jobPriorities)
|
public HumanoidCharacterProfile WithJobPriorities(IReadOnlyDictionary<string, JobPriority> jobPriorities)
|
||||||
@@ -85,7 +93,8 @@ namespace Content.Shared.Preferences
|
|||||||
Sex,
|
Sex,
|
||||||
Appearance,
|
Appearance,
|
||||||
new Dictionary<string, JobPriority>(jobPriorities),
|
new Dictionary<string, JobPriority>(jobPriorities),
|
||||||
PreferenceUnavailable);
|
PreferenceUnavailable,
|
||||||
|
_antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority)
|
public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority)
|
||||||
@@ -100,12 +109,44 @@ namespace Content.Shared.Preferences
|
|||||||
dictionary[jobId] = priority;
|
dictionary[jobId] = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable);
|
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable, _antagPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode)
|
public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode)
|
||||||
{
|
{
|
||||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode);
|
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode, _antagPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HumanoidCharacterProfile WithAntagPreferences(IReadOnlyList<string> antagPreferences)
|
||||||
|
{
|
||||||
|
return new HumanoidCharacterProfile(
|
||||||
|
Name,
|
||||||
|
Age,
|
||||||
|
Sex,
|
||||||
|
Appearance,
|
||||||
|
_jobPriorities,
|
||||||
|
PreferenceUnavailable,
|
||||||
|
new List<string>(antagPreferences));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HumanoidCharacterProfile WithAntagPreference(string antagId, bool pref)
|
||||||
|
{
|
||||||
|
var list = new List<string>(_antagPreferences);
|
||||||
|
if(pref)
|
||||||
|
{
|
||||||
|
if(!list.Contains(antagId))
|
||||||
|
{
|
||||||
|
list.Add(antagId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(list.Contains(antagId))
|
||||||
|
{
|
||||||
|
list.Remove(antagId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Summary =>
|
public string Summary =>
|
||||||
@@ -119,6 +160,7 @@ namespace Content.Shared.Preferences
|
|||||||
if (Sex != other.Sex) return false;
|
if (Sex != other.Sex) return false;
|
||||||
if (PreferenceUnavailable != other.PreferenceUnavailable) return false;
|
if (PreferenceUnavailable != other.PreferenceUnavailable) return false;
|
||||||
if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false;
|
if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false;
|
||||||
|
if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false;
|
||||||
return Appearance.MemberwiseEquals(other.Appearance);
|
return Appearance.MemberwiseEquals(other.Appearance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
Content.Shared/Roles/AntagPrototype.cs
Normal file
48
Content.Shared/Roles/AntagPrototype.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Shared.Antags
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes information for a single antag.
|
||||||
|
/// </summary>
|
||||||
|
[Prototype("antag")]
|
||||||
|
public class AntagPrototype : IPrototype, IIndexedPrototype
|
||||||
|
{
|
||||||
|
public string ID { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of this antag as displayed to players.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The antag's objective, displayed at round-start to the player.
|
||||||
|
/// </summary>
|
||||||
|
public string Objective { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not the antag role is one of the bad guys.
|
||||||
|
/// </summary>
|
||||||
|
public bool Antagonist { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not the player can set the antag role in antag preferences.
|
||||||
|
/// </summary>
|
||||||
|
public bool SetPreference { get; private set; }
|
||||||
|
|
||||||
|
public void LoadFrom(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
ID = mapping.GetNode("id").AsString();
|
||||||
|
Name = Loc.GetString(mapping.GetNode("name").ToString());
|
||||||
|
Objective = mapping.GetNode("objective").ToString();
|
||||||
|
Antagonist = mapping.GetNode("antagonist").AsBool();
|
||||||
|
SetPreference = mapping.GetNode("setPreference").AsBool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,7 +35,8 @@ namespace Content.Tests.Server.Preferences
|
|||||||
{
|
{
|
||||||
{SharedGameTicker.OverflowJob, JobPriority.High}
|
{SharedGameTicker.OverflowJob, JobPriority.High}
|
||||||
},
|
},
|
||||||
PreferenceUnavailableMode.StayInLobby
|
PreferenceUnavailableMode.StayInLobby,
|
||||||
|
new List<string>{}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- type: antag
|
||||||
|
id: SuspicionInnocent
|
||||||
|
name: "innocent"
|
||||||
|
antagonist: false
|
||||||
|
setPreference: false
|
||||||
|
objective: "Discover and eliminate all traitors."
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- type: antag
|
||||||
|
id: SuspicionTraitor
|
||||||
|
name: "traitor"
|
||||||
|
antagonist: true
|
||||||
|
setPreference: true
|
||||||
|
objective: "Kill the innocents."
|
||||||
Reference in New Issue
Block a user