Toggle chasecam/mouselook with custom player states?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)

Toggle chasecam/mouselook with custom player states?

Postby vAethor » Tue Jan 11, 2022 9:45 am

I've begun work on a nice 3rd-person WAD using a modified version of LordOZ's SRB2 chasecam script. My idea is the third-person view restricts the player to melee attacks, with a separate key to draw your gun, which ideally kills the chasecam and switches to a first-person view.

My thought is that when in 3rd-person, mouselook is disabled, but when in first-person aiming mode, the player can look up and down but cannot move until you put away your gun. Basically a bit like an old N64-era platformer - third-person but with a first-person "look" mode where the player is immobile, but can look in any direction to aim and fire his weapon.

I am still in the process of teaching myself what everything does in the ACS script for the chasecam. One idea I had is to define two custom cameras, one for the normal view and the other for the first-person aiming view, and swap between them depending on what state the player is currently in. As for toggling mouselook and player movement, I am less sure about that, or if it is even possible. Maybe player movement can be disabled by temporarily setting the player's speed to zero when he enters the aiming state, but I am not sure.

I'd love to hear some feedback on what can be done, or some good workarounds if not everything is possible.
Joined: 10 May 2017

Re: Toggle chasecam/mouselook with custom player states?

Postby Jarewill » Wed Jan 12, 2022 9:02 am

You don't need two cameras for this, as the player actor itself is a camera.
In an ACS script you can use ChangeCamera to change the current camera to TID, or back to the player if the TID is 0.
Changing back to the player will also make it show the current weapon on the HUD.

For freezing player movement you can use SetPlayerProperty(PROP_FROZEN) and it will still allow the player to move the camera and interact with things.
For keeping the pitch in place in 3rd person, use ChangeActorPitch to keep it at 0. (centered)
Remember to make the chasecam not inherit the pitch with this solution, as it will be visibly jerking the camera back in place, but that shouldn't be an issue if the chasecam does not inherit player's pitch.

If I could see the code, I would be able to help more.
Joined: 21 Jul 2019

Re: Toggle chasecam/mouselook with custom player states?

Postby vAethor » Wed Jan 12, 2022 9:40 am

Thanks so much for getting back to me! I had no idea all three of those were possible, that is good news.

As for the code, there really is not much currently aside from adapting the SRB2 chasecam script. The result is rather nice though, albeit basic, when tested in vanilla Doom. You can see the Doom player just like you would a normal chasecam, but interestingly toggling the chasecam in the console seems to switch between the vanilla cam and the custom one defined in the script.

Anyways here's what I've got so far.

Code: Select allExpand view
// ACS
#library "cam"
#include "zcommon.acs"
#include "GravityValues.acs"

// Original script by RomioTheBadass - aka LordOZ_98, based on
// the ArmyGuy's code
// Currently no modifications have been made, as I am still rather new to
// ACS and trying to figure out how it works compared to Decorate and ZScript

script 815 (void) NET CLIENTSIDE //Managing chasecam
  if (GetCVar("chase_active") == true)
   SetCVar("Chase_Active", False);
  if (GetCVar("chase_active") == False)
   SetCVar("Chase_Active", True);

// Scripts
Script "WaypointSpawn" (void)
   int tid = UniqueTID(-32768, 32767);
   Thing_ChangeTID(ActivatorTID(), tid);
   int playerNum = PlayerNumber();
   camWayTID[playerNum] = tid;
   SetActorProperty(camTID[playerNum], APROP_MasterTID, camWayTID[playerNum]);
   SetActorPosition(tid, GetActorX(tid), GetActorY(tid), GetActorZ(0) + GetActorProperty(0, APROP_Height) + GetCVar("chase_height"), false);
   GiveActorInventory(camTID[playerNum], "WarpToWaypoint", 1);

Script "CameraMain" ENTER
   // Set up the TID's and spawn the waypoint
   int tid, playerNum, plrInput, yawAdd, pitchAdd, plrRotType, a, p;
   int plrAngle = GetActorAngle(0);
   playerNum = PlayerNumber();
   tid = UniqueTID(-32768, 32767);
   camTID[playerNum] = tid;
   SpawnForced("ChaseCam", GetActorX(0), GetActorY(0), GetActorZ(0), tid, GetActorAngle(0));
   while (true)
      plrInput = GetPlayerInput(-1, INPUT_BUTTONS);
        yawAdd = GetPlayerInput(-1, INPUT_YAW);
        pitchAdd = -GetPlayerInput(-1, INPUT_PITCH);
      a = a + yawAdd;
      p = p + pitchAdd;
      if (p > 0.23)
         p = 0.23;
      if (p < -0.23)
         p = -0.23;
      LineAttack(0, a + 0.5, -p, 0, "ChaseCamWaypoint", "", GetCVar("chase_dist"), FHF_NORANDOMPUFFZ);
      SetActorAngle(camWayTID[playerNum], a);
      SetActorPitch(camWayTID[playerNum], p);
      SetActorAngle(camTID[playerNum], a);
      SetActorPitch(camTID[playerNum], p);
      plrRotType = GetCVar("chase_rotateplr");
      if (plrRotType == 1)
         plrAngle = a;
      else if (plrRotType == 2)
         if (plrInput & BT_FORWARD || plrInput & BT_BACK || plrInput & BT_MOVELEFT || plrInput & BT_MOVERIGHT || plrInput & BT_ATTACK || plrInput & BT_ALTATTACK)
            plrAngle = a;
      if (GetCVar("chase_active"))
         ChangeCamera(camTID[playerNum], 0, 0);
         plrAngle = a;
         ChangeCamera(0, 0, 0);
      SetActorAngle(0, plrAngle);
      SetActorPitch(0, p);

script "coopchase" (void)

And this is the code in GravityValues:
Code: Select allExpand view

int candrown = 0;
int nojump = 1;

int spinning[64];
int GlideState[64];

int monitorthrust[64];

#define MAXPLAYERS 64

#define PLAYER_TID_START 300


I believe learning more ACS is in order, and I will probably enjoy messing around with the functions you suggested.
Joined: 10 May 2017

Return to Scripting

Who is online

Users browsing this forum: No registered users and 0 guests