Add player path tracing in minimap.
This commit is contained in:
parent
820f10c9f8
commit
13b2cb53b3
10 changed files with 166 additions and 4 deletions
|
|
@ -89,6 +89,9 @@ server bool swwm_altclear = false; // use an alternate, less graphically demand
|
|||
nosave bool swwm_mm_enable = true; // show a minimap below the score counter
|
||||
nosave bool swwm_mm_missiles = true; // show projectiles (how revolutionary)
|
||||
nosave bool swwm_mm_usecanvas = false; // use a canvas to draw the minimap, so its pixel density is consistent with the rest of the HUD
|
||||
nosave noarchive bool swwm_mm_steptrace = false;// traces the player path in the minimap
|
||||
nosave int swwm_mm_maxsteps = 5000; // how many steps to keep track of
|
||||
nosave float swwm_mm_minstep = 32.; // minimum 2D distance between steps in map units
|
||||
|
||||
server noarchive bool swwm_iseriouslywanttoplaythiswithbd = false; // self-explanatory
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@ SWWM_ALTCLEAR = "Alternate 100% FX";
|
|||
SWWM_MM_ENABLE = "Show Minimap";
|
||||
SWWM_MM_MISSILES = "Projectiles In Minimap";
|
||||
SWWM_MM_USECANVAS = "Fixed Scale Minimap";
|
||||
SWWM_MM_STEPTRACE = "Minimap Step Tracing";
|
||||
SWWM_MM_MAXSTEPS = "Minimap Max Steps";
|
||||
SWWM_MM_MINSTEP = "Minimap Step Size";
|
||||
SWWM_AC_UNLOCKED = "Unlocked: ";
|
||||
SWWM_AC_INCOMPLETE = "Incomplete: ";
|
||||
SWWM_AC_UNDISCOVERED = "Undiscovered: ";
|
||||
|
|
@ -288,6 +291,9 @@ TOOLTIP_SWWMACHIEVEMENTMENU = "View your achievements.";
|
|||
TOOLTIP_SWWM_MM_ENABLE = "Displays a minimap on the top right corner of the screen.";
|
||||
TOOLTIP_SWWM_MM_MISSILES = "Displays projectiles in the minimap. Can be toggled if this clutters too much.";
|
||||
TOOLTIP_SWWM_MM_USECANVAS = "Rather than being drawn directly on-screen, the minimap will be drawn to a texture, maintaining the same pixel density as the rest of the HUD. Due to engine quirks, this causes the map to have a one-frame delay.";
|
||||
TOOLTIP_SWWM_MM_STEPTRACE = "Traces the player's path on the minimap. Note: Previously recorded data will be erased when starting a new trace.";
|
||||
TOOLTIP_SWWM_MM_MAXSTEPS = "Maximum player steps to hold in memory.";
|
||||
TOOLTIP_SWWM_MM_MINSTEP = "Minimum distance in map units to count as an individual step.";
|
||||
TOOLTIP_SWWMDEBUGMENU = "Don't touch this unless you know what you're doing.";
|
||||
TOOLTIP_SWWM_DEBUGBLAST = "Shows radii of DoExplosion calls. Damaging explosions are green, with yellow for the hotspot. Non-damaging explosions are blue, with magenta for the hotspot.";
|
||||
TOOLTIP_SWWM_DEBUGVIEW = "Shows collision, orientation and velocity of actors, as well as relationship lines to their target/tracer/master pointers (gold/orange/purple respectively).";
|
||||
|
|
|
|||
|
|
@ -191,6 +191,9 @@ SWWM_ALTCLEAR = "Efecto Alternativo de 100%";
|
|||
SWWM_MM_ENABLE = "Mostrar Minimapa";
|
||||
SWWM_MM_MISSILES = "Proyectiles en Minimapa";
|
||||
SWWM_MM_USECANVAS = "Minimapa a Escala Fija";
|
||||
SWWM_MM_STEPTRACE = "Trazo de Pasos en Minimapa";
|
||||
SWWM_MM_MAXSTEPS = "Máx. de Pasos en Minimapa";
|
||||
SWWM_MM_MINSTEP = "Tam. de Pasos en Minimapa";
|
||||
SWWM_AC_UNLOCKED = "Desbloqueados: ";
|
||||
SWWM_AC_INCOMPLETE = "Incompletos: ";
|
||||
SWWM_AC_UNDISCOVERED = "Sin descubrir: ";
|
||||
|
|
@ -283,6 +286,9 @@ TOOLTIP_SWWMACHIEVEMENTMENU = "Revisa tus logros.";
|
|||
TOOLTIP_SWWM_MM_ENABLE = "Muestra un minimapa en la esquina superior derecha de la pantalla.";
|
||||
TOOLTIP_SWWM_MM_MISSILES = "Muestra proyectiles en el minimapa. Puede ser desactivado si causa problemas de visibilidad.";
|
||||
TOOLTIP_SWWM_MM_USECANVAS = "En vez de dibujarse directamente a la pantalla, el mapa se dibujará en una texture, mantentiendo la misma densidad de píxel que el resto del HUD. Debido a peculiaridades del motor, esto causa que el mapa tenga un frame de retardo.";
|
||||
TOOLTIP_SWWM_MM_STEPTRACE = "Traza el camino del jugador en el minimapa. Nota: Los datos anteriores serán borrados al comenzar un nuevo trazado.";
|
||||
TOOLTIP_SWWM_MM_MAXSTEPS = "Pasos máximos a almacenar en memoria.";
|
||||
TOOLTIP_SWWM_MM_MINSTEP = "Distancia mínima en unidades de mapa que cuente como un paso individual.";
|
||||
TOOLTIP_SWWMDEBUGMENU = "No toques esto a menos que sepas lo que estás haciendo.";
|
||||
TOOLTIP_SWWM_DEBUGBLAST = "Muestra el radio de funciones DoExplosion. Las explosiones con daño son verdes, con amarillo para su punto caliente. Las explosiones sin daño son azules, con magenta para su punto caliente.";
|
||||
TOOLTIP_SWWM_DEBUGVIEW = "Muestra la colisión, orientación y velocidad de actores, junto con lineas de relación hacia sus punteros de objetivo/trazador/maestro (dorado/naranja/púrpura respectivamente).";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[default]
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1043 \cu(Thu 7 Dec 18:12:07 CET 2023)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r1043 \cu(2023-12-07 18:12:07)\c-";
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1044 \cu(Thu 7 Dec 23:17:27 CET 2023)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r1044 \cu(2023-12-07 23:17:27)\c-";
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ OptionMenu "SWWMOptionMenu"
|
|||
Option "$SWWM_MM_ENABLE", "swwm_mm_enable", "YesNo"
|
||||
Option "$SWWM_MM_MISSILES", "swwm_mm_missiles", "YesNo"
|
||||
Option "$SWWM_MM_USECANVAS", "swwm_mm_usecanvas", "YesNo"
|
||||
Option "$SWWM_MM_STEPTRACE", "swwm_mm_steptrace", "YesNo"
|
||||
Slider "$SWWM_MM_MAXSTEPS", "swwm_mm_maxsteps", 100, 8000, 100, 0
|
||||
Slider "$SWWM_MM_MINSTEP", "swwm_mm_minstep", 8, 256, 8, 0
|
||||
Option "$SWWM_TARGET", "swwm_targeter", "SWWMTarget"
|
||||
ScaleSliderFix "$SWWM_BARDIST", "swwm_bardist", 0, 4000, 100, "$SWWM_UNLIMITED"
|
||||
Option "$SWWM_TARGETVAL", "swwm_targetvals", "YesNo"
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ Class SWWMHandler : EventHandler
|
|||
// corruption cards stuff
|
||||
ui bool incardmenu, cardmessaged;
|
||||
|
||||
// ring buffer for player path tracing in minimap
|
||||
const MAX_TRACED_BUFSZ = 8192;
|
||||
transient ui Vector2 traced_steps[MAX_TRACED_BUFSZ];
|
||||
transient ui int traced_steppos, traced_stepnum;
|
||||
transient ui Vector2 oldplayerpos;
|
||||
transient ui bool do_trace_steps;
|
||||
|
||||
enum EProfileTimer
|
||||
{
|
||||
PT_WORLDTICK,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,63 @@ extend Class SWWMHandler
|
|||
if ( !bar ) return;
|
||||
bar.mm_zoom = min(1.,bar.mm_zoom+.25);
|
||||
}
|
||||
else if ( e.Name ~== "swwmstepclear" )
|
||||
{
|
||||
Console.Printf("Cleared %d steps.",traced_stepnum);
|
||||
traced_steppos = 0;
|
||||
traced_stepnum = 0;
|
||||
}
|
||||
else if ( e.Name ~== "swwmstepcount" )
|
||||
{
|
||||
double cmdist = 0.;
|
||||
int startpos = traced_steppos-traced_stepnum;
|
||||
if ( startpos < 0 ) startpos += MAX_TRACED_BUFSZ;
|
||||
for ( int i=1; i<traced_stepnum; i++ )
|
||||
{
|
||||
int idx1 = (startpos+(i-1))%MAX_TRACED_BUFSZ;
|
||||
int idx2 = (startpos+i)%MAX_TRACED_BUFSZ;
|
||||
// skip if vectors are NaN, for safety
|
||||
if ( (traced_steps[idx1] != traced_steps[idx1])
|
||||
|| (traced_steps[idx2] != traced_steps[idx2]) ) continue;
|
||||
double sdist = level.Vec2Diff(traced_steps[idx1],traced_steps[idx2]).length();
|
||||
cmdist += sdist;
|
||||
}
|
||||
Console.Printf("%d steps, %g map units total.",traced_stepnum,cmdist);
|
||||
}
|
||||
}
|
||||
|
||||
private ui void CheckPlayerStep()
|
||||
{
|
||||
if ( swwm_mm_steptrace && !do_trace_steps )
|
||||
{
|
||||
// begin tracing now
|
||||
traced_steppos = 0;
|
||||
traced_stepnum = 0;
|
||||
oldplayerpos = (double.nan,double.nan);
|
||||
do_trace_steps = true;
|
||||
}
|
||||
else if ( !swwm_mm_steptrace && do_trace_steps )
|
||||
{
|
||||
// just stop tracing, don't touch the data
|
||||
do_trace_steps = false;
|
||||
}
|
||||
}
|
||||
|
||||
private ui void DoPlayerStep( Vector2 playerpos, bool ignoremindist = false )
|
||||
{
|
||||
// ignore if current position is NaN
|
||||
if ( playerpos != playerpos ) return;
|
||||
// clamp into map bounds to avoid weirdness
|
||||
playerpos.x = clamp(playerpos.x,-32768.,32767.);
|
||||
playerpos.y = clamp(playerpos.y,-32768.,32767.);
|
||||
double clamped_mdist = clamp(swwm_mm_minstep,8.,256.);
|
||||
double mindistsq = clamped_mdist*clamped_mdist;
|
||||
if ( !ignoremindist && (oldplayerpos == oldplayerpos) && ((oldplayerpos-playerpos).lengthsquared() < mindistsq) )
|
||||
return;
|
||||
oldplayerpos = playerpos;
|
||||
traced_steps[traced_steppos] = playerpos;
|
||||
traced_steppos = (traced_steppos+1)%MAX_TRACED_BUFSZ;
|
||||
traced_stepnum = min(traced_stepnum+1,clamp(swwm_mm_maxsteps,2,MAX_TRACED_BUFSZ));
|
||||
}
|
||||
|
||||
override void InterfaceProcess( ConsoleEvent e )
|
||||
|
|
@ -92,6 +149,28 @@ extend Class SWWMHandler
|
|||
GenericFlash gf = new("GenericFlash").Setup(flash_camera,flash_color,flash_duration);
|
||||
StatusBar.AttachMessage(gf,0,BaseStatusBar.HUDMSGLayer_UnderHUD);
|
||||
}
|
||||
else if ( e.Name ~== "swwmsendplayerstep" )
|
||||
{
|
||||
CheckPlayerStep();
|
||||
let demo = Demolitionist(players[consoleplayer].mo);
|
||||
if ( !demo || !do_trace_steps ) return;
|
||||
DoPlayerStep(demo.pos.xy);
|
||||
}
|
||||
else if ( e.Name ~== "swwmsendplayertele" )
|
||||
{
|
||||
CheckPlayerStep();
|
||||
let demo = Demolitionist(players[consoleplayer].mo);
|
||||
if ( !demo || !do_trace_steps ) return;
|
||||
// send the position we had before teleporting
|
||||
DoPlayerStep(demo.pretelepos.xy,true);
|
||||
// to indicate that the player has teleported, we write a NaN into the buffer (yup)
|
||||
oldplayerpos = (double.nan,double.nan);
|
||||
traced_steps[traced_steppos] = (double.nan,double.nan);
|
||||
traced_steppos = (traced_steppos+1)%MAX_TRACED_BUFSZ;
|
||||
traced_stepnum = min(traced_stepnum+1,clamp(swwm_mm_maxsteps,2,MAX_TRACED_BUFSZ));
|
||||
// send the post-teleport position
|
||||
DoPlayerStep(demo.pos.xy,true);
|
||||
}
|
||||
}
|
||||
|
||||
override void NetworkProcess( ConsoleEvent e )
|
||||
|
|
|
|||
|
|
@ -733,6 +733,56 @@ extend Class SWWMStatusBar
|
|||
else t.smoothalpha = 0.;
|
||||
}
|
||||
}
|
||||
private void DrawTracedSteps( Vector2 basepos, bool smol, bool bUseCanvas = false )
|
||||
{
|
||||
if ( !hnd ) return;
|
||||
double zoomlevel = SWWMUtility.Lerp(oldminimapzoom,minimapzoom,FracTic);
|
||||
double zoomview = MAPVIEWDIST*zoomlevel, zoomclip = CLIPDIST*zoomlevel;
|
||||
int hsz = smol?HALFMAPSIZE_SMALL:HALFMAPSIZE;
|
||||
Vector2 cpos = SWWMUtility.LerpVector2(players[consoleplayer].Camera.prev.xy,players[consoleplayer].Camera.pos.xy,FracTic);
|
||||
int startpos = hnd.traced_steppos-hnd.traced_stepnum;
|
||||
int bufsz = SWWMHandler.MAX_TRACED_BUFSZ;
|
||||
if ( startpos < 0 ) startpos += bufsz;
|
||||
for ( int i=1; i<hnd.traced_stepnum; i++ )
|
||||
{
|
||||
int alph = int((i*255.)/hnd.traced_stepnum);
|
||||
int idx1 = (startpos+(i-1))%bufsz;
|
||||
int idx2 = (startpos+i)%bufsz;
|
||||
// skip if vectors are NaN, for safety
|
||||
if ( (hnd.traced_steps[idx1] != hnd.traced_steps[idx1])
|
||||
|| (hnd.traced_steps[idx2] != hnd.traced_steps[idx2]) ) continue;
|
||||
Vector2 rv1 = level.Vec2Diff(cpos,hnd.traced_steps[idx1]),
|
||||
rv2 = level.Vec2Diff(cpos,hnd.traced_steps[idx2]);
|
||||
Vector2 mid = (rv1+rv2)/2.;
|
||||
Vector2 siz = (abs(rv1.x-rv2.x),abs(rv1.y-rv2.y))/2.;
|
||||
if ( (((siz.x+zoomview)-abs(mid.x)) <= 0) || (((siz.y+zoomview)-abs(mid.y)) <= 0) )
|
||||
continue;
|
||||
// flip Y
|
||||
rv1.y *= -1;
|
||||
rv2.y *= -1;
|
||||
// rotate by view
|
||||
rv1 = Actor.RotateVector(rv1,ViewRot.x-90);
|
||||
rv2 = Actor.RotateVector(rv2,ViewRot.x-90);
|
||||
// clip to frame
|
||||
bool visible;
|
||||
[visible, rv1, rv2] = SWWMUtility.LiangBarsky((-1,-1)*zoomclip,(1,1)*zoomclip,rv1,rv2);
|
||||
if ( !visible ) continue;
|
||||
// scale to minimap frame
|
||||
rv1 *= hsz/zoomclip;
|
||||
rv2 *= hsz/zoomclip;
|
||||
if ( !bUseCanvas )
|
||||
{
|
||||
rv1 *= hs;
|
||||
rv2 *= hs;
|
||||
}
|
||||
// offset to minimap center
|
||||
rv1 += basepos;
|
||||
rv2 += basepos;
|
||||
// draw the line
|
||||
if ( bUseCanvas ) mm_canvas.DrawLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),mm_yourcolor,alph);
|
||||
else Screen.DrawThickLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),max(1.,hs*.5),mm_yourcolor,alph);
|
||||
}
|
||||
}
|
||||
|
||||
private String OrdinalStr( int val, int gender )
|
||||
{
|
||||
|
|
@ -756,6 +806,7 @@ extend Class SWWMStatusBar
|
|||
DrawMapLines(basemappos,smol,true);
|
||||
DrawMapThings(basemappos,smol,true);
|
||||
DrawMapMarkers(basemappos,smol,true);
|
||||
DrawTracedSteps(basemappos,smol,true);
|
||||
// finally, draw the player arrow
|
||||
Vector2 tv[] = {(0,-4),(-3,2),(3,2)};
|
||||
for ( int i=0; i<3; i++ ) mm_canvas.DrawLine(int(tv[i].x+hsz),int(tv[i].y+hsz),int(tv[(i+1)%3].x+hsz),int(tv[(i+1)%3].y+hsz),mm_yourcolor);
|
||||
|
|
@ -779,6 +830,7 @@ extend Class SWWMStatusBar
|
|||
DrawMapLines(basemappos*hs,smol);
|
||||
DrawMapThings(basemappos*hs,smol);
|
||||
DrawMapMarkers(basemappos*hs,smol);
|
||||
DrawTracedSteps(basemappos*hs,smol);
|
||||
// finally, draw the player arrow
|
||||
Vector2 tv[] = {(0,-4),(-3,2),(3,2)};
|
||||
for ( int i=0; i<3; i++ ) tv[i] = (tv[i]+basemappos)*hs;
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ extend Class Demolitionist
|
|||
if ( (gamestate != GS_LEVEL) || !player || (player.mo != self) || (freezetics > 0) ) return;
|
||||
UpdateFace();
|
||||
UpdateTags();
|
||||
if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
if ( hasteleported ) hnd.SendInterfaceEvent(PlayerNumber(),"swwmsendplayertele");
|
||||
else hnd.SendInterfaceEvent(PlayerNumber(),"swwmsendplayerstep");
|
||||
}
|
||||
if ( hasteleported )
|
||||
{
|
||||
// we just got teleported, don't count the travel distance
|
||||
|
|
@ -261,7 +267,7 @@ extend Class Demolitionist
|
|||
if ( vel dot vel > lagvel dot lagvel ) lagvel = lagvel*.8+vel*.2;
|
||||
else lagvel = lagvel*.4+vel*.6;
|
||||
double traveldist = level.Vec3Diff(oldpos,pos).length();
|
||||
if ( (traveldist == double.infinity) || (traveldist == double.nan) )
|
||||
if ( (traveldist == double.infinity) || (traveldist != traveldist) )
|
||||
traveldist = 0.; // prevent glitches from breaking stats
|
||||
if ( !player.onground || bNoGravity )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ extend class SWWMUtility
|
|||
if ( developer >= 2 ) Console.Printf("AchievementProgressIncDOuble: achievement '"..pvar.."' not found");
|
||||
return;
|
||||
}
|
||||
if ( pval == "NaN" ) // this can happen, yup
|
||||
if ( pval ~== "NaN" ) // this can happen, yup
|
||||
pval = "0";
|
||||
hnd.achievementprogress.Insert(pvar,String.Format("%g",pval.ToDouble()+inc));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue