• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

RELEASE: RO3DAudio

Status
Not open for further replies.
Hmm looks like you decided to release this before we have. We have had it in and working for around 6 months now at DH.

thats 2 things we have implemented. you are using now ????.

This is something that I have done on my own accord. If you may have noticed, I made the initiative here and had been toying with the idea for a significant period of time prior (circa the period of time when the request for 3D voice commands was really in force, which was much longer than 6 months ago). Additionally, this was a feature from RO:CA before it was DH. My issue was simply that I didn't know how to go about properly coding the mutator -- I had otherwise been able to isolate what it was that governed the properties for 3D Audio but making a mutator for it was what was holding me back.

Hope that clears things up.

This one, plus 'No Blinking Objectives', plus 'AntiBS', plus 'EH-MGmut' (or however it is spelled) should be released by Tripwire as a patch to be added to all servers as THE standard for RO play. All servers should be running these muts. They definately would raise the bar for RO and everyone playing it.

We have Deeival working on the No Blinking Objectives / No Cap Concentration bar (doesn't show the proportion of players within a capzone, you will only be able to see if it is being capped or not) mutator. That along with 3DAudio will be included with RO-Kriegstadt Beta 4 as part of "Essential Mutators"
 
Upvote 0
Very cool, will try finding a server running it tonight! :D

A question for the server admins already running this; is it affecting server load or ping times in any way? I would think if the server has to send directional voice information to every player as well as the other data, it would be more demanding on the server? Or maybe the client, I dont know?

-S
 
Upvote 0
Very cool, will try finding a server running it tonight! :D

A question for the server admins already running this; is it affecting server load or ping times in any way? I would think if the server has to send directional voice information to every player as well as the other data, it would be more demanding on the server? Or maybe the client, I dont know?

-S

Well we also tried this out on MN waaay ago and we decided that the load on the clients rather than the server was too large, especially when you get around the 50 player number. Why do you think TWI didn't use it?
 
Upvote 0
I want to clear some things up because it seems a few misguided idiots think I stole code from DH:

I began work on trying to crack the code surrounding the 3D Audio last year around a time when it was a big topic of discussion. The usual response from the developers was that things are the way we want them and if you want to change this then do it yourself. So, I took it upon myself to track down what in the code made the game use 3D Audio for enemy players but full volume for friendlies. As stated on the first page,

So the bUseLocationalVoice in ROVoicePack.uc mystery was solved. :D

For those individuals confused about what this is, if you have the RO SDK you can find the file ROVoicePack.uc

C:\Program Files\Valve\Steam\SteamApps\common\red orchestra\ROEngine\Classes\ROVoicePack.uc

This governs the voice commands used by players. Here are the contents:

Code:
//------------------------------------------------------------------------------
// $Id: ROVoicePack.uc,v 1.12 2004/05/17 06:03:02 antarian Exp $
//------------------------------------------------------------------------------
class ROVoicePack extends xVoicePack;

var() SoundGroup SupportSound[20];
var() localized string SupportString[48];
var() localized string SupportAbbrev[48];
var() localized string SupportStringAxis[48];
var() localized string SupportAbbrevAxis[48];
var() name SupportAnim[48];
var() int numSupports;

var() SoundGroup EnemySound[20];
var() localized string EnemyString[48];
var() localized string EnemyAbbrev[48];
var() localized string EnemyStringAxis[48];
var() localized string EnemyAbbrevAxis[48];
var() name EnemyAnim[48];
var() int numEnemies;

var() SoundGroup AlertSound[20];
var() localized string AlertString[48];
var() localized string AlertAbbrev[48];
var() name AlertAnim[48];
var() int numAlerts;

var() name AttackAnim;
var() name DefendAnim;
var() int numAttacks;

var() SoundGroup VehicleDirectionSound[20];
var() localized string VehicleDirectionString[48];
var() localized string VehicleDirectionAbbrev[48];
var() name VehicleDirectionAnim[48];
var() int numVehicleDirections;

var() SoundGroup VehicleAlertSound[20];
var() localized string VehicleAlertString[48];
var() localized string VehicleAlertAbbrev[48];
var() name VehicleAlertAnim[48];
var() int numVehicleAlerts;

var() SoundGroup ExtraSound[20];
var() localized string ExtraString[48];
var() localized string ExtraAbbrev[48];
var() name ExtraAnim[48];
var() int numExtras;

var() byte ShoutVolume;
var() byte WhisperVolume;
var() float ShoutRadius;
var() float WhisperRadius;
var float unitWhisperDistance;
var float unitShoutDistance;

var name CurrentMessageType;

//var ROSoundGroup CommandSound[20];
var() int numCommands;

//#exec OBJ LOAD FILE=ROVoiceSounds.uax

//var() Sound AckSound[32]; // acknowledgement sounds
//var() localized string AckString[32];

var bool bUseAxisStrings;

var bool bUseLocationalVoice;
var bool bIsFromDifferentTeam;
var Pawn pawnSender;
var vector senderLoc;

static function PlayerSpeech( name Type, int Index, string Callsign, Actor PackOwner )
{
    xPlayerSpeech(Type, Index, none, PackOwner);
}

static function xPlayerSpeech(name Type, int Index, PlayerReplicationInfo SquadLeader, Actor PackOwner)
{
    local name broadcasttype;
    local vector myLoc;
    //Log("ROVoicePack::PlayerSpeech() Type = "$Type$" Index = "$Index);
    if (Type == 'TAUNT')
        broadcasttype = 'GLOBAL';
    else
        broadcasttype = 'TEAM';
    if (Controller(PackOwner).Pawn == none)
        myLoc = PackOwner.Location;
    else
        myLoc = Controller(PackOwner).Pawn.Location;

    Controller(PackOwner).SendVoiceMessage( Controller(PackOwner).PlayerReplicationInfo, SquadLeader, Type, Index, broadcasttype, Controller(PackOwner).Pawn, myLoc);
}

function BotInitialize(PlayerReplicationInfo Sender,
                       PlayerReplicationInfo Recipient,
                       name messagetype,
                       byte messageIndex)
{
    DelayedSender = Sender;
    DisplayString = 0;
    bDisplayNextMessage = bShowMessageText;
    if ( messagetype == 'ACK' )
        SetTimer(2.65, false);
    else
        SetTimer(0.65, false);
    CurrentMessageType=messagetype;
    SetMessageByType(messagetype,messageIndex ,Recipient);
}

function ClientInitializeLocational(PlayerReplicationInfo Sender,
                          PlayerReplicationInfo Recipient,
                          name messagetype, byte messageIndex,
                          optional Pawn soundSender, optional vector senderLocation)
{
    pawnSender = soundSender;
    senderLoc = senderLocation;
    ClientInitialize(Sender, Recipient, messagetype, messageIndex);
}

function ClientInitialize(PlayerReplicationInfo Sender,
                          PlayerReplicationInfo Recipient,
                          name messagetype, byte messageIndex)
{
    //log("ClientInitialize called: messagetype = " $ messagetype $ ", messageIndex = " $ messageIndex);

    DelayedSender = Sender;
    DisplayString = 0;
    bDisplayPortrait = false;
    bDisplayNextMessage = bShowMessageText;
    CurrentMessageType = messagetype;

    if(PlayerController(Owner).bNoVoiceMessages    )
    {
        Destroy();
        return;
    }

    if ( Sender.bBot )
    {
        BotInitialize(Sender, Recipient, messagetype, messageIndex);
        return;
    }

    SetTimer(0.6, false);

    SetMessageByType(messagetype,messageIndex ,Recipient);

}

/*static function string getMessagePhraseFor(name messagetype, int messageID)
{
   if ( messagetype == 'SHOUT' )
      return default.ShoutString[messageID];
   else if( messagetype == 'ACK' )
      return default.AckString[messageID];
   else if(  messagetype == 'ORDER' )
      return default.OrderString[messageID];
} */


function SetMessageByType( name messagetype,
                           int messageIndex,
                           PlayerReplicationInfo Recipient)
{
    local Sound MessageSound;

    if ( messagetype == 'SUPPORT' )
        SetClientSupportMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'ACK' )
        SetClientAckMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'ENEMY' )
        SetClientEnemyMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'ALERT' )
        SetClientAlertMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'VEH_ORDERS' )
        SetClientVehicleDirectionMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'VEH_ALERTS' )
        SetClientVehicleAlertMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'ORDER' )
        SetClientOrderMessage(messageIndex, Recipient, MessageSound);

    else if ( messagetype == 'TAUNT' )
        SetClientExtraMessage(messageIndex, Recipient, MessageSound);

    else if( messagetype == 'ATTACK')
        SetClientAttackMessage(messageIndex, Recipient, MessageSound);

    else if( messagetype == 'DEFEND')
        SetClientDefendMessage(messageIndex, Recipient, MessageSound);

    else if( messagetype == 'VEH_GOTO')
        SetClientGotoMessage(messageIndex, Recipient, MessageSound);

    else if( messagetype == 'HELPAT')
        SetClientHelpAtMessage(messageIndex, Recipient, MessageSound);

    else if( messagetype == 'UNDERATTACK')
        SetClientUnderAttackAtMessage(messageIndex, Recipient, MessageSound);

    // Friendly fire message
    else if ( messagetype == 'FRIENDLYFIRE' )
        SetClientFFireMessage(Rand(NumFFires), Recipient, MessageSound);

    // Bot messages
    else if ( messagetype == 'Other' && messageIndex < 10)
        SetClientSupportMessage(messageIndex, Recipient, MessageSound);
    else if ( messagetype == 'Other' && messageIndex < 20)
        SetClientAckMessage(messageIndex - 10, Recipient, MessageSound);
    else if ( messagetype == 'Other' && messageIndex < 30)
        SetClientEnemyMessage(messageIndex - 20, Recipient, MessageSound);
    else if ( messagetype == 'Other' && messageIndex < 40)
        SetClientAlertMessage(messageIndex - 30, Recipient, MessageSound);


    Phrase[0] = MessageSound;
    PhraseString[0] = MessageString;
    DisplayMessage[0] = DisplayString;


}

