Addition to HUD for showing clip counts (kinda cheap-looking, but still better than what Oldskool did). Charge for some weapons and loaded rockets for eightball also use the clipcount display, like in Doom Tournament. Small fixups for dual wielding logic.
1267 lines
37 KiB
Text
1267 lines
37 KiB
Text
Class UPlayer : UTPlayer
|
|
{
|
|
Default
|
|
{
|
|
Player.StartItem "Automag";
|
|
Player.StartItem "DispersionPistol";
|
|
Player.StartItem "UMiniAmmo", 30;
|
|
Player.StartItem "DefaultAmmo", 50;
|
|
}
|
|
|
|
override void GiveDefaultInventory()
|
|
{
|
|
if ( !player ) return;
|
|
// HexenArmor must always be the first item in the inventory because
|
|
// it provides player class based protection that should not affect
|
|
// any other protection item.
|
|
let myclass = GetClass();
|
|
GiveInventoryType('HexenArmor');
|
|
let harmor = HexenArmor(FindInventory('HexenArmor'));
|
|
harmor.Slots[4] = self.HexenArmor[0];
|
|
for ( int i=0; i<4; ++i ) harmor.SlotsIncrement[i] = self.HexenArmor[i+1];
|
|
// BasicArmor must come right after that. It should not affect any
|
|
// other protection item as well but needs to process the damage
|
|
// before the HexenArmor does.
|
|
GiveInventoryType('BasicArmor');
|
|
// Now add the items from the DECORATE definition
|
|
let di = GetDropItems();
|
|
for ( DropItem di=GetDropItems(); di; di=di.Next )
|
|
{
|
|
Class<Actor> ti = di.Name;
|
|
if ( !ti ) continue;
|
|
// no pistol start
|
|
if ( sting_nopstart && ((ti is 'Automag') || (ti is 'UMiniAmmo')) ) continue;
|
|
let tinv = (class<Inventory>)(ti);
|
|
if ( !tinv )
|
|
{
|
|
Console.Printf(TEXTCOLOR_ORANGE.."%s is not an inventory item and cannot be given to a player as start item.\n",di.Name);
|
|
continue;
|
|
}
|
|
let item = FindInventory(tinv);
|
|
if ( item ) item.Amount = clamp(item.Amount+(di.Amount?di.Amount:item.default.Amount),0,item.MaxAmount);
|
|
else
|
|
{
|
|
item = Inventory(Spawn(ti));
|
|
item.bIgnoreSkill = true; // no skill multipliers here
|
|
item.Amount = di.Amount;
|
|
let weap = Weapon(item);
|
|
if ( weap )
|
|
{
|
|
// To allow better control any weapon is emptied of
|
|
// ammo before being given to the player.
|
|
weap.AmmoGive1 = weap.AmmoGive2 = 0;
|
|
}
|
|
bool res;
|
|
Actor check;
|
|
[res,check] = item.CallTryPickup(self);
|
|
if ( !res )
|
|
{
|
|
item.Destroy();
|
|
item = null;
|
|
}
|
|
else if ( check != self )
|
|
{
|
|
// Player was morphed. This is illegal at game start.
|
|
// This problem is only detectable when it's too late to do something about it...
|
|
ThrowAbortException("Cannot give morph item '%s' when starting a game!",di.Name);
|
|
}
|
|
}
|
|
let weap = Weapon(item);
|
|
if ( weap && weap.CheckAmmo(Weapon.EitherFire,false) )
|
|
player.ReadyWeapon = player.PendingWeapon = weap;
|
|
}
|
|
}
|
|
|
|
// Have to modify the give cheat to handle UT armor
|
|
override void CheatGive( String name, int amount )
|
|
{
|
|
if ( PlayerNumber() != consoleplayer )
|
|
A_Log(String.Format("%s is a cheater: give %s\n",player.GetUserName(),name));
|
|
if ( !player.mo || (player.health <= 0) ) return;
|
|
int giveall = ALL_NO;
|
|
if ( name ~== "all" ) giveall = ALL_YES;
|
|
else if (name ~== "everything") giveall = ALL_YESYES;
|
|
if ( name ~== "health" )
|
|
{
|
|
if ( amount > 0 )
|
|
{
|
|
health += amount;
|
|
player.health = health;
|
|
}
|
|
else player.health = health = GetMaxHealth(true);
|
|
}
|
|
if ( giveall || (name ~== "backpack") )
|
|
{
|
|
// Select the correct type of backpack based on the game
|
|
let type = (class<Inventory>)(gameinfo.backpacktype);
|
|
if ( type ) GiveInventory(type,1,true);
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "ammo") )
|
|
{
|
|
// Find every unique type of ammo. Give it to the player if
|
|
// he doesn't have it already, and set each to its maximum.
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<Ammo>)(AllActorClasses[i]);
|
|
if ( !type || (type.GetParentClass() != "Ammo") )
|
|
continue;
|
|
// Only give if it's for a valid weapon, unless using "give everything"
|
|
bool isvalid = false;
|
|
for ( int j=0; j<AllActorClasses.Size(); j++ )
|
|
{
|
|
let type2 = (class<Weapon>)(AllActorClasses[j]);
|
|
if ( !type2 ) continue;
|
|
let rep = GetReplacement(type2);
|
|
if ( (rep != type2) && !(rep is "DehackedPickup") ) continue;
|
|
readonly<Weapon> weap = GetDefaultByType(type2);
|
|
if ( !player.weapons.LocateWeapon(type2) || (weap.bCheatNotWeapon && (giveall != ALL_YESYES)) ) continue;
|
|
if ( (weap.AmmoType1 == type) || (weap.AmmoType2 == type) )
|
|
{
|
|
isvalid = true;
|
|
break;
|
|
}
|
|
}
|
|
if ( !isvalid ) continue;
|
|
let ammoitem = FindInventory(type);
|
|
if ( !ammoitem )
|
|
{
|
|
ammoitem = Inventory(Spawn(type));
|
|
ammoitem.AttachToOwner(self);
|
|
ammoitem.Amount = ammoitem.MaxAmount;
|
|
}
|
|
else if ( ammoitem.Amount < ammoitem.MaxAmount )
|
|
ammoitem.Amount = ammoitem.MaxAmount;
|
|
}
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "armor") )
|
|
{
|
|
// Doomreal gives the player all subclasses of UnrealArmor
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
if ( !(AllActorClasses[i].GetParentClass() is "UnrealArmor") ) continue;
|
|
let item = Inventory(Spawn(AllActorClasses[i]));
|
|
item.ClearCounters(); // don't increase item counts
|
|
if ( !item.CallTryPickup(self) ) item.Destroy();
|
|
}
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "keys") )
|
|
{
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
if ( !(AllActorClasses[i] is "Key") ) continue;
|
|
let keyitem = GetDefaultByType(AllActorClasses[i]);
|
|
if ( keyitem.special1 )
|
|
{
|
|
let item = Inventory(Spawn(AllActorClasses[i]));
|
|
if ( !item.CallTryPickup(self) ) item.Destroy();
|
|
}
|
|
}
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "weapons") )
|
|
{
|
|
let savedpending = player.PendingWeapon;
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<Weapon>)(AllActorClasses[i]);
|
|
if ( !type || (type == "Weapon") ) continue;
|
|
// Don't give replaced weapons unless the replacement was done by Dehacked.
|
|
let rep = GetReplacement(type);
|
|
if ( (rep == type) || (rep is "DehackedPickup") )
|
|
{
|
|
// Give the weapon only if it is set in a weapon slot.
|
|
if ( !player.weapons.LocateWeapon(type) ) continue;
|
|
readonly<Weapon> def = GetDefaultByType(type);
|
|
if ( (giveall == ALL_YESYES) || !def.bCheatNotWeapon )
|
|
{
|
|
GiveInventory(type,1,true);
|
|
if ( (type is 'Automag') && sting_automags )
|
|
{
|
|
// force akimbo
|
|
let t = FindInventory(type);
|
|
if ( t ) t.Amount = 2;
|
|
}
|
|
else if ( (type is 'Betamag') && sting_protomags )
|
|
{
|
|
// force akimbo
|
|
let t = FindInventory(type);
|
|
if ( t ) t.Amount = 2;
|
|
}
|
|
else if ( type is 'DispersionPistol' )
|
|
{
|
|
// force upgrade
|
|
let dsp = DispersionPistol(FindInventory('DispersionPistol'));
|
|
if ( dsp )
|
|
{
|
|
dsp.Ammo1.MaxAmount = 90;
|
|
if ( player.ReadyWeapon == dsp )
|
|
dsp.pendingupgrade = 4;
|
|
else
|
|
{
|
|
dsp.upgradelevel = 4;
|
|
dsp.MainUse = min(6,dsp.upgradelevel+1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
player.PendingWeapon = savedpending;
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "artifacts") )
|
|
{
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<Inventory>)(AllActorClasses[i]);
|
|
if ( !type ) continue;
|
|
let def = GetDefaultByType (type);
|
|
if ( def.Icon.isValid() && ((def.MaxAmount > 1) || (type is 'UnrealInventory')) &&
|
|
!(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") && !(type is "Armor") )
|
|
{
|
|
// Do not give replaced items unless using "give everything"
|
|
if ( (giveall == ALL_YESYES) || (GetReplacement(type) == type) )
|
|
GiveInventory(type,(amount<=0)?def.MaxAmount:amount,true);
|
|
}
|
|
}
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall || (name ~== "puzzlepieces") )
|
|
{
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<PuzzleItem>)(AllActorClasses[i]);
|
|
if ( !type ) continue;
|
|
let def = GetDefaultByType(type);
|
|
if ( !def.Icon.isValid() ) continue;
|
|
// Do not give replaced items unless using "give everything"
|
|
if ( (giveall == ALL_YESYES) || (GetReplacement(type) == type) )
|
|
GiveInventory(type,(amount<=0)?def.MaxAmount:amount,true);
|
|
}
|
|
if ( !giveall ) return;
|
|
}
|
|
if ( giveall ) return;
|
|
let type = name;
|
|
if ( !type )
|
|
{
|
|
if ( PlayerNumber() == consoleplayer )
|
|
A_Log(String.Format("Unknown item \"%s\"\n",name));
|
|
}
|
|
else GiveInventory(type,amount,true);
|
|
}
|
|
|
|
override void PlayAttacking()
|
|
{
|
|
// no animation if crouched
|
|
if ( (player && (player.mo == self)) && (player.crouchdir == -1) ) return;
|
|
// check weapon type
|
|
if ( ((player.ReadyWeapon is 'URifle') && !sting_rifle && (player.buttons&BT_ALTATTACK)) || ((player.ReadyWeapon is 'Peacemaker') && player.buttons&BT_ALTATTACK) )
|
|
return;
|
|
let psp = player.FindPSprite(PSP_WEAPON);
|
|
if ( ((player.ReadyWeapon is 'UBioRifle') && (player.buttons&BT_ALTATTACK))
|
|
|| (player.ReadyWeapon is 'Eightball')
|
|
|| ((player.ReadyWeapon is 'DispersionPistol') && DispersionPistol(player.ReadyWeapon).bCharging)
|
|
|| ((player.ReadyWeapon is 'UBioRifle') && UBioRifle(player.ReadyWeapon).bCharging)
|
|
|| (player.ReadyWeapon is 'Razorjack') )
|
|
{
|
|
if ( !InStateSequence(CurState,FindState("MissileRepStill")) )
|
|
SetStateLabel("MissileRepStill");
|
|
}
|
|
else if ( ((player.ReadyWeapon is 'Stinger') && psp
|
|
&& psp.CurState.InStateSequence(player.ReadyWeapon.FindState("Hold")))
|
|
|| (player.ReadyWeapon is 'UFlamethrower') || (player.ReadyWeapon is 'UMinigun')
|
|
|| ((player.ReadyWeapon is 'Bonesaw') && player.buttons&BT_ATTACK)
|
|
|| ((player.ReadyWeapon is 'Impaler') && psp.CurState.InStateSequence(player.ReadyWeapon.FindState("AltHold"))) )
|
|
{
|
|
if ( !InStateSequence(CurState,FindState("MissileRep")) )
|
|
SetStateLabel("MissileRep");
|
|
}
|
|
else SetStateLabel("Missile");
|
|
}
|
|
|
|
override void PlayFootstep( double vol )
|
|
{
|
|
let boot = UJumpBoots(FindInventory("UJumpBoots"));
|
|
if ( boot ) A_PlaySound("u1/bootfootstep",CHAN_5,min(1.,vol*2));
|
|
else A_PlaySound("ut/playerfootstep",CHAN_5,vol);
|
|
}
|
|
}
|
|
|
|
Class UFemaleArmGibber : UTGibber
|
|
{
|
|
bool firstgib;
|
|
|
|
override void BurstGibs()
|
|
{
|
|
Actor a;
|
|
double ang, pt;
|
|
Vector3 dir;
|
|
if ( !firstgib )
|
|
{
|
|
firstgib = true;
|
|
Actor a = Spawn("UTFemaleArm",Vec3Offset(-14*sin(angle),14*cos(angle),36));
|
|
ang = FRandom[Blod](0,360);
|
|
pt = FRandom[Blod](-90,90);
|
|
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
|
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
|
|
}
|
|
for ( int i=0; i<gibsize; i++ )
|
|
{
|
|
Vector3 box = (FRandom[Blod](-4,4),FRandom[Blod](12,18),FRandom[Blod](32,40));
|
|
let a = Spawn("UTBloodPuff",Vec3Offset(box.x*cos(angle)-box.y*sin(angle),box.x*sin(angle)+box.y*cos(angle),box.z));
|
|
ang = FRandom[Blod](0,360);
|
|
pt = FRandom[Blod](-90,90);
|
|
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
|
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
|
|
}
|
|
A_CountDown();
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
gibsize = 3;
|
|
reactiontime = 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 0 NoDelay; // no sound, done by player
|
|
TNT1 A 1 BurstGibs();
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class UPlayerFemale : UPlayer
|
|
{
|
|
Default
|
|
{
|
|
Player.SoundClass "ufemale";
|
|
UTPlayer.VoiceType VOICE_FemaleOne;
|
|
}
|
|
|
|
void A_ArmPop()
|
|
{
|
|
armlessL = true;
|
|
let a = Actor.Spawn("UFemaleArmGibber",pos);
|
|
a.vel = vel;
|
|
a.Scale = Scale;
|
|
a.A_SetSize(radius,height);
|
|
UTGibber(a).Gibbed = self;
|
|
}
|
|
|
|
States
|
|
{
|
|
Reload:
|
|
#### # 3;
|
|
PLYR ABCDEF 4;
|
|
Goto Spawn;
|
|
Death.Zapped:
|
|
#### # 0;
|
|
Goto Death;
|
|
Death.Decapitated:
|
|
#### # 0 A_HeadPop();
|
|
PLD6 A 3 A_PlayerScream();
|
|
PLD6 B 3 A_NoBlocking();
|
|
PLD6 CDEFGHIJ 3;
|
|
PLD6 K 1 A_DMFade();
|
|
Wait;
|
|
Death:
|
|
#### # 0 A_JumpIf(Health<(GetGibHealth()/3),"Death7");
|
|
#### # 0 A_JumpIf(vel.length()>20,"Death2");
|
|
#### # 0 A_JumpIf(vel.length()>10,"Death5");
|
|
#### # 0 A_Jump(256,"Death1","Death3","Death4");
|
|
Death1:
|
|
#### # 3;
|
|
PLD1 A 3 A_PlayerScream();
|
|
PLD1 B 3 A_NoBlocking();
|
|
PLD1 CDEFGHIJKLMNOPQRSTU 3;
|
|
PLD1 V 1 A_DMFade();
|
|
Wait;
|
|
Death2:
|
|
#### # 3;
|
|
PLD2 A 3 A_PlayerScream();
|
|
PLD2 B 3 A_NoBlocking();
|
|
PLD2 CDEFGHIJKLMNOPQ 3;
|
|
PLD2 R 1 A_DMFade();
|
|
Wait;
|
|
Death3:
|
|
#### # 3;
|
|
PLD3 A 3 A_PlayerScream();
|
|
PLD3 B 3 A_NoBlocking();
|
|
PLD3 CDEFGHIJKLMNO 3;
|
|
PLD3 P 1 A_DMFade();
|
|
Wait;
|
|
Death4:
|
|
#### # 3;
|
|
PLD4 A 3 A_PlayerScream();
|
|
PLD4 B 3 A_NoBlocking();
|
|
PLD4 CDEFGHIJKL 3;
|
|
PLD4 M 1 A_DMFade();
|
|
Wait;
|
|
Death5:
|
|
#### # 3;
|
|
PLD5 A 3 A_PlayerScream();
|
|
PLD5 B 3 A_NoBlocking();
|
|
PLD5 CDEFGHIJKLMNO 3;
|
|
PLD5 P 1 A_DMFade();
|
|
Wait;
|
|
Death7:
|
|
#### # 0 A_ArmPop();
|
|
PLD7 A 3 A_PlayerScream();
|
|
PLD7 B 3 A_NoBlocking();
|
|
PLD7 CDEFGHIJKLMNOPQRSTUV 3;
|
|
PLD7 W 1 A_DMFade();
|
|
Wait;
|
|
Taunt1:
|
|
#### # 5;
|
|
PLT1 ABCDEFGHIJKLMNO 3;
|
|
Goto Spawn+1;
|
|
Taunt2:
|
|
#### # 5;
|
|
PLT2 ABCDEFGHIJKLMNOPQR 3;
|
|
Goto Spawn+1;
|
|
Taunt3:
|
|
#### # 5;
|
|
PLT3 ABCDEFGHIJKLMNO 3;
|
|
Goto Spawn+1;
|
|
Taunt4:
|
|
#### # 0;
|
|
Goto Spawn;
|
|
}
|
|
}
|
|
|
|
Class UPlayerFemale1 : UPlayerFemale
|
|
{
|
|
Default
|
|
{
|
|
Player.DisplayName "$N_FEMALE1";
|
|
UTPlayer.VoiceType VOICE_FemaleTwo;
|
|
-NOMENU;
|
|
}
|
|
States
|
|
{
|
|
See:
|
|
GINA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class UPlayerFemale2 : UPlayerFemale
|
|
{
|
|
Default
|
|
{
|
|
Player.SoundClass "ufemale";
|
|
Player.DisplayName "$N_FEMALE2";
|
|
-NOMENU;
|
|
}
|
|
States
|
|
{
|
|
See:
|
|
SONY A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UMaleTorsoGibber : UTGibber
|
|
{
|
|
bool firstgib;
|
|
|
|
override void BurstGibs()
|
|
{
|
|
static const class<Actor> parts[] = {"UTMaleArm","UTMaleArm","UTMaleTorso","UTHeadMale","UTHeart","UTLiver","UTStomach"};
|
|
static const double partofsy[] = {14,-14,0,0,-2,5,-3};
|
|
static const double partofsz[] = {36,36,32,48,40,32,35};
|
|
Actor a;
|
|
double ang, pt;
|
|
Vector3 dir;
|
|
if ( !firstgib )
|
|
{
|
|
firstgib = true;
|
|
for ( int i=0; i<7; i++ )
|
|
{
|
|
Actor a = Spawn(parts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
|
|
ang = FRandom[Blod](0,360);
|
|
pt = FRandom[Blod](-90,90);
|
|
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
|
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
|
|
}
|
|
}
|
|
for ( int i=0; i<gibsize; i++ )
|
|
{
|
|
Vector3 box = (FRandom[Blod](-15,15),FRandom[Blod](15,15),FRandom[Blod](30,50));
|
|
let a = Spawn("UTBloodPuff",Vec3Offset(box.x*cos(angle)-box.y*sin(angle),box.x*sin(angle)+box.y*cos(angle),box.z));
|
|
ang = FRandom[Blod](0,360);
|
|
pt = FRandom[Blod](-90,90);
|
|
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
|
|
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
|
|
}
|
|
A_CountDown();
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
gibsize = 3;
|
|
reactiontime = 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 0 NoDelay; // no sound, done by player
|
|
TNT1 A 1 BurstGibs();
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
Class UPlayerMale : UPlayer
|
|
{
|
|
Default
|
|
{
|
|
Player.SoundClass "umale1";
|
|
UTPlayer.VoiceType VOICE_MaleOne;
|
|
}
|
|
|
|
void A_TorsoPop()
|
|
{
|
|
headless = true;
|
|
armlessL = true;
|
|
armlessR = true;
|
|
torsoless = true;
|
|
let a = Actor.Spawn("UMaleTorsoGibber",pos);
|
|
a.vel = vel;
|
|
a.Scale = Scale;
|
|
a.A_SetSize(radius,height);
|
|
UTGibber(a).Gibbed = self;
|
|
}
|
|
|
|
States
|
|
{
|
|
Death:
|
|
#### # 0 A_JumpIf(Health<(GetGibHealth()/3),"Death5");
|
|
#### # 0 A_JumpIf(vel.length()>20,"Death6");
|
|
#### # 0 A_JumpIf(vel.length()>10,"Death1");
|
|
#### # 0 A_Jump(256,"Death2","Death3","Death7");
|
|
Death5:
|
|
#### # 0 A_TorsoPop();
|
|
PLD5 A 3 A_PlayerScream();
|
|
PLD5 B 3 A_NoBlocking();
|
|
PLD5 CDEFGHIJKLMNOPQRSTUV 3;
|
|
PLD5 W 1 A_DMFade();
|
|
Wait;
|
|
Death6:
|
|
#### # 3;
|
|
PLD6 A 3 A_PlayerScream();
|
|
PLD6 B 3 A_NoBlocking();
|
|
PLD6 CDEFGHIJKLMNOPQRSTUVWXYZ[ 3;
|
|
PLD6 \ 1 A_DMFade();
|
|
Wait;
|
|
Taunt1:
|
|
#### # 5;
|
|
PLT1 ABCDEFG 6;
|
|
Goto Spawn+1;
|
|
Taunt2:
|
|
#### # 5;
|
|
PLT2 ABCDEFGHIJKLMNOPQRSTUVWXY 3;
|
|
Goto Spawn+1;
|
|
Taunt3:
|
|
#### # 5;
|
|
PLT3 ABCDEFGHIJKLMNO 3;
|
|
Goto Spawn+1;
|
|
Taunt4:
|
|
#### # 0;
|
|
Goto Spawn;
|
|
}
|
|
}
|
|
Class UPlayerMale1 : UPlayerMale
|
|
{
|
|
override void PlayFootstep( double vol )
|
|
{
|
|
let boot = UJumpBoots(FindInventory("UJumpBoots"));
|
|
if ( boot ) A_PlaySound("u1/bootfootstep",CHAN_5,min(1.,vol*2));
|
|
else
|
|
{
|
|
double ang = level.time/(20*TICRATE/35.)*360.;
|
|
if ( sin(ang) > 0 ) A_PlaySound("u1/metalfootstep",CHAN_5,min(1.,vol*2));
|
|
else A_PlaySound("ut/playerfootstep",CHAN_5,vol);
|
|
}
|
|
}
|
|
Default
|
|
{
|
|
Player.DisplayName "$N_MALE1";
|
|
-NOMENU;
|
|
}
|
|
States
|
|
{
|
|
See:
|
|
KURG A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class UPlayerMale2 : UPlayerMale
|
|
{
|
|
Default
|
|
{
|
|
Player.SoundClass "umale2";
|
|
Player.DisplayName "$N_MALE2";
|
|
-NOMENU;
|
|
}
|
|
States
|
|
{
|
|
See:
|
|
ASH_ A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
Class UPlayerMale3 : UPlayerMale
|
|
{
|
|
Default
|
|
{
|
|
Player.SoundClass "umale3";
|
|
Player.DisplayName "$N_MALE3";
|
|
UTPlayer.VoiceType VOICE_MaleTwo;
|
|
-NOMENU;
|
|
}
|
|
States
|
|
{
|
|
See:
|
|
DANT A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UnrealInventory : Inventory
|
|
{
|
|
bool bActive; // is currently activated
|
|
int Charge; // for timed items
|
|
int DefaultCharge;
|
|
private int UItemFlags;
|
|
|
|
Property Charge : DefaultCharge;
|
|
|
|
FlagDef DrawSpecial : UItemFlags, 0; // hud draws special1 as amount
|
|
|
|
// Drawstuffs under HUD
|
|
virtual ui void PreRender( double lbottom ) {}
|
|
// Drawstuffs over HUD
|
|
virtual ui void PostRender( double lbottom ) {}
|
|
|
|
virtual bool DrainCharge( int val )
|
|
{
|
|
Charge -= val;
|
|
if ( Charge > 0 ) return false;
|
|
if ( Amount > 1 )
|
|
{
|
|
Amount--;
|
|
Charge = DefaultCharge;
|
|
bActive = false;
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
override void AttachToOwner( Actor other )
|
|
{
|
|
Super.AttachToOwner(other);
|
|
if ( !Charge ) Charge = DefaultCharge;
|
|
InterHubAmount = MaxAmount; // it's annoying to set this per-subclass
|
|
}
|
|
override bool HandlePickup( Inventory item )
|
|
{
|
|
if ( (item.GetClass() == GetClass()) && ((MaxAmount > 1) || (DefaultCharge > 0)) )
|
|
{
|
|
if ( MaxAmount > 1 )
|
|
{
|
|
if ( UnrealInventory(item).Charge ) // redistribute charge among copies
|
|
{
|
|
int addcharge = Charge+UnrealInventory(item).Charge;
|
|
charge = min(DefaultCharge,addcharge);
|
|
// if there's charge to spare, increase amount
|
|
if ( addcharge > charge )
|
|
{
|
|
Amount = min(MaxAmount,Amount+item.Amount);
|
|
charge = addcharge-charge;
|
|
}
|
|
}
|
|
else Amount = min(MaxAmount,Amount+item.Amount); // fully charged new copy, just increase
|
|
}
|
|
else Charge = DefaultCharge; // reset charge
|
|
item.bPickupGood = true;
|
|
return true;
|
|
}
|
|
return Super.HandlePickup(item);
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
// don't slide on floor when dropped
|
|
if ( bDROPPED && (pos.z <= floorz) )
|
|
vel.xy *= 0;
|
|
}
|
|
override void DetachFromOwner()
|
|
{
|
|
Super.DetachFromOwner();
|
|
// deactivate
|
|
bActive = false;
|
|
}
|
|
override void OnDrop( Actor dropper )
|
|
{
|
|
Super.OnDrop(dropper);
|
|
// drop like weapons
|
|
Vector2 hofs = RotateVector((dropper.radius,0),dropper.angle);
|
|
SetOrigin(dropper.Vec3Offset(hofs.x,hofs.y,dropper.height*0.5),false);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(dropper.pitch,dropper.angle,dropper.roll);
|
|
vel = x*12.0;
|
|
vel.z += 4.0;
|
|
angle = dropper.angle;
|
|
pitch = 0;
|
|
roll = 0;
|
|
}
|
|
|
|
Default
|
|
{
|
|
+INVENTORY.INVBAR;
|
|
UnrealInventory.Charge 0;
|
|
Inventory.PickupSound "misc/p_pkup";
|
|
}
|
|
}
|
|
|
|
Class UTeleportFog : Actor
|
|
{
|
|
Default
|
|
{
|
|
+NOBLOCKMAP;
|
|
+NOTELEPORT;
|
|
+NOGRAVITY;
|
|
RenderStyle "Add";
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
Spawn("UTTeleportLight",pos+(0,0,16));
|
|
A_PlaySound ("misc/teleport");
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UnrealWeapon : UTWeapon
|
|
{
|
|
override void FireEffect()
|
|
{
|
|
Super.FireEffect();
|
|
let invis = UInvisibility(Owner.FindInventory("UInvisibility"));
|
|
if ( invis && invis.bActive ) invis.special1 = -1;
|
|
}
|
|
override void PlayUpSound( Actor origin )
|
|
{
|
|
origin.A_PlaySound(upsound,CHAN_WEAPON,Dampener.Active(origin)?.1:1.);
|
|
}
|
|
// For clips
|
|
virtual clearscope int, int, bool, bool GetClipAmount() const
|
|
{
|
|
return -1, -1, false, false;
|
|
}
|
|
}
|
|
|
|
Class UnrealStaticHandler : StaticEventHandler
|
|
{
|
|
ui TextureID tex[8];
|
|
ui int mtics, cur;
|
|
ui String lastmusic;
|
|
|
|
ui void StartMenu()
|
|
{
|
|
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/UnLogo3.png",TexMan.Type_Any);
|
|
tex[3] = TexMan.CheckForTexture("graphics/UnLogo2.png",TexMan.Type_Any);
|
|
tex[4] = TexMan.CheckForTexture("graphics/UnBg.png",TexMan.Type_Any);
|
|
tex[5] = TexMan.CheckForTexture("graphics/97Bg.png",TexMan.Type_Any);
|
|
tex[6] = TexMan.CheckForTexture("graphics/96Bg.png",TexMan.Type_Any);
|
|
tex[7] = TexMan.CheckForTexture("graphics/95Bg.png",TexMan.Type_Any);
|
|
if ( proto > 2 ) S_ChangeMusic("Unreal");
|
|
else if ( proto == 2 ) S_ChangeMusic("Isotox96");
|
|
else if ( proto == 1 ) S_ChangeMusic("Unreal2");
|
|
else S_ChangeMusic("FlyBy");
|
|
cur = proto;
|
|
}
|
|
|
|
override void OnRegister()
|
|
{
|
|
// remove the UT static handler
|
|
let hnd = UTStaticHandler(StaticEventHandler.Find("UTStaticHandler"));
|
|
if ( hnd ) hnd.Destroy();
|
|
}
|
|
|
|
override void ConsoleProcess( ConsoleEvent e )
|
|
{
|
|
if ( gamestate != GS_TITLELEVEL ) return;
|
|
if ( e.Name ~== "refreshmenu" ) StartMenu();
|
|
}
|
|
|
|
override void PostUiTick()
|
|
{
|
|
if ( gamestate != GS_TITLELEVEL ) return;
|
|
if ( gametic <= 0 ) StartMenu();
|
|
if ( musplaying.Name != lastmusic )
|
|
{
|
|
mtics = 0;
|
|
lastmusic = musplaying.Name;
|
|
}
|
|
else mtics++;
|
|
}
|
|
|
|
override void RenderUnderlay( RenderEvent e )
|
|
{
|
|
if ( gamestate != GS_TITLELEVEL ) return;
|
|
double ar = Screen.GetAspectRatio();
|
|
Vector2 tsize = TexMan.GetScaledSize(tex[cur+4]);
|
|
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+4],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);
|
|
}
|
|
|
|
override void RenderOverlay( RenderEvent e )
|
|
{
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
Class AmmoUsedInSlot
|
|
{
|
|
Class<Ammo> AmmoType;
|
|
bool UsedInSlot[10];
|
|
}
|
|
|
|
Class UnrealMainHandler : EventHandler
|
|
{
|
|
Array<AmmoUsedInSlot> AmmoSlots;
|
|
|
|
override void WorldThingDamaged( WorldEvent e )
|
|
{
|
|
// blow up stinger pumped actors when taking damage from other sources
|
|
if ( e.DamageType == 'Stinger' ) return;
|
|
let ti = ThinkerIterator.Create("TarydiumDebuff",Thinker.STAT_USER);
|
|
TarydiumDebuff t;
|
|
while ( t = TarydiumDebuff(ti.Next()) )
|
|
{
|
|
if ( (t.victim != e.Thing) || t.reentrant ) continue; // make sure to skip any debuffs that already blew up to prevent infinite recursion on chain reactions
|
|
t.Amount += e.Damage/2;
|
|
t.BlowUp();
|
|
break;
|
|
}
|
|
}
|
|
override void CheckReplacement( ReplaceEvent e )
|
|
{
|
|
if ( (e.Replacee == 'Chainsaw') || (e.Replacee == 'Gauntlets') )
|
|
{
|
|
if ( (sting_dubious || sting_olsmp) && !Random[Replacements](0,3) ) e.Replacement = 'WeaponPowerUp';
|
|
else if ( Random[Replacements](0,2) )
|
|
{
|
|
if ( sting_dubious && Random[Replacements](0,1) ) e.Replacement = 'Bonesaw';
|
|
else e.Replacement = 'Stunner';
|
|
}
|
|
else if ( !Random[Replacements](0,2) ) e.Replacement = 'Betamag';
|
|
else e.Replacement = 'Automag';
|
|
}
|
|
else if ( (e.Replacee == 'Fist') || (e.Replacee == 'Staff') ) e.Replacement = 'DispersionPistol';
|
|
else if ( (e.Replacee == 'Pistol') || (e.Replacee == 'GoldWand') )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'Betamag';
|
|
else e.Replacement = 'Automag';
|
|
}
|
|
else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') )
|
|
{
|
|
if ( !Random[Replacements](0,3) )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'Betamag';
|
|
else e.Replacement = 'Automag';
|
|
}
|
|
else switch( Random[Replacements](0,2) )
|
|
{
|
|
case 0:
|
|
e.Replacement = 'Stinger';
|
|
break;
|
|
case 1:
|
|
e.Replacement = 'ASMD';
|
|
break;
|
|
case 2:
|
|
e.Replacement = 'QuadShot';
|
|
break;
|
|
}
|
|
}
|
|
else if ( (e.Replacee == 'Chaingun') || (e.Replacee == 'Blaster') )
|
|
{
|
|
if ( Random[Replacements](0,1) ) e.Replacement = 'UMinigun';
|
|
else e.Replacement = 'Razorjack';
|
|
}
|
|
else if ( (e.Replacee == 'RocketLauncher') || (e.Replacee == 'PhoenixRod') )
|
|
{
|
|
if ( !Random[Replacements](0,3) )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'UFlamethrower';
|
|
else e.Replacement = 'FlameGun';
|
|
}
|
|
else if ( Random[Replacements](0,1) ) e.Replacement = 'UFlakCannon';
|
|
else e.Replacement = 'Eightball';
|
|
}
|
|
else if ( (e.Replacee == 'PlasmaRifle') || (e.Replacee == 'SkullRod') )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'Impaler';
|
|
else if ( Random[Replacements](0,1) ) e.Replacement = 'URifle';
|
|
else e.Replacement = 'UBioRifle';
|
|
}
|
|
else if ( (e.Replacee == 'BFG9000') || (e.Replacee == 'Mace') )
|
|
{
|
|
if ( sting_olsmp && (!sting_dubious || Random[Replacements](0,1)) ) e.Replacement = 'OLSMP';
|
|
else if ( sting_dubious )
|
|
{
|
|
if ( Random[Replacements](0,1) ) e.Replacement = 'SMiniGun';
|
|
else e.Replacement = 'BigGun';
|
|
}
|
|
else e.Replacement = 'WeaponPowerup'; // lousy, I know
|
|
}
|
|
else if ( (e.Replacee == 'Clip') || (e.Replacee == 'GoldWandAmmo') || (e.Replacee == 'GoldWandHefty') ) e.Replacement = 'UClip';
|
|
else if ( (e.Replacee == 'ClipBox') )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'UClip';
|
|
else if ( Random[Replacements](0,1) ) e.Replacement = 'UMiniAmmo';
|
|
else e.Replacement = 'RazorAmmo';
|
|
}
|
|
else if ( (e.Replacee == 'BlasterAmmo') || (e.Replacee == 'BlasterHefty') )
|
|
{
|
|
if ( Random[Replacements](0,1) ) e.Replacement = 'UMiniAmmo';
|
|
else e.Replacement = 'RazorAmmo';
|
|
}
|
|
else if ( (e.Replacee == 'Shell') || (e.Replacee == 'CrossbowAmmo') )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'UClip';
|
|
else switch( Random[Replacements](0,2) )
|
|
{
|
|
case 0:
|
|
e.Replacement = 'StingerAmmo';
|
|
break;
|
|
case 1:
|
|
e.Replacement = 'ASMDAmmo2';
|
|
break;
|
|
case 2:
|
|
e.Replacement = 'UShells2';
|
|
break;
|
|
}
|
|
}
|
|
else if ( (e.Replacee == 'ShellBox') || (e.Replacee == 'CrossbowHefty') )
|
|
{
|
|
switch( Random[Replacements](0,2) )
|
|
{
|
|
case 0:
|
|
e.Replacement = 'StingerAmmo2';
|
|
break;
|
|
case 1:
|
|
e.Replacement = 'ASMDAmmo';
|
|
break;
|
|
case 2:
|
|
e.Replacement = 'UShells';
|
|
break;
|
|
}
|
|
}
|
|
else if ( (e.Replacee == 'RocketAmmo') || (e.Replacee == 'PhoenixRodAmmo') || (e.Replacee == 'MaceAmmo') )
|
|
{
|
|
if ( !Random[Replacements](0,4) ) e.Replacement = 'FlameAmmo';
|
|
else if ( Random[Replacements](0,1) )
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'UFlakBox';
|
|
else e.Replacement = 'UFlakAmmo';
|
|
}
|
|
else
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'URocketAmmo';
|
|
else e.Replacement = 'URocketAmmo2';
|
|
}
|
|
}
|
|
else if ( (e.Replacee == 'RocketBox') || (e.Replacee == 'PhoenixRodHefty') || (e.Replacee == 'MaceHefty') )
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'FlameAmmo';
|
|
else if ( Random[Replacements](0,1) ) e.Replacement = 'UFlakBox';
|
|
else e.Replacement = 'URocketAmmo';
|
|
}
|
|
else if ( (e.Replacee == 'Cell') || (e.Replacee == 'SkullRodAmmo') )
|
|
{
|
|
if ( sting_dubious && !Random[Replacements](0,4) )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'BigAmmo2';
|
|
else e.Replacement = 'BigAmmo3';
|
|
}
|
|
else if ( !Random[Replacements](0,3) )
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'ImpalerAmmo';
|
|
else e.Replacement = 'ImpalerAmmo2';
|
|
}
|
|
else if ( Random[Replacements](0,1) )
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'UBioAmmo';
|
|
else e.Replacement = 'UBioAmmo2';
|
|
}
|
|
else
|
|
{
|
|
if ( !Random[Replacements](0,3) ) e.Replacement = 'URifleAmmo';
|
|
else e.Replacement = 'URifleAmmo2';
|
|
}
|
|
}
|
|
else if ( (e.Replacee == 'CellPack') || (e.Replacee == 'SkullRodHefty') )
|
|
{
|
|
if ( sting_dubious && !Random[Replacements](0,4) )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'BigAmmo';
|
|
else e.Replacement = 'BigAmmo2';
|
|
}
|
|
else if ( !Random[Replacements](0,3) ) e.Replacement = 'ImpalerAmmo';
|
|
else if ( sting_olsmp && !Random[Replacements](0,2) ) e.Replacement = 'OLSMPAmmo';
|
|
else if ( Random[Replacements](0,1) ) e.Replacement = 'UBioAmmo';
|
|
else e.Replacement = 'URifleAmmo';
|
|
}
|
|
else if ( (e.Replacee == 'InvulnerabilitySphere') || (e.Replacee == 'ArtiInvulnerability') ) e.Replacement = 'PowerShield';
|
|
else if ( (e.Replacee == 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') )
|
|
{
|
|
if ( sting_msentry && !Random[Replacements](0,9) ) e.Replacement = 'SentryItem';
|
|
else if ( (sting_dubious || sting_olsmp) && !Random[Replacements](0,2) ) e.Replacement = 'WeaponPowerUp';
|
|
else e.Replacement = 'Amplifier';
|
|
}
|
|
else if ( e.Replacee == 'ArtiEgg' ) e.Replacement = 'VoiceBox';
|
|
else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'SuperHealth';
|
|
else if ( e.Replacee == 'Megasphere' ) e.Replacement = 'ShieldBelt';
|
|
else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') ) e.Replacement = 'MotionDetector';
|
|
else if ( (e.Replacee == 'BlurSphere') || (e.Replacee == 'ArtiInvisibility') ) e.Replacement = 'UInvisibility';
|
|
else if ( (e.Replacee == 'Infrared') || (e.Replacee == 'ArtiTorch') ) e.Replacement = 'UFlashlight';
|
|
else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UJumpBoots';
|
|
else if ( e.Replacee == 'ArtiFly' ) e.Replacement = 'UJumpBoots';
|
|
else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') ) e.Replacement = 'UnrealBackpack';
|
|
else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') ) e.Replacement = 'Flare';
|
|
else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'Bandages';
|
|
else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') ) e.Replacement = 'KevlarSuit';
|
|
else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'UArmor';
|
|
else if ( e.Replacee == 'Stimpack' )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'UHealth';
|
|
else e.Replacement = 'Seeds';
|
|
}
|
|
else if ( e.Replacee == 'Medikit' ) e.Replacement = 'UHealth';
|
|
else if ( e.Replacee == 'ArtiHealth' )
|
|
{
|
|
if ( !Random[Replacements](0,2) ) e.Replacement = 'UHealth';
|
|
else e.Replacement = 'Seeds';
|
|
}
|
|
else if ( e.Replacee == 'ArtiTeleport' )
|
|
{
|
|
// I have no idea what to replace this with, so just have some random stuff
|
|
switch( Random[Replacements](0,7) )
|
|
{
|
|
case 0:
|
|
e.Replacement = 'UnrealBackpack';
|
|
break;
|
|
case 1:
|
|
e.Replacement = 'ShieldBelt';
|
|
break;
|
|
case 2:
|
|
e.Replacement = 'SuperHealth';
|
|
break;
|
|
case 3:
|
|
e.Replacement = 'Amplifier';
|
|
break;
|
|
case 4:
|
|
e.Replacement = 'WeaponPowerUp';
|
|
break;
|
|
case 5:
|
|
e.Replacement = 'VoiceBox';
|
|
break;
|
|
case 6:
|
|
e.Replacement = 'SentryItem';
|
|
break;
|
|
case 7:
|
|
e.Replacement = 'Peacemaker';
|
|
break;
|
|
}
|
|
}
|
|
else if ( e.Replacee == 'TeleportFog' ) e.Replacement = 'UTeleportFog';
|
|
// replace UT items (while this is mainly for the DT map pack, it also has the added effect of preventing the guns from being added by "give all")
|
|
else if ( e.Replacee is 'ImpactHammer' ) e.Replacement = 'DispersionPistol';
|
|
else if ( e.Replacee is 'Translocator' ) e.Replacement = 'UTranslocator';
|
|
else if ( e.Replacee is 'UTChainsaw' ) e.Replacement = 'Slot1Weapons';
|
|
else if ( e.Replacee is 'Enforcer' ) e.Replacement = 'Slot2Weapons';
|
|
else if ( e.Replacee is 'BioRifle' ) e.Replacement = 'Slot3Weapons';
|
|
else if ( e.Replacee is 'ShockRifle' ) e.Replacement = 'Slot4Weapons';
|
|
else if ( e.Replacee is 'PulseGun' ) e.Replacement = 'Slot5Weapons';
|
|
else if ( e.Replacee is 'Ripper2' ) e.Replacement = 'Slot6Weapons';
|
|
else if ( e.Replacee is 'Minigun' ) e.Replacement = 'Slot7Weapons';
|
|
else if ( e.Replacee is 'FlakCannon' ) e.Replacement = 'Slot8Ammo';
|
|
else if ( e.Replacee is 'UTRocketLauncher' ) e.Replacement = 'Slot0Weapons';
|
|
else if ( e.Replacee is 'SniperRifle' ) e.Replacement = 'Slot0Weapons';
|
|
else if ( e.Replacee is 'WarheadLauncher' ) e.Replacement = 'Slot0SWeapons';
|
|
else if ( e.Replacee is 'EnhancedShockRifle' ) e.Replacement = 'Amplifier';
|
|
else if ( e.Replacee is 'ChainsawAmmo' ) e.Replacement = 'UNothing';
|
|
else if ( e.Replacee is 'EClip' ) e.Replacement = 'Slot2Ammo';
|
|
else if ( e.Replacee is 'BioAmmo' ) e.Replacement = 'Slot3Ammo';
|
|
else if ( e.Replacee is 'ShockAmmo' ) e.Replacement = 'Slot4Ammo';
|
|
else if ( e.Replacee is 'PulseAmmo' ) e.Replacement = 'Slot5Ammo';
|
|
else if ( e.Replacee is 'RipperAmmo' ) e.Replacement = 'Slot6Ammo';
|
|
else if ( e.Replacee is 'MiniAmmo' ) e.Replacement = 'Slot7Ammo';
|
|
else if ( e.Replacee is 'FlakAmmo' ) e.Replacement = 'Slot8Ammo';
|
|
else if ( e.Replacee is 'UTRocketAmmo' ) e.Replacement = 'Slot9Ammo';
|
|
else if ( e.Replacee is 'RifleAmmo' ) e.Replacement = 'Slot0Ammo';
|
|
else if ( e.Replacee is 'WarheadAmmo' ) e.Replacement = 'Slot0SAmmo';
|
|
else if ( e.Replacee is 'EnhancedShockAmmo' ) e.Replacement = 'UNothing';
|
|
else if ( e.Replacee is 'UTBackpack' ) e.Replacement = 'UnrealBackpack';
|
|
else if ( e.Replacee is 'UDamage' ) e.Replacement = 'Amplifier';
|
|
// we don't need these
|
|
else if ( e.Replacee is 'UTActivatable' ) e.Replacement = 'UNothing';
|
|
else if ( e.Replacee is 'UTActivatableHealth' ) e.Replacement = 'UNothing';
|
|
}
|
|
|
|
// translocator stuff
|
|
override void PlayerEntered( PlayerEvent e )
|
|
{
|
|
if ( flak_translocator )
|
|
players[e.playernumber].mo.TakeInventory("Translocator",1);
|
|
if ( sting_telegun )
|
|
players[e.playernumber].mo.GiveInventory("UTranslocator",1);
|
|
if ( sting_flares )
|
|
{
|
|
players[e.playernumber].mo.GiveInventory("LightFlare",1);
|
|
players[e.playernumber].mo.GiveInventory("DarkFlare",1);
|
|
}
|
|
}
|
|
override void PlayerRespawned( PlayerEvent e )
|
|
{
|
|
PlayerEntered(e);
|
|
}
|
|
override void NetworkProcess( ConsoleEvent e )
|
|
{
|
|
if ( e.Name ~== "refreshtrans" )
|
|
{
|
|
if ( flak_translocator )
|
|
{
|
|
for ( int i=0; i<MAXPLAYERS; i++ ) if ( playeringame[i] )
|
|
{
|
|
players[i].mo.TakeInventory("Translocator",1);
|
|
}
|
|
}
|
|
if ( sting_telegun )
|
|
{
|
|
for ( int i=0; i<MAXPLAYERS; i++ ) if ( playeringame[i] )
|
|
{
|
|
players[i].mo.GiveInventory("UTranslocator",1);
|
|
}
|
|
}
|
|
if ( sting_flares )
|
|
{
|
|
for ( int i=0; i<MAXPLAYERS; i++ ) if ( playeringame[i] )
|
|
{
|
|
players[i].mo.GiveInventory("LightFlare",1);
|
|
players[i].mo.GiveInventory("DarkFlare",1);
|
|
}
|
|
}
|
|
}
|
|
else if ( (e.Name ~== "usetranslator") && (e.player != -1) && playeringame[e.player] && !menuactive )
|
|
{
|
|
let t = players[e.player].mo.FindInventory("UTranslator");
|
|
if ( t ) t.Use(false);
|
|
}
|
|
}
|
|
private static bool CmpWeapon( Class<Weapon> a, Class <Weapon> b )
|
|
{
|
|
let defa = GetDefaultByType(a);
|
|
let defb = GetDefaultByType(b);
|
|
if ( defa.SlotPriority <= defb.SlotPriority ) return true;
|
|
if ( defa.SlotNumber > defb.SlotNumber ) return true;
|
|
return false;
|
|
}
|
|
override void WorldLoaded( WorldEvent e )
|
|
{
|
|
// More "authentic" Unreal flavor of these edits
|
|
if ( (level.GetChecksum() ~== "959A613006CC3AA912C4A22908B7566A") || (level.GetChecksum() ~== "0EADB2F82732A968B8513E4DC6138439") )
|
|
{
|
|
S_ChangeMusic("Cyrene");
|
|
TextureID sky95 = TexMan.CheckForTexture("95Bg",TexMan.Type_Any);
|
|
level.ChangeSky(sky95,sky95);
|
|
level.ReplaceTextures("rClfFlr0","C_flr19",0);
|
|
level.ReplaceTextures("rClfBas0","C_wal19k",0);
|
|
level.ReplaceTextures("uAlnWl2b","C_WAL19A",0);
|
|
level.ReplaceTextures("xAlnWl2b","C_WAL19F",0);
|
|
}
|
|
// populate weapons array
|
|
Array<Class<Weapon> > SortedWeapons;
|
|
SortedWeapons.Clear();
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (class<Weapon>)(AllActorClasses[i]);
|
|
if ( !type || (type == "Weapon") ) continue;
|
|
let rep = Actor.GetReplacement(type);
|
|
if ( (rep != type) && !(rep is "DehackedPickup") ) continue;
|
|
readonly<Weapon> def = GetDefaultByType(type);
|
|
int wslot = def.SlotNumber;
|
|
if ( wslot == -1 ) continue;
|
|
if ( !def.AmmoType1 ) continue;
|
|
SortedWeapons.Push(type);
|
|
}
|
|
// sort weapons array
|
|
for ( int i=0; i<SortedWeapons.Size(); i++ )
|
|
{
|
|
int j = 1;
|
|
while ( j < SortedWeapons.Size() )
|
|
{
|
|
int k = j;
|
|
while ( (k > 0) && CmpWeapon(SortedWeapons[k-1],SortedWeapons[k]) )
|
|
{
|
|
Class<Weapon> tmp = SortedWeapons[k];
|
|
SortedWeapons[k] = SortedWeapons[k-1];
|
|
SortedWeapons[k-1] = tmp;
|
|
k--;
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
// populate ammo-by-slot array
|
|
AmmoSlots.Clear();
|
|
for ( int i=0; i<SortedWeapons.Size(); i++ )
|
|
{
|
|
readonly<Weapon> def = GetDefaultByType(SortedWeapons[i]);
|
|
int wslot = def.SlotNumber;
|
|
int found = -1;
|
|
for ( int j=0; j<AmmoSlots.Size(); j++ )
|
|
{
|
|
if ( AmmoSlots[j].AmmoType != def.AmmoType1 ) continue;
|
|
found = j;
|
|
}
|
|
if ( found == -1 )
|
|
{
|
|
let asl = new("AmmoUsedInSlot");
|
|
asl.AmmoType = def.AmmoType1;
|
|
asl.UsedInSlot[wslot] = true;
|
|
AmmoSlots.Push(asl);
|
|
}
|
|
else AmmoSlots[found].UsedInSlot[wslot] = true;
|
|
}
|
|
}
|
|
}
|