1.1 release:

- Hexen compatibility (Combiner Patch will be updated soon).
 - Environment Map shader fixes from Doom Tournament.
 - Buffed Stunner so it's actually useful. This goes against what the Unreal
   Bible indicated but whatever, the weapon would be useless otherwise.
 - "Superweapons" now have +ALWAYSPICKUP for consistency.
 - Sneaky Strife stuff:
   - Dispersion Pistol and Stunner have reduced alert radius.
   - Rename Peacemaker sprites to avoid conflict with peasant sprites.
This commit is contained in:
Marisa the Magician 2019-12-15 14:39:11 +01:00
commit 1207748311
16 changed files with 339 additions and 281 deletions

View file

@ -73,14 +73,14 @@ This mod requires GZDoom 4.2.4 or later, and runs on top of Doom Tournament.
## In progress ## In progress
- Tooltips for options. - N/A, this is the 1.1 release.
- Extension to the Translator so it can show item descriptions and whatnot
when picking them up. Give it some usability for normal gameplay. Could
eventually extend this further to make it more like Serious Sam's NETRICSA.
## Planned ## Planned
- Shifted to a 1.1 update: - Shifted to a 1.2 update:
- Extension to the Translator so it can show item descriptions and whatnot
when picking them up. Give it some usability for normal gameplay. Could
eventually extend it further to make it more like Serious Sam's NETRICSA.
- Impaler "slice" animation for melee alt. - Impaler "slice" animation for melee alt.
- Alternate flamethrower secondary that behaves more like the Unreal Bible - Alternate flamethrower secondary that behaves more like the Unreal Bible
describes (unlit blobs at a rate of 4 per second that catch on fire with describes (unlit blobs at a rate of 4 per second that catch on fire with

BIN
graphics/icons/ItemABox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -8,7 +8,7 @@ Model "Peacerocket"
USEACTORPITCH USEACTORPITCH
USEACTORROLL USEACTORROLL
FrameIndex PEAR A 0 0 FrameIndex PEMR A 0 0
} }
Model "PeaceFragment" Model "PeaceFragment"
@ -40,40 +40,40 @@ Model "Peacebarrel"
USEACTORROLL USEACTORROLL
// unfold // unfold
FrameIndex PEAM A 0 0 FrameIndex PEMM A 0 0
FrameIndex PEAM B 0 1 FrameIndex PEMM B 0 1
FrameIndex PEAM C 0 2 FrameIndex PEMM C 0 2
FrameIndex PEAM D 0 3 FrameIndex PEMM D 0 3
FrameIndex PEAM E 0 4 FrameIndex PEMM E 0 4
FrameIndex PEAM F 0 5 FrameIndex PEMM F 0 5
FrameIndex PEAM G 0 6 FrameIndex PEMM G 0 6
FrameIndex PEAM H 0 7 FrameIndex PEMM H 0 7
FrameIndex PEAM I 0 8 FrameIndex PEMM I 0 8
FrameIndex PEAM J 0 9 FrameIndex PEMM J 0 9
FrameIndex PEAM K 0 10 FrameIndex PEMM K 0 10
FrameIndex PEAM L 0 11 FrameIndex PEMM L 0 11
FrameIndex PEAM M 0 12 FrameIndex PEMM M 0 12
FrameIndex PEAM N 0 13 FrameIndex PEMM N 0 13
FrameIndex PEAM O 0 14 FrameIndex PEMM O 0 14
FrameIndex PEAM P 0 15 FrameIndex PEMM P 0 15
FrameIndex PEAM Q 0 16 FrameIndex PEMM Q 0 16
FrameIndex PEAM R 0 17 FrameIndex PEMM R 0 17
FrameIndex PEAM S 0 18 FrameIndex PEMM S 0 18
FrameIndex PEAM T 0 19 FrameIndex PEMM T 0 19
FrameIndex PEAM U 0 20 FrameIndex PEMM U 0 20
FrameIndex PEAM V 0 21 FrameIndex PEMM V 0 21
FrameIndex PEAM W 0 22 FrameIndex PEMM W 0 22
FrameIndex PEAM X 0 23 FrameIndex PEMM X 0 23
FrameIndex PEAM Y 0 24 FrameIndex PEMM Y 0 24
FrameIndex PEAM Z 0 25 FrameIndex PEMM Z 0 25
FrameIndex PEAM [ 0 26 FrameIndex PEMM [ 0 26
FrameIndex PEAM \ 0 27 FrameIndex PEMM \ 0 27
FrameIndex PEAM ] 0 28 FrameIndex PEMM ] 0 28
// launch // launch
FrameIndex PEAL A 0 29 FrameIndex PEML A 0 29
FrameIndex PEAL B 0 30 FrameIndex PEML B 0 30
FrameIndex PEAL C 0 31 FrameIndex PEML C 0 31
FrameIndex PEAL D 0 32 FrameIndex PEML D 0 32
} }
Model "Peacemaker" Model "Peacemaker"
@ -85,11 +85,11 @@ Model "Peacemaker"
ZOffset 5 ZOffset 5
Scale 0.16 -0.16 0.16 Scale 0.16 -0.16 0.16
FrameIndex PEAP B 1 0 FrameIndex PEMP B 1 0
ZOffset 9 ZOffset 9
ROTATING ROTATING
FrameIndex PEAP A 1 0 FrameIndex PEMP A 1 0
} }
Model "Peacemaker" Model "Peacemaker"
@ -102,57 +102,57 @@ Model "Peacemaker"
Offset 7.5 -15 -7.5 Offset 7.5 -15 -7.5
// Select // Select
FrameIndex PEAS A 0 0 FrameIndex PEMS A 0 0
FrameIndex PEAS B 0 1 FrameIndex PEMS B 0 1
FrameIndex PEAS C 0 2 FrameIndex PEMS C 0 2
FrameIndex PEAS D 0 3 FrameIndex PEMS D 0 3
FrameIndex PEAS E 0 4 FrameIndex PEMS E 0 4
FrameIndex PEAS F 0 5 FrameIndex PEMS F 0 5
FrameIndex PEAS G 0 6 FrameIndex PEMS G 0 6
FrameIndex PEAS H 0 7 FrameIndex PEMS H 0 7
FrameIndex PEAS I 0 8 FrameIndex PEMS I 0 8
FrameIndex PEAS J 0 9 FrameIndex PEMS J 0 9
FrameIndex PEAS K 0 10 FrameIndex PEMS K 0 10
FrameIndex PEAS L 0 11 FrameIndex PEMS L 0 11
FrameIndex PEAS M 0 12 FrameIndex PEMS M 0 12
FrameIndex PEAS N 0 13 FrameIndex PEMS N 0 13
FrameIndex PEAS O 0 14 FrameIndex PEMS O 0 14
FrameIndex PEAS P 0 15 FrameIndex PEMS P 0 15
FrameIndex PEAS Q 0 16 FrameIndex PEMS Q 0 16
FrameIndex PEAS R 0 17 FrameIndex PEMS R 0 17
FrameIndex PEAS S 0 18 FrameIndex PEMS S 0 18
FrameIndex PEAS T 0 19 FrameIndex PEMS T 0 19
// Idle // Idle
FrameIndex PEAI A 0 20 FrameIndex PEMI A 0 20
// Down // Down
FrameIndex PEAD A 0 22 FrameIndex PEMD A 0 22
FrameIndex PEAD B 0 23 FrameIndex PEMD B 0 23
FrameIndex PEAD C 0 24 FrameIndex PEMD C 0 24
FrameIndex PEAD D 0 25 FrameIndex PEMD D 0 25
FrameIndex PEAD E 0 26 FrameIndex PEMD E 0 26
FrameIndex PEAD F 0 27 FrameIndex PEMD F 0 27
FrameIndex PEAD G 0 28 FrameIndex PEMD G 0 28
FrameIndex PEAD H 0 29 FrameIndex PEMD H 0 29
FrameIndex PEAD I 0 30 FrameIndex PEMD I 0 30
// Throw // Throw
FrameIndex PEAF A 0 32 FrameIndex PEMF A 0 32
FrameIndex PEAF B 0 33 FrameIndex PEMF B 0 33
FrameIndex PEAF C 0 34 FrameIndex PEMF C 0 34
FrameIndex PEAF D 0 35 FrameIndex PEMF D 0 35
FrameIndex PEAF E 0 36 FrameIndex PEMF E 0 36
FrameIndex PEAF F 0 37 FrameIndex PEMF F 0 37
FrameIndex PEAF G 0 38 FrameIndex PEMF G 0 38
FrameIndex PEAF H 0 39 FrameIndex PEMF H 0 39
FrameIndex PEAF I 0 40 FrameIndex PEMF I 0 40
// Count (0-9) // Count (0-9)
FrameIndex PEAC A 0 43 FrameIndex PEMC A 0 43
FrameIndex PEAC B 0 44 FrameIndex PEMC B 0 44
FrameIndex PEAC C 0 45 FrameIndex PEMC C 0 45
FrameIndex PEAC D 0 46 FrameIndex PEMC D 0 46
FrameIndex PEAC E 0 47 FrameIndex PEMC E 0 47
FrameIndex PEAC F 0 48 FrameIndex PEMC F 0 48
FrameIndex PEAC G 0 49 FrameIndex PEMC G 0 49
FrameIndex PEAC H 0 50 FrameIndex PEMC H 0 50
FrameIndex PEAC I 0 51 FrameIndex PEMC I 0 51
FrameIndex PEAC J 0 52 FrameIndex PEMC J 0 52
} }

