Page 1 of 1

[solved] A WeaponLottery Actor Script

Posted: Sat Jan 10, 2015 3:43 pm
by ANUBITEK
SCRIPT HAS BEEN UPDATED:
http://pastebin.com/QHLEweiq

EDIT:
Sound works now, just add this into the zone's default properties:
- bStatic to False
- bNoDelete to True

So I am now working on a zone in Unreal 227 that is to do the following:

> The player pawn enters a zone, activating a roll.

> A random floating value is chosen; if over 0.7, player is given a flak cannon, and a sound is played; if over 0.8, player is given a flak cannon and a rocket launcher and the same sound is played; if under 0.7, nothing is given, a different sound is played, and the roll happens again.

(NEEDS TO BE ADDED IN)
> When the next roll (and every roll after it) executes, a countdown timer plays (by seconds, so tick needs to be implemented to account for 3 seconds along with 3 countdown sound plays (like Halo 1's respawn timer in multiplayer)).
> If the player neither receives a >0.7 roll nor >0.8 roll for three rolls, a different sound is played and they explode into gibs.

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Sat Jan 10, 2015 4:23 pm
by Spectra

Code: Select all

event ActorEntered(actor other)
{
if ((Other.IsA('PlayerPawn'))) // edit here, define PlayerPawn
        Guy = PlayerPawn;
        gotostate('Lottery_Begin');
        Super.ActorEntered(Other); // Calls the function from this class' parent class, ZoneInfo
}
Your problem was in If condition, where you forgot to put another round bracket at the end. Now it should compile successfully for sure.

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Sat Jan 10, 2015 5:04 pm
by ANUBITEK
Thank you, I'll be sure to compile it after I get home from work. Would you be available to answer more questions on this script later today? I'm very new to coding with only minor experience with C++ and Python, and I've only got to about page 40 of Tim Sweeney's guide to coding, so I'm still trying to figure out correct syntax.

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Sat Jan 10, 2015 5:21 pm
by Higor
General guidelines, try as much as you can to preserve proper casing in names.
And make function names start with an upper case to preserve compatibility with native mods that may have defined said names for native functions. (rare case, but it's a convention among veteran coders)
With the changes below you have a functional zone.

Remove these:

Code: Select all

var sound beep;
var int i;
Add this:

Code: Select all

var int FailCount;
Dunno about the booleans stuff... the current code handles the zone pretty well, unless you want some other functionality?


======================
Brackets boy, brackets.
Without them, firing a rocket into a zone will put it into lottery mode... a failed one that is.
Also, typecasting from Actor into PlayerPawn is necessary to set a PlayerPawn type variable using an Actor reference... and it will fail to do so if said Actor isn't a PlayerPawn (setting to none)

Code: Select all

event ActorEntered(Actor Other)
{
	if ( Other.IsA('PlayerPawn') && !IsInState('Lottery') ) // edit here, define PlayerPawn
	{
		Guy = PlayerPawn(Other);
		GotoState('Lottery');
	}
	Super.ActorEntered(Other); // Calls the function from this class' parent class, ZoneInfo
}

Unreal state code doesn't need counters unless you actually use iterators.
If the whole thing is a linear event, don't use multiple states, one is enough.
GotoState(''); puts the actor in no-state mode
Also, a disabler event if Guy leaves early.

Code: Select all

state Lottery
{
        event ActorLeaving( Actor Other)
        {
                Global.ActorLeaving( Other);
                if ( Other == Guy )
                        GotoState('');
        }
        event EndState()
        {
                Guy = none;
        }
Begin:
        PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        Sleep( 1 );
        PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        Sleep( 1 );
        PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        Sleep( 1 );
        DoLottery();
        Sleep( SPIN_DOWN_TIME_HERE );
        GotoState('');
}

Sounds can be used directly as parameters, same with any non-out parameter type.
Also, a safety get-out-of-here part added.
Also, if Selection >= 0.8... it is ALWAYS >= 0.7 as well...
So we're using ELSE IF system and checking 0.8 first, so we don't redundantly give Flak Cannon twice (same with playing the sound)

Code: Select all

function DoLottery()
{
        local float Selection;

        if ( Guy == none || Guy.bDeleteMe ) //Player disconnected while in lottery
        {
                GotoState('');
                return;
        }

        selection = FRand();
        if (Selection >= 0.8)
        {
                GiveWeapon(Guy, "UnrealI.FlakCannon", true);
                GiveWeapon(Guy, "UnrealShare.Eightball", true);
                PlaySound (sound'RPG_Test.RPG_HaloReady');
        }
        else if (Selection >= 0.7)
        {
                GiveWeapon(Guy, "UnrealI.FlakCannon", true);
                PlaySound (sound'RPG_Test.RPG_HaloReady');
        }
        else
        {
                PlaySound (sound'RPG_Test.RPG_NoDamageHit');
                if ( ++FailCount > 2 )
                {
                        //Make player explode or something
                        FailCount = 0;
                }
        }
}
Nothing's calling this, it has no purpose watsoever, remove it.

Code: Select all

function ModifyPlayer (Pawn Other)
{
        GiveWeapon(Other, "UnrealI.FlakCannon", true);
}

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Sun Jan 11, 2015 8:08 pm
by ANUBITEK
EDIT:
So I compiled the new script with Higor's changes (here: http://pastebin.com/QHLEweiq) but something is wrong. When I start the game (the player spawns in the zone that the zoneinfo is in, here is a screenshot of zone portals for the level: http://i.imgur.com/7iBa48p.jpg) no sound is played, and I don't think I even receive rolls. I honestly can't tell because I do not hear the countdown noise. What could be causing this?

Code: Select all

event ActorEntered(Actor Other)
{
   if ( Other.IsA('PlayerPawn') && !IsInState('Lottery') ) // edit here, define PlayerPawn
   {
      Guy = PlayerPawn(Other);
      GotoState('Lottery');
   }
   Super.ActorEntered(Other); // Calls the function from this class' parent class, ZoneInfo
}
Also, how could I modify this script so the playerpawn is checked for weapons, and if they have weapons RPG_NoDamageHit plays and the lottery doesn't roll?

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Wed Nov 16, 2016 3:53 am
by ANUBITEK
Unfortunately I can't share 2 scripts through this site's file upload feature, but this actor was long finished. Even though this code was written for UGold, I believe that minor changes could allow it to be used for testing. I've left plenty of notes in the code to explain how some of it works:
RPG_LotterTrigger

Code: Select all

//=============================================================================
// RPG_LotteryTrigger.
//=============================================================================
class RPG_LotteryTrigger expands Triggers;

var RPG_LotteryTrigger LotteryTrigger;
var playerpawn PP; // The playerpawn that walks into the trigger.

#exec OBJ LOAD FILE="../Sounds/RPG_Test.uax" PACKAGE=RPG_Test
/*
//  exec import: Texture
    #exec TEXTURE IMPORT NAME=NameForTextureToImportAs FILE=PATH\TO\SomeTexture.pcx GROUP=SomeGroup MIPS=OFF FLAGS=2 PALETTE=SomeTexPalette LODSET=2
//  note no terminating ";". Presumably must be all on one line, too

//  exec import: Sound
    #exec AUDIO IMPORT NAME=NameForSoundToImportAs FILE=PATH\TO\Soundfile.wav GROUP=SomeGroup
*/
var int FailCount;
var int WinCount;
var() int FailLimit;
var() int WinLimit;
var() bool bPersistantFails;
var int CurTimer;
//=============================================================================
//var(Events) name Event; // Left here for informative purposes, works like a normal trigger
//=============================================================================
var() bool bTriggerOnceOnly;

event Touch( Actor Other)
// When an Actor intersects with this actor, this event begins
{
    if ( Other.IsA('PlayerPawn') && !IsInState('Lottery') ) 
//   Typecasts from Actor into PlayerPawn
    {
        if ( WinCount >= WinLimit )
        {
            GotoState('');
        }
        else
        {
        PP = PlayerPawn(Other); 
//       Defines PlayerPawn as PP
        GotoState('Lottery');
//       Changes the State from '', or default (none), to 'Lottery'
        SetCollision( false );
        }
    }
    else
    {
        GotoState('');
    }
    if ( bTriggerOnceOnly )
    {
        SetCollision( false );
    }
}
//=============================================================================
// > Code flow is executed after activated by GoToState('Lottery'),
// > If PP (PlayerPawn) = none, then the state ends.
// > A variable integer (var int) is assigned to CurTimer:
//  - The value will later be read by LotteryPanel, then displayed through
//     a single multi-skin for font.
// > The state begins by assigning 3 to CurTimer, playing a sound, then
//    the state sleeps for one second.  This occurs twice more, CurTimer is
//    assigned 0, function DoLottery() executes, the state sleeps for 1.5
//    seconds to maintain the countdown drawn by RPG_LotteryPanel.
// > The state then ends, though DoLottery() has executed before the end of the
//    state and NOT at the end of the state.
//=============================================================================
state Lottery
// A special code flow exectued during the Actor's native Tick.
{
        event EndState()
        // State-only script function, immediately called after this script's
        //  GoToState() call changes the actor into a different (or none) 
        //  state, executed before the next line of code; consider the current 
        //  state's EndState() as an extension of GoToState().
        // In this case, PP = none because he's either died, disconnected or 
        //  the lottery has finished.
        {
                PP = none; 
                // If PP = none, the state ends.
        }
Begin:
        CurTimer = 3;
        // This value is passed on to RPG_LotteryPanel.  
        //  Ex: ( LotteryTrigger.CurTimer > 1 )
        //  CurTimer is later changed into a String.
        PP.PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        // This sound is played from the player themselves.
        Sleep( 1 );
        // Latent function: can only be called within state code, not from
        //  within functions.
        //=====================================================================
        // > Sleep( float Seconds ): Pauses the state execution for a certain 
        //    amount of time, and then continues.
        // > FinishAnim(): Waits until the current animation sequence you're
        //    playing completes, and then continues.
        // > FinishInterpolation(): Waits for the current InterpolationPoint
        //    movement to complete, and then continues.
        // > Stop;
        // > WaitForLanding(); (pawn only)
        // > MoveToward, MoveTo, StrafeFacing, etc (pawn only)
        // > Goto: Operator, paired with a label name (ex: Goto Begin;).  100%
        //    safer than GotoState from within State.
        // You can customize flow control using While() loops paired with
        //  Sleep(0.0); calls.
        //=====================================================================
        CurTimer = 2;
        PP.PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        Sleep( 1 );
        CurTimer = 1;
        PP.PlaySound ( Sound'RPG_Test.RPG_HaloCount');
        Sleep( 1 );
        CurTimer = 0;
        DoLottery();
//       Executes function DoLottery().
      Sleep( 1.5 ); 
//     Added to preserve number 0 CurTimer for RPG_LotteryPanel.
      GotoState('');
//     Default is none.
}

//=============================================================================
// > Function is called from Lottery after timer has ended.
// > If "PP" (PlayerPawn) is deleted while in RPG_LotteryTrigger, state
//    returns to default.
// > If the PlayerPawn remains, a roll is executed with there being three
//    possible roll results.
//  - For each failure, a count is added toward FailCount.
//  - If the random roll result increments FailCount to be greater than or
//     equal to the number defined in the editor, an explosion sprite appears
//     and the player is killed.
//  - If the player succeeds or fails a roll, FailCount is reset to zero.
//
// > This is an example of playing sound through a local pawn after 
//    type the instigator playerpawn to a string (PP). 
/*
    PP.PlaySound (sound'RPG_Test.RPG_NoDamageHit');
*/
//  - Left for informative purposes.
//=============================================================================
function DoLottery()
{
        local float Selection;

        if ( PP == none || PP.bDeleteMe )
//       Player disconnected while in 'Lottery'.
        {
                GotoState('');
                SetCollision( true );
                return;
//              Note that the optional "return" keyword cannot be used in
//               state code.  "return" ends the function or operator, unless
//               the function is designated a value to return, where it
//               will immediately return a value.
        }
        selection = FRand();
        SetCollision( true );
//       Returns a random number from 0.0 to 1.0
        if (Selection >= 0.8)
        {
                GiveWeapon(PP, "UnrealI.FlakCannon", true);
                GiveWeapon(PP, "UnrealShare.Eightball", true);
//               QUESTION: How can this be changed so that rewards can be
//                          edited within the editor's Actor Advanced 
//                          Properties window?
                if ( bPersistantFails )
                {
                    ++WinCount;
                    return;
                }
                else
                {
                    ++WinCount;
                    FailCount = 0;
                    return;
                }
        }
        else if (Selection >= 0.7)
        {
                GiveWeapon(PP, "UnrealI.FlakCannon", true);
                if ( bPersistantFails )
                {
                    ++WinCount;
                    return;
                }
                else
                {
                    ++WinCount;
                    FailCount = 0;
                    return;
                }

        }
        else
        {
                PP.PlaySound (sound'RPG_Test.RPG_NoDamageHit');
                if ( ++FailCount >= FailLimit )
//              "++" increments the modified value of "FailCount" by 1.
                {
//                       Make player explode or something:
                        Spawn(class'SpriteBallExplosion',,,Location);
//                       local Projectile P;
//                       P = Spawn(ProjectileClass, Instigator,,, Instigator.ViewRotation);
                        PP.TakeDamage( 255,none,Location,vect(0,0,50), 'Exploded');
//                       function TakeDamage (int Damage, Pawn InstigatedBy, vector HitLocation, vector Momentum, name DamageType)
                        PP.Died( none, 'Exploded', Location);
//                       function Died (Pawn Killer, name DamageType, vector HitLocation)
                        FailCount = 0;
                        return;
                }
        }
}

function Weapon GiveWeapon(Pawn PlayerPawn, string aClassName, optional bool bBringUp)
{
    local class<Weapon> WeaponClass; // Defines any WeaponClass defined by 
                                     //  "function Weapon GiveWeapon()".
    local Weapon NewWeapon; // Is used to define initial settings for weapon 
                            //  that is created as a result of 
                            //  "function DoLottery()".
 
    WeaponClass = class<Weapon>(DynamicLoadObject(aClassName, class'Class'));
    // Defines the local class<Weapon>, next dynamically loading the
    //  string in line 157 (and others). DynamicLoadObject is a native 
    //  function declared in Object. It loads an object of a specified class.
    //  Which object of that class is specified as a string. The string is the
    //  name of the thing that you want to load. If that thing does not exist
    //  in memory, it will be loaded from the appropriate package file.

    if ( PlayerPawn.FindInventoryType(WeaponClass) != None )
        return None;
    // Checks the PlayerPawn's Inventory for the weapon defined as WeaponClass,
    //  and if found returns 
    newWeapon = Spawn(WeaponClass);
    if ( newWeapon != None ) {
        newWeapon.RespawnTime = 0.0;
        newWeapon.GiveTo(PlayerPawn);
        newWeapon.bHeldItem = true;
        newWeapon.GiveAmmo(PlayerPawn);
        newWeapon.SetSwitchPriority(PlayerPawn);
        newWeapon.WeaponSet(PlayerPawn);
        newWeapon.AmbientGlow = 0;
        if ( PlayerPawn.IsA('PlayerPawn') )
            newWeapon.SetHand(PlayerPawn(PlayerPawn).Handedness);
        else
            newWeapon.GotoState('Idle');
        if ( bBringUp ) {
            PlayerPawn.Weapon.GotoState('DownWeapon');
            PlayerPawn.PendingWeapon = None;
            PlayerPawn.Weapon = newWeapon;
            PlayerPawn.Weapon.BringUp();
        }
    }
    return newWeapon;
}

Re: WeaponLottery Zone Scripting: Newb Needs Help

Posted: Wed Nov 16, 2016 7:54 am
by PrinceOfFunky
Uh I didn't know about this project, i wanted make a similar thing for the UnrealRace game mode, which would have been a rotating cube and not a zone, like the ones on Super Mario Kart. If you would have picked it, a random weapon would have been given to the player who picked up the cube. But since I can't create mashes, I didn't do it.