diff --git a/mapinfo.txt b/mapinfo.txt new file mode 100644 index 0000000..59650d6 --- /dev/null +++ b/mapinfo.txt @@ -0,0 +1,5 @@ +gameinfo +{ + AddEventHandlers = "GretchenCounterEventHandler" +} + diff --git a/source_data/Makefile b/source_data/Makefile index dec6948..6cd6a97 100644 --- a/source_data/Makefile +++ b/source_data/Makefile @@ -1,6 +1,7 @@ all : \ ../sprites/kgcmb0.png \ ../sprites/kgcma0.png \ + ../sprites/kgcmc0.png \ ../sprites/kgcna0.png \ ../sprites/kgcnb0.png \ ../sprites/bright_kgcma0.png \ @@ -11,7 +12,8 @@ all : \ ../sprites/kgcpa0.png \ ../sprites/kgcpb0.png \ ../sprites/bright_kgcpa0.png \ - ../sprites/bright_kgcpb0.png + ../sprites/bright_kgcpb0.png \ + ../sprites/bright_kgcmc0.png # Base frames ../sprites/kgcma0.png : gretchencounter_weaponsprite.aseprite @@ -26,6 +28,12 @@ all : \ --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 $^ \ @@ -39,6 +47,12 @@ all : \ --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 $^ \ diff --git a/source_data/gretchencounter_weaponsprite.aseprite b/source_data/gretchencounter_weaponsprite.aseprite index 2bfebaa..c6a047f 100644 Binary files a/source_data/gretchencounter_weaponsprite.aseprite and b/source_data/gretchencounter_weaponsprite.aseprite differ diff --git a/sprites/bright_kgcmc0.png b/sprites/bright_kgcmc0.png new file mode 100644 index 0000000..ea27c66 Binary files /dev/null and b/sprites/bright_kgcmc0.png differ diff --git a/sprites/kgcmc0.png b/sprites/kgcmc0.png new file mode 100644 index 0000000..a0a837a Binary files /dev/null and b/sprites/kgcmc0.png differ diff --git a/zscript.zs b/zscript.zs index 42ece36..54e673c 100644 --- a/zscript.zs +++ b/zscript.zs @@ -1,8 +1,25 @@ version "4.10" - const HDLD_KIRI_GRETCHENCOUNTER = "kgc"; +class GretchenCounterEventHandler : StaticEventHandler +{ + override void WorldThingSpawned(WorldEvent e) + { + HDBattery bat = HDBattery(e.Thing); + if(bat) { + bat.ItemsThatUseThis.Push("GretchenCounter"); + console.printf("thing added to thing"); + } + } +} + +enum GretchenCounterStatus +{ + KGC_BATTERY=0, + KGC_ACTIVE=1 +} + class GretchenCounter : HDWeapon { default @@ -28,28 +45,57 @@ class GretchenCounter : HDWeapon float angularVelocity; float needlePosition; int framesSinceLastBeep; - bool onSwitch; - - override double WeaponBulk() - { - return 20; - } + int lastBatteryCheckFrame; override bool AddSpareWeapon(actor newowner) { return AddSpareWeaponRegular(newowner); } - override hdweapon GetSpareWeapon(actor newowner,bool reverse,bool doselect) + override HDWeapon GetSpareWeapon(actor newowner, bool reverse, bool doselect) { - return GetSpareWeaponRegular(newowner,reverse,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, 1000); + if(r < 2) { + weaponstatus[KGC_BATTERY] -= 1; + } + } } states { spawn: - KGCP # -1 { frame = invoker.onSwitch; } - stop; + KGCP # 1 { frame = invoker.GetIsActive(); } + loop; // Needle overlay states. needle_indicator: @@ -67,6 +113,61 @@ class GretchenCounter : HDWeapon } 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"); @@ -74,7 +175,9 @@ class GretchenCounter : HDWeapon // invoker.UpdateDisplay(); updateOverlay(); - A_WeaponReady(WRF_ALLOWUSER3); // USER3 = MagManager. + // USER3 = MagManager. + // USER4 = Unload. + A_WeaponReady(WRF_ALLOWUSER3 | WRF_ALLOWUSER4 | WRF_ALLOWRELOAD); } goto readyend; @@ -85,7 +188,8 @@ class GretchenCounter : HDWeapon KGCM # 1 offset(0, 55) { updateOverlay(); } KGCM # 1 { - invoker.onSwitch = !invoker.onSwitch; + invoker.weaponstatus[KGC_ACTIVE] = + !invoker.weaponstatus[KGC_ACTIVE]; A_PlaySound("kiri/gretchencounter_onoff"); updateOverlay(); } @@ -117,9 +221,17 @@ class GretchenCounter : HDWeapon A_OverlayRotate(355, angle_min + (angle_max - angle_min) * (1.0 - invoker.needlePosition)); - player.getpsprite(PSP_WEAPON).frame = int(invoker.onSwitch); - player.getpsprite(355).frame = int(invoker.onSwitch); - // frame = int(invoker.onSwitch); + 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) @@ -158,9 +270,70 @@ class GretchenCounter : HDWeapon override void Tick() { - // console.printf("lsjksdjklcmsdlkmcsdlkmslckmlkmsdclkmsdclkmsdc"); 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() @@ -193,7 +366,7 @@ class GretchenCounter : HDWeapon // } float totalReading = 0.0; - if(onSwitch) { + if(GetIsActive()) { totalReading = GetReadingForType("BFGNecroShard", 1.0) + GetReadingForType("HDBarrel", 2.0); @@ -206,7 +379,7 @@ class GretchenCounter : HDWeapon lastReading = totalReading; float r = frandom(0.0, 1.0); - if(r < pct_reading && onSwitch) + if(r < pct_reading && GetIsActive()) { // console.printf("test: %f %f", r, pct_reading); referenceActor.A_StartSound("kiri/gretchencounter_click"); @@ -249,7 +422,7 @@ class GretchenCounter : HDWeapon framesSinceLastBeep++; - // if(onSwitch) + // if(GetIsActive()) { if(!wasNeedleAtMax || framesSinceLastBeep > 15) { if(needlePosition >= 0.9) { @@ -260,5 +433,13 @@ class GretchenCounter : HDWeapon } } + override string GetHelpText() + { + return "" + ..WEPHELP_FIRE.." Toggle on/off\n" + ..WEPHELP_RELOAD.." Reload battery\n" + ..WEPHELP_UNLOAD.." Remove battery\n" + ..WEPHELP_MAGMANAGER; + } }