UnrealSP.org, now with 100% more Web 2.0!

Compiled UnrealScript Guide

For questions and discussion about UnrealEd, UnrealScript, and other aspects of Unreal Engine design.

Moderators: Semfry, ividyon

User avatar LannFyre
Skaarj Scout Skaarj Scout
Posts: 31
Joined: 29 Dec 2014, 02:55

Subject: Compiled UnrealScript Guide

Post Posted: 20 Jul 2015, 08:49

I've begun taking information from the UnrealScript Bible (http://www.unrealsp.org/viewtopic.php?f=3&t=3613&sid=667461b249f09180c4b9d3f3b4913319) and compiling it into its own guide that can be viewed in any text editor (such as Notepad++). I've decided to make this it's own topic and plan to one day move it into the Development School section (with approval) once it is sufficiently compiled. I am making this its own topic so the UnrealScript Bible topic is only bumped with additional links or information I can find.

CHAPTER ONE: Introduction to OOP and UnrealScript

Code: Select all

//=============================================================================
/*
> [x.x] Preface
How to navigate:
   > Search [>>] or >> to find important teminology or highlighted notes covering specific
      concepts.
   > Search [x.x] or x.x, x = any number to move between chapters and sections.
   Credit goes to the Unreal and UT development team, and the community for providing the
      information going into this guide.
   Credit goes to everyone that has posted information on unrealwiki, especially the person or
      persons helping host this website.
   Credit goes to Higor, his help has made it so I understand (somewhat) what I am doing.
      Thx m8

> [1.0] Object Oriented Programming In A Nutshell: How You Can Into UnrealScript
First of all a program is a file (data) that changes other data. Your operating system
   (perhaps DOS) is a program.  An example of the data that it might change would be the
   data that the computer is sending to your monitor.  Your program might change that data from
   being no data sent to the monitor (resulting in blank screen) to data being sent to the
   monitor telling it to light up certain pixels on the screen in a pattern resembling letters that
   spell out "Hello World".  An image file is data but it is not a program.  While its data is a pattern
   of pixels to light up on the monitor, which will resemble a picture of something, that data
   alone changes nothing, therefore the image file is not a program.  A program would change
   the data sent to the monitor to be the data that the image file contains.  In an OOP program,
   subclasses of class objects change (override) data in their parent class and act as extensions
   of the program itself. This will become clearer as you read on.
   
Programs execute one line of code at a time in a linear fashion.  Starting from the first line of code
   the program will continue to the second line of code and then the third, unless one of those
   lines of code instruct the program to jump to another line and execute it.  If perhaps the fourth
   line of code instructs the program to execute the 27th line of code, the program will do so and
   then resume execution of its code from line five.  Line 27 of the program's code may be the
   beginning of a block of code that consists of 5 or 6 lines of code.  All 5 or 6 lines would be
   executed before the program returns to line 5 to continue from there.  One of those 5 or 6
   lines of code may instruct the program to jump back up to line 14.  The program will then
   execute line 14 and all lines that follow within the block that begins at line 14 and then
   return to the next line of the block that began at 27 and finish that block before returning
   to line 5.  Think of a picture of Mario or Luigi being printed by a printer, the printer printing
   each pixel of the individual character starting from the top of the picture, moving from left
   to right as the picture is printed from the top to the bottom.  As the printer reaches the end
   of a single layer of Mario or Luigi's pixels, the print head (how ink is applied) moves from
   the last point ink was applied to the newest point.  While a shakey analogy, this is similar
   to how programs are executed: one line of ink (or code) at a time, however the only
   difference is that sometimes our print head (or program) can move from one line to another
   through calls done in ink (code).
   
Rather than bounce around up and down a list of instructions, an Object Oriented Program will
   jump a lot of the time to code within a separate modular piece of the program.  This modular
   piece of the program, perhaps a class file, is compiled and embedded into the program and
   becomes kind of a file inside of a file.  An Exe file that appears to be one file that is the
   program may actually be made up of individual modules and compiled into one file.  Just as
   the program would jump to line 27 of its code, a line of code in an OOP program may call
   (tell the program to jump to) code within another module. That module is kind of like one
   of the blocks of code mentioned earlier.  Now when you look at the code you can see the
   core of the program in one module, and specialized sections of code contained in separate
   modules that might be extended even further other modules that hold even more specific
   code related to the module that they are extending.
   
Use your imagination. Depending on the type of program you are writing, you might imagine the
   modules representing different "real life" objects.  For example, if you are writing a business
   program you may imagine different modules being different departments within the
   same office, each having specific duties where all departments work on modulated aspects
   of the office's one project.  If you were writing a game some of the modules would be items
   and some would be players.  Still yet some other modules in a game would be physics of
   world the game takes place in and some would be smaller components of one module that
   is an item in the game (like a bullets for a gun or guns for a player).  If all of the code in the
   program was one long list of code to be executed in linear fashion it would be very hard to
   keep track of while you were writing it and almost impossible to fix or change the code later.
   That's how it used to be done, but we know better now.  Another reason for programs
   being OOP is that you can actually use these modules in other programs that you write and
   save a whole lot of time for yourself.
   
UnrealScript is a form of object oriented programming (OOP).  OOP is the concept of not just
   writing one massive piece of code, written to run everything, but instead several different
   pieces of code all working together discretely to form the greater whole.  This means that
   all code is not depending on large chunks of code, making it easier to read, translate, or
   debug for coders. Unreal and Unreal Tournament both use Unreal Engine 1, which uses
   UnrealScript (which uses C++ for it's low-level, performance-critical code) to allow for the
   interaction and modification of game objects.  Writing UnrealScript is not possible without
   writing classes and using objects.  Every player, vehicle, weapon, pickup, and light is an
   example of an object.  Even abstract things like the game rules and scoreboard are objects.
   Every object belongs to a Class, which describes what data and functions are applicable to
   that object.  For example, each player has an Enforcer.  These are all of the same class: every
   Enforcer has primary and secondary fire, and has a number of bullets.  The Enforcer, its ammo
   and and any projectile it may fire are all seperate Objects (for example, each Enforcer in a
   game is a seperate object class of a class).
   
   [>>] class - the 'blueprint' for objects.
   Defined on Terminology as: "abstraction that typically is assigned clearly specified
      characteristics; in other words, a chunk of data with a certain class associated to it; the
      class describes the data structure and contains the code that deals with objects of that class".
   
   [>>] object - an actual thing in the world.
   Defined on Terminology as: "type of an object, an object's class defines how an object is
      implemented; derived from or instantiated by an object, from which it inherits clearly defined
      attributes. A class can contain: static data members, objects of another class, pointers and
      references to types and objects of the same or another class, declarations of another class,
      member functions, and friend classes. All Classes are listed in the Actor browser".
   
   PROTIP: If you want a visual example of what is being described as "class objects", make a
      new map in either UnrealEd 2.0/1.  Subtract enough space that you can put a player on the map.
      Go into your actor browser and you will see the "Actor" tree, or a visual example
      of how a simple single-inheritance class graph works.  In this class graph, each class
      that is revealed as you open the sub menus is a "child class", meaning it is a class
      that inherets properties/functions/states from it's parent class.  Each of these classes
      are examples of how OOP is meant to function - inheritance of code from parent classes,
      as well as being easily attachable "modules" ("modules" being a hypothetical visual term).
      [>>] Here is Unreal Tournament's Class Tree hierarchy from Actor in all its beauty and
      glory. The Actor class inherits from Object (UT) (not seen here, but viewable in UnrealEd).
      While some subclasses exist purely to customise data rather than behaviour, this is generally
      frowned upon as most if not all duplicate functions can exist in one actor with multiple
      functions.  When it comes to creating classes, do not create classes if you can just modify
      properties of existing actors through their class objects in editor or game:
         Actor (UT)
         +- Brush
         |   +- Mover (UT)
         |       +- AssertMover
         |       +- AttachMover
         |       +- ElevatorMover
         |       +- GradualMover
         |       +- LoopMover
         |       +- MixMover
         |       +- RotatingMover
         |
         +- DamageType (UT) Not used
         |   +- UnrealDamageType
         |       +- Burned
         |       +- Corroded
         |       +- Decapitated
         |       +- Drowned
         |       +- Fell
         |
         +- Decal
         |   +- FadeShadow
         |   +- PlayerShadow
         |   +- Scorch
         |   |   +- BigEnergyImpact
         |   |   +- biomark
         |   |   +- BlastMark
         |   |   +- BloodSplat
         |   |   +- DirectionalBlast
         |   |   +- EnergyImpact
         |   |   |   +- BoltScorch
         |   |   +- ImpactHole
         |   |   +- NuclearMark
         |   |   +- Pock
         |   |   +- RipperMark
         |   |   +- UTBloodPool
         |   |   |   +- UTBloodPool2
         |   |   +- WallCrack
         |   |
         |   +- TargetShadow
         |
         +- Decoration (UT) How many classes!
         |   +- ut_Decoration
         |
         +- Effects (UT) >>
         |
         +- HUD (UT)
         |   +- ChallengeHUD
         |   |   +- ChallengeTeamHUD
         |   |       +- AssaultHUD
         |   |       +- ChallengeCTFHUD
         |   |       +- ChallengeDominationHUD
         |   |
         |   +- UnrealHUD Not expanded
         |
         +- Info (UT)
         |   +- AssaultInfo
         |   +- BotInfo
         |   +- ChallengeBotInfo
         |   +- ClientScriptedTexture
         |   |   +- ScrollingMessageTexture
         |   +- CodeMaster
         |   +- EndStats
         |   +- FontInfo
         |   +- GameInfo (UT)
         |   |   +- TournamentGameInfo
         |   |   |   +- DeathMatchPlus
         |   |   |   |   +- ChallengeDMP
         |   |   |   |   +- ChallengeIntro
         |   |   |   |   +- LastManStanding
         |   |   |   |   +- TDarkMatch
         |   |   |   |   +- TeamGamePlus
         |   |   |   |   |   +- Assault
         |   |   |   |   |   |   +- TrainingAS
         |   |   |   |   |   +- CTFGame (UT)
         |   |   |   |   |   |   +- TrainingCTF
         |   |   |   |   |   +- Domination
         |   |   |   |   |       +- TrainingDOM
         |   |   |   |   |
         |   |   |   |   +- TrainingDM
         |   |   |   |
         |   |   |   +- UTIntro
         |   |   |       +- LadderLoadGame
         |   |   |       +- LadderNewGame
         |   |   |       +- LadderTransition
         |   |   |       +- TrophyGame
         |   |   |
         |   |   +- UnrealGameInfo Not expanded
         |   |
         |   +- InternetInfo Not expanded
         |   +- Ladder (UT) Not expanded
         |   +- LocalMessage (UT)
         |   |   +- LocalMessagePlus
         |   |       +- CriticalEventPlus
         |   |       |   +- CriticalEventLowPlus
         |   |       |   |   +- ControlPointMessage
         |   |       |   |   +- KillingSpreeMessage
         |   |       |   |   +- LMSOutMessage
         |   |       |   |
         |   |       |   +- CriticalStringPlus
         |   |       |   +- CTFMessage
         |   |       |   +- DeathMatchMessage
         |   |       |   +- FirstBloodMessage
         |   |       |   +- TimeMessage
         |   |       |
         |   |       +- CTFMessage2
         |   |       +- DeathMessagePlus
         |   |       |   +- EradicatedDeathMessage
         |   |       +- DecapitationMessage
         |   |       +- ItemMessagePlus
         |   |       +- KillerMessagePlus
         |   |       +- MultiKillMessage
         |   |       +- PickupMessagePlus
         |   |       |   +- PickupMessageHealthPlus
         |   |       +- StringMesagePlus
         |   |       |   +- RedSayMessagePlus
         |   |       |   +- SayMessagePlus
         |   |       |   +- TeamSayMessagePlus
         |   |       |
         |   |       +- VictimMessage
         |   |
         |   +- MapList Not expanded
         |   +- MeshActor
         |   +- Mutator (UT)
         |   |   +- Arena
         |   |   |   +- FlakArena
         |   |   |   +- impactarena
         |   |   |   +- InstaGibDM
         |   |   |   +- MinigunArena
         |   |   |   +- PulseArena
         |   |   |   +- RocketArena
         |   |   |   +- ShockArena
         |   |   |   +- SniperArena
         |   |   |
         |   |   +- ChainsawMelee
         |   |   +- DMMutator
         |   |   +- FatBoy
         |   |   +- InstantRockets
         |   |   +- JumpMatch
         |   |   +- LowGrav
         |   |   +- NoPowerups
         |   |   +- NoRedeemer
         |   |   +- Relic
         |   |   |   +- RelicDeath
         |   |   |   +- RelicDefense
         |   |   |   +- RelicRedemption
         |   |   |   +- RelicRegen
         |   |   |   +- RelicSpeed
         |   |   |   +- RelicStrength
         |   |   |
         |   |   +- Stealth
         |   |
         |   +- NewGameInterimObject
         |   +- RatedMatchInfo Not expanded - no plans to at this time
         |   +- RatedTeamInfo Not expanded - no plans to at this time
         |   +- ReplicationInfo
         |   |   +- GameReplicationInfo
         |   |   |   +- TournamentGameReplicationInfo
         |   |   |       +- CTFReplicationInfo
         |   |   +- PlayerReplicationInfo
         |   |       +- BotReplicationInfo
         |   |
         |   +- SavedMove
         |   +- ScoreBoard
         |   |   +- TournamentScoreBoard
         |   |   |   +- LMSScoreBoard
         |   |   |   +- TeamScoreBoard
         |   |   |       +- AssaultScoreBoard
         |   |   |       +- DominationScoreBoard
         |   |   |       +- UnrealCTFScoreBoard
         |   |   |
         |   |   +- UnrealScoreBoard
         |   |       +- UnrealTeamScoreBoard
         |   +- SelectionDude Not expanded
         |   +- ServerInfo Not expanded
         |   |   +- ServerInfoTeam
         |   |       +- ServerInfoAS
         |   |       +- ServerInfoCTF
         |   |       +- ServerInfoDOM
         |   |
         |   +- StatLog Not expanded - no plans to at this time
         |   +- TeamInfo
         |   +- TestInfo Not expanded - no plans to at this time
         |   +- VoicePack Not expanded - no plans to at this time
         |   +- ZoneInfo (UT)
         |       +- CloudZone
         |       +- KillingField
         |       +- LavaZone
         |       +- LevelInfo (UT)
         |       +- NitrogenZone
         |       +- PressureZone
         |       +- SkyZoneInfo
         |       |   +- RockingSkyZoneInfo
         |       +- SlimeZone
         |       +- TarZone
         |       +- TeleporterZone
         |       +- ToggleZoneInfo
         |       +- VacuumZone
         |       +- WarpZoneInfo
         |       +- WaterZone
         |
         +- Inventory (UT)
         |   +- LadderInventory
         |   +- Pickup (UT)
         |   |   +- Ammo (UT)
         |   |   |   +- ASMDAmmo
         |   |   |   |   +- DefaultAmmo
         |   |   |   +- FlakBox
         |   |   |   |   +- FlakShellAmmo
         |   |   |   +- NullAmmo
         |   |   |   +- RazorAmmo
         |   |   |   +- RifleAmmo
         |   |   |   |   +- RifleRound
         |   |   |   +- RocketCan
         |   |   |   +- ShellBox
         |   |   |   |   +- Clip
         |   |   |   +- Shells
         |   |   |   +- Sludge
         |   |   |   +- StingerAmmo
         |   |   |   +- TournamentAmmo
         |   |   |       +- BioAmmo
         |   |   |       +- BladeHopper
         |   |   |       +- BulletBox
         |   |   |       |   +- RifleShell
         |   |   |       +- FlakAmmo
         |   |   |       +- Miniammo
         |   |   |       |   +- EClip
         |   |   |       +- PAmmo
         |   |   |       +- RocketPack
         |   |   |       +- ShockCore
         |   |   |       |   +- SuperShockCore
         |   |   |       +- WarHeadAmmo
         |   |   |
         |   |   +- Amplifier
         |   |   +- Armor
         |   |   +- Dampener
         |   |   +- Flare
         |   |   +- Flashlight
         |   |   |   +- SearchLight
         |   |   +- ForceField
         |   |   +- Health
         |   |   |   +- Bandages
         |   |   |   +- NaliFruit
         |   |   |   +- SuperHealth
         |   |   |
         |   |   +- Invisibility
         |   |   +- JumpBoots
         |   |   +- SCUBAGear
         |   |   +- Seeds
         |   |   +- Shieldbelt
         |   |   |   +- PowerShield
         |   |   +- Suits
         |   |   |   +- AsbestosSuit
         |   |   |   +- KevlarSuit
         |   |   |   +- ToxinSuit
         |   |   |
         |   |   +- TournamentHealth
         |   |   |   +- HealthPack
         |   |   |   +- HealthVial
         |   |   |   +- MedBox
         |   |   |
         |   |   +- TournamentPickup
         |   |   |   +- Armor2
         |   |   |   +- RelicInventory
         |   |   |   |   +- RelicDeathInventory
         |   |   |   |   +- RelicDefenseInventory
         |   |   |   |   +- RelicRedemptionInventory
         |   |   |   |   +- RelicRegenInventory
         |   |   |   |   +- RelicSpeedInventory
         |   |   |   |   +- RelicStrengthInventory
         |   |   |   |
         |   |   |   +- ThighPads
         |   |   |   +- UDamage
         |   |   |   +- UT_invisibility
         |   |   |   |   +- UT_Stealth
         |   |   |   +- UT_JumpBoots
         |   |   |   +- UT_ShieldBelt
         |   |   |
         |   |   +- Translator
         |   |   +- VoiceBox
         |   |   +- WeaponPowerup
         |   |
         |   +- TrapSpringer
         |   +- Weapon (UT)
         |      +- ASMD
         |      +- AutoMag
         |      +- DispersionPistol
         |      +- Eightball
         |      +- FlakCannon
         |      +- GESBioRifle
         |      +- Minigun
         |      +- QuadShot
         |      +- Razorjack
         |      +- Rifle
         |      +- Stinger
         |      +- TournamentWeapon
         |          +- Chainsaw
         |          +- Enforcer
         |          |   +- DoubleEnforcer
         |          +- ImpactHammer
         |          +- Minigun
         |          +- PulseGun
         |          +- ripper
         |          +- ShockRifle
         |          |   +- SuperShockRifle
         |          +- SniperRifle
         |          +- Translocator
         |          +- ut_biorifle
         |          +- UT_Eightball
         |          +- UT_FlakCannon
         |          +- WarheadLauncher
         |
         +- Keypoint (UT)
         |   +- AmbientSound (UT)
         |   +- BlockAll
         |   +- BlockMonsters
         |   +- BlockPlayer
         |   +- ClipMarker
         |   +- DynamicAmbientSound
         |   +- Earthquake
         |   |   +- CH_Earthquake
         |   +- GuardPoint
         |   +- HoldSpot
         |   +- InterpolationPoint
         |   +- LocationID
         |   +- MakeNaliFriendly
         |   +- ObjectPath
         |   +- OEMEnd
         |   +- PathPoint
         |   +- RockSlide
         |   |   +- MagmaBurst
         |   +- SpectatorCam
         |   |   +- QuakeCam
         |   +- ThingFactory
         |   |   +- CreatureFactory
         |   +- ThrowStuff
         |   +- TriggeredAmbientSound
         |   +- WayBeacon
         |
         +- Light (UT)
         |   +- ChargeLight
         |   +- DistanceLighting
         |   +- FlashLightBeam
         |   +- OverheadLight
         |   +- QueenTeleportLight
         |   +- SightLight
         |   +- SpotLight
         |   +- TorchFlame
         |   +- TriggerLight There are two identical TriggerLight actors in Engine and UnrealShare.
         |   +- TriggerLightRad
         |   +- WeaponLight
         |       +- EffectLight
         |       +- PurpleLight
         |
         +- Menu Not expanded - no plans to at this time
         |
         +- NavigationPoint (UT) >>
         |
         +- Pawn (UT)
         |   +- Bot (UT)
         |   |   +- HumanBotPlus
         |   |   |   +- FemaleBotPlus
         |   |   |   |   +- TFemaleBot1
         |   |   |   |   +- TFemaleBot2
         |   |   |   |
         |   |   |   +- MaleBotPlus
         |   |   |       +- TBossBot
         |   |   |       +- TMale1Bot
         |   |   |       +- TMale2Bot
         |   |   |
         |   |   +- SkaarjBot
         |   |
         |   +- Bots Not expanded
         |   +- FlockMasterPawn Not expanded
         |   +- FlockPawn Not expanded
         |   +- PlayerPawn Not expanded
         |   +- Scout Not expanded
         |   +- ScriptedPawn Not expanded
         |   +- StationaryPawn Not expanded
         |
         +- Projectile (UT) Not expanded
         +- ShareSounds
         +- SpawnNotify
         +- Triggers (UT)

There are many ways to think of classes and objects: you can imagine a class as a "recipe" or a
   "blueprint" for making things.  It defines properties that every object of this class will have
   (even if the values may differ), and functions (or methods) that every object of this class
   can perform.
   
A basic principle of object orientation (OO) is that two classes shouldn't be doing the same thing. 
   For instance, both the Enforcer and Bio Rifle in Unreal Tournament do very similar things -
   consume ammo, fire an instant shot, do damage to a target, etc.  There are so many
   similarities that much of the basic functionality can be done with the same lines of code. 
   Instead of duplicating this between the two classes, they share a parent class which handles
   most of the basics.  They then extend that class, assume all of it's properties and functions
   (unless said properties and/or functions have been overridden, but that will be described later)
   and then only add or edit what they need.  This has many advantages.  It makes it much
   easier to maintain the basic functions for all three classes, since they share code.

With the Unreal engine, the hardest thing new modders need to grasp is how object oriented it is.
   Unreal's OO design is what makes it possible to create a whole new game without having
   to actually touch any of the original code.  It's what allows for mutators to alter an entire
   game with only a few lines of code.  It makes the engine remarkably versatile to play with,
   but also somewhat easy to break.
   
The main problem most people have with OO is unxpected behavior.  Since you are usually not
   staring at all the relevant code at once, it can be easy to misjudge the end result.
   
Modding games in such a manner used to be left up to those with enough knowledge to know
   how to really hack into somebody else's binaries and change them all around.  In reality,
   game modification probably has a lot to owe to piracy and old school code demos as those
   were the early 8-bit hobbies of doing something with somebody else's technology.  Now,
   the developers of the game give you access to their code, tools to edit it and programs to
   recompile it.
*/
//=============================================================================
/*
> [1.1] Design Goals of UnrealScript
UnrealScript was created to provide the development team and the third-party Unreal developers
   with a powerful, built-in programming language that maps naturally onto the needs and
   nuances of game programming.

The major design goals of UnrealScript are:
[>>] To support the major concepts of time, state, properties, and networking which traditional
   programming languages don't address. This greatly simplifies UnrealScript code. The major
   complication in C/C++ based AI and game logic programming lies in dealing with events
   that take a certain amount of game time to complete, and with events which are dependent
   on aspects of the object's state. In C/C++, this results in spaghetti-code that is hard to write,
   comprehend, maintain, and debug. UnrealScript includes native support for time, state, and
   network replication which greatly simplify game programming.

[>>] To provide Java-style programming simplicity, object-orientation, and compile-time error
   checking. Much as Java brings a clean programming platform to Web programmers,
   UnrealScript provides an equally clean, simple, and robust programming language to 3D
   gaming. The major programming concepts which UnrealScript derives from Java are:
   > a pointerless environment with automatic garbage collection;
   > a simple single-inheritance class graph;
   > strong compile-time type checking;
   > a safe client-side execution "sandbox";
   > and the familiar look and feel of C/C++/Java code (such as upper/lower case insensitivity).
   
[>>] To enable rich, high level programming in terms of game objects and interactions rather
   than bits and pixels. Where design tradeoffs had to be made in UnrealScript, execution speed
   was sacrificed for development simplicity and power. After all, the low-level,
   performance-critical code in Unreal is written in C/C++ where the performance gain
   outweighs the added complexity. UnrealScript operates at a level above that, at the
   object and interaction level, rather than the bits and pixels level.
*/
//=============================================================================

