core/player/PlayerInventory.cs
using Sandbox.UI;
public class PlayerInventory : Component {
[Property, ReadOnly] public BasePlayer Owner {get; set;}
public enum Slot {
Unarmed,
Primary,
}
[Property] public Slot ActiveSlot {get; set;} = Slot.Primary;
[Property, ReadOnly] public Texture Interface {get; set;} = Texture.CreateRenderTarget().WithUAVBinding().WithSize(384,166).Create();
public enum WeaponMode {
Single,
Reload,
}
[Property] public WeaponMode Mode {get; set;} = WeaponMode.Single;
[Property, ReadOnly] public Dictionary<Slot, string> Equipped {get; set;} = new() {{Slot.Unarmed, "unarmed"}, {Slot.Primary, "1887"}};
[Property, ReadOnly] public Dictionary<string, int> AmmoLoaded {get; set;} = new() {{"unarmed", 0}, {"1887", 6}};
[Property, Range(-20,20)] public float Temperature {get; set;} = 20;
private TimeUntil FreezeDialougeCooldown;
private TimeUntil NextFreezeDamage;
public bool NeedToResetFiringMode;
public PlayerMouse.Mode LastMode;
protected override void OnFixedUpdate() {
var a = Owner.IsoEntity.Components.Get<NpcAnimator>();
var m = Owner.IsoEntity.Components.Get<NpcMovement>();
if (!a.IsValid() || !m.IsValid())
return;
//none of the temeperature or damage logic should be here but FUCK YOU FUCK YOU FUCK YOU FUCK YOU FUCK YOU
if (!Owner.Isometric)
Temperature = Math.Max(Temperature.Approach(20, Time.Delta * 5), Temperature);
else if (HeatSource.IsWarm(Scene, Grid.Snap(m.EntityRoot)))
Temperature = Temperature.Approach(20, Time.Delta * (Temperature > 10 ? 0.3f : 1));
else {
Temperature = Temperature.Approach(-20, Time.Delta * (m.Run && m.Path.Count > 0 ? 1.3f : 0.5f));
}
if (FreezeDialougeCooldown && Temperature < -12 && !HeatSource.IsWarm(Scene, Grid.Snap(m.EntityRoot))) {
FreezeDialougeCooldown = 15f;
Owner.IsoEntity.Components.GetOrCreate<NpcTalker>().Speak(Random.Shared.FromList(Owner.IsoEntity.TalkerScript.Freezing), 6);
}
if (NextFreezeDamage && Temperature < -15) {
Owner.IsoEntity.Health -= Random.Shared.Int(1,3);
if (Owner.IsoEntity.Health > 0 && !a.ActivitySet.NonInteruptActivities.Contains(a.Activity))
a.Activity = "flinch";
NextFreezeDamage = 3f;
}
if (Owner.IsoEntity.Health <= 0) {
a.Activity = "die";
Scene.GetAllComponents<PlayerDeath>().FirstOrDefault()?.Dead();
}
if (Input.Pressed("attack1") && Owner.Mouse.TargetButton == PlayerMouse.Button.Swap) {
Sound.Play("sounds/interface/press_button.sound");
if (ActiveSlot == Slot.Primary)
ActiveSlot = Slot.Unarmed;
else if (ActiveSlot == Slot.Unarmed)
ActiveSlot = Slot.Primary;
if (Equipped[ActiveSlot] == "1887") {
m.Path.Clear();
if (!a.ActivitySet.NonInteruptActivities.Contains(a.Activity))
a.Activity = "1887_draw";
}
Mode = WeaponMode.Single;
}
if (Input.Pressed("attack2") && Owner.Mouse.TargetButton == PlayerMouse.Button.Weapon) {
Sound.Play("sounds/interface/press_button.sound");
if (Mode == WeaponMode.Reload)
Mode = WeaponMode.Single;
else
Mode = (WeaponMode)((int)Mode + 1);
}
if (Input.Pressed("attack1") && Owner.Mouse.TargetButton == PlayerMouse.Button.Weapon) {
if (Mode == WeaponMode.Reload) {
if (!Reload(Equipped[ActiveSlot]))
Sound.Play("sounds/interface/press_button.sound");
return;
}
Sound.Play("sounds/interface/press_button.sound");
if (ActiveSlot == Slot.Unarmed)
return;
if (AmmoLoaded[Equipped[ActiveSlot]] <= 0)
Mode = WeaponMode.Reload;
else {
LastMode = Owner.Mouse.InteractMode;
Owner.Mouse.InteractMode = PlayerMouse.Mode.Shoot;
//NeedToResetFiringMode = LastMode != PlayerMouse.Mode.Shoot;
}
}
if (Input.Pressed("attack1") && Owner.Mouse.TargetLayer != PlayerMouse.Layer.Interface && Owner.Mouse.InteractMode == PlayerMouse.Mode.Shoot) {
if (NeedToResetFiringMode)
Owner.Mouse.InteractMode = LastMode;
NeedToResetFiringMode = false;
if (ActiveSlot == Slot.Unarmed)
return;
if (Mode == WeaponMode.Reload) {
Reload(Equipped[ActiveSlot]);
return;
}
if (Owner.Mouse.HoveredEntity == Owner.IsoEntity)
return;
if (m.Path.Count > 0) {
m.Path.Clear();
return;
}
if (a.ActivitySet.NonInteruptActivities.Contains(a.Activity))
return;
if (AmmoLoaded[Equipped[ActiveSlot]] <= 0)
Shoot(Equipped[ActiveSlot], Owner.Mouse.HoveredEntity);
else {
var pos = Owner.IsoCamera.MouseTarget();
if (Owner.Mouse.HoveredEntity.IsValid()) {
pos = Owner.Mouse.HoveredEntity.WorldPosition;
if (Owner.Mouse.HoveredEntity.Components.TryGet<NpcMovement>(out var hm))
pos = hm.EntityRoot;
}
pos = Grid.Snap(pos);
var best = -1f;
var angle = Rotation.Identity;
for (int i = 0; i < 6; i++) {
var canidate = Grid.Snap(m.EntityRoot + Rotation.FromYaw(i * 60f - 30f).Forward * 30f);
var dot = Vector3.Direction(m.EntityRoot, canidate).Dot(Vector3.Direction(m.EntityRoot, pos));
if (dot < best)
continue;
angle = Rotation.FromYaw(i * 60f - 30f);
best = dot;
}
Owner.IsoEntity.WorldRotation = angle;
Owner.IsoEntity.SnapToGrid();
Owner.IsoEntity.Transform.ClearInterpolation();
var ent = Owner.Mouse.HoveredEntity;
a.AttackAction = () => Shoot(Equipped[ActiveSlot], ent);
if (a.Activity != "die")
a.Activity = "1887_fire"+Random.Shared.Int(1,3);
}
}
RenderInterface();
Owner.IsoEntity.Components.Get<NpcAnimator>().Weapon = Equipped[ActiveSlot];
base.OnFixedUpdate();
}
public bool Reload(string weapon) {
var max = 0;
if (weapon == "1887")
max = 6;
//if (AmmoLoaded[weapon] == 0)
// max = Math.Max(max - 1, 0);
if (AmmoLoaded[weapon] >= max)
return false;
AmmoLoaded[weapon] = max;
Sound.Play("sounds/weapons/1887_reload.sound");
Mode = WeaponMode.Single;
return true;
}
private TimeUntil NextFire;
private TimeUntil WarnAmmo;
public void Shoot(string weapon, IsoEntity target) {
if (!NextFire)
return;
NextFire = 0.5f;
if (AmmoLoaded[weapon] <= 0) {
WarnAmmo = 1f;
Sound.Play("sounds/weapons/dry_fire.sound");
return;
}
AmmoLoaded[weapon]--;
Sound.Play("sounds/weapons/1887_fire.sound");
if (target.IsValid()) {
if (target.WorldPosition.Distance(Owner.IsoEntity.WorldPosition) > 600)
return;
if (target.WorldPosition.Distance(Owner.IsoEntity.WorldPosition) > 200)
target.Health -= Random.Shared.Int(20,30);
else
target.Health -= Random.Shared.Int(30,60);
if (target.Components.TryGet<NpcAnimator>(out var a)) {
if (target.Health > 0)
a.Activity = "flinch";
else
a.Activity = "die";
}
if (target.Components.TryGet<NpcWolfBrain>(out var br)) {
br.ExitCombat = 5f;
}
}
}
public void RenderInterface() {
var shader = new ComputeShader("shaders/cs_interface_draw.shader");
shader.Attributes.Set("Base", Texture.Load("materials/interface/interface_base.vtex"));
if (!WarnAmmo && AmmoLoaded[Equipped[ActiveSlot]] <= 0 && MathF.Sin(WarnAmmo.Relative * 15) > 0f)
shader.Attributes.Set("Ammo", Texture.Load("materials/interface/interface_ammo_error.vtex"));
else
shader.Attributes.Set("Ammo", Texture.Load("materials/interface/interface_ammo_"+AmmoLoaded[Equipped[ActiveSlot]]+".vtex"));
shader.Attributes.Set("Swap", Texture.Load("materials/interface/interface_swap_base.vtex"));
if (Temperature < -12 && MathF.Sin(Time.Now * 15) > 0f)
shader.Attributes.Set("Temp", Texture.Load("materials/interface/interface_temp_on.vtex"));
else
shader.Attributes.Set("Temp", Texture.Load("materials/interface/interface_temp_off.vtex"));
shader.Attributes.Set("Thermo0", Texture.Load("materials/interface/interface_thermometer_empty.vtex"));
shader.Attributes.Set("Thermo1", Texture.Load("materials/interface/interface_thermometer_full.vtex"));
shader.Attributes.Set("ThermoFill", Temperature.Remap(-20f, 20f, 0.53f, 0.94f));
shader.Attributes.Set("Unarmed", Equipped[ActiveSlot] == "unarmed");
if (Mode == WeaponMode.Single)
shader.Attributes.Set("WeapAp", Texture.Load("materials/interface/interface_weapon_ap_3.vtex"));
else if (Mode == WeaponMode.Reload)
shader.Attributes.Set("WeapAp", Texture.Load("materials/interface/interface_weapon_ap_2.vtex"));
shader.Attributes.Set("WeapBase", Texture.Load("materials/interface/interface_weapon_base.vtex"));
shader.Attributes.Set("WeapIcon", Texture.Load("materials/interface/interface_weapon_icon_1887.vtex"));
shader.Attributes.Set("WeapMode", Texture.Load("materials/interface/interface_weapon_mode_"+Mode.ToString().ToLower()+".vtex"));
shader.Attributes.Set("WeapSlot", Texture.Load("materials/interface/interface_weapon_slot_primary.vtex"));
var text = new Bitmap(384,166);
text.DrawText(new() {
Text = Owner.IsoEntity.Health.Clamp(0,100).ToString("000"),
TextColor = Owner.IsoEntity.Health > 10 ? Color.Green.Darken(0.3f) : Color.Red,
FontSize = 12,
}, new(new(34f,47), 80), TextFlag.LeftTop);
text.DrawText(new() {
Text = "ERR",
TextColor = Color.Red.Darken(0.5f),
FontSize = 12,
}, new(new(34f,71), 80), TextFlag.LeftTop);
shader.Attributes.Set("Text", text.ToTexture());
shader.Attributes.Set("RenderSize", Interface.Size);
shader.Attributes.Set("Result", Interface);
shader.Dispatch(Interface.Width, Interface.Height, 1);
}
}