View file

@ -5,5 +5,5 @@ vec4 ProcessTexel()
float mask = texture(masktex,vTexCoord.st).x; float mask = texture(masktex,vTexCoord.st).x;
vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.xyz); vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.xyz);
vec3 norm = reflect(eyedir,normalize(vWorldNormal.xyz)); vec3 norm = reflect(eyedir,normalize(vWorldNormal.xyz));
return vec4(base.rgb+texture(envtex,norm.xz*0.5).rgb*mask,base.a); return vec4(base.rgb+texture(envtex,norm.xz*0.5+0.5).rgb*mask,base.a);
} }

View file

@ -13,5 +13,5 @@ vec4 ProcessTexel()
float mask = texture(masktex,vTexCoord.st).x; float mask = texture(masktex,vTexCoord.st).x;
vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.xyz); vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.xyz);
vec3 norm = reflect(eyedir,normalize(vWorldNormal.xyz)); vec3 norm = reflect(eyedir,normalize(vWorldNormal.xyz));
return vec4(base.rgb+texture(envtex,norm.xz*0.5).rgb*mask,base.a); return vec4(base.rgb+texture(envtex,norm.xz*0.5+0.5).rgb*mask,base.a);
} }

View file

@ -1,4 +1,4 @@
Sprite "PEAPA0",1,1{} Sprite "PEMPA0",1,1{}
Sprite "PEASA0",1,1{} Sprite "PEMSA0",1,1{}
Sprite "PEAMA0",1,1{} Sprite "PEMMA0",1,1{}
Sprite "PEARA0",1,1{} Sprite "PEMRA0",1,1{}

View file

@ -536,7 +536,7 @@ Class Automag : UnrealWeapon
{ {
invoker.clipout = true; invoker.clipout = true;
A_Overlay(-9999,null); A_Overlay(-9999,null);
A_PlaySound("automag/click",CHAN_WEAPON,!Dampener.Active(self)?1.:.1); A_PlaySound("automag/click",CHAN_ITEM,!Dampener.Active(self)?1.:.1);
} }
AUTR ABCDEFGHIJKLMNOPQRSTUVWXY 1; AUTR ABCDEFGHIJKLMNOPQRSTUVWXY 1;
AUTD ABCD 1; AUTD ABCD 1;

View file

@ -432,6 +432,7 @@ Class BigGun : UnrealWeapon
Weapon.AmmoGive 4; Weapon.AmmoGive 4;
Inventory.RespawnTics 2100; Inventory.RespawnTics 2100;
+INVENTORY.IGNORESKILL; +INVENTORY.IGNORESKILL;
+INVENTORY.ALWAYSPICKUP;
UTWeapon.DropAmmo 4; UTWeapon.DropAmmo 4;
BigGun.ClipCount 4; BigGun.ClipCount 4;
+EXTREMEDEATH; +EXTREMEDEATH;

View file