//=============================================================================
/*
> [1.2] Example Program Structure

The following examples illustrate a typical, simple UnrealScript class, and highlights the syntax and
   features of UnrealScript. Pizza, a child class of Meal (Pizza.uc would be it's file name):
*/
//=============================================================================

//=============================================================================
// Pizza
//=============================================================================
class Pizza expands Trigger;

var int NumberOfParts;
var bool bHasCheese;

function postbeginplay();         /* This is inherited from Actor, Meal's parent class. */
{
   local Pizza MyPizza;         /* That's where I'm going to hold the pizza.  Like a dish. */

   MyPizza.Slice(8);            /* Cut into 8 parts */
   log("Slice executed, pizza slices:"@NumberOfParts);
}

function AddCheese()
{
   bHasCheese = true;
}
 
function EatCheese()
{
   bHasCheese = false;
}

function slice(pieces)
{
   NumerOfParts=pieces;
}

function EatParts(int number)
{
   local Pizza MyPizza;

   NumberOfParts -= number;
   if ( NumberOfParts <= 0 )
      Destroy();
}

event Touch( Actor Other)
{
    if ( Other.IsA('PlayerPawn') && !IsInState('EatPizza') )
    {
        Guy = PlayerPawn(Other);
        GotoState('EatPizza');
        SetCollision( false );
        }
    }
    else
    {
        GotoState('');
    }
}

