commit 050351dba6e45c4aee5d1c540ce4eddb9e9e109e Author: Kiri Date: Wed Mar 22 19:35:40 2023 -0700 Initial commit. diff --git a/mapinfo.txt b/mapinfo.txt new file mode 100644 index 0000000..dd8f99d --- /dev/null +++ b/mapinfo.txt @@ -0,0 +1,5 @@ +gameinfo +{ + AddEventHandlers = "JumperCablesMapLoader" +} + diff --git a/zscript.zs b/zscript.zs new file mode 100644 index 0000000..d761318 --- /dev/null +++ b/zscript.zs @@ -0,0 +1,346 @@ +version "4.10" + +const HDLD_KIRI_JUMPERCABLES = "jmp"; + +const jumperCablesRaycastRange = 48; // Same range as the DERP. +const jumperCablesFixRange = 48; // Maximum distance to a broken linedef to fix, from the raycast hit. + +class JumperCablesMapLoader : EventHandler +{ + Map originalLinedefSpecials2; + + static JumperCablesMapLoader Get() + { + JumperCablesMapLoader loader; + loader = JumperCablesMapLoader(EventHandler.Find("JumperCablesMapLoader")); + return loader; + } + + override void WorldLoaded(WorldEvent e) + { + JumperCablesMapLoader loader = Get(); + + loader.originalLinedefSpecials2.Clear(); + + // Console.printf("butt\n"); + // Console.printf("butt %s\n", level.MapName); + // Console.printf("linedefs %d\n", level.Lines.size()); + + for(int k = 0; k < level.Lines.size(); k++) { + Line line = level.Lines[k]; + + if(line.special != 0) { + // Console.printf(" %d = %d\n", line.index(), line.special); + loader.originalLinedefSpecials2.Insert(line.index(), line.special); + } + } + + } +} + + +class JumperCablesDeployed : HDUPK +{ + int lineDefIndex; + + default + { + } + + states + { + spawn: + DERP A -1 { + invoker.bNoGravity = true; + } + stop; + give: + DERP A 0 { + Console.printf("yoink\n"); + // Re-break the line. + level.Lines[lineDefIndex].special = 0; + Destroy(); + } + goto spawn; + } + + override bool OnGrab(Actor grabber) + { + // Re-break the linedef. + level.Lines[lineDefIndex].special = 0; + + // TODO: Spawn a battery. + // TODO: Spawn debris. + + Console.printf("NO!\n"); + Destroy(); + return false; + } +} + +class JumperCablesUsable : HDWeapon +{ + default + { + +weapon.wimpy_weapon; + +inventory.invbar; + +hdweapon.droptranslation; + +hdweapon.fitsinbackpack; + hdweapon.barrelsize 0,0,0; + weapon.selectionorder 1014; + + scale 0.6; + inventory.icon "DERPEX"; + inventory.pickupmessage "Picked up a wiring bypass kit."; + inventory.pickupsound "derp/crawl"; + translation 0; + tag "Wiring Bypass Kit"; + + hdweapon.refid HDLD_KIRI_JUMPERCABLES; + } + + override bool AddSpareWeapon(actor newowner) + { + return AddSpareWeaponRegular(newowner); + } + + override hdweapon GetSpareWeapon(actor newowner,bool reverse,bool doselect) + { + return GetSpareWeaponRegular(newowner,reverse,doselect); + } + + + states + { + + spawn: + DERP A -1; + stop; + + select: + TNT1 A 0; + goto super::select; + + ready: + TNT1 A 1 { + if(PressingFire()) { + SetWeaponState("deploy"); + } + A_WeaponReady(WRF_NOFIRE | WRF_ALLOWRELOAD | WRF_ALLOWUSER4); + + FLineTraceData linetraceData; + DoLineTrace(HDPlayerPawn(invoker.owner), linetraceData); + + if(linetraceData.hitType != TRACE_HitNone) { + Vector3 hitPos = linetraceData.hitLocation - Vec3Offset(0, 0, 0); + SpawnParticleForLineTrace( + HDPlayerPawn(invoker.owner), + linetraceData); + } + } + goto readyend; + + deploy: + TNT1 AA 1; + TNT1 AAAA 1; + TNT1 AAAA 1; + + TNT1 A 0 A_JumpIf(!pressingfire(),"ready"); + TNT1 A 4 A_StartSound("weapons/pismagclick",CHAN_WEAPON); + TNT1 A 2 A_StartSound("derp/crawl",CHAN_WEAPON,CHANF_OVERLAP); + + TNT1 A 1 { + invoker.owner.A_Log("Blep"); + A_WeaponReady(WRF_NOFIRE | WRF_ALLOWRELOAD | WRF_ALLOWUSER4); + AttachCables(HDPlayerPawn(invoker.owner)); + } + goto ready; + + } + + action void SpawnParticleForLineTrace(HDPlayerPawn pawn, FLineTraceData linetraceData) + { + + Line hitLine = linetraceData.hitLine; + String particleColor = "darkred"; + + // if(linetraceData.hitType == TRACE_HitWall) { + // JumperCablesMapLoader loader = JumperCablesMapLoader.Get(); + // int originalSpecial = loader.originalLinedefSpecials2.Get(hitLine.index()); + // int thisLineSpecial = hitLine.special; + + // if(originalSpecial != thisLineSpecial) { + // particleColor = "green"; + // } + // } + + if(LineTraceFindbrokenLine(linetraceData)) { + particleColor = "green"; + } + + Vector3 hitPos = linetraceData.hitLocation - Vec3Offset(0, 0, 0); + // console.printf("hit pos: %f %f %f\n", hitPos.x, hitPos.y, hitPos.z); + A_SpawnParticle( + particleColor, + 0, 10, 2, 0, + hitPos.x, + hitPos.y, + hitPos.z); + } + + action float Vec2Mag(Vector2 v) + { + return sqrt(v.x * v.x + v.y * v.y); + } + + action float GetDistanceToLine(Line testLine, Vector3 position) + { + Vector2 pos2d; + pos2d.x = position.x; + pos2d.y = position.y; + + Vector2 origin = testLine.v1.p; + + // Get the normalized direction from v1 to v2. + Vector2 direction = testLine.v2.p - origin; + float direction_magnitude = Vec2Mag(direction); + direction = direction / direction_magnitude; + + // Get the position relative to the origin. + pos2d -= origin; + + // Project pos2d onto direction, to get a position along the line. + double t = direction dot pos2d; + + // Clamp position along line to start/end. + if(t < 0.0) { + t = 0; + } + if(t > direction_magnitude) { + t = direction_magnitude; + } + + // Closest point on the line (as an offset from origin). + Vector2 position_on_line = direction * t; + + Vector2 delta_to_line = position_on_line - pos2d; + float final_distance = Vec2Mag(delta_to_line); + + return final_distance; + } + + action void DoLineTrace(HDPlayerPawn pawn, FLineTraceData linetraceData) + { + pawn.LineTrace( + pawn.angle, + 48, + pawn.pitch, + flags : TRF_THRUACTORS, + offsetz : pawn.height * 0.8, + data : linetraceData); + } + + action Line LineTraceFindbrokenLine(FLineTraceData linetraceData) + { + JumperCablesMapLoader loader = JumperCablesMapLoader.Get(); + + // If we're placing this on a wall, then we'll just look at the wall's special. + if(linetraceData.hitType == TRACE_HitWall) { + + if(linetraceData.hitLine) { + + Line hitLine = linetraceData.hitLine; + + if(loader.originalLinedefSpecials2.CheckKey(hitLine.index())) { + + int originalSpecial = loader.originalLinedefSpecials2.Get(hitLine.index()); + int currentSpecial = hitLine.special; + + if(originalSpecial != currentSpecial) + { + return hitLine; + } + } + } + } + + // If we hit a sector *or* got close enough to another linedef + // attached to the sector that we're in, then let's find the + // closest linedef within range that we know is damaged. + if(linetraceData.hitType == TRACE_HitFloor || + linetraceData.hitType == TRACE_HitCeiling || + linetraceData.hitType == TRACE_HitWall) + { + Sector sec = linetraceData.hitSector; + Line closestLineInRange = null; + float closestLineDistance = jumperCablesFixRange; + + // Iterate through all linedefs connected to the sector. + for(int secLineIndex = 0; secLineIndex < sec.lines.size(); secLineIndex++) { + + Line secLine = sec.lines[secLineIndex]; + + // If this is currently special, we don't care about it. + if(secLine.special == 0) { + + // If this *used* to be special, we DO care about it! + if(loader.originalLinedefSpecials2.CheckKey(secLine.index())) { + + // See if thise is the closest one we've found so far. + float distanceToLine = GetDistanceToLine( + secLine, linetraceData.hitLocation); + if(distanceToLine <= closestLineDistance) { + closestLineInRange = secLine; + closestLineDistance = distanceToLine; + } + } + } + } + + // If we found something broken, then return the closest + // thing we found. + if(closestLineInRange) { + Console.printf( + "Dist to line: %f\n", + GetDistanceToLine( + closestLineInRange, linetraceData.hitLocation)); + return closestLineInRange; + } + + } + + return null; + } + + action void AttachCables(HDPlayerPawn pawn) + { + JumperCablesMapLoader loader = JumperCablesMapLoader.Get(); + FLineTraceData linetraceData; + DoLineTrace(pawn, linetraceData); + + Line brokenLine = LineTraceFindbrokenLine(linetraceData); + + if(brokenLine) { + + if(loader.originalLinedefSpecials2.CheckKey(brokenLine.index())) { + + // pawn.A_Log(string.Format("Blep3 %d", + // loader.originalLinedefSpecials2.Get(hitLine.index()))); + + int originalSpecial = loader.originalLinedefSpecials2.Get(brokenLine.index()); + int currentSpecial = brokenLine.special; + + if(originalSpecial != currentSpecial) { + + JumperCablesDeployed deployed = JumperCablesDeployed( + Spawn("JumperCablesDeployed", linetraceData.hitLocation)); + deployed.lineDefIndex = brokenLine.index(); + deployed.bNoGravity = true; + + brokenLine.special = originalSpecial; + } + } + } + } +} +