diff --git a/GunLore.md b/GunLore.md index 2f740cf..1964ead 100644 --- a/GunLore.md +++ b/GunLore.md @@ -252,13 +252,13 @@ faster by putting in more than one shell at a time. Standard-issue "room clearing" device manufactured by the Inuit Corporation. -Primary fire: Deploy the device. Having landed on solid ground, it will open up -and release the rockets one by one after a set delay. +Primary fire: Deploy the device. Hold to increase the activation delay, up to +9 seconds. Having landed on solid ground, it will wait and then open up and +release the rockets one by one, after which it will self-destruct. Note that +these rockets will chase after anything that gets close, so keep your distance. -Secondary fire: Adjust the activation delay, up to 9 seconds. - -Note that these rockets will chase after anything that gets close, so keep your -distance. +Secondary fire: Same as before, but the device will instead self-destruct right +away, causing a much bigger boom. ## Impaler diff --git a/Readme.md b/Readme.md index 7a8e0b7..14f4694 100644 --- a/Readme.md +++ b/Readme.md @@ -33,6 +33,7 @@ Doom Tournament (currently the devel branch is required). - Protomag (slot 2) (replaces pistol) - Dual Protomags - Quadshot (slot 3) (replaces shotguns) + - Peacemaker (slot 8) (rare spawn in backpacks) - Backpack (replaces backpack, identical to Doom Tournament version) - Unreal 1 HUD - Translator (has to be spawned in, since it would only be useful for mappers) @@ -71,7 +72,6 @@ Doom Tournament (currently the devel branch is required). - Fireblaster (slot 5) (replaces rocket launcher) - Flamethrower (slot 6) (replaces plasma rifle) - Impaler (slot 7) (replaces plasma rifle) - - Peacemaker (slot 8) (rare spawn in backpacks) - Demolisher (slot 9) (replaces bfg9000) - Autocannon (slot 0) (replaces bfg9000) diff --git a/cvarinfo.txt b/cvarinfo.txt index 492ffc7..f21fbf9 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -87,3 +87,5 @@ server bool sting_bhold = false; // biorifle can be held fully loaded server bool sting_razoraim = false; // razorjack alt follows aim instead of // being steered by player rotation server bool sting_biosplash = false; // biorifle alt splashes like in ut +server bool sting_impalerauto = false; // impaler reloads automatically after + // primary fire diff --git a/graphics/UReticle.png b/graphics/UReticle.png index b53fce4..0ea43ac 100644 Binary files a/graphics/UReticle.png and b/graphics/UReticle.png differ diff --git a/language.txt b/language.txt index 42bc022..3c43af2 100644 --- a/language.txt +++ b/language.txt @@ -6,9 +6,12 @@ DAMNUM_TYPECOLOR_DAMMO3 = "DamYellow"; DAMNUM_TYPECOLOR_DAMMO4 = "DamOrange"; DAMNUM_TYPECOLOR_DAMMO5 = "DamRed"; DAMNUM_TYPECOLOR_STINGER = "DamTeal"; +DAMNUM_TYPECOLOR_TARYDIUMCHARGE = "DamTeal"; DAMNUM_TYPECOLOR_EXPLODED = "DamGold"; DAMNUM_TYPECOLOR_STUNNED = "DamLightBlue"; DAMNUM_TYPECOLOR_IMPALER = "DamMagenta"; +DAMNUM_TYPECOLOR_PEACEDEATH = "DamGold"; +DAMNUM_TYPECOLOR_PEACEBARRELDEATH = "DamGold"; /* Obituaries */ O_DPISTOL = "%o was killed by %k's Dispersion Pistol. What a loser!"; O_AUTOMAG = "%o got gatted by %k's Automag."; @@ -28,6 +31,7 @@ O_IMPALER1 = "%o had an explosive taste of %k's Impaler."; O_IMPALER2 = "%o was cooked alive by %k's Impaler."; O_IMPALERHIT = "%o was pierced by %k's Impaler."; O_PEACE = "%o was hunted down by %k's Peacemaker missiles."; +O_PEACEMK = "%o got too close to %k's Peacemaker launcher."; O_FLAMEGUN = "%o was charred by %k's Fireblaster."; O_FLAMETHROWER = "%o was thoroughly roasted by %k's Flamethrower."; O_BIGGUN = "%k blew a hole through %o with the Demolisher."; @@ -41,6 +45,8 @@ O_OWNOSENTRY = "%o took a bullet from %p own Light Sentry."; O_STINGERX = "%o ate flaming Tarydium death thanks to %k."; O_STINGERX2 = "%o ate flaming Tarydium death."; O_OLSMP = "%o didn't stand a chance against %k's SMP 7243."; +O_SPEACE = "%o got too close to a Peacemaker missile."; +O_SPEACEMK = "%o got too close to a Peacemaker launcher."; /* Pickup messages */ I_WPOWERUP = "You got a Dispersion Pistol Powerup."; I_STINGERAMMOL = "You picked up "; @@ -198,6 +204,8 @@ M_SENTRYDOWN = "Your Minigun Sentry has been destroyed."; M_SENTRYDRY = "Your Minigun Sentry has run out of ammo."; M_SENTRYHIJACK = "Your Minigun Sentry has been hijacked."; M_MSNOROOM = "No room to deploy Sentry."; +M_MSNOFLOOR = "Cannot deploy Sentry at this height."; +M_MSNOFLAT = "Cannot deploy Sentry on such a steep slope."; M_NSTOOFAR = "Cannot recall Sentry from this distance."; M_FFNOROOM = "No room to activate Force Field."; S_MINHUD = "Health %d Score %d Ammo %d"; @@ -276,6 +284,7 @@ O_IMPALER1 = "%o probó el sabor explosivo del Empalador de %k."; O_IMPALER2 = "%o fue cocinad@[ao_esp] viv@[ao_esp] por el Empalador de %k."; O_IMPALERHIT = "%o fue perforad@[ao_esp] por el Empalador de %k."; O_PEACE = "%o fue cazad@[ao_esp] por los misiles Peacemaker de %k."; +O_PEACEMK = "%o se acercó demasiado a la lanzadera Peacemaker de %k."; O_FLAMEGUN = "%o fue carbonizad@[ao_esp] por el Bláster de Fuego de %k."; O_FLAMETHROWER = "%o fue asad@[ao_esp] a conciencia por el Lanzallamas de %k."; O_BIGGUN = "%k abrió un hoyo a través de %o con el Demoledor."; @@ -289,6 +298,8 @@ O_OWNOSENTRY = "%o se llevó un tiro de su propi@[ao_esp] Torreta Ligera."; O_STINGERX = "%o tragó muerte ardiente de Tarydium gracias a %k."; O_STINGERX2 = "%o tragó muerte ardiente de Tarydium."; O_OLSMP = "%o no tenía ninguna oportunidad contra el SMP 7243 de %k."; +O_SPEACE = "%o se acercó demasiado a un misil Peacemaker."; +O_SPEACEMK = "%o se acercó demasiado a una lanzadera Peacemaker."; /* Pickup messages */ I_WPOWERUP = "Has obtenido una Mejora para la Pistola de Dispersión."; I_STINGERAMMOL = "Has recogido "; @@ -432,6 +443,8 @@ M_SENTRYDOWN = "Tu Torreta ha sido destruida."; M_SENTRYDRY = "Tu Torreta se ha quedado sin munición."; M_SENTRYHIJACK = "Tu Torreta ha sido hackeada."; M_MSNOROOM = "No hay espacio para colocar la Torreta."; +M_MSNOFLOOR = "No se puede colocar la Torreta a esta altura."; +M_MSNOFLAT = "No se puede colocar la Torreta en una cuesta tan inclinada."; M_NSTOOFAR = "No se puede retirar la Torreta desde esta distancia."; M_FFNOROOM = "No hay espacio para activar el Campo de Fuerza."; S_MINHUD = "Salud %d Puntuación %d Munición %d"; diff --git a/modeldef.peacemaker b/modeldef.peacemaker index 527a1f2..cb93ce7 100644 --- a/modeldef.peacemaker +++ b/modeldef.peacemaker @@ -1,3 +1,81 @@ +Model "Peacerocket" +{ + Path "models" + Model 0 "perock_d.3d" + SurfaceSkin 0 1 "Jpeace1.png" + PitchOffset -90 + Scale 0.16 0.192 0.16 + USEACTORPITCH + USEACTORROLL + + FrameIndex PEAR A 0 0 +} + +Model "PeaceFragment" +{ + Path "models" + Model 0 "sfrag_d.3d" + Skin 0 "Jpeace1.png" + Scale 0.1 0.1 0.12 + USEACTORPITCH + USEACTORROLL + + FrameIndex CHIP A 0 0 + FrameIndex CHIP B 0 1 + FrameIndex CHIP C 0 2 + FrameIndex CHIP D 0 3 + FrameIndex CHIP E 0 4 + FrameIndex CHIP F 0 5 +} + +Model "Peacebarrel" +{ + Path "models" + Model 0 "peace_d.3d" + Skin 0 "Jpeace1.png" + ZOffset 10 + AngleOffset -45 + Scale 0.16 -0.16 0.192 + USEACTORPITCH + 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 + // launch + FrameIndex PEAL A 0 29 + FrameIndex PEAL B 0 30 + FrameIndex PEAL C 0 31 + FrameIndex PEAL D 0 32 +} + Model "Peacemaker" { Path "models" @@ -5,7 +83,7 @@ Model "Peacemaker" Skin 1 "Jpeacehand1_.png" RollOffset 90 // normally upright, but it's easier to tell apart from a deployed one this way ZOffset 5 - Scale 0.16 0.192 0.16 + Scale 0.16 -0.192 0.16 FrameIndex PEAP B 1 0 @@ -13,3 +91,68 @@ Model "Peacemaker" ROTATING FrameIndex PEAP A 1 0 } + +Model "Peacemaker" +{ + Path "models" + Model 0 "peacehand_d.3d" + Skin 0 "Jpeacehand1.png" + AngleOffset -90 + Scale 0.1 -0.1 0.1 + 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 + // Idle + FrameIndex PEAI 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 + // 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 + // 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 +} diff --git a/models/AMuz1.png b/models/AMuz1.png index 0864a8c..e919e3f 100644 Binary files a/models/AMuz1.png and b/models/AMuz1.png differ diff --git a/models/AMuz2.png b/models/AMuz2.png index ac8ced6..f96cbc7 100644 Binary files a/models/AMuz2.png and b/models/AMuz2.png differ diff --git a/models/AMuz3.png b/models/AMuz3.png index 9c3dee5..acf29e5 100644 Binary files a/models/AMuz3.png and b/models/AMuz3.png differ diff --git a/models/AMuz4.png b/models/AMuz4.png index 41c1cde..c162937 100644 Binary files a/models/AMuz4.png and b/models/AMuz4.png differ diff --git a/models/AMuz5.png b/models/AMuz5.png index f633845..63cb89d 100644 Binary files a/models/AMuz5.png and b/models/AMuz5.png differ diff --git a/models/FireEffect54.png b/models/FireEffect54.png index d73bbee..8241f50 100644 Binary files a/models/FireEffect54.png and b/models/FireEffect54.png differ diff --git a/models/ForceF.png b/models/ForceF.png index c7b1779..ccd470e 100644 Binary files a/models/ForceF.png and b/models/ForceF.png differ diff --git a/models/Glass2.png b/models/Glass2.png index 94771cd..14d9086 100644 Binary files a/models/Glass2.png and b/models/Glass2.png differ diff --git a/models/Glass2_m.png b/models/Glass2_m.png index 6fd7960..8ae3da8 100644 Binary files a/models/Glass2_m.png and b/models/Glass2_m.png differ diff --git a/models/JBRifle1.png b/models/JBRifle1.png index 6099bad..8adca8d 100644 Binary files a/models/JBRifle1.png and b/models/JBRifle1.png differ diff --git a/models/JBRifle1_.png b/models/JBRifle1_.png index 6099bad..8adca8d 100644 Binary files a/models/JBRifle1_.png and b/models/JBRifle1_.png differ diff --git a/models/NyLeve_env.png b/models/NyLeve_env.png index 68a61e5..0bed28c 100644 Binary files a/models/NyLeve_env.png and b/models/NyLeve_env.png differ diff --git a/models/OldAutoMag_a.3d b/models/OldAutoMag_a.3d index b4bae33..49cfb4c 100644 Binary files a/models/OldAutoMag_a.3d and b/models/OldAutoMag_a.3d differ diff --git a/models/OldAutomag.blend b/models/OldAutomag.blend index 24f5ea5..6e926c2 100644 Binary files a/models/OldAutomag.blend and b/models/OldAutomag.blend differ diff --git a/models/UMuz1.png b/models/UMuz1.png index 39c3a68..f114ee5 100644 Binary files a/models/UMuz1.png and b/models/UMuz1.png differ diff --git a/models/UMuz2.png b/models/UMuz2.png index 9947997..a5985e0 100644 Binary files a/models/UMuz2.png and b/models/UMuz2.png differ diff --git a/models/UMuz3.png b/models/UMuz3.png index 04aba91..e3e1c0b 100644 Binary files a/models/UMuz3.png and b/models/UMuz3.png differ diff --git a/models/UMuz4.png b/models/UMuz4.png index 2f9bd86..8aac39d 100644 Binary files a/models/UMuz4.png and b/models/UMuz4.png differ diff --git a/models/UMuz5.png b/models/UMuz5.png index 246f33b..8f28dfe 100644 Binary files a/models/UMuz5.png and b/models/UMuz5.png differ diff --git a/models/UMuz6.png b/models/UMuz6.png index 709d3d4..76a20b8 100644 Binary files a/models/UMuz6.png and b/models/UMuz6.png differ diff --git a/models/UMuz7.png b/models/UMuz7.png index 180d9b7..f070fc1 100644 Binary files a/models/UMuz7.png and b/models/UMuz7.png differ diff --git a/models/UMuz8.png b/models/UMuz8.png index a292fa3..81b6852 100644 Binary files a/models/UMuz8.png and b/models/UMuz8.png differ diff --git a/models/UMuz9.png b/models/UMuz9.png index 58c415c..a95f2fb 100644 Binary files a/models/UMuz9.png and b/models/UMuz9.png differ diff --git a/models/peace_a.3d b/models/peace_a.3d index 41b4c03..03bd19c 100644 Binary files a/models/peace_a.3d and b/models/peace_a.3d differ diff --git a/models/peacehand_a.3d b/models/peacehand_a.3d index 4caea8e..74ff849 100644 Binary files a/models/peacehand_a.3d and b/models/peacehand_a.3d differ diff --git a/models/perock_a.3d b/models/perock_a.3d index 01b1dfc..c0c5f15 100644 Binary files a/models/perock_a.3d and b/models/perock_a.3d differ diff --git a/models/perock_d.3d b/models/perock_d.3d index 25feed5..b39bc18 100644 Binary files a/models/perock_d.3d and b/models/perock_d.3d differ diff --git a/sndinfo.txt b/sndinfo.txt index ec92e42..23fc870 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -255,6 +255,14 @@ betamag/slide oldmage betamag/whip oldawhip betamag/hit oldahit +peace/select peacesel +peace/up peaceup +peace/set peaceset +peace/down peacedn +peace/throw peacethr +peace/open peaceopn +peace/fly brufly1 + translator/event transa3 detector/start detact diff --git a/sounds/Brufly1.ogg b/sounds/Brufly1.ogg new file mode 100644 index 0000000..c5594bb Binary files /dev/null and b/sounds/Brufly1.ogg differ diff --git a/sounds/PeaceOpn.ogg b/sounds/PeaceOpn.ogg new file mode 100644 index 0000000..fbe2bfc Binary files /dev/null and b/sounds/PeaceOpn.ogg differ diff --git a/sounds/PeaceSel.ogg b/sounds/PeaceSel.ogg new file mode 100644 index 0000000..2234574 Binary files /dev/null and b/sounds/PeaceSel.ogg differ diff --git a/sounds/PeaceThr.ogg b/sounds/PeaceThr.ogg new file mode 100644 index 0000000..8039674 Binary files /dev/null and b/sounds/PeaceThr.ogg differ diff --git a/sprites/PFLAA0.png b/sprites/PFLAA0.png new file mode 100644 index 0000000..8512e51 Binary files /dev/null and b/sprites/PFLAA0.png differ diff --git a/zmapinfo.txt b/zmapinfo.txt index 93158d1..ce13447 100644 --- a/zmapinfo.txt +++ b/zmapinfo.txt @@ -28,3 +28,15 @@ DamageType TarydiumCharge // obituary for no instigator Obituary = "$O_STINGERX2" } + +DamageType PeaceDeath +{ + // obituary for no instigator + Obituary = "$O_SPEACE" +} + +DamageType PeaceBarrelDeath +{ + // obituary for no instigator + Obituary = "$O_SPEACEMK" +} diff --git a/zscript/miscitems.zsc b/zscript/miscitems.zsc index 5e35901..3abe7a6 100644 --- a/zscript/miscitems.zsc +++ b/zscript/miscitems.zsc @@ -1527,9 +1527,28 @@ Class SentryItem : UnrealInventory } Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz); FLineTraceData d; - Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); - if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*20; - else origin = d.HitLocation; + Owner.LineTrace(Owner.angle,80,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); + if ( d.HitType != TRACE_HitNone ) + { + Vector3 normal = -d.HitDir; + if ( d.HitType == TRACE_HitFloor ) + { + if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.top.Normal; + else normal = d.HitSector.floorplane.Normal; + } + else if ( d.HitType == TRACE_HitCeiling ) + { + if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.bottom.Normal; + else normal = d.HitSector.ceilingplane.Normal; + } + else if ( d.HitType == TRACE_HitWall ) + { + normal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit(); + if ( !d.LineSide ) normal *= -1; + } + origin = d.HitLocation+normal*20; + } + else origin = d.HitLocation-d.HitDir*20; Owner.LineTrace(0,56,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); origin = d.HitLocation; let a = Spawn("MinigunSentryBase",origin); @@ -1539,6 +1558,28 @@ Class SentryItem : UnrealInventory a.Destroy(); return false; } + if ( a.pos.z-a.floorz > 50 ) + { + if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLOOR")); + a.Destroy(); + return false; + } + F3DFloor ff = null; + for ( int i=0; i floorz ) continue; + ff = a.floorsector.Get3DFLoor(i); + break; + } + Vector3 normal; + if ( ff ) normal = -ff.top.Normal; + else normal = a.floorsector.floorplane.Normal; + if ( normal.z < 0.9 ) + { + if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLAT")); + a.Destroy(); + return false; + } bActive = true; bUNTOSSABLE = true; bUNDROPPABLE = true; @@ -2213,9 +2254,28 @@ Class SentryGunItem : UnrealInventory if ( pickup ) return false; Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz); FLineTraceData d; - Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); - if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*20; - else origin = d.HitLocation; + Owner.LineTrace(Owner.angle,60,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); + if ( d.HitType != TRACE_HitNone ) + { + Vector3 normal = -d.HitDir; + if ( d.HitType == TRACE_HitFloor ) + { + if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.top.Normal; + else normal = d.HitSector.floorplane.Normal; + } + else if ( d.HitType == TRACE_HitCeiling ) + { + if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.bottom.Normal; + else normal = d.HitSector.ceilingplane.Normal; + } + else if ( d.HitType == TRACE_HitWall ) + { + normal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit(); + if ( !d.LineSide ) normal *= -1; + } + origin = d.HitLocation+normal*20; + } + else origin = d.HitLocation-d.HitDir*20; Owner.LineTrace(0,56,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d); origin = d.HitLocation; let a = Spawn("SentryGun",origin); @@ -2225,6 +2285,28 @@ Class SentryGunItem : UnrealInventory a.Destroy(); return false; } + if ( a.pos.z-a.floorz > 50 ) + { + if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLOOR")); + a.Destroy(); + return false; + } + F3DFloor ff = null; + for ( int i=0; i floorz ) continue; + ff = a.floorsector.Get3DFLoor(i); + break; + } + Vector3 normal; + if ( ff ) normal = -ff.top.Normal; + else normal = a.floorsector.floorplane.Normal; + if ( normal.z < 0.9 ) + { + if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLAT")); + a.Destroy(); + return false; + } tracer = a; a.master = Owner; a.angle = Owner.angle; diff --git a/zscript/peacemaker.zsc b/zscript/peacemaker.zsc index 93c21f0..58e41f9 100644 --- a/zscript/peacemaker.zsc +++ b/zscript/peacemaker.zsc @@ -4,22 +4,434 @@ Class PeaceAmmo : Ammo { Inventory.Icon "I_Peace"; Inventory.Amount 1; - Inventory.MaxAmount 8; + Inventory.MaxAmount 1; Ammo.BackpackAmount 0; - Ammo.BackpackMaxAmount 16; + Ammo.BackpackMaxAmount 2; + } +} + +Class PeaceTrail : Actor +{ + Default + { + RenderStyle "Add"; + Radius 0.1; + Height 0; + +NOBLOCKMAP; + +NOGRAVITY; + +DONTSPLASH; + +FORCEXYBILLBOARD; + +NOTELEPORT; + Scale 0.25; + } + override void PostBeginPlay() + { + Super.PostBeginPlay(); + A_AttachLight('RocketLight',DynamicLight.PointLight,Color(255,128,112),32,32); + } + override void Tick() + { + Super.Tick(); + if ( !target || !target.bMISSILE ) + { + A_RemoveLight('RocketLight'); + Destroy(); + return; + } + Vector3 dir = (cos(target.angle)*cos(target.pitch),sin(target.angle)*cos(target.pitch),-sin(target.pitch)); + SetOrigin(level.Vec3Offset(target.pos,-dir*3),true); + } + States + { + Spawn: + PFLA A -1 Bright; + Stop; } } Class PeaceRocket : Actor { + Vector3 Acceleration; + int ticcnt; + Default + { + Obituary "$O_PEACE"; + DamageType 'PeaceDeath'; + Radius 2; + Height 2; + Speed 3.5; + PROJECTILE; + +SKYEXPLODE; + +EXPLODEONWATER; + +SEEKERMISSILE; + +FORCERADIUSDMG; + +NODAMAGETHRUST; + +INTERPOLATEANGLES; + +HITOWNER; + ReactionTime 9; + } + override void PostBeginPlay() + { + Super.PostBeginPlay(); + let l = Spawn("PeaceTrail",pos); + l.target = self; + A_PlaySound("peace/fly",CHAN_VOICE,1.0,true,2.5,pitch:0.8); + Acceleration = vel*1.67; + } + action void A_CheckForTargets() + { + let bi = BlockThingsIterator.Create(self,500); + while ( bi.Next() ) + { + if ( !bi.Thing || (!bi.Thing.bISMONSTER && !bi.Thing.player) || (bi.Thing.Health <= 0) || (Distance3D(bi.Thing) > 500) || !CheckSight(bi.Thing) ) continue; + tracer = bi.Thing; + return; + } + } + action void A_SeekTargets() + { + if ( !tracer || (tracer.Health <= 0) ) return; + double mag = vel.length(); + vel = mag*(level.Vec3Diff(pos,tracer.Vec3Offset(0,0,tracer.height/2)).unit()*mag*6./TICRATE+vel).unit(); + } + action void A_PeaceExplode() + { + bFORCEXYBILLBOARD = true; + A_SetRenderStyle(1.0,STYLE_Add); + A_SprayDecal("RocketBlast",50); + A_NoGravity(); + A_SetScale(1.1); + UTMainHandler.DoBlast(self,200,70000); + A_Explode(100,200); + A_QuakeEx(3,3,3,8,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollIntensity:0.2); + A_PlaySound("utrl/explode",CHAN_VOICE); + A_AlertMonsters(); + Spawn("RocketExplLight",pos); + int numpt = Random[Peace](15,30); + for ( int i=0; i 0. ) + { + Vector3 dir = vel/mag; + if ( mag > 16 ) vel = vel.unit()*16; + angle = atan2(dir.y,dir.x); + pitch = asin(-dir.z); + mag = Acceleration.length(); + Acceleration = dir*mag; + } + for ( int i=0; i<3; i++ ) + { + let s = Spawn("UTSmoke",pos); + s.vel = (FRandom[Peace](-0.2,0.2),FRandom[Peace](-0.2,0.2),FRandom[Peace](-0.2,0.2)); + s.vel += vel*0.1; + s.SetShade(Color(1,1,1)*Random[Peace](32,48)); + } + special1++; + if ( special1 > 35 ) + { + special1 = 0; + A_CheckForTargets(); + A_CountDown(); + } + } + Wait; + Death: + TNT1 A 0 A_PeaceExplode(); + SSMX ABCDEFGHIJ 2 Bright; + Stop; + } } -Class PeaceProj : Actor +Class PeaceFragment : SentryFragment { + Default + { + Scale 0.5; + } +} + +Class PeaceBarrel : Actor +{ + action void A_AlignSelf() + { + // find closest 3d floor for its normal + F3DFloor ff = null; + for ( int i=0; i 20 ) + { + invoker.special2++; + if ( invoker.special2 <= 9 ) + { + A_PlaySound("peace/set",CHAN_ITEM,.4); + player.FindPSprite(PSP_WEAPON).frame = invoker.special2; + } + invoker.special1 = 0; + } + if ( (invoker.special2 >= 10) || !(player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK)) ) + { + invoker.special2 = min(9,invoker.special2); + player.SetPSprite(PSP_WEAPON,invoker.FindState(next)); + } + } Default { Tag "$T_PEACE"; @@ -29,6 +441,8 @@ Class Peacemaker : UnrealWeapon Weapon.SelectionOrder 1; Weapon.AmmoType "PeaceAmmo"; Weapon.AmmoUse 1; + Weapon.AmmoType2 "PeaceAmmo"; + Weapon.AmmoUse2 1; Weapon.AmmoGive 1; UTWeapon.DropAmmo 1; } @@ -39,5 +453,73 @@ Class Peacemaker : UnrealWeapon Stop; PEAP B -1; Stop; + Select: + PEAS 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); + Idle: + PEAI A 1 + { + A_CheckReload(); + A_WeaponReady(); + } + Wait; + EmptyIdle: + TNT1 A 1 + { + let weap = Weapon(invoker); + if ( weap.Ammo1.Amount > 0 ) + return ResolveState("Ready"); + A_CheckReload(); + A_WeaponReady(WRF_NOFIRE); + return ResolveState(null); + } + Wait; + Fire: + PEAC A 1 A_StartCount(); + PEAC # 1 A_CountUp(1); + Wait; + PEAF ABCD 2; + PEAF 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 + { + 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(); + Stop; + AltFire: + PEAC A 1 A_StartCount(); + PEAC # 1 A_CountUp(1); + Wait; + PEAF ABCD 2; + PEAF 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 + { + 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); + Stop; + Deselect: + PEAD A 0 A_JumpIfNoAmmo("EmptyDeselect"); + PEAD ABCDEFGHI 1; + PEAD J 1 A_Lower(int.max); + EmptyDeselect: + TNT1 A 1 A_Lower(int.max); + Wait; } } diff --git a/zscript/unrealhud.zsc b/zscript/unrealhud.zsc index 213baa3..5ea3a8a 100644 --- a/zscript/unrealhud.zsc +++ b/zscript/unrealhud.zsc @@ -345,6 +345,7 @@ Class UnrealHUD : BaseStatusBar for ( int j=0; j