Some extra things before I go to bed:

- Added Gravity Suppressor.
 - Adjusted Health Geodesic sizes.
 - Adjusted max amounts of nuggets (capped at 40 now).
 - Added secret combination to menu (nothing to find yet though, that will come later).
 - 6DOF movement when flying.
This commit is contained in:
Mari the Deer 2020-02-04 02:41:09 +01:00
commit d6228cb42c
17 changed files with 465 additions and 53 deletions

View file

@ -37,6 +37,10 @@ Brightmap Texture "models/GhostArtifact.png"
{
Map "models/GhostArtifact_bright.png"
}
Brightmap Texture "models/Gravity.png"
{
Map "models/Gravity_bright.png"
}
PointLight ARMORNUGGETLIGHT
{
@ -100,3 +104,15 @@ Object GhostArtifact
{
Frame "XZW1" { light "GHOSTARTILIGHT" }
}
PointLight GRAVITYLIGHT
{
Color 0.3 0.8 1.0
Size 40
Offset 0 16 0
Attenuate 1
}
Object GravitySuppressor
{
Frame "XZW1" { light "GRAVITYLIGHT" }
}

View file

@ -100,6 +100,7 @@ SWWM_TRADEFROM = "Received from";
SWWM_MSGSENT = "You sent %dx %s to %s.";
SWWM_MSGRECV = "%s sent you %dx %s.";
SWWM_CHATTAB = "Chat Log";
SWWM_SECRETTAB = "Secret";
SWWM_MAINCONTROLS = "PgUp/PgDn: Switch Tab | Arrows: Navigate | ";
SWWM_INVCONTROLS = "Enter: Use | Backspace: Drop | ";
SWWM_STRCONTROLS = "Enter: Buy | ";

View file

@ -40,7 +40,7 @@ Model "TetraHealthItem"
Path "models"
Model 0 "TetraHealth_d.3d"
Skin 0 "TetraHealth.png"
Scale 0.05 0.05 0.05
Scale 0.03 0.03 0.03
ZOffset 16
ROTATING
@ -52,7 +52,7 @@ Model "CubeHealthItem"
Path "models"
Model 0 "CubeHealth_d.3d"
Skin 0 "CubeHealth.png"
Scale 0.05 0.05 0.05
Scale 0.03 0.03 0.03
ZOffset 16
ROTATING
@ -132,3 +132,16 @@ Model "GhostArtifactX"
FrameIndex XZW1 A 0 0
}
Model "GravitySuppressor"
{
Path "models"
Model 0 "Gravity_d.3d"
SurfaceSkin 0 0 "Gravity.png"
SurfaceSkin 0 1 "silvermap.png"
Scale 0.06 0.06 0.06
ZOffset 16
ROTATING
FrameIndex XZW1 A 0 0
}

View file

@ -408,6 +408,9 @@ powerup/sandwich sounds/CORK.ogg
powerup/ghost sounds/items/CloakOn.ogg
powerup/ghostact sounds/items/CloakLoop3.ogg
powerup/ghostend sounds/items/CloakOff.ogg
powerup/gravity sounds/items/gravityon.ogg
powerup/gravityact sounds/items/gravityact.ogg
powerup/gravityend sounds/items/gravityoff.ogg
menu/activate sounds/hmenu/hmenu1.ogg
menu/backup sounds/hmenu/hmenu2.ogg

BIN
sounds/items/gravityact.ogg Normal file

Binary file not shown.

BIN
sounds/items/gravityoff.ogg Normal file

Binary file not shown.

BIN
sounds/items/gravityon.ogg Normal file

Binary file not shown.

View file

@ -6,6 +6,7 @@ version "4.3"
#include "zscript/swwm_libeye/projector planar.txt"
#include "zscript/swwm_libeye/viewport.txt"
#include "zscript/swwm_coordutil.zsc"
#include "zscript/swwm_quaternion.zsc"
// base code
#include "zscript/swwm_common.zsc"
#include "zscript/swwm_player.zsc"

View file

@ -32,8 +32,8 @@ Class ArmorNuggetItem : SWWMSpareArmor
Stamina 1000;
Inventory.Icon "graphics/HUD/Icons/I_ArmorNugget.png";
Inventory.PickupMessage "$T_NUGGETA";
Inventory.MaxAmount int.max;
Inventory.InterHubAmount int.max;
Inventory.MaxAmount 40;
Inventory.InterHubAmount 40;
Inventory.UseSound "misc/armor_pkup";
SWWMSpareArmor.GiveArmor "ArmorNugget";
+INVENTORY.ALWAYSPICKUP;