state EatPizza
{
   local Pizza MyPizza;
    event EndState()
    {
      Guy = none;
    }
Begin:
        Guy.PlaySound ( Sound'Test.Munch');
        Sleep( 1 );
        Guy.PlaySound ( Sound'Test.Munch');
        Sleep( 1 );
        Guy.PlaySound ( Sound'Test.Munch');
        Sleep( 1 );
      MyPizza.EatParts( 8 );
      Sleep( 1.5 );
      GotoState('');
}

defaultproperties
{
NumberOfParts=1 // Semicolons AREN'T required for default
}
//=============================================================================
/*
> [1.3] UnrealScript Key Elements
The key elements to look at in this script are:

[>>] The class declaration:
Each class "extends" (derives from) one parent class, and each class belongs to a "package,"
   a collection of objects that are distributed together. All functions and variables belong to a
   class, and are only accessible through an actor that belongs to that class. There are no
   system-wide global functions or variables, just functions or variables inherited from parent
   classes.
Defined on Terminology as: "type of an object, an object's class defines how an object is
   implemented; derived from or instantiated by an object, from which it inherits clearly defined
   attributes. A class can contain: static data members, objects of another class, pointers and
   references to types and objects of the same or another class, declarations of another class,
   member functions, and friend classes. All Classes are listed in the Actor browser".
   
[>>] The variable declarations:
UnrealScript supports a very diverse set of variable types including most base C/Java types,
   object references, structs, and arrays. In addition, variables can be made into editable
   properties which designers can access in UnrealEd without any programming.
Defined on Terminology as: "memory location with a symbolic name where a program can
   store information for future retrieval".

[>>] The functions
Functions can take a list of parameters, and they optionally return a value with the "return" type
   ("return;").  Functions can have local variables. Some functions are called by the Unreal
   engine itself (such as BeginPlay), and some functions are called from other script code
   elsewhere (such as Trigger).  Basically, a section of code within an object that is
   declared (created and defined) and does nothing until it is called from somewhere else.
Defined on Terminology as: "piece of code with a defined entry point and one or more exit points".
   > That exit point may be reached upon completion of every line of code in the function or
      as the result of a test within that function that indicates in the event of a negative
      result the program should skip all the rest of the code in the function and exit.

[>>] The code
All of the standard C and Java keywords are supported, like for, while, break, switch, if, and so on.
   Braces and semicolons are used in UnrealScript as in C, C++, and Java.

[>>] Actor and object references
Here you see several cases where a function is called within another object, using an object
   reference.

[>>] The state keyword
This script defines several "states", which are groupings of functions, variables, and code which
   are executed only when the actor is in that state.

Note that all keywords, variable names, functions, and object names in UnrealScript are case-
   insensitive. To UnrealScript, "Demon", "demON", and "demon" are the same thing.
*/
//=============================================================================

