| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- using Content.Shared.Database;
- using Content.Shared.Research.Components;
- using Content.Shared.Research.Prototypes;
- using JetBrains.Annotations;
- namespace Content.Server.Research.Systems;
- public sealed partial class ResearchSystem
- {
- /// <summary>
- /// Syncs the primary entity's database to that of the secondary entity's database.
- /// </summary>
- public void Sync(EntityUid primaryUid, EntityUid otherUid, TechnologyDatabaseComponent? primaryDb = null, TechnologyDatabaseComponent? otherDb = null)
- {
- if (!Resolve(primaryUid, ref primaryDb) || !Resolve(otherUid, ref otherDb))
- return;
- primaryDb.MainDiscipline = otherDb.MainDiscipline;
- primaryDb.CurrentTechnologyCards = otherDb.CurrentTechnologyCards;
- primaryDb.SupportedDisciplines = otherDb.SupportedDisciplines;
- primaryDb.UnlockedTechnologies = otherDb.UnlockedTechnologies;
- primaryDb.UnlockedRecipes = otherDb.UnlockedRecipes;
- Dirty(primaryUid, primaryDb);
- var ev = new TechnologyDatabaseSynchronizedEvent();
- RaiseLocalEvent(primaryUid, ref ev);
- }
- /// <summary>
- /// If there's a research client component attached to the owner entity,
- /// and the research client is connected to a research server, this method
- /// syncs against the research server, and the server against the local database.
- /// </summary>
- /// <returns>Whether it could sync or not</returns>
- public void SyncClientWithServer(EntityUid uid, TechnologyDatabaseComponent? databaseComponent = null, ResearchClientComponent? clientComponent = null)
- {
- if (!Resolve(uid, ref databaseComponent, ref clientComponent, false))
- return;
- if (!TryComp<TechnologyDatabaseComponent>(clientComponent.Server, out var serverDatabase))
- return;
- Sync(uid, clientComponent.Server.Value, databaseComponent, serverDatabase);
- }
- /// <summary>
- /// Tries to add a technology to a database, checking if it is able to
- /// </summary>
- /// <returns>If the technology was successfully added</returns>
- public bool UnlockTechnology(EntityUid client,
- string prototypeid,
- EntityUid user,
- ResearchClientComponent? component = null,
- TechnologyDatabaseComponent? clientDatabase = null)
- {
- if (!PrototypeManager.TryIndex<TechnologyPrototype>(prototypeid, out var prototype))
- return false;
- return UnlockTechnology(client, prototype, user, component, clientDatabase);
- }
- /// <summary>
- /// Tries to add a technology to a database, checking if it is able to
- /// </summary>
- /// <returns>If the technology was successfully added</returns>
- public bool UnlockTechnology(EntityUid client,
- TechnologyPrototype prototype,
- EntityUid user,
- ResearchClientComponent? component = null,
- TechnologyDatabaseComponent? clientDatabase = null)
- {
- if (!Resolve(client, ref component, ref clientDatabase, false))
- return false;
- if (!TryGetClientServer(client, out var serverEnt, out _, component))
- return false;
- if (!CanServerUnlockTechnology(client, prototype, clientDatabase, component))
- return false;
- AddTechnology(serverEnt.Value, prototype);
- TrySetMainDiscipline(prototype, serverEnt.Value);
- ModifyServerPoints(serverEnt.Value, -prototype.Cost);
- UpdateTechnologyCards(serverEnt.Value);
- _adminLog.Add(LogType.Action, LogImpact.Medium,
- $"{ToPrettyString(user):player} unlocked {prototype.ID} (discipline: {prototype.Discipline}, tier: {prototype.Tier}) at {ToPrettyString(client)}, for server {ToPrettyString(serverEnt.Value)}.");
- return true;
- }
- /// <summary>
- /// Adds a technology to the database without checking if it could be unlocked.
- /// </summary>
- [PublicAPI]
- public void AddTechnology(EntityUid uid, string technology, TechnologyDatabaseComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return;
- if (!PrototypeManager.TryIndex<TechnologyPrototype>(technology, out var prototype))
- return;
- AddTechnology(uid, prototype, component);
- }
- /// <summary>
- /// Adds a technology to the database without checking if it could be unlocked.
- /// </summary>
- public void AddTechnology(EntityUid uid, TechnologyPrototype technology, TechnologyDatabaseComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return;
- //todo this needs to support some other stuff, too
- foreach (var generic in technology.GenericUnlocks)
- {
- if (generic.PurchaseEvent != null)
- RaiseLocalEvent(generic.PurchaseEvent);
- }
- component.UnlockedTechnologies.Add(technology.ID);
- foreach (var unlock in technology.RecipeUnlocks)
- {
- if (component.UnlockedRecipes.Contains(unlock))
- continue;
- component.UnlockedRecipes.Add(unlock);
- }
- Dirty(uid, component);
- var ev = new TechnologyDatabaseModifiedEvent();
- RaiseLocalEvent(uid, ref ev);
- }
- /// <summary>
- /// Returns whether a technology can be unlocked on this database,
- /// taking parent technologies into account.
- /// </summary>
- /// <returns>Whether it could be unlocked or not</returns>
- public bool CanServerUnlockTechnology(EntityUid uid,
- TechnologyPrototype technology,
- TechnologyDatabaseComponent? database = null,
- ResearchClientComponent? client = null)
- {
- if (!Resolve(uid, ref client, ref database, false))
- return false;
- if (!TryGetClientServer(uid, out _, out var serverComp, client))
- return false;
- if (!IsTechnologyAvailable(database, technology))
- return false;
- if (technology.Cost > serverComp.Points)
- return false;
- return true;
- }
- private void OnDatabaseRegistrationChanged(EntityUid uid, TechnologyDatabaseComponent component, ref ResearchRegistrationChangedEvent args)
- {
- if (args.Server != null)
- return;
- component.MainDiscipline = null;
- component.CurrentTechnologyCards = new List<string>();
- component.SupportedDisciplines = new List<string>();
- component.UnlockedTechnologies = new List<string>();
- component.UnlockedRecipes = new List<string>();
- Dirty(uid, component);
- }
- }
|