static function byte GetMessageIndex(name PhraseName)
{
    local float r;
    r = FRand();

    if ( PhraseName == 'INJURED' )
        return 0;
    else if ( PhraseName == 'NEEDBACKUP' )
        return 0;
    else if ( PhraseName == 'GOTYOURBACK' )
        return 31;
    else if ( PhraseName == 'MANDOWN' )
        return 0;
    else if ( PhraseName == 'INPOSITION' )
        return 10;
    else if ( PhraseName == 'ONMYWAY' )
        return 10;
    else
        log("Unknown message type used in GetMessageIndex call: " $ PhraseName);
}

function SetClientSupportMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = SupportSound[messageIndex];
    MessageAnim = SupportAnim[messageIndex];

    if (bUseAxisStrings && SupportStringAxis[messageIndex] != "")
        MessageString = SupportStringAxis[messageIndex];
    else
        MessageString = SupportString[messageIndex];
}

function SetClientEnemyMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = EnemySound[messageIndex];
    MessageAnim = EnemyAnim[messageIndex];

    if (bUseAxisStrings && EnemyStringAxis[messageIndex] != "")
        MessageString = EnemyStringAxis[messageIndex];
    else
        MessageString = EnemyString[messageIndex];
}


function SetClientOrderMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = OrderSound[messageIndex];
    MessageString = OrderString[messageIndex];
    MessageAnim = OrderAnim[messageIndex];
}

//=========================================================================================
// SetClientVehicleMessage -
//=========================================================================================
function SetClientVehicleDirectionMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = VehicleDirectionSound[messageIndex];
    MessageString = VehicleDirectionString[messageIndex];
    MessageAnim = VehicleDirectionAnim[messageIndex];
}

function SetClientVehicleAlertMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = VehicleAlertSound[messageIndex];
    MessageString = VehicleAlertString[messageIndex];
    MessageAnim = VehicleAlertAnim[messageIndex];
}

function SetClientDefendMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    local ROGameReplicationInfo ROGameRep;
    local ROPlayer rop;
    rop = ROPlayer(Owner);
    if(rop != none)
       ROGameRep = ROGameReplicationInfo(rop.GameReplicationInfo);

    MessageSound = OrderSound[1];
    MessageString = OrderString[1]@ROGameRep.Objectives[messageIndex].ObjName;
    MessageAnim = DefendAnim;
}

function SetClientHelpAtMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    local ROGameReplicationInfo ROGameRep;
    local ROPlayer rop;
    rop = ROPlayer(Owner);
    if(rop != none)
       ROGameRep = ROGameReplicationInfo(rop.GameReplicationInfo);

    MessageSound = SupportSound[1];
    MessageString = SupportString[1]@ROGameRep.Objectives[messageIndex].ObjName;
    MessageAnim = DefendAnim;
}

function SetClientUnderAttackAtMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    local ROGameReplicationInfo ROGameRep;
    local ROPlayer rop;
    rop = ROPlayer(Owner);
    if(rop != none)
       ROGameRep = ROGameReplicationInfo(rop.GameReplicationInfo);

    MessageSound = AlertSound[8];
    MessageString = AlertString[8]@ROGameRep.Objectives[messageIndex].ObjName;
    MessageAnim = DefendAnim;
}

function SetClientGotoMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    local ROGameReplicationInfo ROGameRep;
    local ROPlayer rop;
    rop = ROPlayer(Owner);
    if(rop != none)
       ROGameRep = ROGameReplicationInfo(rop.GameReplicationInfo);

    MessageSound = VehicleDirectionSound[0];
    MessageString = vehicleDirectionString[0]@ROGameRep.Objectives[messageIndex].ObjName;
    MessageAnim = '';
}


function SetClientAckMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = AckSound[messageIndex];
    MessageString = AckString[messageIndex];
    MessageAnim = AckAnim[messageIndex];
}

function SetClientExtraMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = ExtraSound[messageIndex];
    MessageString = ExtraString[messageIndex];
    MessageAnim = ExtraAnim[messageIndex];
}

function SetClientAlertMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = AlertSound[messageIndex];
    MessageString = AlertString[messageIndex];
    MessageAnim = AlertAnim[messageIndex];
}

function SetClientAttackMessage(int messageIndex,
                                 PlayerReplicationInfo Recipient,
                                 out Sound MessageSound)
{
    local ROGameReplicationInfo ROGameRep;
    local ROPlayer rop;
    rop = ROPlayer(Owner);
    if(rop != none)
       ROGameRep = ROGameReplicationInfo(rop.GameReplicationInfo);
    //log("ROVoicePack::SetClientAttackMessag(), messageIndex  = "$messageIndex);
    //going to assume that the Objective array never get's altered in game.
    //
    MessageSound = OrderSound[0];
    MessageString = OrderString[0]@ROGameRep.Objectives[messageIndex].ObjName;

    MessageAnim = AttackAnim;

}

/*function SetAckMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = AckSound[messageIndex];
    MessageString = AckString[messageIndex];
    MessageAnim = AckAnim[messageIndex];
}*/

function SetClientFFireMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    //MessageSound = FFireSound[messageIndex];
    MessageSound = AlertSound[7];
    //MessageString = FFireString[messageIndex];
    MessageString = AlertString[7];
    MessageAnim = FFireAnim[messageIndex];
}

function SetFFireMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    //MessageSound = FFireSound[messageIndex];
    MessageSound = AlertSound[7];
    //MessageString = FFireString[messageIndex];
    MessageString = AlertString[7];
    MessageAnim = FFireAnim[messageIndex];
}

// Taunts from Players
function SetClientTauntMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{

    MessageSound = TauntSound[messageIndex];
    MessageString = TauntString[messageIndex];
    MessageAnim = TauntAnim[messageIndex];
}

