OldUnreal / UnrealTournamentPatches

Other
976 stars 29 forks source link

Spectator with advanced features, like "ghost" mode #1618

Open t3r6 opened 2 weeks ago

t3r6 commented 2 weeks ago

In Half Life and Counter-Strike 1.6 they allow a spectator to go through walls. It's only possible in UT99 by using the "ghost" cheat but it does not work on servers. I'd be nice to have this feature in some advanced spectator settings.

Another feature I saw in some games: Spectator adjusted speed. It is very helpful when spectating very long maps. For instance: you scroll your mouse up and down to increase or decrease your spectator speed to a complete halt or use "+/-" buttons to accomplish this.

BerserkerBG commented 2 weeks ago

Another feature I saw in some games: Spectator adjusted speed. It is very helpful when spectating very long maps. For instance: you scroll your mouse up and down to increase or decrease your spectator speed to a complete halt or use "+/-" buttons to accomplish this.

I would recommend if user holds the Walk key, it would make the camera faster, but that's about it. The other implementations you suggested with scroll and +/- don't seem good in my opinion, because people usually bind those keys to something else.

t3r6 commented 2 weeks ago

Another feature I saw in some games: Spectator adjusted speed. It is very helpful when spectating very long maps. For instance: you scroll your mouse up and down to increase or decrease your spectator speed to a complete halt or use "+/-" buttons to accomplish this.

I would recommend if user holds the Walk key, it would make the camera faster, but that's about it. The other implementations you suggested with scroll and +/- don't seem good in my opinion, because people usually bind those keys to something else.

Just clicking "shift" may not be enough on some really big maps. Also a spectator with various speeds can also help in creating frag and other movies.

I have an idea. When spectating, click some button to enter the advanced spectator mode. This advanced spectator mode uses its own configurable key binds. Like mouse up and down to increase or decrease your spectator speed, press "g" to go through walls, hide HUD with one button etc.

SeriousBuggie commented 1 week ago

@SeriousBarbie have such mod on MH server. Which allow spectators be ghost and move with bigger (adjustable) speed.

SeriousBarbie commented 1 week ago

This spectator can

class SpectatorSB extends CHSpectator config(BarbiesWorld);

var config int AirSpeedNew; var Actor OldViewTarget;

replication { reliable if (Role < ROLE_Authority) UseTeleporter, SetAirSpeed; }

exec function AltFire( optional float F ) { if (bFire != 0 && ViewTarget != None) { SetLocation(ViewTarget.Location); SetRotation(ViewTarget.Rotation); } //bBehindView = false; //Viewtarget = None; //ClientMessage(ViewingFrom @ OwnCamera, 'Event', true); Super.AltFire(F); }

function Died(pawn Killer, name damageType, vector HitLocation) { // no code - specs cannot die (introduced because of CloudZones) }

exec function Fly() { UnderWaterTime = -1; SetCollision(false, false, false); bCollideWorld = false; ClientRestart(); }

exec function Grab() { local Teleporter NearbyTeleporter; local bool bTeleFound;

bTeleFound = false;
foreach RadiusActors(class'Teleporter', NearbyTeleporter, class'PlayerPawn'.Default.CollisionRadius, Location)
{
    UseTeleporter(NearbyTeleporter);
    bTeleFound = true;
    break;
}
if ( ! bTeleFound)
    ClientMessage("no teleporter is close to you");

}

simulated event PostNetBeginPlay() { Super.PostNetBeginPlay(); if (AirSpeedNew >= 0) AirSpeed = AirSpeedNew; SetTimer(1, true); }

simulated function SetAirSpeed(int NewSpeed) { AirSpeed = NewSpeed; AirSpeedNew = NewSpeed; if (Role != ROLE_Authority) SaveConfig(); }

exec function Suicide() { ClientMessage("Do you want to be a dead Spectator?"); }

event Timer() {

if (ViewTarget == None && OldViewTarget != None)
{
    ViewTarget = OldViewTarget;
    OldViewTarget = None;
}
else
    if (PlayerPawn(ViewTarget) != None)
        if (Projectile(PlayerPawn(ViewTarget).ViewTarget) != None)
            if (ViewTarget != PlayerPawn(ViewTarget).ViewTarget)
            {
                OldViewTarget = ViewTarget;
                ViewTarget = PlayerPawn(ViewTarget).ViewTarget;
            }

}

function UseTeleporter(Teleporter SrcTele) { /** Searches Teleporter with the given WhatTag and returns TRUE if one ore more were found. If multiple exist, a random one is returned. (See also code in stock Teleporter.uc) **/ local int i; local Teleporter DestTele;

if (Role < ROLE_Authority)
    return;

foreach AllActors(class'Teleporter', DestTele)
    if (string(DestTele.tag) ~= SrcTele.URL && SrcTele != DestTele)
        i++;
if (i <= 0)
{
    ClientMessage("Teleport destination for" @ SrcTele @ "not found!");
    return;
}
i = rand(i);
foreach AllActors(class'Teleporter', DestTele)
    if (string(DestTele.tag) ~= SrcTele.URL && SrcTele != DestTele && i-- == 0)
        break;
SetLocation(DestTele.Location);

}

//***

state CheatFlying {

function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
{
    Acceleration = Normal(NewAccel);
    Velocity = Normal(NewAccel) * AirSpeed;
    AutonomousPhysics(DeltaTime);
}

}

defaultproperties { AirSpeedNew=-1 AirSpeed=800 bCheatsEnabled=True bCollideActors=false bBlockActors=false bBlockPlayers=false bCollideWorld=false //bHidden=false //Mesh=LodMesh'UnrealI.Nali2' //DrawType=DT_Mesh //Skin=Texture'UnrealShare.Skins.JNali1' //Texture=Texture'Engine.S_Camera' }