diff --git a/Readme.md b/Readme.md index 946b3ac..23915fe 100644 --- a/Readme.md +++ b/Readme.md @@ -73,14 +73,14 @@ This mod requires GZDoom 4.2.4 or later, and runs on top of Doom Tournament. ## In progress - - Tooltips for options. - - 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. + - N/A, this is the 1.1 release. ## 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. - 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 diff --git a/graphics/icons/ItemABox.png b/graphics/icons/ItemABox.png new file mode 100644 index 0000000..63245ce Binary files /dev/null and b/graphics/icons/ItemABox.png differ diff --git a/modeldef.peacemaker b/modeldef.peacemaker index 3865ea8..ee8b439 100644 --- a/modeldef.peacemaker +++ b/modeldef.peacemaker @@ -8,7 +8,7 @@ Model "Peacerocket" USEACTORPITCH USEACTORROLL - FrameIndex PEAR A 0 0 + FrameIndex PEMR A 0 0 } Model "PeaceFragment" @@ -40,40 +40,40 @@ Model "Peacebarrel" USEACTORROLL // unfold - FrameIndex PEAM A 0 0 - FrameIndex PEAM B 0 1 - FrameIndex PEAM C 0 2 - FrameIndex PEAM D 0 3 - FrameIndex PEAM E 0 4 - FrameIndex PEAM F 0 5 - FrameIndex PEAM G 0 6 - FrameIndex PEAM H 0 7 - FrameIndex PEAM I 0 8 - FrameIndex PEAM J 0 9 - FrameIndex PEAM K 0 10 - FrameIndex PEAM L 0 11 - FrameIndex PEAM M 0 12 - FrameIndex PEAM N 0 13 - FrameIndex PEAM O 0 14 - FrameIndex PEAM P 0 15 - FrameIndex PEAM Q 0 16 - FrameIndex PEAM R 0 17 - FrameIndex PEAM S 0 18 - FrameIndex PEAM T 0 19 - FrameIndex PEAM U 0 20 - FrameIndex PEAM V 0 21 - FrameIndex PEAM W 0 22 - FrameIndex PEAM X 0 23 - FrameIndex PEAM Y 0 24 - FrameIndex PEAM Z 0 25 - FrameIndex PEAM [ 0 26 - FrameIndex PEAM \ 0 27 - FrameIndex PEAM ] 0 28 + FrameIndex PEMM A 0 0 + FrameIndex PEMM B 0 1 + FrameIndex PEMM C 0 2 + FrameIndex PEMM D 0 3 + FrameIndex PEMM E 0 4 + FrameIndex PEMM F 0 5 + FrameIndex PEMM G 0 6 + FrameIndex PEMM H 0 7 + FrameIndex PEMM I 0 8 + FrameIndex PEMM J 0 9 + FrameIndex PEMM K 0 10 + FrameIndex PEMM L 0 11 + FrameIndex PEMM M 0 12 + FrameIndex PEMM N 0 13 + FrameIndex PEMM O 0 14 + FrameIndex PEMM P 0 15 + FrameIndex PEMM Q 0 16 + FrameIndex PEMM R 0 17 + FrameIndex PEMM S 0 18 + FrameIndex PEMM T 0 19 + FrameIndex PEMM U 0 20 + FrameIndex PEMM V 0 21 + FrameIndex PEMM W 0 22 + FrameIndex PEMM X 0 23 + FrameIndex PEMM Y 0 24 + FrameIndex PEMM Z 0 25 + FrameIndex PEMM [ 0 26 + FrameIndex PEMM \ 0 27 + FrameIndex PEMM ] 0 28 // launch - FrameIndex PEAL A 0 29 - FrameIndex PEAL B 0 30 - FrameIndex PEAL C 0 31 - FrameIndex PEAL D 0 32 + FrameIndex PEML A 0 29 + FrameIndex PEML B 0 30 + FrameIndex PEML C 0 31 + FrameIndex PEML D 0 32 } Model "Peacemaker" @@ -85,11 +85,11 @@ Model "Peacemaker" ZOffset 5 Scale 0.16 -0.16 0.16 - FrameIndex PEAP B 1 0 + FrameIndex PEMP B 1 0 ZOffset 9 ROTATING - FrameIndex PEAP A 1 0 + FrameIndex PEMP A 1 0 } Model "Peacemaker" @@ -102,57 +102,57 @@ Model "Peacemaker" Offset 7.5 -15 -7.5 // Select - FrameIndex PEAS A 0 0 - FrameIndex PEAS B 0 1 - FrameIndex PEAS C 0 2 - FrameIndex PEAS D 0 3 - FrameIndex PEAS E 0 4 - FrameIndex PEAS F 0 5 - FrameIndex PEAS G 0 6 - FrameIndex PEAS H 0 7 - FrameIndex PEAS I 0 8 - FrameIndex PEAS J 0 9 - FrameIndex PEAS K 0 10 - FrameIndex PEAS L 0 11 - FrameIndex PEAS M 0 12 - FrameIndex PEAS N 0 13 - FrameIndex PEAS O 0 14 - FrameIndex PEAS P 0 15 - FrameIndex PEAS Q 0 16 - FrameIndex PEAS R 0 17 - FrameIndex PEAS S 0 18 - FrameIndex PEAS T 0 19 + FrameIndex PEMS A 0 0 + FrameIndex PEMS B 0 1 + FrameIndex PEMS C 0 2 + FrameIndex PEMS D 0 3 + FrameIndex PEMS E 0 4 + FrameIndex PEMS F 0 5 + FrameIndex PEMS G 0 6 + FrameIndex PEMS H 0 7 + FrameIndex PEMS I 0 8 + FrameIndex PEMS J 0 9 + FrameIndex PEMS K 0 10 + FrameIndex PEMS L 0 11 + FrameIndex PEMS M 0 12 + FrameIndex PEMS N 0 13 + FrameIndex PEMS O 0 14 + FrameIndex PEMS P 0 15 + FrameIndex PEMS Q 0 16 + FrameIndex PEMS R 0 17 + FrameIndex PEMS S 0 18 + FrameIndex PEMS T 0 19 // Idle - FrameIndex PEAI A 0 20 + FrameIndex PEMI A 0 20 // Down - FrameIndex PEAD A 0 22 - FrameIndex PEAD B 0 23 - FrameIndex PEAD C 0 24 - FrameIndex PEAD D 0 25 - FrameIndex PEAD E 0 26 - FrameIndex PEAD F 0 27 - FrameIndex PEAD G 0 28 - FrameIndex PEAD H 0 29 - FrameIndex PEAD I 0 30 + FrameIndex PEMD A 0 22 + FrameIndex PEMD B 0 23 + FrameIndex PEMD C 0 24 + FrameIndex PEMD D 0 25 + FrameIndex PEMD E 0 26 + FrameIndex PEMD F 0 27 + FrameIndex PEMD G 0 28 + FrameIndex PEMD H 0 29 + FrameIndex PEMD I 0 30 // Throw - FrameIndex PEAF A 0 32 - FrameIndex PEAF B 0 33 - FrameIndex PEAF C 0 34 - FrameIndex PEAF D 0 35 - FrameIndex PEAF E 0 36 - FrameIndex PEAF F 0 37 - FrameIndex PEAF G 0 38 - FrameIndex PEAF H 0 39 - FrameIndex PEAF I 0 40 + FrameIndex PEMF A 0 32 + FrameIndex PEMF B 0 33 + FrameIndex PEMF C 0 34 + FrameIndex PEMF D 0 35 + FrameIndex PEMF E 0 36 + FrameIndex PEMF F 0 37 + FrameIndex PEMF G 0 38 + FrameIndex PEMF H 0 39 + FrameIndex PEMF I 0 40 // Count (0-9) - FrameIndex PEAC A 0 43 - FrameIndex PEAC B 0 44 - FrameIndex PEAC C 0 45 - FrameIndex PEAC D 0 46 - FrameIndex PEAC E 0 47 - FrameIndex PEAC F 0 48 - FrameIndex PEAC G 0 49 - FrameIndex PEAC H 0 50 - FrameIndex PEAC I 0 51 - FrameIndex PEAC J 0 52 + FrameIndex PEMC A 0 43 + FrameIndex PEMC B 0 44 + FrameIndex PEMC C 0 45 + FrameIndex PEMC D 0 46 + FrameIndex PEMC E 0 47 + FrameIndex PEMC F 0 48 + FrameIndex PEMC G 0 49 + FrameIndex PEMC H 0 50 + FrameIndex PEMC I 0 51 + FrameIndex PEMC J 0 52 } diff --git a/shaders/glsl/MeshEnviroMapMasked.fp b/shaders/glsl/MeshEnviroMapMasked.fp index c77c27f..ec62d39 100644 --- a/shaders/glsl/MeshEnviroMapMasked.fp +++ b/shaders/glsl/MeshEnviroMapMasked.fp @@ -5,5 +5,5 @@ vec4 ProcessTexel() float mask = texture(masktex,vTexCoord.st).x; vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.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); } diff --git a/shaders/glsl/MeshEnviroMapMasked_AmbientGlow.fp b/shaders/glsl/MeshEnviroMapMasked_AmbientGlow.fp index a43b0e5..4170ef5 100644 --- a/shaders/glsl/MeshEnviroMapMasked_AmbientGlow.fp +++ b/shaders/glsl/MeshEnviroMapMasked_AmbientGlow.fp @@ -13,5 +13,5 @@ vec4 ProcessTexel() float mask = texture(masktex,vTexCoord.st).x; vec3 eyedir = normalize(uCameraPos.xyz-pixelpos.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); } diff --git a/textures.peacemaker b/textures.peacemaker index 06d5239..07bc29d 100644 --- a/textures.peacemaker +++ b/textures.peacemaker @@ -1,4 +1,4 @@ -Sprite "PEAPA0",1,1{} -Sprite "PEASA0",1,1{} -Sprite "PEAMA0",1,1{} -Sprite "PEARA0",1,1{} +Sprite "PEMPA0",1,1{} +Sprite "PEMSA0",1,1{} +Sprite "PEMMA0",1,1{} +Sprite "PEMRA0",1,1{} diff --git a/zscript/automag.zsc b/zscript/automag.zsc index d833442..5ea4601 100644 --- a/zscript/automag.zsc +++ b/zscript/automag.zsc @@ -536,7 +536,7 @@ Class Automag : UnrealWeapon { invoker.clipout = true; 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; AUTD ABCD 1; diff --git a/zscript/biggun.zsc b/zscript/biggun.zsc index 3eefde9..fe09c57 100644 --- a/zscript/biggun.zsc +++ b/zscript/biggun.zsc @@ -432,6 +432,7 @@ Class BigGun : UnrealWeapon Weapon.AmmoGive 4; Inventory.RespawnTics 2100; +INVENTORY.IGNORESKILL; + +INVENTORY.ALWAYSPICKUP; UTWeapon.DropAmmo 4; BigGun.ClipCount 4; +EXTREMEDEATH; diff --git a/zscript/dispersionpistol.zsc b/zscript/dispersionpistol.zsc index b8ee66f..76dc1a4 100644 --- a/zscript/dispersionpistol.zsc +++ b/zscript/dispersionpistol.zsc @@ -323,7 +323,7 @@ Class DispersionAmmo : Actor action void A_DispExpl() { 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); Spawn(invoker.LightClass,pos); Actor a; @@ -344,6 +344,12 @@ Class DispersionAmmo : Actor UTMainHandler.DoBlast(self,80,6000); 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() { Super.PostBeginPlay(); @@ -542,7 +548,7 @@ Class DispersionPistol : UnrealWeapon A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true); 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); - 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); Vector3 x, y, z; [x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll); @@ -615,7 +621,7 @@ Class DispersionPistol : UnrealWeapon A_OverlayRenderstyle(PSP_FLASH,STYLE_Add); 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); - 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); A_QuakeEx(qs,qs,qs,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); Vector3 x, y, z; diff --git a/zscript/gatling.zsc b/zscript/gatling.zsc index 7773d4f..3aff990 100644 --- a/zscript/gatling.zsc +++ b/zscript/gatling.zsc @@ -250,6 +250,7 @@ Class SMiniGun : UnrealWeapon Weapon.AmmoGive 32; Inventory.RespawnTics 2100; +INVENTORY.IGNORESKILL; + +INVENTORY.ALWAYSPICKUP; UTWeapon.DropAmmo 4; } States diff --git a/zscript/miscitems.zsc b/zscript/miscitems.zsc index b6b73b9..424556e 100644 --- a/zscript/miscitems.zsc +++ b/zscript/miscitems.zsc @@ -1,90 +1,6 @@ // 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[i]); - if ( !type || (type.GetParentClass() != 'Ammo') ) continue; - // check that it's for a valid weapon - bool isvalid = false; - for ( int j=0; j)(AllActorClasses[j]); - if ( !type2 ) continue; - let rep = GetReplacement(type2); - if ( (rep != type2) && !(rep is "DehackedPickup") ) continue; - readonly 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 ) { 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 diff --git a/zscript/olsmp.zsc b/zscript/olsmp.zsc index d46d401..bb1615e 100644 --- a/zscript/olsmp.zsc +++ b/zscript/olsmp.zsc @@ -245,6 +245,7 @@ Class OLSMP : UnrealWeapon UTWeapon.DropAmmo 50; OLSMP.ClipCount 100; +UNREALWEAPON.NOFIRSTGIVE; + +INVENTORY.ALWAYSPICKUP; } States { @@ -337,7 +338,7 @@ Class OLSMP : UnrealWeapon invoker.clipout = true; A_Overlay(-9999,null); 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; AUTD ABCD 1; diff --git a/zscript/peacemaker.zsc b/zscript/peacemaker.zsc index c3ff864..a2df9bb 100644 --- a/zscript/peacemaker.zsc +++ b/zscript/peacemaker.zsc @@ -157,7 +157,7 @@ Class PeaceRocket : Actor States { Spawn: - PEAR A 1 + PEMR A 1 { roll += 5.; A_SeekTargets(); @@ -340,10 +340,10 @@ Class PeaceBarrel : Actor States { Spawn: - PEAM A -1; + PEMM A -1; Stop; Bounce: - PEAM A 0 + PEMM A 0 { if ( BlockingFloor ) A_AlignSelf(); else pitch = roll = 0; @@ -351,59 +351,59 @@ Class PeaceBarrel : Actor } Goto Spawn; Death: - PEAM A 1 A_CheckFloor(1); + PEMM A 1 A_CheckFloor(1); Wait; - PEAM A 4 A_AlignSelf(); - PEAM A 35 + PEMM A 4 A_AlignSelf(); + PEMM A 35 { A_PlaySound((special1<=0)?"eightball/seeklost":"eightball/seeklock",CHAN_AUTO); A_AlertMonsters(); return A_JumpIf(--special1<0,1); } Wait; - PEAM A 0 A_JumpIf(bAMBUSH,"Detonate"); - PEAM A 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); - PEAM B 3; - PEAM 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)); - PEAM E 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); - PEAM F 3 + PEMM A 0 A_JumpIf(bAMBUSH,"Detonate"); + PEMM A 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); + PEMM B 3; + PEMM C 3 A_PlaySound("peace/open",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)); + PEMM E 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); + PEMM F 3 { 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)); } - PEAM G 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); - PEAM H 3 + PEMM G 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2)); + PEMM H 3 { 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)); } - PEAM I 3; - PEAM J 3 + PEMM I 3; + PEMM J 3 { 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)); } - PEAM 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)); - PEAM M 3; - PEAM N 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); - PEAM OPQ 3; - PEAM R 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); - PEAM STU 3; - PEAM V 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); - PEAM XYZ[\] 3; - PEAM ] 35; - PEAM ] 0 A_FireRocket(0); - PEAL A 20; - PEAL A 0 A_FireRocket(1); - PEAL B 20; - PEAL B 0 A_FireRocket(2); - PEAL C 20; - PEAL C 0 A_FireRocket(3); - PEAL D 20; + PEMM K 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); + PEMM L 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2)); + PEMM M 3; + PEMM N 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); + PEMM OPQ 3; + PEMM R 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); + PEMM STU 3; + PEMM V 3 A_PlaySound("eightball/rotate",CHAN_AUTO,.1); + PEMM XYZ[\] 3; + PEMM ] 35; + PEMM ] 0 A_FireRocket(0); + PEML A 20; + PEML A 0 A_FireRocket(1); + PEML B 20; + PEML B 0 A_FireRocket(2); + PEML C 20; + PEML C 0 A_FireRocket(3); + PEML D 20; Detonate: - PEAM A 20; + PEMM A 20; BlowUp: TNT1 A 0 A_BlowUp(); SSMX ABCDEFGHIJ 2 Bright; @@ -492,19 +492,19 @@ Class Peacemaker : UnrealWeapon States { Spawn: - PEAP A -1; + PEMP A -1; Stop; - PEAP B -1; + PEMP B -1; Stop; Select: - PEAS A 1 A_Raise(int.max); + PEMS A 1 A_Raise(int.max); Wait; Ready: - PEAS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE); - PEAS K 0 A_PlaySound("peace/up",CHAN_ITEM,.4); - PEAS KLMNOPQRST 2 A_WeaponReady(WRF_NOFIRE); + PEMS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE); + PEMS K 0 A_PlaySound("peace/up",CHAN_ITEM,.4); + PEMS KLMNOPQRST 2 A_WeaponReady(WRF_NOFIRE); Idle: - PEAI A 1 + PEMI A 1 { A_CheckReload(); A_WeaponReady(); @@ -522,45 +522,45 @@ Class Peacemaker : UnrealWeapon } Wait; Fire: - PEAC A 1 A_StartCount(); - PEAC # 1 A_CountUp(1); + PEMC A 1 A_StartCount(); + PEMC # 1 A_CountUp(1); Wait; - PEAF ABCD 2; - PEAF E 0 + PEMF ABCD 2; + PEMF E 0 { 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); } - PEAF EFG 2; - PEAF H 0 + PEMF EFG 2; + 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); } - PEAF HI 2; // hello - PEAF I -1 A_PeacemakerThrow(); + PEMF HI 2; // hello + PEMF I -1 A_PeacemakerThrow(); Stop; AltFire: - PEAC A 1 A_StartCount(); - PEAC # 1 A_CountUp(1); + PEMC A 1 A_StartCount(); + PEMC # 1 A_CountUp(1); Wait; - PEAF ABCD 2; - PEAF E 0 + PEMF ABCD 2; + PEMF E 0 { 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); } - PEAF EFG 2; - PEAF H 0 + PEMF EFG 2; + 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); } - PEAF HI 2; // howdy - PEAF I -1 A_PeacemakerThrow(true); + PEMF HI 2; // howdy + PEMF I -1 A_PeacemakerThrow(true); Stop; Deselect: - PEAD A 0 A_JumpIfNoAmmo("EmptyDeselect"); - PEAD ABCDEFGHI 1; - PEAD J 1 A_Lower(int.max); + PEMD A 0 A_JumpIfNoAmmo("EmptyDeselect"); + PEMD ABCDEFGHI 1; + PEMD J 1 A_Lower(int.max); EmptyDeselect: TNT1 A 1 A_Lower(int.max); Wait; diff --git a/zscript/stunner.zsc b/zscript/stunner.zsc index e2092a9..a7a583b 100644 --- a/zscript/stunner.zsc +++ b/zscript/stunner.zsc @@ -167,7 +167,7 @@ Class StunProj : Actor SetOrigin(t.Results.HitPos-t.Results.HitVector*4,false); StunExplode(); 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 ) { UTMainHandler.DoKnockback(a,t.Results.HitVector,(bAMBUSH?-22000:26000)*specialf1); @@ -208,10 +208,9 @@ Class StunProj : Actor { moving = false; 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_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)); int numpt = Random[ExploS](10,15); for ( int i=0; i= (d.HitActor.pos.z+d.HitActor.height*0.81) ) dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',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_OverlayRenderStyle(-2,STYLE_Add); 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() { @@ -416,7 +422,7 @@ Class Stunner : UnrealWeapon StunnerAmmo(weap.Ammo1).rechargephase = 0; 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); - if ( !Dampener.Active(self) ) A_AlertMonsters(); + if ( !Dampener.Active(self) && !(gameinfo.gametype&GAME_Strife) ) A_AlertMonsters(); if ( invoker.chargesize >= 5. ) { invoker.count += 1./35.; @@ -451,6 +457,7 @@ Class Stunner : UnrealWeapon Weapon.AmmoGive 50; UTWeapon.DropAmmo 50; +WEAPON.WIMPY_WEAPON; + +NOEXTREMEDEATH; } States { diff --git a/zscript/unrealcommon.zsc b/zscript/unrealcommon.zsc index c10f541..f018227 100644 --- a/zscript/unrealcommon.zsc +++ b/zscript/unrealcommon.zsc @@ -682,7 +682,8 @@ Class UnrealInventory : Inventory Super.AttachToOwner(other); if ( !Charge ) Charge = DefaultCharge; // 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 ) { @@ -950,6 +951,52 @@ Class UNothing : Actor } } +Class HexenEitherOrSession : Thinker +{ + Array > done; + + private bool IsAvailable( Class item ) + { + let ti = ThinkerIterator.Create(item); + Actor a; + while ( a = Actor(ti.Next()) ) return true; + for ( int i=0; i item ) + { + for ( int i=0; i item ) + { + for ( int i=0; i EitherOr( Class a, Class 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 { Array AmmoSlots; @@ -971,6 +1018,25 @@ Class UnrealMainHandler : EventHandler break; } } + private bool IsAvailable( Class item ) + { + let ti = ThinkerIterator.Create(item); + Actor a; + while ( a = Actor(ti.Next()) ) return true; + return false; + } + private Class EitherOr( Class a, Class 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 ) { if ( e.IsFinal ) return; @@ -1140,16 +1206,16 @@ Class UnrealMainHandler : EventHandler else if ( Random[Replacements](0,1) ) e.Replacement = 'UBioAmmo'; 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') ) { 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 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 == 'Megasphere' ) e.Replacement = 'ShieldBelt'; + else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiBoostArmor') ) e.Replacement = 'ShieldBelt'; else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') ) { 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 == 'Infrared') || (e.Replacee == 'ArtiTorch') ) e.Replacement = 'UFlashlight'; else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UJumpBoots'; - else if ( e.Replacee == 'ArtiFly' ) e.Replacement = 'UJumpBoots'; - else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') ) e.Replacement = 'UnrealBackpack'; - else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') ) + else if ( (e.Replacee == 'ArtiFly') || (e.Replacee == 'ArtiSpeedBoots') ) e.Replacement = 'UJumpBoots'; + else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') || (e.Replacee == 'ArtiHealingRadius') ) e.Replacement = 'UnrealBackpack'; + 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'; else e.Replacement = 'Flare'; } 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 == 'BlueArmor') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'UArmor'; + else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') || (e.Replacee == 'PlatinumHelm') ) e.Replacement = 'KevlarSuit'; + 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') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'UHealth'; @@ -1175,7 +1243,7 @@ Class UnrealMainHandler : EventHandler else e.Replacement = 'Seeds'; } 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 switch( Random[Replacements](0,sting_proto?7:5) ) @@ -1207,6 +1275,40 @@ Class UnrealMainHandler : EventHandler } } 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) else if ( e.Replacee is 'ImpactHammer' ) e.Replacement = 'DispersionPistol'; 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 'UTHealthBonus' ) e.Replacement = 'Bandages'; 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'; } diff --git a/zscript/unrealhud.zsc b/zscript/unrealhud.zsc index 8d623b2..8ae6f05 100644 --- a/zscript/unrealhud.zsc +++ b/zscript/unrealhud.zsc @@ -593,7 +593,39 @@ Class UnrealHUD : BaseStatusBar private void DrawKeys( double x, double y, bool leftright = false ) { 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 rows; + Array 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 5 ) return; // Draw frags in DM