// Taunts from Bots
function SetTauntMessage(int messageIndex, PlayerReplicationInfo Recipient, out Sound MessageSound)
{
    MessageSound = TauntSound[messageIndex];
    MessageString = TauntString[messageIndex];
    MessageAnim = TauntAnim[messageIndex];
}
//-----------------------------------------------------------------------------
// overrider timer to play time from the voicepack to give it locational
// sound
//-----------------------------------------------------------------------------
function string getClientParsedMessage()
{
   return  ClientParseMessageString(DelayedSender, PhraseString[PhraseNum]);
}

function Timer()
{
    local PlayerController PlayerOwner;
    local Actor soundPlayer;

    PlayerOwner = PlayerController(Owner);
    if ( bDisplayPortrait && (PhraseNum == 0) && !(bIsFromDifferentTeam && bUseAxisStrings) )
        PlayerController(Owner).myHUD.DisplayPortrait(PortraitPRI);

    /*if ( (bDisplayNextMessage || (DisplayMessage[PhraseNum] != 0)) && DelayedSender.bBot)
    {
           Mesg = ClientParseMessageString(DelayedSender, PhraseString[PhraseNum]);
           PlayerOwner.TeamMessage(DelayedSender,Mesg,'TEAMSAY');
    }*/

    if ( (Phrase[PhraseNum] != None) &&
         ((Level.TimeSeconds - PlayerOwner.LastPlaySpeech > 2) ||
         (PhraseNum > 0))  )
    {
        PlayerOwner.LastPlaySpeech = Level.TimeSeconds;

        if (bUseLocationalVoice)
        {
            if (pawnSender != none)
                pawnSender.PlaySound(Phrase[PhraseNum], SLOT_None,ShoutVolume,,,1.0,false);
            else
            {
                soundPlayer = Spawn(Class'ROVoiceMessageEffect',,, senderLoc);
                if (soundPlayer != none)
                    soundPlayer.PlaySound(Phrase[PhraseNum], SLOT_None,ShoutVolume,,,1.0,false);
                else
                    warn("Unable to spawn ROVoiceMessageEffect at " $ senderLoc $ "!");
            }
        }
        else
        {
            if ( (PlayerOwner.ViewTarget != None) )
            {
                PlayerOwner.ViewTarget.PlaySound(Phrase[PhraseNum], SLOT_Interface,ShoutVolume,,,1.0,false);
            }
            else
            {
                PlayerOwner.PlaySound(Phrase[PhraseNum], SLOT_Interface,ShoutVolume,,,1.0,false);
            }
        }

        if (MessageAnim != '')
        {
            UnrealPlayer(PlayerOwner).Taunt(MessageAnim);
        }

        if ( Phrase[PhraseNum+1] == None )
            Destroy();
        else
        {
            // I don't think we ever get here in RO, but log it just in case. We're
            // trying to cut down on sound packs that need to be loaded on the server
            if( GetSoundDuration(Phrase[PhraseNum]) == 0 )
            {
                log("ROVoicePack Setting the timer for a sound to zero");
            }
            SetTimer(FMax(0.1,GetSoundDuration(Phrase[PhraseNum])), false);
            PhraseNum++;
        }
    }
    else
        Destroy();

}

static function bool isValidDistanceForMessageType(name messageType, float distance)
{
    if(messageType == 'WHISPER' && distance > default.unitWhisperDistance )
    {
        return false;
    }
    else if(messageType == 'ORDER' && distance > default.unitShoutDistance)
        return false;

    return true;
}

static function GetAllSupports( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numSupports; i++ )
    {
        if ( default.SupportAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.SupportAbbrev[i];

        else if ( default.SupportString[i] != "" )
            CmdArray[CmdArray.Length] = default.SupportString[i];

        else break;
    }
}

static function GetAllAcknowledges( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numAcks; i++ )
    {
        if ( default.AckAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.AckAbbrev[i];

        else if ( default.AckString[i] != "" )
            CmdArray[CmdArray.Length] = default.AckString[i];

        else break;
    }
}