//=============================================================================
/*
> [1.4] The Unreal Virtual Machine
The Unreal Virtual Machine consists of several components: the server, the client, the rendering
   engine, and the engine support code.  The Unreal server controls all gameplay and
   interaction between players and actors. In a single-player game, both the Unreal client and
   the Unreal server are run on the same machine; in an Internet game, there is a dedicated
   server running on one machine; all players connect to this machine and are clients.

All gameplay takes place inside a "level", a self-contained environment containing geometry and
   actors.  Though UnrealServer may be capable of running more than one level simultaneously,
   each level operates independently, and levels are shielded from each other: actors cannot
   travel between levels, and actors on one level cannot communicate with actors on another
   level.  Each actor in a map can either be under player control (there can be many players in
   a network game) or under script control.  When an actor is under script control, its script
   completely defines how the actor moves and interacts with other actors.

With all of those actors running around, scripts executing, and events occuring in the world,
   you're probably asking how one can understand the flow of execution in an
   UnrealScript.  The answer is as follows:

[>>] To manage time, Unreal divides each second of gameplay into "ticks." A tick is the smallest unit
   of time in which all actors in a level are updated.  A tick typically takes between 1/100th
   to 1/10th of a second.  The tick time is limited only by CPU power; the faster machine, the
   lower the tick duration.  Some commands in UnrealScript take zero ticks to execute
   (i.e. they execute without any game-time passing), and others take many ticks.  Functions
   which require game-time to pass are called "latent functions".  Some examples of latent
   functions include "Sleep", "FinishAnim", and "MoveTo."  Latent functions in UnrealScript
   may only be called from code within a state, not from code within a function.  While an actor is
   executing a latent function, that actor's state execution doesn't continue until the latent
   function completes.  However, other actors, or the VM, may call functions within the actor. 
   The net result is that all UnrealScript functions can be called at any time, even while
   latent functions are pending.  In traditional programming terms, UnrealScript acts as if each actor
   in a level has its own "thread" of execution.  Internally, Unreal does not use Windows threads,
   because that would be very inefficient (Windows 95 and Windows NT do not handle thousands
   of simultaneous threads efficiently).  Instead, UnrealScript simulates threads. This fact is
   transparent to UnrealScript code, but becomes very apparent when you write C++ code
   which interacts with UnrealScript.

All UnrealScripts execute in parallel.  If there are 100 monsters walking around in a level, all
   100 of those monsters' scripts are executing simultaneously and independently.

//=============================================================================
/*
> [1.5] Class Overview
Before beginning work with UnrealScript, it's important to understand the high-level relationships
   of objects within Unreal.  The architecture of Unreal is a major departure from that of most
   other games: Unreal is purely object-oriented (much like COM/ActiveX), in that it has a well-
   defined object model with support for high-level object oriented concepts such as the object
   graph, serialization, object lifetime, and polymorphism.  Historically, most games have been
   designed monolithically, with their major functionality hardcoded and unexpandable at the
   object level, though many games, such as Doom and Quake, have proven to be very
   expandable at the content level.  There is a major benefit to Unreal's form of object-
   orientation: major new functionality and object types can be added to Unreal at runtime, and
   this expansion can take the form of subclassing, rather than (for example) by modifying a
   bunch of existing code.  This form of extensibility is extremely powerful, as it encourages
   the Unreal community to create Unreal enhancements that all interoperate.

[>>] Class (expands Object) is a special kind of object which describes a class of object. 
   This may seem confusing at first: a class is an object, and a class describes certain objects. 
   But, the concept is sound, and there are many cases where you will deal with Class objects. 
   For example, when you spawn a new actor in UnrealScript, you can specify the new actor's
   class with a Class object.
   
[>>] Object is the parent class of all objects in Unreal.  All of the functions in the Object class are
   accessible everywhere, because everything derives from Object.  Object is an abstract base
   class, in that it doesn't do anything useful.  All functionality is provided by subclasses, such as
   Texture (a texture map), TextBuffer (a chunk of text), and Class (which describes the class
   of other objects).

[>>] Actor (extends Object) is the parent class of all standalone game objects in Unreal.  The Actor
   class contains all of the functionality needed for an actor to move around, interact with other
   actors, affect the environment, and do other useful game-related things.

[>>] Pawn (UT) (expands Actor) is the parent class of all creatures and players in Unreal which
   are capable of high-level AI and player controls.

With UnrealScript, you can write code for any Object class, but 99% of the time, you will be writing
   code for a class derived from Actor.  Most of the useful UnrealScript functionality is game-
   related and deals with actors.
*/
//=============================================================================

//=============================================================================
/*
> [1.6] The Class Declaration
Each script corresponds to exactly one class, and the script begins by declaring the class, the
   class's parent, and any additional information that is relevant to the class. 
   The simplest form is:
*/
//=============================================================================
class MyClass extends MyParentClass;
//=============================================================================
/*
Here I am declaring a new class named "MyClass", which inherets the functionality of
   "MyParentClass".  Additionally, the class resides in the package named "MyPackage".  Each
   class inherets all of the variables, functions, and states from its parent class.  It can then add
   new variable declarations, add new functions (or override the existing functions), add new
   states (or add functionality to the existing states).

The typical approach to class design in UnrealScript is to make a new class (for example a
   Minotaur monster) which expands an existing class that has most of the functionality you
   need (for example the Pawn class, the base class of all monsters).  With this approach, you
   never need to reinvent the wheel.  You can simply add the new functionality you want to
   customize, while keeping all of the existing functionality you don't need to customize. 
   This approach is especially powerful for implementing AI in Unreal, where the built-in AI
   system provides a tremendous amount of base functionality which you can use as building
   blocks for your custom creatures.

The class declaration can take several optional specifiers that affect the class:

[>>] native
   Says "this class uses behind-the-scenes C++ support".  Unreal expects native classes to
   contain a C++ implementation in the DLL corresponding to the class's package.  For example,
   if your package is named "Robots", Unreal looks in the "Robots.dll" for the C++
   implementation of the native class, which is generated by the C++ IMPLEMENT_CLASS macro.

[>>] abstract
   Declares the class as an "abstract base class".  This prevents the user from adding actors
   of this class to the world in UnrealEd, because the class isn't meaningful on its own.  For
   example, the "Pawn" base class is abstract, while the "Brute" subclass is not.  You can place
   a Brute in the world, but you can't place a Pawn in the world.

[>>] guid(a,b,c,d)
   Associates a globally unique identifier (a 128-bit number) with the class.  This Guid is currently
   unused, but will be relevant when native COM support is later added to Unreal.

[>>] transient
   Says "objects belonging to this class should never be saved on disk".  Only useful in
   conjunction with certain kinds of native classes which are non-persistent by nature,
   such as players or windows.

[>>] config(section_name)
   If there are any configurable variables in the class (declared with "config" or "globalconfig"),
   causes those variables to be stored in a particular configuration file:
   > config(system) – Uses the system configuration file, Unreal.ini for Unreal.
   > config(user) – Uses the user configuration file, currently User.ini.
   > config(whatever) – Uses the specified configuration file, for example "whatever.ini".

*/
//=============================================================================
Last edited by LannFyre on 21 Jul 2015, 03:19, edited 2 times in total.
way2goslugger

User avatar LannFyre
Skaarj Scout Skaarj Scout
Posts: 31
Joined: 29 Dec 2014, 02:55

Subject: Re: Compiled UnrealScript Guide

Post Posted: 20 Jul 2015, 09:22

CHAPTER TWO: Coding in UnrealScript and Operators

Code: Select all

//=============================================================================
/*
> [x.x] Preface
How to navigate:
   > Search [>>] or >> to find important teminology or highlighted notes covering specific
      concepts.
   > Search [x.x] or x.x, x = any number to move between chapters and sections.

> [2.0] UnrealScript Code Structure
If you've looked into Lesson 1 of this tutorial series, you'll have noticed in the previous code
   that the structure of code starts with the header of the class, moving into variables, then
   containing the rest of the code for the class.  After the header of a script is the variables,
   generally formatted like so:
*/
//=============================================================================

var int Count;    /* This would go under the header, after the class declarations.  These are used
               to declare variables within a code, which is a symbolic name given to an
               unknown quantity that permits the name to be used independent of the
               information it represents.  Variables are associated with data storage
               locations, and values of a variable are normally changed during the
               course of program execution.  Variables represent all kinds of data,
               including booleans, names, integers, arrays, pictures, sounds, scalars,
               strings, or any object or class of objects.  The symbolic names of
               variables are replaced with the actual data location by the compiler and
               interpreter.  Data in locations changes during execution while
               locations and names are fixed.

//=============================================================================
/*
You will typically find variables at the beginning of a script, but can find local variables within
   code blocks when a single function is dependant on using said local variable.

In UnrealScript, a code block consists of a function, event, or state header and any code that is
   contained within curly braces after the header, as well as any smaller block statements that are
   contained in said braces.  Here is the general function layout:
*/
//=============================================================================

[modifiers] function [returntype] functionname ( [parameter declarations] ) body_or_semicolon
{
/*   After the code block header, code is contained within a set of curly braces followed typically
      by an indentation, either via spaces or tab characters.  This is a code block, which
      includes everything after the function/event/state header until the very last curly brace
      that concludes said code block.  Many sets of curly braces can be seen within the code,
      which make up the conditions or "expressions" within the code that determine how the
      code is executed based on what specific conditions that are met.  Whenever a segment
      of your code is to either come to an end or the next statement is to be read, then a semi
      colon should ALWAYS follow the end of that code.*/
   if ( foo )
   {
      bar;
   }
//    All curly braces must have a partnered curly brace to end any code block(s) and/or
//      expression(s).
//   Curly braces are not always required in single block statements!
   else
      return;   
}