@ -323,7 +323,7 @@ Class DispersionAmmo : Actor
action void A_DispExpl() action void A_DispExpl()
{ {
UTMainHandler.DoKnockback(tracer,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)),6000); UTMainHandler.DoKnockback(tracer,(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)),6000);
A_AlertMonsters(); A_AlertMonsters(gameinfo.gametype&GAME_Strife?100:0);
A_SprayDecal("RazorBlast",20); A_SprayDecal("RazorBlast",20);
Spawn(invoker.LightClass,pos); Spawn(invoker.LightClass,pos);
Actor a; Actor a;
@ -344,6 +344,12 @@ Class DispersionAmmo : Actor
UTMainHandler.DoBlast(self,80,6000); UTMainHandler.DoBlast(self,80,6000);
A_Explode(GetMissileDamage(0,0),80); A_Explode(GetMissileDamage(0,0),80);
} }
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{
if ( gameinfo.gametype&GAME_Strife )
target.DaggerAlert(self.target);
return damage;
}
override void PostBeginPlay() override void PostBeginPlay()
{ {
Super.PostBeginPlay(); Super.PostBeginPlay();
@ -542,7 +548,7 @@ Class DispersionPistol : UnrealWeapon
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true); A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add); A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
UTMainHandler.DoSwing(self,(FRandom[DPistol](-0.1,-0.3),FRandom[DPistol](-0.1,0.3)),2+invoker.upgradelevel*0.5,-0.3,3,SWING_Spring,0,3+invoker.upgradelevel); UTMainHandler.DoSwing(self,(FRandom[DPistol](-0.1,-0.3),FRandom[DPistol](-0.1,0.3)),2+invoker.upgradelevel*0.5,-0.3,3,SWING_Spring,0,3+invoker.upgradelevel);
if ( !Dampener.Active(self) ) A_AlertMonsters(); if ( !Dampener.Active(self) ) A_AlertMonsters(gameinfo.gametype&GAME_Strife?120:0);
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
Vector3 x, y, z; Vector3 x, y, z;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll); [x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
@ -615,7 +621,7 @@ Class DispersionPistol : UnrealWeapon
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add); A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
double ss = 0.5+invoker.chargesize*0.3; double ss = 0.5+invoker.chargesize*0.3;
UTMainHandler.DoSwing(self,(FRandom[DPistol](-0.1,-0.3)*ss,FRandom[DPistol](-0.1,0.3))*ss,2+invoker.upgradelevel*0.5,-0.3,3,SWING_Spring,0,3+invoker.upgradelevel); UTMainHandler.DoSwing(self,(FRandom[DPistol](-0.1,-0.3)*ss,FRandom[DPistol](-0.1,0.3))*ss,2+invoker.upgradelevel*0.5,-0.3,3,SWING_Spring,0,3+invoker.upgradelevel);
if ( !Dampener.Active(self) ) A_AlertMonsters(); if ( !Dampener.Active(self) ) A_AlertMonsters(gameinfo.gametype&GAME_Strife?120:0);
int qs = int(1+invoker.chargesize*0.3); int qs = int(1+invoker.chargesize*0.3);
A_QuakeEx(qs,qs,qs,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); A_QuakeEx(qs,qs,qs,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
Vector3 x, y, z; Vector3 x, y, z;

View file

@ -250,6 +250,7 @@ Class SMiniGun : UnrealWeapon
Weapon.AmmoGive 32; Weapon.AmmoGive 32;
Inventory.RespawnTics 2100; Inventory.RespawnTics 2100;
+INVENTORY.IGNORESKILL; +INVENTORY.IGNORESKILL;
+INVENTORY.ALWAYSPICKUP;
UTWeapon.DropAmmo 4; UTWeapon.DropAmmo 4;
} }
States States

View file

@ -1,90 +1,6 @@
// Backpack that only gives ammo for valid weapons // Backpack that only gives ammo for valid weapons
Class UnrealBackpack : BackpackItem replaces Backpack Class UnrealBackpack : UTBackpack
{ {
override Inventory CreateCopy( Actor other )
{
// Find every unique type of ammoitem. Give it to the player if
// he doesn't have it already, and double its maximum capacity.
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let type = (class<Ammo>)(AllActorClasses[i]);
if ( !type || (type.GetParentClass() != 'Ammo') ) continue;
// check that it's for a valid weapon
bool isvalid = false;
for ( int j=0; j<AllActorClasses.Size(); j++ )
{
let type2 = (class<Weapon>)(AllActorClasses[j]);
if ( !type2 ) continue;
let rep = GetReplacement(type2);
if ( (rep != type2) && !(rep is "DehackedPickup") ) continue;
readonly<Weapon> weap = GetDefaultByType(type2);
if ( !other.player || !other.player.weapons.LocateWeapon(type2) || weap.bCheatNotWeapon ) continue;
if ( (weap.AmmoType1 == type) || (weap.AmmoType2 == type) )
{
isvalid = true;
break;
}
}
if ( !isvalid ) continue;
let ammoitem = Ammo(other.FindInventory(type));
int amount = GetDefaultByType(type).BackpackAmount;
// don't give these at all
if ( (amount <= 0) && (GetDefaultByType(type).BackpackMaxAmount == GetDefaultByType(type).MaxAmount) ) continue;
// extra ammo in baby mode and nightmare mode
if ( !bIgnoreSkill ) amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
if ( amount < 0 ) amount = 0;
if ( !ammoitem )
{
// The player did not have the ammoitem. Add it.
ammoitem = Ammo(Spawn(type));
ammoitem.Amount = bDepleted?0:amount;
if ( ammoitem.BackpackMaxAmount > ammoitem.MaxAmount )
ammoitem.MaxAmount = ammoitem.BackpackMaxAmount;
if ( ammoitem.Amount > ammoitem.MaxAmount )
ammoitem.Amount = ammoitem.MaxAmount;
ammoitem.AttachToOwner(other);
}
else
{
// The player had the ammoitem. Give some more.
if ( ammoitem.MaxAmount < ammoitem.BackpackMaxAmount )
ammoitem.MaxAmount = ammoitem.BackpackMaxAmount;
if ( !bDepleted && (ammoitem.Amount < ammoitem.MaxAmount) )
{
ammoitem.Amount += amount;
if ( ammoitem.Amount > ammoitem.MaxAmount )
ammoitem.Amount = ammoitem.MaxAmount;
}
}
}
return Inventory.CreateCopy(other);
}
override bool HandlePickup( Inventory item )
{
// Since you already have a backpack, that means you already have every
// kind of ammo in your inventory, so we don't need to look at the
// entire PClass list to discover what kinds of ammo exist, and we don't
// have to alter the MaxAmount either.
if ( item is 'BackpackItem' )
{
for ( let probe = Owner.Inv; probe; probe = probe.Inv )
{
if ( probe.GetParentClass() != 'Ammo' ) continue;
if ( probe.Amount >= probe.MaxAmount && !sv_unlimited_pickup ) continue;
int amount = Ammo(probe).Default.BackpackAmount;
// extra ammo in baby mode and nightmare mode
if ( !bIgnoreSkill )
amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
probe.Amount += amount;
if ( (probe.Amount > probe.MaxAmount) && !sv_unlimited_pickup )
probe.Amount = probe.MaxAmount;
}
// The pickup always succeeds, even if you didn't get anything
item.bPickupGood = true;
return true;
}
return false;
}
override void DoPickupSpecial( Actor toucher ) override void DoPickupSpecial( Actor toucher )
{ {
Super.DoPickupSpecial(toucher); Super.DoPickupSpecial(toucher);
@ -114,18 +30,6 @@ Class UnrealBackpack : BackpackItem replaces Backpack
} }
} }
} }
Default
{
Tag "$T_BACKPACK";
Inventory.PickupMessage "$I_BACKPACK";
Inventory.RespawnTics 2100;
}
States
{
Spawn:
BPAK A -1;
Stop;
}
} }
Class UTranslator : UnrealInventory Class UTranslator : UnrealInventory

View file

@ -245,6 +245,7 @@ Class OLSMP : UnrealWeapon
UTWeapon.DropAmmo 50; UTWeapon.DropAmmo 50;
OLSMP.ClipCount 100; OLSMP.ClipCount 100;
+UNREALWEAPON.NOFIRSTGIVE; +UNREALWEAPON.NOFIRSTGIVE;
+INVENTORY.ALWAYSPICKUP;
} }
States States
{ {
@ -337,7 +338,7 @@ Class OLSMP : UnrealWeapon
invoker.clipout = true; invoker.clipout = true;
A_Overlay(-9999,null); A_Overlay(-9999,null);
A_WeaponOffset(0,32); // fix sudden psprite lowering A_WeaponOffset(0,32); // fix sudden psprite lowering
A_PlaySound("automag/click",CHAN_WEAPON,!Dampener.Active(self)?1.:.1,pitch:0.8); A_PlaySound("automag/click",CHAN_ITEM,!Dampener.Active(self)?1.:.1,pitch:0.8);
} }
AUTR ABCDEFGHIJKLMNOPQRSTUVWXY 1; AUTR ABCDEFGHIJKLMNOPQRSTUVWXY 1;
AUTD ABCD 1; AUTD ABCD 1;

View file

@ -157,7 +157,7 @@ Class PeaceRocket : Actor
States States
{ {
Spawn: Spawn:
PEAR A 1 PEMR A 1
{ {
roll += 5.; roll += 5.;
A_SeekTargets(); A_SeekTargets();
@ -340,10 +340,10 @@ Class PeaceBarrel : Actor
States States
{ {
Spawn: Spawn:
PEAM A -1; PEMM A -1;
Stop; Stop;
Bounce: Bounce:
PEAM A 0 PEMM A 0
{ {
if ( BlockingFloor ) A_AlignSelf(); if ( BlockingFloor ) A_AlignSelf();
else pitch = roll = 0; else pitch = roll = 0;
@ -351,59 +351,59 @@ Class PeaceBarrel : Actor
} }
Goto Spawn; Goto Spawn;
Death: Death:
PEAM A 1 A_CheckFloor(1); PEMM A 1 A_CheckFloor(1);
Wait; Wait;
PEAM A 4 A_AlignSelf(); PEMM A 4 A_AlignSelf();
PEAM A 35 PEMM A 35
{ {
A_PlaySound((special1<=0)?"eightball/seeklost":"eightball/seeklock",CHAN_AUTO); A_PlaySound((special1<=0)?"eightball/seeklost":"eightball/seeklock",CHAN_AUTO);
A_AlertMonsters(); A_AlertMonsters();
return A_JumpIf(--special1<0,1); return A_JumpIf(--special1<0,1);
} }
Wait; Wait;
PEAM A 0 A_JumpIf(bAMBUSH,"Detonate"); PEMM A 0 A_JumpIf(bAMBUSH,"Detonate");
PEAM A 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); PEMM A 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
PEAM B 3; PEMM B 3;
PEAM C 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); PEMM C 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
PEAM D 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); PEMM D 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
PEAM E 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); PEMM E 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
PEAM F 3 PEMM F 3
{ {
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
} }
PEAM G 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); PEMM G 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
PEAM H 3 PEMM H 3
{ {
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
} }
PEAM I 3; PEMM I 3;
PEAM J 3 PEMM J 3
{ {
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2)); A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
} }
PEAM K 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); PEMM K 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1);
PEAM L 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2)); PEMM L 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
PEAM M 3; PEMM M 3;
PEAM N 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); PEMM N 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1);
PEAM OPQ 3; PEMM OPQ 3;
PEAM R 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); PEMM R 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1);
PEAM STU 3; PEMM STU 3;
PEAM V 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); PEMM V 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1);
PEAM XYZ[\] 3; PEMM XYZ[\] 3;
PEAM ] 35; PEMM ] 35;
PEAM ] 0 A_FireRocket(0); PEMM ] 0 A_FireRocket(0);
PEAL A 20; PEML A 20;
PEAL A 0 A_FireRocket(1); PEML A 0 A_FireRocket(1);
PEAL B 20; PEML B 20;
PEAL B 0 A_FireRocket(2); PEML B 0 A_FireRocket(2);
PEAL C 20; PEML C 20;
PEAL C 0 A_FireRocket(3); PEML C 0 A_FireRocket(3);
PEAL D 20; PEML D 20;
Detonate: Detonate:
PEAM A 20; PEMM A 20;
BlowUp: BlowUp:
TNT1 A 0 A_BlowUp(); TNT1 A 0 A_BlowUp();
SSMX ABCDEFGHIJ 2 Bright; SSMX ABCDEFGHIJ 2 Bright;
@ -492,19 +492,19 @@ Class Peacemaker : UnrealWeapon
States States
{ {
Spawn: Spawn:
PEAP A -1; PEMP A -1;
Stop; Stop;
PEAP B -1; PEMP B -1;
Stop; Stop;
Select: Select:
PEAS A 1 A_Raise(int.max); PEMS A 1 A_Raise(int.max);
Wait; Wait;
Ready: Ready:
PEAS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE); PEMS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE);
PEAS K 0 A_PlaySound("peace/up",CHAN_ITEM,.4); PEMS K 0 A_PlaySound("peace/up",CHAN_ITEM,.4);
PEAS KLMNOPQRST 2 A_WeaponReady(WRF_NOFIRE); PEMS KLMNOPQRST 2 A_WeaponReady(WRF_NOFIRE);
Idle: Idle:
PEAI A 1 PEMI A 1
{ {
A_CheckReload(); A_CheckReload();
A_WeaponReady(); A_WeaponReady();
@ -522,45 +522,45 @@ Class Peacemaker : UnrealWeapon
} }
Wait; Wait;
Fire: Fire:
PEAC A 1 A_StartCount(); PEMC A 1 A_StartCount();
PEAC # 1 A_CountUp(1); PEMC # 1 A_CountUp(1);
Wait; Wait;
PEAF ABCD 2; PEMF ABCD 2;
PEAF E 0 PEMF E 0
{ {
A_PlaySound("peace/down",CHAN_ITEM,.4); A_PlaySound("peace/down",CHAN_ITEM,.4);
UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8); UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8);
} }
PEAF EFG 2; PEMF EFG 2;
PEAF H 0 PEMF H 0
{ {
UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5); UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5);
} }
PEAF HI 2; // hello PEMF HI 2; // hello
PEAF I -1 A_PeacemakerThrow(); PEMF I -1 A_PeacemakerThrow();
Stop; Stop;
AltFire: AltFire:
PEAC A 1 A_StartCount(); PEMC A 1 A_StartCount();
PEAC # 1 A_CountUp(1); PEMC # 1 A_CountUp(1);
Wait; Wait;
PEAF ABCD 2; PEMF ABCD 2;
PEAF E 0 PEMF E 0
{ {
A_PlaySound("peace/down",CHAN_ITEM,.4); A_PlaySound("peace/down",CHAN_ITEM,.4);
UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8); UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8);
} }
PEAF EFG 2; PEMF EFG 2;
PEAF H 0 PEMF H 0
{ {
UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5); UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5);
} }
PEAF HI 2; // howdy PEMF HI 2; // howdy
PEAF I -1 A_PeacemakerThrow(true); PEMF I -1 A_PeacemakerThrow(true);
Stop; Stop;
Deselect: Deselect:
PEAD A 0 A_JumpIfNoAmmo("EmptyDeselect"); PEMD A 0 A_JumpIfNoAmmo("EmptyDeselect");
PEAD ABCDEFGHI 1; PEMD ABCDEFGHI 1;
PEAD J 1 A_Lower(int.max); PEMD J 1 A_Lower(int.max);
EmptyDeselect: EmptyDeselect:
TNT1 A 1 A_Lower(int.max); TNT1 A 1 A_Lower(int.max);
Wait; Wait;

View file

@ -167,7 +167,7 @@ Class StunProj : Actor
SetOrigin(t.Results.HitPos-t.Results.HitVector*4,false); SetOrigin(t.Results.HitPos-t.Results.HitVector*4,false);
StunExplode(); StunExplode();
Actor a = t.Results.HitActor; Actor a = t.Results.HitActor;
a.DamageMobj(self,target,max(1,int(4*specialf1)),'jolted',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x)); a.DamageMobj(self,target,max(1,int(10*specialf1)),'jolted',DMG_USEANGLE,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
if ( !a.bDONTTHRUST ) if ( !a.bDONTTHRUST )
{ {
UTMainHandler.DoKnockback(a,t.Results.HitVector,(bAMBUSH?-22000:26000)*specialf1); UTMainHandler.DoKnockback(a,t.Results.HitVector,(bAMBUSH?-22000:26000)*specialf1);
@ -208,10 +208,9 @@ Class StunProj : Actor
{ {
moving = false; moving = false;
SetStateLabel("Death"); SetStateLabel("Death");
A_Explode(int(0.6*specialf1),50);
A_QuakeEx(1,1,1,3,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollintensity:0.2); A_QuakeEx(1,1,1,3,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollintensity:0.2);
A_PlaySound("stun/hit",CHAN_VOICE,pitch:FRandom[Stunner](1.5,1.9)-0.08*specialf1); A_PlaySound("stun/hit",CHAN_VOICE,pitch:FRandom[Stunner](1.5,1.9)-0.08*specialf1);
UTMainHandler.DoBlast(self,50,(bAMBUSH?-7000:11000)*specialf1); A_AlertMonsters(gameinfo.gametype&GAME_Strife?100:0);
Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
int numpt = Random[ExploS](10,15); int numpt = Random[ExploS](10,15);
for ( int i=0; i<numpt; i++ ) for ( int i=0; i<numpt; i++ )
@ -223,6 +222,12 @@ Class StunProj : Actor
s.vel = pvel; s.vel = pvel;
} }
} }
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{
if ( gameinfo.gametype&GAME_Strife )
target.DaggerAlert(self.target);
return damage;
}
Default Default
{ {
Obituary "$O_STUNNER"; Obituary "$O_STUNNER";
@ -237,6 +242,7 @@ Class StunProj : Actor
+NODAMAGETHRUST; +NODAMAGETHRUST;
+NOTELEPORT; +NOTELEPORT;
+FORCEXYBILLBOARD; +FORCEXYBILLBOARD;
+NOEXTREMEDEATH;
} }
States States
{ {
@ -368,7 +374,7 @@ Class Stunner : UnrealWeapon
LineTrace(angle,60,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); LineTrace(angle,60,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor ) if ( d.HitType == TRACE_HitActor )
{ {
int dmg = int(5*invoker.chargesize); int dmg = int(12*invoker.chargesize);
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.81) ) if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.81) )
dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',DMG_THRUSTLESS); dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',DMG_THRUSTLESS);
else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'impact',DMG_THRUSTLESS); else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'impact',DMG_THRUSTLESS);
@ -405,7 +411,7 @@ Class Stunner : UnrealWeapon
A_OverlayFlags(-2,PSPF_RenderStyle,true); A_OverlayFlags(-2,PSPF_RenderStyle,true);
A_OverlayRenderStyle(-2,STYLE_Add); A_OverlayRenderStyle(-2,STYLE_Add);
StunnerAmmo(weap.Ammo1).rechargephase = 0; StunnerAmmo(weap.Ammo1).rechargephase = 0;
if ( !Dampener.Active(self) ) A_AlertMonsters(); if ( !Dampener.Active(self) && !(gameinfo.gametype&GAME_Strife) ) A_AlertMonsters();
} }
action State A_ChargeUp() action State A_ChargeUp()
{ {
@ -416,7 +422,7 @@ Class Stunner : UnrealWeapon
StunnerAmmo(weap.Ammo1).rechargephase = 0; StunnerAmmo(weap.Ammo1).rechargephase = 0;
UTMainHandler.DoSwing(self,(FRandom[Stunner](-1,1),FRandom[Stunner](-1,1)),0.02*invoker.chargesize,0,2,SWING_Spring); UTMainHandler.DoSwing(self,(FRandom[Stunner](-1,1),FRandom[Stunner](-1,1)),0.02*invoker.chargesize,0,2,SWING_Spring);
A_WeaponOffset(FRandom[Stunner](-1,1)*1.2*invoker.chargesize,32+FRandom[Stunner](-1,1)*1.2*invoker.chargesize); A_WeaponOffset(FRandom[Stunner](-1,1)*1.2*invoker.chargesize,32+FRandom[Stunner](-1,1)*1.2*invoker.chargesize);
if ( !Dampener.Active(self) ) A_AlertMonsters(); if ( !Dampener.Active(self) && !(gameinfo.gametype&GAME_Strife) ) A_AlertMonsters();
if ( invoker.chargesize >= 5. ) if ( invoker.chargesize >= 5. )
{ {
invoker.count += 1./35.; invoker.count += 1./35.;
@ -451,6 +457,7 @@ Class Stunner : UnrealWeapon
Weapon.AmmoGive 50; Weapon.AmmoGive 50;
UTWeapon.DropAmmo 50; UTWeapon.DropAmmo 50;
+WEAPON.WIMPY_WEAPON; +WEAPON.WIMPY_WEAPON;
+NOEXTREMEDEATH;
} }
States States
{ {

View file

@ -682,7 +682,8 @@ Class UnrealInventory : Inventory
Super.AttachToOwner(other); Super.AttachToOwner(other);
if ( !Charge ) Charge = DefaultCharge; if ( !Charge ) Charge = DefaultCharge;
// it's annoying to set this per-subclass // it's annoying to set this per-subclass
InterHubAmount = bUNLIMITEDCOPIES?int.max:MaxAmount; if ( !(gameinfo.gametype&GAME_Hexen) )
InterHubAmount = bUNLIMITEDCOPIES?int.max:MaxAmount;
} }
override bool HandlePickup( Inventory item ) override bool HandlePickup( Inventory item )
{ {
@ -950,6 +951,52 @@ Class UNothing : Actor
} }
} }
Class HexenEitherOrSession : Thinker
{
Array<Class<Actor> > done;
private bool IsAvailable( Class<Actor> item )
{
let ti = ThinkerIterator.Create(item);
Actor a;
while ( a = Actor(ti.Next()) ) return true;
for ( int i=0; i<done.Size(); i++ ) if ( done[i] == item ) return true;
return false;
}
void MarkDone( Class<Actor> item )
{
for ( int i=0; i<done.Size(); i++ ) if ( done[i] == item ) return;
done.Push(item);
}
void MarkUnDone( Class<Actor> item )
{
for ( int i=0; i<done.Size(); i++ )
{
if ( done[i] != item ) continue;
done.Delete(i);
i--;
}
}
Class<Actor> EitherOr( Class<Actor> a, Class<Actor> b, bool allowed = true )
{
if ( !allowed ) return a;
if ( IsAvailable(a) )
{
MarkDone(a);
if ( IsAvailable(b) )
{
MarkDone(b);
if ( Random[Replacements](0,1) ) return b;
return a;
}
return b;
}
return a;
}
}
Class UnrealMainHandler : EventHandler Class UnrealMainHandler : EventHandler
{ {
Array<AmmoUsedInSlot> AmmoSlots; Array<AmmoUsedInSlot> AmmoSlots;
@ -971,6 +1018,25 @@ Class UnrealMainHandler : EventHandler
break; break;
} }
} }
private bool IsAvailable( Class<Actor> item )
{
let ti = ThinkerIterator.Create(item);
Actor a;
while ( a = Actor(ti.Next()) ) return true;
return false;
}
private Class<Actor> EitherOr( Class<Actor> a, Class<Actor> b, bool allowed = true )
{
let ti = ThinkerIterator.Create("HexenEitherOrSession",Thinker.STAT_STATIC);
HexenEitherOrSession hs = HexenEitherOrSession(ti.Next());
if ( !hs )
{
hs = new("HexenEitherOrSession");
hs.ChangeStatNum(Thinker.STAT_STATIC);
hs.done.Clear();
}
return hs.EitherOr(a,b,allowed);
}
override void CheckReplacement( ReplaceEvent e ) override void CheckReplacement( ReplaceEvent e )
{ {
if ( e.IsFinal ) return; if ( e.IsFinal ) return;
@ -1140,16 +1206,16 @@ Class UnrealMainHandler : EventHandler
else if ( Random[Replacements](0,1) ) e.Replacement = 'UBioAmmo'; else if ( Random[Replacements](0,1) ) e.Replacement = 'UBioAmmo';
else e.Replacement = 'URifleAmmo'; else e.Replacement = 'URifleAmmo';
} }
else if ( (e.Replacee == 'InvulnerabilitySphere') || (e.Replacee == 'ArtiInvulnerability') ) e.Replacement = 'PowerShield'; else if ( (e.Replacee == 'InvulnerabilitySphere') || (e.Replacee == 'ArtiInvulnerability') || (e.Replacee == 'ArtiInvulnerability2') ) e.Replacement = 'PowerShield';
else if ( (e.Replacee == 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') ) else if ( (e.Replacee == 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') )
{ {
if ( sting_msentry && !Random[Replacements](0,9) ) e.Replacement = 'SentryItem'; if ( sting_msentry && !Random[Replacements](0,9) ) e.Replacement = 'SentryItem';
else if ( ((sting_proto && sting_dubious) || sting_olsmp) && !Random[Replacements](0,2) ) e.Replacement = 'WeaponPowerUp'; else if ( ((sting_proto && sting_dubious) || sting_olsmp) && !Random[Replacements](0,2) ) e.Replacement = 'WeaponPowerUp';
else e.Replacement = 'Amplifier'; else e.Replacement = 'Amplifier';
} }
else if ( e.Replacee == 'ArtiEgg' ) e.Replacement = 'VoiceBox'; else if ( (e.Replacee == 'ArtiEgg') || (e.Replacee == 'ArtiPork') ) e.Replacement = 'VoiceBox';
else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'SuperHealth'; else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'SuperHealth';
else if ( e.Replacee == 'Megasphere' ) e.Replacement = 'ShieldBelt'; else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiBoostArmor') ) e.Replacement = 'ShieldBelt';
else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') ) else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') )
{ {
if ( sting_proto && Random[Replacements](0,2) ) e.Replacement = 'MotionDetector'; if ( sting_proto && Random[Replacements](0,2) ) e.Replacement = 'MotionDetector';
@ -1158,16 +1224,18 @@ Class UnrealMainHandler : EventHandler
else if ( (e.Replacee == 'BlurSphere') || (e.Replacee == 'ArtiInvisibility') ) e.Replacement = 'UInvisibility'; else if ( (e.Replacee == 'BlurSphere') || (e.Replacee == 'ArtiInvisibility') ) e.Replacement = 'UInvisibility';
else if ( (e.Replacee == 'Infrared') || (e.Replacee == 'ArtiTorch') ) e.Replacement = 'UFlashlight'; else if ( (e.Replacee == 'Infrared') || (e.Replacee == 'ArtiTorch') ) e.Replacement = 'UFlashlight';
else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UJumpBoots'; else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UJumpBoots';
else if ( e.Replacee == 'ArtiFly' ) e.Replacement = 'UJumpBoots'; else if ( (e.Replacee == 'ArtiFly') || (e.Replacee == 'ArtiSpeedBoots') ) e.Replacement = 'UJumpBoots';
else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') ) e.Replacement = 'UnrealBackpack'; else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') || (e.Replacee == 'ArtiHealingRadius') ) e.Replacement = 'UnrealBackpack';
else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') ) else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') || (e.Replacee is 'ArtiPoisonBag') || (e.Replacee is 'ArtiBlastRadius') )
{ {
if ( sting_abonus && Random[Replacements](0,3) ) e.Replacement = 'UArmorBonus'; if ( sting_abonus && Random[Replacements](0,3) ) e.Replacement = 'UArmorBonus';
else e.Replacement = 'Flare'; else e.Replacement = 'Flare';
} }
else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'Bandages'; else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'Bandages';
else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') ) e.Replacement = 'KevlarSuit'; else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') || (e.Replacee == 'PlatinumHelm') ) e.Replacement = 'KevlarSuit';
else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'UArmor'; else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'EnchantedShield') || (e.Replacee == 'MeshArmor') ) e.Replacement = 'UArmor';
else if ( e.Replacee == 'AmuletOfWarding' ) e.Replacement = 'AsbestosSuit';
else if ( e.Replacee == 'FalconShield' ) e.Replacement = 'ToxinSuit';
else if ( (e.Replacee == 'Stimpack') || (e.Replacee == 'ArtiHealth') ) else if ( (e.Replacee == 'Stimpack') || (e.Replacee == 'ArtiHealth') )
{ {
if ( Random[Replacements](0,1) ) e.Replacement = 'UHealth'; if ( Random[Replacements](0,1) ) e.Replacement = 'UHealth';
@ -1175,7 +1243,7 @@ Class UnrealMainHandler : EventHandler
else e.Replacement = 'Seeds'; else e.Replacement = 'Seeds';
} }
else if ( e.Replacee == 'Medikit' ) e.Replacement = 'UHealth'; else if ( e.Replacee == 'Medikit' ) e.Replacement = 'UHealth';
else if ( e.Replacee == 'ArtiTeleport' ) else if ( (e.Replacee == 'ArtiTeleport') || (e.Replacee == 'ArtiTeleportOther') || (e.Replacee == 'ArtiDarkServant') )
{ {
// I have no idea what to replace this with, so just have some random stuff // I have no idea what to replace this with, so just have some random stuff
switch( Random[Replacements](0,sting_proto?7:5) ) switch( Random[Replacements](0,sting_proto?7:5) )
@ -1207,6 +1275,40 @@ Class UnrealMainHandler : EventHandler
} }
} }
else if ( e.Replacee == 'TeleportFog' ) e.Replacement = 'UTeleportFog'; else if ( e.Replacee == 'TeleportFog' ) e.Replacement = 'UTeleportFog';
// Doomreal's weapon progression for Hexen is a bit more... involved when it comes to including proto content
else if ( (e.Replacee == 'FWeapFist') || (e.Replacee == 'CWeapMace') || (e.Replacee == 'MWeapWand') )
e.Replacement = 'DispersionPistol';
else if ( e.Replacee == 'FWeapAxe' ) e.Replacement = EitherOr('Automag','Betamag',sting_proto);
else if ( e.Replacee == 'CWeapStaff' ) e.Replacement = EitherOr('Stinger','Quadshot',sting_proto);
else if ( e.Replacee == 'MWeapFrost' ) e.Replacement = EitherOr('ASMD','Stunner',sting_proto);
else if ( (e.Replacee == 'FWeaponPiece3') || (e.Replacee == 'FWeapQuietus') || (e.Replacee.GetClassName() == 'mkFullQuietus') ) e.Replacement = 'Eightball';
else if ( e.Replacee == 'CWeaponPiece3' ) e.Replacement = 'WeaponPowerUp';
else if ( e.Replacee == 'MWeaponPiece3' ) e.Replacement = EitherOr('Automag','Betamag',sting_proto);
else if ( e.Replacee == 'FWeapHammer' ) e.Replacement = EitherOr('UFlakCannon','FlameGun',sting_proto);
else if ( e.Replacee == 'CWeapFlame' ) e.Replacement = EitherOr('Razorjack','UFlamethrower',sting_proto);
else if ( e.Replacee == 'MWeapLightning' ) e.Replacement = EitherOr('UBioRifle','Impaler',sting_proto);
else if ( e.Replacee == 'FWeaponPiece2' )
{
if ( sting_proto && sting_dubious ) e.Replacement = 'Bonesaw';
else e.Replacement = 'WeaponPowerUp';
}
else if ( (e.Replacee == 'CWeaponPiece2') || (e.Replacee == 'CWeapWraithverge') || (e.Replacee.GetClassName() == 'mkFullWraithverge') ) e.Replacement = 'URifle';
else if ( e.Replacee == 'MWeaponPiece2' ) e.Replacement = 'WeaponPowerUp';
else if ( e.Replacee == 'FWeaponPiece1' )
{
if ( sting_proto && sting_dubious ) e.Replacement = 'BigGun';
else e.Replacement = 'UnrealBackpack';
}
else if ( e.Replacee == 'CWeaponPiece1' )
{
if ( sting_proto && sting_dubious ) e.Replacement = 'SMiniGun';
else e.Replacement = 'UnrealBackpack';
}
else if ( (e.Replacee == 'MWeaponPiece1') || (e.Replacee == 'MWeapBloodscourge') || (e.Replacee.GetClassName() == 'mkFullBloodscourge') )
{
if ( sting_olsmp ) e.Replacement = 'OLSMP';
else e.Replacement = 'UnrealBackpack';
}
// replace UT items (prevents them from being cheated in) // replace UT items (prevents them from being cheated in)
else if ( e.Replacee is 'ImpactHammer' ) e.Replacement = 'DispersionPistol'; else if ( e.Replacee is 'ImpactHammer' ) e.Replacement = 'DispersionPistol';
else if ( e.Replacee is 'Translocator' ) e.Replacement = 'UTranslocator'; else if ( e.Replacee is 'Translocator' ) e.Replacement = 'UTranslocator';
@ -1252,7 +1354,7 @@ Class UnrealMainHandler : EventHandler
else if ( e.Replacee is 'UTHealthPack' ) e.Replacement = 'SuperHealth'; else if ( e.Replacee is 'UTHealthPack' ) e.Replacement = 'SuperHealth';
else if ( e.Replacee is 'UTHealthBonus' ) e.Replacement = 'Bandages'; else if ( e.Replacee is 'UTHealthBonus' ) e.Replacement = 'Bandages';
else if ( e.Replacee is 'UTJumpBoots' ) e.Replacement = 'UJumpBoots'; else if ( e.Replacee is 'UTJumpBoots' ) e.Replacement = 'UJumpBoots';
else if ( e.Replacee is 'UTActivatable' ) e.Replacement = 'UNothing'; else if ( (e.Replacee is 'UTActivatable') && (!(e.Replacee is 'ActUTFullAmmoBox') || !(gameinfo.gametype&GAME_Hexen)) ) e.Replacement = 'UNothing';
else if ( e.Replacee is 'UTActivatableHealth' ) e.Replacement = 'UNothing'; else if ( e.Replacee is 'UTActivatableHealth' ) e.Replacement = 'UNothing';
} }

View file

@ -593,7 +593,39 @@ Class UnrealHUD : BaseStatusBar
private void DrawKeys( double x, double y, bool leftright = false ) private void DrawKeys( double x, double y, bool leftright = false )
{ {
if ( deathmatch ) return; // no need to draw in DM if ( deathmatch ) return; // no need to draw in DM
if ( gameinfo.gametype&(GAME_Hexen|GAME_Strife) ) return; // no key display for these ATM (will do eventually) if ( gameinfo.gametype&(GAME_Hexen|GAME_Strife) )
{
if ( !automapactive ) return;
int kw = (gameinfo.gametype&GAME_Strife)?20:30,
kh = (gameinfo.gametype&GAME_Strife)?20:40;
int nkeys = 0;
Array<int> rows;
Array<Inventory> keys;
keys.Clear();
rows.Clear();
rows.Push(0);
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
{
if ( !(i is 'Key') ) continue;
keys.Push(i);
if ( rows[rows.Size()-1] >= 6 ) rows.Push(1);
else rows[rows.Size()-1]++;
}
int j = 0;
CurX = (ClipX-kw);
for ( int i=0; i<rows.Size(); i++ )
{
CurY = (ClipY-rows[i]*kh)*0.5;
for ( int k=0; k<rows[i]; k++ )
{
Screen.DrawTexture(keys[j].Icon,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
j++;
CurY += kh;
}
CurX -= kw;
}
return;
}
CurX = x; CurX = x;
CurY = y; CurY = y;
int cnt = 0; int cnt = 0;
@ -768,10 +800,14 @@ Class UnrealHUD : BaseStatusBar
DrawString(mOldDigitsSmall,FormatNumber(sec,3),(633,378),DI_TEXT_ALIGN_RIGHT); DrawString(mOldDigitsSmall,FormatNumber(sec,3),(633,378),DI_TEXT_ALIGN_RIGHT);
if ( sec2 != -1 ) if ( sec2 != -1 )
DrawString(mOldDigitsSmall,FormatNumber(sec2,3),(556,378),DI_TEXT_ALIGN_LEFT); DrawString(mOldDigitsSmall,FormatNumber(sec2,3),(556,378),DI_TEXT_ALIGN_LEFT);
for ( int i=0; i<6; i++ ) if ( gameinfo.gametype&(GAME_Hexen|GAME_Strife) ) DrawKeys(0,0);
else
{ {
if ( !CPlayer.mo.CheckKeys(i+1,false,true) ) continue; for ( int i=0; i<6; i++ )
DrawImage(OldKeys[((i==0)&&(gameinfo.gametype&GAME_Heretic))?6:i],(keyofs[i],366),DI_ITEM_OFFSETS); {
if ( !CPlayer.mo.CheckKeys(i+1,false,true) ) continue;
DrawImage(OldKeys[((i==0)&&(gameinfo.gametype&GAME_Heretic))?6:i],(keyofs[i],366),DI_ITEM_OFFSETS);
}
} }
if ( HudMode > 5 ) return; if ( HudMode > 5 ) return;
// Draw frags in DM // Draw frags in DM