static function GetAllEnemies( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numEnemies; i++ )
    {
        if ( default.EnemyAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.EnemyAbbrev[i];

        else if ( default.EnemyString[i] != "" )
            CmdArray[CmdArray.Length] = default.EnemyString[i];

        else break;
    }
}

static function GetAllAlerts( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numAlerts; i++ )
    {
        if ( default.AlertAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.AlertAbbrev[i];

        else if ( default.AlertString[i] != "" )
            CmdArray[CmdArray.Length] = default.AlertString[i];

        else break;
    }
}

static function GetAllVehicleDirections( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numVehicleDirections; i++ )
    {
        if ( default.VehicleDirectionAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.VehicleDirectionAbbrev[i];

        else if ( default.VehicleDirectionString[i] != "" )
            CmdArray[CmdArray.Length] = default.VehicleDirectionString[i];

        else break;
    }
}

static function GetAllVehicleAlerts( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numVehicleAlerts; i++ )
    {
        if ( default.VehicleAlertAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.VehicleAlertAbbrev[i];

        else if ( default.VehicleAlertString[i] != "" )
            CmdArray[CmdArray.Length] = default.VehicleAlertString[i];

        else break;
    }
}

static function GetAllOrders( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < MAXORDER; i++ )
    {
        if ( default.OrderAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.OrderAbbrev[i];

        else if ( default.OrderString[i] != "" )
            CmdArray[CmdArray.Length] = default.OrderString[i];

        else break;
    }
}

static function GetAllExtras( out array<string> CmdArray )
{
    local int i;

    CmdArray.Length = 0;
    for ( i = 0; i < default.numExtras; i++ )
    {
        if ( default.ExtraAbbrev[i] != "" )
            CmdArray[CmdArray.Length] = default.ExtraAbbrev[i];

        else if ( default.ExtraString[i] != "" )
            CmdArray[CmdArray.Length] = default.ExtraString[i];

        else break;
    }
}