//    Here is the same code as above, but with comments removed for a better visual
//      representation.
[modifiers] function [returntype] functionname ( [parameter declarations] ) body_or_semicolon
{
   if ( foo )
   {
      bar;
   }
   else
      return;   
}

/*   Typically you will not have the same functions written in duplicate in the same class, as this
      can cause issues at compile time.  Instead, you would use code duplication methods
      like so: */
exec function butts( optional float f )
{
   local int lookanumber;

   if ( foo != true)
   {
      GotoState('fart');    // UnrealScript code is case insensitive.  GotoState() = gotostate()
   }
   else
   {
      GotoState('');
   }
}

exec function altbutts( optional float f )
{
   butts(); // All code in butts() is executed when altbutts() is executed.
}

//=============================================================================
/*
There are many different ways to write code blocks in UnrealScript, but I will only be covering the
   method Epic used when writing their code.  When it comes to writing code blocks and
   expressions, it is best to always write code for human reading first and computation second.
   If a fellow programmer cannot understand or comprehend what you have written, then it may
   be difficult for you yourself to debug your code as you either continue to write it or as you
   write additional code(s) and script(s).  That being said, keep in mind that when it comes to
   indentation for code, some coders may be using other software to code in and while your code
   may look great in your editor or even Unreal Editor, it may look terrible for anyone else
   dealing with your code in their editor.  This tutorial (any myself in general) will use tabs.
   
Sometimes a coder may wish to include comments into their scripts to either explain segments of
   code, or to pass questions to other coders within script.  In computer programming, a
   comment is a programmer-readable annotation in the source code of a computer program
   (or a script in our case).  Comments will be ignored by the compiler, so they can also be used to
   temporarily 'disable' a line of text.  To make a comment within code, there are two methods:
[>>] single line comments - initiated via //
//   ex: // My name is Tim.

[>>] multiple line comments - inititated via /*, ended via */
/*    ex: /* My daughter's name was Tim,
         but now it's Billy. */
//=============================================================================

//=============================================================================
/*
> [2.1] UnrealScript Operators: Turbo Nerd Edition
Other times a coder may need to include above plus sign or minus sign, modulo or something to
   compare statements to allow for if/then statements in their expressions.  These are just a few
   examples of what are known in OOP (and programming in general) as "Operators".

Operators (as defined by Wikipedia) are in essence constructs which behave generally like
   functions, but which differ syntactically or semantically from usual functions.  Common simple
   examples include arithmetic (addition with +, comparison with >) and logical operations (such
   as AND or &&).  More involved examples include assignment (usually =), or a field access in a
   object (usually .).  Languages usually define a set of built-in operators, and in some cases
   allow user-defined operators.  If any operator is available as either a prefix or postfix
   version, they basically have the same effect on any given variable. 
   The only difference is what they return:
[>>] preoperators - returns the variable's new value (after the operator's effect).

[>>] postoperators - returns the old value (the value before the operator did something).

There are three types of regular operators in UnrealScript, defined in the Object class:
[>>] infix operators (a + b):
   > [modifiers] operator(precedence) [returntype] operatorname ( left operand, right operand ) body_or_semicolon

[>>] prefix operators (-x):
   > [modifiers] preoperator [returntype] operatorname ( operand ) body_or_semicolon
   
[>>] postfix operators (i++):
   > [modifiers] postoperator [returntype] operatorname ( operand ) body_or_semicolon

Infix operators always have two operands, while prefix and postfix operators have exactly one
   operand.  In Unrealscript, operators are limited to having one or two parameters.
   UnrealScript's built-in operators are defined in the Object class.  All operator declarations
   must include the modifier final.  The operator name can either be a single symbol character
   (^, !, $, %, &, /, ?, *, +, ~, @, -, >, <, |), a symbol combination (!=, $=, /=, ==, @=, +=, *=, ~=,
   -=, ^^, &&, ++, **, --, <<, >>, >>>, ||) or a standard function name.  (examples in the engine are
   dot and cross)

Operators can be overloaded, that means multiple operators with the same name or symbol
   can be defined, as long as they differ in their operand types.  Overloading with identical
   operand types is not allowed as the engine would not be able to distinguish between the
   definitions.

The precedence of operators is used to group expressions, or controls how tightly an operator
   binds its operands.  A precedence value can only be specified for infix operators (pre/postfix
   operators bind as tightly as possible), with lower numbers binding more tightly.  For example,
   * has a precedence of 16, while + has 20.  That means * binds more tightly than +, so
   a * b + c * d is evaluated as (a * b) + (c * d).  It is possible to define different precedence
   values for overloaded operators.  For example the -= operator as combined subtract and
   assign for numeric values has a precedence of 34, while the -= operator for removing
   occurrences of a string in another string has a precedence of 45.  To make it short,
   all regular infix operators of the same precedence are left-associative and there's no way
   to change that.  a + b + c + d is always evaluated as ((a + b) + c) + d.  While this doesn't
   change the general evaluation order of the operands, it may have an impact on the type
   of operation and the result.

The following table lists the operator precedence for the default operators, the valid range
   for precedence values is 0-255.  Operators further up in the table bind more tightly.  Here's
   a list of the existing values used in the built in operators:

Preoperator      -         Negation
Pre-/Postoperator   ++         Increment
Pre-/Postoperator   --         Decrement
12             **          Exponentiation
16             *          Multiplication / Color Component Multiplication
16             /          Division
16             Dot          Dot Product
16             Cross       Cross Product
18             %          Modulus
20             +          Addition / Color Component Addition
20             -          Subtraction / Color Component Subtraction
22            <<          Left Shift (bit shifting, vector transformation)
22            >>          Right Shift (bit shifting, vector transformation)
22             >>>          Unsigned Right Shift (bit shifting, vector transformation)
24             <          Less Than
24             >          Greater Than
24             <=          Less or Equal
24             >=          Greater or Equal
24             ==          Equality
24             ~=          Approximate Equality
26             !=          Not Equal/Inequality
28             &         Bitwise AND
28             |          Bitwise Inclusive OR
28             ^         Bitwise Exclusive Or
28             {}         Code Block Curly Brace
30             &&          Logical AND
30             ^^          Logical Exclusive OR
32             ||          logical Inclusive OR
34             +=          Combined Addition Arithmetic Assignment
34             -=         Combined Subtraction Arithmetic Assignment
34             *=         Combined Multiplication Arithmetic Assignment
34             /=          Combined Division Arithmetic Assignment
40             @          String Concatenation (two strings combined /w space in
                        between)
40             $         String Concatenation (two strings combined /w no space)
44             @=          Combined Concatenation and Assignment (two strings
                        combined /w space, result assigned to first variable and
                        returned)
44             $=          Combined Concatenation and Assignment (two strings
                        combined /w no space, result assigned to first variable
                        and returned)
45             -=          Substring Removal (remove occurances of second string from
                        first string)
-             =          Assignment

And here is the structure of operators within Object:
//=============================================================================
Boolean Operators:
[>>] !bool
native(129) static final preoperator bool ! (bool A)

[>>] bool == bool
{{{1}}}

[>>] bool != bool
{{{1}}}

[>>] bool && bool
native(130) static final operator(30) bool && (bool A, skip bool B)

[>>] bool ^^ bool
native(131) static final operator(30) bool ^^ (bool A, bool B)

[>>] bool || bool
native(132) static final operator(32) bool
//=============================================================================

//=============================================================================
Byte Operators:
[>>] ++byte
native(137) static final preoperator byte ++ (out byte A)

[>>] byte++
native(139) static final postoperator byte ++ (out byte A)

[>>] --byte
native(138) static final preoperator byte -- (out byte A)

[>>] byte--
native(140) static final postoperator byte -- (out byte A)

[>>] byte *= byte
{{{1}}}

[>>] byte += byte
{{{1}}}

[>>] byte -= byte
{{{1}}}

[>>] byte /= byte
{{{1}}}
//=============================================================================

//=============================================================================
Int Operators:
[>>] ++int
native(163) static final preoperator int ++ (out int A)

[>>] int++
native(165) static final postoperator int ++ (out int A)

[>>] --int
native(164) static final preoperator int -- (out int A)

[>>] int--
native(166) static final postoperator int -- (out int A)

[>>] -int
native(143) static final preoperator int - (int A)

[>>] ~int
native(141) static final preoperator int ~ (int A)

[>>] int * int
native(144) static final operator(16) int * (int A, int B)

[>>] int *= float
{{{1}}}

[>>] int / int
native(145) static final operator(16) int / (int A, int B)

[>>] int /= float
{{{1}}}

[>>] int + int
native(146) static final operator(20) int + (int A, int B)

[>>] int += int
{{{1}}}

[>>] int - int
native(147) static final operator(20) int - (int A, int B)

[>>] int -= int
{{{1}}}

[>>] int & int
native(156) static final operator(28) int & (int A, int B)

[>>] int ^ int
native(157) static final operator(28) int ^ (int A, int B)

[>>] int | int
native(158) static final operator(28) int

[>>] int > int
native(151) static final operator(24) bool > (int A, int B)

[>>] int < int
native(150) static final operator(24) bool < (int A, int B)

[>>] int >= int
{{{1}}}

[>>] int <= int
{{{1}}}

[>>] int == int
{{{1}}}

[>>] int != int
{{{1}}}

[>>] int << int
native(148) static final operator(22) int << (int A, int B)

[>>] int >> int
native(149) static final operator(22) int >> (int A, int B)

[>>] int >>> int
native(196) static final operator(22) int >>> (int A, int B)
//=============================================================================

//=============================================================================
Float Operators:
[>>] -float
native(169) static final preoperator float - (float A)

[>>] float ** float
native(170) static final operator(12) float ** (float A, float B)

[>>] float * float
native(171) static final operator(16) float * (float A, float B)

[>>] float *= float
{{{1}}}

[>>] float / float
native(172) static final operator(16) float / (float A, float B)

[>>] float /= float
{{{1}}}

[>>] float + float
native(174) static final operator(20) float + (float A, float B)

[>>] float += float
{{{1}}}

[>>] float - float
native(175) static final operator(20) float - (float A, float B)

[>>] float -= float
{{{1}}}

[>>] float % float
native(173) static final operator(18) float % (float A, float B)

[>>] float > float
native(177) static final operator(24) bool > (float A, float B)

[>>] float < float
native(176) static final operator(24) bool < (float A, float B)

[>>] float >= float
{{{1}}}

[>>] float <= float
{{{1}}}

[>>] float == float
{{{1}}}

[>>] float != float
{{{1}}}

[>>] float ~= float
{{{1}}}

[>>] float * vector
native(213) static final operator(16) Vector * (float A, Vector B)

[>>] float * rotator
native(288) static final operator(16) Rotator * (float A, Rotator B)
//=============================================================================

//=============================================================================
String Operators:

[>>] string > string
native(116) static final operator(24) bool > (string A, string B)

[>>] string < string
native(115) static final operator(24) bool < (string A, string B)

[>>] string >= string
{{{1}}}

[>>] string <= string
{{{1}}}

[>>] string == string
{{{1}}}

[>>] string != string
{{{1}}}

[>>] string ~= string
{{{1}}}

[>>] string $ string
native(112) static final operator(40) string $ (coerce string A, coerce string B)

[>>] string @ string
native(168) static final operator(40) string @ (coerce string A, coerce string B)
//=============================================================================

//=============================================================================
Name Operators:
[>>] name == name
{{{1}}}

[>>] name != name
{{{1}}}
//=============================================================================

//=============================================================================
Object Operators:
[>>] Object == Object
{{{1}}}

[>>] Object != Object
{{{1}}}
//=============================================================================

//=============================================================================
Vector Operators:
[>>] -vector
native(211) static final preoperator Vector - (Vector A)

[>>] vector * float
native(212) static final operator(16) Vector * (Vector A, float B)

[>>] vector / float
native(214) static final operator(16) Vector / (Vector A, float B)

[>>] vector /= float
{{{1}}}

[>>]vector * vector
native(296) static final operator(16) Vector * (Vector A, Vector B)

[>>] vector *= vector
{{{1}}}

[>>] vector *= float
{{{1}}}

[>>] vector + vector
native(215) static final operator(20) Vector + (Vector A, Vector B)

[>>] vector += vector
{{{1}}}

[>>] vector - vector
native(216) static final operator(20) Vector - (Vector A, Vector B)

[>>] vector -= vector
{{{1}}}

[>>] vector == vector
{{{1}}}

[>>] vector != vector
{{{1}}}

[>>] vector Cross vector
native(220) static final operator(16) Vector Cross (Vector A, Vector B)

[>>] vector Dot vector
native(219) static final operator(16) float Dot (Vector A, Vector B)

[>>] vector << rotator
native(275) static final operator(22) Vector << (Vector A, Rotator B)

[>>] vector >> rotator
native(276) static final operator(22) Vector >> (Vector A, Rotator B)
//=============================================================================

//=============================================================================
Rotator Operators:
[>>] rotator * float
native(287) static final operator(16) Rotator * (Rotator A, float B)

[>>] rotator *= float
{{{1}}}

[>>] rotator / float
native(289) static final operator(16) Rotator / (Rotator A, float B)

[>>] rotator /= float
{{{1}}}

[>>] rotator + rotator
native(316) static final operator(20) Rotator + (Rotator A, Rotator B)

[>>] rotator += rotator
{{{1}}}

[>>] rotator - rotator
native(317) static final operator(20) Rotator - (Rotator A, Rotator B)

[>>] rotator -= rotator
{{{1}}}

[>>] rotator == rotator
{{{1}}}

[>>] rotator != rotator
{{{1}}}
//=============================================================================
*/
//=============================================================================

