// HORNY // Surprisingly, I've put in actual effort into this compatibility thing (even // if it's just sort of partial). // Demo-chan has no pp in this body that they can stick into the girls, so all // they get is the headpats. There's some sort of crazy magic going on here, // that makes the demon gals fall to their knees instantly. Saya thinks it // might be a side effect of teaching them the "blow kiss" spell (which has the // same effect). // Obviously, all the standard weapons work, and these gals appear to be of the // masochistic kind. This is generally not very effective compared to the pats // and smooches, but it's there, if you're willing to hurt them (I wouldn't). Class SWWMHDoomHandler : StaticEventHandler { ui int timer; ui TextureID scr; bool detected; override void OnRegister() { foreach ( cls:AllActorClasses ) { if ( cls.GetClassName() != "HDoomPlayer" ) continue; detected = true; break; } if ( !detected ) return; SetRandomSeed[hdscreen](Random[hdscreen]()+consoleplayer+MSTime()); Console.Printf( "\cx┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\c-\n" "\cx┃ \cfOh my, someone appears to be \cgH \ckO \cdR \cvN \chY \ct♥ \cx┃\c-\n" "\cx┃ \cfWell, all you'll be getting here is the power of headpats. \cx┃\c-\n" "\cx┃ \cfIf you want Demo-chan to actually fuck some hot demon girls, \cx┃\c-\n" "\cx┃ \cfjust go commission a porn artist or something, idk. \cx┃\c-\n" "\cx┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\c-"); S_StartSound("compat/warn",CHAN_YOUDONEFUCKEDUP,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); } override void WorldLoaded( WorldEvent e ) { // get rid of ourselves if not needed if ( !detected && !bDestroyed ) Destroy(); } static bool IsCuteGirl( Actor a ) { Class p = a.GetClass(); while ( p.GetParentClass() && (p.GetParentClass() != 'Actor') ) { p = p.GetParentClass(); if ( p.GetClassName() == 'HDoomMonster' ) return true; } return false; } static bool IsSexyTime( Actor a ) { Class p = a.GetClass(); while ( p.GetParentClass() && (p.GetParentClass() != 'Actor') ) { p = p.GetParentClass(); if ( p.GetClassName() == 'SexActor' ) return true; } return false; } static bool IsStaticSexyTime( Actor a ) { Class p = a.GetClass(); while ( p.GetParentClass() && (p.GetParentClass() != 'Actor') ) { p = p.GetParentClass(); if ( p.GetClassName() == 'StaticSexActor' ) return true; } return false; } override void WorldThingSpawned( WorldEvent e ) { // demo can't sex the ladies (not with this body) // spawn a headpat tracker, we can at least do this much for them if ( IsSexyTime(e.Thing) ) { e.Thing.bUSESPECIAL = false; let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos); hp.target = e.Thing; // sweet dreams, demon HeadpatTracker(hp).patstate = e.Thing.FindState("TooLate"); HeadpatTracker(hp).deathstate = e.Thing.FindState("Finish"); // height fixes String cname = e.Thing.GetClassName(); if ( cname.Left(12) ~== "Cacodemoness" ) HeadpatTracker(hp).hdoomheightfix = .2; else if ( cname.Left(12) ~== "ImpEncounter" ) HeadpatTracker(hp).hdoomheightfix = .35; else if ( cname.Left(8) ~== "Mancubus" ) HeadpatTracker(hp).hdoomheightfix = .1; else if ( cname.Left(9) ~== "HLostSoul" ) HeadpatTracker(hp).hdoomheightfix = .5; else if ( cname.Left(10) ~== "ArchViless" ) HeadpatTracker(hp).hdoomheightfix = -.1; } else if ( IsStaticSexyTime(e.Thing) ) { e.Thing.bUSESPECIAL = false; let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos); hp.target = e.Thing; if ( e.Thing.GetClassName() == 'ImpInAChair' ) { HeadpatTracker(hp).hdoomheightfix = .2; HeadpatTracker(hp).hdoomangfix = 15; } } else if ( IsCuteGirl(e.Thing) ) { let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos); hp.target = e.Thing; // sweet dreams, demon HeadpatTracker(hp).lethalpat = true; String cname = e.Thing.GetClassName(); // height fixes if ( cname.Left(12) ~== "ImpEncounter" ) HeadpatTracker(hp).hdoomheightfix = .1; else if ( cname.Left(8) ~== "Mancubus" ) HeadpatTracker(hp).hdoomheightfix = -.1; else if ( cname.Left(9) ~== "HLostSoul" ) HeadpatTracker(hp).hdoomheightfix = .5; else if ( cname.Left(10) ~== "ArchViless" ) HeadpatTracker(hp).hdoomheightfix = -.3; } } override void WorldThingRevived( WorldEvent e ) { // reattach pats WorldThingSpawned(e); } override void UiTick() { if ( !detected ) return; if ( gamestate == GS_LEVEL ) { if ( timer == 50 ) { S_StartSound("bestsound",CHAN_YOUDONEFUCKEDUP,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); S_StartSound("bestsound",CHAN_YOUDONEFUCKEDUP,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); } else if ( timer == 70 ) { int ngiggl = Random[hdscreen](1,14); S_StartSound(String.Format("saya/giggle%d",ngiggl),CHAN_YOUDONEFUCKEDUP,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); S_StartSound(String.Format("saya/giggle%d",ngiggl),CHAN_YOUDONEFUCKEDUP,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); } timer++; } else timer = 0; } override void RenderOverlay( RenderEvent e ) { if ( !detected || (timer < 50) || (timer > 150) ) return; if ( !scr ) scr = TexMan.CheckForTexture("graphics/hdscreen.png"); 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; } double alph = clamp(2.5-(timer+e.FracTic)/50.,0.,.25)*4.; 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,DTA_Alpha,alph); } }