defaultproperties
{
    bHidden=true
    numTaunts=0

    numSupports=10
    SupportAbbrev(0)="Help needed"
    SupportAbbrev(1)="Help needed at..."
    SupportAbbrev(2)="Ammo needed"
    SupportAbbrev(3)="Request sniper"
    SupportAbbrev(4)="MG support needed"
    SupportAbbrev(5)="Need an AT Rifle"
    SupportAbbrevAxis(5)="Need a Panzerfaust"
    SupportAbbrev(6)="Request demolition"
    SupportAbbrev(7)="Request tank"
    SupportAbbrev(8)="Request artillery"
    SupportAbbrev(9)="Request transport"

    SupportString(0)="We need help!"
    SupportString(1)="Need help at"
    SupportString(2)="I need ammo!"
    SupportString(3)="Get a sniper over here!"
    SupportString(4)="We need MG support!"
    SupportString(5)="We need an AT Rifle!"
    SupportStringAxis(5)="We need a Panzerfaust!"
    SupportString(6)="Someone blow this!"
    SupportString(7)="We need a tank!"
    SupportString(8)="Give us artillery!"
    SupportString(9)="I need transport!"

    numAcks=4
    AckAbbrev(0)="Yes Sir"
    AckAbbrev(1)="Negative"
    AckAbbrev(2)="Thanks"
    AckAbbrev(3)="Apologize"

    AckString(0)="Yes sir!"
    AckString(1)="No, no!"
    AckString(2)="Thanks"
    AckString(3)="Sorry"


    numEnemies=9
    EnemyAbbrev(0)="Infantry spotted"
    EnemyAbbrev(1)="MG position"
    EnemyAbbrev(2)="Sniper"
    EnemyAbbrev(3)="Sapper"
    EnemyAbbrevAxis(3)="Pioner"
    EnemyAbbrev(4)="Anti-tank soldiers"
    EnemyAbbrev(5)="Small vehicle"
    EnemyAbbrev(6)="Tank"
    EnemyAbbrevAxis(6)="Panzer"
    EnemyAbbrev(7)="Heavy tank"
    EnemyAbbrev(8)="Artillery"

    EnemyString(0)="Infantry spotted!"
    EnemyString(1)="MG position!"
    EnemyString(2)="Sniper!"
    EnemyString(3)="Sapper!"
    EnemyStringAxis(3)="Pionier!"
    EnemyString(4)="Anti-tank soldiers!"
    EnemyString(5)="Small vehicle!"
    EnemyString(6)="Tank! Tank!"
    EnemyStringAxis(6)="Achtung, panzer!"
    EnemyString(7)="Heavy tank!"
    EnemyString(8)="Artillery!"


    numAlerts=10
    AlertAbbrev(0)="Grenade"
    AlertAbbrev(1)="Go go go"
    AlertAbbrev(2)="Take cover"
    AlertAbbrev(3)="Stop"
    AlertAbbrev(4)="Follow me"
    AlertAbbrev(5)="Satchel planted"
    AlertAbbrev(6)="Covering fire"
    AlertAbbrev(7)="Friendly fire"
    AlertAbbrev(8)="Under attack at objective"
    AlertAbbrev(9)="Retreat"

    AlertString(0)="Grenade!"
    AlertString(1)="Go go go!"
    AlertString(2)="Take cover!"
    AlertString(3)="Stop!"
    AlertString(4)="Follow me!"
    AlertString(5)="Satchel planted!"
    AlertString(6)="Covering fire!"
    AlertString(7)="Friendly fire!"
    AlertString(8)="Under attack at"
    AlertString(9)="Retreat!"


    numCommands=8
    OrderAbbrev(0)="Attack..."
    OrderAbbrev(1)="Defend..."
    OrderAbbrev(2)="Hold Position"
    OrderAbbrev(3)="Follow Me"
    OrderAbbrev(4)="Move out"
    OrderAbbrev(5)="Retreat"
    OrderAbbrev(6)="Engage"
    OrderAbbrev(7)="Cease Fire"

    OrderString(0)="Attack"
    OrderString(1)="Defend"
    OrderString(2)="Hold this position!"
    OrderString(3)="Follow me!"
    OrderString(4)="Attack at will!"
    OrderString(5)="Retreat!"
    OrderString(6)="Fire at will!"
    OrderString(7)="Cease fire!"


       numVehicleDirections=10
       vehicleDirectionAbbrev(0)="Go to..."
    vehicleDirectionAbbrev(1)="Move forward"
    vehicleDirectionAbbrev(2)="Stop"
    vehicleDirectionAbbrev(3)="Move back"
    vehicleDirectionAbbrev(4)="Go left"
    vehicleDirectionAbbrev(5)="Go right"
    vehicleDirectionAbbrev(6)="Forward 5 metres"
    vehicleDirectionAbbrev(7)="Back 5 metres"
    vehicleDirectionAbbrev(8)="Turn left a little"
    vehicleDirectionAbbrev(9)="Turn right a little"

    vehicleDirectionString(0)="Go to"
    vehicleDirectionString(1)="Move forward"
    vehicleDirectionString(2)="Stop"
    vehicleDirectionString(3)="Move back"
    vehicleDirectionString(4)="Go left"
    vehicleDirectionString(5)="Go right"
    vehicleDirectionString(6)="Forward 5 metres!"
    vehicleDirectionString(7)="Back 5 metres!"
    vehicleDirectionString(8)="Turn left a little!"
    vehicleDirectionString(9)="Turn right a little!"

    numVehicleAlerts=10
       vehicleAlertAbbrev(0)="Enemy in front"
    vehicleAlertAbbrev(1)="Enemy left flank"
    vehicleAlertAbbrev(2)="Enemy right flank"
    vehicleAlertAbbrev(3)="Enemy behind us"
    vehicleAlertAbbrev(4)="Enemy infantry close"
    vehicleAlertAbbrev(5)="Acknowledged"
    vehicleAlertAbbrev(6)="Negative"
    vehicleAlertAbbrev(7)="We're burning"
    vehicleAlertAbbrev(8)="Get out"
    vehicleAlertAbbrev(9)="Loaded"

    vehicleAlertString(0)="Enemy in front!"
    vehicleAlertString(1)="Enemy left flank!"
    vehicleAlertString(2)="Enemy right flank!"
    vehicleAlertString(3)="Enemy behind us!"
    vehicleAlertString(4)="Enemy infantry close!"
    vehicleAlertString(5)="Yes, sir!"
    vehicleAlertString(6)="No, no!"
    vehicleAlertString(7)="We're burning!"
    vehicleAlertString(8)="Get out!"
    vehicleAlertString(9)="Loaded."


    numExtras=3
    ExtraAbbrev(0)="I will kill you"
    ExtraAbbrev(1)="No retreat"
    ExtraAbbrev(2)="Insult"

    ExtraString(0)="I will kill you!"
    ExtraString(1)="No retreat!"
    ExtraString(2)="*insult*"

    bUseAxisStrings=false

    ShoutVolume=2.0
    WhisperVolume=1
    unitWhisperDistance=512.0
    unitShoutDistance=4096.0
    ShoutRadius=409.6
    WhisperRadius=25.6

    bUseLocationalVoice=false

}
What we are concerned with is bLocationalVoice, a boolean operator (it is at the end of the code).