//=============================================================================
/*
> [2.2] Operator Precedence Example

Supplemental to the previous seciont, the following examples illustrate how precedence works in
   terms of operators:
*/
//=============================================================================

local int a,b,c,d,e;
 
a=2; b=3; c=4; d=2; e=5;
 
               // log output:
log(a@b@c@d@e);      // 2 3 4 2 5
log(a*b+++c**d*e);      // 88.000000
log(a@b@c@d@e);      // 2 4 4 2 5

/* The following is how the second segment is actually broken down via UnrealScript's own
   method of evaluation. */

(a * (b++)) + ((c ** d) * e)
/*
(2 * (3++)) + ((4 ** 2) * 5) // Focus on where the "++" is at for "3"
// > (2 * (3)) + ((16) * 5) // "++" was a post operator in this equation, so 3 is not incremented yet
// > (6) + (80)
// > 86

//=============================================================================
/*
> [2.3]  Boolean Operators: ARE YOU A LIAR OR NOT
[>>] iff (if and only if)
   > The word "iff" means "if and only if," implying that if the given condition isn't met, the
   operation will yield a different (the opposite) result.  (This is maths and logic jargon, not an
   UnrealScript operator.)
   
[>>] short-curcuit
   > Some binary boolean operators only evaluate their right operand if the result of the entire
   expression isn't already defined by the result of the first operand.  In this case, the right
   operand is skipped, which is a particularly handy feature if evaluation of that right operand has
   non-trivial side effects (like a function call) or relies on the left operand's result.
*/
//=============================================================================

/* Here's an example of short-circuiting via an Inclusive Or operator.  In the case of Inclusive Or
   operators, an expression is true and it's code block executes if either operand or both are
   evaluated.  In this case, the second operand can be skipped entirely or "short-curcuited" if
   just the first operand is evaluated. */

if (bAlreadyConfirmed || ShowMessageBox("Are you sure?"))

/* The second example uses an And operator, which executes its code block only if both
   conditions are met -- this prevents "Accessed None"s. */

if (ThisPawn != None && ThisPawn.bIsPlayer) ... // prevent "Accessed None"s

//=============================================================================
/*
Operation:      Operator:      Precedence:   Description:         Short-circuit:

Negation         !         Unary      Negates a boolean
                              expression.

And            &&         30         True iff both operands   First operand false =
                              are true.            expression false.

Exclusive Or      ^^         30         True iff one of the
                              operands is true (but
                              not both).

Inclusive Or      |         32         True iff one or both of   First operand true =
                              the operands are true.   expression true.
*/
//=============================================================================

//=============================================================================
/*
> [2.4] Comparison Operators: some 'nanners are more equal than others.
Comparison operators apply to values of all types.  Only compatible types can be compared
   (numbers with numbers, strings with strings and so on).  Object (classes, actors, textures,
   etc.) and Name properties can only be compared using Equal or Unequal.

Operation:          Operator :   Precedence:       Remarks:
Equal             ==          24    
Approximately Equal    ~=          24             Equality within 0.0001 (numbers)
                                    Case-insensitve equality (strings)
Less             <          24    
Less or Equal          <=          24    
Greater             >          24    
Greater or Equal       >=          24    
Not Equal          !=          26
*/
//=============================================================================

//=============================================================================
/*
> [2.5] Numeric Operators: effin'. . .  Math.
Numeric operators apply to values of type int, float and byte.

Operation:       Operator:    Precedence:    Description:
Negation          -          Preoperator       Returns the negative value of the operand
Increment       ++          Pre-/Postoperator    Increments the variable operand by 1
Decrement       --          Pre-/Postoperator    Decrements the variable operand by 1
Exponentiation   **          12             Puts the first operand to the power of the
                                 second operand
Multiplication       *          16             Multiplies both operands
Division          /          16             Divides the first operand by the second
                                 operand
Modulo          %          18             Divides the first operand by the second
                                 and returns the remainder
Addition          +          20             Adds both operands
Subtraction       -          20             Subtracts the second operand from the
                                 first operand

The modulo operator follows the computer science definition of modulus rather than the
   mathematical one: the modulo operation finds the remainder after division of one number
   by another.
   ex: -8 % 10 = -8 (and not 2)
   ex: 11 % 3 = 2
   
This results from differing interpretations of whether % should be a "modulo" or "remainder"
   operator (which is not the same thing), as well as differing results of what the integer division
   operation returns for negative numbers in different programming languages.  UnrealScript's
   definition is consistent with what (most) C/C++ does, which is probably appropriate
   considering that the language is similar in many other ways.

The assignment operator = can be combined with +, -, * and /.  These combined operators +=, -=,
   *= and /= assign the result of the operation to the first operand (which must be a variable). 
   These combined assignment operators also return the new value of the variable, so:
*/
//=============================================================================
   b += c;      // equivalent to  b = b + c;
   a = b += c;  // equivalent to  b = b + c;  a = b;  or  a = (b = b + c);
//=============================================================================
/*
   will add b and c and assign the result to a and b.
*/
//=============================================================================

