Adding frag counter first.

This commit is contained in:
Kiri 2023-09-02 18:20:13 -07:00
commit d484cca3be
29 changed files with 661 additions and 0 deletions

1
cvarinfo.txt Normal file
View File

@ -0,0 +1 @@
server int snektech_spawnflags = 1;

35
gldefs.txt Normal file
View File

@ -0,0 +1,35 @@
brightmap sprite kgcma0
{
map "sprites/bright_kgcma0.png"
disablefullbright
}
brightmap sprite kgcmb0
{
map "sprites/bright_kgcmb0.png"
disablefullbright
}
brightmap sprite kgcna0
{
map "sprites/bright_kgcma0.png"
disablefullbright
}
brightmap sprite kgcnb0
{
map "sprites/bright_kgcmb0.png"
disablefullbright
}
brightmap sprite kgcpa0
{
map "sprites/bright_kgcpa0.png"
disablefullbright
}
brightmap sprite kgcpb0
{
map "sprites/bright_kgcpb0.png"
disablefullbright
}

5
mapinfo.txt Normal file
View File

@ -0,0 +1,5 @@
gameinfo
{
AddEventHandlers = "GretchenCounterEventHandler"
}

12
menudef.txt Normal file
View File

@ -0,0 +1,12 @@
AddOptionMenu "OptionsMenu"
{
Submenu "Snektech Discount Party Pack", "SnekTechMenu"
}
OptionMenu "SnekTechMenu"
{
Title "SnekTech Discount Party Pack"
StaticText "----- Item Spawns -----", "Teal"
FlagOption "Gretchen Counter", "snektech_spawnflags", "YesNo", 0
}

3
sndinfo.txt Normal file
View File

@ -0,0 +1,3 @@
kiri/gretchencounter_click "sounds/kirigretchencounter_click.ogg"
kiri/gretchencounter_blip "sounds/kirigretchencounter_blip.ogg"
kiri/gretchencounter_onoff "sounds/kirigretchencounter_onoff.ogg"

Binary file not shown.

Binary file not shown.

Binary file not shown.

105
source_data/Makefile Normal file
View File

@ -0,0 +1,105 @@
all : \
../sprites/kgcmb0.png \
../sprites/kgcma0.png \
../sprites/kgcmc0.png \
../sprites/kgcna0.png \
../sprites/kgcnb0.png \
../sprites/bright_kgcma0.png \
../sprites/bright_kgcmb0.png \
../sounds/kirigretchencounter_click.ogg \
../sounds/kirigretchencounter_blip.ogg \
../sounds/kirigretchencounter_onoff.ogg \
../sprites/kgcpa0.png \
../sprites/kgcpb0.png \
../sprites/bright_kgcpa0.png \
../sprites/bright_kgcpb0.png \
../sprites/bright_kgcmc0.png
# Base frames
../sprites/kgcma0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--ignore-layer "brightmap" \
--frame-range 0,0 --save-as $@
../sprites/kgcmb0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--ignore-layer "brightmap" \
--frame-range 1,1 --save-as $@
../sprites/kgcmc0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--ignore-layer "brightmap" \
--frame-range 2,2 --save-as $@
# Brightmaps
../sprites/bright_kgcma0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--layer "brightmap" \
--frame-range 0,0 --save-as $@
../sprites/bright_kgcmb0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--layer "brightmap" \
--frame-range 1,1 --save-as $@
../sprites/bright_kgcmc0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--layer "brightmap" \
--frame-range 2,2 --save-as $@
# Needle
../sprites/kgcna0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--layer "needle" \
--frame-range 0,0 --save-as $@
../sprites/kgcnb0.png : gretchencounter_weaponsprite.aseprite
aseprite $^ \
-b \
--layer "needle" \
--frame-range 1,1 --save-as $@
# Pickup sprite
../sprites/kgcpa0.png : gretchencounter_pickupsprite.aseprite
aseprite $^ \
-b \
--ignore-layer "brightmap" \
--frame-range 0,0 --save-as $@
../sprites/kgcpb0.png : gretchencounter_pickupsprite.aseprite
aseprite $^ \
-b \
--ignore-layer "brightmap" \
--frame-range 1,1 --save-as $@
../sprites/bright_kgcpa0.png : gretchencounter_pickupsprite.aseprite
aseprite $^ \
-b \
--layer "brightmap" \
--frame-range 0,0 --save-as $@
../sprites/bright_kgcpb0.png : gretchencounter_pickupsprite.aseprite
aseprite $^ \
-b \
--layer "brightmap" \
--frame-range 1,1 --save-as $@
# Sounds
../sounds/kirigretchencounter_click.ogg : kirigretchencounter_click.wav
ffmpeg -i $^ "-filter:a" "volume=1.0" $@
../sounds/kirigretchencounter_blip.ogg : kirigretchencounter_blip.wav
ffmpeg -i $^ "-filter:a" "volume=1.0" $@
../sounds/kirigretchencounter_onoff.ogg : on_off_switch.wav
ffmpeg -i $^ "-filter:a" "volume=1.0" $@

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sprites/bright_kgcma0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
sprites/bright_kgcmb0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
sprites/bright_kgcmc0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
sprites/bright_kgcpa0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sprites/bright_kgcpb0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sprites/kgcma0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
sprites/kgcmb0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
sprites/kgcmc0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
sprites/kgcna0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sprites/kgcnb0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sprites/kgcpa0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
sprites/kgcpb0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

9
textures.txt Normal file
View File

@ -0,0 +1,9 @@
sprite KGCPA0, 32, 32 {
offset 16, 32
patch KGCPA0,0,0 { }
}
sprite KGCPB0, 32, 32 {
offset 16, 32
patch KGCPB0,0,0 { }
}

491
zscript.zs Normal file
View File

@ -0,0 +1,491 @@
version "4.10"
enum SnekTechSpawnFlags
{
SNEKTECH_GRETCHENCOUNTER = 0
}
const HDLD_KIRI_GRETCHENCOUNTER = "kgc";
class GretchenCounterEventHandler : EventHandler
{
bool GetItemEnabled(int item)
{
int spawnFlags = CVar.GetCVar("snektech_spawnflags").GetInt();
if(spawnFlags & (1 << item)) {
return true;
}
return false;
}
override void WorldThingSpawned(WorldEvent e)
{
if(!e.Thing) {
return;
}
// Disable drop useless ammo for batteries.
HDBattery bat = HDBattery(e.Thing);
if(bat) {
bat.ItemsThatUseThis.Push("GretchenCounter");
}
// Delete disabled items from backpacks that just spawned.
HDBackpack pack = HDBackpack(e.Thing);
if(pack && !pack.owner) {
if(!GetItemEnabled(SNEKTECH_GRETCHENCOUNTER)) {
pack.storage.DestroyItem("GretchenCounter");
}
}
}
override void CheckReplacement(ReplaceEvent e)
{
if(!e.Replacement) {
return;
}
if(e.isFinal) {
return;
}
if(GetItemEnabled(SNEKTECH_GRETCHENCOUNTER)) {
if(e.Replacee == "Stimpack") {
if(random() < 12) {
e.Replacement = "GretchenCounter";
}
}
}
}
}
enum GretchenCounterStatus
{
KGC_BATTERY=0,
KGC_ACTIVE=1
}
class GretchenCounter : HDWeapon
{
default
{
+weapon.wimpy_weapon;
+inventory.invbar;
+hdweapon.droptranslation;
+hdweapon.fitsinbackpack;
hdweapon.barrelsize 0,0,0;
weapon.selectionorder 1014;
scale 0.6;
inventory.icon "KGCPA0";
inventory.pickupmessage "Picked up a Gretchen Counter.";
inventory.pickupsound "derp/crawl";
translation 0;
tag "Gretchen Counter";
hdweapon.refid HDLD_KIRI_GRETCHENCOUNTER;
}
float lastReading;
float angularVelocity;
float needlePosition;
int framesSinceLastBeep;
int lastBatteryCheckFrame;
override bool AddSpareWeapon(actor newowner)
{
return AddSpareWeaponRegular(newowner);
}
override HDWeapon GetSpareWeapon(actor newowner, bool reverse, bool doselect)
{
return GetSpareWeaponRegular(newowner, reverse, doselect);
}
int hash(int x)
{
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
bool HasBatteryCharge()
{
int bat = weaponstatus[KGC_BATTERY];
if(bat > 0) {
int timeHash = hash(level.time / 10);
if((timeHash % 5) < bat) {
return true;
}
}
return false;
}
void TickBattery()
{
if(weaponstatus[KGC_ACTIVE] &&
weaponstatus[KGC_BATTERY] > 0)
{
// Discharge rate: 1/1000 chance per tick.
int r = random(0, 4000);
if(r < 2) {
weaponstatus[KGC_BATTERY] -= 1;
}
}
}
states
{
spawn:
KGCP # 1 { frame = invoker.GetIsActive(); }
loop;
// Needle overlay states.
needle_indicator:
KGCN # 1; wait;
select0:
KGCM # 1 {
updateOverlay();
}
goto select0big;
deselect0:
KGCM # 1 {
updateOverlay();
}
goto deselect0big;
user3:
#### A 0 A_MagManager("HDBattery");
goto ready;
unload:
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 10 {
if(invoker.weaponstatus[KGC_BATTERY] != -1) {
A_StartSound("weapons/pocket", 9);
HDMagAmmo.GiveMag(self, "HDBattery", invoker.weaponstatus[KGC_BATTERY]);
invoker.weaponstatus[KGC_BATTERY] = -1;
}
}
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 0) { updateOverlay(); }
goto ready;
reload:
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 10 {
if(CountInv("HDBattery")) {
// Unload existing battery.
if(invoker.weaponstatus[KGC_BATTERY] != -1) {
A_StartSound("weapons/pocket", 9);
HDMagAmmo.GiveMag(self, "HDBattery", invoker.weaponstatus[KGC_BATTERY]);
invoker.weaponstatus[KGC_BATTERY] = -1;
}
// Load new mag.
A_StartSound("weapons/plasload", 8);
HDMagAmmo magAmmo = HDMagAmmo(
FindInventory("HDBattery"));
if(magAmmo) {
invoker.weaponstatus[KGC_BATTERY] = magAmmo.TakeMag(true);
}
}
}
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 0) { updateOverlay(); }
goto ready;
ready:
KGCM B 1 {
A_Overlay(355, "needle_indicator");
A_OverlayPivotAlign(355, PSPA_CENTER, PSPA_BOTTOM);
// invoker.UpdateDisplay();
updateOverlay();
// USER3 = MagManager.
// USER4 = Unload.
A_WeaponReady(WRF_ALLOWUSER3 | WRF_ALLOWUSER4 | WRF_ALLOWRELOAD);
}
goto readyend;
fire:
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 1 {
invoker.weaponstatus[KGC_ACTIVE] =
!invoker.weaponstatus[KGC_ACTIVE];
A_PlaySound("kiri/gretchencounter_onoff");
updateOverlay();
}
KGCM # 1 offset(0, 55) { updateOverlay(); }
KGCM # 1 offset(0, 40) { updateOverlay(); }
KGCM # 1 offset(0, 20) { updateOverlay(); }
KGCM # 1 offset(0, 0) { updateOverlay(); }
goto waiting;
waiting:
KGCM # 1 { updateOverlay(); }
KGCM # 1 { updateOverlay(); }
KGCM # 1 { updateOverlay(); }
KGCM # 1 { updateOverlay(); }
KGCM # 1 { updateOverlay(); }
KGCM # 1 A_Refire("waiting");
goto ready;
readyend:
#### # 0 A_ReadyEnd();
#### # 0 A_Jump(256,"ready");
}
action void updateOverlay()
{
float angle_min = -45.0;
float angle_max = 45.0;
A_OverlayRotate(355,
angle_min + (angle_max - angle_min) * (1.0 - invoker.needlePosition));
if(invoker.weaponstatus[KGC_ACTIVE]) {
if(invoker.HasBatteryCharge()) {
player.getpsprite(PSP_WEAPON).frame = 1;
} else {
player.getpsprite(PSP_WEAPON).frame = 2;
}
} else {
player.getpsprite(PSP_WEAPON).frame = 0;
}
player.getpsprite(355).frame = int(invoker.GetIsActive());
}
float GetReadingForType(String type_name, float distance_scale)
{
ThinkerIterator iter = ThinkerIterator.Create(type_name);
Actor mo;
float totalReading = 0.0;
Actor referenceActor = owner;
if(!referenceActor) {
referenceActor = self;
}
while(mo = Actor(iter.Next()))
{
if(mo.health <= 0) {
continue;
}
float dist = referenceActor.Distance3D(mo);
// Convert to "meters" (with a minimum).
if(dist < 32) {
dist = 32;
}
// Scale distance.
dist *= distance_scale;
// Apply inverse-square falloff.
totalReading += 1.0 / (dist * dist);
}
return totalReading;
}
override void Tick()
{
super.Tick();
UpdateDisplay();
TickBattery();
}
override void DrawHUDStuff(
HDStatusBar statusBar, HDWeapon weapon,
HDPlayerPawn pawn)
{
if(statusBar.hudlevel == 1) {
statusBar.drawbattery(
-54, -4,
statusBar.DI_SCREEN_CENTER_BOTTOM,
reloadorder : true);
statusBar.drawnum(
pawn.countinv("HDBattery"),
-46, -8,
statusBar.DI_SCREEN_CENTER_BOTTOM);
}
int bat = weapon.weaponstatus[KGC_BATTERY];
if(bat > 0) {
// Draw battery bar.
statusbar.drawwepnum(bat, 20);
} else if(bat > -1) {
// No battery.
statusBar.drawstring(
statusBar.mamountfont, "00000",
(-16,-9),
statusBar.DI_TEXT_ALIGN_RIGHT |
statusBar.DI_TRANSLATABLE |
statusBar.DI_SCREEN_CENTER_BOTTOM,
Font.CR_DARKGRAY);
}
}
bool GetIsActive()
{
return weaponstatus[KGC_ACTIVE] &&
HasBatteryCharge();
}
override void InitializeWepStats(bool idfa)
{
weaponstatus[KGC_BATTERY] = 20;
weaponstatus[KGC_ACTIVE] = 0;
super.InitializeWepStats(idfa);
}
override double WeaponBulk()
{
int battery_weight = 0;
if(weaponstatus[KGC_BATTERY] != -1) {
// Battery bulk = 18, but inside this combines with its
// bulk (takes up less room).
battery_weight = 10;
}
// This item's bulk is 20. Battery adds to that.
return battery_weight + 20;
}
void UpdateDisplay()
{
Actor referenceActor = owner;
if(!referenceActor) {
referenceActor = self;
}
// ThinkerIterator iter = ThinkerIterator.Create("BFGNecroShard");
// Actor mo;
// int shardCount = 0;
// float totalReading = 0.0;
// while(mo = BFGNecroShard(iter.Next()))
// {
// //shardCount++;
// float dist = Distance3D(mo);
// // Convert to "meters" (with a minimum).
// if(dist < 32) {
// dist = 32;
// }
// dist /= 32.0;
// // // Arbitrary scaling.
// // dist /= 16.0;
// totalReading += 1.0 / (dist * dist);
// shardCount += 1;
// }
float totalReading = 0.0;
if(GetIsActive()) {
totalReading =
GetReadingForType("BFGNecroShard", 1.0) +
GetReadingForType("HDBarrel", 2.0);
}
// lastReading = totalReading * 0.01 + lastReading * 0.99;
float pct_reading = lastReading * 2000.0;
lastReading = totalReading;
float r = frandom(0.0, 1.0);
if(r < pct_reading && GetIsActive())
{
// console.printf("test: %f %f", r, pct_reading);
referenceActor.A_StartSound("kiri/gretchencounter_click");
}
// if(pct_reading > 1.0) {
// pct_reading = 1.0;
// }
// String meter_str = "";
// float k;
// for(k = 0.0; k < 1.0; k += 0.02) {
// if(k < pct_reading) {
// meter_str = meter_str.."#";
// } else {
// meter_str = meter_str.."_";
// }
// }
// if(pct_reading > 1.0) {
// pct_reading = 1.0;
// }
// A_OverlayRotate(355,
// angle_min + (angle_max - angle_min) * (1.0 - pct_reading));
angularvelocity += pct_reading - needlePosition;
angularvelocity *= 0.97;
bool wasNeedleAtMax = (needlePosition >= 0.9);
needlePosition += angularvelocity * 0.1;
needlePosition = clamp(needlePosition, 0.0, 1.0);
// console.printf("Ang vel %f", angularvelocity);
// console.printf("Shard count: [%s] %f", meter_str, pct_reading);
framesSinceLastBeep++;
// if(GetIsActive())
{
if(!wasNeedleAtMax || framesSinceLastBeep > 15) {
if(needlePosition >= 0.9) {
referenceActor.A_StartSound("kiri/gretchencounter_blip");
framesSinceLastBeep = 0;
}
}
}
}
override string GetHelpText()
{
return ""
..WEPHELP_FIRE.." Toggle on/off\n"
..WEPHELP_RELOAD.." Reload battery\n"
..WEPHELP_UNLOAD.." Remove battery\n"
..WEPHELP_MAGMANAGER;
}
}