version "4.10" const HDLD_KIRI_GRETCHENCOUNTER = "kgc"; 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; bool onSwitch; override double WeaponBulk() { return 20; } override bool AddSpareWeapon(actor newowner) { return AddSpareWeaponRegular(newowner); } override hdweapon GetSpareWeapon(actor newowner,bool reverse,bool doselect) { return GetSpareWeaponRegular(newowner,reverse,doselect); } states { spawn: KGCP # -1 { frame = invoker.onSwitch; } stop; // Needle overlay states. needle_indicator: KGCN # 1; wait; select0: KGCM # 1 { updateOverlay(); } goto select0big; deselect0: KGCM # 1 { updateOverlay(); } goto deselect0big; ready: KGCM B 1 { A_Overlay(355, "needle_indicator"); A_OverlayPivotAlign(355, PSPA_CENTER, PSPA_BOTTOM); // invoker.UpdateDisplay(); updateOverlay(); A_WeaponReady(WRF_ALLOWUSER3); // USER3 = MagManager. } goto readyend; fire: KGCM # 1 offset(0, 20) { updateOverlay(); } KGCM # 1 offset(0, 40) { updateOverlay(); } KGCM # 1 offset(0, 55) { updateOverlay(); } KGCM # 1 { invoker.onSwitch = !invoker.onSwitch; 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)); player.getpsprite(PSP_WEAPON).frame = int(invoker.onSwitch); player.getpsprite(355).frame = int(invoker.onSwitch); // frame = int(invoker.onSwitch); } 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() { // console.printf("lsjksdjklcmsdlkmcsdlkmslckmlkmsdclkmsdclkmsdc"); super.Tick(); UpdateDisplay(); } 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(onSwitch) { 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 && onSwitch) { // 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(onSwitch) { if(!wasNeedleAtMax || framesSinceLastBeep > 15) { if(needlePosition >= 0.9) { referenceActor.A_StartSound("kiri/gretchencounter_blip"); framesSinceLastBeep = 0; } } } } }