Replaced gib sound (sorry).
Finetuned DoBlast/DoKnockback behavior. Added separate voice line for friend kills. HDoom detection. More sneaky stuff for future Strife compat.
This commit is contained in:
parent
9ba6304eab
commit
a9d1f0d691
25 changed files with 341 additions and 39 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
BIN
graphics/HDScreen.png
Normal file
BIN
graphics/HDScreen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -116,9 +116,6 @@ GOTREDSKUL = "Red Skull Key";
|
|||
// edited vanilla pickup messages
|
||||
TXT_DEFAULTPICKUPMSG = "Unidentified Item";
|
||||
// other edited messages
|
||||
ENDGAME = "This will trigger the crash handler.\n"
|
||||
"\n"
|
||||
"Press Y or N.";
|
||||
QUITMSG = "You really want to go?\n"
|
||||
"What a shame...";
|
||||
QUITMSG1 = "Wow, don't just go and leave,\n"
|
||||
|
|
|
|||
|
|
@ -127,6 +127,12 @@ SWWM_SUBS_DEFAULT_SCOREKILL24 = "Get outta my way.";
|
|||
SWWM_SUBS_DEFAULT_SCOREKILL25 = "Want some more?";
|
||||
SWWM_SUBS_DEFAULT_SCOREKILL26 = "Done and done.";
|
||||
SWWM_SUBS_DEFAULT_SCOREKILL27 = "It's done.";
|
||||
// oopsies
|
||||
SWWM_SUBS_DEFAULT_NFRIENDKILL = "4";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL1 = "Oh my god.";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL2 = "My god. I'm so sorry.";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL3 = "Oh god...";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL4 = "Oh my god. Are you alright?";
|
||||
// getting hurt by monsters
|
||||
SWWM_SUBS_DEFAULT_NGETHIT = "18";
|
||||
SWWM_SUBS_DEFAULT_GETHIT1 = "Whatever...";
|
||||
|
|
|
|||
|
|
@ -109,9 +109,6 @@ GOTREDSKUL = "Calavera Llave Roja";
|
|||
// edited vanilla pickup messages
|
||||
TXT_DEFAULTPICKUPMSG = "Item No Identificado";
|
||||
// other edited messages
|
||||
ENDGAME = "Esto activará el handler de crasheo.\n"
|
||||
"\n"
|
||||
"Pulsa Y ó N.";
|
||||
QUITMSG = "¿En serio quieres irte?\n"
|
||||
"Pues que pena...";
|
||||
QUITMSG1 = "Wow, pero no te vayas aun,\n"
|
||||
|
|
|
|||
|
|
@ -117,6 +117,12 @@ SWWM_SUBS_DEFAULT_SCOREKILL24 = "Quita de en medio.";
|
|||
SWWM_SUBS_DEFAULT_SCOREKILL25 = "¿Quieres más?";
|
||||
SWWM_SUBS_DEFAULT_SCOREKILL26 = "Hecho y hecho.";
|
||||
SWWM_SUBS_DEFAULT_SCOREKILL27 = "Hecho.";
|
||||
// oopsies
|
||||
SWWM_SUBS_DEFAULT_NFRIENDKILL = "4";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL1 = "Oh dios mío.";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL2 = "Dios mío. Lo siento mucho.";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL3 = "Oh dios...";
|
||||
SWWM_SUBS_DEFAULT_FRIENDKILL4 = "Oh dios mío. ¿Estás bien?";
|
||||
// getting hurt by monsters
|
||||
SWWM_SUBS_DEFAULT_GETHIT1 = "Pues vale...";
|
||||
SWWM_SUBS_DEFAULT_GETHIT2 = "*suspiro*";
|
||||
|
|
|
|||
|
|
@ -719,7 +719,12 @@ misc/chat2 sounds/menu/chatsnd.ogg
|
|||
Chat sounds/menu/chatsnd.ogg // hexen what the fuck
|
||||
misc/sundowner sounds/SUNDOWNER.ogg
|
||||
misc/emone sounds/EMONE.ogg
|
||||
misc/gibbed sounds/DEARGODWHY.ogg // probably the "sloppiest" gib sound I've ever heard. thanks, freedoom
|
||||
misc/gibbed1 sounds/general/Gib1.ogg
|
||||
misc/gibbed2 sounds/general/Gib2.ogg
|
||||
misc/gibbed3 sounds/general/Gib3.ogg
|
||||
misc/gibbed4 sounds/general/Gib4.ogg
|
||||
misc/gibbed5 sounds/general/Gib5.ogg
|
||||
$random misc/gibbed { misc/gibbed1 misc/gibbed2 misc/gibbed3 misc/gibbed4 misc/gibbed5 }
|
||||
|
||||
misc/underwater sounds/general/uWater1a.ogg
|
||||
misc/underslime sounds/general/uGoop1.ogg
|
||||
|
|
|
|||
Binary file not shown.
BIN
sounds/general/Gib1.ogg
Normal file
BIN
sounds/general/Gib1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/Gib2.ogg
Normal file
BIN
sounds/general/Gib2.ogg
Normal file
Binary file not shown.
BIN
sounds/general/Gib3.ogg
Normal file
BIN
sounds/general/Gib3.ogg
Normal file
Binary file not shown.
BIN
sounds/general/Gib4.ogg
Normal file
BIN
sounds/general/Gib4.ogg
Normal file
Binary file not shown.
BIN
sounds/general/Gib5.ogg
Normal file
BIN
sounds/general/Gib5.ogg
Normal file
Binary file not shown.
BIN
sounds/voice/default/friendkill1.ogg
Normal file
BIN
sounds/voice/default/friendkill1.ogg
Normal file
Binary file not shown.
BIN
sounds/voice/default/friendkill2.ogg
Normal file
BIN
sounds/voice/default/friendkill2.ogg
Normal file
Binary file not shown.
BIN
sounds/voice/default/friendkill3.ogg
Normal file
BIN
sounds/voice/default/friendkill3.ogg
Normal file
Binary file not shown.
BIN
sounds/voice/default/friendkill4.ogg
Normal file
BIN
sounds/voice/default/friendkill4.ogg
Normal file
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
GameInfo
|
||||
{
|
||||
AddEventHandlers = "SWWMFontPreloader", "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMVanillaBossHandler", "SWWMHandler"
|
||||
AddEventHandlers = "SWWMFontPreloader", "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMHDoomHandler", "SWWMVanillaBossHandler", "SWWMHandler"
|
||||
PlayerClasses = "Demolitionist"
|
||||
StatusBarClass = "SWWMStatusBar"
|
||||
BackpackType = "HammerspaceEmbiggener"
|
||||
|
|
|
|||
|
|
@ -73,11 +73,12 @@ Class SWWMUtility
|
|||
return (((p.y-l.v1.p.y)*l.delta.x+(l.v1.p.x-p.x)*l.delta.y) > double.epsilon);
|
||||
}
|
||||
|
||||
// not portal aware, will have to fix that later
|
||||
// sphere intersection check, useful for proximity detection
|
||||
static bool SphereIntersect( Actor a, Vector3 p, double radius )
|
||||
{
|
||||
Vector3 amin = a.pos+(-a.radius,-a.radius,0),
|
||||
amax = a.pos+(a.radius,a.radius,a.height);
|
||||
Vector3 ap = p+level.Vec3Diff(p,a.pos); // portal-relative actor position
|
||||
Vector3 amin = ap+(-a.radius,-a.radius,0),
|
||||
amax = ap+(a.radius,a.radius,a.height);
|
||||
double distsq = 0.;
|
||||
if ( p.x < amin.x ) distsq += (amin.x-p.x)**2;
|
||||
if ( p.x > amax.x ) distsq += (p.x-amax.x)**2;
|
||||
|
|
@ -87,6 +88,81 @@ Class SWWMUtility
|
|||
if ( p.z > amax.z ) distsq += (p.z-amax.z)**2;
|
||||
return (distsq <= (radius**2));
|
||||
}
|
||||
|
||||
// THANKS FOR NOT GIVING US ANY OTHER WAY TO CHECK IF A LOCK NUMBER IS VALID
|
||||
static bool IsValidLockNum( int l )
|
||||
{
|
||||
if ( (l < 1) || (l > 255) ) return true;
|
||||
Array<Int> valid;
|
||||
valid.Clear();
|
||||
for ( int i=0; i<Wads.GetNumLumps(); i++ )
|
||||
{
|
||||
String lname = Wads.GetLumpName(i);
|
||||
if ( !(lname ~== "LOCKDEFS") ) continue;
|
||||
String data = Wads.ReadLump(i);
|
||||
Array<String> lines;
|
||||
lines.Clear();
|
||||
data.Split(lines,"\n");
|
||||
for ( int j=0; j<lines.Size(); j++ )
|
||||
{
|
||||
if ( lines[j].Left(10) ~== "CLEARLOCKS" ) valid.Clear();
|
||||
else if ( Lines[j].Left(5) ~== "LOCK " )
|
||||
{
|
||||
Array<String> spl;
|
||||
spl.Clear();
|
||||
lines[j].Split(spl," ",TOK_SKIPEMPTY);
|
||||
// check game string (if any)
|
||||
if ( spl.Size() > 2 )
|
||||
{
|
||||
if ( (spl[2] ~== "DOOM") && !(gameinfo.gametype&GAME_Doom) ) continue;
|
||||
else if ( (spl[2] ~== "HERETIC") && !(gameinfo.gametype&GAME_Heretic) ) continue;
|
||||
else if ( (spl[2] ~== "HEXEN") && !(gameinfo.gametype&GAME_Hexen) ) continue;
|
||||
else if ( (spl[2] ~== "STRIFE") && !(gameinfo.gametype&GAME_Strife) ) continue;
|
||||
else if ( (spl[2] ~== "CHEX") && !(gameinfo.gametype&GAME_Chex) ) continue;
|
||||
}
|
||||
valid.Push(spl[1].ToInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( int i=0; i<valid.Size(); i++ )
|
||||
{
|
||||
if ( valid[i] == l ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// wheeeeeeee, let's play a game of "who is who"
|
||||
static bool IsCivilian( Actor a )
|
||||
{
|
||||
if ( a is 'Beggar' )
|
||||
{
|
||||
if ( (a.level.mapname ~== "MAP32") && (a is 'Beggar1') )
|
||||
return false; // Prisoner (sorry but we have to)
|
||||
return true;
|
||||
}
|
||||
if ( a is 'Peasant' )
|
||||
{
|
||||
// exclude certain key NPCs
|
||||
if ( (a.level.mapname ~== "MAP01") && (a is 'Peasant9') )
|
||||
return false; // Beldin (sorry but we have to)
|
||||
if ( (a.level.mapname ~== "MAP02") && (a is 'Peasant22') )
|
||||
return false; // Mourel (fuck that guy)
|
||||
if ( (a.level.mapname ~== "MAP02") && (a is 'Peasant4') )
|
||||
return false; // Harris (also fuck that guy)
|
||||
if ( (a.level.mapname ~== "MAP04") && (a is 'Peasant5') )
|
||||
return false; // Derwin (fat bastard)
|
||||
if ( (a.level.mapname ~== "MAP04") && (a is 'Peasant7') )
|
||||
return false; // Ketrick (THIS IS GARBAGE)
|
||||
if ( (a.level.mapname ~== "MAP05") && (a is 'Peasant7') )
|
||||
return false; // Montag (gimme the damn key)
|
||||
if ( (a.level.mapname ~== "MAP05") && (a is 'Peasant8') )
|
||||
return false; // Wolenick (gimme a hand)
|
||||
if ( (a.level.mapname ~== "MAP33") && (a is 'Peasant5') )
|
||||
return false; // Harris (also fuck that guy)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Stats
|
||||
|
|
@ -1338,7 +1414,11 @@ Class SWWMBulletTrail : LineTracer
|
|||
t.ShootThroughList.Clear();
|
||||
t.Trace(pos,level.PointInSector(pos.xy),dir,dist,0);
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Actor.Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
|
|
@ -1952,9 +2032,17 @@ Class SWWMHandler : EventHandler
|
|||
Actor a;
|
||||
while ( a = Actor(ti.Next()) )
|
||||
{
|
||||
if ( !a.player && !a.bIsMonster && !a.bCountKill ) continue;
|
||||
if ( !a.player && !a.bISMONSTER ) continue;
|
||||
// ignore the dead
|
||||
if ( (a.Health <= 0) || a.bKILLED || a.bCORPSE ) continue;
|
||||
// ignore friends
|
||||
if ( a.IsFriend(players[consoleplayer].mo) ) continue;
|
||||
// [Strife] ignore if not in combat
|
||||
if ( (gameinfo.gametype&GAME_Strife) && !a.bINCOMBAT && !a.bJUSTATTACKED ) continue;
|
||||
// [Strife] ignore certain classes
|
||||
if ( (a is 'RatBuddy') || (a is 'Peasant') || (a is 'Beggar') ) continue;
|
||||
// [Strife] ignore Oracle's spectre while it's inactive
|
||||
if ( (a is 'AlienSpectre3') && a.InStateSequence(a.CurState,a.FindState("Spawn")) ) continue;
|
||||
// ignore if not targetted or either actor can't see the other
|
||||
if ( (a.target != players[consoleplayer].mo)
|
||||
|| !a.CheckSight(players[consoleplayer].mo)
|
||||
|
|
@ -2070,7 +2158,7 @@ Class SWWMHandler : EventHandler
|
|||
if ( (e.DamageSource == players[consoleplayer].mo) && (e.Thing.bISMONSTER || e.Thing.player) )
|
||||
{
|
||||
// make sure it's not a moth, because otherwise they won't shut up about accidentally hurting them (it happens a lot)
|
||||
if ( e.Thing.IsFriend(e.DamageSource) && !(e.Thing is 'LampMoth') )
|
||||
if ( (e.Thing.IsFriend(e.DamageSource) || SWWMUtility.IsCivilian(e.Thing)) && !(e.Thing is 'LampMoth') )
|
||||
{
|
||||
if ( !lastcombat || (gametic > lastcombat+20) )
|
||||
lastcombat = AddOneliner("hitfriend",1,15);
|
||||
|
|
@ -2093,7 +2181,11 @@ Class SWWMHandler : EventHandler
|
|||
{
|
||||
highesttic = gametic;
|
||||
if ( !lastcombat || (gametic > lastcombat+20) )
|
||||
lastcombat = AddOneliner("scorekill",1,15);
|
||||
{
|
||||
if ( e.Thing.IsFriend(e.DamageSource) || SWWMUtility.IsCivilian(e.Thing) )
|
||||
lastcombat = AddOneliner("friendkill",1,15);
|
||||
else lastcombat = AddOneliner("scorekill",1,15);
|
||||
}
|
||||
}
|
||||
if ( !e.Thing.default.bCountKill ) // no credits
|
||||
return;
|
||||
|
|
@ -2272,11 +2364,15 @@ Class SWWMHandler : EventHandler
|
|||
// oneliner on locked doors
|
||||
if ( !e.Thing ) return;
|
||||
int locknum = SWWMUtility.GetLineLock(e.ActivatedLine);
|
||||
if ( !locknum ) return;
|
||||
if ( (locknum < 1) || (locknum > 255) ) return;
|
||||
if ( e.Thing.CheckLocalView() && !e.Thing.CheckKeys(locknum,false,true) )
|
||||
{
|
||||
if ( !lastlock || (gametic > lastlock+20) )
|
||||
lastlock = AddOneliner("locked",2);
|
||||
{
|
||||
if ( SWWMUtility.IsValidLockNum(locknum) )
|
||||
lastlock = AddOneliner("locked",2);
|
||||
else lastlock = AddOneliner("jammed",2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2525,7 +2621,6 @@ Class SWWMHandler : EventHandler
|
|||
if ( (e.player == -1) || !playeringame[e.player] || !players[e.player].mo ) return;
|
||||
let mo = players[e.player].mo;
|
||||
if ( (mo.Health <= 0) || !(mo is 'Demolitionist') ) return;
|
||||
// TODO redo these as fake weapons
|
||||
switch ( e.Args[0] )
|
||||
{
|
||||
case 1:
|
||||
|
|
@ -2759,28 +2854,62 @@ Class SWWMHandler : EventHandler
|
|||
hnd.flashes.push(qf);
|
||||
}
|
||||
|
||||
// Doom's explosions aren't fully 3D
|
||||
static void DoBlast( Actor Source, double ExplosionRadius, double MomentumTransfer, Actor ignoreme = null )
|
||||
// Doom's explosions aren't fully 3D in their knockback
|
||||
static void DoBlast( Actor Source, double ExplosionRadius, double MomentumTransfer, Actor ignoreme = null, bool forceblast = false )
|
||||
{
|
||||
BlockThingsIterator bi = BlockThingsIterator.Create(Source,ExplosionRadius);
|
||||
while ( bi.Next() )
|
||||
{
|
||||
Actor a = bi.Thing;
|
||||
if ( !a || (a == ignoreme) || !a.bSHOOTABLE || !Source.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) || (a == Source) || (Source.Distance3D(a) > ExplosionRadius) || a.bCANNOTPUSH || (a.Mass >= 10000000) )
|
||||
// early checks for self and ignored actor (usually the instigator)
|
||||
if ( !a || (a == ignoreme) || (a == Source) )
|
||||
continue;
|
||||
// can't be affected
|
||||
if ( !a.bSHOOTABLE && !a.bVULNERABLE )
|
||||
continue;
|
||||
// no blasting if no radius dmg (unless forced)
|
||||
if ( a.bNORADIUSDMG && !Source.bFORCERADIUSDMG && !forceblast )
|
||||
continue;
|
||||
// massive, no knockback
|
||||
if ( a.bCANNOTPUSH || (a.Mass >= 10000000) )
|
||||
continue;
|
||||
// check the DONTHARMCLASS/DONTHARMSPECIES flags
|
||||
if ( !a.player && ((Source.bDONTHARMCLASS && (a.GetClass() == Source.GetClass())) || (Source.bDONTHARMSPECIES && (a.GetSpecies() == Source.GetSpecies()))) )
|
||||
continue;
|
||||
// can we see it
|
||||
if ( !Source.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
// make use of GetRadiusDamage to see if it's in range
|
||||
if ( Source.GetRadiusDamage(a,int(MomentumTransfer),int(ExplosionRadius),oldradiusdmg:Source.bOLDRADIUSDMG) <= 0 )
|
||||
continue;
|
||||
// perform our own blasting code, based partially on Unreal's HurtRadius
|
||||
Vector3 midpoint = a.Vec3Offset(0,0,a.height*0.5);
|
||||
Vector3 dir = Level.Vec3Diff(Source.pos,midpoint);
|
||||
double dist = max(1,dir.length());
|
||||
double damagescale = 1-max(0,(dist-a.radius)/ExplosionRadius);
|
||||
// intersecting, randomize direction
|
||||
if ( dir.length() <= double.epsilon )
|
||||
{
|
||||
double ang = FRandom[DoBlast](0,360);
|
||||
double pt = FRandom[DoBlast](-90,90);
|
||||
dir = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt));
|
||||
}
|
||||
dir = dir/dist;
|
||||
a.vel += dir*damagescale*(MomentumTransfer/(Thinker.TICRATE*max(50,a.mass)));
|
||||
Vector3 momentum = dir*damagescale*(MomentumTransfer/Thinker.TICRATE);
|
||||
momentum /= max(50,a.mass); // cap minimum mass to prevent ridiculously strong pushing
|
||||
a.vel += momentum;
|
||||
}
|
||||
}
|
||||
|
||||
// Same for this
|
||||
static void DoKnockback( Actor Victim, Vector3 HitDirection, double MomentumTransfer )
|
||||
{
|
||||
if ( !Victim || !Victim.bSHOOTABLE || Victim.bCANNOTPUSH || (Victim.Mass >= 10000000) ) return;
|
||||
if ( !Victim )
|
||||
return;
|
||||
if ( !Victim.bSHOOTABLE && !Victim.bVULNERABLE )
|
||||
return;
|
||||
if ( Victim.bCANNOTPUSH || (Victim.Mass >= 10000000) )
|
||||
return;
|
||||
Victim.vel += HitDirection*(MomentumTransfer/(Thinker.TICRATE*max(50,Victim.Mass)));
|
||||
}
|
||||
|
||||
|
|
@ -2815,7 +2944,7 @@ Class SWWMCrashHandler : StaticEventHandler
|
|||
wasinmap = true;
|
||||
timer = 0;
|
||||
}
|
||||
else if ( (gamestate == GS_FULLCONSOLE) && (wasinmap || (timer > 0)) )
|
||||
else if ( (gamestate == GS_FULLCONSOLE) && ((wasinmap && !players[consoleplayer].viewheight) || (timer > 0)) )
|
||||
{
|
||||
wasinmap = false;
|
||||
if ( timer == 1 )
|
||||
|
|
@ -2883,9 +3012,53 @@ Class SWWMBrutalHandler : StaticEventHandler
|
|||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
if ( !detected ) return;
|
||||
if ( scr.IsNull() ) scr = TexMan.CheckForTexture("graphics/bdscreen.png",TexMan.Type_Any);
|
||||
if ( !scr ) scr = TexMan.CheckForTexture("graphics/bdscreen.png",TexMan.Type_Any);
|
||||
Screen.Dim("Red",(timer/350.)-.2,0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
Screen.DrawTexture(scr,false,FRandom[bdscreen](-1,1)*max(timer-40,0)**3*.000003,FRandom[bdscreen](-1,1)*max(timer-40,0)**3*.000003,DTA_VirtualWidth,1280,DTA_VirtualHeight,960,DTA_Alpha,min(1.,timer/50.));
|
||||
double ar = Screen.GetAspectRatio();
|
||||
Vector2 tsize = TexMan.GetScaledSize(scr);
|
||||
Vector2 vsize = (Screen.GetWidth(),Screen.GetHeight());
|
||||
if ( (tsize.x > vsize.x) || (tsize.y > vsize.y) )
|
||||
{
|
||||
double sar = tsize.x/tsize.y;
|
||||
if ( sar > ar ) vsize = (tsize.x,tsize.x/ar);
|
||||
else if ( sar < ar ) vsize = (tsize.y*ar,tsize.y);
|
||||
else vsize = tsize;
|
||||
}
|
||||
Screen.DrawTexture(scr,false,(vsize.x-tsize.x)/2.+FRandom[bdscreen](-1,1)*max(timer-40,0)**3*.000003,(vsize.y-tsize.y)/2.+FRandom[bdscreen](-1,1)*max(timer-40,0)**3*.000003,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_Alpha,min(1.,timer/50.));
|
||||
Screen.Dim("Red",(timer/70.)-3.5,0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
// HORNY
|
||||
Class SWWMHDoomHandler : StaticEventHandler
|
||||
{
|
||||
ui TextureID scr;
|
||||
bool detected;
|
||||
|
||||
override void OnRegister()
|
||||
{
|
||||
for ( int i=0; i<AllActorClasses.size(); i++ )
|
||||
{
|
||||
if ( AllActorClasses[i].GetClassName() != "HDoomPlayer" ) continue;
|
||||
detected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
if ( !detected ) return;
|
||||
if ( !scr ) scr = TexMan.CheckForTexture("graphics/hdscreen.png",TexMan.Type_Any);
|
||||
double ar = Screen.GetAspectRatio();
|
||||
Vector2 tsize = TexMan.GetScaledSize(scr);
|
||||
Vector2 vsize = (Screen.GetWidth(),Screen.GetHeight());
|
||||
if ( (tsize.x > vsize.x) || (tsize.y > vsize.y) )
|
||||
{
|
||||
double sar = tsize.x/tsize.y;
|
||||
if ( sar > ar ) vsize = (tsize.x,tsize.x/ar);
|
||||
else if ( sar < ar ) vsize = (tsize.y*ar,tsize.y);
|
||||
else vsize = tsize;
|
||||
}
|
||||
Screen.DrawTexture(scr,false,(vsize.x-tsize.x)/2.,(vsize.y-tsize.y)/2.,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
String nstr = String.Format("%ds",Powerup(i).EffectTics/Thinker.TICRATE);
|
||||
int len = mTewiFont.mFont.StringWidth(nstr);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha);
|
||||
return;
|
||||
}
|
||||
if ( (i is 'SWWMLamp') && aspowerup )
|
||||
|
|
@ -597,7 +597,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,SWWMLamp(i).isBlinking()?alpha*.5:alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
String nstr = String.Format("%d%%",SWWMLamp(i).Charge);
|
||||
int len = mTewiFont.mFont.StringWidth(nstr);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,SWWMLamp(i).isBlinking()?alpha*.5:alpha);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,SWWMLamp(i).isBlinking()?alpha*.5:alpha);
|
||||
return;
|
||||
}
|
||||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
|
|
@ -607,7 +607,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
if ( (i.Amount > 99999) && !forceamt ) nstr = "99999";
|
||||
else nstr = String.Format("%d",i.Amount);
|
||||
int len = mTewiFont.mFont.StringWidth(nstr);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,33 @@ Class SWWMArmor : Armor abstract
|
|||
Super.AttachToOwner(other);
|
||||
// find last armor that's better than us
|
||||
Inventory found = null;
|
||||
bool foundarmor = false;
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( i is 'SWWMArmor' ) foundarmor = true;
|
||||
if ( !(i is 'SWWMArmor') || (i == self) || (SWWMArmor(i).priority < priority) ) continue;
|
||||
found = i;
|
||||
Console.Printf("%s is better",i.GetTag());
|
||||
}
|
||||
if ( !found && !foundarmor )
|
||||
{
|
||||
// check if first item in inventory is health or a sandwich
|
||||
if ( (other.Inv is 'SWWMHealth') || (other.Inv is 'GrilledCheeseSandwich') )
|
||||
{
|
||||
// place ourselves before it
|
||||
Console.Printf("Moving before %s",other.Inv.GetTag());
|
||||
Inv = other.Inv;
|
||||
other.Inv = self;
|
||||
return;
|
||||
}
|
||||
// find first item with health or sandwich after it
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( (i == self) || (!(i.Inv is 'SWWMHealth' ) && !(i.Inv is 'GrilledCheeseSandwich')) ) continue;
|
||||
Console.Printf("%s is right next to %s",i.GetTag(),i.Inv.GetTag());
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !found ) return;
|
||||
// place ourselves right after it
|
||||
|
|
@ -161,6 +184,55 @@ Class SWWMHealth : Inventory abstract
|
|||
|
||||
Property GiveHealth : giveme;
|
||||
|
||||
override void AttachToOwner( Actor other )
|
||||
{
|
||||
Super.AttachToOwner(other);
|
||||
// find last health item that's better than us
|
||||
Inventory found = null;
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( !(i is 'SWWMHealth') || (i == self) || (GetDefaultByType(SWWMHealth(i).giveme).Amount < GetDefaultByType(giveme).Amount) ) continue;
|
||||
found = i;
|
||||
Console.Printf("%s is better",i.GetTag());
|
||||
}
|
||||
if ( !found )
|
||||
{
|
||||
// find last armor item
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( !(i is 'SWWMArmor') ) continue;
|
||||
found = i;
|
||||
Console.Printf("Moving next to armor %s",i.GetTag());
|
||||
}
|
||||
}
|
||||
if ( !found )
|
||||
{
|
||||
// check if the first item in inventory is a sandwich
|
||||
if ( other.Inv is 'GrilledCheeseSandwich' )
|
||||
{
|
||||
Console.Printf("Moving before %s",other.Inv.GetTag());
|
||||
// place ourselves before it
|
||||
Inv = other.Inv;
|
||||
other.Inv = self;
|
||||
return;
|
||||
}
|
||||
// find first item next to a sandwich
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( (i == self) || !(i.Inv is 'GrilledCheeseSandwich') ) continue;
|
||||
Console.Printf("%s is right next to %s",i.GetTag(),i.Inv.GetTag());
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !found ) return;
|
||||
// place ourselves right after it
|
||||
Inventory saved = found.Inv;
|
||||
found.Inv = self;
|
||||
other.Inv = Inv;
|
||||
Inv = saved;
|
||||
}
|
||||
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
bool shouldautouse = false;
|
||||
|
|
@ -778,6 +850,7 @@ Class UseList
|
|||
Class UseLineTracer : LineTracer
|
||||
{
|
||||
Array<UseList> uses;
|
||||
Array<Line> glass;
|
||||
|
||||
override ETraceStatus TraceCallback()
|
||||
{
|
||||
|
|
@ -805,6 +878,8 @@ Class UseLineTracer : LineTracer
|
|||
{
|
||||
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything|Line.ML_BlockUse)) )
|
||||
return TRACE_Stop;
|
||||
if ( Results.HitLine.special == GlassBreak ) // fuck glass
|
||||
glass.Push(Results.HitLine);
|
||||
return TRACE_Skip;
|
||||
}
|
||||
}
|
||||
|
|
@ -971,21 +1046,11 @@ Class SWWMWeapon : Weapon abstract
|
|||
{
|
||||
// temporarily disable parry field so we can trace through
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = false;
|
||||
let raging = RagekitPower(FindInventory("RagekitPower"));
|
||||
int maxang = raging?18:12;
|
||||
for ( int i=0; i<maxang; i++ )
|
||||
{
|
||||
if ( TryMelee(angle+i*(45./16),dmg) || TryMelee(angle-i*(45./16),dmg) )
|
||||
{
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// check for usables
|
||||
let ut = new("UseLineTracer");
|
||||
ut.uses.Clear();
|
||||
ut.glass.Clear();
|
||||
ut.Trace(Vec3Offset(0,0,player.viewheight),CurSector,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),sin(-pitch)),DEFMELEERANGE,0);
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
for ( int i=0; i<ut.uses.Size(); i++ )
|
||||
{
|
||||
if ( ut.uses[i].hitactor )
|
||||
|
|
@ -1001,6 +1066,22 @@ Class SWWMWeapon : Weapon abstract
|
|||
if ( !(ut.uses[i].hitline.activation&SPAC_UseThrough) ) break;
|
||||
}
|
||||
}
|
||||
// fuck glass
|
||||
for ( int i=0; i<ut.glass.Size(); i++ )
|
||||
{
|
||||
ut.glass[i].Activate(self,0,SPAC_Impact);
|
||||
}
|
||||
let raging = RagekitPower(FindInventory("RagekitPower"));
|
||||
int maxang = raging?18:12;
|
||||
for ( int i=0; i<maxang; i++ )
|
||||
{
|
||||
if ( TryMelee(angle+i*(45./16),dmg) || TryMelee(angle-i*(45./16),dmg) )
|
||||
{
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( invoker.pfield ) invoker.pfield.bSHOOTABLE = true;
|
||||
// check for walls instead
|
||||
FTranslatedLineTarget t;
|
||||
double slope = AimLineAttack(angle,DEFMELEERANGE,t,0.,ALF_CHECK3D);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,23 @@ Class GrilledCheeseSandwich : Inventory
|
|||
Super.DoEffect();
|
||||
if ( Amount <= 0 ) DepleteOrDestroy();
|
||||
}
|
||||
override void AttachToOwner( Actor other )
|
||||
{
|
||||
Super.AttachToOwner(other);
|
||||
// find last armor or health item
|
||||
Inventory found = null;
|
||||
for ( Inventory i=other.Inv; i; i=i.Inv )
|
||||
{
|
||||
if ( !(i is 'SWWMHealth') && !(i is 'SWWMArmor') ) continue;
|
||||
found = i;
|
||||
}
|
||||
if ( !found ) return;
|
||||
// place ourselves right after it
|
||||
Inventory saved = found.Inv;
|
||||
found.Inv = self;
|
||||
other.Inv = Inv;
|
||||
Inv = saved;
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
|
|||
|
|
@ -647,7 +647,11 @@ Class SaltBeam : Actor
|
|||
t.ignore = target;
|
||||
t.Trace(pos,cursector,x,32,TRACE_HitSky);
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Actor.Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
|
|
@ -2014,7 +2018,11 @@ Class Spreadgun : SWWMWeapon
|
|||
action void ProcessTraceHit( SpreadgunTracer t, Vector3 origin, Vector3 dir, int dmg, double mm, Class<Actor> impact = "SpreadImpact", int bc = 1, bool large = false )
|
||||
{
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(self,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Spawn(large?"InvisibleSplasher":"SmolInvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
|
|
|
|||
|
|
@ -714,7 +714,11 @@ Class BiosparkBeam : Actor
|
|||
t.ShootThroughList.Clear();
|
||||
t.Trace(pos,CurSector,x,speed,TRACE_HitSky);
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.hitlist.Size(); i++ )
|
||||
{
|
||||
if ( t.hitlist[i].hitactor is 'BiosparkHitbox' )
|
||||
|
|
@ -1033,7 +1037,11 @@ Class BiosparkArc : Actor
|
|||
t.ShootThroughList.Clear();
|
||||
t.Trace(pos,CurSector,x,speed,TRACE_HitSky);
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.hitlist.Size(); i++ )
|
||||
{
|
||||
SWWMHandler.DoKnockback(t.hitlist[i].hitactor,-t.hitlist[i].x,GetMissileDamage(0,0)*1000);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,11 @@ Class CandyBeam : Actor
|
|||
t.ShootThroughList.Clear();
|
||||
t.Trace(pos,CurSector,x,dist,0);
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
if ( t.ShootThroughList[i].special == GlassBreak ) // fuck glass
|
||||
t.ShootThroughList[i].Activate(target,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<t.hitlist.Size(); i++ )
|
||||
{
|
||||
SWWMHandler.DoKnockback(t.hitlist[i].hitactor,t.hitlist[i].x,12000);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue