Initial commit.
This commit is contained in:
commit
050351dba6
5
mapinfo.txt
Normal file
5
mapinfo.txt
Normal file
@ -0,0 +1,5 @@
|
||||
gameinfo
|
||||
{
|
||||
AddEventHandlers = "JumperCablesMapLoader"
|
||||
}
|
||||
|
346
zscript.zs
Normal file
346
zscript.zs
Normal file
@ -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<int, int> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user