Now what does my mutator do? It overrides that variable and sets it to true. The full code of my mutator is as follows:

Code:
///==========================================================
///3D Audio Mutator for Red Orchestra Ostfront 41-45
///==========================================================

class RO3DAudioMut extends Mutator;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
    if ( Other.IsA('ROVoicePack') )
    {
    ROVoicePack(Other).bUseLocationalVoice = true;
    }
    return true;
}


defaultproperties
{
    bAddToServerPackages=True
    FriendlyName="3D Audio Mutator"
    Description="Makes it such that friendly voice commands are heard in 3D. Mutator by EvilHobo."
}
How did I figure out how to do this? I consulted the BeyondUnreal forums as the UnrealWiki wasn't helping me much.

For the relevant thread:
http://forums.beyondunreal.com/showthread.php?t=175478

So what exactly does Darkest Hour do? They did things the easy way from what I can surmise, which is basically copying all of the stock Tripwire files, changing the variables, and compiling it together in a separate package with all different classes.

There is no mutator to be found, no source code to steal.

Those who label me a thief don't have a clue what they are talking about.

If anyone wants to try it out themselves, you can take the code I posted, compile it, and use it as a mutator on your system. You will see that it provides the exact same effect as what I released.

EDIT: Oh that's funny, MN did it too? THEY MUST BE STEALING CODE FROM DH.
 
Upvote 0
Well we also tried this out on MN waaay ago and we decided that the load on the clients rather than the server was too large, especially when you get around the 50 player number. Why do you think TWI didn't use it?

So the load is on the clients, not the server? That should be ok then, in the long run at least, as people get more powerful computers.

Also, as to *why* - I basically thought TWI disabled it to improve teamplay, especially on pub servers, as having any sort of command structure with 'realistic' 3D voice will be really hard. 32 ppl would be 3-4 squads , so you would need some basic command and control. Hence - easier to have the commanders voice (and everyone else screaming for help) in their heads... improved teamplay on public servers, more popular game... nothing wrong with that :D

I tried it on the Werewolf server tonight, but couldn't really tell the difference. But the server was almost full of bots - I'm guessing this does not work with bots at all??

And chill with the *stealing* thing OK? It's for the good of the *community* so it's good for all!
 
Upvote 0
I hopped on the KgW server too and didn't see a difference.

There is probably something I missed in the code. It works just fine in offline (with bots), but I will need to check it out for the online portion.


RO3DAudio was added to the server yesterday. (For the test)
However, it did not function online correctly. :(

It accurately functioned certainly to Bot of offline.
 
Upvote 0
Status
Not open for further replies.