diff --git a/graphics/BDScreen.png b/graphics/BDScreen.png index cf8735711..c7ac80c23 100644 Binary files a/graphics/BDScreen.png and b/graphics/BDScreen.png differ diff --git a/graphics/HDScreen.png b/graphics/HDScreen.png new file mode 100644 index 000000000..6108b89f2 Binary files /dev/null and b/graphics/HDScreen.png differ diff --git a/language.def_base b/language.def_base index 0efd9431a..1a91909b6 100644 --- a/language.def_base +++ b/language.def_base @@ -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" diff --git a/language.def_voice b/language.def_voice index b3e63c39d..f37634668 100644 --- a/language.def_voice +++ b/language.def_voice @@ -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..."; diff --git a/language.es_base b/language.es_base index 30c4af45c..422c7448f 100644 --- a/language.es_base +++ b/language.es_base @@ -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" diff --git a/language.es_voice b/language.es_voice index ec83d0a4e..cf49016c6 100644 --- a/language.es_voice +++ b/language.es_voice @@ -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*"; diff --git a/sndinfo.txt b/sndinfo.txt index 802db92b3..f7b84cb58 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -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 diff --git a/sounds/DEARGODWHY.ogg b/sounds/DEARGODWHY.ogg deleted file mode 100644 index 89d4d4f0b..000000000 Binary files a/sounds/DEARGODWHY.ogg and /dev/null differ diff --git a/sounds/general/Gib1.ogg b/sounds/general/Gib1.ogg new file mode 100644 index 000000000..88ad8f043 Binary files /dev/null and b/sounds/general/Gib1.ogg differ diff --git a/sounds/general/Gib2.ogg b/sounds/general/Gib2.ogg new file mode 100644 index 000000000..92e1ad396 Binary files /dev/null and b/sounds/general/Gib2.ogg differ diff --git a/sounds/general/Gib3.ogg b/sounds/general/Gib3.ogg new file mode 100644 index 000000000..2b225e799 Binary files /dev/null and b/sounds/general/Gib3.ogg differ diff --git a/sounds/general/Gib4.ogg b/sounds/general/Gib4.ogg new file mode 100644 index 000000000..489b42b2c Binary files /dev/null and b/sounds/general/Gib4.ogg differ diff --git a/sounds/general/Gib5.ogg b/sounds/general/Gib5.ogg new file mode 100644 index 000000000..4e1626f59 Binary files /dev/null and b/sounds/general/Gib5.ogg differ diff --git a/sounds/voice/default/friendkill1.ogg b/sounds/voice/default/friendkill1.ogg new file mode 100644 index 000000000..023dd00d1 Binary files /dev/null and b/sounds/voice/default/friendkill1.ogg differ diff --git a/sounds/voice/default/friendkill2.ogg b/sounds/voice/default/friendkill2.ogg new file mode 100644 index 000000000..d89404530 Binary files /dev/null and b/sounds/voice/default/friendkill2.ogg differ diff --git a/sounds/voice/default/friendkill3.ogg b/sounds/voice/default/friendkill3.ogg new file mode 100644 index 000000000..8e53afdfc Binary files /dev/null and b/sounds/voice/default/friendkill3.ogg differ diff --git a/sounds/voice/default/friendkill4.ogg b/sounds/voice/default/friendkill4.ogg new file mode 100644 index 000000000..91df728b9 Binary files /dev/null and b/sounds/voice/default/friendkill4.ogg differ diff --git a/zmapinfo.txt b/zmapinfo.txt index bce72f7cc..a72690f5e 100644 --- a/zmapinfo.txt +++ b/zmapinfo.txt @@ -1,6 +1,6 @@ GameInfo { - AddEventHandlers = "SWWMFontPreloader", "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMVanillaBossHandler", "SWWMHandler" + AddEventHandlers = "SWWMFontPreloader", "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMHDoomHandler", "SWWMVanillaBossHandler", "SWWMHandler" PlayerClasses = "Demolitionist" StatusBarClass = "SWWMStatusBar" BackpackType = "HammerspaceEmbiggener" diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index 58ee617bf..f0ca88d90 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -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 valid; + valid.Clear(); + for ( int i=0; i lines; + lines.Clear(); + data.Split(lines,"\n"); + for ( int j=0; j 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 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 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); + } +} diff --git a/zscript/swwm_hud.zsc b/zscript/swwm_hud.zsc index 0c3a1fb2f..8b3b4242b 100644 --- a/zscript/swwm_hud.zsc +++ b/zscript/swwm_hud.zsc @@ -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); } } diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index 9f8fff1ce..4d3044319 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -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 uses; + Array 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 impact = "SpreadImpact", int bc = 1, bool large = false ) { for ( int i=0; i