Code: Select all
//Code by Mike Ratzlaff, AKA Sir Robin on ZDoom forums. Use this however you want but please credit me. Thanks!
version "4.10"
// ---------- Line3d Stuff ----------
class Marker3d : actor
{
default
{
height 7;
radius 7;
+RollSprite
+NoGravity
+NoBlockmap
+NoInteraction
+FORCEXYBILLBOARD
}
states
{
spawn:
MARK Y -1 bright;
stop;
}
override void BeginPlay()
{
roll=45;
}
}
class Line3d : actor
{
int TimeToLive,TimeToCycle;
vector3 startVector,deltaVector;
actor marker;
default
{
height 1;
radius 1;
+NoGravity
+NoBlockmap
+NoInteraction
}
states
{
spawn:
PIXL M -1 bright;
stop;
}
override void tick()
{
super.tick();
if (TimeToLive > 0)
{
if (TimeToLive < 15)
{
A_SetRenderStyle(TimeToLive/15.,STYLE_Translucent);
if (marker) marker.A_SetRenderStyle(TimeToLive/15.,STYLE_Translucent);
}
TimeToLive--;
if (TimeToLive == 0) Destroy();
}
if (TimeToCycle > 1 && marker)
{
marker.SetOrigin(startVector + deltaVector * (level.time % TimeToCycle) / (TimeToCycle - 1), false);
}
}
override void OnDestroy()
{
if (marker) marker.Destroy();
super.OnDestroy();
}
void SetEndPoints(vector3 StartPos, vector3 EndPos, int TimeToLive = -1, int TimeToCycle = 0)
{
startVector = StartPos;
deltaVector = EndPos - StartPos;
vector3 midOff = deltaVector / 2;
SetOrigin(StartPos + midOff, false);
scale.y = deltaVector.length();
scale.x = 0.25;
pitch = -90 - VectorAngle(deltaVector.xy.length(),deltaVector.z);
angle = VectorAngle(deltaVector.x, deltaVector.y);
self.TimeToLive=TimeToLive;
self.TimeToCycle=TimeToCycle;
if (TimeToCycle > 1)
{
if (marker)
marker.SetOrigin(StartPos,false);
else
marker=spawn("marker3d",StartPos);
}
else
{
if (marker) marker.destroy();
}
A_SetSize(max(abs(deltaVector.x),abs(deltaVector.y)) / 2, abs(deltaVector.z) / 2);
}
static Line3d SpawnTo(vector3 StartPos, vector3 EndPos, int TimeToLive = -1, int TimeToCycle = 0)
{
Line3d l3d = Line3d(actor.spawn("Line3d",StartPos));
if (l3d) l3d.SetEndPoints(StartPos,EndPos,TimeToLive, TimeToCycle);
return l3d;
}
}
// ---------- Happy Fun Party Stuff ----------
//A place to park some math functions
//Developed by Mike Ratzlaff (AKA Sir Robin on Zdoom forums) with a tremendous amount of help From Player701
Struct LineTraceCalc
{
static double, double, double GetHitAnglePitchRoll(FLineTraceData t){
double ang, pt, roll;
switch (t.HitType)
{
case TRACE_HitFloor:
case TRACE_HitCeiling:
[ang, pt, roll] = GetHitAnglePitchRollFromPlane(t);
break;
case TRACE_HitWall:
[ang, pt, roll] = GetHitAnglePitchRollFromLine(t);
break;
default:
return 180+VectorAngle(t.HitDir.x,t.HitDir.y), 270+VectorAngle(t.HitDir.xy.length(),t.HitDir.z), 0;
}
return ang, pt, roll;
}
static double, double, double GetHitAnglePitchRollFromPlane(FLineTraceData t){
bool is3dfloor = t.Hit3DFloor != null;
SecPlane p;
if (is3dfloor)
{
p = t.HitType == TRACE_HitFloor ? t.Hit3DFloor.top : t.Hit3DFloor.bottom;
}
else if (t.HitType == TRACE_HitFloor)
{
p = t.HitSector.floorplane;
}
else // if (t.HitType == TRACE_HitCeiling)
{
p = t.HitSector.ceilingplane;
}
let n = p.Normal;
if (is3dfloor){n=-1*n;}
double ang = 0, pt = -asin(n.Z);
if (n.XY.Length() > 0)
{
ang = atan2(n.Y, n.X);
}
double roll = VectorAngle(t.HitDir.x,t.HitDir.y) + 180 - ang;
return ang, pt - 90, pt > 0 ? roll : -roll;
}
static double, double, double GetHitAnglePitchRollFromLine(FLineTraceData t)
{
let delta = t.HitLine.delta;
double ang = atan2(delta.Y, delta.X);
return ang + (t.LineSide == Line.front ? -90 : 90), -90, 0;
}
}
class Marker3d_M : Marker3d //Marker Magenta
{
states
{
spawn:
MARK M -1 bright;
stop;
}
}
//Put this in inventory and then use it on floors, walls, ceilings, actors, or even open space
//To stop the flow, drop it and pick it up again
class LineDrawer : Inventory
{
vector3 lastPos, nextPos;
line3d ActiveLine;
FLineTraceData curFltd;
default
{
+Inventory.InvBar;
}
states
{
spawn:
UNKN A -1;
stop;
}
override void tick()
{
super.tick();
if(!owner || !owner.player || !owner.player.mo)
{
if (ActiveLine) ActiveLine.destroy();
return;
}
Owner.LineTrace(
owner.angle,
owner.player.mo.userange,
owner.pitch,
TRF_SolidActors,
owner.player.viewheight,
data: curFltd
);
nextPos = curFltd.HitLocation;
if (ActiveLine) ActiveLine.SetEndPoints(lastPos,nextPos,-1,20);
}
override bool use(bool pickup)
{
if(!owner || !owner.player || !owner.player.mo) return false;
lastPos=nextPos;
ActiveLine=line3d.SpawnTo(lastPos,NextPos);
if (curFltd.HitType == TRACE_HitFloor || curFltd.HitType == TRACE_HitWall || curFltd.HitType == TRACE_HitCeiling)
{
actor marker = spawn("Marker3d_M",curFltd.HitLocation);
double y,p,r;
[y,p,r] = LineTraceCalc.GetHitAnglePitchRoll(curFltd);
marker.bFlatSprite = true;
marker.angle = y;
marker.pitch = p;
marker.roll = random(0,359);
}
return false;
}
override bool PreTeleport( Vector3 destpos, double destangle, int flags )
{
if (ActiveLine) ActiveLine.Destroy();
return super.PreTeleport(destpos, destangle, flags);
}
override void PreTravelled()
{
if (ActiveLine) ActiveLine.Destroy();
super.PreTravelled();
}
override void OnDestroy()
{
if (ActiveLine) ActiveLine.Destroy();
super.OnDestroy();
}
}
//Put this inventory and go frolic, drop it to stop the madness
class LinesComingOutMyButt : Inventory
{
vector3 lastPos, nextPos;
line3d ActiveLine;
const TimeToCycle = 5;
const TimeToLive = 350;
default
{
+Inventory.InvBar;
}
states
{
spawn:
UNKN A -1;
stop;
}
override void tick()
{
super.tick();
if(!owner || !owner.player || !owner.player.mo)
{
if (ActiveLine) ActiveLine.destroy();
return;
}
nextPos = owner.pos + (RotateVector((16,0),owner.angle+180),owner.player.viewheight / 2);
if (ActiveLine)
{
ActiveLine.SetEndPoints(lastPos,nextPos,TimeToLive);
}
else
{
lastPos=nextPos;
ActiveLine=line3d.SpawnTo(lastPos,nextPos,TimeToLive);
}
if (level.time % TimeToCycle == 0 && lastPos != nextPos)
{
ActiveLine.SetEndPoints(lastPos,nextPos,TimeToLive,TimeToCycle);
lastPos=nextPos;
ActiveLine=line3d.SpawnTo(lastPos,nextPos,TimeToLive);
}
}
override bool PreTeleport( Vector3 destpos, double destangle, int flags )
{
console.printf(level.time..": "..GetCharacterName()..": PreTeleport");
if (ActiveLine) ActiveLine=null;
return super.PreTeleport(destpos, destangle, flags);
}
override void OnDestroy()
{
if (ActiveLine) ActiveLine.Destroy();
super.OnDestroy();
}
}
Code: Select all
//Code by Mike Ratzlaff, AKA Sir Robin on ZDoom forums. Use this however you want but please credit me. Thanks!
// ---------- Line3d Stuff ----------
sprite MARKY0, 14, 14 //Marker Yellow (baseline)
{
offset 7,7
patch selectbo, 7, 7
patch selectbo, -23, -23
}
sprite PIXLM0, 1, 1 //pixel: magenta
{
offset 1,1
patch selectbo, 0, 0 {translation "0:255=251:251"} //patch can be anything, just using it to draw a pixel
}
// ---------- Happy Fun Party Stuff ----------
sprite MARKM0, 14, 14 //Marker Magenta
{
offset 7,7
patch MARKY0, 0, 0 {translation "160:167=251:254"}
}