2023-09-09 16:54:49 -07:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Spraypaint cans
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Super cheap.
|
|
|
|
//
|
2023-09-09 12:31:23 -07:00
|
|
|
|
2023-09-09 13:00:20 -07:00
|
|
|
const KIRI_SPRAY_DISTANCE = 96;
|
2023-09-09 12:31:23 -07:00
|
|
|
const KIRI_SPRAY_SHAKEANIM_MAXANGLE = 20.0;
|
|
|
|
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);
|
2023-09-09 14:34:54 -07:00
|
|
|
const KIRI_SPRAY_PRESSURE_DECAY_RATE = 0.1;
|
2023-09-09 12:31:23 -07:00
|
|
|
|
2023-09-09 13:00:20 -07:00
|
|
|
const HDLD_KIRI_SPRAYCAN = "ksp";
|
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
enum KiriSprayerStatus
|
|
|
|
{
|
2023-09-09 13:00:20 -07:00
|
|
|
KIRI_SPRAY_WS_PAINT = 1,
|
|
|
|
KIRI_SPRAY_WS_PRESSURE = 2
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekTechSprayer : HDWeapon
|
2023-09-09 09:02:54 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
radius 2;
|
|
|
|
height 4;
|
|
|
|
+SpriteAngle;
|
|
|
|
Scale 0.4;
|
|
|
|
|
|
|
|
+hdweapon.fitsinbackpack;
|
|
|
|
+weapon.wimpy_weapon;
|
|
|
|
|
|
|
|
+INVENTORY.PERSISTENTPOWER;
|
|
|
|
+INVENTORY.INVBAR;
|
2023-09-09 13:00:20 -07:00
|
|
|
|
|
|
|
// inventory.icon "KSPRB0";
|
|
|
|
inventory.pickupsound "kiri/spraycan_rattle";
|
|
|
|
inventory.pickupmessage "Picked up some spraypaint cans.";
|
2023-09-09 14:34:54 -07:00
|
|
|
|
|
|
|
inventory.amount 1;
|
|
|
|
inventory.maxamount 100;
|
2023-09-09 13:00:20 -07:00
|
|
|
|
|
|
|
hdweapon.refid HDLD_KIRI_SPRAYCAN;
|
2023-09-09 14:34:54 -07:00
|
|
|
|
|
|
|
tag "Spraypaint Can";
|
2023-09-09 09:02:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
states
|
|
|
|
{
|
|
|
|
spawn:
|
|
|
|
KSPR B -1;
|
|
|
|
stop;
|
|
|
|
|
|
|
|
ready:
|
2023-09-09 16:44:13 -07:00
|
|
|
KSPR A 1 {
|
|
|
|
A_WeaponReady(WRF_ALL);
|
|
|
|
A_WeaponBusy(false);
|
|
|
|
}
|
2023-09-09 09:02:54 -07:00
|
|
|
goto readyend;
|
|
|
|
|
2023-09-09 16:44:13 -07:00
|
|
|
altfire:
|
2023-09-09 12:31:23 -07:00
|
|
|
reload:
|
|
|
|
KSPR A 1 offset(0, 20) {
|
|
|
|
A_OverlayPivot(0, 0.5, 1.0);
|
|
|
|
A_OverlayRotate(0, 0);
|
|
|
|
|
|
|
|
A_StartSound(
|
|
|
|
"kiri/spraycan_rattle",
|
|
|
|
CHAN_WEAPON, CHANF_NOSTOP);
|
|
|
|
}
|
|
|
|
KSPR A 1 offset(0, 40) { A_OverlayRotate(0, sin(level.time * 5.0) * KIRI_SPRAY_SHAKEANIM_MAXANGLE * 1.0/3.0); }
|
|
|
|
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, 80) {
|
|
|
|
A_OverlayRotate(0, sin(level.time * 5.0) * KIRI_SPRAY_SHAKEANIM_MAXANGLE);
|
|
|
|
|
|
|
|
// Taper off pressure increase amount based on how much
|
|
|
|
// pressure is in there already.
|
|
|
|
float pressureIncreaseScale = 1.0 - (
|
2023-09-09 14:34:54 -07:00
|
|
|
float(invoker.GetPressure()) /
|
2023-09-09 12:31:23 -07:00
|
|
|
float(KIRI_SPRAY_MAXPRESSURE));
|
|
|
|
pressureIncreaseScale *= pressureIncreaseScale;
|
|
|
|
|
|
|
|
// Add pressure.
|
2023-09-09 14:34:54 -07:00
|
|
|
int pressure = invoker.GetPressure();
|
|
|
|
pressure +=
|
2023-09-09 12:31:23 -07:00
|
|
|
random(0,
|
|
|
|
KIRI_SPRAY_PRESSUREBUILDSCALE
|
2023-09-09 13:00:20 -07:00
|
|
|
* invoker.weaponstatus[KIRI_SPRAY_WS_PAINT]
|
2023-09-09 12:31:23 -07:00
|
|
|
/ KIRI_SPRAY_MAXPAINT);
|
|
|
|
|
|
|
|
// Cap pressure amount.
|
2023-09-09 14:34:54 -07:00
|
|
|
if(pressure > KIRI_SPRAY_MAXPRESSURE) {
|
|
|
|
pressure = KIRI_SPRAY_MAXPRESSURE;
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
invoker.SetPressure(pressure);
|
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
|
|
|
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); }
|
|
|
|
KSPR A 1 offset(0, 20) { A_OverlayRotate(0, 0); }
|
|
|
|
goto ready;
|
|
|
|
|
2023-09-09 09:02:54 -07:00
|
|
|
fire:
|
|
|
|
KSPR A 2 {
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
if(invoker.GetPressure() < KIRI_SPRAY_PRESSURE_PER_USE) {
|
2023-09-09 12:31:23 -07:00
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
invoker.owner.A_Log("Not enough pressure to spray.", true);
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
float zOffset = GunHeight() * 0.8;
|
|
|
|
FLineTraceData lineTraceData;
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class<SnekTechSprayerPattern> sprayerPatternClass = "SnekTechSprayerPattern";
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
// Find the spray pattern class that matches the
|
|
|
|
// player's CVar for selected pattern.
|
|
|
|
String currentSprayCVar = CVar.GetCVar(
|
|
|
|
"snektech_spraypattern",
|
|
|
|
invoker.owner.player).GetString();
|
|
|
|
for(int i = 0; i < AllActorClasses.size(); i++) {
|
2023-09-09 18:03:56 -07:00
|
|
|
class<SnekTechSprayerPattern> thisPatternClass = (class<SnekTechSprayerPattern>)(AllActorClasses[i]);
|
2023-09-09 12:31:23 -07:00
|
|
|
if(thisPatternClass) {
|
|
|
|
if(thisPatternClass.GetClassName() == currentSprayCVar) {
|
2023-09-09 18:03:56 -07:00
|
|
|
sprayerPatternClass = (class<SnekTechSprayerPattern>)(AllActorClasses[i]);
|
2023-09-09 12:31:23 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the actual decal name out of it.
|
|
|
|
let defaultSprayClass = GetDefaultByType(sprayerPatternClass);
|
|
|
|
String actualDecalName = defaultSprayClass.decalName;
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
// Find a wall to spray on.
|
|
|
|
bool traceHit = LineTrace(
|
|
|
|
angle,
|
2023-09-09 13:00:20 -07:00
|
|
|
KIRI_SPRAY_DISTANCE,
|
2023-09-09 12:31:23 -07:00
|
|
|
pitch,
|
|
|
|
flags : TRF_THRUACTORS,
|
|
|
|
offsetz : zOffset,
|
|
|
|
data : lineTraceData);
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
if(traceHit && lineTraceData.HitLine) {
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
A_StartSound(
|
|
|
|
"kiri/spraycan_spray",
|
|
|
|
CHAN_WEAPON);
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-10 20:20:14 -07:00
|
|
|
let normal = lineTraceData.HitDir;
|
|
|
|
let spawnedThing = Actor.Spawn("SnekTechSprayerDecalSpawner", lineTraceData.HitLocation - normal);
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerDecalSpawner spawner = SnekTechSprayerDecalSpawner(spawnedThing);
|
2023-09-09 12:31:23 -07:00
|
|
|
|
2023-09-10 20:20:14 -07:00
|
|
|
if(spawner) {
|
|
|
|
spawner.angle = VectorAngle(-normal.x, -normal.y);
|
2023-09-09 12:31:23 -07:00
|
|
|
spawner.actualDecalName = actualDecalName;
|
|
|
|
spawner.master = invoker.owner;
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
invoker.SetPressure(invoker.GetPressure() - KIRI_SPRAY_PRESSURE_PER_USE);
|
2023-09-09 13:00:20 -07:00
|
|
|
invoker.weaponstatus[KIRI_SPRAY_WS_PAINT] -= 1;
|
2023-09-09 09:02:54 -07:00
|
|
|
}
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
invoker.owner.A_Log("Not close enough to a wall to spray.", true);
|
2023-09-09 12:31:23 -07:00
|
|
|
|
2023-09-09 09:02:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
goto waiting;
|
|
|
|
|
2023-09-12 20:44:37 -07:00
|
|
|
unload:
|
|
|
|
KSPR A 2 { invoker.CycleSprayPattern(-1); }
|
|
|
|
goto waiting;
|
|
|
|
|
2023-09-09 16:44:13 -07:00
|
|
|
firemode:
|
2023-09-12 20:44:37 -07:00
|
|
|
KSPR A 2 { invoker.CycleSprayPattern(1); }
|
2023-09-09 12:31:23 -07:00
|
|
|
goto waiting;
|
|
|
|
|
2023-09-09 09:02:54 -07:00
|
|
|
waiting:
|
|
|
|
KSPR A 5;
|
2023-09-09 12:31:23 -07:00
|
|
|
KSPR A 0 A_Refire("waiting");
|
2023-09-09 09:02:54 -07:00
|
|
|
goto ready;
|
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
select0:
|
|
|
|
KSPR A 0 offset(0, 120);
|
|
|
|
---- A 1 A_Raise(12);
|
|
|
|
wait;
|
|
|
|
|
|
|
|
deselect0:
|
|
|
|
KSPR A 0;
|
|
|
|
---- A 1 A_Lower(12);
|
|
|
|
wait;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-09-09 13:00:20 -07:00
|
|
|
override bool AddSpareWeapon(actor newowner)
|
|
|
|
{
|
|
|
|
return AddSpareWeaponRegular(newowner);
|
|
|
|
}
|
|
|
|
|
|
|
|
override HDWeapon GetSpareWeapon(actor newowner, bool reverse, bool doselect)
|
|
|
|
{
|
|
|
|
return GetSpareWeaponRegular(newowner, reverse, doselect);
|
|
|
|
}
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
// 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;
|
2023-09-10 20:20:07 -07:00
|
|
|
int lastChargedTime = int(round(
|
|
|
|
float(pressure - KIRI_SPRAY_MAXPRESSURE) / float(KIRI_SPRAY_PRESSURE_DECAY_RATE) + time));
|
2023-09-09 14:34:54 -07:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
override void InitializeWepStats(bool idfa)
|
|
|
|
{
|
|
|
|
super.InitializeWepStats(idfa);
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
SetPressure(0);
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
// Add a little bit of randomness to the amount of paint in
|
|
|
|
// the can.
|
2023-09-09 13:00:20 -07:00
|
|
|
weaponstatus[KIRI_SPRAY_WS_PAINT] =
|
2023-09-09 12:31:23 -07:00
|
|
|
KIRI_SPRAY_MAXPAINT
|
|
|
|
- random(0, KIRI_SPRAY_MAXPAINT / 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
override void DrawHUDStuff(
|
|
|
|
HDStatusBar statusBar, HDWeapon weapon,
|
|
|
|
HDPlayerPawn pawn)
|
|
|
|
{
|
|
|
|
// Current pressure (top bar).
|
|
|
|
statusBar.DrawWepNum(
|
2023-09-09 14:34:54 -07:00
|
|
|
GetPressure(),
|
2023-09-09 12:31:23 -07:00
|
|
|
KIRI_SPRAY_MAXPRESSURE, posy:-10);
|
|
|
|
|
|
|
|
// Total paint remaining (bottom bar).
|
|
|
|
statusBar.DrawWepNum(
|
2023-09-09 13:00:20 -07:00
|
|
|
weaponstatus[KIRI_SPRAY_WS_PAINT],
|
2023-09-09 12:31:23 -07:00
|
|
|
KIRI_SPRAY_MAXPAINT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GetSprayPatternList(Array<String> ret)
|
|
|
|
{
|
|
|
|
ret.clear();
|
|
|
|
for(int i = 0; i < AllActorClasses.Size(); i++) {
|
|
|
|
class<Actor> c = AllActorClasses[i];
|
2023-09-09 18:03:56 -07:00
|
|
|
if(c is "SnekTechSprayerPattern" && c != "SnekTechSprayerPattern") {
|
2023-09-09 12:31:23 -07:00
|
|
|
ret.push(c.GetClassName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-12 20:44:37 -07:00
|
|
|
void CycleSprayPattern(int increment)
|
2023-09-09 12:31:23 -07:00
|
|
|
{
|
|
|
|
// Find the current entry in the list of patterns.
|
|
|
|
String currentPattern = CVar.GetCVar("snektech_spraypattern", owner.player).GetString();
|
|
|
|
Array<String> patternList;
|
|
|
|
GetSprayPatternList(patternList);
|
|
|
|
int currentIndex = patternList.find(currentPattern);
|
|
|
|
|
|
|
|
// Make sure we're actually in the list (CVar might not be in
|
|
|
|
// list, due to mods getting shuffled around and whatever).
|
|
|
|
if(currentIndex >= patternList.size()) {
|
|
|
|
currentIndex = -1;
|
|
|
|
}
|
|
|
|
|
2023-09-12 20:44:37 -07:00
|
|
|
// Increment/decrement the index.
|
|
|
|
int newIndex = (currentIndex + increment) % patternList.size();
|
|
|
|
if(newIndex < 0) {
|
|
|
|
newIndex = patternList.size() - 1;
|
|
|
|
}
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
// Set the new CVar.
|
2023-09-10 20:20:11 -07:00
|
|
|
currentPattern = patternList[newIndex];
|
|
|
|
// first, update the Actual cvar
|
|
|
|
if (owner.PlayerNumber() == consoleplayer)
|
|
|
|
CVar.FindCVar("snektech_spraypattern").SetString(currentPattern);
|
|
|
|
// then update the per-player copy so the help text is correct
|
|
|
|
CVar.GetCVar("snektech_spraypattern", owner.player).SetString(currentPattern);
|
2023-09-12 20:44:37 -07:00
|
|
|
|
|
|
|
// Print it.
|
|
|
|
owner.A_Log(
|
|
|
|
String.format(
|
|
|
|
"Selected spray pattern: (%d/%d) %s",
|
|
|
|
newIndex + 1, patternList.size(),
|
|
|
|
currentPattern),
|
|
|
|
true);
|
2023-09-09 12:31:23 -07:00
|
|
|
|
|
|
|
// Current pattern is referenced in the help text, so reset
|
|
|
|
// it.
|
|
|
|
A_SetHelpText();
|
|
|
|
}
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
override double WeaponBulk()
|
|
|
|
{
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
|
2023-09-09 12:31:23 -07:00
|
|
|
override String GetHelpText()
|
|
|
|
{
|
|
|
|
super.GetHelpText();
|
|
|
|
|
2023-09-09 14:34:54 -07:00
|
|
|
int messageIndex = level.time;
|
2023-09-09 12:31:23 -07:00
|
|
|
Array<String> messages = {
|
|
|
|
"Deface the tyrant's property.",
|
|
|
|
"Engage in civil disobedience.",
|
|
|
|
"Create a beautiful work of art.",
|
|
|
|
"Show the world that you still exist.",
|
|
|
|
"Defy the tyrant."
|
|
|
|
};
|
|
|
|
|
|
|
|
String currentPattern = CVar.GetCVar("snektech_spraypattern", owner.player).GetString();
|
|
|
|
|
|
|
|
return
|
2023-09-09 16:44:13 -07:00
|
|
|
WEPHELP_FIREMODE .. " Cycle pattern (current: "..currentPattern..").\n"..
|
2023-09-12 20:44:37 -07:00
|
|
|
WEPHELP_UNLOAD .. " Cycle pattern (backwards).\n"..
|
2023-09-09 16:44:13 -07:00
|
|
|
WEPHELP_ALTFIRE .. " Shake the can.\n"..
|
|
|
|
WEPHELP_FIRE .. " "..messages[messageIndex % messages.Size()].."\n";
|
2023-09-09 09:02:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-10 20:20:14 -07:00
|
|
|
class SnekTechSprayerDecalSpawner : Decal
|
2023-09-09 09:02:54 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
+nogravity;
|
|
|
|
}
|
|
|
|
|
|
|
|
states
|
|
|
|
{
|
|
|
|
spawn:
|
2023-09-09 16:44:13 -07:00
|
|
|
TNT1 A -1;
|
2023-09-09 09:02:54 -07:00
|
|
|
stop;
|
|
|
|
}
|
|
|
|
|
|
|
|
int thisSprayerId;
|
2023-09-09 12:31:23 -07:00
|
|
|
String actualDecalName;
|
2023-09-09 09:02:54 -07:00
|
|
|
|
2023-09-10 20:20:14 -07:00
|
|
|
Array<Thinker> decals;
|
|
|
|
|
|
|
|
void SpawnDecal()
|
|
|
|
{
|
|
|
|
Thinker think;
|
|
|
|
array<thinker> seen;
|
|
|
|
|
|
|
|
// find every decal that Isn't ours
|
|
|
|
let iter = ThinkerIterator.Create('Thinker', STAT_DECAL);
|
|
|
|
while (think = iter.Next()) {
|
|
|
|
// BaseDecal isn't exported to zscript so we have to filter this manually
|
|
|
|
if (think.GetClassName() == 'BaseDecal') {
|
|
|
|
seen.Push(think);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-12 23:32:15 -07:00
|
|
|
// SpawnDecal checks arg0 for the decal ID/name.
|
|
|
|
// gzdoom passes string arguments as negated string table indices, so
|
|
|
|
// we need to cast the decal name to a Name (implicitly adding it to
|
|
|
|
// the string table), then to an int (to get the index).
|
|
|
|
args[0] = -int(Name(actualDecalName));
|
2023-09-10 20:20:14 -07:00
|
|
|
Super.SpawnDecal();
|
|
|
|
|
|
|
|
// then find every decal that we spawned
|
|
|
|
iter.Reinit();
|
|
|
|
while (think = iter.Next()) {
|
|
|
|
if (think.GetClassName() == 'BaseDecal' &&
|
|
|
|
seen.Find(think) == seen.Size())
|
|
|
|
{
|
|
|
|
decals.Push(think);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override void OnDestroy()
|
|
|
|
{
|
|
|
|
for (let i = 0; i < decals.Size(); i++) {
|
|
|
|
if (decals[i]) {
|
|
|
|
decals[i].Destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decal::BeginPlay deletes the actor
|
|
|
|
override void BeginPlay() {Actor.BeginPlay();}
|
|
|
|
|
2023-09-09 09:02:54 -07:00
|
|
|
override void PostBeginPlay()
|
|
|
|
{
|
|
|
|
Super.PostBeginPlay();
|
2023-09-10 20:20:14 -07:00
|
|
|
|
|
|
|
// copy A_SprayDecal z offset
|
|
|
|
setz(pos.z + height / 2);
|
|
|
|
|
|
|
|
SpawnDecal();
|
|
|
|
if (decals.Size() == 0) {
|
|
|
|
Destroy();
|
|
|
|
return;
|
|
|
|
}
|
2023-09-09 09:02:54 -07:00
|
|
|
|
|
|
|
// Figure out a new ID number.
|
2023-09-09 18:03:56 -07:00
|
|
|
ThinkerIterator iter = ThinkerIterator.Create("SnekTechSprayerDecalSpawner");
|
|
|
|
SnekTechSprayerDecalSpawner otherSpawner;
|
2023-09-09 09:02:54 -07:00
|
|
|
int maxId = 0;
|
2023-09-09 18:03:56 -07:00
|
|
|
while(otherSpawner = SnekTechSprayerDecalSpawner(iter.Next())) {
|
2023-09-09 09:02:54 -07:00
|
|
|
|
|
|
|
if(otherSpawner == self) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Keep track of the highest ID.
|
|
|
|
if(otherSpawner.thisSprayerId > maxId) {
|
|
|
|
if(otherSpawner.master == master) {
|
|
|
|
maxId = otherSpawner.thisSprayerId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
thisSprayerId = maxId + 1;
|
|
|
|
|
|
|
|
// Clear old sprayers.
|
2023-09-09 18:03:56 -07:00
|
|
|
iter = ThinkerIterator.Create("SnekTechSprayerDecalSpawner");
|
|
|
|
while(otherSpawner = SnekTechSprayerDecalSpawner(iter.Next())) {
|
2023-09-09 09:02:54 -07:00
|
|
|
|
|
|
|
if(otherSpawner == self) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-09-10 19:51:53 -07:00
|
|
|
int maxSpraysPerPlayer =
|
|
|
|
CVar.GetCVar("snektech_maxspraysperplayer").GetInt();
|
|
|
|
if(otherSpawner.thisSprayerId <= (thisSprayerId - maxSpraysPerPlayer)) {
|
2023-09-09 09:02:54 -07:00
|
|
|
if(otherSpawner.master == master) {
|
|
|
|
otherSpawner.Destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekTechSprayerPattern : Actor
|
2023-09-09 12:31:23 -07:00
|
|
|
{
|
|
|
|
string decalName;
|
|
|
|
property decalName:decalName;
|
|
|
|
|
|
|
|
default {
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "KiriTestDecal";
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_TransPride : SnekTechSprayerPattern
|
2023-09-09 12:31:23 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_TransPride";
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_LesbianPride : SnekTechSprayerPattern
|
2023-09-09 12:31:23 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_LesbianPride";
|
2023-09-09 12:31:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_NBPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_NBPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_AcePride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_AcePride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_ProgressPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_ProgressPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_DemiPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_DemiPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_PanPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_PanPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_SwitchPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_SwitchPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_BiPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_BiPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:03:56 -07:00
|
|
|
class SnekSpray_GayPride : SnekTechSprayerPattern
|
2023-09-09 16:44:13 -07:00
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
2023-09-09 18:03:56 -07:00
|
|
|
SnekTechSprayerPattern.decalName "SnekSpray_GayPride";
|
2023-09-09 16:44:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|