//=============================================================================
/*
> [2.6] Bitwise Operators: Clever Title Edition
Bits are what bytes are formed with, a byte has 8 bits. A bit is nothing more than a 0 or 1.

Bit operations in any programming language are operations on each individual bit or in a set of
   specific bits rather than the byte as a whole, such as setting one or more of the bits of a
   byte to 0 or 1, or shifting the entire bit array to the left or the right (adding a 0 to one side or
   the other).  And who says a byte also says a word (16 bits), dword (32bits) or a qword (64bits),
   commonly known as 16bit, 32bit and 64bit integers respectively.

Operation:          Operator:    Precedence:    Description
Inversion          ~          Preoperator    Performs a bitwise inversion of the
                                 operand
Shift Left             <<          22          Shifts the bits of the first operand to the
                                 left
Shift Right (Arithmetic)    >>          22          Shifts the bits of the first operand right,
                                 maintaining its signum
Shift Right          >>>          22          Shifts the bits of the first operand right,
                                 filling with zeroes
And                &          28          Bitwise and
Or                |          28          Bitwise or
Exclusive Or          ^          28          Bitwise exclusive or

For the shift operators, only the 5 least significant bits of the second operand are used.
   What does that mean? Well, it's a neat feature that allows you to specify, how many bits you
   want to stay instead of how many you want to get rid of:
*/
//=============================================================================

// IntToHex() is a custom function that converts an integer into its hexadecimal string
//   representation
 
// -12 = 0xfffffff4 -> five least significant bits: 0xfffffff4 & 0x0000001f = 0x00000014 = 20
// 12 bits = 3 hex digits; 20 bits = 5 hex digits
 
// shift positive ints                 log output
log(IntToHex(0x02468ace <<   12));  //  68ace000
log(IntToHex(0x02468ace <<  -12));  //  ace00000 = same as 0x02468ace <<  20
log(IntToHex(0x02468ace >>   12));  //  00002468
log(IntToHex(0x02468ace >>  -12));  //  00000024 = same as 0x02468ace >>  20
log(IntToHex(0x02468ace >>>  12));  //  00002468
log(IntToHex(0x02468ace >>> -12));  //  00000024 = same as 0x02468ace >>> 20
 
// shift negative ints (to prove there's no difference from the usual behavior)
log(IntToHex(0xfdb97531 <<   12));  //  97531000
log(IntToHex(0xfdb97531 <<  -12));  //  53100000 = same as 0xfdb97531 <<  20
log(IntToHex(0xfdb97531 >>   12));  //  ffffdb97
log(IntToHex(0xfdb97531 >>  -12));  //  ffffffdb = same as 0xfdb97531 >>  20
log(IntToHex(0xfdb97531 >>>  12));  //  000fdb97
log(IntToHex(0xfdb97531 >>> -12));  //  00000fdb = same as 0xfdb97531 >>> 20

//=============================================================================
/*
> [2.7] Vector Operators
Operation:          Operator:    Precedence:             Description:
Reverse             -          Preoperator    Returns the negative value of the operand
Multiply components    *          16          Multiplies the corresponding components
                                 of both vectors
Multiply by scalar       *          16          (vector * float or float * vector)
Divide by scalar       /          16          (vector / float)
Dot product          Dot          16          Calculates the dot product (inner product)
                                 of the vectors
Cross product          Cross       16          Calculates the cross product (outer
                                 product) of the vectors
Addition             +          20          Adds both vectors
Subtraction          -          20          Reverses the second vector and adds
                                 it to the first one

Here the assignment operator = can also be combined with +, -, * and /.  All combined assignment
   operators have a precedence of 34, so be careful when combining them with the string
   operators $ and @ since those have a precedence of 40.
*/
//=============================================================================

//=============================================================================
/*
> [2.8] Rotator Operators
Operation:             Operator:    Precedence:    Description:
Multiplication             *          16          Multiplies all components of the
                                    rotator
Division                /          16          Divides all components
Addition                +          20          Adds the rotations
Subtraction             -          20          Reverses the second rotator and
                                    adds it to the first one
Rotate vector (reversed)    <<          22          Rotates the vector in the way
                                    described by the rotator
Rotate vector             >>          22          Rotates the vector in the way
                                    described by the rotator, but in
                                    reversed direction
                                    
Again, the assignment operator = can be combined with +, -, * and /.

Note that rotators can't be inverted with the - preoperator.  You will have to use -1 * theRotator-
   for this operation.

The effect of the rotator/vector operators << and >> can be explained using the result of the
   global functions GetAxes() and GetUnAxes() function:   
*/
//=============================================================================

static final operator(22) vector << (vector A, rotator B)
{
  local vector X, Y, Z;
  GetAxes(B, X, Y, Z);
  return X * A.X + Y * A.Y + Z * A.Z;
}
 
static final operator(22) vector >> (vector A, rotator B)
{
  local vector X, Y, Z;
  GetUnAxes(B, X, Y, Z);
  return X * A.X + Y * A.Y + Z * A.Z;
}

//=============================================================================
/*
The << operator performs exactly the calculations required to position a player's weapon in
   first person view based on a constant view offset vector and the player's view rotation.
*/
//=============================================================================

//=============================================================================
/*
> [2.9] String Operators
Operation:                Operator:    Precedence:   Description:
String Concatenation          @          40          The two strings are put together
                                       with a space in between.
String Concatenation          $          40          The two strings are put together
                                       without any space in between.
String Concatenation and Assign    @=          44          The two strings are put together
                                       with a space in between and the
                                       result is assigned to the first
                                       variable and returned.
String Concatenation and Assign    $=          44          The two strings are put together
                                       without any space in between and
                                       the result is assigned to the first
                                       variable and returned.
Remove ocurances and Assign    -=          45          Removes all occurances of the
                                       second string from the first string.

Aside from the string operators, there are other things that you can do with strings that have
   been implemented as Global Functions.
*/
//=============================================================================

//=============================================================================
/*
> [2.10] Color Operators
Color operators are only available in subclasses of Actor in UnrealEngine 1 and 2.

Operation :      Operator:      Precedence:    Description:
Multiplication       *          16          Multiplies all components of the color by a float
Addition          +          20          Adds the colors
Subtraction       -          20          Subtracts the colors (what happens if the RH
                              component is bigger than the LH?)

There are no combined assignment operators for colors.
*/
//=============================================================================
Last edited by LannFyre on 10 Aug 2015, 22:21, edited 3 times in total.
way2goslugger

User avatar LannFyre
Skaarj Scout Skaarj Scout
Posts: 31
Joined: 29 Dec 2014, 02:55

Subject: Re: Compiled UnrealScript Guide

Post Posted: 10 Aug 2015, 22:28

So I'm bumping this topic again as I've begun making progress on chapter three. I apologize for the hiatus, long story short I was without a decent computer for a short while.

I have a question for everyone on this next chapter: so I'm boiling down all of the information for what was planned to be three separate chapters into one, because most of the information was duplicate information just spread out. Does anyone think that this is a good format to go with for this chapter? Here is what I have so far, covering integers (decimal, hexadecimal, octal), floating point (decimal and scientific notation), booleans, and strings. I've included the data type information and technical information for each of these in this chapter, but I'm wondering if that was the right thing to do. If anyone has any feedback, please feel free to post it or just PM me. I can also be reached at [email protected]

CHAPTER THREE: Literals, Data Types, and Variables

Code: Select all

//=============================================================================
/*
> [x.x] Preface
How to navigate:
   > Search [>>] or >> to find important teminology or highlighted notes covering specific
      concepts.
   > Search [x.x] or x.x, x = any number to move between chapters and sections.
   
   > CHAPTER EXCLUSIVE: In "Technical information" sections, there are sections that denote
      the format of a literal.  An example would be that of int:
         literal = nnn
      In these sections, the letter "n" is being used in place of regular numbers, for
      ambiguity in description.  The literals do not actually consist of "nnn" or otherwise
      unless otherwise stated.

> [3.0] Literals Introduction: Literally Describing Things
Literals in general are notations that represent a value, which can be anything from certain
   numbers, true or false values, strings of text, and a host of other contextual notations.
   Programming languages in general contain these types of notations and UnrealScript is
   no different.  UnrealScript has various built-in data types, which contain the data that
   literals are comprised of.  UnrealScript types can be divided in three general groups:
   primitive types, reference types and composite types. 
   
[>>] Primitive types:
A primitive type only consists of a single and usually simple value.  Variables declared
   of a primitive type directly contain that value and when assigning that value to
   another variable or passing it to a function call, a new copy of the value is created. 
   Modifications to that copy have absolutely no effect on the original value still
   stored in the source variable.
   
[>>] Reference types:
Unlike variables of primitive types, variables declared as a reference type only contain a
   reference to the actual data.  When assigning a reference type value to a variable
   or passing it to function calls, only the reference, not the referenced data, is copied. 
   As a result it is possible that two reference type variables point to the same data and
   changes made to the data through one variable are immediately visible through the other.

[>>] Composite types:
Unlike all the other types described above, a composite type can contain more than one
   value.  The composite types available in UnrealScript all work similar to primitive types:
   assigning them to other variables or passing them in function calls creates a copy
   of the data.

In the following sections, each literal will be defined not only by what they represent, but their
   technical type information as well.
*/
//=============================================================================

