Some work in progress here.

- Upstreamed GetClipAmount() from Doomreal, for inter-compatibility.
- Fix missing unique pickup messages for clips and single flak shell.
- Implement ice death support.
- Fix frictionless corpses sliding around.
- Add support for a Red Heretic key, should work with any custom maps that use it.
- Added anti-bd feature, thanks to Skerion for letting me use this hilarious video.
- Fixed missing drown sound for Female skins.
- Added missing Redeemer altfire sound.
- Fix damage scaling of Biorifle alt.
- Flak Cannon altfire has been adjusted so it fires faster and reloads slower, like in UT.
- Voodoo dolls can now produce liquid splashes.
- Pain and death sounds will always be overriden by drowning when underwater, like in UT.
- Add player portraits to each class for the settings menu.
This commit is contained in:
Marisa the Magician 2019-11-27 21:27:34 +01:00
commit 6b248cd843
226 changed files with 369 additions and 54 deletions

View file

@ -537,7 +537,7 @@ Class BioGel : Actor
invoker.deadtimer = -2;
if ( invoker.atline ) invoker.atline.RemoteActivate(target,invoker.atside,SPAC_Impact,pos);
UTMainHandler.DoBlast(self,Min(175,int(Scale.x*50)),20000*Scale.x);
A_Explode(int(20*Scale.x),Min(175,int(Scale.x*50)));
A_Explode(int(Args[0]*Scale.x),Min(175,int(Scale.x*50)));
A_PlaySound("ges/explode",CHAN_VOICE);
int numpt = Min(300,int(Scale.x*30))+Random[GES](-10,10);
for ( int i=0; i<numpt; i++ )
@ -564,6 +564,7 @@ Class BioGel : Actor
Obituary "$O_BIORIFLE";
DamageType 'Slime';
RenderStyle "Add";
Args 20;
Radius 3;
Height 3;
Scale 2;
@ -639,6 +640,11 @@ Class BioGlob : BioGel
{
int numsplash;
Default
{
Args 75;
}
void SpawnSplash()
{
Vector3 ofs = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
@ -685,6 +691,10 @@ Class BioRifle : UTWeapon
double charge;
bool bCharging;
override int, int, bool, bool GetClipAmount()
{
return bCharging?min(5,int(charge+0.1)):-1, -1, false, false;
}
action void A_BioFire( bool alt = false )
{
Weapon weap = Weapon(invoker);

View file

@ -47,6 +47,23 @@ Class UTHereticBlueKey : KeyBlue
}
}
// for heretic mods that add it
Class UTHereticRedKey : HereticKey
{
Default
{
Tag "$T_REDKEY";
Species "KeyRed";
Inventory.PickupMessage "$I_REDKEY";
}
States
{
Spawn:
UKEY A -1;
Stop;
}
}
// Base class for items that can be activated from the inventory bar
Class UTActivatable : Inventory
{

View file

@ -221,12 +221,20 @@ Class Enforcer : UTWeapon
{
int ClipCount, SlaveClipCount;
bool SlaveActive, SlaveDown, SlaveReload, SlaveAltFire;
bool ClipOut, SlaveClipOut;
int SlaveRefire;
double AltAccuracy;
property ClipCount : ClipCount;
property SlaveClipCount : SlaveClipCount;
override int, int, bool, bool GetClipAmount()
{
if ( !flak_enforcerreload ) return Super.GetClipAmount();
if ( Amount > 1 ) return ClipOut?-1:ClipCount, SlaveClipOut?-1:SlaveClipCount, (ClipCount<5), (SlaveClipCount<5);
return ClipOut?-1:ClipCount, -1, (ClipCount<5), false;
}
override bool HandlePickup( Inventory item )
{
if ( item.GetClass() == GetClass() )
@ -493,6 +501,7 @@ Class Enforcer : UTWeapon
Ready:
ENFS A 0
{
invoker.slaveclipout = invoker.clipout = false;
invoker.slavedown = false;
if ( !invoker.slaveactive && (CountInv("Enforcer") > 1) )
{
@ -607,6 +616,7 @@ Class Enforcer : UTWeapon
}
ENFR A 0
{
invoker.clipout = true;
invoker.clipcount = 0;
A_Overlay(-9999,null);
A_PlaySound("enforcer/click",CHAN_WEAPON);
@ -615,6 +625,7 @@ Class Enforcer : UTWeapon
ENR2 AB 1;
ENR2 B 30
{
invoker.clipout = false;
invoker.clipcount = min(invoker.default.clipcount,invoker.Ammo1.Amount);
A_PlaySound("enforcer/reload",CHAN_WEAPON);
if ( self is 'UTPlayer' )
@ -638,6 +649,7 @@ Class Enforcer : UTWeapon
invoker.slavereload = 0;
return ResolveState("LeftIdle");
}
invoker.slaveclipout = true;
invoker.slaveclipcount = 0;
A_Overlay(-9998,null);
A_PlaySound("enforcer/click",CHAN_6);
@ -647,6 +659,7 @@ Class Enforcer : UTWeapon
2NR2 AB 1;
2NR2 B 30
{
invoker.slaveclipout = false;
invoker.slaveclipcount = min(invoker.default.slaveclipcount,invoker.Ammo1.Amount);
A_PlaySound("enforcer/reload",CHAN_6);
if ( self is 'UTPlayer' )

View file

@ -12,6 +12,7 @@ Class FlakAmmo : Ammo
}
override String PickupMessage()
{
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
return String.Format("%s%d%s",StringTable.Localize("$I_FLAKAMMOL"),Amount,StringTable.Localize("$I_FLAKAMMOR"));
}
States
@ -782,6 +783,15 @@ Class FlakCannon : UTWeapon
if ( invoker.Ammo1.Amount > 0 ) A_Loading();
}
FLKL BCEFGIJKMNO 1;
Goto Idle;
AltLoading:
FLKL A 2
{
A_CheckReload();
if ( invoker.Ammo1.Amount > 0 ) A_Loading();
}
FLKL BCEFGIJKMNO 2;
Goto Idle;
Idle:
FLKI A 1 A_WeaponReady();
Wait;
@ -801,9 +811,9 @@ Class FlakCannon : UTWeapon
Goto Loading;
AltFire:
FLKA A 1 A_FireSlug();
FLKA BCDEFGHIJK 2;
FLKA BCDEFGHIJK 1;
FLKA K 4;
Goto Loading;
Goto AltLoading;
Select:
FLKS A 1 A_Raise(int.max);
Wait;

View file

@ -44,6 +44,10 @@ Class ImpactHammer : UTWeapon
{
double chargesize, count;
override int, int, bool, bool GetClipAmount()
{
return (chargesize>0)?min(10,int(chargesize/.15)):-1, -1, false, false;
}
action void A_ResetCharge()
{
invoker.chargesize = 0;

View file

@ -12,6 +12,7 @@ Class MiniAmmo : Ammo
}
override String PickupMessage()
{
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
return String.Format("%s%d%s",StringTable.Localize("$I_MINIAMMOL"),Amount,StringTable.Localize("$I_MINIAMMOR"));
}
States

View file

@ -559,12 +559,19 @@ Class PulseMag : UTCasing
Class PulseGun : UTWeapon
{
int clipcount;
bool ClipOut;
double sangle;
Actor beam;
transient ui Font usmf;
Property ClipCount : clipcount;
override int, int, bool, bool GetClipAmount()
{
if ( !flak_pulsereload ) return Super.GetClipAmount();
return ClipOut?-1:ClipCount, -1, (ClipCount<10), false;
}
action void A_DrainAmmo()
{
Weapon weap = Weapon(invoker);
@ -737,6 +744,10 @@ Class PulseGun : UTWeapon
PGNP B -1;
Stop;
Ready:
PGNS A 0
{
invoker.clipout = false;
}
PGNS ABCDEFGHIJKLMNOPQRSTUVW 1 A_WeaponReady(WRF_NOFIRE);
Idle:
PGNI A 1
@ -800,6 +811,7 @@ Class PulseGun : UTWeapon
PGNR BCDEFGHIJKLMNO 1;
PGNR P 1
{
invoker.clipout = true;
invoker.clipcount = 0;
}
PGNR QRSTUVWXYZ 1;
@ -816,6 +828,7 @@ Class PulseGun : UTWeapon
PGR2 BCD 1;
PGR2 E 1
{
invoker.clipout = false;
invoker.clipcount = Min(invoker.default.clipcount,invoker.Ammo1.Amount);
}
PGR2 FGHIJKLMNOPQRSTUVWX 1;

View file

@ -360,6 +360,12 @@ Class Translocator : UTWeapon
Actor module;
double ammocharge;
override int, int, bool, bool GetClipAmount()
{
if ( !flak_transloc2k4 ) return Super.GetClipAmount();
return (ammocharge>0)?int(ammocharge*9.9):-1, -1, false, false;
}
override void Tick()
{
Super.Tick();

View file

@ -240,16 +240,28 @@ Class UTPlayer : DoomPlayer
Super.Tick();
if ( InStateSequence(CurState,FindState("See",true)) )
SetStateLabel("See2");
if ( !player || (player.mo != self) ) return;
if ( flak_utmovement )
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
PlaySplash(1.);
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
PlaySurface();
if ( (waterlevel >= 3) && !underwatersnd )
{
bNOFRICTION = true;
bNOFRICTIONBOUNCE = true;
underwatersnd = Spawn("UTUnderSound",pos);
underwatersnd.target = self;
}
else
else if ( (waterlevel < 3) && underwatersnd )
underwatersnd.Destroy();
lastwaterlevel = waterlevel;
if ( !flak_utmovement || !player || (player.mo != self) || (player.cheats&(CF_FROZEN|CF_TOTALLYFROZEN)) )
{
bNOFRICTION = false;
bNOFRICTIONBOUNCE = false;
return;
}
else
{
bNOFRICTION = true;
bNOFRICTIONBOUNCE = true;
}
if ( !footsteps ) footsteps = CVar.GetCVar('flak_footsteps',players[consoleplayer]);
if ( !footsteps.GetBool() || (Health <= 0) ) return;
@ -279,21 +291,9 @@ Class UTPlayer : DoomPlayer
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) PlayWetFootstep(vol);
else PlayFootstep(vol);
}
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
PlaySplash(1.);
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
PlaySurface();
if ( (waterlevel >= 3) && !underwatersnd )
{
underwatersnd = Spawn("UTUnderSound",pos);
underwatersnd.target = self;
}
else if ( (waterlevel < 3) && underwatersnd )
underwatersnd.Destroy();
lastground = player.onground;
lastvelz = prevvelz;
prevvelz = vel.z;
lastwaterlevel = waterlevel;
}
double FrictionToUnreal()
@ -698,7 +698,8 @@ Class UTPlayer : DoomPlayer
override void DeathThink()
{
Super.DeathThink();
if ( !flak_utmovement || !player || (player.mo != self) || (player.cheats&(CF_FROZEN|CF_TOTALLYFROZEN)) ) return;
if ( !flak_utmovement || !player || (player.mo != self) || (player.cheats&(CF_FROZEN|CF_TOTALLYFROZEN)) )
return;
// unreal physics while dead
double friction = FrictionToUnreal();
if ( !bNoGravity && player.onground && (waterlevel < 3) )
@ -1027,6 +1028,60 @@ Class UTPlayer : DoomPlayer
return Super.GetDeathHeight();
}
// mostly a copy of A_FreezeDeathChunks but with some DT specific gib
// behaviour
void A_FreezeDeathChunksDT()
{
if ( (vel != (0,0,0)) && !bShattering )
{
tics = 3*TICRATE;
return;
}
vel = (0,0,0);
A_PlaySound ("misc/icebreak",CHAN_BODY);
// [RH] In Hexen, this creates a random number of shards (range [24,56])
// with no relation to the size of the self shattering. I think it should
// base the number of shards on the size of the dead thing, so bigger
// things break up into more shards than smaller things.
// An actor with radius 20 and height 64 creates ~40 chunks.
int numChunks = max(4,int(radius*Height)/32);
int i = Random[FreezeDeathChunks](0,numChunks/4-1);
for ( i=max(24,numChunks+i); i>=0; i-- )
{
double xo = (random[FreezeDeathChunks]()-128)*radius/128;
double yo = (random[FreezeDeathChunks]()-128)*radius/128;
double zo = (random[FreezeDeathChunks]()*Height/255);
Actor mo = Spawn("IceChunk",Vec3Offset(xo,yo,zo),ALLOW_REPLACE);
if ( !mo ) continue;
mo.SetState(mo.SpawnState+random[FreezeDeathChunks](0,2));
mo.Vel.X = random2[FreezeDeathChunks]()/128.;
mo.Vel.Y = random2[FreezeDeathChunks]()/128.;
mo.Vel.Z = (mo.pos.Z-pos.Z)/Height*4;
}
// Gib the player, the camera will attach to the head at this point
A_GibMe();
A_NoBlocking();
SetStateLabel('null');
}
void A_PainDT()
{
if ( waterlevel > 2 ) A_PlaySound("*death-drowning",CHAN_VOICE);
else A_Pain();
}
void A_PlayerScreamDT()
{
if ( waterlevel > 2 ) A_PlaySound("*death-drowning",CHAN_VOICE);
else A_PlayerScream();
}
void A_XScreamDT()
{
if ( waterlevel > 2 ) A_PlaySound("*death-drowning",CHAN_VOICE);
else A_XScream();
}
States
{
Spawn:
@ -1108,21 +1163,21 @@ Class UTPlayer : DoomPlayer
Pain:
#### # 0 A_Jump(256,1,3,5,7);
#### # 2;
PLAY W 3 A_Pain();
PLAY W 3 A_PainDT();
Goto Spawn;
#### # 2;
PLAY Y 3 A_Pain();
PLAY Y 3 A_PainDT();
Goto Spawn;
#### # 2;
PLAY Z 3 A_Pain();
PLAY Z 3 A_PainDT();
Goto Spawn;
Pain.Decapitated:
#### # 2;
PLAY X 3 A_Pain();
PLAY X 3 A_PainDT();
Goto Spawn;
Death.Decapitated:
#### # 0 A_HeadPop();
PLD4 A 3 A_PlayerScream();
PLD4 A 3 A_PlayerScreamDT();
PLD4 B 3 A_NoBlocking();
PLD4 CDEFGHIJKLMNO 3;
PLD4 P 1 A_DMFade();
@ -1133,14 +1188,14 @@ Class UTPlayer : DoomPlayer
#### # 0 A_Jump(256,"Death2","Death3","Death7","Death8");
Death11:
#### # 3;
PD11 A 3 A_PlayerScream();
PD11 A 3 A_PlayerScreamDT();
PD11 B 3 A_NoBlocking();
PD11 CDEFGHIJKLMNOPQ 3;
PD11 R 1 A_DMFade();
Wait;
Death.Zapped:
#### # 3;
PLD9 A 3 A_PlayerScream();
PLD9 A 3 A_PlayerScreamDT();
PLD9 B 3 A_NoBlocking();
PLD9 CDEFGHIJKLMNOPQRST 2;
PD9B A 2 A_SetSize(-1,height*0.25); // reduce now
@ -1149,35 +1204,35 @@ Class UTPlayer : DoomPlayer
Wait;
Death8:
#### # 3;
PLD8 A 3 A_PlayerScream();
PLD8 A 3 A_PlayerScreamDT();
PLD8 B 3 A_NoBlocking();
PLD8 CDEFGHIJKLMNOPQ 3;
PLD8 R 1 A_DMFade();
Wait;
Death7:
#### # 3;
PLD7 A 3 A_PlayerScream();
PLD7 A 3 A_PlayerScreamDT();
PLD7 B 3 A_NoBlocking();
PLD7 CDEFGHIJKLMNOPQRST 3;
PLD7 U 1 A_DMFade();
Wait;
Death3:
#### # 3;
PLD3 A 3 A_PlayerScream();
PLD3 A 3 A_PlayerScreamDT();
PLD3 B 3 A_NoBlocking();
PLD3 CDEFGHIJKL 3;
PLD3 M 1 A_DMFade();
Wait;
Death2:
#### # 3;
PLD2 A 3 A_PlayerScream();
PLD2 A 3 A_PlayerScreamDT();
PLD2 B 3 A_NoBlocking();
PLD2 CDEFGHIJKLMNO 3;
PLD2 P 1 A_DMFade();
Wait;
Death1:
#### # 3;
PLD1 A 3 A_PlayerScream();
PLD1 A 3 A_PlayerScreamDT();
PLD1 B 3 A_NoBlocking();
PLD1 CDEFGHIJKL 3;
PLD1 M 1 A_DMFade();
@ -1185,7 +1240,7 @@ Class UTPlayer : DoomPlayer
XDeath:
TNT1 A 350
{
A_XScream();
A_XScreamDT();
A_NoBlocking();
A_GibMe();
}
@ -1209,6 +1264,10 @@ Class UTPlayer : DoomPlayer
#### # 5;
PLT4 ABCDEFGHIJKLMNO 3;
Goto Spawn;
Ice:
PICE A 5 A_FreezeDeath();
PICE A 1 A_FreezeDeathChunksDT();
Wait;
}
}
@ -1255,13 +1314,13 @@ Class UTUnderSound : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
SetOrigin(target.pos,true);
curfluid = lastfluid = GetFluid();
fluidsounds[0] = 'ut/underwater';
fluidsounds[1] = 'ut/underslime';
fluidsounds[2] = 'ut/underlava';
fluidsounds[3] = 'ut/undernitro';
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,100.);
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,0.);
A_SoundVolume(CHAN_VOICE,(players[consoleplayer].camera==target)?1.:0.);
}
override void OnDestroy()
@ -1272,15 +1331,15 @@ Class UTUnderSound : Actor
override void Tick()
{
Super.Tick();
if ( !target || !target.player || (target.waterlevel < 3) )
if ( !target || (target.waterlevel < 3) )
{
Destroy();
return;
}
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
SetOrigin(target.pos,true);
curfluid = GetFluid();
if ( curfluid != lastfluid )
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,100.);
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,0.);
lastfluid = curfluid;
A_SoundVolume(CHAN_VOICE,(players[consoleplayer].camera==target)?1.:0.);
}
@ -1499,6 +1558,12 @@ Class UTPlayerTMale1 : UTPlayer
UTPlayer.VoiceType VOICE_MaleOne;
-NOMENU;
}
States
{
See:
TMAL A -1;
Stop;
}
}
Class UTPlayerTMale2 : UTPlayer
{
@ -1510,6 +1575,12 @@ Class UTPlayerTMale2 : UTPlayer
UTPlayer.VoiceType VOICE_MaleTwo;
-NOMENU;
}
States
{
See:
TMAL B -1;
Stop;
}
}
Class UTPlayerTFemale : UTPlayer
{
@ -1545,14 +1616,14 @@ Class UTPlayerTFemale : UTPlayer
Goto Spawn;
Death.Decapitated:
#### # 0 A_HeadPop();
PLD6 A 3 A_PlayerScream();
PLD6 A 3 A_PlayerScreamDT();
PLD6 B 3 A_NoBlocking();
PLD6 CDEFGHIJ 3;
PLD6 K 1 A_DMFade();
Wait;
Death.Zapped:
#### # 3;
PLD9 A 3 A_PlayerScream();
PLD9 A 3 A_PlayerScreamDT();
PLD9 B 3 A_NoBlocking();
PLD9 CDEFGHIJKLMNOPQRST 2;
PD9B A 2 A_SetSize(-1,height*0.25); // reduce now
@ -1565,42 +1636,42 @@ Class UTPlayerTFemale : UTPlayer
#### # 0 A_Jump(256,"Death1","Death3","Death4","Death7");
Death7:
#### # 3;
PLD7 A 3 A_PlayerScream();
PLD7 A 3 A_PlayerScreamDT();
PLD7 B 3 A_NoBlocking();
PLD7 CDEFGHIJ 3;
PLD7 K 1 A_DMFade();
Wait;
Death5:
#### # 0 A_LegPop();
PLD5 A 3 A_PlayerScream();
PLD5 A 3 A_PlayerScreamDT();
PLD5 B 3 A_NoBlocking();
PLD5 CDEFGHIJKL 3;
PLD5 M 1 A_DMFade();
Wait;
Death4:
#### # 3;
PLD4 A 3 A_PlayerScream();
PLD4 A 3 A_PlayerScreamDT();
PLD4 B 3 A_NoBlocking();
PLD4 CDEFGHIJKL 3;
PLD4 M 1 A_DMFade();
Wait;
Death3:
#### # 3;
PLD3 A 3 A_PlayerScream();
PLD3 A 3 A_PlayerScreamDT();
PLD3 B 3 A_NoBlocking();
PLD3 CDEFGHIJKLMNO 3;
PLD3 P 1 A_DMFade();
Wait;
Death2:
#### # 3;
PLD2 A 3 A_PlayerScream();
PLD2 A 3 A_PlayerScreamDT();
PLD2 B 3 A_NoBlocking();
PLD2 CDEFGHIJKLMNOPQ 3;
PLD2 R 1 A_DMFade();
Wait;
Death1:
#### # 3;
PLD1 A 3 A_PlayerScream();
PLD1 A 3 A_PlayerScreamDT();
PLD1 B 3 A_NoBlocking();
PLD1 CDEFGHIJKLMNOPQRSTUV 3;
PLD1 W 1 A_DMFade();
@ -1617,6 +1688,12 @@ Class UTPlayerTFemale1 : UTPlayerTFemale
UTPlayer.VoiceType VOICE_FemaleOne;
-NOMENU;
}
States
{
See:
TFEM A -1;
Stop;
}
}
Class UTPlayerTFemale2 : UTPlayerTFemale
{
@ -1628,6 +1705,12 @@ Class UTPlayerTFemale2 : UTPlayerTFemale
UTPlayer.VoiceType VOICE_FemaleTwo;
-NOMENU;
}
States
{
See:
TFEM B -1;
Stop;
}
}
Class UTPlayerTBoss : UTPlayer
{
@ -1649,6 +1732,12 @@ Class UTPlayerTBoss : UTPlayer
if ( bossfootsteps.GetBool() ) A_PlaySound("ut/bossfootstep",CHAN_5,vol);
else Super.PlayFootstep(vol);
}
States
{
See:
TBOS A -1;
Stop;
}
}
Class UTWeapon : Weapon
@ -1814,6 +1903,12 @@ Class UTWeapon : Weapon
return rslt;
}
// For clips
virtual clearscope int, int, bool, bool GetClipAmount() const
{
return -1, -1, false, false;
}
Default
{
Weapon.BobStyle "Smooth";
@ -2367,6 +2462,7 @@ Class ShredCorpseHitbox : Actor
}
accdamage = target.Health;
A_SetSize(target.radius,target.height);
if ( target.bIceCorpse ) bNOBLOOD = true; // ice statue
}
override void Tick()
{
@ -2408,6 +2504,15 @@ Class ShredCorpseHitbox : Actor
int gibhealth = (target.GibHealth==int.min)?-target.SpawnHealth():target.GibHealth;
if ( accdamage < gibhealth )
{
// force chunks if frozen
if ( target.bIceCorpse )
{
target.bSHATTERING = true;
if ( target is 'UTPlayer' ) UTPlayer(target).A_FreezeDeathChunksDT();
else target.A_FreezeDeathChunks();
Destroy();
return 0;
}
// force gib (cheap ATM)
State gib = target.FindState("XDeath",true);
if ( !gib ) gib = target.FindState("Death.Extreme",true);
@ -2839,6 +2944,10 @@ Class UTStaticHandler : StaticEventHandler
Class UTMainHandler : EventHandler
{
Array<QueuedFlash> flashes;
TextureID gframes[166];
transient ui int gframe;
transient ui Font rfont;
bool isbd, ispb;
override void CheckReplacement( ReplaceEvent e )
{
@ -2980,6 +3089,13 @@ Class UTMainHandler : EventHandler
else if ( e.Replacee == 'KeyYellow' ) e.Replacement = 'UTHereticYellowKey';
else if ( e.Replacee == 'KeyGreen' ) e.Replacement = 'UTHereticGreenKey';
else if ( e.Replacee == 'KeyBlue' ) e.Replacement = 'UTHereticBlueKey';
else if ( e.Replacee.GetClassName() == 'KeyRed' )
{
// pretty sure that is a standardized name, so it should work for any heretic mod that adds it
e.Replacement = 'UTHereticRedKey';
}
// TODO Hexen replacements
// TODO Strife replacements
}
private Actor AddLight( Vector3 pos, Color col, int radius )
@ -3003,6 +3119,19 @@ Class UTMainHandler : EventHandler
override void WorldLoaded( WorldEvent e )
{
isbd = ispb = false;
for ( int i=0; i<AllActorClasses.size(); i++ )
{
if ( AllActorClasses[i].GetClassName() == "BrutalWeapon" )
isbd = true;
else if ( AllActorClasses[i].GetClassName() == "BrutalDoomer" )
ispb = true;
}
if ( isbd || ispb )
{
for ( int i=0; i<166; i++ )
gframes[i] = TexMan.CheckForTexture(String.Format("graphics/grunt/B_%03d.jpg",i+1),TexMan.Type_Any);
}
// just replace the -noflat- with a better scaled version and change the sky
if ( !flak_doomtest )
{
@ -3405,4 +3534,61 @@ Class UTMainHandler : EventHandler
s.str = initial;
s.tstr = initial;
}
override void UiTick()
{
if ( !ispb && !isbd ) return;
if ( !(gametic%2) )
{
if ( !(gframe%11) && gframe < 160 )
{
S_Sound("ut/malejump",CHAN_VOICE|CHAN_UI,(gframe>100)?.5:1.);
S_Sound("ut/malejump",CHAN_WEAPON|CHAN_UI,(gframe>100)?.5:1.);
}
if ( ((gframe >= 37) && (gframe < 49) && !((gframe-37)%3))
|| ((gframe >= 89) && (gframe < 101) && !((gframe-89)%3))
|| ((gframe >= 141) && (gframe < 153) && !((gframe-141)%3)) )
{
S_Sound("ut/land",CHAN_BODY|CHAN_UI,(gframe>100)?.5:1.);
S_Sound("ut/land",CHAN_ITEM|CHAN_UI,(gframe>100)?.5:1.);
}
gframe++;
}
if ( gframe >= 166 ) gframe = 0;
}
// almost forgot about this
override void RenderUnderlay( RenderEvent e )
{
if ( !ispb && !isbd ) return;
double ar = Screen.GetAspectRatio();
Vector2 tsize = TexMan.GetScaledSize(gframes[gframe]);
double sar = tsize.x/tsize.y;
Vector2 vsize;
if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
else vsize = tsize;
Screen.DrawTexture(gframes[gframe],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add);
String txtme = "STOP LOADING BRUTAL DOOM WITH EVERYTHING";
if ( !rfont ) rfont = Font.GetFont('USmallFont');
Vector2 bcoord = ((CleanWidth-rfont.StringWidth(txtme))*.5,CleanHeight*0.8);
for ( int i=0; i<txtme.Length(); i++ )
{
String chr = txtme.Mid(i,1);
for ( int j=0; j<8; j++ )
{
Vector2 ccoord = bcoord + (cos((gametic+e.fractic+i-j)*8.),sin((gametic+e.fractic+i-j)*8.))*CleanXFac*3;
Screen.DrawText(rfont,Font.CR_DARKRED,ccoord.x,ccoord.y,chr,DTA_VirtualWidth,CleanWidth,DTA_VirtualHeight,CleanHeight,DTA_KeepRatio,true,DTA_Alpha,(8-j)/8.);
}
bcoord.x += rfont.StringWidth(chr);
}
bcoord = ((CleanWidth-rfont.StringWidth(txtme))*.5,CleanHeight*0.8);
for ( int i=0; i<txtme.Length(); i++ )
{
String chr = txtme.Mid(i,1);
Vector2 ccoord = bcoord + (cos((gametic+e.fractic+i)*8.),sin((gametic+e.fractic+i)*8.))*CleanXFac*3;
Screen.DrawText(rfont,Font.CR_FIRE,ccoord.x,ccoord.y,chr,DTA_VirtualWidth,CleanWidth,DTA_VirtualHeight,CleanHeight,DTA_KeepRatio,true);
bcoord.x += rfont.StringWidth(chr);
}
}
}

View file

@ -352,6 +352,7 @@ Class GuidedWarShell : WarShell
{
Super.PostBeginPlay();
if ( target && target.player ) target.player.camera = self;
A_PlaySound("warhead/altfire",CHAN_WEAPON,local:true);
justleft = true;
}
override void Tick()
@ -721,7 +722,7 @@ Class WarheadLauncher : UTWeapon
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
A_PlaySound("warhead/fire",CHAN_WEAPON);
A_PlaySound("warhead/altfire",CHAN_WEAPON);
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(128,255,128,128),1);
A_AlertMonsters();