Fix polymorphed null error (#11571)
This commit is contained in:
@@ -10,7 +10,8 @@ namespace Content.Server.Polymorph.Components
|
|||||||
/// The polymorph prototype, used to track various information
|
/// The polymorph prototype, used to track various information
|
||||||
/// about the polymorph
|
/// about the polymorph
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PolymorphPrototype Prototype = default!;
|
[DataField("prototype", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<PolymorphPrototype>))]
|
||||||
|
public string Prototype = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The original entity that the player will revert back into
|
/// The original entity that the player will revert back into
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
|
|
||||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
|
[Dependency] private readonly IComponentFactory _compFact = default!;
|
||||||
[Dependency] private readonly ServerInventorySystem _inventory = default!;
|
[Dependency] private readonly ServerInventorySystem _inventory = default!;
|
||||||
[Dependency] private readonly SharedHandsSystem _sharedHands = default!;
|
[Dependency] private readonly SharedHandsSystem _sharedHands = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||||
@@ -98,10 +99,11 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
var child = Spawn(proto.Entity, targetTransformComp.Coordinates);
|
var child = Spawn(proto.Entity, targetTransformComp.Coordinates);
|
||||||
MakeSentientCommand.MakeSentient(child, EntityManager);
|
MakeSentientCommand.MakeSentient(child, EntityManager);
|
||||||
|
|
||||||
var comp = EnsureComp<PolymorphedEntityComponent>(child);
|
var comp = _compFact.GetComponent<PolymorphedEntityComponent>();
|
||||||
|
comp.Owner = child;
|
||||||
comp.Parent = target;
|
comp.Parent = target;
|
||||||
comp.Prototype = proto;
|
comp.Prototype = proto.ID;
|
||||||
RaiseLocalEvent(child, new PolymorphComponentSetupEvent(), true);
|
EntityManager.AddComponent(child, comp);
|
||||||
|
|
||||||
var childXform = Transform(child);
|
var childXform = Transform(child);
|
||||||
childXform.LocalRotation = targetTransformComp.LocalRotation;
|
childXform.LocalRotation = targetTransformComp.LocalRotation;
|
||||||
@@ -212,11 +214,6 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used after the polymorphedEntity component has it's data set up.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class PolymorphComponentSetupEvent : InstantActionEvent { };
|
|
||||||
|
|
||||||
public sealed class PolymorphActionEvent : InstantActionEvent
|
public sealed class PolymorphActionEvent : InstantActionEvent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ using Content.Shared.Polymorph;
|
|||||||
using Robust.Server.Containers;
|
using Robust.Server.Containers;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Polymorph.Systems
|
namespace Content.Server.Polymorph.Systems
|
||||||
{
|
{
|
||||||
public sealed class PolymorphedEntitySystem : EntitySystem
|
public sealed class PolymorphedEntitySystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
@@ -29,7 +31,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<PolymorphedEntityComponent, PolymorphComponentSetupEvent>(OnInit);
|
SubscribeLocalEvent<PolymorphedEntityComponent, ComponentStartup>(OnInit);
|
||||||
SubscribeLocalEvent<PolymorphedEntityComponent, RevertPolymorphActionEvent>(OnRevertPolymorphActionEvent);
|
SubscribeLocalEvent<PolymorphedEntityComponent, RevertPolymorphActionEvent>(OnRevertPolymorphActionEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +55,11 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
if (Deleted(component.Parent))
|
if (Deleted(component.Parent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var proto = component.Prototype;
|
if (!_proto.TryIndex(component.Prototype, out PolymorphPrototype? proto))
|
||||||
|
{
|
||||||
|
Logger.Error($"{nameof(PolymorphedEntitySystem)} encountered an improperly initialized polymorph component while reverting. Entity {ToPrettyString(uid)}. Prototype: {component.Prototype}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var uidXform = Transform(uid);
|
var uidXform = Transform(uid);
|
||||||
var parentXform = Transform(component.Parent);
|
var parentXform = Transform(component.Parent);
|
||||||
@@ -65,7 +71,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
if (_container.TryGetContainingContainer(uid, out var cont))
|
if (_container.TryGetContainingContainer(uid, out var cont))
|
||||||
cont.Insert(component.Parent);
|
cont.Insert(component.Parent);
|
||||||
|
|
||||||
if (component.Prototype.TransferDamage &&
|
if (proto.TransferDamage &&
|
||||||
TryComp<DamageableComponent>(component.Parent, out var damageParent) &&
|
TryComp<DamageableComponent>(component.Parent, out var damageParent) &&
|
||||||
_damageable.GetScaledDamage(uid, component.Parent, out var damage) &&
|
_damageable.GetScaledDamage(uid, component.Parent, out var damage) &&
|
||||||
damage != null)
|
damage != null)
|
||||||
@@ -89,6 +95,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
slot.EmptyContainer();
|
slot.EmptyContainer();
|
||||||
|
|
||||||
foreach (var hand in _sharedHands.EnumerateHeld(uid))
|
foreach (var hand in _sharedHands.EnumerateHeld(uid))
|
||||||
|
// This causes errors/bugs. Use hand related functions instead.
|
||||||
hand.TryRemoveFromContainer();
|
hand.TryRemoveFromContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +112,17 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
QueueDel(uid);
|
QueueDel(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, PolymorphedEntityComponent component, PolymorphComponentSetupEvent args)
|
public void OnInit(EntityUid uid, PolymorphedEntityComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
if (component.Prototype.Forced)
|
if (!_proto.TryIndex(component.Prototype, out PolymorphPrototype? proto))
|
||||||
|
{
|
||||||
|
// warning instead of error because of the all-comps one entity test.
|
||||||
|
Logger.Warning($"{nameof(PolymorphedEntitySystem)} encountered an improperly set up polymorph component while initializing. Entity {ToPrettyString(uid)}. Prototype: {component.Prototype}");
|
||||||
|
RemCompDeferred(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proto.Forced)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var act = new InstantAction()
|
var act = new InstantAction()
|
||||||
@@ -116,7 +131,7 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
EntityIcon = component.Parent,
|
EntityIcon = component.Parent,
|
||||||
DisplayName = Loc.GetString("polymorph-revert-action-name"),
|
DisplayName = Loc.GetString("polymorph-revert-action-name"),
|
||||||
Description = Loc.GetString("polymorph-revert-action-description"),
|
Description = Loc.GetString("polymorph-revert-action-description"),
|
||||||
UseDelay = TimeSpan.FromSeconds(component.Prototype.Delay),
|
UseDelay = TimeSpan.FromSeconds(proto.Delay),
|
||||||
};
|
};
|
||||||
|
|
||||||
_actions.AddAction(uid, act, null);
|
_actions.AddAction(uid, act, null);
|
||||||
@@ -126,19 +141,26 @@ namespace Content.Server.Polymorph.Systems
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
foreach (var entity in EntityQuery<PolymorphedEntityComponent>())
|
foreach (var comp in EntityQuery<PolymorphedEntityComponent>())
|
||||||
{
|
{
|
||||||
entity.Time += frameTime;
|
comp.Time += frameTime;
|
||||||
|
|
||||||
if(entity.Prototype.Duration != null && entity.Time >= entity.Prototype.Duration)
|
if (!_proto.TryIndex(comp.Prototype, out PolymorphPrototype? proto))
|
||||||
Revert(entity.Owner);
|
{
|
||||||
|
Logger.Error($"{nameof(PolymorphedEntitySystem)} encountered an improperly initialized polymorph component while updating. Entity {ToPrettyString(comp.Owner)}. Prototype: {comp.Prototype}");
|
||||||
|
RemCompDeferred(comp.Owner, comp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!TryComp<MobStateComponent>(entity.Owner, out var mob))
|
if(proto.Duration != null && comp.Time >= proto.Duration)
|
||||||
|
Revert(comp.Owner);
|
||||||
|
|
||||||
|
if (!TryComp<MobStateComponent>(comp.Owner, out var mob))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((entity.Prototype.RevertOnDeath && mob.IsDead()) ||
|
if ((proto.RevertOnDeath && mob.IsDead()) ||
|
||||||
(entity.Prototype.RevertOnCrit && mob.IsCritical()))
|
(proto.RevertOnCrit && mob.IsCritical()))
|
||||||
Revert(entity.Owner);
|
Revert(comp.Owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user