Oh boy, here comes a big one.
Doomreal development is officially back to life. Doomreal now depends on Doom Tournament, as it's an add-on for it. Most of the resources are in place right now, just a couple more things left to add in. Flak cannon is still incomplete and weapon development will be resumed soon. There is a main menu now, I hope you like it. Player classes don't have models assigned yet, so they will look weird. Overall this is not yet very playable.
This commit is contained in:
parent
f532f74d85
commit
d3b11d1ef2
1145 changed files with 1065 additions and 883 deletions
|
|
@ -1,165 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
|
@ -85,8 +85,8 @@ Class UnrealBackpack : BackpackItem replaces Backpack
|
|||
}
|
||||
Default
|
||||
{
|
||||
Tag "Backpack";
|
||||
Inventory.PickupMessage "You got a Backpack.";
|
||||
Tag "$T_BACKPACK";
|
||||
Inventory.PickupMessage "$I_BACKPACK";
|
||||
Inventory.RespawnTics 2100;
|
||||
}
|
||||
States
|
||||
|
|
@ -113,9 +113,9 @@ Class UTranslator : UnrealInventory
|
|||
CurY = ClipY/2-68;
|
||||
Screen.DrawTexture(thud,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
||||
String ttxt;
|
||||
if ( bShowHint && (Hint.length() > 0) ) ttxt = String.Format("Hint: %s",Hint);
|
||||
if ( bShowHint && (Hint.length() > 0) ) ttxt = String.Format("%s: %s",StringTable.Localize("$TR_HINT"),Hint);
|
||||
else if ( NewMessage.length() > 0 ) ttxt = NewMessage;
|
||||
else ttxt = "No new messages.";
|
||||
else ttxt = StringTable.Localize("$TR_NOMSG");
|
||||
BrokenLines lines = tfnt.BreakLines(ttxt,220);
|
||||
int th = tfnt.GetHeight();
|
||||
CurX += 20;
|
||||
|
|
@ -143,8 +143,8 @@ Class UTranslator : UnrealInventory
|
|||
|
||||
Default
|
||||
{
|
||||
Tag "Universal Translator";
|
||||
Inventory.PickupMessage "You got the Universal Translator.";
|
||||
Tag "$T_TRANSLATOR";
|
||||
Inventory.PickupMessage "$I_TRANSLATOR";
|
||||
Inventory.Icon "I_Tran";
|
||||
Inventory.MaxAmount 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
Coordinate Utility 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 mkCoordUtil
|
||||
{
|
||||
// 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
|
||||
Matrix4 mRoll = Matrix4.rotate((0,0,1),roll);
|
||||
Matrix4 mPitch = Matrix4.rotate((1,0,0),apitch);
|
||||
Matrix4 mYaw = Matrix4.rotate((0,-1,0),ayaw);
|
||||
// scaling
|
||||
Matrix4 mScale = Matrix4.identity();
|
||||
mScale.set(1,1,pr);
|
||||
// YZ swap
|
||||
Matrix4 mYZ = Matrix4.create();
|
||||
mYZ.set(0,0,1);
|
||||
mYZ.set(2,1,1);
|
||||
mYZ.set(1,2,-1);
|
||||
mYZ.set(3,3,1);
|
||||
// translation
|
||||
Matrix4 mMove = Matrix4.identity();
|
||||
mMove.set(3,0,-eye.x);
|
||||
mMove.set(3,1,-eye.y);
|
||||
mMove.set(3,2,-eye.z);
|
||||
// perspective
|
||||
Matrix4 mPerspective = Matrix4.perspective(fov,ar,5,65535);
|
||||
// full matrix
|
||||
Matrix4 mView = mRoll.mul(mPitch);
|
||||
mView = mView.mul(mYaw);
|
||||
mView = mView.mul(mScale);
|
||||
mView = mView.mul(mYZ);
|
||||
mView = mView.mul(mMove);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +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 Matrix4
|
||||
{
|
||||
private double m[16];
|
||||
|
||||
Matrix4 init()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<16; i++ ) m[i] = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
static Matrix4 create()
|
||||
{
|
||||
return new("Matrix4").init();
|
||||
}
|
||||
|
||||
static Matrix4 identity()
|
||||
{
|
||||
Matrix4 o = 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;
|
||||
}
|
||||
|
||||
Matrix4 add( Matrix4 o )
|
||||
{
|
||||
Matrix4 r = 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;
|
||||
}
|
||||
|
||||
Matrix4 scale( double s )
|
||||
{
|
||||
Matrix4 r = 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;
|
||||
}
|
||||
|
||||
Matrix4 mul( Matrix4 o )
|
||||
{
|
||||
Matrix4 r = 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 Matrix4 rotate( Vector3 axis, double theta )
|
||||
{
|
||||
Matrix4 r = 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 Matrix4 perspective( double fov, double ar, double znear, double zfar )
|
||||
{
|
||||
Matrix4 r = 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;
|
||||
}
|
||||
|
||||
// UE-like axes from rotation
|
||||
static Vector3, Vector3, Vector3 getaxes( double pitch, double yaw, double roll )
|
||||
{
|
||||
Vector3 x = (1,0,0), y = (0,-1,0), z = (0,0,1); // y inverted for left-handed result
|
||||
Matrix4 mRoll = Matrix4.rotate((1,0,0),roll);
|
||||
Matrix4 mPitch = Matrix4.rotate((0,1,0),pitch);
|
||||
Matrix4 mYaw = Matrix4.rotate((0,0,1),yaw);
|
||||
Matrix4 mRot = mRoll.mul(mYaw);
|
||||
mRot = mRot.mul(mPitch);
|
||||
x = mRot.vmat(x);
|
||||
y = mRot.vmat(y);
|
||||
z = mRot.vmat(z);
|
||||
return x, y, z;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
// Unused dead code, kept for reference
|
||||
|
||||
// Tier 1 (chainsaw)
|
||||
Class Tier1Weapon : RandomSpawner2 replaces Chainsaw
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@ Class StingerAmmo : Ammo
|
|||
{
|
||||
Default
|
||||
{
|
||||
Tag "Tarydium Shards";
|
||||
Tag "$T_STINGERAMMO";
|
||||
Inventory.Icon "I_Stingr";
|
||||
Inventory.PickupMessage "You picked up 40 Tarydium Shards.";
|
||||
Inventory.PickupMessage "";
|
||||
Inventory.Amount 40;
|
||||
Inventory.MaxAmount 200;
|
||||
Ammo.BackpackAmount 80;
|
||||
Ammo.BackpackMaxAmount 400;
|
||||
Ammo.DropAmount 10;
|
||||
}
|
||||
override String PickupMessage()
|
||||
{
|
||||
return String.Format("%s%d%s",StringTable.Localize("$I_STINGERAMMOL"),Amount,StringTable.Localize("$I_STINGERAMMOR"));
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -23,7 +27,7 @@ Class StingerProjectile : Actor
|
|||
{
|
||||
Default
|
||||
{
|
||||
Obituary "%o was perforated by %k's Stinger.";
|
||||
Obituary "$O_STINGER";
|
||||
DamageType 'shot';
|
||||
DamageFunction Random[Stinger](15,25);
|
||||
Speed 40;
|
||||
|
|
@ -52,12 +56,12 @@ Class StingerProjectile : Actor
|
|||
}
|
||||
}
|
||||
|
||||
Class Stinger : UnrealWeapon
|
||||
Class Stinger : UTWeapon
|
||||
{
|
||||
Default
|
||||
{
|
||||
Tag "Stinger";
|
||||
Inventory.PickupMessage "You picked up the Stinger.";
|
||||
Tag "$T_STINGER";
|
||||
Inventory.PickupMessage "$I_STINGER";
|
||||
Weapon.UpSound "stinger/select";
|
||||
Weapon.SlotNumber 3;
|
||||
Weapon.SelectionOrder 7;
|
||||
|
|
@ -66,6 +70,7 @@ Class Stinger : UnrealWeapon
|
|||
Weapon.AmmoType2 "StingerAmmo";
|
||||
Weapon.AmmoUse2 1;
|
||||
Weapon.AmmoGive 40;
|
||||
UTWeapon.DropAmmo 20;
|
||||
}
|
||||
action void A_StingerFire()
|
||||
{
|
||||
|
|
@ -73,11 +78,12 @@ Class Stinger : UnrealWeapon
|
|||
if ( !weap ) return;
|
||||
if ( weap.Ammo1.Amount <= 0 ) return;
|
||||
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
||||
UnrealMainHandler.DoFlash(self,Color(16,0,64,255),1);
|
||||
UTMainHandler.DoFlash(self,Color(16,0,64,255),1);
|
||||
UTMainHandler.DoSwing(self,(FRandom[Stinger](-0.1,-0.2),FRandom[Stinger](-0.1,0.1)),4,-1.5,2,SWING_Spring,2,2);
|
||||
A_AlertMonsters();
|
||||
A_QuakeEx(1,1,1,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
||||
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+8.0*y-9.0*z;
|
||||
Actor p = Spawn("StingerProjectile",origin);
|
||||
p.angle = angle;
|
||||
|
|
@ -90,13 +96,14 @@ Class Stinger : UnrealWeapon
|
|||
Weapon weap = Weapon(invoker);
|
||||
if ( !weap ) return;
|
||||
if ( weap.Ammo1.Amount <= 0 ) return;
|
||||
UnrealMainHandler.DoFlash(self,Color(16,0,64,255),1);
|
||||
UTMainHandler.DoFlash(self,Color(16,0,64,255),1);
|
||||
UTMainHandler.DoSwing(self,(FRandom[Stinger](-0.3,-0.8),FRandom[Stinger](-0.4,0.4)),4,-1,3,SWING_Spring,3,5);
|
||||
A_AlertMonsters();
|
||||
A_QuakeEx(1,1,1,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
||||
[x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+8.0*y-9.0*z;
|
||||
[x, y, z] = Matrix4.GetAxes(BulletSlope(),angle,roll);
|
||||
[x, y, z] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll);
|
||||
A_PlaySound("stinger/altfire",CHAN_WEAPON);
|
||||
Actor p;
|
||||
double a, s;
|
||||
|
|
|
|||
7
zscript/uarmoritems.zsc
Normal file
7
zscript/uarmoritems.zsc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Class UnrealArmor : UTArmor
|
||||
{
|
||||
Default
|
||||
{
|
||||
-INVENTORY.ALWAYSPICKUP;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,19 @@ Class UFlakBox : Ammo
|
|||
{
|
||||
Default
|
||||
{
|
||||
Tag "Flak Shell Box";
|
||||
Inventory.Icon "I_Flak";
|
||||
Inventory.PickupMessage "You picked up 10 Flak Shells.";
|
||||
Tag "$T_FLAKAMMO";
|
||||
Inventory.Icon "I_FlakAm";
|
||||
Inventory.PickupMessage "";
|
||||
Inventory.Amount 10;
|
||||
Inventory.MaxAmount 50;
|
||||
Ammo.BackpackAmount 5;
|
||||
Ammo.BackpackMaxAmount 100;
|
||||
Ammo.DropAmount 5;
|
||||
}
|
||||
override String PickupMessage()
|
||||
{
|
||||
return String.Format("%s%d%s",StringTable.Localize("$I_FLAKAMMOL"),Amount,StringTable.Localize("$I_FLAKAMMOR"));
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -23,11 +27,12 @@ Class UFlakAmmo : UFlakBox
|
|||
{
|
||||
Default
|
||||
{
|
||||
Tag "Flak Shell";
|
||||
Inventory.Icon "I_Flak";
|
||||
Inventory.PickupMessage "You picked up a Flak Shell.";
|
||||
Tag "$T_FLAKAMMO2";
|
||||
Inventory.Icon "I_FlakAm";
|
||||
Inventory.PickupMessage "$I_FLAKAMMO2";
|
||||
Inventory.Amount 1;
|
||||
Ammo.DropAmount 1;
|
||||
+INVENTORY.IGNORESKILL;
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -37,20 +42,18 @@ Class UFlakAmmo : UFlakBox
|
|||
}
|
||||
}
|
||||
|
||||
Class UFlakCannon : UnrealWeapon
|
||||
Class UFlakCannon : UTWeapon
|
||||
{
|
||||
bool bLoaded;
|
||||
action void A_Loading( bool first = false )
|
||||
{
|
||||
invoker.bLoaded = true;
|
||||
if ( first ) A_PlaySound("uflak/load",CHAN_WEAPON);
|
||||
else A_PlaySound("uflak/reload",CHAN_6);
|
||||
if ( first ) A_PlaySound("flak/load",CHAN_WEAPON);
|
||||
else A_PlaySound("flak/reload",CHAN_6);
|
||||
}
|
||||
Default
|
||||
{
|
||||
Tag "Flak Cannon";
|
||||
Inventory.PickupMessage "You got the Flak Cannon.";
|
||||
Weapon.UpSound "uflak/select";
|
||||
Tag "$T_FLAKCANNON";
|
||||
Inventory.PickupMessage "$I_FLAKCANNON";
|
||||
Weapon.UpSound "flak/select";
|
||||
Weapon.SlotNumber 6;
|
||||
Weapon.SelectionOrder 4;
|
||||
Weapon.AmmoType "UFlakBox";
|
||||
|
|
@ -58,6 +61,7 @@ Class UFlakCannon : UnrealWeapon
|
|||
Weapon.AmmoType2 "UFlakBox";
|
||||
Weapon.AmmoUse2 1;
|
||||
Weapon.AmmoGive 10;
|
||||
UTWeapon.DropAmmo 5;
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -76,33 +80,34 @@ Class UFlakCannon : UnrealWeapon
|
|||
FLKL BCEFGIJKMNO 1;
|
||||
Goto Idle;
|
||||
Loading:
|
||||
FLKL A 1 A_Loading();
|
||||
FLKL A 1
|
||||
{
|
||||
A_CheckReload();
|
||||
if ( invoker.Ammo1.Amount > 0 ) A_Loading();
|
||||
}
|
||||
FLKL BCEFGIJKMNO 1;
|
||||
Goto Idle;
|
||||
Idle:
|
||||
FLKI A 1
|
||||
{
|
||||
A_CheckReload();
|
||||
A_WeaponReady();
|
||||
}
|
||||
Wait;
|
||||
Idle2:
|
||||
FLI2 A 1
|
||||
{
|
||||
A_CheckReload();
|
||||
A_WeaponReady();
|
||||
}
|
||||
FLKI A 1 A_WeaponReady();
|
||||
Wait;
|
||||
Fire:
|
||||
FLKI A 0 A_JumpIf(!invoker.bLoaded,"Loading");
|
||||
FLKF ABCDEFGHIJ 1;
|
||||
FLKF A 1
|
||||
{
|
||||
A_Overlay(PSP_FLASH,"Flash");
|
||||
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
|
||||
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
|
||||
}
|
||||
FLKF BCDEFGHIJ 1;
|
||||
FLKE ABCDEFGHIJKLMNS 1;
|
||||
FLKE S 0 A_JumpIfNoAmmo("Idle2");
|
||||
Goto Loading;
|
||||
AltFire:
|
||||
FLKI A 0 A_JumpIf(!invoker.bLoaded,"Loading");
|
||||
FLKA ABCDEFGHIJK 2;
|
||||
FLKA K 0 A_JumpIfNoAmmo("Idle2");
|
||||
FLKA A 2
|
||||
{
|
||||
A_Overlay(PSP_FLASH,"AltFlash");
|
||||
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
|
||||
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
|
||||
}
|
||||
FLKA BCDEFGHIJK 2;
|
||||
Goto Loading;
|
||||
Deselect:
|
||||
FLKD A 0 A_JumpIfNoAmmo("Deselect2");
|
||||
|
|
@ -113,5 +118,11 @@ Class UFlakCannon : UnrealWeapon
|
|||
FLD2 ABCDEF 1;
|
||||
FLD2 F 1 A_Lower(int.max);
|
||||
Wait;
|
||||
Flash:
|
||||
FLFF ABCDEFGHIJ 1 Bright;
|
||||
Stop;
|
||||
AltFlash:
|
||||
FLFA ABCDEFGHIJK 2 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,10 @@
|
|||
Class UnrealPlayer : DoomPlayer
|
||||
Class UPlayer : UTPlayer
|
||||
{
|
||||
bool lastground;
|
||||
double lastvelz, prevvelz;
|
||||
transient CVar footsteps;
|
||||
|
||||
Default
|
||||
{
|
||||
Player.StartItem "Automag";
|
||||
Player.StartItem "DispersionPistol";
|
||||
Player.StartItem "UMiniAmmo", 30;
|
||||
Player.DamageScreenColor "FF 00 00", 1.0;
|
||||
Player.ViewHeight 46;
|
||||
//Player.StartItem "Automag";
|
||||
//Player.StartItem "DispersionPistol";
|
||||
//Player.StartItem "UMiniAmmo", 30;
|
||||
}
|
||||
|
||||
// Have to modify the give cheat to handle UT armor
|
||||
|
|
@ -81,7 +75,7 @@ Class UnrealPlayer : DoomPlayer
|
|||
// Doomreal gives the player all subclasses of UnrealArmor
|
||||
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
||||
{
|
||||
if ( !(AllActorClasses[i] is "UnrealArmor") ) continue;
|
||||
if ( !(AllActorClasses[i].GetParentClass() is "UnrealArmor") ) continue;
|
||||
let item = Inventory(Spawn(AllActorClasses[i]));
|
||||
if ( !item.CallTryPickup(self) ) item.Destroy();
|
||||
}
|
||||
|
|
@ -162,91 +156,61 @@ Class UnrealPlayer : DoomPlayer
|
|||
}
|
||||
else GiveInventory(type,amount,true);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !player ) return;
|
||||
if ( !footsteps ) footsteps = CVar.GetCVar('stinger_footsteps',players[consoleplayer]);
|
||||
if ( !footsteps.GetBool() ) return;
|
||||
double ang = level.time/(20*TICRATE/35.)*360.;
|
||||
if ( (abs(sin(ang)) >= 1.0) && player.onground && (player.cmd.forwardmove || player.cmd.sidemove) )
|
||||
{
|
||||
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid ) A_PlaySound("u1/playerfootstepwet",CHAN_5,abs(vel.xy.length())*0.03);
|
||||
else A_PlaySound("u1/playerfootstep",CHAN_5,abs(vel.xy.length())*0.03);
|
||||
}
|
||||
if ( player.onground && !bNoGravity && !lastground && (lastvelz < -4) && (lastvelz >= -8) )
|
||||
{
|
||||
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid ) A_PlaySound("u1/wetsplash",CHAN_AUTO,abs(lastvelz*0.0625));
|
||||
else A_PlaySound("*land",CHAN_AUTO,abs(lastvelz*0.03));
|
||||
}
|
||||
lastground = player.onground;
|
||||
lastvelz = prevvelz;
|
||||
prevvelz = vel.z;
|
||||
}
|
||||
}
|
||||
|
||||
// Random Spawner that passes through dropped status to items
|
||||
Class RandomSpawner2 : RandomSpawner
|
||||
Class UPlayerMale1 : UPlayer
|
||||
{
|
||||
override void PostSpawn( Actor spawned )
|
||||
{
|
||||
if ( !bDROPPED ) return;
|
||||
if ( spawned is 'Inventory' ) Inventory(spawned).bTOSSED = bDROPPED;
|
||||
if ( spawned is 'UnrealWeapon' )
|
||||
{
|
||||
spawned.SetState(spawned.ResolveState("Spawn")+1);
|
||||
Inventory(spawned).bALWAYSPICKUP = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class UnrealWeapon : Weapon
|
||||
{
|
||||
// Drawstuffs under HUD
|
||||
virtual ui void PreRender( double lbottom ) {}
|
||||
// Drawstuffs over HUD
|
||||
virtual ui void PostRender( double lbottom ) {}
|
||||
|
||||
override Inventory CreateTossable( int amt )
|
||||
{
|
||||
if ( Ammo1 && (Ammo1.Amount <= 0) ) return null;
|
||||
Inventory d = Super.CreateTossable(amt);
|
||||
if ( d && (d.GetClass() == GetClass()) )
|
||||
{
|
||||
d.SetState(d.ResolveState("Spawn")+1);
|
||||
d.bALWAYSPICKUP = true;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
override bool SpecialDropAction( Actor dropper )
|
||||
{
|
||||
SetState(ResolveState("Spawn")+1);
|
||||
bALWAYSPICKUP = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !Owner || !Owner.player || (Owner.player.ReadyWeapon != self) ) return;
|
||||
Owner.player.WeaponState |= WF_WEAPONBOBBING; // U1 weapons always bob
|
||||
}
|
||||
|
||||
override void OwnerDied()
|
||||
{
|
||||
Super.OwnerDied();
|
||||
A_ClearRefire();
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
Weapon.BobStyle "Smooth";
|
||||
Weapon.BobSpeed 1.5;
|
||||
Weapon.BobRangeX 0.2;
|
||||
Weapon.BobRangeY 0.4;
|
||||
+WEAPON.NOALERT;
|
||||
Player.SoundClass "umale";
|
||||
Player.DisplayName "$N_MALE1";
|
||||
Player.Portrait "";
|
||||
UTPlayer.VoiceType VOICE_MaleOne;
|
||||
-NOMENU;
|
||||
}
|
||||
}
|
||||
Class UPlayerMale2 : UPlayer
|
||||
{
|
||||
Default
|
||||
{
|
||||
Player.SoundClass "umale";
|
||||
Player.DisplayName "$N_MALE2";
|
||||
Player.Portrait "";
|
||||
UTPlayer.VoiceType VOICE_MaleOne;
|
||||
-NOMENU;
|
||||
}
|
||||
}
|
||||
Class UPlayerMale3 : UPlayer
|
||||
{
|
||||
Default
|
||||
{
|
||||
Player.SoundClass "umale";
|
||||
Player.DisplayName "$N_MALE3";
|
||||
Player.Portrait "";
|
||||
UTPlayer.VoiceType VOICE_MaleTwo;
|
||||
-NOMENU;
|
||||
}
|
||||
}
|
||||
Class UPlayerFemale1 : UPlayer
|
||||
{
|
||||
Default
|
||||
{
|
||||
Player.SoundClass "ufemale";
|
||||
Player.DisplayName "$N_FEMALE1";
|
||||
Player.Portrait "";
|
||||
UTPlayer.VoiceType VOICE_FemaleTwo;
|
||||
-NOMENU;
|
||||
}
|
||||
}
|
||||
Class UPlayerFemale2 : UPlayer
|
||||
{
|
||||
Default
|
||||
{
|
||||
Player.SoundClass "ufemale";
|
||||
Player.DisplayName "$N_FEMALE2";
|
||||
Player.Portrait "";
|
||||
UTPlayer.VoiceType VOICE_FemaleOne;
|
||||
-NOMENU;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,119 +234,96 @@ Class UnrealInventory : Inventory
|
|||
}
|
||||
}
|
||||
|
||||
Class UnrealArmor : Armor
|
||||
Class UnrealStaticHandler : StaticEventHandler
|
||||
{
|
||||
int absorb;
|
||||
ui TextureID tex[6];
|
||||
ui int mtics, cur;
|
||||
ui String lastmusic;
|
||||
|
||||
Property ArmorAbsorption : absorb;
|
||||
|
||||
Default
|
||||
ui void StartMenu()
|
||||
{
|
||||
+INVENTORY.AUTOACTIVATE;
|
||||
+INVENTORY.UNTOSSABLE;
|
||||
Inventory.MaxAmount 0;
|
||||
}
|
||||
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
|
||||
{
|
||||
int saved;
|
||||
if ( (amount > 0) && !DamageTypeDefinition.IgnoreArmor(damageType) )
|
||||
{
|
||||
saved = damage*absorb/100.;
|
||||
if ( amount <= saved ) saved = amount;
|
||||
newdamage -= saved;
|
||||
amount -= saved;
|
||||
damage = newdamage;
|
||||
}
|
||||
if ( damage > 0 ) newdamage = ApplyDamageFactors(GetClass(),damageType,damage,damage);
|
||||
if ( amount <= 0 ) Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Class GenericFlash : HUDMessageBase
|
||||
{
|
||||
Color col;
|
||||
int duration;
|
||||
double alpha;
|
||||
Actor cam;
|
||||
GenericFlash Setup( Actor camera, Color c, int d )
|
||||
{
|
||||
alpha = 1.0;
|
||||
col = c;
|
||||
duration = d;
|
||||
cam = camera;
|
||||
return self;
|
||||
}
|
||||
override bool Tick()
|
||||
{
|
||||
alpha -= 1./duration;
|
||||
return (alpha<=0);
|
||||
}
|
||||
override void Draw( int bottom, int visibility )
|
||||
{
|
||||
if ( automapactive || (visibility != BaseStatusBar.HUDMSGLayer_UnderHUD) ) return;
|
||||
if ( cam && (players[consoleplayer].camera != cam) ) return;
|
||||
Screen.Dim(col,(col.a/255.)*alpha,0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
Class QueuedFlash
|
||||
{
|
||||
Color c;
|
||||
int duration;
|
||||
int tic;
|
||||
Actor cam;
|
||||
}
|
||||
|
||||
Class UnrealMainHandler : StaticEventHandler
|
||||
{
|
||||
Array<QueuedFlash> flashes;
|
||||
|
||||
override void WorldLoaded( WorldEvent e )
|
||||
{
|
||||
if ( gamestate != GS_LEVEL || e.IsSaveGame ) return;
|
||||
// prettify Kinsie's test map for a more Unreal feel
|
||||
if ( level.levelname ~== "Modder Test Map" )
|
||||
{
|
||||
TexMan.ReplaceTextures("-noflat-","-kinsie-",0);
|
||||
TextureID skytx = TexMan.CheckForTexture("BlueSky",TexMan.Type_Any);
|
||||
level.ChangeSky(skytx,skytx);
|
||||
// TODO handplace some dynamic lights and add Unreal/UT ambient sounds
|
||||
}
|
||||
CVar protomenu = CVar.GetCVar('stinger_introtype',players[consoleplayer]);
|
||||
if ( !protomenu ) return; // this can happen
|
||||
int proto = protomenu.GetInt();
|
||||
tex[0] = TexMan.CheckForTexture("graphics/UnLogo0.png",TexMan.Type_Any);
|
||||
tex[1] = TexMan.CheckForTexture("graphics/UnLogo1.png",TexMan.Type_Any);
|
||||
tex[2] = TexMan.CheckForTexture("graphics/UnLogo2.png",TexMan.Type_Any);
|
||||
tex[3] = TexMan.CheckForTexture("graphics/UnBg.png",TexMan.Type_Any);
|
||||
tex[4] = TexMan.CheckForTexture("graphics/97Bg.png",TexMan.Type_Any);
|
||||
tex[5] = TexMan.CheckForTexture("graphics/95Bg.png",TexMan.Type_Any);
|
||||
if ( proto > 1 ) S_ChangeMusic("Unreal");
|
||||
else if ( proto == 1 ) S_ChangeMusic("Unreal2");
|
||||
else S_ChangeMusic("FlyBy");
|
||||
cur = proto;
|
||||
}
|
||||
|
||||
override void WorldThingSpawned( WorldEvent e )
|
||||
override void OnRegister()
|
||||
{
|
||||
if ( e.Thing.bBOSS ) e.Thing.bNOTELEFRAG = true;
|
||||
// remove the UT static handler
|
||||
let hnd = UTStaticHandler(StaticEventHandler.Find("UTStaticHandler"));
|
||||
if ( hnd ) hnd.Destroy();
|
||||
}
|
||||
|
||||
override void WorldTick()
|
||||
override void ConsoleProcess( ConsoleEvent e )
|
||||
{
|
||||
for ( int i=0; i<flashes.size(); i++ )
|
||||
{
|
||||
if ( flashes[i].tic >= gametic ) continue;
|
||||
flashes.Delete(i);
|
||||
i--;
|
||||
}
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
if ( e.Name ~== "refreshmenu" ) StartMenu();
|
||||
}
|
||||
|
||||
override void PostUiTick()
|
||||
{
|
||||
for ( int i=0; i<flashes.size(); i++ )
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
if ( gametic <= 0 ) StartMenu();
|
||||
if ( musplaying.Name != lastmusic )
|
||||
{
|
||||
if ( flashes[i].tic < gametic ) continue;
|
||||
GenericFlash gf = new("GenericFlash").Setup(flashes[i].cam,flashes[i].c,flashes[i].duration);
|
||||
StatusBar.AttachMessage(gf,0,BaseStatusBar.HUDMSGLayer_UnderHUD);
|
||||
mtics = 0;
|
||||
lastmusic = musplaying.Name;
|
||||
}
|
||||
else mtics++;
|
||||
}
|
||||
|
||||
static void DoFlash( Actor camera, Color c, int duration )
|
||||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
QueuedFlash qf = new("QueuedFlash");
|
||||
qf.duration = duration;
|
||||
qf.c = c;
|
||||
qf.tic = gametic;
|
||||
qf.cam = camera;
|
||||
let hnd = UnrealMainHandler(StaticEventHandler.Find("UnrealMainHandler"));
|
||||
hnd.flashes.push(qf);
|
||||
// we have to stand in for the UT handler on this function
|
||||
// although it doesn't make much sense yet
|
||||
if ( players[consoleplayer].camera.player && players[consoleplayer].camera.player.ReadyWeapon && (players[consoleplayer].camera.player.ReadyWeapon is 'UTWeapon') )
|
||||
UTWeapon(players[consoleplayer].camera.player.ReadyWeapon).RenderOverlay(e);
|
||||
if ( gamestate != GS_TITLELEVEL ) return;
|
||||
double ar = Screen.GetAspectRatio();
|
||||
Vector2 tsize = TexMan.GetScaledSize(tex[cur+3]);
|
||||
double sar = tsize.x/tsize.y;
|
||||
Vector2 vsize;
|
||||
if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
|
||||
else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
|
||||
else vsize = tsize;
|
||||
Screen.DrawTexture(tex[cur+3],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
|
||||
Screen.Dim("Black",clamp(1.-((mtics+e.FracTic)/Thinker.TICRATE)*.2,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
|
||||
if ( menuactive ) return;
|
||||
tsize = TexMan.GetScaledSize(tex[cur]);
|
||||
sar = tsize.x/tsize.y;
|
||||
if ( sar > ar ) vsize = (tsize.x,tsize.x/ar);
|
||||
else if ( sar < ar ) vsize = (tsize.y*ar,tsize.y);
|
||||
else vsize = tsize;
|
||||
double alf = clamp(((mtics+e.FracTic)/Thinker.TICRATE)-8,0.,1.);
|
||||
Screen.DrawTexture(tex[cur],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_Alpha,alf);
|
||||
}
|
||||
}
|
||||
|
||||
Class UnrealMainHandler : EventHandler
|
||||
{
|
||||
override void CheckReplacement( ReplaceEvent e )
|
||||
{
|
||||
if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') )
|
||||
{
|
||||
/*if ( !Random[Replacements](0,3) ) e.Replacement = 'Enforcer';
|
||||
else if ( Random[Replacements](0,1) ) */e.Replacement = 'Stinger';
|
||||
/*else e.Replacement = 'ShockRifle';*/
|
||||
}
|
||||
else if ( (e.Replacee == 'RocketLauncher') || (e.Replacee == 'PhoenixRod') )
|
||||
{
|
||||
/*if ( Random[Replacements](0,1) ) */e.Replacement = 'UFlakCannon';
|
||||
/*else e.Replacement = 'UTRocketLauncher';*/
|
||||
}
|
||||
else if ( e.Replacee == 'Backpack' ) e.Replacement = 'UnrealBackpack';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,4 @@
|
|||
// An almost 1:1 recreation of the Unreal 1 HUD
|
||||
Class ViewTracer : LineTracer
|
||||
{
|
||||
Actor ignore;
|
||||
|
||||
override ETraceStatus TraceCallback()
|
||||
{
|
||||
if ( Results.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( (Results.HitActor == ignore) || !Results.HitActor.player || !Results.HitActor.bSHOOTABLE || Results.HitActor.bINVISIBLE ) return TRACE_Skip;
|
||||
return TRACE_Stop;
|
||||
}
|
||||
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
|
||||
{
|
||||
if ( !Results.HitLine.sidedef[1] ) return TRACE_Stop;
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class UnrealHUD : BaseStatusBar
|
||||
{
|
||||
double FracTic;
|
||||
|
|
@ -38,6 +18,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
// Fonts
|
||||
Font LargeFont, LargeRedFont, MedFont, WhiteFont, TinyFont,
|
||||
TinyWhiteFont, TinyRedFont;
|
||||
HUDFont mMapFont;
|
||||
|
||||
// Common Textures
|
||||
TextureID HalfHud, HudLine, HudAmmo, IconHeal, IconSkul, IconSel,
|
||||
|
|
@ -64,6 +45,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
TinyFont = Font.FindFont('UTinyFont');
|
||||
TinyWhiteFont = Font.FindFont('UTinyWhiteFont');
|
||||
TinyRedFont = Font.FindFont('UTinyRedFont');
|
||||
mMapFont = HUDFont.Create(WhiteFont);
|
||||
HalfHud = TexMan.CheckForTexture("HalfHud",TexMan.Type_Any);
|
||||
HudLine = TexMan.CheckForTexture("HudLine",TexMan.Type_Any);
|
||||
HudAmmo = TexMan.CheckForTexture("HudAmmo",TexMan.Type_Any);
|
||||
|
|
@ -78,17 +60,19 @@ Class UnrealHUD : BaseStatusBar
|
|||
{
|
||||
Super.Draw(state,TicFrac);
|
||||
HudMode = CVar.GetCVar('stinger_hudmode',players[consoleplayer]).GetInt();
|
||||
scalev.x = scalev.y = Max(1,CVar.GetCVar('stinger_hudscale',players[consoleplayer]).GetInt());
|
||||
scalev.x = scalev.y = Max(0,CVar.GetCVar('stinger_hudscale',players[consoleplayer]).GetInt());
|
||||
if ( scalev.x == 0 )
|
||||
scalev.x = scalev.y = max(1,min(Screen.GetWidth()/640.,Screen.GetHeight()/480.));
|
||||
ClipX = Screen.GetWidth()/scalev.x;
|
||||
ClipY = Screen.GetHeight()/scalev.y;
|
||||
CurX = 0;
|
||||
CurY = 0;
|
||||
double lbottom = Screen.GetHeight()-32*scalev.y; // TODO properly calculate
|
||||
double lbottom = Screen.GetHeight()-32*scalev.y;
|
||||
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
|
||||
if ( i is 'UnrealInventory' )
|
||||
UnrealInventory(i).PreRender(lbottom);
|
||||
if ( CPlayer.ReadyWeapon is 'UnrealWeapon' )
|
||||
UnrealWeapon(CPlayer.ReadyWeapon).PreRender(lbottom);
|
||||
if ( CPlayer.ReadyWeapon is 'UTWeapon' )
|
||||
UTWeapon(CPlayer.ReadyWeapon).PreRender(lbottom);
|
||||
if ( (state == HUD_StatusBar) || (state == HUD_Fullscreen) )
|
||||
{
|
||||
BeginHUD();
|
||||
|
|
@ -98,8 +82,8 @@ Class UnrealHUD : BaseStatusBar
|
|||
for ( Inventory i=CPlayer.mo.inv; i; i=i.inv )
|
||||
if ( i is 'UnrealInventory' )
|
||||
UnrealInventory(i).PostRender(lbottom);
|
||||
if ( CPlayer.ReadyWeapon is 'UnrealWeapon' )
|
||||
UnrealWeapon(CPlayer.ReadyWeapon).PostRender(lbottom);
|
||||
if ( CPlayer.ReadyWeapon is 'UTWeapon' )
|
||||
UTWeapon(CPlayer.ReadyWeapon).PostRender(lbottom);
|
||||
}
|
||||
|
||||
private void DrawNumberOf( int n, double x, double y )
|
||||
|
|
@ -132,8 +116,21 @@ Class UnrealHUD : BaseStatusBar
|
|||
double width = CurX;
|
||||
CurX = x;
|
||||
CurY = y;
|
||||
if ( bRed ) Screen.DrawTexture(i.Icon,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_TranslationIndex,RedIcon);
|
||||
else Screen.DrawTexture(i.Icon,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
||||
// scale to fit
|
||||
Vector2 scl = TexMan.GetScaledSize(i.Icon);
|
||||
double mscl = 32./max(scl.x,scl.y);
|
||||
double dw = (ClipX/mscl), dh = (ClipY/mscl);
|
||||
double dx = CurX/mscl, dy = CurY/mscl;
|
||||
if ( bRed )
|
||||
{
|
||||
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_TranslationIndex,RedIcon);
|
||||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TranslationIndex,RedIcon,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
||||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFragCount( double x, double y )
|
||||
|
|
@ -200,8 +197,11 @@ Class UnrealHUD : BaseStatusBar
|
|||
if ( cw && (cw.SlotNumber != -1) ) cwslot = cw.SlotNumber?(cw.SlotNumber-1):9;
|
||||
let pw = CPlayer.PendingWeapon;
|
||||
int pwslot = -1;
|
||||
if ( pw && (pw.SlotNumber != -1) ) pwslot = pw.SlotNumber?(pw.SlotNumber-1):9;
|
||||
if ( pw && (pw != WP_NOCHANGE) && (pw.SlotNumber != -1) ) pwslot = pw.SlotNumber?(pw.SlotNumber-1):9;
|
||||
Weapon wslots[10];
|
||||
// zero-initialize, fixes asmjit crash
|
||||
for ( int i=0; i<10; i++ )
|
||||
wslots[i] = null;
|
||||
// first run, populate the full array of weapons
|
||||
for ( int i=0; i<10; i++ )
|
||||
{
|
||||
|
|
@ -237,7 +237,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
if ( !wslots[i] ) continue;
|
||||
Font cfont = TinyFont;
|
||||
if ( cwslot == i ) cfont = TinyWhiteFont;
|
||||
int realslot = (i<9)?(i+1):i;
|
||||
int realslot = (i<9)?(i+1):9;
|
||||
CurX = HalfHUDX-3+realslot*6;
|
||||
CurY = HalfHUDY+4;
|
||||
Screen.DrawText(cfont,Font.CR_UNTRANSLATED,CurX,CurY,String.Format("%d",realslot),DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
||||
|
|
@ -262,7 +262,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO draw translator
|
||||
// draw translator
|
||||
if ( translator )
|
||||
{
|
||||
if ( translator.bCurrentlyActivated ) translator.DrawTranslator(scalev,ClipX,ClipY);
|
||||
|
|
@ -303,7 +303,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
CurY = y;
|
||||
for ( Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
||||
{
|
||||
if ( !(Inv is 'UnrealArmor') ) continue;
|
||||
if ( !(Inv is 'UTArmor') ) continue;
|
||||
ArmorAmount += Inv.Amount;
|
||||
if ( (Inv.Amount <= 0) || Inv.Icon.IsNull() ) continue;
|
||||
if ( !bDrawOne )
|
||||
|
|
@ -312,9 +312,9 @@ Class UnrealHUD : BaseStatusBar
|
|||
DrawIconValue(Inv.Amount);
|
||||
CurX += 32;
|
||||
}
|
||||
else if ( UnrealArmor(Inv).absorb > CurAbs )
|
||||
else if ( UTArmor(Inv).absorb > CurAbs )
|
||||
{
|
||||
CurAbs = UnrealArmor(Inv).absorb;
|
||||
CurAbs = UTArmor(Inv).absorb;
|
||||
BestArmor = Inv;
|
||||
}
|
||||
}
|
||||
|
|
@ -346,9 +346,13 @@ Class UnrealHUD : BaseStatusBar
|
|||
}
|
||||
CurX = x;
|
||||
Screen.DrawTexture(IconBase,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true);
|
||||
// TODO downscale icons in cases where they're bigger than a 32x32 box
|
||||
TextureID icon = CPlayer.ReadyWeapon.Icon.IsNull()?CPlayer.ReadyWeapon.Ammo1.Icon:CPlayer.ReadyWeapon.Icon;
|
||||
Screen.DrawTexture(icon,false,CurX+16,CurY+16,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_CenterOffset,true);
|
||||
// scale to fit
|
||||
Vector2 scl = TexMan.GetScaledSize(icon);
|
||||
double mscl = 32./max(scl.x,scl.y);
|
||||
double dw = (ClipX/mscl), dh = (ClipY/mscl);
|
||||
double dx = CurX/mscl, dy = CurY/mscl;
|
||||
Screen.DrawTexture(icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
CurX += 32;
|
||||
CurY += 29;
|
||||
DrawIconValue(CPlayer.ReadyWeapon.Ammo1.Amount);
|
||||
|
|
@ -386,21 +390,21 @@ Class UnrealHUD : BaseStatusBar
|
|||
cl2 = teams[lastseen.player.GetTeam()].mName;
|
||||
cl1 = String.Format("Dark%s",cl2);
|
||||
}
|
||||
String tname = String.Format("\c[%s]Name:\c[%s] %s",cl1,cl2,lastseen.player.GetUserName());
|
||||
String tname = String.Format("\c[%s]%s:\c[%s] %s",cl1,StringTable.Localize("$M_NAME"),cl2,lastseen.player.GetUserName());
|
||||
CurX = (ClipX-WhiteFont.StringWidth(tname))/2;
|
||||
CurY = ClipY-54;
|
||||
Screen.DrawText(WhiteFont,Font.CR_UNTRANSLATED,CurX,CurY,tname,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,lalpha/2.);
|
||||
if ( !deathmatch || (lastseen.IsTeammate(CPlayer.mo)) )
|
||||
{
|
||||
CurY += 1.2*WhiteFont.GetHeight();
|
||||
tname = String.Format("\c[%s]Health:\c[%s] %d",cl1,cl2,lastseen.Health);
|
||||
tname = String.Format("\c[%s]%s:\c[%s] %d",cl1,StringTable.Localize("$M_HEALTH"),cl2,lastseen.Health);
|
||||
Screen.DrawText(WhiteFont,Font.CR_UNTRANSLATED,CurX,CurY,tname,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,lalpha/2.);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawKeys( double x, double y )
|
||||
{
|
||||
// TODO
|
||||
// TODO draws the key icons from right to left, bottom to top
|
||||
}
|
||||
|
||||
private void DrawUnrealHUD()
|
||||
|
|
@ -432,8 +436,8 @@ Class UnrealHUD : BaseStatusBar
|
|||
else if ( HudMode == 3 ) DrawFragCount(0,ClipY-64);
|
||||
else if ( HudMode == 4 ) DrawFragCount(0,ClipY-32);
|
||||
// Display Keys
|
||||
if ( HudMode < 3 ) DrawKeys(ClipX,ClipY-64);
|
||||
else if ( HudMode < 6 ) DrawKeys(ClipX,ClipY);
|
||||
if ( HudMode < 3 ) DrawKeys(ClipX-32,ClipY-32);
|
||||
else if ( HudMode < 6 ) DrawKeys(ClipX,ClipY-32);
|
||||
// Display Identification Info
|
||||
DrawIdentifyInfo();
|
||||
}
|
||||
|
|
@ -449,7 +453,71 @@ Class UnrealHUD : BaseStatusBar
|
|||
CPlayer.inventorytics = 0;
|
||||
}
|
||||
|
||||
override void DrawAutomapHUD( double TicFrac )
|
||||
override void DrawAutomapHUD( double ticFrac )
|
||||
{
|
||||
int crdefault = Font.CR_GREY;
|
||||
int highlight = Font.CR_RED;
|
||||
double cbottom = Screen.GetHeight()*0.99;
|
||||
let scale = GetHUDScale();
|
||||
double textdist = 8./scale.Y;
|
||||
int height = WhiteFont.GetHeight();
|
||||
String printtext;
|
||||
int SCREENWIDTH = screen.GetWidth();
|
||||
BeginHUD();
|
||||
let y = textdist;
|
||||
let width = WhiteFont.StringWidth("00:00:00");
|
||||
double tmp, hres;
|
||||
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution);
|
||||
double swidth = 0;
|
||||
double ltop = 0, rtop = 0;
|
||||
if ( HudMode < 2 )
|
||||
{
|
||||
for ( Inventory Inv=CPlayer.mo.Inv; Inv; Inv=Inv.Inv )
|
||||
{
|
||||
if ( !(Inv is 'UTArmor') ) continue;
|
||||
if ( (Inv.Amount <= 0) || Inv.Icon.IsNull() ) continue;
|
||||
rtop += 64*scalev.y;
|
||||
break;
|
||||
}
|
||||
if ( CPlayer.mo.InvSel ) ltop += 64*scalev.y;
|
||||
}
|
||||
int protrusion = GetProtrusion(swidth/hres);
|
||||
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,protrusion);
|
||||
width += int((swidth-hres)/scale.X);
|
||||
if ( am_showtime )
|
||||
{
|
||||
printtext = level.TimeFormatted();
|
||||
DrawString(mMapFont,level.TimeFormatted(),(-textdist-width,y+rtop),0,crdefault);
|
||||
y += height;
|
||||
}
|
||||
if ( am_showtotaltime ) DrawString(mMapFont,level.TimeFormatted(true),(-textdist-width,y+rtop),0,crdefault);
|
||||
if ( !deathmatch )
|
||||
{
|
||||
y = textdist;
|
||||
if ( am_showmonsters )
|
||||
{
|
||||
DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_MONSTERS"),crdefault+65,level.killed_monsters,level.total_monsters),(textdist,y+ltop),0,highlight);
|
||||
y += height;
|
||||
}
|
||||
if ( am_showsecrets )
|
||||
{
|
||||
DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_SECRETS"),crdefault+65,level.found_secrets,level.total_secrets),(textdist,y+ltop),0,highlight);
|
||||
y += height;
|
||||
}
|
||||
if ( am_showitems ) DrawString(mMapFont,String.Format("%s\34%c %d/%d",Stringtable.Localize("$AM_ITEMS"),crdefault+65,level.found_items,level.total_items),(textdist,y+ltop),0,highlight);
|
||||
}
|
||||
String mapname = level.FormatMapName(crdefault);
|
||||
BrokenLines lines = WhiteFont.BreakLines(mapname,int(SCREENWIDTH/scale.X));
|
||||
int numlines = lines.Count();
|
||||
int finalwidth = int(WhiteFont.StringWidth(lines.StringAt(numlines-1))*scale.X);
|
||||
[tmp,tmp,hres] = StatusbarToRealCoords(0,0,HorizontalResolution);
|
||||
protrusion = GetProtrusion(finalwidth/hres);
|
||||
[tmp,tmp,tmp,hres] = StatusbarToRealCoords(0,0,0,protrusion);
|
||||
y = (cbottom-hres)/scale.Y-height*numlines;
|
||||
for ( int i = 0; i < numlines; i++ )
|
||||
{
|
||||
DrawString(mMapFont,lines.StringAt(i),(0,y+ltop),DI_TEXT_ALIGN_CENTER|DI_SCREEN_HCENTER|DI_SCREEN_TOP,highlight);
|
||||
y += height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
103
zscript/unrealmenus.zsc
Normal file
103
zscript/unrealmenus.zsc
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// draws unreal-style main menu
|
||||
Class ListMenuItemUnrealBg : ListMenuItem
|
||||
{
|
||||
TextureID tex[3];
|
||||
|
||||
void Init( ListMenuDescriptor desc, String dummy )
|
||||
{
|
||||
Super.Init(0,0);
|
||||
tex[0] = TexMan.CheckForTexture("graphics/rmetal.png",TexMan.Type_Any);
|
||||
tex[1] = TexMan.CheckForTexture("graphics/menubarr.png",TexMan.Type_Any);
|
||||
tex[2] = TexMan.CheckForTexture("graphics/unlogo.png",TexMan.Type_Any);
|
||||
}
|
||||
|
||||
override void Drawer( bool selected )
|
||||
{
|
||||
double StartX = 0.5*CleanWidth_1-128;
|
||||
int num = (CleanHeight_1/512)+1;
|
||||
for ( int i=0; i<=num; i++ )
|
||||
Screen.DrawTexture(tex[0],false,StartX*CleanXFac_1,512*CleanYFac_1*i,DTA_CleanNoMove_1,true);
|
||||
Screen.DrawTexture(tex[1],false,StartX*CleanXFac_1,(CleanHeight_1-58)*CleanYFac_1,DTA_CleanNoMove_1,true,DTA_LegacyRenderStyle,STYLE_Add);
|
||||
Screen.DrawTexture(tex[2],false,StartX*CleanXFac_1,(CleanHeight_1-52)*CleanYFac_1,DTA_CleanNoMove_1,true);
|
||||
}
|
||||
}
|
||||
|
||||
Class ListMenuItemUnrealTextItem : ListMenuItemSelectable
|
||||
{
|
||||
String mText;
|
||||
Font mFont;
|
||||
int mColor;
|
||||
int mSpacing;
|
||||
|
||||
void Init( ListMenuDescriptor desc, String text, String hotkey, Name child, int param = 0 )
|
||||
{
|
||||
Super.Init(desc.mXpos,desc.mYpos,desc.mLinespacing,child,param);
|
||||
mText = text;
|
||||
mFont = Font.GetFont('ULargeFont');
|
||||
mColor = Font.CR_UNTRANSLATED;
|
||||
mSpacing = desc.mLineSpacing;
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
}
|
||||
|
||||
void InitDirect( double x, double y, int height, String hotkey, String text, Font font, int color, int color2, Name child, int param = 0 )
|
||||
{
|
||||
Super.Init(x,y,height,child,param);
|
||||
mText = text;
|
||||
mFont = Font.GetFont('ULargeFont');
|
||||
mColor = Font.CR_UNTRANSLATED;
|
||||
int pos = 0;
|
||||
mHotkey = hotkey.GetNextCodePoint(0);
|
||||
}
|
||||
|
||||
override void Drawer( bool selected )
|
||||
{
|
||||
let tFont = generic_ui?NewSmallFont:mFont;
|
||||
double basex = floor(0.5*(CleanWidth_1-tFont.StringWidth(StringTable.Localize(mText))));
|
||||
double basey = floor(0.25*(CleanHeight_1-mSpacing*5));
|
||||
Screen.DrawText(tFont,mColor,(basex+mXPos)*CleanXFac_1,(basey+mYpos)*CleanYFac_1,mText,DTA_CleanNoMove_1,true,DTA_Alpha,selected?1.0:0.5);
|
||||
}
|
||||
|
||||
override int GetWidth()
|
||||
{
|
||||
let tFont = generic_ui?NewSmallFont:mFont;
|
||||
return max(1,tFont.StringWidth(StringTable.Localize(mText)));
|
||||
}
|
||||
|
||||
override void DrawSelector( double xofs, double yofs, TextureID tex )
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
// for hud config
|
||||
Class OptionMenuItemHudType : OptionMenuItem
|
||||
{
|
||||
TextureID tex[6];
|
||||
CVar mCVar;
|
||||
|
||||
OptionMenuItemHudType Init( String label )
|
||||
{
|
||||
Super.Init(label,"",true);
|
||||
mCVar = CVar.FindCVar('stinger_hudmode');
|
||||
tex[0] = TexMan.CheckForTexture("graphics/Hud1.png",TexMan.Type_Any);
|
||||
tex[1] = TexMan.CheckForTexture("graphics/Hud2.png",TexMan.Type_Any);
|
||||
tex[2] = TexMan.CheckForTexture("graphics/Hud3.png",TexMan.Type_Any);
|
||||
tex[3] = TexMan.CheckForTexture("graphics/Hud4.png",TexMan.Type_Any);
|
||||
tex[4] = TexMan.CheckForTexture("graphics/Hud5.png",TexMan.Type_Any);
|
||||
tex[5] = TexMan.CheckForTexture("graphics/Hud6.png",TexMan.Type_Any);
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool Selectable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
override int Draw( OptionMenuDescriptor desc, int y, int indent, bool selected )
|
||||
{
|
||||
int xpos = indent + CursorSpace();
|
||||
int ypos = y + OptionMenuSettings.mLinespacing*CleanYfac_1;
|
||||
Screen.DrawTexture(tex[mCVar.GetInt()],false,xpos,ypos,DTA_CleanNoMove_1,true);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue