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.pendingupgrade = 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;
|
|
}
|
|
}
|
|
}
|