//=============================================================================
/*
> [3.1] Number Literals
In UnrealScript, all numeric literals start with a digit.  Numeric literals can either stand for an
   integer or a floating point value and may be prefixed with a minus sign.
   
The compiler recognizes any "glob" consisting of digits, the letters A to F, the letter X and the
   decimal dot as a number, as long as it starts with a digit.  If it contains an X then it's treated
   as hexadecimal integer literal, if it contains a dot it's treated as floating point literal,
   otherwise it's a decimal integer literal.
   
[>>] Integer Number Literals (PRIMITIVE)
UnrealScript has two integer types, "byte" and "int", "int" the larger of them.  Int values are
   integer numbers in the range -2147483648 to 2147483647, in other words signed 32
   bit values.  The UnrealScript compiler knows two types of integer literals:
   decimal and hexadecimal.  Decimal literals only consist of the decimal digits 0 to 9,
   while hexadecimal literals start with 0x, directly followed by the hexadecimal digits
   0 to 9 and A to F.  Upper- and lowercase letters can be mixed freely in hexadecimal
   literals.  Values exceeding the allowed range are truncated to the least significant 32
   bits.  For example the hexadecimal literal 0x100000005 actually represents the value 5. 
   The loose interpretation of "globs" of digits, A to F, and X allows for an aditional
   interger literal: octal integer literals.  An octal integer literal starts with 0, followed by
   any combination of the octal digits 0 to 7.  It also needs to include the letter X, otherwise
   it will be treated as decimal integer literal.
   
The smaller of UnrealScript's two integer types is "byte".  Byte values are integer numbers in
   the range 0 to 255, in other words unsigned 8 bit values.  Any int literal can also be
   used in "byte context".  If the value is outside the allowed range it will be truncated
   to the 8 least significant bits.  For example the hexadecimal literal 0x100 (256)
   actually represents the value 0 and the decimal literal -1 represents the value 255.

Examples:
   123         // Decimal Integer Number Literal
   0xC0FFEE   // NOT a Hexadecimal Integer Number Literal
   010         // Decimal Integer Number Literal
   0123456789ax   // NOT a Octal Integer Number Literal
   123456789ax    // NOT a Octal Integer Number Literal

The first example is a typical decimal literal that can represent a byte or int value, while
   the second example is a hexadecimal literal that exceeds the byte range and definitely
   stands for a value of type int.  The third example is not octal, but just a decimal literal
   with a leading zero representing the value ten.  The fourth example is interpreted
   as the value 1234567oct, which is the same as 342391dec.  The character 8 is no valid
   octal digit and thus terminates the value.  The compiler takes the entire number glob,
   sees the X in it and passes it to the generic number parser.  That one sees the
   leading zero, not followed by an X and treats the literal as octal. The fifth example
   contains an X, but does not start with a 0, so it is actually treated as decimal literal
   and stands for the value 123456789dec.  It contains the letter A, but it doesn't start
   with 0x, so it's not a hexadecimal literal and the number parser stops when it
   arrives at the A.

Technical information:
   [>>] int
      Size: 32-bit
      Number range: -2147483648 to 2147483647
      Initial value: 0
      Literal = nnn
   [>>] byte
      Size: 8-bit (1 byte)
      Numbers range: 0 to 255
         > Assigning a number that exceeds this range will wrap it at the boundaries!
         > Setting a byte variable to 256 will actually set it to 0!
      Initial value: 0
      Literal = 0xnnn
   
[>>] Float Number Literals (PRIMITIVE)
UnrealScript has a single precision floating point type called float.  The possible float values are
   distributed over the huge range of about 3.403·1038 to -3.403·1038.  The smallest possible
   value greater than 0 is about 1.175·10-38.  Generally, float values have a precision of
   about 6 or 7 decimal digits.

Floating point literals always start with one or more digits, followed by a decimal dot.  After
   the dot, there may be zero or more decimal digits.  Note that you can't use the comma
   as decimal separator, even if that's the standard way to display decimal fractions
   on your system.

Float literals can either be specified in decimal or scientific notation.  For example the
   literal 1.2e3 (where either e or d are interchangable, representing exponentation) means
   1.2·103 = 1200.  Note that float literals must always contain the decimal point, even when
   using scientific notation, and must always start with a number or with the minus sign
   followed by a number.  Unfortunately, negative exponents are not allowed in scientific
   notation.  A hexadecimal representation like in Java is not supported.

If a floating point operation has a result that exceeds the highest or lowest possible number,
   the return value has the special value of positive or negative infinity respectively.  Invalid
   operations such as division by zero or adding positive and negative infinity return the
   special value NaN, "Not a Number".  Be careful about those three special values as they will
   propagate.  That means, if you subtract, add, multiply or divide infinity values, the result will
   be infinity again.  If you perform an operation with the NaN value, the result will either be
   NaN again or (for comparison operators) something totally unexpected.  For example if
   you perform the operation a = x / 0, variable a will contain NaN.  Now the comparison
   a == a will actually return the value false!  Unlike NaN, infinity values will behave as
   expected if used in comparison operations, that is positive infinity is greater than any
   other value, negative infinity is smaller than any other value.

Examples:
   1.0         // Floating Point Number Literal
   123.456      // Floating Point Number Literal
   987.         // Floating Point Number Literal
   .1337      // NOT a Floating Point Number Literal
   1.5e2      // Scientific Floating Point Number Literal
   1.5d2      // Scientific Floating Point Number Literal
   1.5e+2      // NOT a Scientific Floating Point Number Literal
   1.5e-2      // NOT a Scientific Floating Point Number Literal
   1.f

The first three examples are valid examples of floating point number literals, each starting with a
   number then being followed by a decimal point.  The fourth example is incorrect, as the
   literal begins with no number and proceeds immediately to the decimal dot, which would
   terminate the value.  A scientific floating point literal starts like a normal floating point
   literal, but after the decimal dot and optional decimal places there's the letter D or E,
   followed by one or more digits.  Only the first two examples actually are actually a single
   literal.  The next two examples really represent the expressions 1.5 +/- 2.0 respectively. 
   The last example can be found quite often in the UT2004 script code and is nothing else
   than the value 1.0 expressed in a way C++ and Java programmers immediately recognize
   as a float value.  You could, in fact, also write 1.a and it would mean the exact same
   thing in UnrealScript.

Technical information:
   [>>] float
      Size: 32-bit (Single precision with a 23 bit mantissa). // EDIT LATER: 23 BIT OR 24 BIT???
      Number range: -8388608 to 8388608 (which would be 2^23)
      Initial value: 0
      Literal = nnn.nnn (Float literals between -1 to 1 exclusive MUST start with a 0)
         > Correct: x = 0.314;
         > Incorrect: x = .314;
   
As specified in the IEEE floating-point standard, the float type internally has a length of 32 bits
   and consists of a 23 bit fraction part, an 8 bit exponent and one sign bit.  Especially the
   23 bit fraction part (called the "mantissa") imposes a limit on floating point precision. 
   When large int values greater than 223 or smaller than -223 are typecasted to float, they
   may get rounded.
*/
//=============================================================================

//=============================================================================
/*
> [3.2] Boolean Values

[>>] Boolean Literals (PRIMITIVE)
Boolean literals are quick to explain.  There are only two of them, True and False.  Both are
   case-insensitive, like any other identifiers in UnrealScript, so "true" and "tRuE" are the
   same thing to the compiler.  UnrealScript's boolean type is bool and allows the values
   of true and false. These are also the names of the boolean literals (ie, bfire or
   bActiveCamera).  The convention is to start bool variables with "b".  You will see this
   throughout UnrealScript code, known as Hungarian notation, as it is easy to read for
   programmers.  It is suggested sticking with this to maintain coding consistency .


The bool type has some restrictions in UnrealScript.  For example it's not possible to declare
   static or dynamic arrays of bool values in Unreal Engine generations 1 and 2 or to use the
   parameter modifier "out" on bool parameters in function declarations.
*/
//=============================================================================

//=============================================================================
/*
> [3.3] Strings
Strings can contain any combination of Unicode characters.  String literals start and end with
   double quotes and may not extend past the end of a line.  Between these there may be any
   number of characters, except for previously mentioned line breaks.

[>>] String Literals (PRIMITIVE)
UnrealScript has a character string data type called string.  Technically string literals (but not
   values) are allowed to have a length of up to 1023 characters.  Internally strings are
   zero-terminated, which means no string can contain the null character because it would be
   recognized as the end of the string.  To include a double quote or backslash character in
   the string, it must be "escaped" by a(nother) backslash character.  Starting with Unreal
   Engine 3, strings could also contain other escape sequences, such as \n for a newline
   character. However in Unreal Engine 1 and 2, escaped letters only stand for themselves,
   i.e. the string "\n" is absolutely equal to the string "n" there.

String values are immutable and UnrealScript neither provides "character" type nor allows
   direct access to individual string characters.  There are, however, functions for extracting
   substrings and returning the Unicode value of the first character of a string.  There's also a
   function for returning a string of length 1 containing a character corresponding to a
   specified Unicode value.  Here is a list of some of these functions:

[>>] int Len(string) - returns the length of the string

[>>] int inStr(string s, string t) - returns the offset of the first appearance of t in s, or -1 if it
   is not found

[>>] string Mid(string s, int i, optional int j) - returns the first j characters of the string
   starting at offset i

[>>] string Left(string, int i) - returns the i leftmost characters of the string

[>>] string Right(string, int i) - returns the i rightmost characters of the string

[>>] string Caps(string) - returns the string converted to uppercase

Note: very early builds of Unreal Engine 1 had a fixed-length string type, which was declared
   with the syntax string[length].  This type is no longer supported and only mentioned here
   in case you run into its declaration in old code snippets.
*/
//=============================================================================
way2goslugger


Who is online

Users browsing this forum: No registered users and 45 guests

Copyright © 2001-2024 UnrealSP.org

Powered by phpBB® Forum Software © phpBB Limited