View file

@ -1195,30 +1195,41 @@ Class SWWMHandler : EventHandler
}
}
private void DoKeyTagFix( Actor a )
{
if ( a is 'RedCard' ) a.SetTag("$T_REDCARD");
else if ( a is 'BlueCard' ) a.SetTag("$T_BLUECARD");
else if ( a is 'YellowCard' ) a.SetTag("$T_YELLOWCARD");
else if ( a is 'RedSkull' ) a.SetTag("$T_REDSKULL");
else if ( a is 'BlueSkull' ) a.SetTag("$T_BLUESKULL");
else if ( a is 'YellowSkull' ) a.SetTag("$T_YELLOWSKULL");
else if ( a is 'KeyYellow' ) a.SetTag("$T_YELLOWKEY");
else if ( a is 'KeyGreen' ) a.SetTag("$T_GREENKEY");
else if ( a is 'KeyBlue' ) a.SetTag("$T_BLUEKEY");
else if ( a.GetClassName() == 'KeyRed' ) a.SetTag("$T_REDKEY");
else if ( a is 'KeySteel' ) a.SetTag("$T_KEYSTEEL");
else if ( a is 'KeyCave' ) a.SetTag("$T_KEYCAVE");
else if ( a is 'KeyAxe' ) a.SetTag("$T_KEYAXE");
else if ( a is 'KeyFire' ) a.SetTag("$T_KEYFIRE");
else if ( a is 'KeyEmerald' ) a.SetTag("$T_KEYEMERALD");
else if ( a is 'KeyDungeon' ) a.SetTag("$T_KEYDUNGEON");
else if ( a is 'KeySilver' ) a.SetTag("$T_KEYSILVER");
else if ( a is 'KeyRusted' ) a.SetTag("$T_KEYRUSTED");
else if ( a is 'KeyHorn' ) a.SetTag("$T_KEYHORN");
else if ( a is 'KeySwamp' ) a.SetTag("$T_KEYSWAMP");
else if ( a is 'KeyCastle' ) a.SetTag("$T_KEYCASTLE");
}
static void KeyTagFix( Actor a )
{
let hnd = SWWMHandler(Find("SWWMHandler"));
if ( hnd ) hnd.DoKeyTagFix(a);
}
// tempfix keys have no tags
override void WorldThingSpawned( WorldEvent e )
{
if ( e.Thing is 'RedCard' ) e.Thing.SetTag("$T_REDCARD");
else if ( e.Thing is 'BlueCard' ) e.Thing.SetTag("$T_BLUECARD");
else if ( e.Thing is 'YellowCard' ) e.Thing.SetTag("$T_YELLOWCARD");
else if ( e.Thing is 'RedSkull' ) e.Thing.SetTag("$T_REDSKULL");
else if ( e.Thing is 'BlueSkull' ) e.Thing.SetTag("$T_BLUESKULL");
else if ( e.Thing is 'YellowSkull' ) e.Thing.SetTag("$T_YELLOWSKULL");
else if ( e.Thing is 'KeyYellow' ) e.Thing.SetTag("$T_YELLOWKEY");
else if ( e.Thing is 'KeyGreen' ) e.Thing.SetTag("$T_GREENKEY");
else if ( e.Thing is 'KeyBlue' ) e.Thing.SetTag("$T_BLUEKEY");
else if ( e.Thing.GetClassName() == 'KeyRed' ) e.Thing.SetTag("$T_REDKEY");
else if ( e.Thing is 'KeySteel' ) e.Thing.SetTag("$T_KEYSTEEL");
else if ( e.Thing is 'KeyCave' ) e.Thing.SetTag("$T_KEYCAVE");
else if ( e.Thing is 'KeyAxe' ) e.Thing.SetTag("$T_KEYAXE");
else if ( e.Thing is 'KeyFire' ) e.Thing.SetTag("$T_KEYFIRE");
else if ( e.Thing is 'KeyEmerald' ) e.Thing.SetTag("$T_KEYEMERALD");
else if ( e.Thing is 'KeyDungeon' ) e.Thing.SetTag("$T_KEYDUNGEON");
else if ( e.Thing is 'KeySilver' ) e.Thing.SetTag("$T_KEYSILVER");
else if ( e.Thing is 'KeyRusted' ) e.Thing.SetTag("$T_KEYRUSTED");
else if ( e.Thing is 'KeyHorn' ) e.Thing.SetTag("$T_KEYHORN");
else if ( e.Thing is 'KeySwamp' ) e.Thing.SetTag("$T_KEYSWAMP");
else if ( e.Thing is 'KeyCastle' ) e.Thing.SetTag("$T_KEYCASTLE");
if ( e.Thing is 'Key' ) DoKeyTagFix(e.Thing);
}
override void PostUiTick()
@ -1478,6 +1489,7 @@ Class SWWMHandler : EventHandler
else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'RefresherItem';
else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiEgg') || (e.Replacee == 'PlatinumHelm') ) e.Replacement = 'GrilledCheeseSandwich';
else if ( (e.Replacee == 'Blursphere') || (e.Replacee == 'ArtiInvisibility') || (e.Replacee == 'AmuletOfWarding') ) e.Replacement = 'GhostArtifact';
else if ( (e.Replacee == 'Radsuit') || (e.Replacee == 'ArtiFly') || (e.Replacee == 'ArtiSpeedBoots') ) e.Replacement = 'GravitySuppressor';
else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'SilverShield') || (e.Replacee == 'MeshArmor') ) e.Replacement = 'BlastSuitItem';
else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'FalconShield') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'WarArmorItem';
}

