1.0 release. Requires 4.2.3 or higher.

- Migrated screen projection code to libeye.
- Some pickups emit light, like in Doomreal.
- Backported map revealer item from Doomreal.
- Brand new Invulnerability and Night Vision powerups.
- Add option to allow Shield Belt and armors simultaneously.
- Backported armor bonus model from Doomreal.
- Added Dual Enforcers icon for HUD.
- Changed player class names to their character names, like in Doomreal.
- Terrain splashes.
- Translocator doesn't telefrag other players in coop.
- Reduced view shake from Impact Hammer.
- Various other updates and bug fixes.
This commit is contained in:
Marisa the Magician 2019-10-21 21:57:35 +02:00
commit b79d29f071
91 changed files with 1994 additions and 511 deletions

View file

@ -3,7 +3,7 @@
What began as a test for importing UT vertex meshes has turned into an actual
full UT weapon and item mod.
This mod requires GZDoom g4.3pre-79-gbcef44051 or later.
This mod requires GZDoom 4.2.3 or later.
## Currently implemented
@ -55,46 +55,30 @@ This mod requires GZDoom g4.3pre-79-gbcef44051 or later.
- UT player classes
- Heretic compatibility
- Spanish localization
- UT gore system (toggleable)
- UT gore system (WIP, toggleable)
- Liquid splashes
- Original Invulnerability and Night Vision items
## In progress
- General polishing, bugfixing and rebalancing
- Add some more effects
- Lava/Slime footstep sounds?
- French, Italian and German localizations (I'll need help for these)
- N/A, this is the 1.0 release
## Ideas
## Planned
- Code cleanup / backporting of improvements from Doomreal
- Stop using A_Overlay instead of player.SetPSprite, this breaks stuff (and
is the reason the Enforcer does that lowering thing when reloading)
- Simplify certain fire loops (especially the minigun/biorifle)
- Add ####-based tweening to some weapon animations where needed
- Remember to flip the translocator model so people stop complaining
- Fancy titlemap like Doomreal
- Pickup lights like Doomreal
- Figure out some alternative invincibility item. Kinda like how I improvised
the backpack replacement
## Future plans
- Additional model optimization and cleanup (optional, not needed for 1.0)
- Trim out unused animations (this one is going to be very time-consuming)
- Add ammo counters to Pulsegun, Minigun, Flak Cannon and Rocket Launcher once
scripted textures are implemented
- Redo player models once GZDoom gets a well deserved model animation system
overhaul (mainly to clean up the current, messy implementation of this)
- Add weapon attachment support to player models when that is also added in
(at the moment all player models have an integrated placeholder weapon)
- Port some of my UT weapon mods (and maybe also some of my personal faves by
others, such as Psi Weapon Dreams)
- Hexen/Strife compatibility ???
- Relics?
- Stuff for 1.1
- Fancy titlemap like Doomreal.
- Touch up blood/gibbing features. At the moment, Nashgore is still a
superior alternative.
- Hexen/Strife compatibility ???
- Stuff for much later
- Add ammo counters to Pulsegun, Minigun, Flak Cannon and Rocket Launcher
once scripted textures are implemented
- Redo player models once GZDoom gets a well deserved model animation system
overhaul (mainly to clean up the current, messy implementation of this)
- Add weapon attachment support to player models when that is also added in
(at the moment all player models have an integrated placeholder weapon)
## Known bugs
- Translocator allows telefragging other players in coop (no idea if I can
even fix this)
- Biorifle sludge doesn't attach properly when it lands on the edge between
sectors. This is most noticeable with moving sectors and 3d floors.

BIN
brightmaps/JAllMap1_a00.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
brightmaps/JAllMap1_a01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
brightmaps/JAllMap1_a02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
brightmaps/JAllMap1_a03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,3 +1,5 @@
Models, textures and audio (C)1999 Epic Games.
Porting and adjustments by Marisa Kirisame.
Special thanks to KeksDose for libeye.

View file

@ -45,3 +45,4 @@ user float flak_flashstrength = 1.0; // strength of screen flashes
server bool flak_sawammo = false; // chainsaw uses fuel
user bool flak_zoomsound = false; // sniper rifle plays unused zoom sounds (annoying)
user bool flak_zoomshader = false; // sniper rifle has a scope shader
server bool flak_vanillaarmor = true; // shield belt removes body/thigh armors on pickup

View file

@ -1,3 +1,244 @@
// Lights
PulseLight "UTRedKeyLight"
{
Color 1.0 0.0 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
DontLightSelf 1
}
PulseLight "UTBlueKeyLight"
{
Color 0.0 0.0 1.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
DontLightSelf 1
}
PulseLight "UTGoldKeyLight"
{
Color 1.0 0.8 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
DontLightSelf 1
}
PulseLight "UTGreenKeyLight"
{
Color 0.0 1.0 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
DontLightSelf 1
}
Object "UTRedSkull"
{
Frame "USKL" { light "UTRedKeyLight" }
}
Object "UTBlueSkull"
{
Frame "USKL" { light "UTBlueKeyLight" }
}
Object "UTGoldSkull"
{
Frame "USKL" { light "UTGoldKeyLight" }
}
Object "UTRedKey"
{
Frame "UKEY" { light "UTRedKeyLight" }
}
Object "UTBlueKey"
{
Frame "UKEY" { light "UTBlueKeyLight" }
}
Object "UTGoldKey"
{
Frame "UKEY" { light "UTGoldKeyLight" }
}
Object "UTHereticYellowKey"
{
Frame "UKEY" { light "UTGoldKeyLight" }
}
Object "UTHereticGreenKey"
{
Frame "UKEY" { light "UTGreenKeyLight" }
}
Object "UTHereticBlueKey"
{
Frame "UKEY" { light "UTBlueKeyLight" }
}
PointLight SHOCKAMMOLIGHT
{
Color 0.0 0.2 0.8
Size 20
Offset 0 12 0
Attenuate 1
DontLightSelf 1
}
PointLight SHOCKAMMOLIGHT2
{
Color 0.0 0.1 0.3
Size 12
Offset 0 5 0
Attenuate 1
DontLightSelf 1
}
Object ShockAmmo
{
Frame "SHOA" { light "SHOCKAMMOLIGHT" }
}
Object ShockAmmo2
{
Frame "SHOA" { light "SHOCKAMMOLIGHT2" }
}
PointLight BIOAMMOLIGHT
{
Color 0.3 1.0 0.1
Size 12
Offset 3 4 0
Attenuate 1
DontLightSelf 1
}
PointLight BIOAMMOLIGHT2
{
Color 0.3 1.0 0.1
Size 9
Offset 2 3 0
Attenuate 1
DontLightSelf 1
}
Object BioAmmo
{
Frame "BIOA" { light "BIOAMMOLIGHT" }
}
Object BioAmmo2
{
Frame "BIOA" { light "BIOAMMOLIGHT2" }
}
PointLight PULSEAMMOLIGHT
{
Color 0.15 0.3 0.05
Size 12
Offset 0 4 0
Attenuate 1
DontLightSelf 1
}
Object PulseAmmo
{
Frame "PAMO" { light "PULSEAMMOLIGHT" }
}
PointLight HEALTHPACKLIGHT
{
Color 0.0 0.2 1.0
Size 40
Offset 12 12 0
Attenuate 1
DontLightSelf 1
}
Object UTHealthPack
{
Frame "HBOX" { light "HEALTHPACKLIGHT" }
}
Object ActHealthPack
{
Frame "HBOX" { light "HEALTHPACKLIGHT" }
}
PointLight HEALTHBOXLIGHT
{
Color 0.0 0.2 1.0
Size 30
Offset 0 12 0
Attenuate 1
DontLightSelf 1
}
Object UTHealthBox
{
Frame "HBOX" { light "HEALTHBOXLIGHT" }
}
Object ActHealthBox
{
Frame "HBOX" { light "HEALTHBOXLIGHT" }
}
PointLight MEDBOXLIGHT
{
Color 0.0 0.2 1.0
Size 20
Offset 0 12 0
Attenuate 1
DontLightSelf 1
}
Object UTMedBox
{
Frame "HBOX" { light "MEDBOXLIGHT" }
}
Object ActMedBox
{
Frame "HBOX" { light "MEDBOXLIGHT" }
}
PointLight HEALTHVIALLIGHT
{
Color 0.3 0.6 1.0
Size 20
Offset 0 12 0
Attenuate 1
DontLightSelf 1
}
Object UTHealthBonus
{
Frame "VIAL" { light "HEALTHVIALLIGHT" }
}
PointLight UTCOMPLIGHT
{
Color 0.3 1.0 0.2
Size 12
Offset 0 8 0
Attenuate 1
}
Object UTMapRevealer
{
Frame "TRNS" { light "UTCOMPLIGHT" }
}
PointLight UTINVISLIGHT
{
Color 0.3 0.3 0.32
Size 12
Offset 0 8 0
Attenuate 1
}
Object UTInvisibility
{
Frame "INVS" { light "UTINVISLIGHT" }
}
Object ActUTInvisibility
{
Frame "INVS" { light "UTINVISLIGHT" }
}
PointLight UTVISLIGHT
{
Color 0.3 0.5 0.8
Size 30
Offset 0 24 0
Attenuate 1
}
Object UTNightVision
{
Frame "UKEY" { light "UTVISLIGHT" }
}
Object ActUTNightVision
{
Frame "UKEY" { light "UTVISLIGHT" }
}
// Shaders / Brightmaps
HardwareShader Texture "models/Jgreen.png"
{
Shader "shaders/glsl/MeshEnviroMap.fp"
@ -462,16 +703,6 @@ HardwareShader Texture "invis31"
{
Shader "shaders/glsl/MeshEnviroMap.fp"
}
HardwareShader Texture "models/JTranslator1.png"
{
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JTranslator1.png"
}
HardwareShader Texture "models/JBigFlash1.png"
{
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JBigFlash1.png"
}
Brightmap Texture "models/Chunk_a00.png"
{
Map "brightmaps/Chunk_a00.png"
@ -528,74 +759,51 @@ HardwareShader Texture "models/jbarrel4.png"
{
Shader "shaders/glsl/AmbientGlow.fp"
}
PulseLight "UTRedKeyLight"
HardwareShader Texture "models/shield.png"
{
Color 1.0 0.0 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
Shader "shaders/glsl/AmbientGlow.fp"
}
PulseLight "UTBlueKeyLight"
HardwareShader Texture "models/JAllMap1_a00.png"
{
Color 0.0 0.0 1.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JAllMap1_a00.png"
}
PulseLight "UTGoldKeyLight"
HardwareShader Texture "models/JAllMap1_a01.png"
{
Color 1.0 0.8 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JAllMap1_a01.png"
}
PulseLight "UTGreenKeyLight"
HardwareShader Texture "models/JAllMap1_a02.png"
{
Color 0.0 1.0 0.0
Size 15
SecondarySize 20
Interval 2.0
Offset 0 16 0
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JAllMap1_a02.png"
}
Object "UTRedSkull"
HardwareShader Texture "models/JAllMap1_a03.png"
{
Frame "USKL" { light "UTRedKeyLight" }
Shader "shaders/glsl/AmbientGlow_Brightmapped.fp"
Texture "brighttex" "brightmaps/JAllMap1_a03.png"
}
Object "UTBlueSkull"
HardwareShader Texture "models/JAllMap2.png"
{
Frame "USKL" { light "UTBlueKeyLight" }
Shader "shaders/glsl/AmbientGlow.fp"
}
Object "UTGoldSkull"
HardwareShader Texture "models/JAllMap3.png"
{
Frame "USKL" { light "UTGoldKeyLight" }
Shader "shaders/glsl/AmbientGlow.fp"
}
Object "UTRedKey"
HardwareShader Texture "models/GOLD.png"
{
Frame "UKEY" { light "UTRedKeyLight" }
Shader "shaders/glsl/MeshEnviroMap_AmbientGlow.fp"
}
Object "UTBlueKey"
HardwareShader Texture "models/s_camera.png"
{
Frame "UKEY" { light "UTBlueKeyLight" }
Shader "shaders/glsl/AmbientGlow.fp"
}
Object "UTGoldKey"
HardwareShader Texture "models/Effect1.png"
{
Frame "UKEY" { light "UTGoldKeyLight" }
}
Object "UTHereticYellowKey"
{
Frame "UKEY" { light "UTGoldKeyLight" }
}
Object "UTHereticGreenKey"
{
Frame "UKEY" { light "UTGreenKeyLight" }
}
Object "UTHereticBlueKey"
{
Frame "UKEY" { light "UTBlueKeyLight" }
Shader "shaders/glsl/MeshEnviroMap_AmbientGlow.fp"
}
// PP shaders
HardwareShader PostProcess scene
{
Name "RedeemerView"
@ -603,6 +811,13 @@ HardwareShader PostProcess scene
Texture StaticTexture "textures/static1.png"
Uniform float Timer
}
HardwareShader PostProcess scene
{
Name "UTRifleScope"
Shader "shaders/glsl/UTRifleScope.fp" 330
}
// Skyboxes
SkyBox "KGDaySky" fliptop
{
"graphics/SkySetB_front.png"
@ -612,8 +827,3 @@ SkyBox "KGDaySky" fliptop
"graphics/SkySetB_up.png"
"graphics/SkySetB_down.png"
}
HardwareShader PostProcess scene
{
Name "UTRifleScope"
Shader "shaders/glsl/UTRifleScope.fp" 330
}

BIN
graphics/hud/IconAut2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
graphics/hud/ItemInvl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

BIN
graphics/hud/UseAut2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -87,6 +87,8 @@ I_TRANSLOCATOR = "You got the Translocator Source Module.";
I_WARHEADAMMO = "You picked up a Redeemer Missile.";
I_REDEEMER = "You got the Redeemer.";
I_CHAINSAWAMMO = "You picked up a Fuel Can.";
I_UTINVUL = "You have Invulnerability!";
I_UTVISION = "You have Night Vision.";
/* Tags */
T_ARMORBONUS = "Armor Bonus";
T_THIGHPADS = "Thigh Pads";
@ -142,17 +144,21 @@ T_TRANSLOCATOR = "Translocator";
T_WARHEADAMMO = "Redeemer Missile";
T_REDEEMER = "Redeemer";
T_CHAINSAWAMMO = "Chainsaw Fuel";
T_UTINVUL = "Invulnerability";
T_UTVISION = "Night Vision";
/* Miscellaneous */
D_SHIELDBELT = "The Shield Belt has depleted.";
D_UDAMAGE = "Damage Amplifier has worn off.";
D_INVISIBILITY = "Invisibility has worn off.";
D_JUMPBOOTS = "The AntiGrav Boots have drained.";
D_SEARCHLIGHT = "Searchlight batteries have died.";
N_TBOSS = "Boss";
N_TMALE1 = "Male Commando";
N_TMALE2 = "Male Soldier";
N_TFEMALE1 = "Female Commando";
N_TFEMALE2 = "Female Soldier";
D_UTINVUL = "Invulnerability has worn off.";
D_UTVISION = "Night Vision has worn off.";
N_TBOSS = "Xan";
N_TMALE1 = "Blake";
N_TMALE2 = "Brock";
N_TFEMALE1 = "Ivana";
N_TFEMALE2 = "Lauren";
M_SINGLEROCKETON = "Instant Rocket mode enabled";
M_SINGLEROCKETOFF = "Instant Rocket mode disabled";
M_CLIP = "Clip";
@ -162,6 +168,7 @@ M_NAME = "Name";
M_HEALTH = "Health";
M_NOAMMO = "%s has no ammo.";
M_NOAMMO2 = "%s have no ammo.";
M_ISELECT = "%s selected.";
/* Menus */
FLAK_BTOP1 = "Standard";
FLAK_BTOP2 = "Beta";
@ -186,7 +193,6 @@ FLAK_RECOIL = "Visual recoil";
FLAK_RSTRENGTH = "Visual recoil strength";
FLAK_IOPTS = "Item Options";
FLAK_RADBOOTS = "Jump Boots act like Radsuit";
FLAK_DMSSHOCK = "Allow Enhanced Shock Rifle in DM";
FLAK_TOPTS = "Translocator Options";
FLAK_TLOCBOSS = "Prevent boss telefrag";
FLAK_TLOCAMMO = "Translocator has ammo";
@ -221,6 +227,7 @@ FLAK_FSTRENGTH = "Screen flash strength";
FLAK_SAWAMMO = "Chainsaw uses ammo";
FLAK_ZSHADER = "Sniper scope shader";
FLAK_ZOOMSND = "Enable zoom sounds";
FLAK_VARMOR = "Shield Belt removes Armor";
FLAK_TAUNTS = "Taunts";
FLAK_TAUNT1 = "Victory 1";
FLAK_TAUNT2 = "Victory 2";
@ -312,6 +319,8 @@ I_TRANSLOCATOR = "Has conseguido el Módulo Fuente del Translocalizador.";
I_WARHEADAMMO = "Has recogido un Misil de Redentor.";
I_REDEEMER = "Has obtenido el Redentor.";
I_CHAINSAWAMMO = "Has recogido una Lata de Combustible.";
I_UTINVUL = "Tienes la Invulnerabilidad!";
I_UTVISION = "Tienes la Visión Nocturna.";
/* Tags */
T_ARMORBONUS = "Armadura Extra";
T_THIGHPADS = "Musleras";
@ -367,17 +376,16 @@ T_TRANSLOCATOR = "Translocalizador";
T_WARHEADAMMO = "Misil de Redentor";
T_REDEEMER = "Redentor";
T_CHAINSAWAMMO = "Combustible de Motosierra";
T_UTINVUL = "Invulnerabilidad";
T_UTVISION = "Visión Nocturna";
/* Miscellaneous */
D_SHIELDBELT = "El Cinturón Protector se ha agotado.";
D_UDAMAGE = "El Amplificador de Daño ha desaparecido.";
D_INVISIBILITY = "La Invisibilidad ha desaparecido.";
D_JUMPBOOTS = "Las Botas Antigravedad se han agotado.";
D_SEARCHLIGHT = "Las pilas del Faro se han agotado.";
N_TBOSS = "Jefe";
N_TMALE1 = "Comando Hombre";
N_TMALE2 = "Soldado Hombre";
N_TFEMALE1 = "Comando Mujer";
N_TFEMALE2 = "Soldado Mujer";
D_UTINVUL = "La Invulnerabilidad ha desaparecido.";
D_UTVISION = "La Visión Nocturna ha desaparecido.";
M_SINGLEROCKETON = "Modo de Cohetes Instantáneos activado";
M_SINGLEROCKETOFF = "Modo de Cohetes Instantáneos desactivado";
M_CLIP = "Cargador";
@ -387,6 +395,7 @@ M_NAME = "Nombre";
M_HEALTH = "Salud";
M_NOAMMO = "%s no tiene munición.";
M_NOAMMO2 = "%s no tienen munición.";
M_ISELECT = "Seleccionado %s.";
/* Menus */
FLAK_BTOP1 = "Estándar";
FLAK_BTOP2 = "Beta";
@ -411,7 +420,6 @@ FLAK_RECOIL = "Retroceso visual";
FLAK_RSTRENGTH = "Potencia de retroceso visual";
FLAK_IOPTS = "Opciones de Inventario";
FLAK_RADBOOTS = "Botas Antigrav. funcionan como Traje Antirradiación";
FLAK_DMSSHOCK = "Permitir Rifle de Choque Mejorado en DM";
FLAK_TOPTS = "Opciones de Translocalizador";
FLAK_TLOCBOSS = "Evitar telecarga a jefes";
FLAK_TLOCAMMO = "Translocalizador con munición";
@ -446,6 +454,7 @@ FLAK_FSTRENGTH = "Intensidad de destellos en pantalla";
FLAK_SAWAMMO = "La motosierra usa combustible";
FLAK_ZSHADER = "Shader de mira de Rifle de Francotirador";
FLAK_ZOOMSND = "Habilitar sonidos de zoom";
FLAK_VARMOR = "El Cinturón Protector quita la Armadura";
FLAK_TAUNTS = "Provocaciones";
FLAK_TAUNT1 = "Victoria 1";
FLAK_TAUNT2 = "Victoria 2";

View file

@ -36,7 +36,7 @@ OptionMenu "UTOptionMenu"
StaticText " "
StaticText "$FLAK_IOPTS", "Gold"
Option "$FLAK_RADBOOTS", "flak_radboots", "YesNo"
Option "$FLAK_DMSSHOCK", "flak_dmsshock", "YesNo"
Option "$FLAK_VARMOR", "flak_vanillaarmor", "YesNo"
StaticText " "
StaticText "$FLAK_TOPTS", "Gold"
Option "$FLAK_TLOCBOSS", "flak_nobosstelefrag", "YesNo"
@ -101,7 +101,7 @@ OptionMenu "UTCreditsMenu"
StaticText "Zard1084, Jonathan Nemo, NekoMithos, 3d0xp0xy", "White"
StaticText " "
StaticText "$FLAK_CTHANK", "Gold"
StaticText "KynikossDragonn", "White"
StaticText "KynikossDragonn, Raffine52, KeksDose", "White"
StaticText " "
StaticText "$FLAK_CUT", "Red"
StaticText " "

View file

@ -143,12 +143,10 @@ Model "UTHealthBonus"
Model "UTArmorBonus"
{
Path "models"
Model 0 "bossheadm_d.3d"
Skin 0 "bossheadT.png"
Scale 0.06 0.06 0.072
AngleOffset -90
RollOffset 12
ZOffset 5.5
Model 0 "ubonus_d.3d"
Skin 0 "shield.png"
Scale 0.08 -0.08 0.096
AngleOffset 90
FrameIndex XANH A 0 0
}
@ -188,18 +186,6 @@ Model "UTShieldBelt"
FrameIndex BELT A 0 0
}
Model "ActShieldBelt"
{
Path "models"
Model 0 "ShieldBeltMeshM_d.3d"
Skin 0 "AUbelt1.png"
Scale 0.1 0.1 0.12
AngleOffset -90
ZOffset 4
FrameIndex BELT A 0 0
}
Model "UDamage"
{
Path "models"
@ -364,7 +350,7 @@ Model "UTInvisibilityX"
FrameIndex INVS A 0 0
}
Model "ActInvisibility"
Model "ActUTInvisibility"
{
Path "models"
Model 0 "invis2M_d.3d"
@ -379,12 +365,21 @@ Model "ActInvisibility"
Model "UTMapRevealer"
{
Path "models"
Model 0 "TranslatorMesh_d.3d"
Skin 0 "JTranslator1.png"
Scale 0.08 0.08 0.096
ZOffset 4
Model 0 "cheapcomp_d.3d"
SurfaceSkin 0 1 "JAllMap2.png"
SurfaceSkin 0 2 "JAllMap3.png"
Scale 0.04 0.04 0.048
ZOffset 3
AngleOffset 90
SurfaceSkin 0 0 "JAllMap1_a00.png"
FrameIndex TRNS A 0 0
SurfaceSkin 0 0 "JAllMap1_a01.png"
FrameIndex TRNS B 0 0
SurfaceSkin 0 0 "JAllMap1_a02.png"
FrameIndex TRNS C 0 0
SurfaceSkin 0 0 "JAllMap1_a03.png"
FrameIndex TRNS D 0 0
}
Model "UTJumpBoots"
@ -409,30 +404,6 @@ Model "ActJumpBoots"
FrameIndex JBUT A 0 0
}
Model "Searchlight"
{
Path "models"
Model 0 "BigFlash_d.3d"
Skin 0 "JBigFlash1.png"
Scale 0.07 0.07 0.084
AngleOffset -90
ZOffset 9
FrameIndex SLIT A 0 0
}
Model "ActSearchlight"
{
Path "models"
Model 0 "BigFlash_d.3d"
Skin 0 "JBigFlash1.png"
Scale 0.07 0.07 0.084
AngleOffset -90
ZOffset 9
FrameIndex SLIT A 0 0
}
Model "UTChip"
{
Path "models"
@ -450,3 +421,457 @@ Model "UTChip"
FrameIndex CHIP C 0 2
FrameIndex CHIP D 0 3
}
Model "UTInvulnerability"
{
Path "models"
Model 0 "U_d.3d"
Skin 0 "GOLD.png"
Scale 0.15 0.15 0.18
ZOffset 24
ROTATING
FrameIndex UKEY A 0 0
}
Model "ActUTInvulnerability"
{
Path "models"
Model 0 "U_d.3d"
Skin 0 "GOLD.png"
Scale 0.15 0.15 0.18
ZOffset 24
ROTATING
FrameIndex UKEY A 0 0
}
Model "UTNightVision"
{
Path "models"
Model 0 "VisionM_d.3d"
SurfaceSkin 0 0 "s_camera.png"
Scale 0.15 0.15 0.18
ZOffset 24
ROTATING
FrameIndex UKEY A 0 0
}
Model "ActUTNightVision"
{
Path "models"
Model 0 "VisionM_d.3d"
SurfaceSkin 0 0 "s_camera.png"
Scale 0.15 0.15 0.18
ZOffset 24
ROTATING
FrameIndex UKEY A 0 0
}
Model "UTNightVisionX"
{
Path "models"
Model 0 "VisionM_d.3d"
SurfaceSkin 0 1 "Effect1.png"
Scale 0.15 0.15 0.18
ZOffset 24
ROTATING
DONTCULLBACKFACES
FrameIndex UKEY A 0 0
}
Model "WaterRing"
{
Path "models"
Model 0 "RingEx_d.3d"
Skin 0 "WetRing.png"
Scale 1.0 1.0 1.2
ZOffset 1
DONTCULLBACKFACES
USEACTORPITCH
USEACTORROLL
FrameIndex RNGX A 0 0
FrameIndex RNGX B 0 1
FrameIndex RNGX C 0 2
FrameIndex RNGX D 0 3
FrameIndex RNGX E 0 4
FrameIndex RNGX F 0 5
}
Model "UTWaterSplash"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_water.png"
Scale 0.16 0.16 0.192
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTWaterSplish"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_water.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTBloodSplash"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_blood.png"
Scale 0.16 0.16 0.192
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTBloodSplish"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_blood.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTSlimeSplash"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_sludge.png"
Scale 0.16 0.16 0.192
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTSlimeSplish"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_sludge.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTNukageSplash"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_nukage.png"
Scale 0.16 0.16 0.192
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTNukageSplish"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_nukage.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTLavaSplash"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_lava.png"
Scale 0.16 0.16 0.192
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}
Model "UTLavaSplish"
{
Path "models"
Model 0 "WaterImpactM_d.3d"
Skin 0 "splash_lava.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
FrameIndex SPSH A 0 1
FrameIndex SPSH B 0 2
FrameIndex SPSH C 0 3
FrameIndex SPSH D 0 4
FrameIndex SPSH E 0 5
FrameIndex SPSH F 0 6
FrameIndex SPSH G 0 7
FrameIndex SPSH H 0 8
FrameIndex SPSH I 0 9
FrameIndex SPSH J 0 10
FrameIndex SPSH K 0 11
FrameIndex SPSH L 0 12
FrameIndex SPSH M 0 13
FrameIndex SPSH N 0 14
FrameIndex SPSH O 0 15
FrameIndex SPSH P 0 16
FrameIndex SPSH Q 0 17
FrameIndex SPSH R 0 18
FrameIndex SPSH S 0 19
FrameIndex SPSH T 0 20
FrameIndex SPSH U 0 21
FrameIndex SPSH V 0 22
FrameIndex SPSH W 0 23
FrameIndex SPSH X 0 24
FrameIndex SPSH Y 0 25
FrameIndex SPSH Z 0 26
}

Binary file not shown.

Binary file not shown.

BIN
models/CheapComp_a.3d Normal file

Binary file not shown.

BIN
models/CheapComp_d.3d Normal file

Binary file not shown.

BIN
models/Effect1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
models/GOLD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
models/JAllMap1_a00.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
models/JAllMap1_a01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
models/JAllMap1_a02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
models/JAllMap1_a03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
models/JAllMap2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
models/JAllMap3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

BIN
models/Ringex_a.3d Normal file

Binary file not shown.

BIN
models/Ringex_d.3d Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
models/U_a.3d Normal file

Binary file not shown.

BIN
models/U_d.3d Normal file

Binary file not shown.

BIN
models/VisionM_a.3d Normal file

Binary file not shown.

BIN
models/VisionM_d.3d Normal file

Binary file not shown.

BIN
models/WaterImpactM_a.3d Normal file

Binary file not shown.

BIN
models/WaterImpactM_d.3d Normal file

Binary file not shown.

BIN
models/WetRing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
models/s_camera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

BIN
models/shield.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
models/splash_blood.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
models/splash_lava.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
models/splash_nukage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
models/splash_sludge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
models/splash_water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
models/ubonus_a.3d Normal file

Binary file not shown.

BIN
models/ubonus_d.3d Normal file

Binary file not shown.

View file

@ -182,6 +182,7 @@ ut/playerfootsteplava dslava1
ut/lavasplash goopj1
ut/lavasurface goope1
ut/underlava ulava1
ut/lavaex expl04
ut/playerfootstepnitro lsplash
ut/nitrosplash dsplash
@ -192,7 +193,7 @@ ut/undernitro ulnitro1
misc/secret capsound
misc/i_pkup ammopick
misc/k_pkup ammosnd
misc/k_pkup cntrlsnd
misc/w_pkup weaponpk
misc/p_pkup genpicks
misc/spawn respsnd2
@ -204,6 +205,7 @@ misc/ut_heal uthealth
$volume misc/ut_heal 0.7 // a bit too loud otherwise
misc/ut_shard shardpck
misc/ut_armor armorut
misc/hud_sel swclick
belt/pickup beltsnd
belt/absorb sbelthe2
boot/pickup bootsnd
@ -213,8 +215,6 @@ udamage/pickup amppckup
udamage/fire1 ampfire
udamage/fire2 ampfire2
udamage/drain ampout
trans/pickup voicesnd
lite/pickup fshlite1
misc/gibbed1 gib1
misc/gibbed2 gib2
misc/gibbed3 gib3
@ -341,3 +341,9 @@ testamb/lava lava31
testamb/water trickle1
testamb/wind1 wind21
testamb/wind2 wind23
uinvul/pickup invlpick
uinvul/hit invlhit
uinvul/drain invlout
uvision/pickup visions

BIN
sounds/CntrlSnd.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sounds/InvlHit.ogg Normal file

Binary file not shown.

BIN
sounds/InvlOut.ogg Normal file

Binary file not shown.

BIN
sounds/InvlPick.ogg Normal file

Binary file not shown.

BIN
sounds/SWClick.ogg Normal file

Binary file not shown.

BIN
sounds/VisionS.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sprites/FEXPA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
sprites/FEXPB0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
sprites/FEXPC0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
sprites/FEXPD0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
sprites/FEXPE0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
sprites/FEXPF0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
sprites/FEXPG0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
sprites/FEXPH0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
sprites/FEXPI0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sprites/FEXPJ0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -20,3 +20,4 @@ Sprite "SLITA0",1,1{}
Sprite "CHIPA0",1,1{}
Sprite "USKLA0",1,1{}
Sprite "UKEYA0",1,1{}
Sprite "RNGXA0",1,1{}

View file

@ -1,6 +1,9 @@
version "4.3"
version "4.2.2"
#include "zscript/dt_matrix.zsc"
#include "zscript/dt_libeye/projector.txt"
#include "zscript/dt_libeye/projector gl.txt"
#include "zscript/dt_libeye/projector planar.txt"
#include "zscript/dt_libeye/viewport.txt"
#include "zscript/dt_coordutil.zsc"
#include "zscript/dt_quaternion.zsc"
#include "zscript/utgore.zsc"

View file

@ -1,8 +1,9 @@
Class UTArmor : Armor
{
int absorb;
int absorb, priority;
Property ArmorAbsorption : absorb;
Property AbsorptionPriority : priority;
Default
{
@ -11,6 +12,23 @@ Class UTArmor : Armor
+INVENTORY.KEEPDEPLETED;
+INVENTORY.ALWAYSPICKUP;
}
override void AttachToOwner( Actor other )
{
Super.AttachToOwner(other);
// find last armor that's better than us
Inventory found = null;
for ( Inventory i=other.Inv; i; i=i.Inv )
{
if ( !(i is 'UTArmor') || (i == self) || (UTArmor(i).priority < priority) ) continue;
found = i;
}
if ( !found ) return;
// place ourselves right after it
Inventory saved = found.Inv;
found.Inv = self;
other.Inv = Inv;
Inv = saved;
}
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
{
int saved;
@ -48,6 +66,7 @@ Class UTArmorBonus : UTArmor
Inventory.MaxAmount 50;
Inventory.InterHubAmount 50;
UTArmor.ArmorAbsorption 25;
UTArmor.AbsorptionPriority 1;
Inventory.PickupMessage "$I_ARMORBONUS";
Inventory.PickupSound "misc/ut_shard";
}
@ -63,7 +82,7 @@ Class UTThighPads : UTArmor
{
override bool HandlePickup( Inventory item )
{
if ( item is 'UTThighPads' )
if ( flak_vanillaarmor && (item is 'UTThighPads') )
{
let s = Owner.FindInventory("UTShieldBelt");
if ( s )
@ -87,6 +106,7 @@ Class UTThighPads : UTArmor
Inventory.MaxAmount 50;
Inventory.InterHubAmount 50;
UTArmor.ArmorAbsorption 50;
UTArmor.AbsorptionPriority 7;
Inventory.PickupMessage "$I_THIGHPADS";
Inventory.PickupSound "misc/ut_armor";
}
@ -102,7 +122,7 @@ Class UTBodyArmor : UTArmor
{
override bool HandlePickup( Inventory item )
{
if ( item is 'UTBodyArmor' )
if ( flak_vanillaarmor && (item is 'UTBodyArmor') )
{
let s = Owner.FindInventory("UTShieldBelt");
if ( s )
@ -126,6 +146,7 @@ Class UTBodyArmor : UTArmor
Inventory.MaxAmount 100;
Inventory.InterHubAmount 100;
UTArmor.ArmorAbsorption 75;
UTArmor.AbsorptionPriority 7;
Inventory.PickupMessage "$I_BODYARMOR";
Inventory.PickupSound "misc/ut_armor";
}
@ -156,7 +177,7 @@ Class UTShieldBelt : UTArmor
}
override bool HandlePickup( Inventory item )
{
if ( (item is 'UTBodyArmor') || (item is 'UTThighPads') )
if ( flak_vanillaarmor && ((item is 'UTBodyArmor') || (item is 'UTThighPads')) )
{
// sum up current amounts
let a = Owner.FindInventory("UTBodyArmor");
@ -177,8 +198,11 @@ Class UTShieldBelt : UTArmor
override bool Use( bool pickup )
{
// removes thigh pads and body armor like in UT
Owner.TakeInventory("UTThighPads",50);
Owner.TakeInventory("UTBodyArmor",150);
if ( flak_vanillaarmor )
{
Owner.TakeInventory("UTThighPads",50);
Owner.TakeInventory("UTBodyArmor",150);
}
return false;
}
Default
@ -190,6 +214,7 @@ Class UTShieldBelt : UTArmor
Inventory.MaxAmount 150;
Inventory.InterHubAmount 150;
UTArmor.ArmorAbsorption 100;
UTArmor.AbsorptionPriority 10;
Inventory.PickupMessage "$I_SHIELDBELT";
Inventory.PickupSound "belt/pickup";
Inventory.RespawnTics 2100;

View file

@ -95,28 +95,27 @@ Class ActUDamage : UTActivatable
}
}
Class ActShieldBelt : UTActivatable
Class ActUTInvulnerability : UTActivatable
{
Default
{
Tag "$T_SHIELDBELT";
Inventory.Icon "ItemBelt";
Inventory.PickupMessage "$I_SHIELDBELT";
Tag "$T_UTINVUL";
Inventory.Icon "ItemInvl";
Inventory.PickupMessage "$I_UTINVUL";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+INVENTORY.ISARMOR;
UTActivatable.GiveItem "UTShieldBelt";
Inventory.RespawnTics 2100;
UTActivatable.GiveItem "UTInvulnerability";
Inventory.RespawnTics 4200;
}
States
{
Spawn:
BELT A -1;
UKEY A -1;
Stop;
}
}
Class ActInvisibility : UTActivatable
Class ActUTInvisibility : UTActivatable
{
Default
{
@ -143,6 +142,33 @@ Class ActInvisibility : UTActivatable
}
}
Class ActUTNightVision : UTActivatable
{
Default
{
Tag "$T_UTVISION";
Inventory.Icon "ItemLite";
Inventory.PickupMessage "$I_UTVISION";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
UTActivatable.GiveItem "UTNightVision";
Inventory.RespawnTics 4200;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("UTNightVisionX",pos);
tracer.angle = angle;
tracer.target = self;
}
States
{
Spawn:
UKEY A -1;
Stop;
}
}
Class ActJumpBoots : UTActivatable
{
Default
@ -161,25 +187,6 @@ Class ActJumpBoots : UTActivatable
}
}
Class ActSearchlight : UTActivatable
{
Default
{
Tag "$T_SEARCHLIGHT";
Inventory.Icon "ItemLite";
Inventory.PickupMessage "$I_SEARCHLIGHT";
+COUNTITEM;
UTActivatable.GiveItem "Searchlight";
Inventory.RespawnTics 1050;
}
States
{
Spawn:
SLIT A -1;
Stop;
}
}
// These have to be subclassed from HealthPickup for auto-use
Class UTActivatableHealth : HealthPickup
{

View file

@ -7,69 +7,6 @@
Class dt_CoordUtil
{
// projects a world point onto screen
// view matrix setup mostly pulled from gutawer's code
static Vector3 WorldToScreen( Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov )
{
double ar = Screen.getWidth()/double(Screen.getHeight());
double fovr = (ar>=1.3)?1.333333:ar;
double fov = 2*atan(tan(clamp(vfov,5,170)*0.5)/fovr);
float pr = level.pixelstretch;
double angx = cos(pitch);
double angy = sin(pitch)*pr;
double alen = sqrt(angx*angx+angy*angy);
double apitch = asin(angy/alen);
double ayaw = yaw-90;
// rotations
dt_Matrix4 mRoll = dt_Matrix4.rotate((0,0,1),roll);
dt_Matrix4 mPitch = dt_Matrix4.rotate((1,0,0),apitch);
dt_Matrix4 mYaw = dt_Matrix4.rotate((0,-1,0),ayaw);
// scaling
dt_Matrix4 mScale = dt_Matrix4.identity();
mScale.set(1,1,pr);
// YZ swap
dt_Matrix4 mYZ = dt_Matrix4.create();
mYZ.set(0,0,1);
mYZ.set(2,1,1);
mYZ.set(1,2,-1);
mYZ.set(3,3,1);
// translation
dt_Matrix4 mMove = dt_Matrix4.identity();
mMove.set(3,0,-eye.x);
mMove.set(3,1,-eye.y);
mMove.set(3,2,-eye.z);
// perspective
dt_Matrix4 mPerspective = dt_Matrix4.perspective(fov,ar,5,65535);
// full matrix
dt_Matrix4 mView = mRoll.mul(mPitch);
mView = mView.mul(mYaw);
mView = mView.mul(mScale);
mView = mView.mul(mYZ);
mView = mView.mul(mMove);
dt_Matrix4 mWorldToScreen = mPerspective.mul(mView);
return mWorldToScreen.vmat(vect);
}
// converts a projected screen position to 2D canvas coords
// thanks once again to gutawer for making this thing screenblocks-aware
// [NEW] added second return value: true if the point has valid depth (i.e.: it's not behind view)
// [TODO] handle forced aspect ratio (e.g.: 320x200 scaling)
static Vector2, bool ToViewport( Vector3 screenpos, bool scrblocks = true )
{
if ( scrblocks )
{
int winx, winy, winw, winh;
[winx,winy,winw,winh] = Screen.getViewWindow();
int sh = Screen.getHeight();
int ht = sh;
int screenblocks = CVar.GetCVar("screenblocks",players[consoleplayer]).getInt();
if ( screenblocks < 10 ) ht = (screenblocks*sh/10)&~7;
int bt = sh-(ht+winy-((ht-winh)/2));
return (winx,sh-bt-ht)+((screenpos.x+1)*winw,(-screenpos.y+1)*ht)*0.5, (screenpos.z<=1.0);
}
else return ((screenpos.x+1)*Screen.getWidth(),(-screenpos.y+1)*Screen.getHeight())*0.5, (screenpos.z<=1.0);
}
// In Tim Sweeney's own words: "transform by a pitch-yaw-roll rotation"
static Vector3, Vector3, Vector3 GetUnAxes( double pitch, double yaw, double roll )
{

View file

@ -0,0 +1,58 @@
libeye (for projection and deprojection)
written by KeksDose / MemeDose (May 2019)
(updated July 2019)
All rights etc. etc. who cares, you may reuse this as you wish and edit it, and
leave this note intact.
//
//
/////((
@@////////// ((
(( %////((///// (( (( ((
(( @@//(((/////// ((( ////////////// ((
( /////////////////////////(((((((////////// ((
@@///@@@@@@//////////(((((((((//@@@////////// ((
(( ///// /////((((((((((((((//@@% %%@/////////// ((
//////////((((((((((((((//////((((( %%@@////////// ((
((%%//////////@@%% @@//(((((((/// ( (((( %%///////// (
(( ////////@@ ((( @@//(((((((///// (( ( @@/////////
((/////////@ (( (( @@/(((((((///// (( (( @@/((((///((
(( ///((//@@ (( (( %@@@@@@////////// (((( /((((/// ((
((/////((//%%( ////%%%@@////////// @//((((///
////(((// ///////// //@@/////////////////(((((//
( ////(((////( //////////////////////@@@@////////////(((((////((
////(((((((// //////////////////////////// %%@@///(((((((((// (
//(((((((((/////////////////// //////////// %%@//(((((((//// ((
//(((((((((((////////////((/// /////////////// @@//(((((((///
//(((((((((((////////(( /////////((//////////// ( //(((((((///////
//((((((( ((///////( ##### ////( ((/////// ( @@//(((((///////
//((((((( (((//////((( ### (((( ##### ((/////// (( //(((///////@@
//((((((((((((@@/////////(((((((((((((((((((((///// ///////////% ((
//((((((((((((%% ///////((((((((((((//////// //////////////@@%% ((
@@//(((((((((/%%(( /////////////////////// ///////////////// (((
( //(((((((((/ (( ///////////////////////
%%//(((((((///(( (( //////////////@///////%%
(( @@/((((((///(( (( //////////////@@%% /////// ((
(( /(((((((// ( //////////////@%% //////%((
(( @@//(((////(( (( /////(((((((///@@ ((( /////// (
( @@(((((// ( ////(((((((///@@% (((( /////////%%((
((%%//(((/////////(((((((//@%% //////////%% ((
((////(((((///////(((((///////////////////////% ((
( ////(((((/////(((((((((//////////((((///@@%% ((
////(((//////@//////(((((((((((((////@@@%% (
(( /////////@@%% %%@@@@@@@@@@@@@@@@@@@%% ((
(( @@@@@%% ((
(( (((
%%//%
( //((/ ((
( ///////((
( ///////((
///// ((
//
//
(( ///// ((

View file

@ -0,0 +1,150 @@
/* kd:
In open-gl, your screen rotates nicely and you can do mostly what you know
to be sane. It's all about making a rotation of your view and using what
you know about right triangles.
*/
class dtLe_GlScreen : dtLe_ProjScreen {
protected vector3 forw_unit;
protected vector3 right_unit;
protected vector3 down_unit;
override void Reorient (vector3 world_view_pos, vector3 world_ang) {
// kd: Pitch is a weird gzd joke. It's probably to compensate looking
// speed and all. After that, you see what makes this fast.
world_ang.y = VectorAngle(
cos(world_ang.y),
sin(world_ang.y) * pixel_stretch);
super.Reorient(world_view_pos, world_ang);
let cosang = cos(world_ang.x);
let cosvang = cos(world_ang.y);
let cosrang = cos(world_ang.z);
let sinang = sin(world_ang.x);
let sinvang = sin(world_ang.y);
let sinrang = sin(world_ang.z);
let right_no_roll = (
sinang,
- cosang,
0);
let down_no_roll = (
- sinvang * cosang,
- sinvang * sinang,
- cosvang);
forw_unit = (
cosvang * cosang,
cosvang * sinang,
- sinvang);
down_unit = cosrang * down_no_roll - sinrang * right_no_roll;
right_unit = cosrang * right_no_roll + sinrang * down_no_roll;
}
// kd: Projection handling. These get called to make stuff a little faster,
// since you may wanna project many many times.
protected vector3 forw_in;
protected vector3 right_in;
protected vector3 down_in;
override void BeginProjection () {
forw_in = forw_unit;
right_in = right_unit / tan_fov_2.x;
down_in = down_unit / tan_fov_2.y;
forw_in.z *= pixel_stretch;
right_in.z *= pixel_stretch;
down_in.z *= pixel_stretch;
}
override void ProjectWorldPos (vector3 world_pos) {
diff = levellocals.vec3diff(view_pos, world_pos);
proj_pos = (diff dot right_in, diff dot down_in);
depth = diff dot forw_in;
}
override void ProjectActorPos (Actor mo, vector3 offset, double t) {
let inter_pos = mo.prev + t * (mo.pos - mo.prev);
diff = levellocals.vec3diff(view_pos, inter_pos + offset);
proj_pos = (diff dot right_in, diff dot down_in);
depth = diff dot forw_in;
}
override void ProjectActorPosPortal (Actor mo, vector3 offset, double t) {
let inter_pos = mo.prev + t * levellocals.vec3diff(mo.prev, mo.pos);
diff = levellocals.vec3diff(view_pos, inter_pos + offset);
proj_pos = (diff dot right_in, diff dot down_in);
depth = diff dot forw_in;
}
override vector2 ProjectToNormal () const {
return proj_pos / depth;
}
override vector2 ProjectToScreen () const {
let normal_pos = proj_pos / depth + (1, 1);
return 0.5 * (
normal_pos.x * resolution.x,
normal_pos.y * resolution.y);
}
override vector2 ProjectToCustom (
vector2 origin,
vector2 resolution) const {
let normal_pos = proj_pos / depth + (1, 1);
return origin + 0.5 * (
normal_pos.x * resolution.x,
normal_pos.y * resolution.y);
}
// kd: Same deal but backwards-ish.
protected vector3 forw_out;
protected vector3 right_out;
protected vector3 down_out;
override void BeginDeprojection () {
// kd: Same deal as above, but reversed. This time, we're compensating
// for what we rightfully assume is a projected position.
forw_out = forw_unit;
right_out = right_unit * tan_fov_2.x;
down_out = down_unit * tan_fov_2.y;
forw_out.z /= pixel_stretch;
right_out.z /= pixel_stretch;
down_out.z /= pixel_stretch;
}
override vector3 DeprojectNormalToDiff (
vector2 normal_pos,
double depth) const {
return depth * (
forw_out +
normal_pos.x * right_out +
normal_pos.y * down_out);
}
override vector3 DeprojectScreenToDiff (
vector2 screen_pos,
double depth) const {
// kd: Same thing...
let normal_pos = 2 * (
screen_pos.x / resolution.x,
screen_pos.y / resolution.y) - (1, 1);
return depth * (
forw_out +
normal_pos.x * right_out +
normal_pos.y * down_out);
}
}

View file

@ -0,0 +1,125 @@
/* kd:
This does projection stuff in Carmack / software renderer. It's conceptually
simpler, but nonetheless a little tricky to understand if you're
used to open-gl.
*/
class dtLe_SwScreen : dtLe_ProjScreen {
// kd: Less info necessary than for open-gl, but it's there.
protected vector2 right_planar_unit;
protected vector3 forw_planar_unit;
override void Reorient (vector3 world_view_pos, vector3 world_ang) {
super.Reorient(world_view_pos, world_ang);
right_planar_unit = (
sin(view_ang.x),
- cos(view_ang.x));
forw_planar_unit = (
- right_planar_unit.y,
right_planar_unit.x,
tan(view_ang.y));
}
// kd: Projection:
protected vector3 forw_planar_in;
protected vector2 right_planar_in;
override void BeginProjection () {
// kd: This doesn't cause any imprecisions. It also prevents two
// multiplications with every projection.
right_planar_in = right_planar_unit / tan_fov_2.x;
forw_planar_in = forw_planar_unit;
}
override void ProjectWorldPos (vector3 world_pos) {
// kd: Your view is flat. If you pitch up or down, imagine that all the
// actors move up and down in reality. That's effectively how it works.
// You can see this in the addition to diff.z.
diff = levellocals.vec3diff(view_pos, world_pos);
depth = forw_planar_in.xy dot diff.xy;
diff.z += forw_planar_in.z * depth;
proj_pos = (
right_planar_in dot diff.xy,
- pixel_stretch * diff.z / tan_fov_2.y);
}
override void ProjectActorPos (Actor mo, vector3 offset, double t) {
let inter_pos = mo.prev + t * (mo.pos - mo.prev);
ProjectWorldPos(inter_pos + offset);
}
override void ProjectActorPosPortal (Actor mo, vector3 offset, double t) {
let inter_pos = mo.prev + t * levellocals.vec3diff(mo.prev, mo.pos);
ProjectWorldPos(inter_pos + offset);
}
override vector2 ProjectToNormal () const {
return proj_pos / depth;
}
override vector2 ProjectToScreen () const {
let normal_pos = proj_pos / depth + (1, 1);
return 0.5 * (
normal_pos.x * resolution.x,
normal_pos.y * resolution.y);
}
override vector2 ProjectToCustom (
vector2 origin,
vector2 resolution) const {
let normal_pos = proj_pos / depth + (1, 1);
return origin + 0.5 * (
normal_pos.x * resolution.x,
normal_pos.y * resolution.y);
}
// kd: Just as simple. You again assume you are trying to reverse a
// projected position from the screen back into the world.
protected vector3 forw_planar_out;
protected vector3 right_planar_out;
protected vector3 down_planar_out;
override void BeginDeprojection () {
forw_planar_out.xy = forw_planar_unit.xy;
forw_planar_out.z = 0;
right_planar_out.xy = tan_fov_2.x * right_planar_unit;
right_planar_out.z = 0;
down_planar_out = (
0,
0,
tan_fov_2.y / pixel_stretch);
}
override vector3 DeprojectNormalToDiff (
vector2 normal_pos,
double depth) const {
return depth * (
forw_planar_out +
normal_pos.x * right_planar_out +
- (0, 0, forw_planar_unit.z) - normal_pos.y * down_planar_out);
}
override vector3 DeprojectScreenToDiff (
vector2 screen_pos,
double depth) const {
// kd: Same thing...
let normal_pos = 2 * (
screen_pos.x / resolution.x,
screen_pos.y / resolution.y) - (1, 1);
return depth * (
forw_planar_out +
normal_pos.x * right_planar_out +
- (0, 0, forw_planar_unit.z) - normal_pos.y * down_planar_out);
}
}

View file

@ -0,0 +1,193 @@
/* kd:
Here's how to do projections and deprojections. You'd use the subclasses
to do anything worthwhile. You may project world to screen and backwards.
*/
class dtLe_ProjScreen {
// kd: Screen info
protected vector2 resolution;
protected vector2 origin;
protected vector2 tan_fov_2;
protected double pixel_stretch;
protected double aspect_ratio;
// kd: Setup calls which you'll need to call at least once.
void CacheResolution () {
CacheCustomResolution((Screen.GetWidth(), Screen.GetHeight()) );
}
void CacheCustomResolution (vector2 new_resolution) {
// kd: This is for convenience and converting normal <-> screen pos.
resolution = new_resolution;
// kd: This isn't really necessary but I kinda like it.
pixel_stretch = level.pixelstretch;
// kd: Get the aspect ratio. 5:4 is handled just like 4:3... I GUESS
// this'll do.
aspect_ratio = max(4.0 / 3, Screen.GetAspectRatio());
}
double AspectRatio () const {
return aspect_ratio;
}
// kd: Once you know you got screen info, you can call this whenever your
// fov changes. Like CacheFov(player.fov) will do.
void CacheFov (double hor_fov = 90) {
// kd: This holds: aspect ratio = tan(horizontal fov) / tan(ver fov).
// gzd always uses hor fov, but the fov only holds in 4:3 (in a 4:3 box
// in your screen centre), so we just extend it.
tan_fov_2.x = tan(hor_fov / 2) * aspect_ratio / (4.0 / 3);
tan_fov_2.y = tan_fov_2.x / aspect_ratio;
}
// kd: Also need some view info. Angle is yaw, pitch, roll in world format
// so positive pitch is up. Call one of the following functions.
protected vector3 view_ang;
protected vector3 view_pos;
ui void OrientForRenderOverlay (RenderEvent event) {
Reorient(
event.viewpos, (
event.viewangle,
event.viewpitch,
event.viewroll));
}
ui void OrientForRenderUnderlay (RenderEvent event) {
Reorient(
event.viewpos, (
event.viewangle,
event.viewpitch,
event.viewroll));
}
void OrientForPlayer (PlayerInfo player) {
Reorient(
player.mo.vec3offset(0, 0, player.viewheight), (
player.mo.angle,
player.mo.pitch,
player.mo.roll));
}
virtual void Reorient (vector3 world_view_pos, vector3 world_ang) {
view_ang = world_ang;
view_pos = world_view_pos;
}
// kd: Now we can do projections and such (position in the level, go to
// your screen).
protected double depth;
protected vector2 proj_pos;
protected vector3 diff;
virtual void BeginProjection () {}
virtual void ProjectWorldPos (vector3 world_pos) {}
virtual void ProjectActorPos (
Actor mo,
vector3 offset = (0,0,0),
double t = 1) {}
// kd: Portal aware version.
virtual void ProjectActorPosPortal (
Actor mo,
vector3 offset = (0,0,0),
double t = 1) {}
virtual vector2 ProjectToNormal () const { return (0, 0); }
virtual vector2 ProjectToScreen () const { return (0, 0); }
virtual vector2 ProjectToCustom (
vector2 origin,
vector2 resolution) const {
return (0, 0);
}
bool IsInFront () const {
return 0 < depth;
}
bool IsInScreen () const {
if( proj_pos.x < -depth || depth < proj_pos.x ||
proj_pos.y < -depth || depth < proj_pos.y) {
return false;
}
return true;
}
// kd: Deprojection (point on screen, go into the world):
virtual void BeginDeprojection () {}
virtual vector3 DeprojectNormalToDiff (
vector2 normal_pos,
double depth = 1) const {
return (0, 0, 0);
}
virtual vector3 DeprojectScreenToDiff (
vector2 screen_pos,
double depth = 1) const {
return (0, 0, 0);
}
virtual vector3 DeprojectCustomToDiff (
vector2 origin,
vector2 resolution,
vector2 screen_pos,
double depth = 1) const {
return (0, 0, 0);
}
// kd: A normal position is in the -1 <= x, y <= 1 range on your screen.
// This will be your screen no matter the resolution:
/*
(-1, -1) -- --- --- (0, -1) --- --- --- --- (1, -1)
| |
| |
| |
(-1, 0) (0, 0) (1, 0)
| |
| |
| |
(-1, 1) --- --- --- (0, 1) --- --- --- --- (1, 1)
*/
// So this scales such a position back into your drawing resolution.
vector2 NormalToScreen (vector2 normal_pos) const {
normal_pos = 0.5 * (normal_pos + (1, 1));
return (
normal_pos.x * resolution.x,
normal_pos.y * resolution.y);
}
// kd: And this brings a screen position to normal. Make sure the resolution
// is the same for your cursor.
vector2 ScreenToNormal (vector2 screen_pos) const {
screen_pos = (
screen_pos.x / resolution.x,
screen_pos.y / resolution.y);
return 2 * screen_pos - (1, 1);
}
// kd: Other interesting stuff.
vector3 Difference () const {
return diff;
}
double Distance () const {
return diff.length();
}
}

View file

@ -0,0 +1,141 @@
/* kd:
This helps repositioning the view port for stuff like screen blocks. It's a
little more than that, cuz it can also determine stuff like, "is this scene
position in the viewport?" Cuz the scene doesn't necessarily match the
viewport.
Well yea... see the examples. Imagine how annoying it is to even get this
idea to begin with.
*/
struct dtLe_Viewport {
private vector2 scene_origin;
private vector2 scene_size;
private vector2 viewport_origin;
private vector2 viewport_bound;
private vector2 viewport_size;
private double scene_aspect;
private double viewport_aspect;
private double scale_f;
private vector2 scene_to_viewport;
ui void FromHud () const {
scene_aspect = Screen.GetAspectRatio();
vector2 hud_origin;
vector2 hud_size;
[hud_origin.x, hud_origin.y, hud_size.x, hud_size.y] =
Screen.GetViewWindow();
let window_resolution = (
Screen.GetWidth(),
Screen.GetHeight());
let window_to_normal = (
1.0 / window_resolution.x,
1.0 / window_resolution.y);
viewport_origin = (
window_to_normal.x * hud_origin.x,
window_to_normal.y * hud_origin.y);
viewport_size = (
window_to_normal.x * hud_size.x,
window_to_normal.y * hud_size.y);
viewport_aspect = hud_size.x / hud_size.y;
viewport_bound = viewport_origin + viewport_size;
// kd: The scene is what is actually rendered. It's not always the same
// as the viewport. When the statusbar comes into play, the scene is
// obscured by the viewport being too small.
// Example: Compare screenblocks 11 against screenblocks 10 in unmodded
// Doom. You will notice that the scaling of the 3d world is the same,
// but it's moved up by half the height of the statusbar.
// That makes this viewport stuff kinda really annoying to deal with.
// Also statusbar.getsomethingfromstatusbar, really really nice naming.
let statusbar_height =
(window_resolution.y - Statusbar.GetTopOfStatusbar()) / window_resolution.y;
scale_f = hud_size.x / window_resolution.x;
scene_aspect = Screen.GetAspectRatio();
let offset = 10 < screenblocks ? 0 : 0.5 * statusbar_height;
scene_size = (
scale_f,
scale_f);
scene_origin = viewport_origin - (0, 0.5 * (scene_size.y - viewport_size.y));
scene_to_viewport = (
viewport_size.x / scene_size.x,
viewport_size.y / scene_size.y);
}
// kd: Is the scene pos (normal, just like projected normal) inside the
// view port? If yes, it's visible in the 3d world, even through resizing.
bool IsInside (vector2 scene_pos) const {
let normal_pos = scene_origin + (
scene_size.x * 0.5 * (1 + scene_pos.x),
scene_size.y * 0.5 * (1 + scene_pos.y));
if( normal_pos.x < viewport_origin.x || viewport_bound.x < normal_pos.x ||
normal_pos.y < viewport_origin.y || viewport_bound.y < normal_pos.y) {
return false;
}
return true;
}
// kd: Use these for drawing (and make sure the aspect ratios match).
vector2 SceneToCustom (vector2 scene_pos, vector2 resolution) const {
let normal_pos = 0.5 * (
(scene_pos.x + 1) * scene_size.x,
(scene_pos.y + 1) * scene_size.y);
return (
(scene_origin.x + normal_pos.x) * resolution.x,
(scene_origin.y + normal_pos.y) * resolution.y);
}
vector2 SceneToWindow (vector2 scene_pos) const {
return SceneToCustom(
scene_pos,
(Screen.GetWidth(), Screen.GetHeight()) );
}
vector2 ViewportToCustom (vector2 viewport_pos, vector2 resolution) const {
let normal_pos = 0.5 * (
(viewport_pos.x + 1) * viewport_size.x,
(viewport_pos.y + 1) * viewport_size.y);
return (
(viewport_origin.x + normal_pos.x) * resolution.x,
(viewport_origin.y + normal_pos.y) * resolution.y);
}
vector2 ViewportToWindow (vector2 viewport_pos) const {
return ViewportToCustom(
viewport_pos,
(Screen.GetWidth(), Screen.GetHeight()) );
}
double Scale () const {
return scale_f;
}
}

View file

@ -1,108 +0,0 @@
/*
Matrix Math helper class.
(C)2018 Marisa Kirisame, UnSX Team.
Released under the GNU Lesser General Public License version 3 (or later).
See https://www.gnu.org/licenses/lgpl-3.0.txt for its terms.
*/
Class dt_Matrix4
{
private double m[16];
dt_Matrix4 init()
{
int i;
for ( i=0; i<16; i++ ) m[i] = 0;
return self;
}
static dt_Matrix4 create()
{
return new("dt_Matrix4").init();
}
static dt_Matrix4 identity()
{
dt_Matrix4 o = dt_Matrix4.create();
for ( int i=0; i<4; i++ ) o.set(i,i,1);
return o;
}
double get( int c, int r )
{
return m[r*4+c];
}
void set( int c, int r, double v )
{
m[r*4+c] = v;
}
dt_Matrix4 add( dt_Matrix4 o )
{
dt_Matrix4 r = dt_Matrix4.create();
int i, j;
for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ )
r.set(j,i,get(j,i)+o.get(j,i));
return r;
}
dt_Matrix4 scale( double s )
{
dt_Matrix4 r = dt_Matrix4.create();
int i, j;
for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ )
r.set(j,i,get(j,i)*s);
return r;
}
dt_Matrix4 mul( dt_Matrix4 o )
{
dt_Matrix4 r = dt_Matrix4.create();
int i, j;
for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ )
r.set(j,i,get(0,i)*o.get(j,0)+get(1,i)*o.get(j,1)+get(2,i)*o.get(j,2)+get(3,i)*o.get(j,3));
return r;
}
Vector3 vmat( Vector3 o )
{
double x, y, z, w;
x = get(0,0)*o.x+get(1,0)*o.y+get(2,0)*o.z+get(3,0);
y = get(0,1)*o.x+get(1,1)*o.y+get(2,1)*o.z+get(3,1);
z = get(0,2)*o.x+get(1,2)*o.y+get(2,2)*o.z+get(3,2);
w = get(0,3)*o.x+get(1,3)*o.y+get(2,3)*o.z+get(3,3);
return (x,y,z)/w;
}
static dt_Matrix4 rotate( Vector3 axis, double theta )
{
dt_Matrix4 r = dt_Matrix4.identity();
double s, c, oc;
s = sin(theta);
c = cos(theta);
oc = 1.0-c;
r.set(0,0,oc*axis.x*axis.x+c);
r.set(1,0,oc*axis.x*axis.y-axis.z*s);
r.set(2,0,oc*axis.x*axis.z+axis.y*s);
r.set(0,1,oc*axis.y*axis.x+axis.z*s);
r.set(1,1,oc*axis.y*axis.y+c);
r.set(2,1,oc*axis.y*axis.z-axis.x*s);
r.set(0,2,oc*axis.z*axis.x-axis.y*s);
r.set(1,2,oc*axis.z*axis.y+axis.x*s);
r.set(2,2,oc*axis.z*axis.z+c);
return r;
}
static dt_Matrix4 perspective( double fov, double ar, double znear, double zfar )
{
dt_Matrix4 r = dt_Matrix4.create();
double f = 1/tan(fov*0.5);
r.set(0,0,f/ar);
r.set(1,1,f);
r.set(2,2,(zfar+znear)/(znear-zfar));
r.set(3,2,(2*zfar*znear)/(znear-zfar));
r.set(2,3,-1);
return r;
}
}

View file

@ -51,7 +51,7 @@ Class BulletImpact : Actor
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOCLIP;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
Scale 0.25;
@ -84,6 +84,8 @@ Class BulletImpact : Actor
s.vel = pvel;
}
A_PlaySound("bullet/hit",CHAN_VOICE,attenuation:3.0);
let s = Spawn("Splasher",Vec3Offset(0,0,2));
s.vel = (0,0,-4);
}
States
{
@ -93,6 +95,24 @@ Class BulletImpact : Actor
}
}
Class Splasher : Actor
{
Default
{
Radius 0.1;
Height 0;
+CORPSE;
+NOTELEPORT;
}
States
{
Spawn:
Crash:
TNT1 A 2;
Stop;
}
}
Class UTCasing : Actor
{
int deadtimer, numbounces;

View file

@ -59,7 +59,7 @@ Class ImpactHammer : UTWeapon
invoker.count = 0;
A_AlertMonsters();
}
A_QuakeEx(clamp(int(invoker.chargesize*3),0,3),clamp(int(invoker.chargesize*3),0,3),clamp(int(invoker.chargesize*3),0,3),2,0,96,"",QF_RELATIVE,rollIntensity:clamp(invoker.chargesize*0.3,0,0.3));
A_QuakeEx(clamp(int(invoker.chargesize),0,2),clamp(int(invoker.chargesize),0,2),clamp(int(invoker.chargesize),0,2),2,0,96,"",QF_RELATIVE,rollIntensity:clamp(invoker.chargesize*0.3,0,0.3));
UTMainHandler.DoSwing(self,(FRandom[Impact](-1,1),FRandom[Impact](-1,1)),invoker.chargesize*0.1,0,1,SWING_Spring);
if ( !(player.cmd.buttons&BT_ATTACK) )
{

View file

@ -105,6 +105,107 @@ Class DamageAmplifier : Powerup
}
}
Class UTInvulnerability : PowerupGiver
{
Default
{
Tag "$T_UTINVUL";
Inventory.PickupMessage "$I_UTINVUL";
+COUNTITEM;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.BIGPOWERUP;
Inventory.MaxAmount 0;
Powerup.Type "UTInvulPower";
Inventory.PickupSound "uinvul/pickup";
Inventory.RespawnTics 4200;
}
States
{
Spawn:
UKEY A -1;
Stop;
}
}
Class UTInvulLight : DynamicLight
{
Default
{
DynamicLight.Type "Point";
Args 255,238,0,80;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
if ( target.player )
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
else SetOrigin(target.Vec3Offset(0,0,target.height/2),true);
args[LIGHT_INTENSITY] = Random[UInvuln](10,12)*8;
bDORMANT = Powerup(master).isBlinking();
}
}
Class UTInvulPower : Powerup
{
Actor l;
int lasteffect;
Default
{
Powerup.Duration -60;
Powerup.Color "FFEE00", 0.05;
}
override void BeginPlay()
{
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void InitEffect()
{
Super.InitEffect();
lasteffect = int.min;
l = Spawn("UTInvulLight",Owner.pos);
l.target = Owner;
l.master = self;
}
override void DoEffect()
{
Super.DoEffect();
if ( (EffectTics == 175) || (EffectTics == 140) || (EffectTics == 105) || (EffectTics == 70) || (EffectTics == 35) )
Owner.A_PlaySound("uinvul/drain",CHAN_7,1.0,false,0.25);
}
override void EndEffect()
{
Super.EndEffect();
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_UTINVUL"));
}
override bool isBlinking()
{
return ((EffectTics <= 175) && (EffectTics%35 >= 30));
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive )
{
if ( !passive || (damage <= 0) ) return;
newdamage = 0;
if ( gametic < lasteffect ) return;
Owner.A_PlaySound("uinvul/hit",CHAN_7,1.0,false,0.25);
UTMainHandler.DoFlash(Owner,Color(48,255,238,0),6);
lasteffect = gametic+5; // prevent excess flash
}
}
// Backpack that only gives ammo for valid weapons
Class UTBackpack : BackpackItem
{
@ -277,7 +378,7 @@ Class UTInvisibilityX : Actor
return;
}
Warp(target,flags:WARPF_COPYINTERPOLATION|WARPF_NOCHECKPOSITION);
bInvisible = target.bInvisible;
bInvisible = target.bInvisible||!target.InStateSequence(target.CurState,target.FindState("Spawn"));
}
States
{
@ -291,18 +392,19 @@ Class UTMapRevealer : MapRevealer
{
Default
{
Tag "$T_MAPREVEALER";
+COUNTITEM;
+INVENTORY.FANCYPICKUPSOUND;
+INVENTORY.ALWAYSPICKUP;
Inventory.MaxAmount 0;
Inventory.PickupSound "trans/pickup";
Inventory.PickupSound "misc/p_pkup";
Inventory.PickupMessage "$I_MAPREVEALER";
}
States
{
Spawn:
TRNS A -1;
Stop;
TRNS ABCDCB 6;
Loop;
}
}
@ -385,6 +487,7 @@ Class PowerJumpBoots_IronFeet : PowerIronFeet
}
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
{
Inventory.AbsorbDamage(damage,damageType,newdamage);
}
override void DoEffect()
{
@ -394,159 +497,108 @@ Class PowerJumpBoots_IronFeet : PowerIronFeet
}
}
Class Searchlight : Inventory
Class UTNightVision : PowerupGiver
{
Actor lt[3];
int ticcnt;
Default
{
Tag "$T_SEARCHLIGHT";
Tag "$T_UTVISION";
Inventory.PickupMessage "$I_UTVISION";
+COUNTITEM;
+INVENTORY.UNTOSSABLE;
+INVENTORY.FANCYPICKUPSOUND;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
Inventory.Amount 200;
Inventory.MaxAmount 200;
Inventory.InterHubAmount 0;
Inventory.PickupMessage "$I_SEARCHLIGHT";
Inventory.PickupSound "lite/pickup";
Inventory.RespawnTics 1050;
+INVENTORY.BIGPOWERUP;
Inventory.MaxAmount 0;
Powerup.Type "UTVisionPower";
Inventory.PickupSound "uvision/pickup";
Inventory.RespawnTics 4200;
}
override bool Use( bool pickup )
override void PostBeginPlay()
{
if ( !lt[0] ) lt[0] = Spawn("mkLight");
lt[0].target = owner;
lt[0].master = self;
if ( !lt[1] ) lt[1] = Spawn("mkLight2");
lt[1].target = owner;
lt[1].master = self;
if ( !lt[2] ) lt[2] = Spawn("mkLight3");
lt[2].target = owner;
lt[2].master = self;
return Super.Use(pickup);
}
override void DetachFromOwner()
{
Super.DetachFromOwner();
if ( lt[0] ) lt[0].Destroy();
if ( lt[1] ) lt[1].Destroy();
if ( lt[2] ) lt[2].Destroy();
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner ) return;
if ( ticcnt++ < TICRATE ) return;
ticcnt = 0;
if ( --Amount <= 0 )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_SEARCHLIGHT"));
DepleteOrDestroy();
}
Super.PostBeginPlay();
tracer = Spawn("UTNightVisionX",pos);
tracer.angle = angle;
tracer.target = self;
}
States
{
Spawn:
SLIT A -1;
UKEY A -1;
Stop;
}
}
/* hello, Soundless Mound copypasted lights */
Class mkLight : DynamicLight
Class UTNightVisionX : UTInvisibilityX
{
int basecolor[3];
Default
{
Alpha 0.3;
}
States
{
Spawn:
UKEY A -1 Bright;
Stop;
}
}
Class UTVisionLight : DynamicLight
{
Default
{
DynamicLight.Type "Point";
+DynamicLight.SPOT;
+DynamicLight.ATTENUATE;
+DynamicLight.DONTLIGHTSELF;
args 255,224,160,300;
DynamicLight.SpotInnerAngle 20;
DynamicLight.SpotOuterAngle 35;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
basecolor[0] = args[LIGHT_RED];
basecolor[1] = args[LIGHT_GREEN];
basecolor[2] = args[LIGHT_BLUE];
+DYNAMICLIGHT.SPOT;
DynamicLight.SpotInnerAngle 60;
DynamicLight.SpotOuterAngle 90;
Args 224,238,255,800;
}
override void Tick()
{
Super.Tick();
if ( !target || !Inventory(master) )
if ( !target || !master )
{
Destroy();
return;
}
if ( target.player ) SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
else SetOrigin(target.vec3Offset(0,0,target.height*0.75),true);
A_SetAngle(target.angle,SPF_INTERPOLATE);
A_SetPitch(target.pitch,SPF_INTERPOLATE);
args[LIGHT_RED] = int(basecolor[0]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_GREEN] = int(basecolor[1]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_BLUE] = int(basecolor[2]*clamp(Inventory(master).amount/40.,0.,1.));
bDORMANT = (target.health <= 0);
if ( Inventory(target) && target.bInvisible ) bDORMANT = true;
// alert monsters hit by the light
if ( GetClass() != "mkLight" ) return;
if ( !bDORMANT && target.player && (target.health > 0) )
{
BlockThingsIterator bt = BlockThingsIterator.Create(target,args[LIGHT_INTENSITY]);
while ( bt.Next() )
{
if ( !bt.Thing || (Distance3D(bt.Thing) > args[LIGHT_INTENSITY]) ) continue;
Vector3 aimdir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
Vector3 reldir = Vec3To(bt.Thing).unit();
if ( (acos(aimdir dot reldir) < SpotOuterAngle+5) && bt.Thing.CheckSight(target) ) bt.Thing.LastHeard = target;
}
}
Vector3 x, y, z, origin;
[x, y, z] = dt_CoordUtil.GetAxes(target.pitch,target.angle,target.roll);
if ( target.player )
origin = target.Vec2OffsetZ(0,0,target.player.viewz);
else origin = target.Vec3Offset(0,0,target.height/2);
SetOrigin(origin,true);
angle = target.angle;
pitch = target.pitch;
args[LIGHT_INTENSITY] = Random[UVision](40,48)*20;
bDORMANT = ((players[consoleplayer].Camera != target)||Powerup(master).isBlinking());
}
}
Class mkLight2 : mkLight
Class UTVisionPower : Powerup
{
Default
{
args 128,112,96,300;
DynamicLight.SpotInnerAngle 0;
DynamicLight.SpotOuterAngle 50;
}
}
Class mkLight3 : DynamicLight
{
int basecolor[3];
Actor l;
Default
{
DynamicLight.Type "Point";
+DynamicLight.ATTENUATE;
args 32,28,24,0;
Powerup.Duration -90;
Powerup.Color "AAEEFF", 0.05;
}
override void PostBeginPlay()
override void BeginPlay()
{
Super.PostBeginPlay();
basecolor[0] = args[LIGHT_RED];
basecolor[1] = args[LIGHT_GREEN];
basecolor[2] = args[LIGHT_BLUE];
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void Tick()
override void InitEffect()
{
Super.Tick();
if ( !target || Inventory(target) || !Inventory(master) )
{
Destroy();
return;
}
args[LIGHT_RED] = int(basecolor[0]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_GREEN] = int(basecolor[1]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_BLUE] = int(basecolor[2]*clamp(Inventory(master).amount/40.,0.,1.));
SetOrigin(target.vec3Offset(0,0,target.height*0.5),true);
Super.InitEffect();
l = Spawn("UTVisionLight",Owner.pos);
l.target = Owner;
l.master = self;
}
override void EndEffect()
{
Super.EndEffect();
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_UTVISION"));
}
}

View file

@ -143,6 +143,8 @@ Class Razor2 : Actor
}
Goto Spawn;
Death:
TNT1 A 0 A_RazorHit();
XDeath:
TNT1 A 1 A_StopSound(CHAN_VOICE);
Stop;
}

View file

@ -442,6 +442,15 @@ Class Translocator : UTWeapon
A_AlertMonsters();
// squeeze down new z if ceiling is in the way
if ( (newpos.z+height > moduleceilingz) ) newpos.z = max(modulefloorz,moduleceilingz-height);
// temporarily disable telefragging for all allies
bool oldnotele[MAXPLAYERS];
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || !players[i].mo ) continue;
oldnotele[i] = players[i].mo.bNOTELEFRAG;
if ( !IsFriend(players[i].mo) ) continue;
players[i].mo.bNOTELEFRAG = true;
}
if ( Warp(self,newpos.x,newpos.y,newpos.z,flags:WARPF_ABSOLUTEPOSITION|WARPF_TESTONLY) && TeleportMove(newpos,true) )
{
SpawnTeleportFog(oldpos,true,false);
@ -454,6 +463,11 @@ Class Translocator : UTWeapon
player.fov = min(175,player.desiredfov+60);
}
else A_PlaySound("transloc/return",CHAN_WEAPON);
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || !players[i].mo ) continue;
players[i].mo.bNOTELEFRAG = oldnotele[i];
}
if ( bBroken )
{
UTMainHandler.DoFlash(self,Color(255,255,255,255),50);

View file

@ -139,13 +139,21 @@ Class UTPlayer : DoomPlayer
if ( giveall || (name ~== "armor") )
{
// Doom Tournament just gives the player a shield belt and maximum bonuses
let belt = Inventory(Spawn("UTShieldBelt"));
belt.ClearCounters();
if ( !belt.CallTryPickup(self) ) belt.Destroy();
let bonus = Inventory(Spawn("UTArmorBonus"));
bonus.ClearCounters();
bonus.Amount = bonus.MaxAmount;
if ( !bonus.CallTryPickup(self) ) bonus.Destroy();
// in non-vanilla mode, also gives body/thigh armor
Class<Inventory> which[] =
{
"UTShieldBelt", "UTArmorBonus",
"UTBodyArmor", "UTThighpads"
};
Inventory inv;
int mx = flak_vanillaarmor?2:4;
for ( int i=0; i<mx; i++ )
{
inv = Inventory(Spawn(which[i]));
inv.ClearCounters();
inv.Amount = inv.MaxAmount;
if ( !inv.CallTryPickup(self) ) inv.Destroy();
}
if ( !giveall ) return;
}
if ( giveall || (name ~== "keys") )
@ -1274,23 +1282,71 @@ Class UTUnderSound : Actor
}
}
// TODO terrain stuff
// terrain splashes
Class UTTerrainFX : Actor
{
Default
{
RenderStyle "Add";
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
}
States
{
Spawn:
TNT1 A 1;
SPSH ABCDEFGHIJKLMNOPQRSTUVWXYZ 1 A_FadeOut(1./26.);
Stop;
}
}
Class UTWaterSplish : UTTerrainFX
{
override void PostBeginPlay()
{
Super.PostBeginPlay();
let r = Spawn("WaterRing",pos);
r.scale *= 0.3;
}
}
Class UTWaterSplash : UTTerrainFX
{
override void PostBeginPlay()
{
Super.PostBeginPlay();
Spawn("WaterRing",pos);
}
}
Class WaterRing : Actor
{
Default
{
RenderStyle "Add";
Scale 0.15;
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
alpha -= 1./20.;
}
States
{
Spawn:
RNGX ABCDEF 5 Bright;
Stop;
}
}
Class UTBloodSplish : UTTerrainFX
@ -1311,18 +1367,112 @@ Class UTSlimeSplash : UTTerrainFX
Class UTNukageSplish : UTTerrainFX
{
Default
{
+BRIGHT;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
int numpt = Random[Terrain](3,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Terrain](-1,1),FRandom[Terrain](-1,1),FRandom[Terrain](-1,1)).unit()*FRandom[Terrain](2,5);
let s = Spawn("BioSpark",pos);
s.vel = pvel;
}
numpt = Random[Terrain](1,2);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Terrain](-1,1),FRandom[Terrain](-1,1),FRandom[Terrain](-1,1)).unit()*FRandom[Terrain](.6,1.2);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.scale *= 0.7;
s.A_SetRenderStyle(0.5,STYLE_AddShaded);
if ( Random[Terrain](0,1) ) s.SetShade("40FF60");
else s.SetShade("60FF40");
}
}
}
Class UTNukageSplash : UTTerrainFX
{
Default
{
+BRIGHT;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
int numpt = Random[Terrain](8,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Terrain](-1,1),FRandom[Terrain](-1,1),FRandom[Terrain](-1,1)).unit()*FRandom[Terrain](3,12);
let s = Spawn("BioSpark",pos);
s.vel = pvel;
}
numpt = Random[Terrain](3,5);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Terrain](-1,1),FRandom[Terrain](-1,1),FRandom[Terrain](-1,1)).unit()*FRandom[Terrain](1.2,2.4);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.scale *= 2;
s.A_SetRenderStyle(0.5,STYLE_AddShaded);
if ( Random[Terrain](0,1) ) s.SetShade("40FF60");
else s.SetShade("60FF40");
}
}
}
Class UTLavaSplish : UTTerrainFX
{
Default
{
+BRIGHT;
}
}
Class UTLavaSplash : UTTerrainFX
{
Default
{
+BRIGHT;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
Spawn("FlameExplosion",pos);
}
}
Class FlameExplosion : Actor
{
Default
{
RenderStyle "Add";
Radius 0.1;
Height 0;
Scale 0.8;
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOTELEPORT;
+FORCEXYBILLBOARD;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_PlaySound("ut/lavaex",CHAN_VOICE);
Spawn("SlugSmoke",pos);
Spawn("SlugLight",pos);
}
States
{
Spawn:
FEXP ABCDEFGHIJ 2 BRIGHT;
Stop;
}
}
Class UTNitroSplish : UTTerrainFX
@ -2775,25 +2925,31 @@ Class UTMainHandler : EventHandler
else if ( Random[Replacements](0,1) ) e.Replacement = 'MiniAmmo';
else e.Replacement = 'RifleAmmo';
}
else if ( e.Replacee == 'InvulnerabilitySphere' ) e.Replacement = (!deathmatch||flak_dmsshock)?'EnhancedShockRifle':'UDamage';
else if ( e.Replacee == 'InvulnerabilitySphere' ) e.Replacement = 'UTInvulnerability';
else if ( e.Replacee == 'Berserk' ) e.Replacement = 'UDamage';
else if ( (e.Replacee == 'ArtiTomeOfPower') || (e.Replacee == 'ArtiEgg') ) e.Replacement = 'ActUDamage';
else if ( e.Replacee == 'Soulsphere' ) e.Replacement = 'UTHealthPack';
else if ( e.Replacee == 'ArtiSuperHealth' ) e.Replacement = 'ActHealthPack';
else if ( e.Replacee == 'Megasphere' ) e.Replacement = 'UTShieldBelt';
else if ( e.Replacee == 'ArtiInvulnerability' ) e.Replacement = 'ActShieldBelt';
else if ( e.Replacee == 'ArtiInvulnerability' ) e.Replacement = 'ActUTInvulnerability';
else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') ) e.Replacement = 'UTMapRevealer';
else if ( e.Replacee == 'BlurSphere' ) e.Replacement = 'UTInvisibility';
else if ( e.Replacee == 'ArtiInvisibility' ) e.Replacement = 'ActInvisibility';
else if ( e.Replacee == 'Infrared' ) e.Replacement = 'Searchlight';
else if ( e.Replacee == 'ArtiTorch' ) e.Replacement = 'ActSearchlight';
else if ( e.Replacee == 'ArtiInvisibility' ) e.Replacement = 'ActUTInvisibility';
else if ( e.Replacee == 'Infrared' ) e.Replacement = 'UTNightVision';
else if ( e.Replacee == 'ArtiTorch' ) e.Replacement = 'ActUTNightVision';
else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UTJumpBoots';
else if ( e.Replacee == 'ArtiFly' ) e.Replacement = 'ActJumpBoots';
else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') ) e.Replacement = 'UTBackpack';
else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') ) e.Replacement = 'UTArmorBonus';
else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'UTHealthBonus';
else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') ) e.Replacement = 'UTThighPads';
else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'UTBodyArmor';
else if ( e.Replacee == 'GreenArmor' ) e.Replacement = 'UTThighPads';
else if ( e.Replacee == 'Silvershield' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'UTThighPads';
else e.Replacement = 'UTBodyArmor';
}
else if ( e.Replacee == 'BlueArmor' ) e.Replacement = 'UTBodyArmor';
else if ( e.Replacee == 'EnchantedShield' ) e.Replacement = 'UTShieldBelt';
else if ( e.Replacee == 'Stimpack' ) e.Replacement = 'UTMedBox';
else if ( e.Replacee == 'Medikit' ) e.Replacement = 'UTHealthBox';
else if ( e.Replacee == 'ArtiHealth' )
@ -2804,9 +2960,7 @@ Class UTMainHandler : EventHandler
else if ( e.Replacee == 'ArtiTeleport' )
{
// I have no idea what to replace this with, so just have some random stuff
if ( Random[Replacements](0,1) ) e.Replacement = 'UTBackpack';
else if ( Random[Replacements](0,1) ) e.Replacement = 'ActShieldBelt';
else if ( Random[Replacements](0,1) ) e.Replacement = 'ActHealthPack';
if ( Random[Replacements](0,1) ) e.Replacement = 'ActHealthPack';
else e.Replacement = 'ActUDamage';
}
else if ( e.Replacee == 'RedCard' ) e.Replacement = 'UTRedKey';

View file

@ -69,6 +69,7 @@ Class UTBloodDrop : Actor
RenderStyle "Translucent";
+MISSILE;
+NOTELEPORT;
+DONTSPLASH;
+THRUACTORS;
+FORCEXYBILLBOARD;
}

View file

@ -23,7 +23,7 @@ Class ViewTracer : LineTracer
Class UTHud : BaseStatusBar
{
TextureID AmmoBar, Boxes[4], Keys[5], BigNum[12], Flash, Slots[10], Icons[14], Uses[14], Man[5], Woman[5], Boss[5], WeaponBox, IconTloc2, UseTloc2, IconSaw2, UseSaw2, ItemBox, ItemSel, ItemFlash, ItemArrow[2], LastItem, FacePanel[3];
TextureID AmmoBar, Boxes[4], Keys[5], BigNum[12], Flash, Slots[10], Icons[14], Uses[14], Man[5], Woman[5], Boss[5], WeaponBox, IconTloc2, UseTloc2, IconSaw2, UseSaw2, IconAuto2, UseAuto2, ItemBox, ItemSel, ItemFlash, ItemArrow[2], LastItem, FacePanel[3];
Class<Weapon> IconClasses[14];
double HScale;
Color tintcolor, bgcolor;
@ -34,6 +34,7 @@ Class UTHud : BaseStatusBar
int lastseentic;
bool showweapons, showfrags, showammo, showstatus, showinfo;
double hudsize, weaponsize, statussize;
bool justselected;
HUDFont mUTFont12, mUTFont40;
@ -167,6 +168,8 @@ Class UTHud : BaseStatusBar
UseTloc2 = TexMan.CheckForTexture("UseTrn2",TexMan.Type_Any);
IconSaw2 = TexMan.CheckForTexture("IconSaw2",TexMan.Type_Any);
UseSaw2 = TexMan.CheckForTexture("UseSaw2",TexMan.Type_Any);
IconAuto2 = TexMan.CheckForTexture("IconAut2",TexMan.Type_Any);
UseAuto2 = TexMan.CheckForTexture("UseAut2",TexMan.Type_Any);
FacePanel[0] = TexMan.CheckForTexture("FacePnl",TexMan.Type_Any);
FacePanel[1] = TexMan.CheckForTexture("FacePnlA",TexMan.Type_Any);
FacePanel[2] = TexMan.CheckForTexture("Static1",TexMan.Type_Any);
@ -252,7 +255,9 @@ Class UTHud : BaseStatusBar
if ( !(w is IconClasses[i]) ) continue;
if ( use )
{
if ( (i == 10) && flak_sawammo )
if ( (i == 1) && (w.Amount > 1) )
UTDrawTintedTex(UseAuto2,sx,opacity+7);
else if ( (i == 10) && flak_sawammo )
UTDrawTintedTex(UseSaw2,sx,opacity+7);
else if ( (i == 11) && flak_transloc2k4 )
UTDrawTintedTex(UseTloc2,sx,opacity+7);
@ -260,7 +265,9 @@ Class UTHud : BaseStatusBar
}
else
{
if ( (i == 10) && flak_sawammo )
if ( (i == 1) && (w.Amount > 1) )
UTDrawTintedTex(IconAuto2,sx,opacity,halftint);
else if ( (i == 10) && flak_sawammo )
UTDrawTintedTex(IconSaw2,sx,opacity,halftint);
else if ( (i == 11) && flak_transloc2k4 )
UTDrawTintedTex(IconTloc2,sx,opacity,halftint);
@ -433,11 +440,14 @@ Class UTHud : BaseStatusBar
CurY = 0;
Color dollcolor = tintcolor;
DamageAmplifier d;
UTInvulPower p;
UTJumpBoots j;
d = DamageAmplifier(CPlayer.mo.FindInventory("DamageAmplifier"));
p = UTInvulPower(CPlayer.mo.FindInventory("UTInvulPower"));
j = UTJumpBoots(CPlayer.mo.FindInventory("UTJumpBoots"));
if ( d && !d.isBlinking() ) dollcolor = d.BlendColor;
int dolltype = 0;
if ( p && !p.isBlinking() ) dollcolor = LerpColor(GoldColor,dollcolor,((gametic+fractic)/15)%1.);
if ( CPlayer.mo is 'UTPlayer' ) dolltype = UTPlayer(CPlayer.mo).DollType;
else
{
@ -1036,6 +1046,25 @@ Class UTHud : BaseStatusBar
LastItem = CPlayer.mo.InvSel.Icon;
LastAmount = CPlayer.mo.InvSel.Amount-1;
}
if ( CPlayer.inventorytics >= (5*Thinker.TICRATE)-1 )
{
if ( CPlayer.mo.InvSel )
{
PickupMsg = CPlayer.mo.InvSel.GetTag();
PickupMsgTic = gametic+50;
S_Sound("misc/hud_sel",CHAN_UI);
}
}
if ( CPlayer.inventorytics > 0 ) justselected = false;
else
{
if ( !justselected && CPlayer.mo.InvSel )
{
Console.Printf(StringTable.Localize("$M_ISELECT"),CPlayer.mo.InvSel.GetTag());
S_Sound("misc/hud_sel",CHAN_UI);
}
justselected = true;
}
if ( deathmatch||teamplay )
{
if ( CPlayer.fragcount != lastfragcnt ) lastfrag = level.time;

View file

@ -444,6 +444,13 @@ Class RedeemerHUD : HUDMessageBase
Array<TargetActor> ta;
Shape2D sshape, darrow;
bool dodim;
// libeye stuff
dtLe_ProjScreen proj;
dtLe_GLScreen gl_proj;
dtLe_SWScreen sw_proj;
dtLe_Viewport viewport;
bool can_project;
transient CVar cvar_renderer;
RedeemerHUD Init()
{
@ -460,15 +467,45 @@ Class RedeemerHUD : HUDMessageBase
sshape.PushCoord((1,1));
sshape.PushTriangle(0,3,1);
sshape.PushTriangle(0,2,3);
gl_proj = new("dtLe_GLScreen");
sw_proj = new("dtLe_SWScreen");
PrepareProjection();
return self;
}
void PrepareProjection()
{
if ( !cvar_renderer )
cvar_renderer = CVar.GetCVar("vid_rendermode",players[consoleplayer]);
if ( !cvar_renderer )
{
can_project = proj = gl_proj;
return;
}
switch ( cvar_renderer.GetInt() )
{
case 0:
case 1:
proj = sw_proj;
break;
default:
proj = gl_proj;
break;
}
can_project = proj;
}
override bool Tick()
{
PrepareProjection();
LagRoll = dt_Quat.Normalize180(ViewRoll-LagRoll2);
LagRoll2 += dt_Quat.Normalize180(LagRoll-LagRoll2)*0.1;
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() )
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() && can_project )
{
viewport.FromHud();
proj.CacheResolution();
proj.CacheFov(players[consoleplayer].fov);
proj.Reorient(ViewPos,(ViewAngle,ViewPitch,ViewRoll));
proj.BeginProjection();
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
@ -479,11 +516,11 @@ Class RedeemerHUD : HUDMessageBase
{
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
Vector3 wpos = ViewPos+tdir;
Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV);
if ( spos.z > 1.0 ) continue;
proj.ProjectWorldPos(ViewPos+tdir);
Vector2 npos = proj.ProjectToNormal();
if ( !proj.IsInFront() ) continue;
TargetActor te = new("TargetActor");
te.vpos = dt_CoordUtil.ToViewport(spos);
te.vpos = viewport.SceneToWindow(npos);
te.diststr = String.Format("%f",tdir.length());
te.diststr.Replace(".","");
ta.Push(te);
@ -496,10 +533,15 @@ Class RedeemerHUD : HUDMessageBase
if ( visibility != StatusBar.HUDMSGLayer_UnderHUD ) return;
if ( dodim ) Screen.Dim("C8 00 00",0.2,0,0,Screen.GetWidth(),Screen.GetHeight());
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() )
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && can_project )
{
if ( CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() )
{
viewport.FromHud();
proj.CacheResolution();
proj.CacheFov(players[consoleplayer].fov);
proj.Reorient(ViewPos,(ViewAngle,ViewPitch,ViewRoll));
proj.BeginProjection();
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
@ -510,11 +552,11 @@ Class RedeemerHUD : HUDMessageBase
{
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
Vector3 wpos = ViewPos+tdir;
Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV);
if ( spos.z > 1.0 ) continue;
proj.ProjectWorldPos(ViewPos+tdir);
Vector2 npos = proj.ProjectToNormal();
if ( !proj.IsInFront() ) continue;
TargetActor te = new("TargetActor");
te.vpos = dt_CoordUtil.ToViewport(spos);
te.vpos = viewport.SceneToWindow(npos);
te.diststr = String.Format("%f",tdir.length());
te.diststr.Replace(".","");
ta.Push(te);