diff --git a/TODO.md b/TODO.md index 3b56b7a..719880a 100644 --- a/TODO.md +++ b/TODO.md @@ -14,5 +14,8 @@ - ~~Caco plush sprite scaling~~ - ~~Frag counter in loadout starts with no battery~~ - ~~Organize source_data~~ +- ~~Spraycan spawn CVars~~ +- ~~Spraycan bulk~~ +- More spray patterns - Loadout code descriptions (hdweapon.loadoutcodes) diff --git a/cvarinfo.txt b/cvarinfo.txt index e4234b1..3e3ecb6 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -1,2 +1,2 @@ -server int snektech_spawnflags = 3; +server int snektech_spawnflags = 11; user string snektech_spraypattern = "SnekSpray_TransPride"; diff --git a/menudef.txt b/menudef.txt index f920c88..ce606d2 100644 --- a/menudef.txt +++ b/menudef.txt @@ -10,5 +10,6 @@ OptionMenu "SnekTechMenu" FlagOption "Gretchen Counter", "snektech_spawnflags", "YesNo", 0 FlagOption "Wiring Bypass Kit", "snektech_spawnflags", "YesNo", 1 FlagOption "Cacodemon Plushie", "snektech_spawnflags", "YesNo", 2 + FlagOption "Spraypaint Can", "snektech_spawnflags", "YesNo", 3 } diff --git a/sounds/spraycan_rattle.aup3 b/sounds/spraycan_rattle.aup3 index e15134b..cb9a227 100644 Binary files a/sounds/spraycan_rattle.aup3 and b/sounds/spraycan_rattle.aup3 differ diff --git a/sounds/spraycan_spray.aup3 b/sounds/spraycan_spray.aup3 index 548ba9f..17e1c54 100644 Binary files a/sounds/spraycan_spray.aup3 and b/sounds/spraycan_spray.aup3 differ diff --git a/source_data/spray_lesbianpride.aseprite b/source_data/spray_lesbianpride.aseprite index 5dd4d89..07a2604 100644 Binary files a/source_data/spray_lesbianpride.aseprite and b/source_data/spray_lesbianpride.aseprite differ diff --git a/sprites/spraycan/kspra0.png b/sprites/spraycan/kspra0.png new file mode 100644 index 0000000..a3bff41 Binary files /dev/null and b/sprites/spraycan/kspra0.png differ diff --git a/sprites/spraycan/ksprb0.png b/sprites/spraycan/ksprb0.png new file mode 100644 index 0000000..e02c5f8 Binary files /dev/null and b/sprites/spraycan/ksprb0.png differ diff --git a/sprites/spraycan/kspya0.png b/sprites/spraycan/kspya0.png new file mode 100644 index 0000000..6af2d2b Binary files /dev/null and b/sprites/spraycan/kspya0.png differ diff --git a/sprites/spraycan/kspyb0.png b/sprites/spraycan/kspyb0.png new file mode 100644 index 0000000..1744652 Binary files /dev/null and b/sprites/spraycan/kspyb0.png differ diff --git a/zscript/snektech.zs b/zscript/snektech.zs index 90213b5..c932d1e 100644 --- a/zscript/snektech.zs +++ b/zscript/snektech.zs @@ -81,6 +81,11 @@ class SnekTechEventHandler : EventHandler e.Thing, SNEKTECH_CACOPLUSHIE, "KiriCacodemonPlushie"); + + DoSnekTechBackpackSpawnCheck( + e.Thing, + SNEKTECH_SPRAYCAN, + "Sprayer"); } override void CheckReplacement(ReplaceEvent e) @@ -107,6 +112,8 @@ class SnekTechEventHandler : EventHandler SNEKTECH_CACOPLUSHIE, "BlurSphere", "KiriCacodemonPlushie", 6, e); + + // Note: No replacements for spray cans. } } diff --git a/zscript/spraycan.zs b/zscript/spraycan.zs index 4ad5100..c32c015 100644 --- a/zscript/spraycan.zs +++ b/zscript/spraycan.zs @@ -1,5 +1,6 @@ // FIXME: Make consts and enums consistent formatting. +// FIXME: Add bulk. const KIRI_SPRAY_DISTANCE = 96; const KIRI_SPRAY_SHAKEANIM_MAXANGLE = 20.0; @@ -7,6 +8,7 @@ const KIRI_SPRAY_MAXPAINT = 50; const KIRI_SPRAY_MAXPRESSURE = 100; const KIRI_SPRAY_PRESSUREBUILDSCALE = 20; const KIRI_SPRAY_PRESSURE_PER_USE = (KIRI_SPRAY_MAXPRESSURE / 2); +const KIRI_SPRAY_PRESSURE_DECAY_RATE = 0.1; const HDLD_KIRI_SPRAYCAN = "ksp"; @@ -34,10 +36,13 @@ class Sprayer : HDWeapon // inventory.icon "KSPRB0"; inventory.pickupsound "kiri/spraycan_rattle"; inventory.pickupmessage "Picked up some spraypaint cans."; - // inventory.amount 1; - // inventory.maxamount 100; + + inventory.amount 1; + inventory.maxamount 100; hdweapon.refid HDLD_KIRI_SPRAYCAN; + + tag "Spraypaint Can"; } states @@ -67,22 +72,25 @@ class Sprayer : HDWeapon // Taper off pressure increase amount based on how much // pressure is in there already. float pressureIncreaseScale = 1.0 - ( - float(invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE]) / + float(invoker.GetPressure()) / float(KIRI_SPRAY_MAXPRESSURE)); pressureIncreaseScale *= pressureIncreaseScale; // Add pressure. - invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE] += + int pressure = invoker.GetPressure(); + pressure += random(0, KIRI_SPRAY_PRESSUREBUILDSCALE * invoker.weaponstatus[KIRI_SPRAY_WS_PAINT] / KIRI_SPRAY_MAXPAINT); // Cap pressure amount. - if(invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE] > KIRI_SPRAY_MAXPRESSURE) { - invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE] = KIRI_SPRAY_MAXPRESSURE; + if(pressure > KIRI_SPRAY_MAXPRESSURE) { + pressure = KIRI_SPRAY_MAXPRESSURE; } + invoker.SetPressure(pressure); + } KSPR A 1 offset(0, 60) { A_OverlayRotate(0, sin(level.time * 5.0) * KIRI_SPRAY_SHAKEANIM_MAXANGLE * 2.0/3.0); } KSPR A 1 offset(0, 40) { A_OverlayRotate(0, sin(level.time * 5.0) * KIRI_SPRAY_SHAKEANIM_MAXANGLE * 1.0/3.0); } @@ -92,7 +100,7 @@ class Sprayer : HDWeapon fire: KSPR A 2 { - if(invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE] < KIRI_SPRAY_PRESSURE_PER_USE) { + if(invoker.GetPressure() < KIRI_SPRAY_PRESSURE_PER_USE) { invoker.owner.A_Log("Not enough pressure to spray."); @@ -151,7 +159,7 @@ class Sprayer : HDWeapon spawner.actualDecalName = actualDecalName; spawner.master = invoker.owner; - invoker.weaponstatus[KIRI_SPRAY_WS_PRESSURE] -= KIRI_SPRAY_PRESSURE_PER_USE; + invoker.SetPressure(invoker.GetPressure() - KIRI_SPRAY_PRESSURE_PER_USE); invoker.weaponstatus[KIRI_SPRAY_WS_PAINT] -= 1; } @@ -195,11 +203,66 @@ class Sprayer : HDWeapon return GetSpareWeaponRegular(newowner, reverse, doselect); } + // Why do we store pressure as this weird equation? + // + // Pressure is stored as a time since the a hypothetical last + // "fully charged" time, based on the level time and pressure + // decay rate. + // + // This way we can decay pressure without ticking, important for + // spare weapons and stuff in backpacks. + int GetPressure() const + { + int time = level.TotalTime; + int lastChargedTime = weaponstatus[KIRI_SPRAY_WS_PRESSURE]; + int pressure = int( + float(KIRI_SPRAY_MAXPRESSURE) - + float(time - lastChargedTime) * KIRI_SPRAY_PRESSURE_DECAY_RATE); + + if(pressure > KIRI_SPRAY_MAXPRESSURE) { + pressure = KIRI_SPRAY_MAXPRESSURE; + } + + if(pressure < 0) { + pressure = 0; + } + + return pressure; + } + + void SetPressure(int pressure) + { + if(pressure > KIRI_SPRAY_MAXPRESSURE) { + pressure = KIRI_SPRAY_MAXPRESSURE; + } + + if(pressure < 0) { + pressure = 0; + } + + int time = level.TotalTime; + int lastChargedTime = round( + float(pressure - KIRI_SPRAY_MAXPRESSURE) / float(KIRI_SPRAY_PRESSURE_DECAY_RATE) + time); + + weaponstatus[KIRI_SPRAY_WS_PRESSURE] = lastChargedTime; + } + + void ResetPressure() + { + int resetValue = -int(float(KIRI_SPRAY_MAXPRESSURE) / float(KIRI_SPRAY_PRESSURE_DECAY_RATE)); + weaponstatus[KIRI_SPRAY_WS_PRESSURE] = resetValue; + } + + override void Consolidate() + { + ResetPressure(); + } + override void InitializeWepStats(bool idfa) { super.InitializeWepStats(idfa); - weaponstatus[KIRI_SPRAY_WS_PRESSURE] = 0; + SetPressure(0); // Add a little bit of randomness to the amount of paint in // the can. @@ -208,26 +271,13 @@ class Sprayer : HDWeapon - random(0, KIRI_SPRAY_MAXPAINT / 10); } - override void Tick() - { - super.Tick(); - - // Gradually decay pressure. - if(random(0, 256) < 4) { - weaponstatus[KIRI_SPRAY_WS_PRESSURE] -= 1; - if(weaponstatus[KIRI_SPRAY_WS_PRESSURE] < 0) { - weaponstatus[KIRI_SPRAY_WS_PRESSURE] = 0; - } - } - } - override void DrawHUDStuff( HDStatusBar statusBar, HDWeapon weapon, HDPlayerPawn pawn) { // Current pressure (top bar). statusBar.DrawWepNum( - weaponstatus[KIRI_SPRAY_WS_PRESSURE], + GetPressure(), KIRI_SPRAY_MAXPRESSURE, posy:-10); // Total paint remaining (bottom bar). @@ -274,11 +324,16 @@ class Sprayer : HDWeapon A_SetHelpText(); } + override double WeaponBulk() + { + return 10; + } + override String GetHelpText() { super.GetHelpText(); - int messageIndex = level.time; //(level.time / 60); + int messageIndex = level.time; Array messages = { "Deface the tyrant's property.", "Engage in civil disobedience.",