View file

@ -90,8 +90,8 @@ Class HealthNuggetItem : SWWMHealth
Stamina 1200;
Inventory.Icon "graphics/HUD/Icons/I_HealthNugget.png";
Inventory.PickupMessage "$T_NUGGETH";
Inventory.MaxAmount int.max;
Inventory.InterHubAmount int.max;
Inventory.MaxAmount 40;
Inventory.InterHubAmount 40;
SWWMHealth.GiveHealth "HealthNugget";
+INVENTORY.ALWAYSPICKUP;
+COUNTITEM;

View file

@ -222,7 +222,7 @@ Class SWWMStatusBar : BaseStatusBar
private void DrawInventory()
{
// active items (armor / powerups)
double xx = margin;
double xx = margin+2;
double yy = ss.y-(margin+60);
if ( CPlayer.mo.InvSel && !isInventoryBarVisible() ) yy -= 34;
bool drewarmor = false;

View file

@ -457,7 +457,7 @@ Class SWWMWeapon : Weapon abstract
}
else flashstate = weap.FindState(flashlabel);
player.SetPSprite(PSP_FLASH,flashstate);
A_OverlayFlags(PSP_FLASH,PSPF_RENDERSTYLE,true);
A_OverlayFlags(PSP_FLASH,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
A_OverlayRenderStyle(PSP_FLASH,STYLE_Add);
}
// tells the SWWM HUD that this weapon has ammo available

View file

@ -10,7 +10,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
TAB_LIBRARY,
TAB_STORE,
TAB_TRADING,
TAB_CHAT
TAB_CHAT,
TAB_SECRET
};
TextureID MainWindow, TabSeparator, WindowSeparator, WindowSeparatorH,
@ -45,6 +46,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
int lastuseamt;
int checkuse;
int checkdrop;
// seeeeecret
int kcode;
override void Init( Menu parent )
{
@ -75,6 +78,38 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
override bool MenuEvent( int mkey, bool fromcontroller )
{
switch ( kcode )
{
case 0:
case 1:
if ( mkey == MKEY_UP ) kcode++;
else kcode = 0;
break;
case 2:
case 3:
if ( mkey == MKEY_DOWN ) kcode++;
else kcode = 0;
break;
case 4:
case 6:
if ( mkey == MKEY_LEFT ) kcode++;
else kcode = 0;
break;
case 5:
case 7:
if ( mkey == MKEY_RIGHT ) kcode++;
else kcode = 0;
break;
case 10:
if ( mkey == MKEY_ENTER )
{
MenuSound("misc/secret");
curtab = TAB_SECRET;
}
default:
kcode = 0;
break;
}
switch ( mkey )
{
case MKEY_BACK:
@ -270,6 +305,21 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
switch ( ev.type )
{
case UIEvent.Type_KeyDown:
switch ( kcode )
{
case 8:
if ( ev.keystring ~== "B" )
kcode++;
else kcode = 0;
break;
case 9:
if ( ev.keystring ~== "A" ) kcode++;
else kcode = 0;
break;
default:
kcode = 0;
break;
}
if( (ikey[0] && (ev.keystring == mkey[0])) || (ikey[1] && (ev.keystring == mkey[1])) )
{
MenuSound("menu/democlose");
@ -301,9 +351,11 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
static const string tabnames[] =
{
"$SWWM_MISSTAB", "$SWWM_STATTAB", "$SWWM_INVTAB", "$SWWM_KEYTAB",
"$SWWM_KBASETAB", "$SWWM_STORETAB", "$SWWM_TRADETAB", "$SWWM_CHATTAB"
"$SWWM_KBASETAB", "$SWWM_STORETAB", "$SWWM_TRADETAB", "$SWWM_CHATTAB",
"$SWWM_SECRETTAB"
};
for ( int i=0; i<8; i++ )
int mx = (curtab==TAB_SECRET)?9:8;
for ( int i=0; i<mx; i++ )
{
str = StringTable.Localize(tabnames[i]);
Screen.DrawText(TewiFont,curtab==i?Font.CR_FIRE:Font.CR_DARKGRAY,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
@ -583,9 +635,11 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
else
else if ( curtab == TAB_SECRET )
{
// TODO easter egg "konami code" hidden tab
str = StringTable.Localize("$SWWM_COMINGSOON");
Screen.DrawText(TewiFont,Font.CR_FIRE,(ss.x-TewiFont.StringWidth(str))/2.,(ss.y-TewiFont.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
}

View file

@ -6,6 +6,7 @@ Class Demolitionist : PlayerPawn
double dashfuel, dashboost;
int dashcooldown, boostcooldown, fuelcooldown;
bool dashsnd;
bool sendtoground;
bool key_reentrant;
int lastdamage;
@ -22,6 +23,8 @@ Class Demolitionist : PlayerPawn
int lastmpain;
double guideangle, guidepitch, guideroll;
Default
{
Speed 1;
@ -48,15 +51,15 @@ Class Demolitionist : PlayerPawn
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" )
else if ( name ~== "everything" ) giveall = ALL_YESYES;
if ( giveall || (name ~== "health") )
{
if ( amount > 0 )
{
health += amount;
health = min(health+amount,1000);
player.health = health;
}
else player.health = health = GetMaxHealth(true);
else player.health = health = 1000;
}
if ( giveall || (name ~== "backpack") )
{
@ -144,10 +147,14 @@ Class Demolitionist : PlayerPawn
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
if ( !(AllActorClasses[i] is "Key") ) continue;
// clean up redundant keys
if ( !(gameinfo.gametype&GAME_CHEX) && ((AllActorClasses[i] is 'ChexRedCard') || (AllActorClasses[i] is 'ChexBlueCard') || (AllActorClasses[i] is 'ChexYellowCard')) ) continue;
else if ( (gameinfo.gametype&GAME_CHEX) && !(AllActorClasses[i] is 'ChexRedCard') && !(AllActorClasses[i] is 'ChexBlueCard') && !(AllActorClasses[i] is 'ChexYellowCard') ) continue;
let keyitem = GetDefaultByType(AllActorClasses[i]);
if ( keyitem.special1 )
{
let item = Inventory(Spawn(AllActorClasses[i]));
SWWMHandler.KeyTagFix(item);
if ( !item.CallTryPickup(self) ) item.Destroy();
}
}
@ -182,7 +189,7 @@ Class Demolitionist : PlayerPawn
if ( !type ) continue;
let def = GetDefaultByType (type);
if ( def.Icon.isValid() &&
!(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") && !(type is "Armor") )
!(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") && !(type is "Armor") && !(type is "Key") )
{
// Do not give replaced items unless using "give everything"
if ( (giveall == ALL_YESYES) || (GetReplacement(type) == type) )
@ -325,7 +332,7 @@ Class Demolitionist : PlayerPawn
lastground = player.onground;
lastvelz = prevvelz;
prevvelz = vel.z;
bNOFRICTION = InStateSequence(CurState,FindState("Dash"));
bNOFRICTION = (((waterlevel<2)&&(bFly||bFlyCheat||(player.cheats&CF_NOCLIP2)))||InStateSequence(CurState,FindState("Dash")));
fuelcooldown = max(0,fuelcooldown-1);
dashcooldown = max(0,dashcooldown-1);
boostcooldown = max(0,boostcooldown-1);
@ -420,20 +427,106 @@ Class Demolitionist : PlayerPawn
player.viewz += ssup;
ssup = max(0,(ssup*.7)-.25);
}
override void CheckPitch()
{
if ( (waterlevel < 2) && (bFly || bFlyCheat || (player.cheats&CF_NOCLIP2)) )
return; // handled in moveplayer
Super.CheckPitch();
}
override void CheckMoveUpDown()
{
if ( InStateSequence(CurState,FindState("Dash")) )
player.cmd.upmove = 0;
if ( (waterlevel < 2) && (bFly || bFlyCheat || (player.cheats&CF_NOCLIP2)) )
{
double fs = TweakSpeeds(1.,0.);
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 accel;
if ( (player.cmd.upmove == -32768) || sendtoground )
{
sendtoground = true;
player.centering = true;
accel = (0,0,-4096);
}
else accel = z*player.cmd.upmove*8.;
accel *= fs/128.;
vel = vel+accel/TICRATE;
if ( sendtoground ) vel.xy *= .6;
if ( (pos.z <= floorz) || bOnMobj ) sendtoground = false;
if ( vel.length() > 50. )
vel = vel.unit()*50.;
return;
}
else sendtoground = false;
Super.CheckMoveUpDown();
}
override void MovePlayer()
{
if ( InStateSequence(CurState,FindState("Dash")) )
player.cmd.forwardmove = player.cmd.sidemove = 0;
Super.MovePlayer();
if ( (waterlevel < 2) && (bFly || bFlyCheat || (player.cheats&CF_NOCLIP2)) )
{
player.onground = false;
if ( player.turnticks )
{
player.turnticks--;
guideangle = (180./TURN180_TICKS);
}
else guideangle += .2*player.cmd.yaw*(360./65536.);
guidepitch -= .2*player.cmd.pitch*(360./65536.);
if ( player.centering )
{
guidepitch = clamp(deltaangle(pitch,0),-3.,3.);
guideroll = clamp(deltaangle(roll,0),-3.,3.);
}
swwm_Quat orient = swwm_Quat.create_euler(pitch,angle,roll);
swwm_Quat angles = swwm_Quat.create_euler(guidepitch,guideangle,guideroll);
orient = orient.qmul(angles);
double npitch, nangle, nroll;
[npitch, nangle, nroll] = orient.to_euler();
angle = nangle;
pitch = npitch;
roll = nroll;
if ( (abs(roll) <= 0.) && (abs(pitch) <= 0.) ) player.centering = false;
double fs = TweakSpeeds(1.,0.);
fs *= max(abs(player.cmd.forwardmove/12800.),abs(player.cmd.sidemove/10240.));
if ( CanCrouch() && (player.crouchfactor != -1) ) fs *= player.crouchfactor;
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 accel = x*player.cmd.forwardmove+y*player.cmd.sidemove+z*player.cmd.upmove;
accel *= fs/128.;
vel = vel+accel/TICRATE;
if ( vel.length() > 50. )
vel = vel.unit()*50.;
vel *= .99;
player.vel = (1,1)*vel.length();
player.jumptics = -2;
if ( !(player.cheats & CF_PREDICTING) && (player.cmd.forwardmove|player.cmd.sidemove) )
PlayRunning();
if ( player.cheats&CF_REVERTPLEASE )
{
player.cheats &= ~CF_REVERTPLEASE;
player.camera = player.mo;
}
}
else
{
Super.MovePlayer();
if ( abs(roll) > 0. ) roll += clamp(deltaangle(roll,0),-3.,3.);
}
guideangle *= .9;
guidepitch *= .9;
guideroll *= .9;
if ( player.onground ) lastgroundtic = gametic;
// anchor to ground when going down steps
if ( !player.onground && !bNoGravity && (waterlevel < 2) && (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) && (vel.z < 0) )
if ( !player.onground && !bFly && !bFlyCheat && !(player.cheats&CF_NOCLIP2) && (waterlevel < 2) && (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) && (vel.z < 0) )
{
ssup = max(0,(pos.z-floorz));
SetOrigin(Vec2OffsetZ(0,0,floorz),true);
player.onground = true;
}
if ( !(player.cmd.forwardmove|player.cmd.sidemove) )
if ( !(player.cheats & CF_PREDICTING) && !(player.cmd.forwardmove|player.cmd.sidemove) )
PlayIdle();
Vector3 dodge = (0,0,0), x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
@ -442,12 +535,10 @@ Class Demolitionist : PlayerPawn
if ( !(fm|sm) ) fm = 1;
if ( fm ) dodge += (fm>0)?X:-X;
if ( sm ) dodge += (sm>0)?Y:-Y;
if ( player.onground )
{
dodge.z = max(0,dodge.z);
if ( dodge == (0,0,0) ) dodge.xy = RotateVector((1,0),angle);
}
dodge.z += .15;
if ( player.onground ) dodge.z = max(0,dodge.z);
if ( dodge == (0,0,0) ) dodge.xy = RotateVector((1,0),angle);
if ( (waterlevel < 2) && !(bFly || bFlyCheat || (player.cheats&CF_NOCLIP2)) )
dodge.z += .15;
if ( (dodge.length() > 0) && (dashcooldown <= 0) && (dashfuel > 20.) && player.cmd.buttons&BT_USER2 )
{
dashdir = dodge.unit();
@ -474,7 +565,7 @@ Class Demolitionist : PlayerPawn
{
if ( player.crouchoffset ) player.crouching = 1;
else if ( waterlevel >= 2 ) vel.z = 4*Speed;
else if ( bNoGravity ) vel.z = 3.;
else if ( bFly || bFlyCheat || (player.cheats&CF_NOCLIP2) ) return;
else if ( level.IsJumpingAllowed()
&& (player.onground && (player.jumptics == 0))
|| (!player.onground && (level.maptime > last_jump_held) && (((dashfuel > 10.) && (boostcooldown <= 0)) || walljump)) )
@ -795,7 +886,7 @@ Class Demolitionist : PlayerPawn
Spawn:
// normal idle
#### # 2;
XZW1 A 1 A_JumpIf(player&&(player.mo==self)&&(abs(player.cmd.yaw)>128),"Turn");
XZW1 A 1 A_JumpIf(player&&(player.mo==self)&&(abs(player.cmd.yaw|player.cmd.pitch)>128),"Turn");
Wait;
See:
// normal walking
@ -808,7 +899,7 @@ Class Demolitionist : PlayerPawn
Goto See+1;
Turn:
#### # 8 A_StartSound("demolitionist/runstart",CHAN_FOOTSTEP,CHANF_OVERLAP,.1);
XZW1 C 1 A_JumpIf(!player||!player.cmd.yaw,1);
XZW1 C 1 A_JumpIf(!player||!(player.cmd.yaw|player.cmd.pitch),1);
Wait;
XZW1 C 3 A_StartSound("demolitionist/runstop",CHAN_FOOTSTEP,CHANF_OVERLAP,.1);
Goto Spawn+1;

View file

@ -128,7 +128,7 @@ Class GhostPower : PowerInvisibility
{
Super.InitEffect();
if ( !Owner ) return;
Owner.bNOTARGET = true;
DoEffect();
}
override void EndEffect()
{
@ -143,6 +143,7 @@ Class GhostPower : PowerInvisibility
{
Super.DoEffect();
if ( !Owner ) return;
Owner.bNOTARGET = true;
if ( !snd ) snd = Spawn("GhostSnd",Owner.pos);
snd.target = Owner;
snd.master = self;
@ -213,7 +214,7 @@ Class GhostArtifact : Inventory
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
A_StartSound(UseSound,CHAN_ITEM);
Owner.A_StartSound(UseSound,CHAN_ITEM);
let g = GhostPower(Owner.FindInventory("GhostPower"));
if ( g ) g.EffectTics = g.default.EffectTics;
else Owner.GiveInventory("GhostPower",1);
@ -236,3 +237,126 @@ Class GhostArtifact : Inventory
Stop;
}
}
Class GravSnd : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
if ( players[consoleplayer].Camera == target )
{
A_SoundVolume(CHAN_VOICE,0.);
A_SoundVolume(CHAN_7,.7);
}
else
{
A_SoundVolume(CHAN_VOICE,.2);
A_SoundVolume(CHAN_7,0.);
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("powerup/gravityact",CHAN_VOICE,CHANF_LOOPING,.2,1.5);
A_StartSound("powerup/gravityact",CHAN_7,CHANF_LOOPING,.7,ATTN_NONE);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_7);
}
}
Class GravityPower : Powerup
{
Actor snd;
Default
{
Inventory.Icon "graphics/HUD/Icons/I_Gravity.png";
Powerup.Duration -60;
}
override void InitEffect()
{
Super.InitEffect();
if ( !Owner ) return;
DoEffect();
if ( Owner.pos.z <= Owner.floorz )
Owner.vel.z = 1;
}
override void EndEffect()
{
Super.EndEffect();
if ( !Owner ) return;
if ( !Owner.bFLYCHEAT )
{
Owner.bFLY = false;
Owner.bNOGRAVITY = false;
if ( Owner.pos.z > Owner.floorz ) Owner.player.centering = true;
}
Owner.A_StartSound("powerup/gravityend",CHAN_ITEM);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_GRAVITYS"));
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner ) return;
Owner.bFLY = true;
Owner.bNOGRAVITY = true;
if ( !snd ) snd = Spawn("GravSnd",Owner.pos);
snd.target = Owner;
snd.master = self;
}
}
Class GravitySuppressor : Inventory
{
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
Owner.A_StartSound(UseSound,CHAN_ITEM);
let g = GravityPower(Owner.FindInventory("GravityPower"));
if ( g ) g.EffectTics = g.default.EffectTics;
else Owner.GiveInventory("GravityPower",1);
return true;
}
Default
{
Tag "$T_GRAVITYS";
Stamina 16000;
Inventory.Icon "graphics/HUD/Icons/I_Gravity.png";
Inventory.PickupSound "misc/p_pkup";
Inventory.UseSound "powerup/gravity";
Inventory.PickupMessage "$T_GRAVITYS";
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.INVBAR;
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+FLOATBOB;
FloatBobStrength 0.25;
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}

View file

@ -0,0 +1,97 @@
/*
Quaternion 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 swwm_Quat
{
protected double W, X, Y, Z;
swwm_Quat init( double w, double x, double y, double z )
{
self.W = w;
self.X = x;
self.Y = y;
self.Z = z;
return self;
}
void copy( swwm_Quat q )
{
W = q.W;
X = q.X;
Y = q.Y;
Z = q.Z;
}
static swwm_Quat create( double w, double x, double y, double z )
{
return new("swwm_Quat").init(w,x,y,z);
}
static swwm_Quat create_axis( Vector3 axis, double theta )
{
double scale = axis dot axis;
if ( scale < double.epsilon ) return swwm_Quat.create(1,0,0,0);
theta *= 0.5;
double f = sin(theta)/sqrt(scale);
return swwm_Quat.create(cos(theta),axis.x*f,axis.y*f,axis.z*f);
}
static swwm_Quat create_euler( double pitch, double yaw, double roll )
{
swwm_Quat zrot = swwm_Quat.create_axis((0,0,1),yaw);
swwm_Quat yrot = swwm_Quat.create_axis((0,1,0),pitch);
swwm_Quat xrot = swwm_Quat.create_axis((1,0,0),roll);
swwm_Quat sum = zrot.qmul(yrot);
sum = sum.qmul(xrot);
return sum;
}
// copied here since Actor.Normalize180 is not (yet) clearscope
static double Normalize180( double ang )
{
ang = ang%360;
ang = (ang+360)%360;
if ( ang > 180 ) ang -= 360;
return ang;
}
double, double, double to_euler()
{
double stest = z*x-w*y;
double yawY = 2*(w*z+x*y);
double yawX = 1-2*(y*y+z*z);
double st = 0.4999995;
double pitch = 0;
double yaw = 0;
double roll = 0;
if ( stest <= -st )
{
pitch = 90;
yaw = atan2(yawY,yawX);
roll = Normalize180(yaw+(2*atan2(x,w)));
}
else if ( stest > st )
{
pitch = -90;
yaw = atan2(yawY,yawX);
roll = Normalize180(yaw+(2*atan2(x,w)));
}
else
{
pitch = -asin(2*stest);
yaw = atan2(yawY,yawX);
roll = atan2(2*(w*x+y*z),(1-2*(x*x+y*y)));
}
return pitch, yaw, roll;
}
swwm_Quat qmul( swwm_Quat q )
{
return swwm_Quat.create(w*q.w-x*q.x-y*q.y-z*q.z,w*q.x+x*q.w+y*q.z-z
*q.y,w*q.y+y*q.w+z*q.x-x*q.z,w*q.z+z*q.w+x*q.y-y*q.x);
}
}