· web viewdesign document. table of contents. executive...

235
1

Upload: others

Post on 14-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

1

Page 2:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Full Sail!Design DocumentTable of Contents

Executive Summary………………………………………………………………………………..3

Treatment……………………………………………………………………………………….…..4-9

Interactivity……………………………………………………………………………..……..10-11

Torque Engine Specifics and Game Logic……………………………..……….12-14

Reference of Key Elements and Controls……………………………….………15-16

Art Production and Design……………………………………………………………….…..17

Example Code…………………………………………………………………….…………18-192

Scripts (Alphabetical Order)…………………………………………………………….………18-163

Watercraft Class……………………………………………………………………………………..164-186

GuiCompassCtrl Class…………………………………………………………………………….186-192

Conclusion…………………………………………………………………………………..………193

2

Page 3:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Executive Summary

High Concept -Massively immersive multiplayer 3D pirate ship racing and combat on the high seas.

Genre -A unique combination of racing, third person adventure, and first person shooter genres.

Platform -Primary Platforms Computers running the Windows operating system, versions `98 and later.

Secondary Platforms Macintosh computer systems.

Target Audience -Primary Audience Fans of racing/combat games. Fans of games involving pirates. Persons with interest in naval combat.

Secondary Audience Enthusiasts of seventeenth and eighteenth century history. Racing enthusiasts. Sailing enthusiasts.

Unique Features - Beautifully realistic terrains and textures Created with the Torque Engine, which was used in the best-selling game, “Tribes 2.” Unique team based combat and racing allowing up to three players to man different positions on a ship, then go head to head with multiple ships.

3

Page 4:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Treatment

Dust Jacket Story - Have you ever found your life on land lacking? Have you felt the call of the sea on countless occasions? Have you still not found a problem that can’t be solved with a cutlass? Now through the use of things like calculus, you will finally get to live out your dreams of pillaging and plundering on the high seas. In this massively immersive multiplayer environment, players get to live out their pirate dreams as they are pitted against each other and the sea in a good ole’ fashion galleon race. Ready for Action? Ready for Adventure? Ready for lots of clichéd pirate dialogue? Of course you are, so come aboard me bucko’ and set sail for adventure.

The Story – The Caribbean Islands was a place that held adventure and mystery in the seventeenth century. Ships sailed the high seas in search of new discoveries and fortune. Although the sea held great prosperity for some, it held grave danger for all. The great sea was the home for ruthless pirates waiting to plunder innocent merchants and whoever else may happen upon them.

Captains Morgan and Bacardi were two such pirates. Pillaging had been slow as of late, so the two sat in a seedy port bar drinking away their last bounties. As slow as “business” had been, rumors had arisen of a bountiful fish harvest in the small coastal village of Paradise Key. Rumors also said that because of this harvest the village was booming with business…and money.

Upon hearing the news both the surly pirate captains discussed the matter over multiple rounds of Grog. Deciding that it would be foolish for both crews to have to split the treasures taken from an attack on the village, a friendly competition would decide who would plunder and who would have to step aside. On the morn there would be a race. The first ship to Paradise Key would have complete rights to pillage the village without interference from the other pirates. With an enthusiastic “Arrgh!” and a clang of the Grog mugs the race was set…but who would be victorious?

Characters – Captain Morgan and Captain Bacardi, cheesy stereotypical pirates wearing typical pirate garb, large colorful button laden jackets, scarves, peg legs, eye patches, pirate hats, parrots, hooks for hands, every conceivable pirate cliché known to man.

Captain Morgan:

4

Page 5:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Dashing, daring, feared by men, loved by women, Captain Morgan is a cunning and ruthless pirate who’s lust for money is rivaled only by his appetite for rum.

Captain Morgan carries himself in the highest regard. A long flowing black mane drapes across his broad shoulders and thick robust mustaches flow from under his noble nose. Dressed brightly in reds and yellows, ornately embroidered velvet from all of Europe adorns his garments. Gleaming golden buttons line his coat ending at the keenly crafted cutlass at his side. He carries with him the scent of salt and the sea and in his eyes gleam the knowledge of the unknown.

Brief History:Captain Morgan has been a pirate for longer than most can

remember. Rumor says he was raised on the sea and as a boy helped out by carrying loot back to the ship from plundered villages and cities.

As a young adult, Morgan was revered by many of the pirates on his crew for his knowledge of the sea and his prowess with a sword. Not a man was known who could best him by sword or drink.

One stormy night, the captain of the vessel that Morgan called home gave the order to change course away from the village they had planned to sack that very night. The captain complained that the storm was too fierce for them the approach the city and continuing was folly. Morgan, knowing the ship had faced storms far worse, scoffed at the captain and drew together a mutiny. A fierce battle was waged on the ship and in the end the ex-captain’s body was thrown overboard with cheers of “Captain Morgan!” being heard throughout the torrents of rain.

From that day forward, Captain Morgan ruled his ship and his men.

Behaviors and Attributes:Because of the demo state that Full Sail! is in, none of the

pirate attributes have been added into the game. If the game project were to be completed in full, each of the pirates would have navigation and marksmanship attributes that would make them unique. These attribute values would be assigned according to what personality the pirate had. Captain Morgan would have a relatively high navigation skill as well as a high marksmanship skill. This would allow him to have better capability in both steering the ship and firing the cannons and pistols.

5

Page 6:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Sample Dialogue:All of the pirates have similar phrases that will be spoken

periodically throughout the game. The phrases are meant to carry a humorous and sea-faring feel:

“Avast ye matey!”“Land ho!”“Aarrgh!”“Ahoy!”“Shiver me timbers!”“Hang’em from the yardarm!”“Heave-to ye scurvy seadogs!”“Run a shot across the bow!”“That land-lubber will surely be dancin’ the hempen jig!”“Walk the plank!”

These are some of the phrases that will be spoken during gameplay as certain events occur. Each pirate will have a slightly different dialect than the others.

Vocabulary of Motion:Each of the pirates will have two animations (emotes) that

they can perform at any time. The first is a salute in which the pirate will raise his arm across his chest. The second is a wave to be used as a greeting or a taunt to a recently fallen enemy.

Captain Bacardi:Stout and strong-willed, swift and wily, Captain Bacardi

proves without argument that size does not matter.

Standing a mere four feet and two inches, Captain Bacardi commands his vessel like a giant. Wild, crimson hair juts out from under his hat. The gleaming white skull and crossbones on his hat forewarn of his demeanor, as cruel and stoic as the sea itself. His face carries no emotion and his sword carries the blood of many.

Brief History:Bacardi led a normal childhood on a small island in the

Caribbean. He smiled, played, and laughed as normal children do until the age of fourteen when his village was invaded by Spanish conquerors. His father and mother were slain in the attack, but Bacardi managed to somehow escape.

Years later, after his shift working the docks, Bacardi sat for a nice cold mug of grog at the local bar. Minutes after he

6

Page 7:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

arrived, a group of rowdy surly men charged into the bar. The air in the room quickly changed from the scent of stale beer to that of rotting fish. They were obviously pirates and it seemed that everyone in the room knew this.

The pirates moved across the room and made themselves comfortable at a table near Bacardi, knocking the empty mugs resting there to the floor and demanding service from the barmaid.

“Aarrgh, maties, look at the fine wench there! Wench! Why don’t ye come over here and make some company and ye best bring some grog with ye!” shouted one of the pirates, the others following it up with an uproar of laughter. Bacardi glanced over to the pirate’s table at the commotion, just as one of the pirate’s looked his way.

“Whatchye lookin’ at me boy? Ner ye seen a pirate before?” The pirate stood, glaring at Bacardi who quickly looked down at the floor. “Are ye scared of pira—look at me boy!!”

Bacardi looked back up at the pirate who was approaching him now, “No, I’m not scared of pirates,” he replied quietly. Something disturbed Bacardi greatly, but he couldn’t quite put his finger on it.

“How about pirate captains—““Here are the grogs you want—“ interrupted the barmaid.With a swift backhand, the woman sprawled across the

flow, the mugs clanging to the floor loudly, “Can’t ye see I’m talkin’, wench?!”

Suddenly it hit bacardi like a musket round; a vision of his mother being struck down appeared. This pirate was the one who killed his parents.

“Well, me bucko, do ye think ye could run me ship?” asked the pirate, smirking at his fellow crew members.

“Yes,” was all Bacardi said, fire glowing in his eyes. He reached out in one swift movement pulling the pirate’s own sword from its scabbard. The pirate, shocked by the sudden attack, watched in horror as his own cutlass was driven into his chest. Bacardi withdrew the sword and swung it around separating the pirate’s head from his shoulders before the first drop of blood hit the floor.

The other pirates sat, astounded that their captain had just been defeated.

Bacardi glanced over them, no emotion in his face, “So, where’s this new ship of mine?”

Behaviors and Attributes:

7

Page 8:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Because of the demo state that Full Sail! is in, none of the pirate attributes have been added into the game. If the game project were to be completed in full, each of the pirates would have navigation and marksmanship attributes that would make them unique. These attribute values would be assigned according to what personality the pirate had. Captain Bacardi would have a medium navigation skill but a high marksmanship skill. He hasn’t sailed the seas for long, but his prowess in combat is unstoppable.

Sample Dialogue:All of the pirates have similar phrases that will be spoken

periodically throughout the game. The phrases are meant to carry a humorous and sea-faring feel:

“Avast ye matey!”“Land ho!”“Aarrgh!”“Shiver me timbers!”“Hang’em from the yardarm!”“Heave-to ye scurvy seadogs!”“Run a shot across the bow!”“That land-lubber will surely be dancin’ the hempen jig!”“Walk the plank!”

These are some of the phrases that will be spoken during gameplay as certain events occur. Each pirate will have a slightly different dialect than the others.

Vocabulary of Motion:Each of the pirates will have two animations (emotes) that

they can perform at any time. The first is a salute in which the pirate will raise his arm across his chest. The second is a wave to be used as a greeting or a taunt to a recently fallen enemy.

Level Description – Journey to Paradise KeyThe tropical paradise of the Caribbean meets the mystery and

danger of piracy.The secluded village of Paradise Key lies deep within the

Caribbean Islands. Many uninhabited islands are located nearby, all dusted by palm trees and other tropical plants and animals. Although seemingly a paradise, the waters of Paradise Key hold within them many dangers. A major pirate route lies nearby. The sea is also unusually infested with sharks.

8

Page 9:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Brief History:Paradise Key is a quiet village populated by an unspoken people.

The community gathers enough food and other goods to suffice for their own survival. However, Paradise Key recently came upon a bountiful fish harvest. None of the villagers know what could have caused this overpopulation of fish, but they now rejoice in the fact that their fish supply has grown one-hundred-fold.

Now, with the mysterious fish supply, the village’s exports and business have grown tremendously. Merchants from all around the Caribbean have traveled many miles just to trade with Paradise Key.

However, the fame comes with a price. With all of the business comes wealth. With all the wealth comes pirates.

Rules:The world’s rules following the Journey to Paradise Key are not

different from the real world, other than the number of lives. In game, the players will have unlimited lives, however they will have to be picked up from shore upon dying by their shipmates. The first ship to Paradise Key wins.

Behaviors:The world itself cannot be changed. If a cannon is fired and hits

a tree or the ground, there will not be a hole or even a mark for that matter. The world itself is mainly just scenery and a guide to show the player the way to the finish. The only exception to this is if the player falls into the water. Since the sharks are heavily populated in Paradise Key, a player will most surely be eaten upon falling into the sea. This will cause them to respawn at the nearest dock.

Environmental Aspects:The only environmental aspects of note are the sharks (noted

above) and the sounds of the sea (seagulls, ocean waves, etc.)

9

Page 10:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Interactivity

Goal – The objective of Full Sail! is team-based combat and racing. With three different positions to fill on the ship, teamwork is essential to win the race. The only goal is to be the first to the village, so you can have pillaging rights to it. Get there by any means possible, including wiping out the other pirates trying to get there before you.

Interface – Full Sail! will feature several unique interfaces that will reflect the current ship station that the player is currently at.

The crow’s nest position gives the best vantage point from which to see the course and your opponents. From this position you’ll be able to direct the helmsman on which direction to turn and you’ll be equipped with a gun to fire on your opponents.

The helmsman position is one of the most important stations on the ship. The player in this position will be in charge of steering the ship. Since the sails are so large on the galleon, the player will have to rely on directions given from the crow’s nest in order to navigate with the poor visibility.

The cannon position is used to wreak havoc amongst your opponents. Cannonballs may be fired out from either side of the ship at the opposing pirates. With practice and good aim, a player can kill opposing pirates causing them to respawn elsewhere and leaving the opposing ship manless.

The default view for Full Sail! is a third person view from above and behind the player. The player can freely move about the ship and mount a station at any time. Once in a station, the view is switched to first person and the player cannot move, but is in control of that given station whether it be steering, firing a cannon, or firing a pistol and navigating.

10

Page 11:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

User Experience - The user will use the various stations/mounting points about the ship in conjunction with his teammates to coordinate the ship movement and attack.

At the cannon position, the player will control in order to skillfully hit the opposing pirate ship. The goal in this position is to take out opposing pirates.

The helmsman position will consist of controlling the ship’s direction according to the feedback given to him from the player in the crow’s nest.

Thus, it is the goal of the pirate manning the Crow’s Nest to decide the best approach to the race’s path and relaying the info to the helmsman. Also the player in the crow’s nest is equipped with a pistol to attempt to take out nearby pirates.

Working together, the pirates should be able to successfully defend against the other pirate ship and navigate the racecourse in a timely manner.

Interactive Rhythm - The typical race session should last anywhere from five to ten minutes depending on the skill of the opposing teams and their experience working with their fellow pirates. This is much like many of the team-based first person shooters on the market today, such as Counterstrike and Return to Castle Wolfenstein. If Full Sail! was to be developed past the demo state, it would take into consideration different ship types also, each with their own special attributes and upgrades such as armor.

Replay value is found in the variation of team members and opponents. As you get skilled at a level, playing against other skilled players will change the experience and make it more exciting. Working out team strategies and gaining knowledge of using a particular station on the ship are further reasons for continued play. This once again resembles games such as Return to Castle Wolfenstein, which has different character classes that you can choose; each of the classes are important in their own respect.

How the User Marks Progress – Players can easily mark their progress throughout the race by looking at their position compared to their opponents position. The player can also see how many players are currently on their ship and opposing ships in order to judge how many players will have to be picked up at docks along the way. Once a player spots the village of Paradise Key, they are on the home stretch!

11

Page 12:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Torque Engine specifics and Game logic

Platform Specific Features - The Torque Engine is built from the ground up to be completely multi platform with native support in the form of a Windows server & client utilizing both OpenGL and DirectX. The Mac Implementation supports a Mac OS 9/X server & client with OpenGL. Currently there is also a Linux dedicated server with a client under development. Support for 3D applications comes in the form of an extensive Math library, including Vectors, Matrices, Quaternions, etc. The Torque engine’s memory manager and extensive debugging features are unparalleled, coupled with the resource manager, debugging is made much easier on the end user. The abstraction layer of the Torque engine also contains support for File and Stream IO, Action Map input for Keyboard, Mouse and Joystick/Control Pads. Open source sound is also supported via the OpenAL format, a project aimed at creating a universal open source audio library much like OpenGL has done with graphics.

Scripting Language - The Torque Engine’s scripting language is designed to separate game play specific code from engine code in order to aid in the development of mods or the modification of existing game play without having to worry about the core functionality of the engine. Included with Torque is the scripting language’s integrated compiler, done at load time. With it’s C++ like syntax and intermediate tokenized object format, the language itself is easy to pickup for experienced programmers. The scripting language also sports a large variety of complement functions including math, object manipulation, fileIO and TCP/IP, once again extending the features of the engine without actually manipulating engine specific code.

GUI Editor - The GUI Editor within the Torque engine is accessible within engine to provide a visual means of manipulating a script driven interface, included with it are a set of default controls and the ability to easily write custom controls. The Torque GUI Editor also has support for True Type fonts in order to personalize the look of an in game interface.

Mission Editor - Included in the Torque Engine is an integrated mission editor which allows the user to construct, place, size, scale and rotate objects in real time. Along with placing objects the mission editor also allows the user to edit object properties. The Mission Editor also gives the user the power to control mission lighting and add mission scripting. Aiding the user in this process is a multi-level undo/redo option which proves to be more than useful.

12

Page 13:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Tied in with the mission editor is the built in terrain editor which uses a rule based fractal height field generator.

3D Engine - The Torque Engine is easily on par with current 3D engines in features, some of these features include: multi-pass texturing for detailed textures, layered volumetric fog for adding atmosphere to large outdoor environments. Decals for adding small details such as bullet holes are footprints, Environment mapping for adding an immersive effects such as the reflection of the sky on a body of water, and Vertex and multi-pass lighting for intricately detailed lighting effects. Since the Torque engine supports such large outdoor landscapes, it also makes use of true spherical distance fogging and clipping for terrain and buildings.

Particle Engine - The particle engine included in the Torque engine is designed for it’s ease of use as it’s integrated into the scripting engine. Particles can be extensively modified by manipulating attributes such as mass, drag, starting velocity, etc. The Torque engine’s sophisticated particle generators can even emit multiple particle types at once.

Terrain Engine - The Terrain Engine in the Torque engine is renowned for handling expansive outdoor environments. Included with this functionality is continuous, seamless, LOD mesh generation. A clean looks is given to terrain through aggregated tile mip-mapping. The terrain is also very detailed with light mapping for hills and building shadows, as well as dynamically generated blend tiles. Since the outdoor environments can be so large, the Torque engine also supports altitude based fog banks for fogging the lowest valleys or even the highest altitudes for flying. Not only does the terrain engine handle massive environments but it also seamlessly integrates with the interior engine with absolutely no loads or performance hits for traversal between indoors and out.

Interiors/Buildings - Interior instances in the Torque engine are portal based for extremely quick rendering and excellent performance. Interiors are created with the long established WorldCraft tool currently maintained by Valve Software, creators of Half Life. Detailed indoor environments make use of animated light maps to lend a sense of atmosphere to interiors. Also buildings within Torque can be placed, manipulated and even scaled within the mission editor. Water - Water in Torque is perhaps the most detailed in any current 3D Engine designed to handle indoor and outdoor environments. The water in Torque is created through continuous, seamless LOD mesh generation for large bodies of water. Waves

13

Page 14:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

within the Torque engine are also dynamically generated, making use of multi-pass texturing for wave crests and shoreline textures. The Water much like everything else in Torque integrates seamlessly with the terrain and interior instances.

Networking - The Torque engine contains Dynamix’s legendary award winning client/server architecture for multiplayer gaming. Torque makes use of both UDP and TCP as it’s networking protocol, including such features as bit level stream packing, string and message packing and an optimal Notified Delivery Protocol.

Sound - 3D Sound is also supported in the Torque engine through a multi-channel prioritized SFX manager. Available 3D effects included panning, volume, Doppler effect, and cones. OpenAL provides the sound libraries.

Tools - The Torque engine comes with tool support in the form of a converter for WorldCraft for creating interior instances, as well as an exporter for 3D Studio Max for the creation of in game objects, players, and vehicles.

Misc. Features - Some of the extra features included in the Torque engine are extensive collision routines, including ray to polygon, polygon to polygon, ray to polytope, etc. Detailed vehicle physics are also supported in the Torque engine for use in the massive outdoor environments.

14

Page 15:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Reference of Key Elements

This is where I am going to go into detail about how the game will function from start to finish. I will also explain what details the full version of the game will have.

At the beginning of the game the player will have a few choices that he/she can make: Host Game, Join Game, Options, and Quit. Once the player actually starts the game, he/she will be given the choice of which team to join. (In the full version of the game, the player will be able to choose a single player version with opposing computer players as well as choose from different ships each with their own statistics. The player will also be able to choose what pirate they want to play with.)

The players will start out in a bar following the storyline and have to run out to their ships. Once the players have boarded, they can continue to run about the ship aimlessly or choose one of the stations to mount.

Once one of the players mounts the helmsman position the ship will begin moving. The helmsman won’t have clear enough visibility to steer through the twisting path to Paradise Key however, so someone will have to man the crow’s nest to give navigational instructions. The only other position to take is the cannon. With both the cannon and the pistol that is given to the crow’s nest, the player can fire upon opposing players. If a player is shot enough times or is unfortunate enough to fall overboard and be eaten by sharks, he/she will respawn at the next nearest dock. Their team will then have to navigate to them to retrieve them or suffer the consequences of being one man short.

At anytime a player may dismount a station and choose a different one that is unoccupied. This allows for less than three people to run a ship, although it may be a bit frantic to do so.

Finally, once a ship arrives at Paradise Key, the race ends. The team’s time is shown and if they were fast enough they will be recorded in the high score listing for others to try and beat.

Controls

Game is started in Observer Mode.L selects team Spacebar jumpsW moves forward S moves backwardD strafes right A strafes left

Ctrl+B mounts the Helm Ctrl+N mounts the Crow’s Nest

15

Page 16:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Ctrl+M mounts the Cannon Left Mouse fires weapon

Ctrl+W waves Ctrl+S salutesArt and Production Design

Style of Art and Animation – Full Sail! is set in the early 18th Century with its art resembling a pirate theme. Gently sloping islands in the sea and palm trees will be the norm along with some ambient sea life models. There will also be a decent variety of trees and models typical of the setting. The village of Paradise Key will also follow the theme and storyline. It is a very small village adorned with rudimentary houses. The color scheme follows the flashy elegant style of the time. The pirates will be dressed in bright reds and yellows and their ships will fly the stereotypical black and white flags. The animation is consistently life-like so all models will move as they would in real life.

Style of Audio Effects - Typical ocean and pirate sounds will permeate throughout the game. These will consist of: seagulls, ocean waves, gun fire, cannon fire, and creaking ships. Voiceovers will also be done to add variety and pirate spirit to the game. Different events will trigger different responses from the pirates in game.

Style of Music - As this is a pirate game through and through, it is very necessary to generate a real feeling for the pirate theme. Traditional pirate songs will accompany some menus and some in-game action. Some other more general battle music with a lot of drums and brass will also be present during the actual racing to add both variety and a sense of urgency to the gameplay.

16

Page 17:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Example Code//-----------------------------------------------------------------------------// ActionMap.cs//-----------------------------------------------------------------------------

//------------------------------------------------------------------------------// Utility remap functions://------------------------------------------------------------------------------

function ActionMap::copyBind( %this, %otherMap, %command ){ if ( !isObject( %otherMap ) ) { error( "ActionMap::copyBind - \"" @ %otherMap @ "\" is not an object!" ); return; }

%bind = %otherMap.getBinding( %command ); if ( %bind !$= "" ) { %device = getField( %bind, 0 ); %action = getField( %bind, 1 ); %flags = %otherMap.isInverted( %device, %action ) ? "SDI" : "SD"; %deadZone = %otherMap.getDeadZone( %device, %action ); %scale = %otherMap.getScale( %device, %action ); %this.bind( %device, %action, %flags, %deadZone, %scale, %command ); }}

//------------------------------------------------------------------------------function ActionMap::blockBind( %this, %otherMap, %command ){ if ( !isObject( %otherMap ) ) { error( "ActionMap::copyBind - \"" @ %otherMap @ "\" is not an object!" ); return; }

%bind = %otherMap.getBinding( %command ); if ( %bind !$= "" ) %this.bind( getField( %bind, 0 ), getField( %bind, 1 ), "" );}

//-----------------------------------------------------------------------------// AIPlayer.cs// Portions Copyright (c) 2001 by Sierra Online, Inc.

17

Page 18:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// This is the default AIPlayer class file, when the aiAddPlayer function// is executed, if an initalization function is provided it will//

//-----------------------------------------------------------------------------// Callback Handlers//-----------------------------------------------------------------------------function AIPlayer::onStuck() { echo( "onStuck" );}

function AIPlayer::onUnStuck() { echo( "onUnStuck" );}

function AIPlayer::onStop() { echo( "onStop" );}

function AIPlayer::onMove() { echo( "onMove" );}

function AIPlayer::onReachDestination() { echo( "onReachDestination" );}

function AIPlayer::onTargetEnterLOS() { echo( "onTargetEnterLOS" );}

function AIPlayer::onTargetExitLOS() { echo( "onTargetExitLOS" );}

function AIPlayer::onAdd() { echo( "I've been added." );}

//-----------------------------------------------------------------------------////-----------------------------------------------------------------------------// audio.cs - common\client\//-----------------------------------------------------------------------------

function OpenALInit(){ OpenALShutdownDriver();

18

Page 19:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

echo(""); echo("OpenAL Driver Init:");

echo ($pref::Audio::driver); if($pref::Audio::driver $= "OpenAL") if(!OpenALInitDriver()) error(" Failed to initialize driver.");

echo(" Vendor: " @ alGetString("AL_VENDOR")); echo(" Version: " @ alGetString("AL_VERSION")); echo(" Renderer: " @ alGetString("AL_RENDERER")); echo(" Extensions: " @ alGetString("AL_EXTENSIONS"));

alxListenerf( AL_GAIN_LINEAR, $pref::Audio::masterVolume ); for (%channel=1; %channel <= 8; %channel++) alxSetChannelVolume(%channel, $pref::Audio::channelVolume[%channel]);

echo("");}

//--------------------------------------------------------------------------

function OpenALShutdown(){ OpenALShutdownDriver(); //alxStopAll(); //AudioGui.delete(); //sButtonDown.delete(); //sButtonOver.delete();}

//-----------------------------------------------------------------------------// audio.cs – common\server\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function ServerPlay2D(%profile){ // Play the given sound profile on every client. // The sounds will be transmitted as an event, not attached to any object. for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) ClientGroup.getObject(%idx).play2D(%profile);}

function ServerPlay3D(%profile,%transform){ // Play the given sound profile at the given position on every client

19

Page 20:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// The sound will be transmitted as an event, not attached to any object. for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) ClientGroup.getObject(%idx).play3D(%profile,%transform);}

//-----------------------------------------------------------------------------// audioProfile.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// 3D Sounds//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Single shot sounds

datablock AudioDescription(AudioDefault3d){ volume = 1.0; isLooping= false;

is3D = true; minDistance= 20.0; MaxDistance= 100.0; type = $EffectAudioType;};

datablock AudioDescription(AudioClose3d){ volume = 1.0; isLooping= false;

is3D = true; minDistance= 10.0; MaxDistance= 60.0; type = $EffectAudioType;};

datablock AudioDescription(AudioClosest3d){ volume = 1.0; isLooping= false;

is3D = true; minDistance= 5.0; MaxDistance= 30.0; type = $EffectAudioType;};

20

Page 21:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// Looping sounds

datablock AudioDescription(AudioDefaultLooping3d){ volume = 1.0; isLooping= true;

is3D = true; ReferenceDistance= 20.0; MaxDistance= 100.0; type = $EffectAudioType;};

datablock AudioDescription(AudioCloseLooping3d){ volume = 1.0; isLooping= true;

is3D = true; minDistance= 10.0; MaxDistance= 50.0; type = $EffectAudioType;};

datablock AudioDescription(AudioClosestLooping3d){ volume = 1.0; isLooping= true;

is3D = true; minDistance= 5.0; MaxDistance= 30.0; type = $EffectAudioType;};

//-----------------------------------------------------------------------------// 2d sounds//-----------------------------------------------------------------------------

// Used for non-looping environmental sounds (like power on, power off)datablock AudioDescription(Audio2D){ volume = 1.0; isLooping = false; is3D = false; type = $EffectAudioType;};

// Used for Looping Environmental Soundsdatablock AudioDescription(AudioLooping2D){ volume = 1.0;

21

Page 22:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

isLooping = true; is3D = false; type = $EffectAudioType;};

//-----------------------------------------------------------------------------datablock AudioProfile(Oceanfx){ filename = "~/data/sound/fx/ocean.wav"; description = "AudioDefaultLooping3d"; preload = false;};

//-----------------------------------------------------------------------------// audioProfile.cs – fps\client\scripts\// //-----------------------------------------------------------------------------

// assign some human readable variable to channel numbers$DefaultAudioType = 0;$GuiAudioType = 1;$SimAudioType = 2;

new AudioDescription(AudioDefault){ volume = 1.0; isLooping = false; is3D = false; type = $DefaultAudioType;};

new AudioDescription(AudioGui){ volume = 1.0; isLooping = false; is3D = false; type = $GuiAudioType;};

new AudioDescription(AudioSim){ volume = 1.0; isLooping = true; is3D = true; type = $SimAudioType;};

new AudioProfile(AudioButtonOver){ filename = "~/data/sound/ui/buttonOver.wav"; description = "AudioGui"; preload = true;

22

Page 23:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

};

new AudioDescription(backgroundLoop){ volume = 0.7; isLooping = true; is3D = false; type = $DefaultAudioType;};

//-----------------------------------------------------------------------------// bluePlayer.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

// Load dts shapes and merge animationsexec("~/data/shapes/player/blue/blueplayer.cs");// Timeouts for corpse deletion.$CorpseTimeoutValue = 22 * 1000;

// Damage Rate for entering Liquid$DamageLava = 0.01;$DamageHotLava = 101;$DamageCrustyLava = 0.01;

//$PlayerDeathAnim::TorsoFrontFallForward = 1;$PlayerDeathAnim::TorsoFrontFallBack = 2;$PlayerDeathAnim::TorsoBackFallForward = 3;$PlayerDeathAnim::TorsoLeftSpinDeath = 4;$PlayerDeathAnim::TorsoRightSpinDeath = 5;$PlayerDeathAnim::LegsLeftGimp = 6;$PlayerDeathAnim::LegsRightGimp = 7;$PlayerDeathAnim::TorsoBackFallForward = 8;$PlayerDeathAnim::HeadFrontDirect = 9;$PlayerDeathAnim::HeadBackFallForward = 10;$PlayerDeathAnim::ExplosionBlowBack = 11;

//----------------------------------------------------------------------------// Player Audio Profiles//----------------------------------------------------------------------------

//----------------------------------------------------------------------------

datablock AudioProfile(DeathCrySound){ fileName = ""; description = AudioClose3d; preload = true;};

datablock AudioProfile(PainCrySound)

23

Page 24:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ fileName = ""; description = AudioClose3d; preload = true;};

datablock AudioProfile(ArmorMoveBubblesSound){ filename = "~/data/sound/replaceme.wav"; description = AudioCloseLooping3d; preload = true;};

datablock AudioProfile(WaterBreathMaleSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClosestLooping3d; preload = true;};

//----------------------------------------------------------------------------

datablock AudioProfile(FootLightSoftSound){ filename = "~/data/sound/fx/Footstep_soft.wav"; description = AudioClosest3d; preload = true;};

datablock AudioProfile(FootLightHardSound){ filename = "~/data/sound/fx/footfall.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(FootLightMetalSound){ filename = "~/data/sound/fx/footfall.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(FootLightSnowSound){ filename = "~/data/sound/fx/Footstep_soft.wav"; description = AudioClosest3d; preload = true;};

datablock AudioProfile(FootLightShallowSplashSound){ filename = "~/data/sound/fx/walkwtr.wav"; description = AudioClose3d; preload = true;};

24

Page 25:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

datablock AudioProfile(FootLightWadingSound){ filename = "~/data/sound/fx/walkwtr.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(FootLightUnderwaterSound){ filename = "~/data/sound/fx/footfall.wav"; description = AudioClosest3d; preload = true;};

datablock AudioProfile(FootLightBubblesSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true;};

//----------------------------------------------------------------------------

datablock AudioProfile(ImpactLightSoftSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true; effect = ImpactSoftEffect;};

datablock AudioProfile(ImpactLightHardSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true; effect = ImpactHardEffect;};

datablock AudioProfile(ImpactLightMetalSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true; effect = ImpactMetalEffect;};

datablock AudioProfile(ImpactLightSnowSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClosest3d; preload = true; effect = ImpactSnowEffect;};

25

Page 26:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

datablock AudioProfile(ImpactLightWaterEasySound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(ImpactLightWaterMediumSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(ImpactLightWaterHardSound){ filename = "~/data/sound/replaceme.wav"; description = AudioDefault3d; preload = true;};

datablock AudioProfile(ExitingWaterLightSound){ filename = "~/data/sound/replaceme.wav"; description = AudioClose3d; preload = true;};

//----------------------------------------------------------------------------// Splash//----------------------------------------------------------------------------

datablock ParticleData(PlayerSplashMist){ dragCoefficient = 2.0; gravityCoefficient = -0.05; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 400; lifetimeVarianceMS = 100; useInvAlpha = false; spinRandomMin = -90.0; spinRandomMax = 500.0; textureName = "~/data/shapes/player/splash"; colors[0] = "0.7 0.8 1.0 1.0"; colors[1] = "0.7 0.8 1.0 0.5"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 0.5; sizes[1] = 0.5; sizes[2] = 0.8; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

26

Page 27:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

datablock ParticleEmitterData(PlayerSplashMistEmitter){ ejectionPeriodMS = 5; periodVarianceMS = 0; ejectionVelocity = 3.0; velocityVariance = 2.0; ejectionOffset = 0.0; thetaMin = 85; thetaMax = 85; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; lifetimeMS = 250; particles = "PlayerSplashMist";};

datablock ParticleData(PlayerBubbleParticle){ dragCoefficient = 0.0; gravityCoefficient = -0.50; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 400; lifetimeVarianceMS = 100; useInvAlpha = false; textureName = "~/data/shapes/player/splash"; colors[0] = "0.7 0.8 1.0 0.4"; colors[1] = "0.7 0.8 1.0 0.4"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 0.1; sizes[1] = 0.3; sizes[2] = 0.3; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData(PlayerBubbleEmitter){ ejectionPeriodMS = 1; periodVarianceMS = 0; ejectionVelocity = 2.0; ejectionOffset = 0.5; velocityVariance = 0.5; thetaMin = 0; thetaMax = 80; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "PlayerBubbleParticle";};

datablock ParticleData(PlayerFoamParticle){ dragCoefficient = 2.0; gravityCoefficient = -0.05; inheritedVelFactor = 0.0;

27

Page 28:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

constantAcceleration = 0.0; lifetimeMS = 400; lifetimeVarianceMS = 100; useInvAlpha = false; spinRandomMin = -90.0; spinRandomMax = 500.0; textureName = "~/data/shapes/player/splash"; colors[0] = "0.7 0.8 1.0 0.20"; colors[1] = "0.7 0.8 1.0 0.20"; colors[2] = "0.7 0.8 1.0 0.00"; sizes[0] = 0.2; sizes[1] = 0.4; sizes[2] = 1.6; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData(PlayerFoamEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 3.0; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 85; thetaMax = 85; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "PlayerFoamParticle";};

datablock ParticleData( PlayerFoamDropletsParticle ){ dragCoefficient = 1; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = -0.0; lifetimeMS = 600; lifetimeVarianceMS = 0; textureName = "~/data/shapes/player/splash"; colors[0] = "0.7 0.8 1.0 1.0"; colors[1] = "0.7 0.8 1.0 0.5"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 0.8; sizes[1] = 0.3; sizes[2] = 0.0; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData( PlayerFoamDropletsEmitter ){ ejectionPeriodMS = 7; periodVarianceMS = 0;

28

Page 29:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

ejectionVelocity = 2; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 60; thetaMax = 80; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; particles = "PlayerFoamDropletsParticle";};

datablock ParticleData( PlayerSplashParticle ){ dragCoefficient = 1; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = -0.0; lifetimeMS = 600; lifetimeVarianceMS = 0; colors[0] = "0.7 0.8 1.0 1.0"; colors[1] = "0.7 0.8 1.0 0.5"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 0.5; sizes[1] = 0.5; sizes[2] = 0.5; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData( PlayerSplashEmitter ){ ejectionPeriodMS = 1; periodVarianceMS = 0; ejectionVelocity = 3; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 60; thetaMax = 80; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 100; particles = "PlayerSplashParticle";};

datablock SplashData(PlayerSplash){ numSegments = 15; ejectionFreq = 15; ejectionAngle = 40; ringLifetime = 0.5; lifetimeMS = 300; velocity = 4.0; startRadius = 0.0;

29

Page 30:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

acceleration = -3.0; texWrap = 5.0;

texture = "~/data/shapes/player/splash";

emitter[0] = PlayerSplashEmitter; emitter[1] = PlayerSplashMistEmitter;

colors[0] = "0.7 0.8 1.0 0.0"; colors[1] = "0.7 0.8 1.0 0.3"; colors[2] = "0.7 0.8 1.0 0.7"; colors[3] = "0.7 0.8 1.0 0.0"; times[0] = 0.0; times[1] = 0.4; times[2] = 0.8; times[3] = 1.0;};

//----------------------------------------------------------------------------// Foot puffs//----------------------------------------------------------------------------

datablock ParticleData(LightPuff){ dragCoefficient = 2.0; gravityCoefficient = -0.01; inheritedVelFactor = 0.6; constantAcceleration = 0.0; lifetimeMS = 800; lifetimeVarianceMS = 100; useInvAlpha = true; spinRandomMin = -35.0; spinRandomMax = 35.0; colors[0] = "1.0 1.0 1.0 1.0"; colors[1] = "1.0 1.0 1.0 0.0"; sizes[0] = 0.1; sizes[1] = 0.8; times[0] = 0.3; times[1] = 1.0;};

datablock ParticleEmitterData(LightPuffEmitter){ ejectionPeriodMS = 35; periodVarianceMS = 10; ejectionVelocity = 0.2; velocityVariance = 0.1; ejectionOffset = 0.0; thetaMin = 20; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; useEmitterColors = true; particles = "LightPuff";

30

Page 31:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

};

//----------------------------------------------------------------------------// Liftoff dust//----------------------------------------------------------------------------

datablock ParticleData(LiftoffDust){ dragCoefficient = 1.0; gravityCoefficient = -0.01; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 1000; lifetimeVarianceMS = 100; useInvAlpha = true; spinRandomMin = -90.0; spinRandomMax = 500.0; colors[0] = "1.0 1.0 1.0 1.0"; sizes[0] = 1.0; times[0] = 1.0;};

datablock ParticleEmitterData(LiftoffDustEmitter){ ejectionPeriodMS = 5; periodVarianceMS = 0; ejectionVelocity = 2.0; velocityVariance = 0.0; ejectionOffset = 0.0; thetaMin = 90; thetaMax = 90; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; useEmitterColors = true; particles = "LiftoffDust";};

//----------------------------------------------------------------------------

datablock DecalData(LightMaleFootprint){ sizeX = 0.125; sizeY = 0.25; textureName = "~/data/shapes/player/footprint";};

datablock DebrisData( PlayerDebris ){ explodeOnMaxBounce = false;

elasticity = 0.15; friction = 0.5;

31

Page 32:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

lifetime = 4.0; lifetimeVariance = 0.0;

minSpinSpeed = 40; maxSpinSpeed = 600;

numBounces = 5; bounceVariance = 0;

staticOnMaxBounce = true; gravModifier = 1.0;

useRadiusMass = true; baseRadius = 1;

velocity = 20.0; velocityVariance = 12.0;};

datablock PlayerData(BluePirate){ renderFirstPerson = false; emap = true;

className = Armor; shapeFile = "~/data/shapes/player/blue/blueplayer.dts"; cameraMaxDist = 3; computeCRC = true;

canObserve = true; cmdCategory = "Clients";

cameraDefaultFov = 90.0; cameraMinFov = 5.0; cameraMaxFov = 120.0;

debrisShapeName = "~/data/shapes/player/debris_player.dts"; debris = playerDebris;

aiAvoidThis = true;

minLookAngle = -1.4; maxLookAngle = 1.4; maxFreelookAngle = 3.0;

mass = 90; drag = 0.3; maxdrag = 0.4; density = 10; maxDamage = 100; maxEnergy = 60; repairRate = 0.33; energyPerDamagePoint = 75.0;

rechargeRate = 0.256;

runForce = 48 * 90;

32

Page 33:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

runEnergyDrain = 0; minRunEnergy = 0; maxForwardSpeed = 14; maxBackwardSpeed = 13; maxSideSpeed = 13;

maxUnderwaterForwardSpeed = 8.4; maxUnderwaterBackwardSpeed = 7.8; maxUnderwaterSideSpeed = 7.8;

jumpForce = 8.3 * 90; jumpEnergyDrain = 0; minJumpEnergy = 0; jumpDelay = 15;

recoverDelay = 9; recoverRunForceScale = 1.2;

minImpactSpeed = 45; speedDamageScale = 0.4;

boundingBox = "1.2 1.2 2.3"; pickupRadius = 0.75;

// Damage location details boxNormalHeadPercentage = 0.83; boxNormalTorsoPercentage = 0.49; boxHeadLeftPercentage = 0; boxHeadRightPercentage = 1; boxHeadBackPercentage = 0; boxHeadFrontPercentage = 1;

// Foot Prints decalData = LightMaleFootprint; decalOffset = 0.25;

footPuffEmitter = LightPuffEmitter; footPuffNumParts = 10; footPuffRadius = 0.25;

dustEmitter = LiftoffDustEmitter;

splash = PlayerSplash; splashVelocity = 4.0; splashAngle = 67.0; splashFreqMod = 300.0; splashVelEpsilon = 0.60; bubbleEmitTime = 0.4; splashEmitter[0] = PlayerFoamDropletsEmitter; splashEmitter[1] = PlayerFoamEmitter; splashEmitter[2] = PlayerBubbleEmitter; mediumSplashSoundVelocity = 10.0; hardSplashSoundVelocity = 20.0; exitSplashSoundVelocity = 5.0;

// Controls over slope of runnable/jumpable surfaces runSurfaceAngle = 70;

33

Page 34:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

jumpSurfaceAngle = 80;

minJumpSpeed = 20; maxJumpSpeed = 30;

horizMaxSpeed = 68; horizResistSpeed = 33; horizResistFactor = 0.35;

upMaxSpeed = 80; upResistSpeed = 25; upResistFactor = 0.3;

footstepSplashHeight = 0.35;

//NOTE: some sounds commented out until wav's are available

// Footstep Sounds FootSoftSound = FootLightSoftSound; FootHardSound = FootLightHardSound; FootMetalSound = FootLightMetalSound; FootSnowSound = FootLightSnowSound; FootShallowSound = FootLightShallowSplashSound; FootWadingSound = FootLightWadingSound; FootUnderwaterSound = FootLightUnderwaterSound; //FootBubblesSound = FootLightBubblesSound; //movingBubblesSound = ArmorMoveBubblesSound; //waterBreathSound = WaterBreathMaleSound;

//impactSoftSound = ImpactLightSoftSound; //impactHardSound = ImpactLightHardSound; //impactMetalSound = ImpactLightMetalSound; //impactSnowSound = ImpactLightSnowSound;

//impactWaterEasy = ImpactLightWaterEasySound; //impactWaterMedium = ImpactLightWaterMediumSound; //impactWaterHard = ImpactLightWaterHardSound;

groundImpactMinSpeed = 10.0; groundImpactShakeFreq = "4.0 4.0 4.0"; groundImpactShakeAmp = "1.0 1.0 1.0"; groundImpactShakeDuration = 0.8; groundImpactShakeFalloff = 10.0;

//exitingWater = ExitingWaterLightSound;

observeParameters = "0.5 4.5 4.5";

// Allowable Inventory Items maxInv[BulletAmmo] = 20; maxInv[HealthKit] = 1; maxInv[CrossbowAmmo] = 100; maxInv[CannonAmmo] = 999; maxInv[Crossbow] = 1; maxInv[Cannon] = 1;};

34

Page 35:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//----------------------------------------------------------------------------// Armor Datablock methods//----------------------------------------------------------------------------

//----------------------------------------------------------------------------

function Armor::onAdd(%this,%obj){ // Vehicle timeout %obj.mountVehicle = true;

// Default dynamic armor stats %obj.setRechargeRate(%this.rechargeRate); %obj.setRepairRate(0);}

function Armor::onRemove(%this, %obj){ if (%obj.client.player == %obj) %obj.client.player = 0;}

function Armor::onNewDataBlock(%this,%obj){

}

//----------------------------------------------------------------------------

function Armor::onMount(%this,%obj,%vehicle,%node){ if (%node == 0) { %obj.setTransform("0 0 0 0 0 1 0"); %obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true); %obj.lastWeapon = %obj.getMountedImage($WeaponSlot);

%obj.unmountImage($WeaponSlot); %obj.setControlObject(%vehicle); %obj.client.setObjectActiveImage(%vehicle, 2); } if(%node == 10) { %obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true); %obj.lastWeapon = %obj.getMountedImage($WeaponSlot); %obj.unmountImage($WeaponSlot); %weapon = new Item() { dataBlock = Cannon;

35

Page 36:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

};

MissionCleanup.add(%weapon); %obj.pickup(%weapon, 1); %ammo = new Item() { dataBlock = CannonAmmo; }; MissionCleanup.add(%ammo); %obj.pickup(%ammo,999); }}

function Armor::onUnmount(%this, %obj, %vehicle, %node ){ // Set whatever point the player was just at to mountable so that it can be mounted again.// If they were at the cannon, take away their cannon and the ammo. if (%node == 0) %vehicle.helmMountable = true;

if(%node == 1) %vehicle.nestMountable = true; if (%node == 10) { %obj.decInventory("Cannon", 1); %obj.decInventory("CannonAmmo", 999); %vehicle.cannonMountable = true; }}

function Armor::doDismount(%this, %obj, %forced){ // This function is called by player.cc when the jump trigger // is true while mounted if (!%obj.isMounted()) return;

// Position above dismount point %pos = getWords(%obj.getTransform(), 0, 2); %oldPos = %pos; %vec[0] = " 0 0 1"; %vec[1] = " 0 0 1"; %vec[2] = " 0 0 -1"; %vec[3] = " 1 0 0"; %vec[4] = "-1 0 0"; %impulseVec = "0 0 0"; %vec[0] = MatrixMulVector( %obj.getTransform(), %vec[0]);

// Make sure the point is valid %pos = "0 0 0"; %numAttempts = 5; %success = -1; for (%i = 0; %i < %numAttempts; %i++) {

36

Page 37:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 3)); if (%obj.checkDismountPoint(%oldPos, %pos)) { %success = %i; %impulseVec = %vec[%i]; break; } } if (%forced && %success == -1) %pos = %oldPos;

%obj.unmount(); %obj.setControlObject(%obj); if(%obj.mVehicle) { %obj.mVehicle.getDataBlock().playerDismounted(%obj.mVehicle, %obj); %obj.mVehicle.mountable = true; } %obj.mountVehicle = false; %obj.schedule(4000, "MountVehicles", true);

// Position above dismount point %obj.setTransform(%pos); %obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass)); %obj.setPilot(false); %obj.vehicleTurret = ""; %obj.unmountImage($WeaponSlot); %obj.mountNode0 = false; %obj.mountNode1 = false; %obj.mountNode10 = false;}

//----------------------------------------------------------------------------

function Armor::onCollision(%this,%obj,%col,%client){ if (%obj.getState() $= "Dead") return;

// Try and pickup all items if (%col.getClassName() $= "Item") %obj.pickup(%col); %this = %col.getDataBlock(); if((%this.className $= WheeledVehicleData || %this.className $= WaterCraftData) || %this.className $= HoverVehicleData || %this.className $= FlyingVehicleData && %obj.mountVehicle && %obj.getState() $= "Move") { if(%obj.mountNode0) { if(%col.mountable) {

37

Page 38:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if(%col.helmMountable) { %node = 0; %col.mountable = true; %col.mountObject(%obj,%node); %obj.mVehicle = %col; %obj.mountNode1 = false; %obj.mountNode10 = false; %col.helmMountable = false; } else messageClient(%obj.client, 'MountMsg', '\c0You can not mount at the Helm at this time.'); } } if(%obj.mountNode1) { if(%col.mountable) { if(%col.nestMountable) { %node = 1; %col.mountable = true; %col.mountObject(%obj,%node); %obj.mVehicle = %col; %obj.mountNode0 = false; %obj.mountNode10 = false; %col.nestMountable = false; } else messageClient(%obj.client, 'MountMsg', '\c0You can not mount at the Nest at this time.');

} } if(%obj.mountNode10) { if(%col.mountable) { if(%col.cannonMountable) { %node = 10; %col.mountable = true; %col.mountObject(%obj,%node); %obj.mVehicle = %col; %obj.mountNode0 = false; %obj.mountNode1 = false; %col.cannonMountable = false; } else messageClient(%obj.client, 'MountMsg', '\c0You can not mount at the Cannon at this time.');

} } }}

38

Page 39:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function Armor::onImpact(%this, %obj, %collidedObject, %vec, %vecLen){ %obj.damage(0, VectorAdd(%obj.getPosition(),%vec), %vecLen * %this.speedDamageScale, "Impact");}

//----------------------------------------------------------------------------

function Armor::damage(%this, %obj, %sourceObject, %position, %damage, %damageType){ if (%obj.getState() $= "Dead") return;

%obj.applyDamage(%damage); %location = "Body";

// Deal with client callbacks here because we don't have this // information in the onDamage or onDisable methods %client = %obj.client; %sourceClient = %sourceObject ? %sourceObject.client : 0;

if (%obj.getState() $= "Dead") %client.onDeath(%sourceObject, %sourceClient, %damageType, %location);}

function Armor::onDamage(%this, %obj, %delta){ // This method is invoked by the ShapeBase code whenever the // object's damage level changes. if (%delta > 0 && %obj.getState() !$= "Dead") {

// Increment the flash based on the amount. %flash = %obj.getDamageFlash() + ((%delta / %this.maxDamage) * 2); if (%flash > 0.75) %flash = 0.75; %obj.setDamageFlash(%flash);

// If the pain is excessive, let's hear about it. if (%amount > 10) %obj.playPain(); }}

function Armor::onDisabled(%this,%obj,%state){ // The player object sets the "disabled" state when damage exceeds // it's maxDamage value. This is method is invoked by ShapeBase // state mangement code.

// If we want to deal with the damage information that actually // caused this death, then we would have to move this code into // the script "damage" method. %obj.playDeathCry();

39

Page 40:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%obj.playDeathAnimation(); %obj.setDamageFlash(0.75);

// Release the main weapon trigger %obj.setImageTrigger(0, false);

// Schedule corpse removal. Just keeping the place clean. %obj.schedule($CorpseTimeoutValue - 1000, "startFade", 1000, 0, true); %obj.schedule($CorpseTimeoutValue, "delete");}

//-----------------------------------------------------------------------------

function Armor::onLeaveMissionArea(%this, %obj){ // Inform the client %obj.client.onLeaveMissionArea();}

function Armor::onEnterMissionArea(%this, %obj){ // Inform the client %obj.client.onEnterMissionArea();}

//-----------------------------------------------------------------------------

function Armor::onEnterLiquid(%this, %obj, %coverage, %type){ switch(%type) { case 0: //Water case 1: //Ocean Water case 2: //River Water case 3: //Stagnant Water case 4: //Lava %obj.setDamageDt(%this, $DamageLava, "Lava"); case 5: //Hot Lava %obj.setDamageDt(%this, $DamageHotLava, "Lava"); case 6: //Crusty Lava %obj.setDamageDt(%this, $DamageCrustyLava, "Lava"); case 7: //Quick Sand }}

function Armor::onLeaveLiquid(%this, %obj, %type){ %obj.clearDamageDt();}

//-----------------------------------------------------------------------------

function Armor::onTrigger(%this, %obj, %triggerNum, %val)

40

Page 41:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ // This method is invoked when the player receives a trigger // move event. The player automatically triggers slot 0 and // slot one off of triggers # 0 & 1. Trigger # 2 is also used // as the jump key.}

//-----------------------------------------------------------------------------// Player methods//-----------------------------------------------------------------------------

//----------------------------------------------------------------------------

function Player::kill(%this, %damageType){ %this.damage(0, %this.getPosition(), 10000, %damageType);}

//----------------------------------------------------------------------------

function Player::mountVehicles(%this,%bool){ // If set to false, this variable disables vehicle mounting. %this.mountVehicle = %bool;}

function Player::isPilot(%this){ %vehicle = %this.getObjectMount(); // There are two "if" statements to avoid a script warning. if (%vehicle) if (%vehicle.getMountNodeObject(0) == %this) return true; return false;}

//----------------------------------------------------------------------------

function Player::playDeathAnimation(%this){ if (%this.deathIdx++ > 11) %this.deathIdx = 1; %this.setActionThread("Death" @ %this.deathIdx);}

function Player::playCelAnimation(%this,%anim){ if (%this.getState() !$= "Dead") %this.setActionThread("cel"@%anim);}

41

Page 42:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//----------------------------------------------------------------------------

function Player::playDeathCry( %this ){ %client = %this.client; //playTargetAudio( %client.target, "replaceme", AudioClosest3d, false );}

function Player::playPain( %this ){ %client = %this.client; //playTargetAudio( %client.target, "replaceme", AudioClosest3d, false);}

//-----------------------------------------------------------------------------// bluePlayer.cs – fps\data\shapes\////-----------------------------------------------------------------------------

datablock TSShapeConstructor(BluePlayerDts){ baseShape = "./blueplayer.dts"; sequence0 = "./player_root.dsq root"; sequence1 = "./player_forward.dsq run"; sequence2 = "./player_back.dsq back"; sequence3 = "./player_side.dsq side"; sequence4 = "./player_lookde.dsq look"; sequence5 = "./player_head.dsq head"; sequence6 = "./player_fall.dsq fall"; sequence7 = "./player_land.dsq land"; sequence8 = "./player_jump.dsq jump"; sequence9 = "./player_diehead.dsq death1"; sequence10 = "./player_diechest.dsq death2"; sequence11 = "./player_dieback.dsq death3"; sequence12 = "./player_diesidelf.dsq death4"; sequence13 = "./player_diesidert.dsq death5"; sequence14 = "./player_dieleglf.dsq death6"; sequence15 = "./player_dielegrt.dsq death7"; sequence16 = "./player_dieslump.dsq death8"; sequence17 = "./player_dieknees.dsq death9"; sequence18 = "./player_dieforward.dsq death10"; sequence19 = "./player_diespin.dsq death11"; sequence20 = "./player_looksn.dsq looksn"; sequence21 = "./player_lookms.dsq lookms"; sequence22 = "./player_scoutroot.dsq scoutroot"; sequence23 = "./player_headside.dsq headside"; sequence24 = "./player_recoilde.dsq light_recoil"; sequence25 = "./player_sitting.dsq sitting"; sequence26 = "./player_celsalute.dsq celsalute"; sequence27 = "./player_celwave.dsq celwave"; sequence28 = "./player_standjump.dsq standjump"; sequence29 = "./player_looknw.dsq looknw";

42

Page 43:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

};

//-----------------------------------------------------------------------------// camera.cs fps\server\scripts\// //-----------------------------------------------------------------------------

// Global movement speed that affects all cameras. This should be moved// into the camera datablock.$Camera::movementSpeed = 40;

//-----------------------------------------------------------------------------// Define a datablock class to use for our observer camera//-----------------------------------------------------------------------------

datablock CameraData(Observer){ mode = "Observer";};

//-----------------------------------------------------------------------------

function Observer::onTrigger(%this,%obj,%trigger,%state){ // state = 0 means that a trigger key was released if (%state == 0) return;

// Default player triggers: 0=fire 1=altFire 2=jump %client = %obj.getControllingClient(); switch$ (%obj.mode) { case "Observer": // Do something interesting.

case "Corpse": // Viewing dead corpse, so we probably want to respawn. %client.spawnPlayer();

// Set the camera back into observer mode, since in // debug mode we like to switch to it. %this.setMode(%obj,"Observer"); }}

function Observer::setMode(%this,%obj,%mode,%arg1,%arg2,%arg3){ switch$ (%mode) { case "Observer": // Let the player fly around

43

Page 44:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%obj.setFlyMode();

case "Corpse": // Lock the camera down in orbit around the corpse, // which should be arg1 %transform = %arg1.getTransform(); %obj.setOrbitMode(%arg1, %transform, 0.5, 4.5, 4.5);

} %obj.mode = %mode;}

//-----------------------------------------------------------------------------// Camera methods//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function Camera::onAdd(%this,%obj){ // Default start mode %this.setMode(%this.mode);}

function Camera::setMode(%this,%mode,%arg1,%arg2,%arg3){ // Punt this one over to our datablock %this.getDatablock().setMode(%this,%mode,%arg1,%arg2,%arg3);}

//-----------------------------------------------------------------------------// cannon.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Cannon weapon. This file contains all the items related to this weapon// including explosions, ammo, the item and the weapon item image.// These objects rely on the item & inventory support system defined// in item.cs and inventory.cs//-----------------------------------------------------------------------------

// DB// Sounds for firing the weapon.

datablock AudioProfile(CannonFireSound){ filename = "~/data/sound/fx/cannon.wav";

44

Page 45:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

description = AudioClose3d; preload = true;};

datablock AudioProfile(CannonExplosionSound){ filename = "~/data/sound/fx/cannon.wav"; description = AudioDefault3d; preload = true;};

// DB end

//-----------------------------------------------------------------------------// Cannon Ball projectile particles

datablock ParticleData(CannonBallParticle){ textureName = "~/data/shapes/particles/smoke"; dragCoeffiecient = 0.0; gravityCoefficient = -0.2; // rises slowly inheritedVelFactor = 0.00; lifetimeMS = 500; // lasts 0.7 second lifetimeVarianceMS = 150; // ...more or less useInvAlpha = false; spinRandomMin = -30.0; spinRandomMax = 30.0;

colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 1.0"; colors[2] = "0 0 0 0";

sizes[0] = 1; sizes[1] = 2; sizes[2] = 1; times[0] = 0.0; times[1] = 0.3; times[2] = 1.0;};

datablock ParticleEmitterData(CannonBallEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 5;

ejectionVelocity = 0.25; velocityVariance = 0.10;

thetaMin = 0.0; thetaMax = 90.0;

particles = "CannonBallParticle";};

45

Page 46:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// Projectile Explosion

datablock ParticleData(CannonBallExplosionParticle){ dragCoefficient = 2; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 750; lifetimeVarianceMS = 150; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 0.0"; sizes[0] = 10; sizes[1] = 15;};

datablock ParticleEmitterData(CannonBallExplosionEmitter){ ejectionPeriodMS = 7; periodVarianceMS = 0; ejectionVelocity = 2; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "CannonBallExplosionParticle";};

datablock ParticleData(CannonExplosionSmoke){ textureName = "~/data/shapes/particles/smoke"; dragCoeffiecient = 100.0; gravityCoefficient = 0; inheritedVelFactor = 0.25; constantAcceleration = -0.80; lifetimeMS = 1500; lifetimeVarianceMS = 300; useInvAlpha = true; spinRandomMin = -80.0; spinRandomMax = 80.0;

colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.2 0.2 0.2 1.0"; colors[2] = "0.0 0.0 0.0 0.0";

sizes[0] = 12; sizes[1] = 15; //sizes[2] = 20;

times[0] = 0.0; times[1] = 0.5;

46

Page 47:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//times[2] = 1.0;};

datablock ParticleEmitterData(CannonExplosionSmokeEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 4; velocityVariance = 0.5; thetaMin = 0.0; thetaMax = 60.0; lifetimeMS = 250; particles = "CannonExplosionSmoke";};

datablock ParticleData(CannonExplosionSparks){ textureName = "~/data/shapes/particles/spark"; dragCoefficient = 1; gravityCoefficient = 0.0; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 300; lifetimeVarianceMS = 350;

colors[0] = "0.60 0.40 0.30 1.0"; colors[1] = "0.60 0.40 0.30 1.0"; colors[2] = "1.0 0.40 0.30 0.0";

sizes[0] = 12; sizes[1] = 17; //sizes[2] = 25;

times[0] = 0.0; times[1] = 0.5; //times[2] = 1.0;};

datablock ParticleEmitterData(CannonExplosionSparkEmitter){ ejectionPeriodMS = 3; periodVarianceMS = 0; ejectionVelocity = 13; velocityVariance = 6.75; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 100; particles = "CannonExplosionSparks";};

datablock ExplosionData(CannonSubExplosion1){

47

Page 48:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

offset = 1.0; emitter[0] = CannonExplosionSmokeEmitter; emitter[1] = CannonExplosionSparkEmitter;};

datablock ExplosionData(CannonSubExplosion2){ offset = 1.0; emitter[0] = CannonExplosionSmokeEmitter; emitter[1] = CannonExplosionSparkEmitter;};

datablock ExplosionData(CannonBallExplosion){ soundProfile = CannonExplosionSound; lifeTimeMS = 1200;

// Volume particles particleEmitter = CannonBallExplosionEmitter; particleDensity = 80; particleRadius = 8; faceViewer = true; // Point emission emitter[0] = CannonExplosionSmokeEmitter; emitter[1] = CannonExplosionSparkEmitter;

// Sub explosion objects subExplosion[0] = CannonSubExplosion1; subExplosion[1] = CannonSubExplosion2;

// Camera Shaking shakeCamera = true; camShakeFreq = "20.0 25.0 20.0"; camShakeAmp = "40.0 50.0 40.0"; camShakeDuration = 0.7; camShakeRadius = 50.0;

// Dynamic light lightStartRadius = 6; lightEndRadius = 3; lightStartColor = "0.5 0.5 0"; lightEndColor = "0 0 0";};

//-----------------------------------------------------------------------------// Projectile Object

datablock ProjectileData(CannonProjectile){ projectileShapeName = "~/data/shapes/cannon/projectile.dts"; directDamage = 40; radiusDamage = 20; damageRadius = 15.0; explosion = CannonBallExplosion; particleEmitter = CannonBallEmitter;

48

Page 49:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

muzzleVelocity = 100; velInheritFactor = 0.3;

armingDelay = 0; lifetime = 5000; fadeDelay = 5000; bounceElasticity = 0;

bounceFriction = 0; isBallistic = true; gravityMod = 0.80;

hasLight = true; lightRadius = 6.0; lightColor = "0.5 0.5 0";};

function CannonProjectile::onCollision(%this, %obj, %col, %fade, %pos, %normal){ // Apply damage to the object all shape base objects if (%col.getType() & $TypeMasks::ShapeBaseObjectType) %col.damage(%obj, %pos, %this.directDamage, "CannonBall");

// Radius damage is a support scripts defined in radiusDamage.cs radiusDamage(%obj, %pos, %this.damageRadius, %this.radiusDamage, "CannonBall", 0);}

//-----------------------------------------------------------------------------// Ammo Item

datablock ItemData(CannonAmmo){ // Mission editor category category = "Ammo";

// Add the Ammo namespace as a parent. The ammo namespace provides // common ammo related functions and hooks into the inventory system. className = "Ammo";

// Basic Item properties shapeFile = "~/data/shapes/cannon/projectile.dts"; mass = 1; elasticity = 0.2; friction = 0.6;

// Dynamic properties defined by the scripts pickUpName = "cannon balls!"; maxInventory = 999;};

49

Page 50:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//--------------------------------------------------------------------------// Weapon Item. This is the item that exists in the world, i.e. when it's// been dropped, thrown or is acting as re-spawnable item. When the weapon// is mounted onto a shape, the CannonballImage is used.

datablock ItemData(Cannon){ // Mission editor category category = "Weapon";

// Hook into Item Weapon class hierarchy. The weapon namespace // provides common weapon handling functions in addition to hooks // into the inventory system. className = "Weapon";

// Basic Item properties shapeFile = "~/data/shapes/cannon/weapon.dts"; mass = 1; elasticity = 0.2; friction = 0.6; emap = true;

// Dynamic properties defined by the scripts pickUpName = "a Cannon!!"; image = CannonImage;};

//--------------------------------------------------------------------------// Cannon image which does all the work. Images do not normally exist in// the world, they can only be mounted on ShapeBase objects.

datablock ShapeBaseImageData(CannonImage){ // Basic Item properties shapeFile = "~/data/shapes/cannon/weapon.dts"; emap = true;

// Specify mount point & offset for 3rd person, and eye offset // for first person rendering. mountPoint = 0; offset = "0 0 0"; eyeOffset = "0.1 0.2 -0.55";

// When firing from a point offset from the eye, muzzle correction // will adjust the muzzle vector to point to the eye LOS point. // Since this weapon doesn't actually fire from the muzzle point, // we need to turn this off. correctMuzzleVector = false;

// Add the WeaponImage namespace as a parent, WeaponImage namespace // provides some hooks into the inventory system.

50

Page 51:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

className = "WeaponImage";

// Projectile && Ammo. item = Cannon; ammo = CannonAmmo; projectile = CannonProjectile; projectileType = Projectile;

// Images have a state system which controls how the animations // are run, which sounds are played, script callbacks, etc. This // state system is downloaded to the client so that clients can // predict state changes and animate accordingly. The following // system supports basic ready->fire->reload transitions as // well as a no-ammo->dryfire idle state.

// Initial start up state stateName[0] = "Preactivate"; stateTransitionOnLoaded[0] = "Activate"; stateTransitionOnNoAmmo[0] = "NoAmmo"; // Activating the gun. Called when the weapon is first // mounted and there is ammo. stateName[1] = "Activate"; stateTransitionOnTimeout[1] = "Ready"; stateTimeoutValue[1] = 0.6; stateSequence[1] = "Activate";

// Ready to fire, just waiting for the trigger stateName[2] = "Ready"; stateTransitionOnNoAmmo[2] = "NoAmmo"; stateTransitionOnTriggerDown[2] = "Fire";

// Fire the weapon. Calls the fire script which does // the actual work. stateName[3] = "Fire"; stateTransitionOnTimeout[3] = "Reload"; stateTimeoutValue[3] = 0.2; stateFire[3] = true; stateRecoil[3] = LightRecoil; stateAllowImageChange[3] = false; stateSequence[3] = "Fire"; stateScript[3] = "onFire"; stateSound[3] = "CannonFireSound"; // **** Added in sound tutorial // Play the reload animation, and transition into stateName[4] = "Reload"; stateTransitionOnNoAmmo[4] = "NoAmmo"; stateTransitionOnTimeout[4] = "Ready"; stateTimeoutValue[4] = 0.8; stateAllowImageChange[4] = false; stateSequence[4] = "Reload"; stateEjectShell[4] = true;

// No ammo in the weapon, just idle until something // shows up. Play the dry fire sound if the trigger is // pulled. stateName[5] = "NoAmmo";

51

Page 52:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

stateTransitionOnAmmo[5] = "Reload"; stateSequence[5] = "NoAmmo"; stateTransitionOnTriggerDown[5] = "DryFire";

// No ammo dry fire stateName[6] = "DryFire"; stateTimeoutValue[6] = 1.0; stateTransitionOnTimeout[6] = "NoAmmo";};

//-----------------------------------------------------------------------------

function CannonImage::onFire(%this, %obj, %slot){ %projectile = %this.projectile;

// Decrement inventory ammo. The image's ammo state is updated // automatically by the ammo inventory hooks. %obj.decInventory(%this.ammo,1);

// Determine initial projectile velocity based on the // gun's muzzle point and the object's current velocity %muzzleVector = %obj.getMuzzleVector(%slot); %objectVelocity = %obj.getVelocity(); %muzzleVelocity = VectorAdd( VectorScale(%muzzleVector, %projectile.muzzleVelocity), VectorScale(%objectVelocity, %projectile.velInheritFactor));

// Create the projectile object %p = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%p); return %p;}

//-----------------------------------------------------------------------------// canvas.cs – common\client\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Function to construct and initialize the default canvas window// used by the games

function initCanvas(%windowName)

52

Page 53:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ videoSetGammaCorrection($pref::OpenGL::gammaCorrection); if (!createCanvas(%windowName)) { quit(); return; }

setOpenGLTextureCompressionHint( $pref::OpenGL::compressionHint ); setOpenGLAnisotropy( $pref::OpenGL::anisotropy ); setOpenGLMipReduction( $pref::OpenGL::mipReduction ); setOpenGLInteriorMipReduction( $pref::OpenGL::interiorMipReduction ); setOpenGLSkyMipReduction( $pref::OpenGL::skyMipReduction );

// Declare default GUI Profiles. exec("~/ui/defaultProfiles.cs");

// Common GUI's exec("~/ui/GuiEditorGui.gui"); exec("~/ui/ConsoleDlg.gui"); exec("~/ui/InspectDlg.gui"); exec("~/ui/LoadFileDlg.gui"); exec("~/ui/SaveFileDlg.gui"); exec("~/ui/MessageBoxOkDlg.gui"); exec("~/ui/MessageBoxYesNoDlg.gui"); exec("~/ui/MessageBoxOKCancelDlg.gui"); exec("~/ui/MessagePopupDlg.gui"); exec("~/ui/HelpDlg.gui");

// Commonly used helper scripts exec("./metrics.cs"); exec("./messageBox.cs"); exec("./screenshot.cs"); exec("./cursor.cs"); exec("./help.cs");

// Init the audio system OpenALInit();}

function resetCanvas(){ if (isObject(Canvas)) { Canvas.repaint(); }}

//-----------------------------------------------------------------------------// centerPrint.cs fps\server\scripts\// //-----------------------------------------------------------------------------

function centerPrintAll( %message, %time, %lines ){ if( %lines $= "" || ((%lines > 3) || (%lines < 1)) )

53

Page 54:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%lines = 1; %count = ClientGroup.getCount(); for (%i = 0; %i < %count; %i++)

{%cl = ClientGroup.getObject(%i);

if( !%cl.isAIControlled() ) commandToClient( %cl, 'centerPrint', %message, %time, %lines ); }}

function bottomPrintAll( %message, %time, %lines ){ if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) %lines = 1; %count = ClientGroup.getCount();

for (%i = 0; %i < %count; %i++){

%cl = ClientGroup.getObject(%i); if( !%cl.isAIControlled() ) commandToClient( %cl, 'bottomPrint', %message, %time, %lines ); }}

//-------------------------------------------------------------------------------------------------------

function centerPrint( %client, %message, %time, %lines ){ if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) %lines = 1; commandToClient( %client, 'CenterPrint', %message, %time, %lines );}

function bottomPrint( %client, %message, %time, %lines ){ if( %lines $= "" || ((%lines > 3) || (%lines < 1)) ) %lines = 1;

commandToClient( %client, 'BottomPrint', %message, %time, %lines );}

//-------------------------------------------------------------------------------------------------------

function clearCenterPrint( %client ){ commandToClient( %client, 'ClearCenterPrint');}

function clearBottomPrint( %client ){ commandToClient( %client, 'ClearBottomPrint');}

54

Page 55:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-------------------------------------------------------------------------------------------------------

function clearCenterPrintAll(){

%count = ClientGroup.getCount();for (%i = 0; %i < %count; %i++){

%cl = ClientGroup.getObject(%i); if( !%cl.isAIControlled() ) commandToClient( %cl, 'ClearCenterPrint'); }}

function clearBottomPrintAll(){

%count = ClientGroup.getCount();for (%i = 0; %i < %count; %i++){

%cl = ClientGroup.getObject(%i); if( !%cl.isAIControlled() ) commandToClient( %cl, 'ClearBottomPrint'); }}

//-----------------------------------------------------------------------------// centerPrint.cs fps\client\scripts\// //-----------------------------------------------------------------------------

$centerPrintActive = 0;$bottomPrintActive = 0;

// Selectable window sizes$CenterPrintSizes[1] = 20;$CenterPrintSizes[2] = 36;$CenterPrintSizes[3] = 56;

// time is specified in secondsfunction clientCmdCenterPrint( %message, %time, %size ){ // if centerprint already visible, reset text and time. if ($centerPrintActive) { if (centerPrintDlg.removePrint !$= "") cancel(centerPrintDlg.removePrint); } else { CenterPrintDlg.visible = 1; $centerPrintActive = 1; }

CenterPrintText.setText( "<just:center>" @ %message ); CenterPrintDlg.extent = firstWord(CenterPrintDlg.extent) @ " " @ $CenterPrintSizes[%size];

55

Page 56:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if (%time > 0) centerPrintDlg.removePrint = schedule( ( %time * 1000 ), 0, "clientCmdClearCenterPrint" );}

// time is specified in secondsfunction clientCmdBottomPrint( %message, %time, %size ){ // if bottomprint already visible, reset text and time. if ($bottomPrintActive) { if( bottomPrintDlg.removePrint !$= "") cancel(bottomPrintDlg.removePrint); } else { bottomPrintDlg.setVisible(true); $bottomPrintActive = 1; } bottomPrintText.setText( "<just:center>" @ %message ); bottomPrintDlg.extent = firstWord(bottomPrintDlg.extent) @ " " @ $CenterPrintSizes[%size];

if (%time > 0) bottomPrintDlg.removePrint = schedule( ( %time * 1000 ), 0, "clientCmdClearbottomPrint" );}

function BottomPrintText::onResize(%this, %width, %height){ %this.position = "0 0";}

function CenterPrintText::onResize(%this, %width, %height){ %this.position = "0 0";}

//-------------------------------------------------------------------------------------------------------

function clientCmdClearCenterPrint(){ $centerPrintActive = 0; CenterPrintDlg.visible = 0; CenterPrintDlg.removePrint = "";}

function clientCmdClearBottomPrint(){ $bottomPrintActive = 0; BottomPrintDlg.visible = 0; BottomPrintDlg.removePrint = "";}

//-----------------------------------------------------------------------------

56

Page 57:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// chatHud.cs - fps\client\scripts\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Message Hud//-----------------------------------------------------------------------------

// chat hud sizes$outerChatLenY[1] = 72;$outerChatLenY[2] = 140;$outerChatLenY[3] = 200;

// All messages are stored in this HudMessageVector, the actual// MainChatHud only displays the contents of this vector.

new MessageVector(HudMessageVector);$LastHudTarget = 0;

//-----------------------------------------------------------------------------// The base client support in common processes messages from the server// but will the following message handlers for display.

function onServerMessage(%text){ // General server message, dump it to the message hud. ChatHud.addLine(%text);}

function onChatMessage(%text){ // Chat goes to our chat hud! ChatHud.addLine(%text);}

//-----------------------------------------------------------------------------// MainChatHud methods//-----------------------------------------------------------------------------

function MainChatHud::onWake( %this ){ // set the chat hud to the users pref %this.setChatHudLength( $Pref::ChatHudLength );}

//------------------------------------------------------------------------------

57

Page 58:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function MainChatHud::setChatHudLength( %this, %length ){ %outerChatLenX = firstWord(outerChatHud.extent); %chatScrollLenX = firstWord(chatScrollHud.extent);

outerChatHud.extent = %outerChatLenX SPC $outerChatLenY[%length]; chatScrollHud.extent = %chatScrollLenX SPC $outerChatLenY[%length];

//find out how many lines per page are visible %chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1); if (%chatScrollHeight <= 0) return;

%textHeight = chatHud.profile.fontSize; if (%textHeight <= 0) %textHeight = 12;

%pageLines = mFloor(%chatScrollHeight / %textHeight); if (%pageLines <= 0) %pageLines = 1;

// Put the last line at the bottom. %pos = HudMessageVector.getNumLines() - %pageLines; if (%pos < 0) %pos = 0; ChatHud.position = "0" SPC (-1 * %pos * %textHeight);

ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1)); ChatPageDown.position = (firstWord(outerChatHud.extent) - firstWord(ChatPageDown.extent)) SPC ($outerChatLenY[%length] - getWord(ChatPageDown.extent, 1)); ChatPageDown.setVisible(false);}

//------------------------------------------------------------------------------

function MainChatHud::nextChatHudLen( %this ){ %len = $pref::ChatHudLength++; if ($pref::ChatHudLength == 4) $pref::ChatHudLength = 1; %this.setChatHudLength($pref::ChatHudLength);}

//-----------------------------------------------------------------------------// ChatHud methods// This is the actual message vector/text control which is part of// the MainChatHud dialog//-----------------------------------------------------------------------------

58

Page 59:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function ChatHud::addLine(%this,%text){ //first, see if we're "scrolled up"... %textHeight = %this.profile.fontSize; if (%textHeight <= 0) %textHeight = 12; %chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1); %chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1); %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); if (%linesToScroll > 0) %origPosition = %this.position; //add the message... while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize)) { %tag = HudMessageVector.getLineTag(0); if(%tag != 0) %tag.delete(); HudMessageVector.popFrontLine(); } HudMessageVector.pushBackLine(%text, $LastHudTarget); $LastHudTarget = 0;

//now that we've added the message, see if we need to reset the position if (%linesToScroll > 0) { chatPageDown.setVisible(true); %this.position = %origPosition; } else chatPageDown.setVisible(false);}

//-----------------------------------------------------------------------------

function ChatHud::pageUp(%this){ // Find out the text line height %textHeight = %this.profile.fontSize; if (%textHeight <= 0) %textHeight = 12;

// Find out how many lines per page are visible %chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1); if (%chatScrollHeight <= 0) return;

%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; if (%pageLines <= 0)

59

Page 60:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%pageLines = 1;

// See how many lines we actually can scroll up: %chatPosition = -1 * getWord(%this.position, 1); %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); if (%linesToScroll <= 0) return;

if (%linesToScroll > %pageLines) %scrollLines = %pageLines; else %scrollLines = %linesToScroll;

// Now set the position %this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) + (%scrollLines * %textHeight));

// Display the pageup icon chatPageDown.setVisible(true);}

//-----------------------------------------------------------------------------

function ChatHud::pageDown(%this){ // Find out the text line height %textHeight = %this.profile.fontSize; if (%textHeight <= 0) %textHeight = 12;

// Find out how many lines per page are visible %chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1); if (%chatScrollHeight <= 0) return;

%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; if (%pageLines <= 0) %pageLines = 1;

// See how many lines we actually can scroll down: %chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1); %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5); if (%linesToScroll <= 0) return;

if (%linesToScroll > %pageLines) %scrollLines = %pageLines; else %scrollLines = %linesToScroll;

// Now set the position %this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) - (%scrollLines * %textHeight));

60

Page 61:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// See if we have should (still) display the pagedown icon if (%scrollLines < %linesToScroll) chatPageDown.setVisible(true); else chatPageDown.setVisible(false);}

//-----------------------------------------------------------------------------// Support functions//-----------------------------------------------------------------------------

function pageUpMessageHud(){ ChatHud.pageUp();}

function pageDownMessageHud(){ ChatHud.pageDown();}

function cycleMessageHudSize(){ MainChatHud.nextChatHudLen();}

//-----------------------------------------------------------------------------// client.cs – fps\client\scripts.cs// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Server Admin Commands//-----------------------------------------------------------------------------

function SAD(%password){ if (%password !$= "") commandToServer('SAD', %password);}

function SADSetPassword(%password){ commandToServer('SADSetPassword', %password);}

//----------------------------------------------------------------------------// Misc server commands

61

Page 62:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//----------------------------------------------------------------------------

function clientCmdSyncClock(%time){ // Store the base time in the hud control it will automatically increment. HudClock.setTime(%time);}

//-----------------------------------------------------------------------------// clientconnection.cs – common\server\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// This script function is the first called on a client accept//function GameConnection::onConnect( %client, %name ){ // Send down the connection error info, the client is // responsible for displaying this message if a connection // error occures. messageClient(%client,'MsgConnectionError',"",$Pref::Server::ConnectionError);

// Send mission information to the client sendLoadInfoToClient( %client );

// Simulated client lag for testing... // %client.setSimulatedNetParams(0.1, 30);

// if hosting this server, set this client to superAdmin if (%client.getAddress() $= "local") { %client.isAdmin = true; %client.isSuperAdmin = true; }

// Get the client's unique id: // %authInfo = %client.getAuthInfo(); // %client.guid = getField( %authInfo, 3 ); %client.guid = 0; addToServerGuidList( %client.guid ); // Set admin status %client.isAdmin = false; %client.isSuperAdmin = false;

// Save client preferences on the connection object for later use. %client.gender = "Male"; %client.armor = "Light"; %client.race = "Human"; %client.skin = addTaggedString( "base" );

62

Page 63:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%client.setPlayerName(%name); %client.score = 0;

// $instantGroup = ServerGroup; $instantGroup = MissionCleanup; echo("CADD: " @ %client @ " " @ %client.getAddress());

// Inform the client of all the other clients %count = ClientGroup.getCount(); for (%cl = 0; %cl < %count; %cl++) { %other = ClientGroup.getObject(%cl); if ((%other != %client)) { // These should be "silent" versions of these messages... messageClient(%client, 'MsgClientJoin', "", %other.name, %other, %other.sendGuid, %other.score, %other.isAIControlled(), %other.isAdmin, %other.isSuperAdmin); } }

// Inform the client we've joined up messageClient(%client, 'MsgClientJoin', '\c2Welcome aboard %1, we were just about to shove off!.', %client.name, %client, %client.sendGuid, %client.score, %client.isAiControlled(), %client.isAdmin, %client.isSuperAdmin);

// Inform all the other clients of the new guy messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.', %client.name, %client, %client.sendGuid, %client.score, %client.isAiControlled(), %client.isAdmin, %client.isSuperAdmin);

// If the mission is running, go ahead download it to the client if ($missionRunning) %client.loadMission(); $Server::PlayerCount++;}

//-----------------------------------------------------------------------------// A player's name could be obtained from the auth server, but for

63

Page 64:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// now we use the one passed from the client.// %realName = getField( %authInfo, 0 );//function GameConnection::setPlayerName(%client,%name){ %client.sendGuid = 0;

// Minimum length requirements %name = stripTrailingSpaces( strToPlayerName( %name ) ); if ( strlen( %name ) < 3 ) %name = "ScallyWag!";

// Make sure the alias is unique, we'll hit something eventually if (!isNameUnique(%name)) { %isUnique = false; for (%suffix = 1; !%isUnique; %suffix++) { %nameTry = %name @ "." @ %suffix; %isUnique = isNameUnique(%nameTry); } %name = %nameTry; }

// Tag the name with the "smurf" color: %client.nameBase = %name; %client.name = addTaggedString("\cp\c8" @ %name @ "\co");}

function isNameUnique(%name){ %count = ClientGroup.getCount(); for ( %i = 0; %i < %count; %i++ ) { %test = ClientGroup.getObject( %i ); %rawName = stripChars( detag( getTaggedString( %test.name ) ), "\cp\co\c6\c7\c8\c9" ); if ( strcmp( %name, %rawName ) == 0 ) return false; } return true;}

//-----------------------------------------------------------------------------// This function is called when a client drops for any reason//function GameConnection::onDrop(%client, %reason){ %client.onClientLeaveGame(); removeFromServerGuidList( %client.guid ); messageAllExcept(%client, -1, 'MsgClientDrop', '\c1%1 has left the game.', %client.name, %client);

removeTaggedString(%client.name); echo("CDROP: " @ %client @ " " @ %client.getAddress()); $Server::PlayerCount--;

64

Page 65:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// Reset the server if everyone has left the game if( $Server::PlayerCount == 0 && $Server::Dedicated) schedule(0, 0, "resetServerDefaults");}

//-----------------------------------------------------------------------------

function GameConnection::startMission(%this){ // Inform the client the mission starting commandToClient(%this, 'MissionStart', $missionSequence);}

function GameConnection::endMission(%this){ // Inform the client the mission is done commandToClient(%this, 'MissionEnd', $missionSequence);}

//--------------------------------------------------------------------------// Sync the clock on the client.

function GameConnection::syncClock(%client, %time){ commandToClient(%client, 'syncClock', %time);}

//--------------------------------------------------------------------------// Update all the clients with the new score

function GameConnection::incScore(%this,%delta){ %this.score += %delta; messageAll('MsgClientScoreChanged', "", %this.score, %this);}

//-----------------------------------------------------------------------------// commands.cs – common\server\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Misc. server commands avialable to clients//-----------------------------------------------------------------------------

65

Page 66:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function serverCmdSAD( %client, %password ){ if( %password !$= "" && %password $= $Pref::Server::AdminPassword) { %client.isAdmin = true; %client.isSuperAdmin = true; %name = getTaggedString( %client.name ); MessageAll( 'MsgAdminForce', "\c2" @ %name @ " has become Admin by force.", %client ); }}

function serverCmdSADSetPassword(%client, %password){ if(%client.isSuperAdmin) $Pref::Server::AdminPassword = %password;}

//----------------------------------------------------------------------------// Server chat message handlers

function serverCmdTeamMessageSent(%client, %text){ if(strlen(%text) >= $Pref::Server::MaxChatLen) %text = getSubStr(%text, 0, $Pref::Server::MaxChatLen); chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.name, %text);}

function serverCmdMessageSent(%client, %text){ if(strlen(%text) >= $Pref::Server::MaxChatLen) %text = getSubStr(%text, 0, $Pref::Server::MaxChatLen); chatMessageAll(%client, '\c4%1: %2', %client.name, %text);}

//-----------------------------------------------------------------------------// commands.cs - fps\server\scripts\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Misc. server commands avialable to clients//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

66

Page 67:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function serverCmdToggleCamera(%client){ if ($Server::TestCheats || $Server::ServerType $= "SinglePlayer") { %control = %client.getControlObject(); if (%control == %client.player) { %control = %client.camera; %control.mode = toggleCameraFly; } else { %control = %client.player; %control.mode = observerFly; } %client.setControlObject(%control); }}

function serverCmdDropPlayerAtCamera(%client){ if ($Server::TestCheats) { %client.player.setTransform(%client.camera.getTransform()); %client.player.setVelocity("0 0 0"); %client.setControlObject(%client.player); }}

function serverCmdDropCameraAtPlayer(%client){ if ($Server::TestCheats) { %client.camera.setTransform(%client.player.getEyeTransform()); %client.camera.setVelocity("0 0 0"); %client.setControlObject(%client.camera); }}

//-----------------------------------------------------------------------------

function serverCmdSuicide(%client){ %client.player.kill("Suicide");}

function serverCmdPlayCel(%client,%anim){ if (isObject(%client.player)) %client.player.playCelAnimation(%anim);}

function serverCmdPlayDeath(%client){ if (isObject(%client.player)) %client.player.playDeathAnimation();

67

Page 68:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

//-----------------------------------------------------------------------------// AWfunction serverCmdJoinTeam(%client, %teamid){ echo("Join Team Server Command Called"); %client.joinTeam(%teamid);}

function serverCmdMountDriver(%client){

if(%client.player.mountNode0) { messageClient(%client, 'MountMsg', '\c0You will no longer mount at the Helm.'); %client.player.mountNode0 = false; } else { messageClient(%client, 'MountMsg', '\c0You will now mount at the Helm.'); %client.player.mountNode0 = true; %client.player.mountNode1 = false; %client.player.mountNode10 = false; } }function serverCmdMountNest(%client){

if(%client.player.mountNode1) { messageClient(%client, 'MountMsg', '\c0You will no longer mount in the Crows Nest.'); %client.player.mountNode1 = false; } else { messageClient(%client, 'MountMsg', '\c0You will now mount in the Crows Nest.'); %client.player.mountNode1 = true; %client.player.mountNode0 = false; %client.player.mountNode10 = false; }

}function serverCmdMountCannon(%client){

if(%client.player.mountNode10) { messageClient(%client, 'MountMsg', '\c0You will no longer mount at the Cannon.');

68

Page 69:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%client.player.mountNode10 = false; } else { messageClient(%client, 'MountMsg', '\c0You will now mount at the Cannon.');

%client.player.mountNode10 = true; %client.player.mountNode0 = false; %client.player.mountNode1 = false; }}// AW End

//-----------------------------------------------------------------------------// config.cs - fps\client\// //-----------------------------------------------------------------------------

moveMap.delete();new ActionMap(moveMap);moveMap.bindCmd(keyboard, "escape", "", "escapeFromGame();");moveMap.bindCmd(keyboard, "f2", "", "PlayerListGui.toggle();");moveMap.bind(keyboard, "a", moveleft);moveMap.bind(keyboard, "d", moveright);moveMap.bind(keyboard, "w", moveForward);moveMap.bind(keyboard, "s", movebackward);moveMap.bind(keyboard, "space", jump);moveMap.bind(keyboard, "r", setZoomFOV);moveMap.bind(keyboard, "e", toggleZoom);moveMap.bind(keyboard, "z", toggleFreeLook);moveMap.bind(keyboard, "tab", toggleFirstPerson);moveMap.bind(keyboard, "alt c", toggleCamera);moveMap.bindCmd(keyboard, "ctrl w", "commandToServer(\'playCel\',\"wave\");", "");moveMap.bindCmd(keyboard, "ctrl s", "commandToServer(\'playCel\',\"salute\");", "");moveMap.bindCmd(keyboard, "ctrl k", "commandToServer(\'suicide\');", "");moveMap.bindCmd(keyboard, "ctrl b", "commandToServer(\'MountDriver\');", "");moveMap.bindCmd(keyboard, "ctrl n", "commandToServer(\'MountNest\');", "");moveMap.bindCmd(keyboard, "ctrl m", "commandToServer(\'MountCannon\');", "");moveMap.bindCmd(keyboard, "h", "commandToServer(\'use\',\"HealthKit\");", "");moveMap.bindCmd(keyboard, "1", "commandToServer(\'use\',\"Crossbow\");", "");moveMap.bindCmd(keyboard, "2", "commandToServer(\'use\',\"Cannon\");", "");moveMap.bindCmd(keyboard, "l", "Canvas.pushDialog(TeamSelectDlg);", "");moveMap.bind(keyboard, "u", toggleMessageHud);moveMap.bind(keyboard, "pageup", pageMessageHudUp);

69

Page 70:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

moveMap.bind(keyboard, "pagedown", pageMessageHudDown);moveMap.bind(keyboard, "p", resizeMessageHud);moveMap.bind(keyboard, "f8", dropCameraAtPlayer);moveMap.bind(keyboard, "f7", dropPlayerAtCamera);moveMap.bind(mouse0, "xaxis", yaw);moveMap.bind(mouse0, "yaxis", pitch);moveMap.bind(mouse0, "button0", mouseFire);

//-----------------------------------------------------------------------------// crossbow.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Crossbow weapon. This file contains all the items related to this weapon// including explosions, ammo, the item and the weapon item image.// These objects rely on the item & inventory support system defined// in item.cs and inventory.cs//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Sounds profiles

datablock AudioProfile(CrossbowReloadSound){ filename = "~/data/sound/fx/crossbow_reload.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(CrossbowFireSound){ filename = "~/data/sound/fx/crossbow_firing.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(CrossbowFireEmptySound){ filename = "~/data/sound/fx/crossbow_firing_empty.wav"; description = AudioClose3d; preload = true;};

datablock AudioProfile(CrossbowExplosionSound){ filename = "~/data/sound/fx/crossbow_explosion.wav"; description = AudioDefault3d; preload = true;};

70

Page 71:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// Crossbow bolt projectile particles

datablock ParticleData(CrossbowBoltParticle){ textureName = "~/data/shapes/particles/smoke"; dragCoeffiecient = 0.0; gravityCoefficient = -0.2; // rises slowly inheritedVelFactor = 0.00; lifetimeMS = 500; // lasts 0.7 second lifetimeVarianceMS = 150; // ...more or less useInvAlpha = false; spinRandomMin = -30.0; spinRandomMax = 30.0;

colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 1.0"; colors[2] = "0 0 0 0";

sizes[0] = 0.25; sizes[1] = 0.5; sizes[2] = 1.0;

times[0] = 0.0; times[1] = 0.3; times[2] = 1.0;};

datablock ParticleEmitterData(CrossbowBoltEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 5;

ejectionVelocity = 0.25; velocityVariance = 0.10;

thetaMin = 0.0; thetaMax = 90.0;

particles = CrossbowBoltParticle;};

//-----------------------------------------------------------------------------// Projectile Explosion

datablock ParticleData(CrossbowExplosionParticle){ textureName = "~/data/shapes/particles/smoke"; dragCoefficient = 2; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 1000;

71

Page 72:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

lifetimeVarianceMS = 150;

colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 0.0";

sizes[0] = 0.5; sizes[1] = 1.0;};

datablock ParticleEmitterData(CrossbowExplosionEmitter){ ejectionPeriodMS = 7; periodVarianceMS = 0; ejectionVelocity = 2; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "CrossbowExplosionParticle";};

datablock ParticleData(CrossbowExplosionSmoke){ textureName = "~/data/shapes/particles/smoke"; dragCoeffiecient = 100.0; gravityCoefficient = 0; inheritedVelFactor = 0.25; constantAcceleration = -0.80; lifetimeMS = 1200; lifetimeVarianceMS = 300; useInvAlpha = true; spinRandomMin = -80.0; spinRandomMax = 80.0;

colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.2 0.2 0.2 1.0"; colors[2] = "0.0 0.0 0.0 0.0";

sizes[0] = 1.0; sizes[1] = 1.5; sizes[2] = 2.0;

times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;

};

datablock ParticleEmitterData(CrossbowExplosionSmokeEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 4; velocityVariance = 0.5;

72

Page 73:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

thetaMin = 0.0; thetaMax = 180.0; lifetimeMS = 250; particles = "CrossbowExplosionSmoke";};

datablock ParticleData(CrossbowExplosionSparks){ textureName = "~/data/shapes/particles/spark"; dragCoefficient = 1; gravityCoefficient = 0.0; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 500; lifetimeVarianceMS = 350;

colors[0] = "0.60 0.40 0.30 1.0"; colors[1] = "0.60 0.40 0.30 1.0"; colors[2] = "1.0 0.40 0.30 0.0";

sizes[0] = 0.5; sizes[1] = 0.25; sizes[2] = 0.25;

times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData(CrossbowExplosionSparkEmitter){ ejectionPeriodMS = 3; periodVarianceMS = 0; ejectionVelocity = 13; velocityVariance = 6.75; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 180; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 100; particles = "CrossbowExplosionSparks";};

datablock ExplosionData(CrossbowSubExplosion1){ offset = 1.0; emitter[0] = CrossbowExplosionSmokeEmitter; emitter[1] = CrossbowExplosionSparkEmitter;};

datablock ExplosionData(CrossbowSubExplosion2){ offset = 1.0; emitter[0] = CrossbowExplosionSmokeEmitter;

73

Page 74:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

emitter[1] = CrossbowExplosionSparkEmitter;};

datablock ExplosionData(CrossbowExplosion){ soundProfile = CrossbowExplosionSound; lifeTimeMS = 1200;

// Volume particles particleEmitter = CrossbowExplosionEmitter; particleDensity = 80; particleRadius = 1;

// Point emission emitter[0] = CrossbowExplosionSmokeEmitter; emitter[1] = CrossbowExplosionSparkEmitter;

// Sub explosion objects subExplosion[0] = CrossbowSubExplosion1; subExplosion[1] = CrossbowSubExplosion2; // Camera Shaking shakeCamera = true; camShakeFreq = "10.0 11.0 10.0"; camShakeAmp = "1.0 1.0 1.0"; camShakeDuration = 0.5; camShakeRadius = 10.0;

// Dynamic light lightStartRadius = 6; lightEndRadius = 3; lightStartColor = "0.5 0.5 0"; lightEndColor = "0 0 0";};

//-----------------------------------------------------------------------------// Projectile Object

datablock ProjectileData(CrossbowProjectile){ projectileShapeName = "~/data/shapes/crossbow/projectile.dts"; directDamage = 20; radiusDamage = 20; damageRadius = 1.5; explosion = CrossbowExplosion; particleEmitter = CrossbowBoltEmitter;

muzzleVelocity = 100; velInheritFactor = 0.3;

armingDelay = 0; lifetime = 5000; fadeDelay = 5000; bounceElasticity = 0; bounceFriction = 0;

74

Page 75:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

isBallistic = true; gravityMod = 0.80;

hasLight = true; lightRadius = 4.0; lightColor = "0.5 0.5 0";};

function CrossbowProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal){ // Apply damage to the object all shape base objects if (%col.getType() & $TypeMasks::ShapeBaseObjectType) %col.damage(%obj,%pos,%this.directDamage,"CrossbowBolt");

// Radius damage is a support scripts defined in radiusDamage.cs radiusDamage(%obj,%pos,%this.damageRadius,%this.radiusDamage,"CrossbowBolt",0);}

//-----------------------------------------------------------------------------// Ammo Item

datablock ItemData(CrossbowAmmo){ // Mission editor category category = "Ammo";

// Add the Ammo namespace as a parent. The ammo namespace provides // common ammo related functions and hooks into the inventory system. className = "Ammo";

// Basic Item properties shapeFile = "~/data/shapes/crossbow/ammo.dts"; mass = 1; elasticity = 0.2; friction = 0.6;

// Dynamic properties defined by the scriptspickUpName = "crossbow bolts";

maxInventory = 20;};

//--------------------------------------------------------------------------// Weapon Item. This is the item that exists in the world, i.e. when it's// been dropped, thrown or is acting as re-spawnable item. When the weapon// is mounted onto a shape, the CrossbowImage is used.

datablock ItemData(Crossbow){ // Mission editor category

75

Page 76:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

category = "Weapon";

// Hook into Item Weapon class hierarchy. The weapon namespace // provides common weapon handling functions in addition to hooks // into the inventory system. className = "Weapon";

// Basic Item properties shapeFile = "~/data/shapes/crossbow/weapon.dts"; mass = 1; elasticity = 0.2; friction = 0.6; emap = true;

// Dynamic properties defined by the scriptspickUpName = "a crossbow";image = CrossbowImage;

};

//--------------------------------------------------------------------------// Crossbow image which does all the work. Images do not normally exist in// the world, they can only be mounted on ShapeBase objects.

datablock ShapeBaseImageData(CrossbowImage){ // Basic Item properties shapeFile = "~/data/shapes/crossbow/weapon.dts"; emap = true;

// Specify mount point & offset for 3rd person, and eye offset // for first person rendering. mountPoint = 0; eyeOffset = "0.1 0.4 -0.6";

// When firing from a point offset from the eye, muzzle correction // will adjust the muzzle vector to point to the eye LOS point. // Since this weapon doesn't actually fire from the muzzle point, // we need to turn this off. correctMuzzleVector = false;

// Add the WeaponImage namespace as a parent, WeaponImage namespace // provides some hooks into the inventory system. className = "WeaponImage";

// Projectile && Ammo. item = Crossbow; ammo = CrossbowAmmo; projectile = CrossbowProjectile; projectileType = Projectile;

// Images have a state system which controls how the animations // are run, which sounds are played, script callbacks, etc. This // state system is downloaded to the client so that clients can // predict state changes and animate accordingly. The following

76

Page 77:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// system supports basic ready->fire->reload transitions as // well as a no-ammo->dryfire idle state.

// Initial start up state stateName[0] = "Preactivate"; stateTransitionOnLoaded[0] = "Activate"; stateTransitionOnNoAmmo[0] = "NoAmmo";

// Activating the gun. Called when the weapon is first // mounted and there is ammo. stateName[1] = "Activate"; stateTransitionOnTimeout[1] = "Ready"; stateTimeoutValue[1] = 0.6; stateSequence[1] = "Activate";

// Ready to fire, just waiting for the trigger stateName[2] = "Ready"; stateTransitionOnNoAmmo[2] = "NoAmmo"; stateTransitionOnTriggerDown[2] = "Fire";

// Fire the weapon. Calls the fire script which does // the actual work. stateName[3] = "Fire"; stateTransitionOnTimeout[3] = "Reload"; stateTimeoutValue[3] = 0.2; stateFire[3] = true; stateRecoil[3] = LightRecoil; stateAllowImageChange[3] = false; stateSequence[3] = "Fire"; stateScript[3] = "onFire"; stateSound[3] = CrossbowFireSound;

// Play the relead animation, and transition into stateName[4] = "Reload"; stateTransitionOnNoAmmo[4] = "NoAmmo"; stateTransitionOnTimeout[4] = "Ready"; stateTimeoutValue[4] = 0.8; stateAllowImageChange[4] = false; stateSequence[4] = "Reload"; stateEjectShell[4] = true; stateSound[4] = CrossbowReloadSound;

// No ammo in the weapon, just idle until something // shows up. Play the dry fire sound if the trigger is // pulled. stateName[5] = "NoAmmo"; stateTransitionOnAmmo[5] = "Reload"; stateSequence[5] = "NoAmmo"; stateTransitionOnTriggerDown[5] = "DryFire";

// No ammo dry fire stateName[6] = "DryFire"; stateTimeoutValue[6] = 1.0; stateTransitionOnTimeout[6] = "NoAmmo"; stateSound[6] = CrossbowFireEmptySound;};

77

Page 78:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function CrossbowImage::onFire(%this, %obj, %slot){ %projectile = %this.projectile;

// Decrement inventory ammo. The image's ammo state is update // automatically by the ammo inventory hooks. %obj.decInventory(%this.ammo,1);

// Determin initial projectile velocity based on the // gun's muzzle point and the object's current velocity %muzzleVector = %obj.getMuzzleVector(%slot); %objectVelocity = %obj.getVelocity(); %muzzleVelocity = VectorAdd( VectorScale(%muzzleVector, %projectile.muzzleVelocity), VectorScale(%objectVelocity, %projectile.velInheritFactor));

// Create the projectile object %p = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%p); return %p;}

//-----------------------------------------------------------------------------// cursor.cs – common\client\// //-----------------------------------------------------------------------------

//------------------------------------------------------------------------------// Cursor Control//------------------------------------------------------------------------------

$cursorControlled = true;

function cursorOff(){ if ( $cursorControlled ) lockMouse(true); Canvas.cursorOff();}

function cursorOn(){

78

Page 79:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if ( $cursorControlled ) lockMouse(false); Canvas.cursorOn(); Canvas.setCursor(DefaultCursor); }

// In the CanvasCursor package we add some additional functionality to the// built-in GuiCanvas class, of which the global Canvas object is an instance.// In this case, the behavior we want is for the cursor to automatically display,// except when the only guis visible want no cursor - most notably,// in the case of the example, the play gui.// In order to override or extend an existing class, we use the script package// feature.

package CanvasCursor{

// The checkCursor method iterates through all the root controls on the canvas// (basically the content control and any visible dialogs). If all of them// have the .noCursor attribute set, the cursor is turned off, otherwise it is// turned on.

function GuiCanvas::checkCursor(%this){ %cursorShouldBeOn = false; for(%i = 0; %i < %this.getCount(); %i++) { %control = %this.getObject(%i); if(%control.noCursor $= "") { %cursorShouldBeOn = true; break; } } if(%cursorShouldBeOn != %this.isCursorOn()) { if(%cursorShouldBeOn) cursorOn(); else cursorOff(); }}

// below, all functions which can alter which content controls are visible// are extended to call the checkCursor function. For package'd functions,// the Parent:: call refers to the original implementation of that function,// or a version that was declared in a previously activated package.

79

Page 80:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// In this case the parent calls should point to the built in versions// of GuiCanvas functions.

function GuiCanvas::setContent(%this, %ctrl){ Parent::setContent(%this, %ctrl); %this.checkCursor();}

function GuiCanvas::pushDialog(%this, %ctrl){ Parent::pushDialog(%this, %ctrl); %this.checkCursor();}

function GuiCanvas::popDialog(%this, %ctrl){ Parent::popDialog(%this, %ctrl); %this.checkCursor();}

function GuiCanvas::popLayer(%this, %layer){ Parent::popLayer(%this, %layer); %this.checkCursor();}

};

// activate the package when the script loads.activatePackage(CanvasCursor);

//-----------------------------------------------------------------------------// cursor.cs – common\editor\// //-----------------------------------------------------------------------------

//------------------------------------------------------------------------------// Editor Cursors//------------------------------------------------------------------------------

new GuiCursor(EditorHandCursor){ hotSpot = "7 0"; bitmapName = "./CUR_hand.png";};

new GuiCursor(EditorRotateCursor){ hotSpot = "11 18"; bitmapName = "./CUR_rotate.png";};

80

Page 81:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

new GuiCursor(EditorMoveCursor){ hotSpot = "9 13"; bitmapName = "./CUR_grab.png";};

new GuiCursor(EditorArrowCursor){ hotSpot = "0 0"; bitmapName = "./CUR_3darrow.png";};

new GuiCursor(EditorUpDownCursor){ hotSpot = "5 10"; bitmapName = "./CUR_3dupdown";};new GuiCursor(EditorLeftRightCursor){ hotSpot = "9 5"; bitmapName = "./CUR_3dleftright";};

new GuiCursor(EditorDiagRightCursor){ hotSpot = "8 8"; bitmapName = "./CUR_3ddiagright";};

new GuiCursor(EditorDiagLeftCursor){ hotSpot = "8 8"; bitmapName = "./CUR_3ddiagleft";};

new GuiControl(EmptyControl){ profile = "GuiButtonProfile";};

// debugger is just a simple TCP objectif (!isObject(TCPDebugger))

new TCPObject(TCPDebugger);

//--------------------------------------------------------------// debugger.cs – common\debugger\//--------------------------------------------------------------

function DebuggerConsoleView::print(%this, %line){ %row = %this.addRow(0, %line); %this.scrollVisible(%row);}

function TCPDebugger::onLine(%this, %line){

81

Page 82:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

echo("Got line=>" @ %line); %cmd = firstWord(%line); %rest = restWords(%line); if(%cmd $= "PASS") %this.handlePass(%rest); else if(%cmd $= "COUT") %this.handleLineOut(%rest); else if(%cmd $= "FILELISTOUT") %this.handleFileList(%rest); else if(%cmd $= "BREAKLISTOUT") %this.handleBreakList(%rest); else if(%cmd $= "BREAK") %this.handleBreak(%rest); else if(%cmd $= "RUNNING") %this.handleRunning(); else if(%cmd $= "EVALOUT") %this.handleEvalOut(%rest); else if(%cmd $= "OBJTAGLISTOUT") %this.handleObjTagList(%rest); else %this.handleError(%line); }

//--------------------------------------------------------------// handlers for messages from the server//--------------------------------------------------------------

function TCPDebugger::handlePass(%this, %message){ if(%message $= "WrongPass") { DebuggerConsoleView.print("Disconnected - wrong password."); %this.disconnect(); } else if(%message $= "Connected.") { DebuggerConsoleView.print("Connected."); DebuggerStatus.setValue("CONNECTED"); %this.send("FILELIST\r\n"); }}

function TCPDebugger::handleLineOut(%this, %line){ DebuggerConsoleView.print(%line);}

function TCPDebugger::handleFileList(%this, %line){ DebuggerFilePopup.clear(); %word = 0; while((%file = getWord(%line, %word)) !$= "") { %word++; DebuggerFilePopup.add(%file, %word); }

82

Page 83:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

function TCPDebugger::handleBreakList(%this, %line){ %file = getWord(%line, 0); if(%file != $DebuggerFile) return; %pairs = getWord(%line, 1); %curLine = 1; DebuggerFileView.clearBreakPositions();

//set the possible break positions for(%i = 0; %i < %pairs; %i++) { %skip = getWord(%line, %i * 2 + 2); %breaks = getWord(%line, %i * 2 + 3); %curLine += %skip; for(%j = 0; %j < %breaks; %j++) { DebuggerFileView.setBreakPosition(%curLine); %curLine++; } }

//now set the actual break points...for (%i = 0; %i < DebuggerBreakPoints.rowCount(); %i++){

%breakText = DebuggerBreakPoints.getRowText(%i);%breakLine = getField(%breakText, 0);%breakFile = getField(%breakText, 1);if (%breakFile == $DebuggerFile)

DebuggerFileView.setBreak(%breakLine);}

}

function TCPDebugger::handleBreak(%this, %line){ DebuggerStatus.setValue("BREAK"); // query all the watches for(%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { %id = DebuggerWatchView.getRowId(%i); %row = DebuggerWatchView.getRowTextById(%id); %expr = getField(%row, 0); %this.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); }

// update the call stack window DebuggerCallStack.clear();

%file = getWord(%line, 0); %lineNumber = getWord(%line, 1); %funcName = getWord(%line, 2); DbgOpenFile(%file, %lineNumber, true);

83

Page 84:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%nextWord = 3; %rowId = 0; %id = 0; while(1) { DebuggerCallStack.setRowById(%id, %file @ "\t" @ %lineNumber @ "\t" @ %funcName); %id++; %file = getWord(%line, %nextWord); %lineNumber = getWord(%line, %nextWord + 1); %funcName = getWord(%line, %nextWord + 2); %nextWord += 3; if(%file $= "") break; }}

function TCPDebugger::handleRunning(%this){ DebuggerFileView.setCurrentLine(-1, true); DebuggerCallStack.clear(); DebuggerStatus.setValue("RUNNING...");}

function TCPDebugger::handleEvalOut(%this, %line){ %id = firstWord(%line); %value = restWords(%line);

//see if it's the cursor watch, or from the watch windowif (%id < 0)

DebuggerCursorWatch.setText(DebuggerCursorWatch.expr SPC "=" SPC %value);

else{ %row = DebuggerWatchView.getRowTextById(%id); if(%row $= "") return; %expr = getField(%row, 0); DebuggerWatchView.setRowById(%id, %expr @ "\t" @ %value);}

}

function TCPDebugger::handleObjTagList(%this, %line){}

function TCPDebugger::handleError(%this, %line){ DebuggerConsoleView.print("ERROR - bogus message: " @ %line);}

//--------------------------------------------------------------// handlers for connection related functions//--------------------------------------------------------------

function TCPDebugger::onDNSResolve(%this)

84

Page 85:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{

}

function TCPDebugger::onConnecting(%this){}

function TCPDebugger::onConnected(%this){ // send the password on connect. // %this.send(%this.password @ "\r\n");

// tinman - this function never get's called - instead// send the password immediately...

}

function TCPDebugger::onConnectFailed(%this){

}

function TCPDebugger::onDisconnect(%this){

}

function DebuggerFilePopup::onSelect(%this, %id, %text){ DbgOpenFile(%text, 0, false);}

//--------------------------------------------------------------// Gui glue functions//--------------------------------------------------------------

$DbgWatchSeq = 1;function DbgWatchDialogAdd(){

%expr = WatchDialogExpression.getValue();if (%expr !$= "")

{ DebuggerWatchView.setRowById($DbgWatchSeq, %expr @"\

t(unknown)"); TCPDebugger.send("EVAL " @ $DbgWatchSeq @ " 0 " @ %expr @ "\r\n"); $DbgWatchSeq++; }

//don't forget to close the dialogCanvas.popDialog(DebuggerWatchDlg);

}

function DbgWatchDialogEdit(){

%newValue = EditWatchDialogValue.getValue();%id = DebuggerWatchView.getSelectedId();if (%id >= 0){ %row = DebuggerWatchView.getRowTextById(%id);

85

Page 86:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%expr = getField(%row, 0);if (%newValue $= "")

%assignment = %expr @ " = \"\"";else

%assignment = %expr @ " = " @ %newValue; TCPDebugger.send("EVAL " @ %id @ " 0 " @ %assignment @ "\r\n");

}

//don't forget to close the dialogCanvas.popDialog(DebuggerEditWatchDlg);

}

function DbgSetCursorWatch(%expr){

DebuggerCursorWatch.expr = %expr;if (DebuggerCursorWatch.expr $= "")

DebuggerCursorWatch.setText("");else

TCPDebugger.send("EVAL -1 0 " @ DebuggerCursorWatch.expr @ "\r\n");}

function DebuggerCallStack::onAction(%this){ %id = %this.getSelectedId(); if(%id == -1) return; %text = %this.getRowTextById(%id); %file = getField(%text, 0); %line = getField(%text, 1); DbgOpenFile(%file, %line, %id == 0);}

function DbgConnect(){

%address = DebuggerConnectAddress.getValue();%port = DebuggerConnectPort.getValue();%password = DebuggerConnectPassword.getValue();

if ((%address !$= "" ) && (%port !$= "" ) && (%password !$= "" )){

TCPDebugger.connect(%address @ ":" @ %port); TCPDebugger.schedule(5000, send, %password @ "\r\n");

TCPDebugger.password = %password;}

//don't forget to close the dialogCanvas.popDialog(DebuggerConnectDlg);

}

function DbgBreakConditionSet(){

%condition = BreakCondition.getValue();%passct = BreakPassCount.getValue();%clear = BreakClear.getValue();

if (%condition $= "")

86

Page 87:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%condition = "true"; if (%passct $= "") %passct = "0"; if (%clear $= "") %clear = "false"; //set the condition %id = DebuggerBreakPoints.getSelectedId(); if(%id != -1) { %bkp = DebuggerBreakPoints.getRowTextById(%id); DbgSetBreakPoint(getField(%bkp, 1), getField(%bkp, 0), %clear, %passct, %condition); }

//don't forget to close the dialogCanvas.popDialog(DebuggerBreakConditionDlg);

}

function DbgOpenFile(%file, %line, %selectLine){ if (%file !$= "") { //open the file in the file view if (DebuggerFileView.open(%file)) { DebuggerFileView.setCurrentLine(%line, %selectLine);

if (%file !$= $DebuggerFile){

TCPDebugger.send("BREAKLIST " @ %file @ "\r\n"); $DebuggerFile = %file;

} } }}

function DbgFileViewFind(){

%searchString = DebuggerFindStringText.getValue();%result = DebuggerFileView.findString(%searchString);

//don't forget to close the dialogCanvas.popDialog(DebuggerFindDlg);

}

function DbgFileBreakPoints(%file, %points){ DebuggerFileView.breakPoints(%file, %points);}

// BRKSET:file line clear passct expr - set a breakpoint on the file,linefunction DbgSetBreakPoint(%file, %line, %clear, %passct, %expr){ if(!%clear) { if(%file == $DebuggerFile)

87

Page 88:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

DebuggerFileView.setBreak(%line); } DebuggerBreakPoints.addBreak(%file, %line, %clear, %passct, %expr); TCPDebugger.send("BRKSET " @ %file @ " " @ %line @ " " @ %clear @ " " @ %passct @ " " @ %expr @ "\r\n");}

function DbgRemoveBreakPoint(%file, %line){ if(%file == $DebuggerFile) DebuggerFileView.removeBreak(%line); TCPDebugger.send("BRKCLR " @ %file @ " " @ %line @ "\r\n"); DebuggerBreakPoints.removeBreak(%file, %line);}

$DbgBreakId = 0;

function DebuggerBreakPoints::addBreak(%this, %file, %line, %clear, %passct, %expr){ // columns 0 = line, 1 = file, 2 = expr %textLine = %line @ "\t" @ %file @ "\t" @ %expr @ "\t" @ %passct @ "\t" @ %clear; %selId = %this.getSelectedId(); %selText = %this.getRowTextById(%selId); if(getField(%selText, 0) $= %line && getField(%selText, 1) $= %file) { %this.setRowById(%selId, %textLine); } else { %this.addRow($DbgBreakId, %textLine); $DbgBreakId++; }}

function DebuggerBreakPoints::removeBreak(%this, %file, %line){ for(%i = 0; %i < %this.rowCount(); %i++) { %id = %this.getRowId(%i); %text = %this.getRowTextById(%id); if(getField(%text, 0) $= %line && getField(%text, 1) $= %file) { %this.removeRowById(%id); return; } }}

function DbgDeleteSelectedBreak(){

%selectedBreak = DebuggerBreakPoints.getSelectedId();%rowNum = DebuggerBreakPoints.getRowNumById(%selectedWatch);if (%rowNum >= 0){

%breakText = DebuggerBreakPoints.getRowText(%rowNum);

88

Page 89:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%breakLine = getField(%breakText, 0);%breakFile = getField(%breakText, 1);

DbgRemoveBreakPoint(%breakFile, %breakLine);}

}

function DebuggerBreakPoints::clearBreaks(%this){ while(%this.rowCount()) { %id = %this.getRowId(0); %text = %this.getRowTextById(%id); %file = getField(%text, 1); %line = getField(%text, 0); DbgRemoveBreakPoint(%file, %line); }}

function DebuggerBreakPoints::onAction(%this){ %id = %this.getSelectedId(); if(%id == -1) return; %text = %this.getRowTextById(%id); %line = getField(%text, 0); %file = getField(%text, 1); DbgOpenFile(%file, %line, 0);}

function DebuggerFileView::onRemoveBreakPoint(%this, %line){ %file = $DebuggerFile; DbgRemoveBreakPoint(%file, %line);}

function DebuggerFileView::onSetBreakPoint(%this, %line){ %file = $DebuggerFile; DbgSetBreakPoint(%file, %line, 0, 0, true);}

function DbgConsoleEntryReturn(){ %msg = DbgConsoleEntry.getValue(); if (%msg !$= "") { DebuggerConsoleView.print("%" @ %msg);

if (DebuggerStatus.getValue() $= "NOT CONNECTED") DebuggerConsoleView.print("*** Not connected.");

else if (DebuggerStatus.getValue() $= "BREAK") DebuggerConsoleView.print("*** Target is in BREAK mode.");

else TCPDebugger.send("CEVAL " @ %msg @ "\r\n");

} DbgConsoleEntry.setValue("");

89

Page 90:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

function DbgConsolePrint(%status){ DebuggerConsoleView.print(%status);}

function DbgStackAddFrame(%file, %line, %funcName){ if ((%file !$= "") && (%line !$= "") && (%funcName !$= "")) DebuggerCallStack.add(%file, %line, %funcName);}

function DbgStackGetFrame(){ return DebuggerCallStack.getFrame();}

function DbgStackClear(){ DebuggerCallStack.clear();}

function DbgSetWatch(%expr){

if (%expr !$= "")DebuggerWatchView.set(%expr);

}

function DbgDeleteSelectedWatch(){

%selectedWatch = DebuggerWatchView.getSelectedId();%rowNum = DebuggerWatchView.getRowNumById(%selectedWatch);DebuggerWatchView.removeRow(%rowNum);

}

function DbgRefreshWatches(){ // query all the watches for(%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { %id = DebuggerWatchView.getRowId(%i); %row = DebuggerWatchView.getRowTextById(%id); %expr = getField(%row, 0); TCPDebugger.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); }}

function DbgClearWatches(){ DebuggerWatchView.clear();}

function dbgStepIn(){ TCPDebugger.send("STEPIN\r\n");}

90

Page 91:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function dbgStepOut(){ TCPDebugger.send("STEPOUT\r\n");}

function dbgStepOver(){ TCPDebugger.send("STEPOVER\r\n");}

function dbgContinue(){ TCPDebugger.send("CONTINUE\r\n");}

DebuggerConsoleView.setActive(false);

//-----------------------------------------------------------------------------// default.bind.cs – fps\client\scripts\// //-----------------------------------------------------------------------------

if ( isObject( moveMap ) ) moveMap.delete();new ActionMap(moveMap);

//------------------------------------------------------------------------------// Non-remapable binds//------------------------------------------------------------------------------

function escapeFromGame(){ if ( $Server::ServerType $= "SinglePlayer" ) MessageBoxYesNo( "Quit Mission", "Exit from this Mission?", "disconnect();", ""); else MessageBoxYesNo( "Disconnect", "Disconnect from the server?", "disconnect();", "");}

moveMap.bindCmd(keyboard, "escape", "", "escapeFromGame();");moveMap.bindcmd(keyboard, "F2", "", "PlayerListGui.toggle();");

//------------------------------------------------------------------------------// Movement Keys//------------------------------------------------------------------------------

$movementSpeed = 1; // m/s

function setSpeed(%speed)

91

Page 92:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ if(%speed) $movementSpeed = %speed;}

function moveleft(%val){ $mvLeftAction = %val;}

function moveright(%val){ $mvRightAction = %val;}

function moveforward(%val){ $mvForwardAction = %val;}

function movebackward(%val){ $mvBackwardAction = %val;}

function moveup(%val){ $mvUpAction = %val;}

function movedown(%val){ $mvDownAction = %val;}

function turnLeft( %val ){ $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;}

function turnRight( %val ){ $mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;}

function panUp( %val ){ $mvPitchDownSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;}

function panDown( %val ){ $mvPitchUpSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;}

function getMouseAdjustAmount(%val){

92

Page 93:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// based on a default camera fov of 90' return(%val * ($cameraFov / 90) * 0.01);}

function yaw(%val){ $mvYaw += getMouseAdjustAmount(%val);}

function pitch(%val){ if($pref::Input::InvertMouse) $mvPitch -= getMouseAdjustAmount(%val); else $mvPitch += getMouseAdjustAmount(%val);}

function jump(%val){ $mvTriggerCount2++;}

moveMap.bind( keyboard, a, moveleft );moveMap.bind( keyboard, d, moveright );moveMap.bind( keyboard, w, moveforward );moveMap.bind( keyboard, s, movebackward );moveMap.bind( keyboard, space, jump );moveMap.bind( mouse, xaxis, yaw );moveMap.bind( mouse, yaxis, pitch );

//------------------------------------------------------------------------------// Mouse Trigger//------------------------------------------------------------------------------

function mouseFire(%val){ $mvTriggerCount0++;}

function altTrigger(%val){ $mvTriggerCount1++;}

moveMap.bind( mouse, button0, mouseFire );//moveMap.bind( mouse, button1, altTrigger );

//------------------------------------------------------------------------------// Zoom and FOV functions//------------------------------------------------------------------------------

if($Pref::player::CurrentFOV $= "") $Pref::player::CurrentFOV = 45;

93

Page 94:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function setZoomFOV(%val){ if(%val) toggleZoomFOV();} function toggleZoom( %val ){ if ( %val ) { $ZoomOn = true; setFov( $Pref::player::CurrentFOV ); } else { $ZoomOn = false; setFov( $Pref::player::DefaultFov ); }}

moveMap.bind(keyboard, r, setZoomFOV);moveMap.bind(keyboard, e, toggleZoom);

//------------------------------------------------------------------------------// Camera & View functions//------------------------------------------------------------------------------

function toggleFreeLook( %val ){ if ( %val ) $mvFreeLook = true; else $mvFreeLook = false;}

function toggleFirstPerson(%val){ if (%val) { $firstPerson = !$firstPerson; }}

function toggleCamera(%val){ if (%val) commandToServer('ToggleCamera');}

moveMap.bind( keyboard, z, toggleFreeLook );moveMap.bind(keyboard, tab, toggleFirstPerson );moveMap.bind(keyboard, "alt c", toggleCamera);

94

Page 95:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//------------------------------------------------------------------------------// Misc. Player stuff//------------------------------------------------------------------------------

moveMap.bindCmd(keyboard, "ctrl w", "commandToServer('playCel',\"wave\");", "");moveMap.bindCmd(keyboard, "ctrl s", "commandToServer('playCel',\"salute\");", "");moveMap.bindCmd(keyboard, "ctrl k", "commandToServer('suicide');", "");moveMap.bindCmd(keyboard, "l", "Canvas.pushDialog(TeamSelectDlg);", "");

//------------------------------------------------------------------------------// Item manipulation//------------------------------------------------------------------------------

moveMap.bindCmd(keyboard, "h", "commandToServer('use',\"HealthKit\");", "");moveMap.bindCmd(keyboard, "1", "commandToServer('use',\"Crossbow\");", "");moveMap.bindCmd(keyboard, "2", "commandToServer('use',\"Cannon\");", "");

//------------------------------------------------------------------------------// Message HUD functions//------------------------------------------------------------------------------

function pageMessageHudUp( %val ){ if ( %val ) pageUpMessageHud();}

function pageMessageHudDown( %val ){ if ( %val ) pageDownMessageHud();}

function resizeMessageHud( %val ){ if ( %val ) cycleMessageHudSize();}

moveMap.bind(keyboard, u, toggleMessageHud );//moveMap.bind(keyboard, y, teamMessageHud );moveMap.bind(keyboard, "pageUp", pageMessageHudUp );moveMap.bind(keyboard, "pageDown", pageMessageHudDown );moveMap.bind(keyboard, "p", resizeMessageHud );

95

Page 96:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//------------------------------------------------------------------------------// Demo recording functions//------------------------------------------------------------------------------

function startRecordingDemo( %val ){// if ( %val )// beginDemoRecord(); error( "** This function has temporarily been disabled! **" );}

function stopRecordingDemo( %val ){// if ( %val )// stopRecord(); error( "** This function has temporarily been disabled! **" );}

//moveMap.bind( keyboard, F3, startRecordingDemo );//moveMap.bind( keyboard, F4, stopRecordingDemo );

//------------------------------------------------------------------------------// Helper Functions//------------------------------------------------------------------------------

function dropCameraAtPlayer(%val){ if (%val) commandToServer('dropCameraAtPlayer');}

function dropPlayerAtCamera(%val){ if (%val) commandToServer('DropPlayerAtCamera');}

moveMap.bind(keyboard, "F8", dropCameraAtPlayer);moveMap.bind(keyboard, "F7", dropPlayerAtCamera);

//------------------------------------------------------------------------------// Debugging Functions//------------------------------------------------------------------------------

$MFDebugRenderMode = 0;function cycleDebugRenderMode(%val){ if (!%val) return; if($MFDebugRenderMode == 0) {

96

Page 97:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// Outline mode, including fonts so no stats $MFDebugRenderMode = 1; GLEnableOutline(true); } else if ($MFDebugRenderMode == 1) { // Interior debug mode $MFDebugRenderMode = 2; GLEnableOutline(false); setInteriorRenderMode(7); showInterior(); } else if ($MFDebugRenderMode == 2) { // Back to normal $MFDebugRenderMode = 0; setInteriorRenderMode(0); GLEnableOutline(false); show(); }}

GlobalActionMap.bind(keyboard, "F9", cycleDebugRenderMode);

//------------------------------------------------------------------------------// Misc.//------------------------------------------------------------------------------

GlobalActionMap.bind(keyboard, "tilde", toggleConsole);GlobalActionMap.bindCmd(keyboard, "alt enter", "", "toggleFullScreen();");GlobalActionMap.bindCmd(keyboard, "F1", "", "contextHelp();");

//-----------------------------------------------------------------------------// defaultGameProfile.cs – fps\client\ui\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Override base controlsGuiButtonProfile.soundButtonOver = "AudioButtonOver";

//-----------------------------------------------------------------------------// Chat Hud profiles

new GuiControlProfile ("ChatHudMessageProfile"){ fontType = "BlackChancery"; fontSize = 19;

97

Page 98:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

fontColor = "0 0 200"; // default color (death msgs, scoring, inventory) fontColors[1] = "4 235 105"; // client join/drop, tournament mode fontColors[2] = "219 200 128"; // gameplay, admin/voting, pack/deployable fontColors[3] = "77 253 95"; // team chat, spam protection message, client tasks fontColors[4] = "40 231 240"; // global chat fontColors[5] = "200 200 50 200"; // used in single player game // WARNING! Colors 6-9 are reserved for name coloring autoSizeWidth = true; autoSizeHeight = true;};

new GuiControlProfile ("ChatHudScrollProfile"){ opaque = false; border = false; borderColor = "247 197 45"; bitmap = "common/ui/darkScroll"; hasBitmapArray = true;};

//-----------------------------------------------------------------------------// Common Hud profiles

new GuiControlProfile ("HudScrollProfile"){ opaque = false; border = true; borderColor = "255 0 0"; bitmap = "common/ui/darkScroll"; hasBitmapArray = true;};

new GuiControlProfile ("HudTextProfile"){ opaque = false; fillColor = "128 128 128"; fontColor = "0 255 0"; border = true; borderColor = "0 255 0";};

//-----------------------------------------------------------------------------// Center and bottom print

new GuiControlProfile ("CenterPrintProfile"){ opaque = false; fillColor = "128 128 128"; fontColor = "0 255 0"; border = true;

98

Page 99:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

borderColor = "0 255 0";};

new GuiControlProfile ("CenterPrintTextProfile"){ opaque = false; fontType = "Arial"; fontSize = 12; fontColor = "0 255 0";};

//-----------------------------------------------------------------------------// defaultProfiles.cs – common\ui\// //-----------------------------------------------------------------------------

//--------------------------------------------------------------------------

$Gui::fontCacheDirectory = expandFilename("./cache");$Gui::clipboardFile = expandFilename("./cache/clipboard.gui");

// GuiDefaultProfile is a special case, all other profiles are initialized// to the contents of this profile first then the profile specific// overrides are assigned.

if(!isObject(GuiDefaultProfile)) new GuiControlProfile (GuiDefaultProfile){ tab = false; canKeyFocus = false; hasBitmapArray = false; mouseOverSelected = false;

// fill color opaque = false; fillColor = ($platform $= "macos") ? "211 211 211" : "192 192 192"; fillColorHL = ($platform $= "macos") ? "244 244 244" : "220 220 220"; fillColorNA = ($platform $= "macos") ? "244 244 244" : "220 220 220";

// border color border = false; borderColor = "0 0 0"; borderColorHL = "128 128 128"; borderColorNA = "64 64 64";

// font fontType = "Arial"; fontSize = 14;

fontColor = "0 0 0"; fontColorHL = "32 100 100"; fontColorNA = "0 0 0"; fontColorSEL= "200 200 200";

99

Page 100:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// bitmap information bitmap = ($platform $= "macos") ? "./osxWindow" : "./darkWindow"; bitmapBase = ""; textOffset = "0 0";

// used by guiTextControl modal = true; justify = "left"; autoSizeWidth = false; autoSizeHeight = false; returnTab = false; numbersOnly = false; cursorColor = "0 0 0 255";

// sounds soundButtonDown = ""; soundButtonOver = "";};

if(!isObject(GuiInputCtrlProfile)) new GuiControlProfile( GuiInputCtrlProfile ){ tab = true;

canKeyFocus = true;};

if(!isObject(GuiDialogProfile)) new GuiControlProfile(GuiDialogProfile);

if(!isObject(GuiSolidDefaultProfile)) new GuiControlProfile (GuiSolidDefaultProfile){ opaque = true; border = true;};

if(!isObject(GuiWindowProfile)) new GuiControlProfile (GuiWindowProfile){ opaque = true; border = 2; fillColor = ($platform $= "macos") ? "211 211 211" : "192 192 192"; fillColorHL = ($platform $= "macos") ? "190 255 255" : "64 150 150"; fillColorNA = ($platform $= "macos") ? "255 255 255" : "150 150 150"; fontColor = ($platform $= "macos") ? "0 0 0" : "255 255 255"; fontColorHL = ($platform $= "macos") ? "200 200 200" : "0 0 0"; text = "GuiWindowCtrl test"; bitmap = ($platform $= "macos") ? "./osxWindow" : "./darkWindow"; textOffset = ($platform $= "macos") ? "5 5" : "6 6"; hasBitmapArray = true; justify = ($platform $= "macos") ? "center" : "left";};

if(!isObject(GuiToolWindowProfile)) new GuiControlProfile (GuiToolWindowProfile){ opaque = true;

100

Page 101:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

border = 2; fillColor = "192 192 192"; fillColorHL = "64 150 150"; fillColorNA = "150 150 150"; fontColor = "255 255 255"; fontColorHL = "0 0 0"; bitmap = "./torqueToolWindow"; textOffset = "6 6";};

if(!isObject(EditorToolButtonProfile)) new GuiControlProfile (EditorToolButtonProfile){ opaque = true; border = 2;};

if(!isObject(GuiContentProfile)) new GuiControlProfile (GuiContentProfile){ opaque = true; fillColor = "255 255 255";};

if(!isObject(GuiModelessDialogProfile)) new GuiControlProfile("GuiModelessDialogProfile"){ modal = false;};

if(!isObject(GuiButtonProfile)) new GuiControlProfile (GuiButtonProfile){ opaque = true; border = true; fontColor = "0 0 0"; fontColorHL = "32 100 100"; fixedExtent = true; justify = "center";

canKeyFocus = false;};

if(!isObject(GuiBorderButtonProfile)) new GuiControlProfile (GuiBorderButtonProfile){ fontColorHL = "0 0 0";};

if(!isObject(GuiMenuBarProfile)) new GuiControlProfile (GuiMenuBarProfile){ opaque = true; fillColorHL = "0 0 96"; border = 4; fontColor = "0 0 0"; fontColorHL = "255 255 255"; fontColorNA = "128 128 128"; fixedExtent = true;

101

Page 102:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

justify = "center"; canKeyFocus = false; mouseOverSelected = true; bitmap = ($platform $= "macos") ? "./osxMenu" : "./torqueMenu"; hasBitmapArray = true;};

if(!isObject(GuiButtonSmProfile)) new GuiControlProfile (GuiButtonSmProfile : GuiButtonProfile){ fontSize = 14;};

if(!isObject(GuiRadioProfile)) new GuiControlProfile (GuiRadioProfile){ fontSize = 14; fillColor = "232 232 232"; fontColorHL = "32 100 100"; fixedExtent = true; bitmap = ($platform $= "macos") ? "./osxRadio" : "./torqueRadio"; hasBitmapArray = true;};

if(!isObject(GuiScrollProfile)) new GuiControlProfile (GuiScrollProfile){ opaque = true; fillColor = "255 255 255"; border = 3; borderThickness = 2; borderColor = "0 0 0"; bitmap = ($platform $= "macos") ? "./osxScroll" : "./darkScroll"; hasBitmapArray = true;};

if(!isObject(GuiSliderProfile)) new GuiControlProfile (GuiSliderProfile);

if(!isObject(GuiTextProfile)) new GuiControlProfile (GuiTextProfile){ fontColor = "0 0 0"; autoSizeWidth = true; autoSizeHeight = true;};

if(!isObject(EditorTextProfile)) new GuiControlProfile (EditorTextProfile){ fontType = "Arial Bold"; fontColor = "0 0 0"; autoSizeWidth = true; autoSizeHeight = true;};

if(!isObject(EditorTextProfileWhite)) new GuiControlProfile (EditorTextProfileWhite){ fontType = "Arial Bold";

102

Page 103:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

fontColor = "255 255 255"; autoSizeWidth = true; autoSizeHeight = true;};

if(!isObject(GuiMediumTextProfile)) new GuiControlProfile (GuiMediumTextProfile : GuiTextProfile){ fontSize = 24;};

if(!isObject(GuiBigTextProfile)) new GuiControlProfile (GuiBigTextProfile : GuiTextProfile){ fontSize = 36;};

if(!isObject(GuiCenterTextProfile)) new GuiControlProfile (GuiCenterTextProfile : GuiTextProfile){ justify = "center";};

if(!isObject(MissionEditorProfile)) new GuiControlProfile (MissionEditorProfile){ canKeyFocus = true;};

if(!isObject(EditorScrollProfile)) new GuiControlProfile (EditorScrollProfile){ opaque = true; fillColor = "192 192 192 192"; border = 3; borderThickness = 2; borderColor = "0 0 0"; bitmap = "./darkScroll"; hasBitmapArray = true;};

if(!isObject(GuiTextEditProfile)) new GuiControlProfile (GuiTextEditProfile){ opaque = true; fillColor = "255 255 255"; fillColorHL = "128 128 128"; border = 3; borderThickness = 2; borderColor = "0 0 0"; fontColor = "0 0 0"; fontColorHL = "255 255 255"; fontColorNA = "128 128 128"; textOffset = "0 2"; autoSizeWidth = false; autoSizeHeight = true; tab = true;

103

Page 104:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

canKeyFocus = true;};

if(!isObject(GuiControlListPopupProfile)) new GuiControlProfile (GuiControlListPopupProfile){ opaque = true; fillColor = "255 255 255"; fillColorHL = "128 128 128"; border = true; borderColor = "0 0 0"; fontColor = "0 0 0"; fontColorHL = "255 255 255"; fontColorNA = "128 128 128"; textOffset = "0 2"; autoSizeWidth = false; autoSizeHeight = true; tab = true; canKeyFocus = true; bitmap = ($platform $= "macos") ? "./osxScroll" : "./darkScroll"; hasBitmapArray = true;};

if(!isObject(GuiTextArrayProfile)) new GuiControlProfile (GuiTextArrayProfile : GuiTextProfile){ fontColorHL = "32 100 100"; fillColorHL = "200 200 200";};

if(!isObject(GuiTextListProfile)) new GuiControlProfile (GuiTextListProfile : GuiTextProfile) ;

if(!isObject(GuiTreeViewProfile)) new GuiControlProfile (GuiTreeViewProfile){ fontSize = 13; // dhc - trying a better fit... fontColor = "0 0 0"; fontColorHL = "64 150 150";};

if(!isObject(GuiCheckBoxProfile)) new GuiControlProfile (GuiCheckBoxProfile){ opaque = false; fillColor = "232 232 232"; border = false; borderColor = "0 0 0"; fontSize = 14; fontColor = "0 0 0"; fontColorHL = "32 100 100"; fixedExtent = true; justify = "left"; bitmap = ($platform $= "macos") ? "./osxCheck" : "./torqueCheck"; hasBitmapArray = true;

};

104

Page 105:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if(!isObject(GuiPopUpMenuProfile)) new GuiControlProfile (GuiPopUpMenuProfile){ opaque = true; mouseOverSelected = true;

border = 4; borderThickness = 2; borderColor = "0 0 0"; fontSize = 14; fontColor = "0 0 0"; fontColorHL = "32 100 100"; fontColorSEL = "32 100 100"; fixedExtent = true; justify = "center"; bitmap = ($platform $= "macos") ? "./osxScroll" : "./darkScroll"; hasBitmapArray = true;};

if(!isObject(GuiEditorClassProfile)) new GuiControlProfile (GuiEditorClassProfile){ opaque = true; fillColor = "232 232 232"; border = true; borderColor = "0 0 0"; borderColorHL = "127 127 127"; fontColor = "0 0 0"; fontColorHL = "32 100 100"; fixedExtent = true; justify = "center"; bitmap = ($platform $= "macos") ? "./osxScroll" : "./darkScroll"; hasBitmapArray = true;};

if(!isObject(LoadTextProfile)) new GuiControlProfile ("LoadTextProfile"){ fontColor = "66 219 234"; autoSizeWidth = true; autoSizeHeight = true;};

if(!isObject(GuiMLTextProfile)) new GuiControlProfile ("GuiMLTextProfile"){ fontColorLink = "255 96 96"; fontColorLinkHL = "0 0 255";};

//--------------------------------------------------------------------------// Console Window

105

Page 106:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if(!isObject(GuiConsoleProfile)) new GuiControlProfile ("GuiConsoleProfile"){ fontType = ($platform $= "macos") ? "Courier New" : "Lucida Console"; fontSize = 12; fontColor = "0 0 0"; fontColorHL = "130 130 130"; fontColorNA = "255 0 0"; fontColors[6] = "50 50 50"; fontColors[7] = "50 50 0"; fontColors[8] = "0 0 50"; fontColors[9] = "0 50 0"; };

if(!isObject(GuiProgressProfile)) new GuiControlProfile ("GuiProgressProfile"){ opaque = false; fillColor = "44 152 162 100"; border = true; borderColor = "78 88 120";};

if(!isObject(GuiProgressTextProfile)) new GuiControlProfile ("GuiProgressTextProfile"){ fontColor = "0 0 0"; justify = "center";};

//--------------------------------------------------------------------------// Gui Inspector

if(!isObject(GuiInspectorTextEditProfile)) new GuiControlProfile ("GuiInspectorTextEditProfile"){ opaque = true; fillColor = "255 255 255"; fillColorHL = "128 128 128"; border = true; borderColor = "0 0 0"; fontColor = "0 0 0"; fontColorHL = "255 255 255"; autoSizeWidth = false; autoSizeHeight = true; tab = false; canKeyFocus = true;};

if(!isObject(GuiBitmapBorderProfile)) new GuiControlProfile(GuiBitmapBorderProfile){ bitmap = "./darkBorder";

106

Page 107:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

hasBitmapArray = true;};

//-------------------------------------- Cursors//new GuiCursor(DefaultCursor){ hotSpot = "1 1"; bitmapName = "./CUR_3darrow";};

//-----------------------------------------------------------------------------// defaults.cs – fps\client\// //-----------------------------------------------------------------------------

// The master server is declared with the server defaults, which is// loaded on both clients & dedicated servers. If the server mod// is not loaded on a client, then the master must be defined. //$pref::Master[0] = "2:v12master.dyndns.org:28002";

$pref::Player::Name = "ScallyWag!";$pref::Player::defaultFov = 90;$pref::Player::zoomSpeed = 0;

$pref::Net::LagThreshold = 400;$pref::Net::Port = 28000;

$pref::shadows = "2";$pref::HudMessageLogSize = 40;$pref::ChatHudLength = 1;

$pref::Input::LinkMouseSensitivity = 1;$pref::Input::MouseEnabled = 0;$pref::Input::JoystickEnabled = 0;$pref::Input::KeyboardTurnSpeed = 0.1;$pref::Input::InvertMouse = 0;

$pref::sceneLighting::cacheSize = 20000;$pref::sceneLighting::purgeMethod = "lastCreated";$pref::sceneLighting::cacheLighting = 1;$pref::sceneLighting::terrainGenerateLevel = 1;

$pref::Terrain::DynamicLights = 1;$pref::Interior::TexturedFog = 0;

$pref::Video::displayDevice = "OpenGL";$pref::Video::allowOpenGL = 1;$pref::Video::allowD3D = 1;$pref::Video::preferOpenGL = 1;$pref::Video::appliedPref = 0;$pref::Video::disableVerticalSync = 1;$pref::Video::monitorNum = 0;$pref::Video::windowedRes = "800 600";

107

Page 108:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

$pref::OpenGL::force16BitTexture = "0";$pref::OpenGL::forcePalettedTexture = "0";$pref::OpenGL::maxHardwareLights = 3;$pref::VisibleDistanceMod = 1.0;

$pref::Audio::driver = "OpenAL";$pref::Audio::forceMaxDistanceUpdate = 0;$pref::Audio::environmentEnabled = 0;$pref::Audio::masterVolume = 0.8;$pref::Audio::channelVolume1 = 0.8;$pref::Audio::channelVolume2 = 0.8;$pref::Audio::channelVolume3 = 0.8;$pref::Audio::channelVolume4 = 0.8;$pref::Audio::channelVolume5 = 0.8;$pref::Audio::channelVolume6 = 0.8;$pref::Audio::channelVolume7 = 0.8;$pref::Audio::channelVolume8 = 0.8;

//-----------------------------------------------------------------------------// defaults.cs – show\// //-----------------------------------------------------------------------------

$pref::shadows = "2";

$pref::Input::LinkMouseSensitivity = 1;$pref::Input::MouseEnabled = 0;$pref::Input::JoystickEnabled = 0;$pref::Input::KeyboardTurnSpeed = 0.1;

$pref::sceneLighting::cacheSize = 20000;$pref::sceneLighting::purgeMethod = "lastCreated";$pref::sceneLighting::cacheLighting = 1;$pref::sceneLighting::terrainGenerateLevel = 1;

$pref::Terrain::DynamicLights = 1;$pref::Interior::TexturedFog = 0;

$pref::Video::displayDevice = "OpenGL";$pref::Video::allowOpenGL = 1;$pref::Video::allowD3D = 1;$pref::Video::preferOpenGL = 1;$pref::Video::appliedPref = 0;$pref::Video::disableVerticalSync = 1;

$pref::OpenGL::force16BitTexture = "0";$pref::OpenGL::forcePalettedTexture = "0";$pref::OpenGL::maxHardwareLights = 3;$pref::VisibleDistanceMod = 1.0;

$pref::Audio::drivers = "";$pref::Audio::enableVoiceCapture = 1;$pref::Audio::forceMaxDistanceUpdate = 0;$pref::Audio::voiceChannels = 2;$pref::Audio::activeDriver = "default";

108

Page 109:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

$pref::Audio::environmentEnabled = 0;$pref::Audio::microphoneEnabled = 1;$pref::Audio::musicEnabled = 1;$pref::Audio::musicVolume = 0.8;$pref::Audio::masterVolume = 0.8;$pref::Audio::effectsVolume = 1.0;$pref::Audio::voiceVolume = 1.0;$pref::Audio::guiVolume = 0.8;$pref::Audio::radioVolume = 0.8;$pref::Audio::captureGainScale = 1.0;

//-----------------------------------------------------------------------------// Torque Game Engine// // Copyright (c) 2001 GarageGames.Com// Portions Copyright (c) 2001 by Sierra Online, Inc.//-----------------------------------------------------------------------------

// List of master servers to query, each one is tried in order// until one responds$Pref::Server::RegionMask = 2;$pref::Master[0] = "2:v12master.dyndns.org:28002";

// Information about the server$Pref::Server::Name = "Full Sail! – 3D Pirate Ship Racing";$Pref::Server::Info = "This is a Full Sail! – 3D Pirate Ship Racing Server.";

// The connection error message is transmitted to the client immediatly// on connection, if any further error occures during the connection// process, such as network traffic mismatch, or missing files, this error// message is display. This message should be replaced with information// usefull to the client, such as the url or ftp address of where the// latest version of the game can be obtained.$Pref::Server::ConnectionError = "You do not have the correct version of Full Sail! – 3D Pirate Ship Racing or "@ "the related art needed to connect to this server, please contact "@ "the server operator to obtain the latest version of this game.";

// The network port is also defined by the client, this value // overrides pref::net::port for dedicated servers$Pref::Server::Port = 28000;

// If the password is set, clients must provide it in order// to connect to the server$Pref::Server::Password = "";

// Password for admin clients$Pref::Server::AdminPassword = "";

// Misc server settings.$Pref::Server::MaxPlayers = 64;$Pref::Server::TimeLimit = 20; // In minutes

109

Page 110:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

$Pref::Server::KickBanTime = 300; // specified in seconds$Pref::Server::BanTime = 1800; // specified in seconds$Pref::Server::FloodProtectionEnabled = 1;$Pref::Server::MaxChatLen = 120;

// Voice compression is currently not supported in the Torque Engine// .v12 (1.2 kbits/sec), .v24 (2.4 kbits/sec), .v29 (2.9kbits/sec)$Audio::voiceCodec = ".v12";

//-----------------------------------------------------------------------------// galleon.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

// Galleon Audio

datablock AudioProfile(GalleonSoftImpactSound){ filename = "~/data/sound/Xplode.wav"; description = AudioClose3d; preload = true; effect = SoftImpactEffect;};

datablock AudioProfile(GalleonHardImpactSound){ filename = "~/data/sound/Xplode.wav"; description = AudioClose3d; preload = true; effect = HardImpactEffect;};

datablock AudioProfile(GalleonExitWaterMediumSound){ fileName = "~/data/sound/Thrust.WAV"; description = AudioClose3d; preload = true;};

datablock AudioProfile(GalleonImpactWaterSoftSound){ fileName = "~/data/sound/Thrust.WAV"; description = AudioClose3d; preload = true;};

datablock AudioProfile(GalleonImpactWaterMediumSound){ fileName = "~/data/sound/Thrust.WAV"; description = AudioClose3d; preload = true;};

datablock AudioProfile(GalleonWakeMediumSplashSound){

110

Page 111:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

fileName = "~/data/sound/fx/ocean.wav"; description = AudioDefault3d; preload = true;};

datablock AudioProfile(GalleonThrustSound){ filename = "~/data/sound/Thrust.WAV"; description = AudioDefaultLooping3d; preload = true; effect = ScoutFlyerThrustEffect;};

datablock AudioProfile(GalleonEngineSound){ filename = "~/data/sound/EngineHum.WAV"; description = AudioDefaultLooping3d; preload = true;};// End Galleon Audio//-------------------------------------------------------------// Vehicle Galleon Explosiondatablock ParticleData(GalleonExplosionParticle){ dragCoefficient = 2; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 750; lifetimeVarianceMS = 150; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0 0.2 1 1.0"; colors[1] = "0 0.2 1 0.0"; sizes[0] = 0.5; sizes[1] = 1.0;};

datablock ParticleEmitterData(GalleonExplosionEmitter){ ejectionPeriodMS = 7; periodVarianceMS = 0; ejectionVelocity = 1; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "GalleonExplosionParticle";};

datablock ExplosionData(GalleonVehicleExplosion){ explosionShape = "~/data/shapes/Vehicles/Galleon/Galleon.dts";

particleEmitter = GalleonExplosionEmitter;

111

Page 112:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

particleDensity = 50; particleRadius = 0.2;

faceViewer = true; explosionScale = "1 1 1";

shakeCamera = true; camShakeFreq = "10.0 11.0 10.0"; camShakeAmp = "1.0 1.0 1.0"; camShakeDuration = 0.5; camShakeRadius = 10.0;};// End Galleon Explosion//---------------------------------------------------------------------------------------// Vehicle Galleon Debrisdatablock DebrisData(GalleonShapeDebris){ explodeOnMaxBounce = false;

elasticity = 0.15; friction = 0.5;

lifetime = 4.0; lifetimeVariance = 0.0;

minSpinSpeed = 40; maxSpinSpeed = 600;

numBounces = 5; bounceVariance = 0;

staticOnMaxBounce = true; gravModifier = 1.0;

useRadiusMass = true; baseRadius = 1;

velocity = 20.0; velocityVariance = 12.0;};

datablock ParticleData(GalleonContrailParticle){ dragCoefficient = 1.5; gravityCoefficient = 0; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 3000; lifetimeVarianceMS = 0; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0.6 0.6 0.6 0.5"; colors[1] = "0.2 0.2 0.2 0"; sizes[0] = 0.6; sizes[1] = 5;};

112

Page 113:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

datablock ParticleEmitterData(GalleonContrailEmitter){ ejectionPeriodMS = 5; periodVarianceMS = 0; ejectionVelocity = 1; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 10; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "GalleonContrailParticle";};

datablock ParticleData(GalleonJetParticle){ dragCoefficient = 1.5; gravityCoefficient = 0; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 200; lifetimeVarianceMS = 0; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0.9 0.7 0.3 0.6"; colors[1] = "0.3 0.3 0.5 0"; sizes[0] = 2; sizes[1] = 6;};

datablock ParticleEmitterData(GalleonJetEmitter){ ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 20; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 10; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "GalleonJetParticle";};// End Galleon Debris//---------------------------------------------------------------------------------------// Galleon Definitiondatablock WaterCraftData(Galleon){ spawnOffset = "0 0 0"; emap = true; category = "Vehicles"; shapeFile = "~/data/shapes/Vehicles/Galleon/Galleon.dts"; multipassenger = true; computeCRC = true;

113

Page 114:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

debrisShapeName = "~/data/shapes/Vehicles/Galleon/Galleon.dts"; debris = GalleonShapeDebris; renderWhenDestroyed = false;

density = 1.0;// weaponNode = 10; minMountDist = 3; mountPose[0] = sitting; mountPose[1] = standing; mountPose[2] = standing; numMountPoints = 3; isProtectedMountPoint[0] = true; isProtectedMountPoint[1] = true; isProtectedMountPoint[2] = true; cameraMaxDist = 20; cameraOffset = 1; cameraLag = 3;

maxDamage = 1000; destroyedLevel = 1000;

isShielded = false; // energyPerDamagePoint = 160; // maxEnergy = 280; // Afterburner and any energy weapon pool // rechargeRate = 0.8;

minDrag = 20; // Linear Drag (eventually slows you down when not thrusting...constant drag)

// Maneuvering maxSteeringAngle = 10; // Max radiens you can rotate the wheel. Smaller number is more maneuverable. maxForwardSpeed = 30; // speed in which forward thrust force is no longer applied (meters/second) // Rigid body mass = 1; // Mass of the vehicle - leave at 1 unless you want the boat to sink bodyFriction = 0; // Don't mess with this. bodyRestitution = 0.05; // When you hit the ground, how much you rebound. (between 0 and 1) minRollSpeed = 2000; // Don't mess with this. softImpactSpeed = 3; // Sound hooks. This is the soft hit. hardImpactSpeed = 15; // Sound hooks. This is the hard hit.

dragForce = 0.20; vertFactor = 0.0; floatingThrustFactor = 0.0;

114

Page 115:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

mainThrustForce = 20; reverseThrustForce = 5; strafeThrustForce = 0; turboFactor = 1.0;

stabLenMin = 15.0; stabLenMax = 18.0; stabSpringConstant = 10; stabDampingConstant = 10;

gyroDrag = 30; normalForce = 30; restorativeForce = 10; steeringForce = 15; // Steering jets (force applied when you move the mouse) rollForce = 0; pitchForce = 0;

dustTrailFreqMod = 15.0; triggerTrailHeight = 2.5;

floatingGravMag = 1; brakingForce = 0.2; brakingActivationSpeed = 0.2;

// Ground Impact Damage (uses DamageType::Ground) minImpactSpeed = 5; // If hit ground at speed above this then it's an impact. Meters/second speedDamageScale = 0.06;

// Object Impact Damage (uses DamageType::Impact) collDamageThresholdVel = 23.0; collDamageMultiplier = 0.02;

// minTrailSpeed = 1; // The speed your contrail shows up at. trailEmitter = GalleonContrailEmitter; forwardJetEmitter = GalleonJetEmitter; downJetEmitter = GalleonJetEmitter;

// jetSound = GalleonThrustSound; engineSound = GalleonEngineSound; softImpactSound = GalleonSoftImpactSound; hardImpactSound = GalleonHardImpactSound; // softSplashSoundVelocity = 10.0; mediumSplashSoundVelocity = 15.0; hardSplashSoundVelocity = 20.0; exitSplashSoundVelocity = 10.0;

exitingWater = GalleonExitWaterMediumSound;

115

Page 116:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

impactWaterEasy = GalleonImpactWaterSoftSound; impactWaterMedium = GalleonImpactWaterMediumSound; impactWaterHard = GalleonImpactWaterMediumSound; waterWakeSound = GalleonWakeMediumSplashSound;

triggerDustHeight = 4.0; dustHeight = 1.0; damageEmitterOffset[0] = "0.0 -3.0 0.0 "; damageLevelTolerance[0] = 0.3; damageLevelTolerance[1] = 0.7; numDmgEmitterAreas = 3;

splashEmitter[0] = VehicleFoamDropletsEmitter; splashEmitter[1] = VehicleFoamEmitter;};

// Galleon Functions//// note: this function not complete //function Galleon::onDamage(%this, %obj, %delta){ return;

Parent::onDamage(%this, %obj); if (%delta > 0 && %obj.getState() !$= "Destroyed") { %currentDamage = %obj.getDamageLevel(); MessageAll('ShipDmg', '%1 damage so far to ship!', %currentDamage); if(%currentDamage > %obj.maxDamage) { if(%obj.getDamageState() !$= "Destroyed") %obj.setDamageState(Destroyed); } else { if(%obj.getDamageState() !$= "Enabled") %obj.setDamageState(Enabled); } }}

function Galleon::damage(%this, %obj, %sourceObject, %position, %damage, %damageType){ if (%obj.getState() $= "Destroyed") return;

MessageAll('ShipDmg', '%1 damage done to ship!', %damage); %obj.applyDamage(%damage);}

116

Page 117:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// End Galleon Definition//----------------------------------------------------------------------------------------//-----------------------------------------------------------------------------// game.cs – fps\server\scripts\// //-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Team Structures//-----------------------------------------------------------------------------

// AW$Team0 = new ScriptObject(){ teamId = 0; name = Observer; score = 0; numPlayers = 0; currentGate = 0;};

$Team1 = new ScriptObject(){ teamId = 1; name = Red; score = 0; numPlayers = 0; currentGate = 0;};

$Team2 = new ScriptObject(){ teamId = 2; name = Blue; score = 0; numPlayers = 0; currentGate = 0;};

$Winner = false;$RedStart = false;$BlueStart = false;$RedSpawn = 0;$BlueSpawn = 0;$RedGate = 0;$BlueGate = 0;// AW end

//-----------------------------------------------------------------------------// Functions that implement game-play//-----------------------------------------------------------------------------

117

Page 118:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function createGame(){ // Server::GameType is sent to the master server. // This variable should uniquely identify your game and/or mod. $Server::GameType = "Pirate Racing";

// Server::MissionType sent to the master server. Clients can // filter servers based on mission type. $Server::MissionType = "Deathmatch";

// GameStartTime is the sim time the game started. Used to calculated // game elapsed time. $Game::StartTime = 0;

// Load up all datablocks, objects etc. This function is called when // a server is constructed. exec("./audioProfiles.cs"); exec("./camera.cs"); exec("./markers.cs"); exec("./triggers.cs"); exec("./inventory.cs"); exec("./shapeBase.cs"); exec("./item.cs"); exec("./health.cs"); exec("./weapon.cs"); exec("./radiusDamage.cs"); exec("./cannon.cs"); exec("./crossbow.cs"); exec("./Vehicles/vehicles.cs"); exec("./Vehicles/galleon.cs"); exec("./redplayer.cs"); exec("./blueplayer.cs"); exec("./aiPlayer.cs"); exec("./CheckPoint.cs");

// Keep track of when the game started $Game::StartTime = $Sim::Time;

// DB // Show bounding boxes in DEBUG mode. $GameBase::boundingBox = true;// DB end

}

function destroyGame(){ // This function is called as part of a server shutdown.}

//-----------------------------------------------------------------------------

118

Page 119:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function startGame(){ // Called once the mission has finished loading

// AW // Set the team spawns to the first sphere. $Winner = false; $RedStart = false; $BlueStart = false; $RedSpawn = 0; $BlueSpawn = 0; $RedGate = 0; $BlueGate = 0;// AW end

// DB // Spawn the vehicles. createVehicles();// DB end}

function endGame(){ // Called as part of mission cleanup}

//-----------------------------------------------------------------------------// GameConnection Methods// These methods are extensions to the GameConnection class. Extending// GameConnection make is easier to deal with some of this functionality,// but these could also be implemented as stand-alone functions.//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function GameConnection::onClientEnterGame(%this){ commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);

// Create a new camera object. %this.camera = new Camera() { dataBlock = Observer; };

MissionCleanup.add( %this.camera ); %this.camera.scopeToClient(%this);

// Setup game parameters, the onConnect method currently starts // everyone with a 0 score. %this.score = 0; %this.team = $Team0; //default team is 0 (observer)

119

Page 120:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// Spawn a camera by default on a observer point %this.camera.setTransform(pickObserverPoint(%this)); %this.camera.setVelocity("0 0 0"); %this.setControlObject(%this.camera);}

function GameConnection::onClientLeaveGame(%this){ if (isObject(%this.camera)) %this.camera.delete(); if (isObject(%this.player)) %this.player.delete();}

//-----------------------------------------------------------------------------

function GameConnection::onLeaveMissionArea(%this){ // The control objects invoked this method when they // move out of the mission area.}

function GameConnection::onEnterMissionArea(%this){ // The control objects invoked this method when they // move back into the mission area.}

//-----------------------------------------------------------------------------

function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc){ // Clear out the name on the corpse %this.player.setShapeName("");

// Switch the client over to the death cam and unhook the player object. if (isObject(%this.camera) && isObject(%this.player)) { %this.camera.setMode("Corpse",%this.player); %this.setControlObject(%this.camera); } %this.player = 0;

// Doll out points and display an appropriate message if (%damageType $= "Suicide" || %sourceClient == %this) { %this.incScore(-1); messageAll('MsgClientKilled','%1 takes his own life!',%this.name); } else { if (%sourceClient.name $= "")

120

Page 121:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ %this.incScore(-1); messageAll('MsgClientKilled', '%1 joins Davey Jones!', %this.name); } else { %sourceClient.incScore(1); messageAll('MsgClientKilled','%1 gets nailed by %2!',%this.name, %sourceClient.name); } }}

//-----------------------------------------------------------------------------

function GameConnection::spawnPlayer(%this){ // Combination create player and drop him somewhere

// AW %spawnPoint = pickSpawnPoint(%this);// AW end

%this.createPlayer(%spawnPoint);}

//-----------------------------------------------------------------------------

function GameConnection::createPlayer(%this, %spawnPoint){ if (%this.player > 0) { // The client should not have a player currently // assigned. Assigning a new one could result in // a player ghost. error( "Attempting to create an angus ghost!" ); }

// DB // Create the player object if (%this.team.teamId == 1) { %player = new Player() { dataBlock = RedPirate; client = %this; }; %player.teamNum = 1; } if (%this.team.teamId == 2) { %player = new Player() { dataBlock = BluePirate; client = %this;

121

Page 122:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}; %player.teamNum = 2; }// DB end

MissionCleanup.add(%player);

// Player setup... %player.setTransform(%spawnPoint); %player.setEnergyLevel(60); %player.setShapeName(%this.name); // Update the camera to start with the player %this.camera.setTransform(%player.getEyeTransform());

// Give the client control of the player %this.player = %player; %this.setControlObject(%player);

//On player spawn, reset current gate to gate 0. if(%player.teamNum == 1) %player.nextGate = $RedGate; else %player.nextGate = $BlueGate; setGateTarget(%player);}

//-----------------------------------------------------------------------------// Support functions//-----------------------------------------------------------------------------

function pickSpawnPoint(%client){ %groupName = "MissionGroup/" @ %client.team.name @ "TeamDropPoints"; %group = nameToID(%groupName); if(%client.team.teamId == 1) { %spawn = %group.getObject($RedSpawn); return %spawn.getTransform(); } if(%client.team.teamId == 2) { %spawn = %group.getObject($BlueSpawn); return %spawn.getTransform(); }}

function pickObserverPoint(%client){ %groupName = "MissionGroup/ObserverDropPoints"; %group = nameToID(%groupName);

if (%group != -1) {

122

Page 123:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%count = %group.getCount(); if (%count != 0) { %index = getRandom(%count-1); %spawn = %group.getObject(%index); return %spawn.getTransform(); } else error("No observer spawn points found in " @ %groupName); } else error("Missing observer spawn points group " @ %groupName);

// Could be no spawn points, in which case we'll stick the // player at the center of the world. return "0 0 300 1 0 0 0";}

//-----------------------------------------------------------------------------// Team Functions//-----------------------------------------------------------------------------function GameConnection::joinTeam(%this, %teamid){ //We only have 2 teams so if team is greater than 2 or less than 0 its invalid. if (%teamid > 2 || %teamid < 0) return false;

//If we already are on that team return. if (%teamid == %this.team.teamId) { echo("teamid == this.team.teamId"); //return false; }

%this.leaveTeam(); if (%teamid == 1) %this.team = $Team1; if (%teamid == 2) %this.team = $Team2;

MessageAll('MsgClientJoinTeam', '\c2%1 joined the %2 team.', %this.name, %this.team.name);

%this.spawnPlayer();

// DB - end those stupid msgs in the console!! //Once a player is on a team, start distance check schedule %this.ScheduledDistanceCheck();// DB end}

function GameConnection::leaveTeam(%client, %teamnumber){ %this.score = 0;

123

Page 124:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

messageAll('MsgClientLeaveTeam', '\c2%1 left the %2 team.', %client.name, %client.team.name);

if (%client.player) %client.player.delete();}//-----------------------------------------------------------------------------// ------------------- Vehicle Stuff -------------------------------//-----------------------------------------------------------------------------// DB

function createVehicles(){ // Red Vehicles %groupName = "MissionGroup/RedTeamVehicleSpawn"; %group = nameToID(%groupName); %spawnPoint = %group.getObject(0); // Create the Red vehicle object %vehicle = new WaterCraft() { dataBlock = Galleon; }; MissionCleanup.add(%vehicle);

// Red Vehicle setup... %vehicle.mountable = true; %vehicle.helmMountable = true; %vehicle.nestMountable = true; %vehicle.cannonMountable = true; %vehicle.setTransform(%spawnPoint.getTransform()); %vehicle.setEnergyLevel(60); // Blue Vehicles %groupName = "MissionGroup/BlueTeamVehicleSpawn"; %group = nameToID(%groupName); %spawnPoint = %group.getObject(0); // Create the Blue vehicle object %vehicle = new WaterCraft() { dataBlock = Galleon; }; MissionCleanup.add(%vehicle);

// Blue Vehicle setup... %vehicle.mountable = true; %vehicle.helmMountable = true; %vehicle.nestMountable = true; %vehicle.cannonMountable = true; %vehicle.setTransform(%spawnPoint.getTransform()); %vehicle.setEnergyLevel(60);}// DB end

124

Page 125:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// Gate Stuff//-----------------------------------------------------------------------------//Determine the number of gates in a missionfunction getNumberMissionGates(){

%count = GateGroup.getCount();return %count;

}

//Determine distance from the vehicle to the specified gatenumberfunction getGateDistance(%gatenumber, %player){

%playerPosition = %player.getTransform();%gateObject = GateGroup.getObject(%gatenumber);%dist = vectorDist( %playerPosition, %gateObject.position );return %dist;

}

//The scheduled distance check. Run every 500ms to check the players distance to the next gatefunction GameConnection::ScheduledDistanceCheck(%this){

cancel(%this.distanceCheck);%this.distanceCheck = %this.schedule(500,

"ScheduledDistanceCheck"); %player = %this.player;

%player.nextGate = %player.nextGate $= "" ? 0 : %player.nextGate;%distance = getGateDistance(%player.nextGate, %player);

if(%distance <= 150)GatePassed(%player);

}

//Run this if the player has just passed a gatefunction GatePassed(%player, %this){ %client = %player.client;

//Set next gate as target %prevGate = %client.nextGate; %winner = false;

%count = getNumberMissionGates();

if(%player.teamNum == 1) { if(%player.nextGate >= $RedGate) $RedGate++; %player.nextGate = $RedGate; } else

125

Page 126:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ if(%player.nextGate >= $BlueGate) $BlueGate++;

%player.nextGate = $BlueGate; }

setGateTarget(%player);

if(%player.nextGate > %count - 1 && $Winner == false) { messageAll('WinningMessage','The %1 team has WON the race!!' ,%client.team.name); $Winner = true; }

if(%player.nextGate == 1 && %player.teamNum == 1 && $RedStart == false) { messageAll('StartMessage','The %1 team has set sail!!!', %client.team.name); $RedStart = true; }

if(%player.nextGate == 1 && %player.teamNum == 2 && $BlueStart == false) { messageAll('StartMessage','The %1 team has set sail!!!', %client.team.name); $BlueStart = true; }

messageClient(%client,'StartMessage','\c0You have passed gate %1!!!', %player.nextGate);

if(%player.teamNum == 1) { if(%player.nextGate > $RedSpawn) $RedSpawn = %player.nextGate; }

if(%player.teamNum == 2) { if(%player.nextGate > $BlueSpawn) $BlueSpawn = %player.nextGate; }}

//Set the gate targetfunction setGateTarget(%player){ %client = %player.client; %player.nextGate = %player.nextGate $= "" ? 0 : %player.nextGate;

//Get gate location %gateObject = GateGroup.getObject(%player.nextGate); %gateX = getWord(%gateObject.position, 0);

126

Page 127:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%gateY = getWord(%gateObject.position, 1); %gateZ = getWord(%gateObject.position, 2); %altZ = %gateZ + 15; %gatePos = %gateX SPC %gateY SPC %altZ; //MessageClient(%client, 'StartMessage', 'Gate X, Y, Z set: %1, %2, %3', %gateX, %gateY, %gateZ);

//check if client already has a waypoint marker...if not, make oneif(!isObject(%client.waypointMarker)){

%client.waypointMarker = new WayPoint() {

position = %gatePos;dataBlock = "WayPointMarker";name = "Next Gate";

}; MissionCleanup.add(%client.waypointMarker);

}

//%client.waypointMarker.setTransform( %gatePos ); getNumberMissionGates();}

//-----------------------------------------------------------------------------// help.cs – common\client\// //-----------------------------------------------------------------------------

function HelpDlg::onWake(%this){ HelpFileList.entryCount = 0; HelpFileList.clear(); for(%file = findFirstFile("*.hfl"); %file !$= ""; %file = findNextFile("*.hfl")) { HelpFileList.fileName[HelpFileList.entryCount] = %file; HelpFileList.addRow(HelpFileList.entryCount, fileBase(%file)); HelpFileList.entryCount++; } HelpFileList.sortNumerical(0); HelpFileList.setSelectedRow(0);}

function HelpFileList::onSelect(%this, %row){ %fo = new FileObject(); %fo.openForRead(%this.fileName[%row]); %text = ""; while(!%fo.isEOF()) %text = %text @ %fo.readLine() @ "\n";

%fo.delete(); HelpText.setText(%text);}

127

Page 128:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function getHelp(%helpName){ Canvas.pushDialog(HelpDlg); if(%helpName !$= "") { %index = HelpFileList.findTextIndex(%helpName); HelpFileList.setSelectedRow(%index); }}

function contextHelp(){ for(%i = 0; %i < Canvas.getCount(); %i++) { if(Canvas.getObject(%i).getName() $= HelpDlg) { Canvas.popDialog(HelpDlg); return; } } %content = Canvas.getContent(); %helpPage = %content.getHelpPage(); getHelp(%helpPage);}

function GuiControl::getHelpPage(%this){ return %this.helpPage;}

//-----------------------------------------------------------------------------// init.cs – fps\server\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

// Variables used by server scripts & code. The ones marked with (c)// are accessed from code. Variables preceeded by Pref:: are server// preferences and stored automatically in the ServerPrefs.cs file// in between server sessions.//// (c) Server::ServerType {SinglePlayer, MultiPlayer}// (c) Server::GameType Unique game name// (c) Server::Dedicated Bool// ( ) Server::MissionFile Mission .mis file name// (c) Server::MissionName DisplayName from .mis file// (c) Server::MissionType Not used// (c) Server::PlayerCount Current player count// (c) Server::GuidList Player GUID (record list?)// (c) Server::Status Current server status//// (c) Pref::Server::Name Server Name

128

Page 129:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// (c) Pref::Server::Password Password for client connections// ( ) Pref::Server::AdminPassword Password for client admins// (c) Pref::Server::Info Server description// (c) Pref::Server::MaxPlayers Max allowed players// (c) Pref::Server::RegionMask Registers this mask with master server// ( ) Pref::Server::BanTime Duration of a player ban// ( ) Pref::Server::KickBanTime Duration of a player kick & ban// ( ) Pref::Server::MaxChatLen Max chat message len// ( ) Pref::Server::FloodProtectionEnabled Bool

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function initServer(){ echo("\n--------- Initializing MOD: FPS Server ---------");

// Server::Status is returned in the Game Info Query and represents the // current status of the server. This string sould be very short. $Server::Status = "Unknown";

// Turn on testing/debug script functions $Server::TestCheats = true;

// The common module provides the basic server functionality initBaseServer();

// Load up game server support scripts exec("./scripts/commands.cs"); exec("./scripts/centerPrint.cs"); exec("./scripts/game.cs");}

//-----------------------------------------------------------------------------

function initDedicated(){ enableWinConsole(true); echo("\n--------- Starting Dedicated Server ---------");

// Make sure this variable reflects the correct state. $Server::Dedicated = true;

// The server isn't started unless a mission has been specified. if ($missionArg !$= "") { // Need to intialize the network before starting up the server. setNetPort($Pref::Server::Port);

129

Page 130:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

createServer("MultiPlayer", $missionArg); } else echo("No mission specified (use -mission filename)");}

//-----------------------------------------------------------------------------// init.cs – fps\client\////-----------------------------------------------------------------------------

// Variables used by client scripts & code. The ones marked with (c)// are accessed from code. Variables preceeded by Pref:: are client// preferences and stored automatically in the ~/client/prefs.cs file// in between sessions.//// (c) Client::MissionFile Mission file name// ( ) Client::Password Password for server join

// (?) Pref::Player::CurrentFOV// (?) Pref::Player::DefaultFov// ( ) Pref::Input::KeyboardTurnSpeed

// (c) pref::Master[n] List of master servers// (c) pref::Net::RegionMask // (c) pref::Client::ServerFavoriteCount// (c) pref::Client::ServerFavorite[FavoriteCount]// .. Many more prefs... need to finish this off

// Moves, not finished with this either...// (c) firstPerson// $mv*Action...

//-----------------------------------------------------------------------------// These are variables used to control the shell scripts and// can be overriden by mods:

//-----------------------------------------------------------------------------

function initClient(){ echo("\n--------- Initializing MOD: FPS Client ---------");

// Make sure this variable reflects the correct state. $Server::Dedicated = false;

// The file spec used to find missions for the load/host // mission screen. $Client::MissionFileSpec = "*/missions/*.mis";

// Game information used to query the master server $Client::GameTypeQuery = "Test App";

130

Page 131:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

$Client::MissionTypeQuery = "Any";

// The common module provides basic client functionality initBaseClient();

// InitCanvas starts up the graphics system. // The canvas needs to be constructed before the gui scripts are // run because many of the controls assume the canvas exists at // load time. initCanvas("Full Sail! - 3D Pirate Ship Racing");

/// Load client-side Audio Profiles/Descriptions exec("./scripts/audioProfiles.cs");

// Load up the Game GUIs exec("./ui/defaultGameProfiles.cs"); exec("./ui/PlayGui.gui"); exec("./ui/ChatHud.gui"); exec("./ui/playerList.gui");

// Load up the shell GUIs exec("./ui/mainMenuGui.gui"); exec("./ui/aboutDlg.gui"); exec("./ui/startMissionGui.gui"); exec("./ui/joinServerGui.gui"); exec("./ui/loadingGui.gui"); exec("./ui/optionsDlg.gui"); exec("./ui/remapDlg.gui"); exec("./scripts/TeamSelectDlg.cs"); exec("./ui/TeamSelectDlg.gui");

// Client scripts exec("./scripts/client.cs"); exec("./scripts/missionDownload.cs"); exec("./scripts/serverConnection.cs"); exec("./scripts/playerList.cs"); exec("./scripts/loadingGui.cs"); exec("./scripts/optionsDlg.cs"); exec("./scripts/chatHud.cs"); exec("./scripts/messageHud.cs"); exec("./scripts/playGui.cs"); exec("./scripts/centerPrint.cs");

// Default player key bindings exec("./scripts/default.bind.cs"); exec("./config.cs");

// Really shouldn't be starting the networking unless we are // going to connect to a remote server, or host a multi-player // game. setNetPort($pref::Net::Port);

// Copy saved script prefs into C++ code. setShadowDetailLevel( $pref::shadows ); setDefaultFov( $pref::Player::defaultFov ); setZoomSpeed( $pref::Player::zoomSpeed );

131

Page 132:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// Start up the main menu... this is separated out into a // method for easier mod override. loadMainMenu();}

//-----------------------------------------------------------------------------

function loadMainMenu(){ // Startup the client with the Main menu... Canvas.setContent( MainMenuGui ); Canvas.setCursor("DefaultCursor");}

//-----------------------------------------------------------------------------// inventory.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

// This inventory system is totally scripted, no C++ code involved.// It uses object datablock names to track inventory and is generally// object type, or class, agnostic. In other words, it will inventory// any kind of ShapeBase object, though the throw method does assume// that the objects are small enough to throw :)//// For a ShapeBase object to support inventory, it must have an array// of inventory max values://// %this.maxInv[GunAmmo] = 100;// %this.maxInv[SpeedGun] = 1;//// where the names "SpeedGun" and "GunAmmo" are datablocks.//// For objects to be inventoriable, they must provide a set of inventory// callback methods, mainly://// onUse// onThrow// onPickup//// Example methods are given further down. The item.cs file also contains// example inventory items.

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Inventory server commands//-----------------------------------------------------------------------------

132

Page 133:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function serverCmdUse(%client,%data){ %client.getControlObject().use(%data);}

//-----------------------------------------------------------------------------// ShapeBase inventory support//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function ShapeBase::use(%this,%data){ // Use an object in the inventory. if (%this.getInventory(%data) > 0) return %data.onUse(%this); return false;}

function ShapeBase::throw(%this,%data,%amount){ // Throw objects from inventory. The onThrow method is // responsible for decrementing the inventory. if (%this.getInventory(%data) > 0) { %obj = %data.onThrow(%this,%amount); if (%obj) { %this.throwObject(%obj); return true; } } return false;}

function ShapeBase::pickup(%this,%obj,%amount){ // This method is called to pickup an object and add it // to the inventory. The datablock onPickup method is actually // responsible for doing all the work, including incrementing // the inventory. %data = %obj.getDatablock();

// Try and pickup the max if no value was specified if (%amount $= "") %amount = %this.maxInventory(%data) - %this.getInventory(%data);

// The datablock does the work... if (%amount < 0) %amount = 0; if (%amount) return %data.onPickup(%obj,%this,%amount); return false;}

133

Page 134:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function ShapeBase::maxInventory(%this,%data){ // If there is no limit defined, we assume 0 return %this.getDatablock().maxInv[%data.getName()];}

function ShapeBase::incInventory(%this,%data,%amount){ // Increment the inventory by the given amount. The return value // is the amount actually added, which may be less than the // requested amount due to inventory restrictions. %max = %this.maxInventory(%data); %total = %this.inv[%data.getName()]; if (%total < %max) { if (%total + %amount > %max) %amount = %max - %total; %this.setInventory(%data,%total + %amount); return %amount; } return 0;}

function ShapeBase::decInventory(%this,%data,%amount){ // Decrement the inventory by the given amount. The return value // is the amount actually removed. %total = %this.inv[%data.getName()]; if (%total > 0) { if (%total < %amount) %amount = %total; %this.setInventory(%data,%total - %amount); return %amount; } return 0;}

//-----------------------------------------------------------------------------

function ShapeBase::getInventory(%this,%data){ // Return the current inventory amount return %this.inv[%data.getName()];}

function ShapeBase::setInventory(%this,%data,%value){ // Set the inventory amount for this datablock and invoke // inventory callbacks. All changes to inventory go through this // single method.

// Impose inventory limits if (%value < 0)

134

Page 135:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%value = 0; else { %max = %this.maxInventory(%data); if (%value > %max) %value = %max; }

// Set the value and invoke object callbacks %name = %data.getName(); if (%this.inv[%name] != %value) { %this.inv[%name] = %value; %data.onInventory(%this,%value); %this.getDataBlock().onInventory(%data,%value); } return %value;}

//-----------------------------------------------------------------------------

function ShapeBase::clearInventory(%this){ // To be filled in...}

//-----------------------------------------------------------------------------

function ShapeBase::throwObject(%this,%obj){ // Throw the given object in the direction the shape is looking. // The force value is hardcoded according to the current default // object mass and mission gravity (20m/s^2). %throwForce = %this.throwForce; if (!%throwForce) %throwForce = 20;

// Start with the shape's eye vector... %eye = %this.getEyeVector(); %vec = vectorScale(%eye, %throwForce);

// Add a vertical component to give the object a better arc %verticalForce = %throwForce / 2; %dot = vectorDot("0 0 1",%eye); if (%dot < 0) %dot = -%dot; %vec = vectorAdd(%vec,vectorScale("0 0 " @ %verticalForce,1 - %dot));

// Add the shape's velocity %vec = vectorAdd(%vec,%this.getVelocity());

// Set the object's position and initial velocity %pos = getBoxCenter(%this.getWorldBox()); %obj.setTransform(%pos);

135

Page 136:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

%obj.applyImpulse(%pos,%vec);

// Since the object is thrown from the center of the // shape, the object needs to avoid colliding with it's // thrower. %obj.setCollisionTimeout(%this);}

//-----------------------------------------------------------------------------// Callback hooks invoked by the inventory system//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// ShapeBase object callbacks invoked by the inventory system

function ShapeBase::onInventory(%this, %data, %value){ // Invoked on ShapeBase objects whenever their inventory changes // for the given datablock.}

//-----------------------------------------------------------------------------// ShapeBase datablock callback invoked by the inventory system.

function ShapeBaseData::onUse(%this,%user){ // Invoked when the object uses this datablock, should return // true if the item was used. return false;}

function ShapeBaseData::onThrow(%this,%user,%amount){ // Invoked when the object is thrown. This method should // construct and return the actual mission object to be // physically thrown. This method is also responsible for // decrementing the user's inventory. return 0;}

function ShapeBaseData::onPickup(%this,%obj,%user,%amount){ // Invoked when the user attempts to pickup this datablock object. // The %amount argument is the space in the user's inventory for // this type of datablock. This method is responsible for // incrementing the user's inventory is something is addded. // Should return true if something was added to the inventory. return false;}

function ShapeBaseData::onInventory(%this,%user,%value)

136

Page 137:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ // Invoked whenever an user's inventory total changes for // this datablock.}//-----------------------------------------------------------------------------// item.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

// These scripts make use of dynamic attribute values on Item datablocks,// these are as follows://// maxInventory Max inventory per object (100 bullets per box, etc.)// pickupName Name to display when client pickups item//// Item objects can have://// count The # of inventory items in the object. This// defaults to maxInventory if not set.

// Respawntime is the amount of time it takes for a static "auto-respawn"// object, such as an ammo box or weapon, to re-appear after it's been// picked up. Any item marked as "static" is automaticlly respawned.$Item::RespawnTime = 20 * 1000;

// Poptime represents how long dynamic items (those that are thrown or// dropped) will last in the world before being deleted.$Item::PopTime = 10 * 1000;

//-----------------------------------------------------------------------------// ItemData base class methods used by all items//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function Item::respawn(%this){ // This method is used to respawn static ammo and weapon items // and is usually called when the item is picked up. // Instant fade... %this.startFade(0, 0, true); %this.hide(true);

// Shedule a reapearance %this.schedule($Item::RespawnTime, "hide", false); %this.schedule($Item::RespawnTime + 100, "startFade", 1000, 0, false);}

137

Page 138:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function Item::schedulePop(%this){ // This method deletes the object after a default duration. Dynamic // items such as thrown or drop weapons are usually popped to avoid // world clutter. %this.schedule($Item::PopTime - 1000, "startFade", 1000, 0, true); %this.schedule($Item::PopTime, "delete");}

//-----------------------------------------------------------------------------// Callbacks to hook items into the inventory system

function ItemData::onThrow(%this,%user,%amount){ // Remove the object from the inventory if (%amount $= "") %amount = 1; if (%this.maxInventory !$= "") if (%amount > %this.maxInventory) %amount = %this.maxInventory; if (!%amount) return 0; %user.decInventory(%this,%amount);

// Construct the actual object in the world, and add it to // the mission group so it's cleaned up when the mission is // done. The object is given a random z rotation. %obj = new Item() { datablock = %this; rotation = "0 0 1 " @ (getRandom() * 360); count = %amount; }; MissionGroup.add(%obj); %obj.schedulePop(); return %obj;}

function ItemData::onPickup(%this,%obj,%user,%amount){ // Add it to the inventory, this currently ignores the request // amount, you get what you get. If the object doesn't have // a count or the datablock doesn't have maxIventory set, the // object cannot be picked up. %count = %obj.count; if (%count $= "") if (%this.maxInventory !$= "") { if (!(%count = %this.maxInventory)) return; } else %count = 1; %user.incInventory(%this,%count);

// Inform the client what they got.

138

Page 139:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if (%user.client) messageClient(%user.client, 'MsgItemPickup', '\c0You picked up %1', %this.pickupName);

// If the item is a static respawn item, then go ahead and // respawn it, otherwise remove it from the world. // Anything not taken up by inventory is lost. if (%obj.isStatic()) %obj.respawn(); else %obj.delete(); return true;}

//-----------------------------------------------------------------------------// Hook into the mission editor.

function ItemData::create(%data){ // The mission editor invokes this method when it wants to create // an object of the given datablock type. For the mission editor // we always create "static" re-spawnable rotating objects. %obj = new Item() { dataBlock = %data; static = true; rotate = true; }; return %obj;}

//-----------------------------------------------------------------------------// loadingGui.cs – fps\client\scripts\// //-----------------------------------------------------------------------------

//------------------------------------------------------------------------------function LoadingGui::onAdd(%this){ %this.qLineCount = 0;}

//------------------------------------------------------------------------------function LoadingGui::onWake(%this){ // Play sound... CloseMessagePopup();}

//------------------------------------------------------------------------------function LoadingGui::onSleep(%this)

139

Page 140:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ // Clear the load info: if ( %this.qLineCount !$= "" ) { for ( %line = 0; %line < %this.qLineCount; %line++ ) %this.qLine[%line] = ""; } %this.qLineCount = 0;

LOAD_MapName.setText( "" ); LOAD_MapDescription.setText( "" ); LoadingProgress.setValue( 0 ); LoadingProgressTxt.setValue( "WAITING FOR SERVER" );

// Stop sound...}

//-----------------------------------------------------------------------------// main.cs – common\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function initCommon(){ // All mods need the random seed set setRandomSeed();

// Very basic functions used by everyone exec("./client/canvas.cs"); exec("./client/audio.cs");}

function initBaseClient(){ // Base client functionality exec("./client/message.cs"); exec("./client/mission.cs"); exec("./client/missionDownload.cs"); exec("./client/actionMap.cs"); exec("./editor/editor.cs");

// There are also a number of support scripts loaded by the canvas // when it's first initialized. Check out client/canvas.cs}

function initBaseServer(){ // Base server functionality exec("./server/audio.cs"); exec("./server/server.cs"); exec("./server/message.cs");

140

Page 141:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

exec("./server/commands.cs"); exec("./server/missionInfo.cs"); exec("./server/missionLoad.cs"); exec("./server/missionDownload.cs"); exec("./server/clientConnection.cs"); exec("./server/kickban.cs");}

//-----------------------------------------------------------------------------package Common {

function displayHelp() { Parent::displayHelp(); error( "Common Mod options:\n"@ " -fullscreen Starts game in full screen mode\n"@ " -windowed Starts game in windowed mode\n"@ " -autoVideo Auto detect video, but prefers OpenGL\n"@ " -openGL Force OpenGL acceleration\n"@ " -directX Force DirectX acceleration\n"@ " -voodoo2 Force Voodoo2 acceleration\n"@ " -noSound Starts game without sound\n"@ " -prefs <configFile> Exec the config file\n" );}

function parseArgs(){ Parent::parseArgs();

// Load up defaults console values. exec("./defaults.cs");

// Arguments override defaults... for (%i = 1; %i < $Game::argc ; %i++) { %arg = $Game::argv[%i]; %nextArg = $Game::argv[%i+1]; %hasNextArg = $Game::argc - %i > 1; switch$ (%arg) { //-------------------- case "-fullscreen": $pref::Video::fullScreen = 1; $argUsed[%i]++;

//-------------------- case "-windowed": $pref::Video::fullScreen = 0; $argUsed[%i]++;

//-------------------- case "-noSound":

141

Page 142:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

error("no support yet"); $argUsed[%i]++;

//-------------------- case "-openGL": $pref::Video::displayDevice = "OpenGL"; $argUsed[%i]++;

//-------------------- case "-directX": $pref::Video::displayDevice = "D3D"; $argUsed[%i]++;

//-------------------- case "-voodoo2": $pref::Video::displayDevice = "Voodoo2"; $argUsed[%i]++;

//-------------------- case "-autoVideo": $pref::Video::displayDevice = ""; $argUsed[%i]++;

//-------------------- case "-prefs": $argUsed[%i]++; if (%hasNextArg) { exec(%nextArg, true, true); $argUsed[%i+1]++; %i++; } else error("Error: Missing Command Line argument. Usage: -prefs <path/script.cs>"); } }}

function onStart(){ Parent::onStart(); echo("\n--------- Initializing MOD: Common ---------"); initCommon();}

function onExit(){ OpenALShutdown(); Parent::onExit();}

}; // Common packageactivatePackage(Common);

//-----------------------------------------------------------------------------// main.cs – show\

142

Page 143:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// //-----------------------------------------------------------------------------

// For the show tool to have access to shapes and art in your game,// it must be run as a mod on top of your game.

//-----------------------------------------------------------------------------

function initShow(){ $showAutoDetail = false;

exec("~/ui/tsShowGui.gui"); exec("~/ui/tsShowLoadDlg.gui"); exec("~/ui/tsShowMiscDlg.gui"); exec("~/ui/tsShowThreadControlDlg.gui"); exec("~/ui/tsShowEditScale.gui"); exec("~/ui/tsShowLightDlg.gui"); exec("~/ui/tsShowTransitionDlg.gui"); exec("~/ui/tsShowTranDurEditDlg.gui"); exec("~/ui/tsShowDetailControlDlg.gui");

exec("~/scripts/show.bind.cs");}

//-----------------------------------------------------------------------------

function stopShow(){ Canvas.popDialog(TSShowThreadControlDlg); Canvas.popDialog(TSShowTransitionDlg); Canvas.popDialog(TSShowLoadDialog); Canvas.popDialog(TSShowLightDlg); Canvas.popDialog(TSShowMiscDialog); Canvas.popDialog(TShowEditScale); Canvas.popDialog(TSShowDetailControlDlg);

showMoveMap.pop(); quit();}

//-----------------------------------------------------------------------------

function startShow(){ // The client mod has already set it's own content, but we'll // just load something new. Canvas.setContent(TSShowGui); Canvas.setCursor("DefaultCursor");

$showShapeList = nextToken(trim($showShapeList), shape, " ");

143

Page 144:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

while (%shape !$= "") { showShapeLoad(%shape); $showShapeList = nextToken($showShapeList, shape, " "); }}

//-----------------------------------------------------------------------------// Package overrides to initialize the mod.// This module currently loads on top of the client mod, but it probably// doesn't need to. Should look into having disabling the client and// doing our own canvas init.package Show {

function displayHelp() { Parent::displayHelp(); error( "Show Mod options:\n"@ " -show <shape> Launch the TS show tool\n"@ " -file <shape> Load the mission\n" );}

function parseArgs(){ Parent::parseArgs(); exec("./defaults.cs"); exec("./prefs.cs");

for (%i = 1; %i < $Game::argc ; %i++) { %arg = $Game::argv[%i]; %nextArg = $Game::argv[%i+1]; %hasNextArg = $Game::argc - %i > 1; switch$ (%arg) { //------------------- case "-show": $argUsed[%i]++; // The "-mod show" shortcut can have an optional file argument if (%hasNextArg && strpos(%nextArg, "-") == -1) { $showShapeList = $showShapeList @ " " @ %nextArg; $argUsed[%i+1]++; %i++; }

//------------------- case "-file": // Load a file $argUsed[%i]++; if (%hasNextArg) {

144

Page 145:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

$showShapeList = $showShapeList @ " " @ %nextArg; $argUsed[%i+1]++; %i++; } else error("Error: Missing Command Line argument. Usage: -file <file_name>"); } }}

function onStart(){ Parent::onStart(); echo("\n--------- Initializing MOD: Show ---------");

if (!isObject(Canvas)) { // If the parent onStart didn't open a canvas, then we're // probably not running as a mod. We'll have to do the work // ourselves. initCanvas("Torque Show Tool"); } initShow(); startShow();}

}; // Show packageactivatePackage(Show);

//-----------------------------------------------------------------------------// main.cs – fps\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Package overrides to initialize the mod.package fps {

function displayHelp() { Parent::displayHelp(); error( "Fps Mod options:\n"@ " -prefs <configFile> Exec the config file\n"@ " -connect <address> Connects to a game at <address>\n" @ " -mission <mission> Load the mission\n" );}

function parseArgs(){ Parent::parseArgs();

// Defaults console values exec("./client/defaults.cs");

145

Page 146:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

exec("./server/defaults.cs");

// Preferences (overide defaults) exec("./client/prefs.cs"); exec("./server/prefs.cs");

// Arguments, which override everything else. for (%i = 1; %i < $Game::argc ; %i++) { %arg = $Game::argv[%i]; %nextArg = $Game::argv[%i+1]; %hasNextArg = $Game::argc - %i > 1; switch$ (%arg) { //-------------------- case "-dedicated": $Server::Dedicated = true; enableWinConsole(true); $argUsed[%i]++;

//-------------------- case "-mission": $argUsed[%i]++; if (%hasNextArg) { $missionArg = %nextArg; $argUsed[%i+1]++; %i++; } else error("Error: Missing Command Line argument. Usage: -mission <mission_name>");

//-------------------- case "-connect": $argUsed[%i]++; if (%hasNextArg) { $JoinGameAddress = %nextArg; $argUsed[%i+1]++; %i++; } else error("Error: Missing Command Line argument. Usage: -connect <ip_address>"); } }}

function onStart(){ Parent::onStart(); echo("\n--------- Initializing MOD: FPS ---------");

// Load the scripts that start it all... exec("./client/init.cs"); exec("./server/init.cs"); exec("./data/init.cs");

146

Page 147:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

// Server gets loaded for all sessions, since clients // can host in-game servers. initServer();

// Start up in either client, or dedicated server mode if ($Server::Dedicated) initDedicated(); else initClient();}

function onExit(){ echo("Exporting client prefs"); export("$pref::*", "./client/prefs.cs", False);

echo("Exporting server prefs"); export("$Pref::Server::*", "./server/prefs.cs", False); BanList::Export("./server/banlist.cs");

Parent::onExit();}

}; // Client packageactivatePackage(fps);

//-----------------------------------------------------------------------------// markers.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

datablock MissionMarkerData(WayPointMarker){ category = "Misc"; shapeFile = "~/data/shapes/markers/octahedron.dts";};

datablock MissionMarkerData(SpawnSphereMarker){ category = "Misc"; shapeFile = "~/data/shapes/markers/octahedron.dts";};

//------------------------------------------------------------------------------// - serveral marker types may share MissionMarker datablock typefunction MissionMarkerData::create(%block){ switch$(%block) { case "WayPointMarker": %obj = new WayPoint() { dataBlock = %block;

147

Page 148:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}; return(%obj); case "SpawnSphereMarker": %obj = new SpawnSphere() { datablock = %block; }; return(%obj); } return(-1);}

//-----------------------------------------------------------------------------// message.cs – common\server\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Server side message commands//-----------------------------------------------------------------------------

function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13){ commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);}

function messageTeam(%team, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13){ %count = ClientGroup.getCount(); for(%cl= 0; %cl < %count; %cl++) { %recipient = ClientGroup.getObject(%cl);

if(%recipient.team == %team) messageClient(%recipient, %msgType, %msgString, %a1, %a2,

%a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); }}

function messageTeamExcept(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13){ %team = %client.team; %count = ClientGroup.getCount(); for(%cl= 0; %cl < %count; %cl++) { %recipient = ClientGroup.getObject(%cl);

if((%recipient.team == %team) && (%recipient != %client)) messageClient(%recipient, %msgType, %msgString, %a1, %a2,

%a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); }}

148

Page 149:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13){ %count = ClientGroup.getCount(); for(%cl = 0; %cl < %count; %cl++) { %client = ClientGroup.getObject(%cl); messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); }}

function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13){ //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1). %count = ClientGroup.getCount(); for(%cl= 0; %cl < %count; %cl++) { %recipient = ClientGroup.getObject(%cl); if((%recipient != %client) && (%recipient.team != %team)) messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); }}

//---------------------------------------------------------------------------// Server side client chat'n//---------------------------------------------------------------------------

//---------------------------------------------------------------------------// silly spam protection...$SPAM_PROTECTION_PERIOD = 10000;$SPAM_MESSAGE_THRESHOLD = 4;$SPAM_PENALTY_PERIOD = 10000;$SPAM_MESSAGE = '\c3FLOOD PROTECTION:\cr You must wait another %1 seconds.';

function GameConnection::spamMessageTimeout(%this){ if(%this.spamMessageCount > 0) %this.spamMessageCount--;}

function GameConnection::spamReset(%this){ %this.isSpamming = false;}

149

Page 150:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function spamAlert(%client){ if($Pref::Server::FloodProtectionEnabled != true) return(false);

if(!%client.isSpamming && (%client.spamMessageCount >= $SPAM_MESSAGE_THRESHOLD)) { %client.spamProtectStart = getSimTime(); %client.isSpamming = true; %client.schedule($SPAM_PENALTY_PERIOD, spamReset); }

if(%client.isSpamming) { %wait = mFloor(($SPAM_PENALTY_PERIOD - (getSimTime() - %client.spamProtectStart)) / 1000); messageClient(%client, "", $SPAM_MESSAGE, %wait); return(true); }

%client.spamMessageCount++; %client.schedule($SPAM_PROTECTION_PERIOD, spamMessageTimeout); return(false);}

//---------------------------------------------------------------------------

function chatMessageClient( %client, %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ){

//see if the client has muted the senderif ( !%client.muted[%sender] ) commandToClient( %client, 'ChatMessage', %sender, %voiceTag,

%voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );}

function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ){ if ( ( %msgString $= "" ) || spamAlert( %sender ) ) return; %count = ClientGroup.getCount(); for ( %i = 0; %i < %count; %i++ ) { %obj = ClientGroup.getObject( %i ); if ( %obj.team == %sender.team ) chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ); }}

150

Page 151:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 ){ if ( ( %msgString $= "" ) || spamAlert( %sender ) ) return; %count = ClientGroup.getCount(); for ( %i = 0; %i < %count; %i++ ) {

%obj = ClientGroup.getObject( %i );if(%sender.team != 0)

chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );

else{

// message sender is an observer -- only send message to other observers

if(%obj.team == %sender.team) chatMessageClient( %obj, %sender, %sender.voiceTag,

%sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );

}}

}

//-----------------------------------------------------------------------------// message.cs – common\client\// //-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Messages and client chat server handlers. Since the base client// does not provide any GUI interfaces, the processed messages are// handed off to local message handlers for display://// onServerMessage(%mesg)// onChatMessage(%mesg)////-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------// Server Messages//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10){ %tag = getWord(%msgType, 0);

151

Page 152:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

for(%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); if(%tag !$= "") for(%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10);}

//-----------------------------------------------------------------------------

function addMessageCallback(%msgType, %func){ for(%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) { // only add each callback once if(%afunc $= %func) return; } $MSGCB[%msgType, %i] = %func;}

//-----------------------------------------------------------------------------

function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10){ if ( %msgString $= "" ) return; %message = detag( %msgString ); // search for wav tag marker %wavStart = strstr( %message, "~w" ); if ( %wavStart != -1 ) { %wav = getSubStr( %message, %wavStart + 2, 1000 ); %wavLengthMS = alxGetWaveLen( %wav ); if ( %wavLengthMS <= $MaxMessageWavLength ) { %handle = alxCreateSource( AudioChat, %wav ); alxPlay( %handle ); } else error( "WAV file \"" @ %wav @ "\" is too long! **" );

%message = getSubStr( %message, 0, %wavStart ); if ( %message !$= "" ) onServerMessage( %message ); } else

onServerMessage( %message );}

152

Page 153:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//---------------------------------------------------------------------------// Register the default message handler right awayaddMessageCallback("",defaultMessageCallback);

//---------------------------------------------------------------------------// Server Chat Messages//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10){ %message = detag( %msgString );

if (%message $= "") return; // search for wav tag marker %wavStart = strstr( %message, "~w" ); if ( %wavStart == -1 ) onChatMessage( %message ); else { %wav = getSubStr(%message, %wavStart + 2, 1000); if (%voice !$= "") %wavFile = "voice/" @ %voice @ "/" @ %wav @ ".wav"; else %wavFile = %wav;

//only play voice files that are < 5000ms in length if (%pitch < 0.5 || %pitch > 2.0) %pitch = 1.0; %wavLengthMS = alxGetWaveLen(%wavFile) * %pitch; if (%wavLengthMS < $MaxMessageWavLength ) { if ( $ClientChatHandle[%sender] != 0 ) alxStop( $ClientChatHandle[%sender] ); $ClientChatHandle[%sender] = alxCreateSource( AudioChat, %wavFile );

//pitch the handle if (%pitch != 1.0) alxSourcef($ClientChatHandle[%sender], "AL_PITCH", %pitch); alxPlay( $ClientChatHandle[%sender] ); } else error( "** WAV file \"" @ %wavFile @ "\" is too long! **" );

%message = getSubStr(%message, 0, %wavStart); onChatMessage(%message); }

153

Page 154:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

//-----------------------------------------------------------------------------// messageBox.cs – common\client\// //-----------------------------------------------------------------------------

function MessageCallback(%dlg,%callback){ Canvas.popDialog(%dlg); eval(%callback);}

// MBSetText resizes the message window, based on the change in size of the text// area.

function MBSetText(%text, %frame, %msg){ %ext = %text.getExtent();

%text.setText("<just:center>" @ %msg); %text.forceReflow();

%newExtent = %text.getExtent();

%deltaY = getWord(%newExtent, 1) - getWord(%ext, 1); %windowPos = %frame.getPosition(); %windowExt = %frame.getExtent();

%frame.resize(getWord(%windowPos, 0), getWord(%windowPos, 1) - (%deltaY / 2), getWord(%windowExt, 0), getWord(%windowExt, 1) + %deltaY);}

//-----------------------------------------------------------------------------// MessageBox OK//-----------------------------------------------------------------------------

function MessageBoxOK( %title, %message, %callback ){

MBOKFrame.setText( %title ); Canvas.pushDialog( MessageBoxOKDlg ); MBSetText(MBOKText, MBOKFrame, %message); MessageBoxOKDlg.callback = %callback;}

//------------------------------------------------------------------------------function MessageBoxOKDlg::onSleep( %this ){ %this.callback = "";}

154

Page 155:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//------------------------------------------------------------------------------// MessageBox OK/Cancel dialog://------------------------------------------------------------------------------

function MessageBoxOKCancel( %title, %message, %callback, %cancelCallback ){

MBOKCancelFrame.setText( %title ); Canvas.pushDialog( MessageBoxOKCancelDlg ); MBSetText(MBOKCancelText, MBOKCancelFrame, %message);

MessageBoxOKCancelDlg.callback = %callback;MessageBoxOKCancelDlg.cancelCallback = %cancelCallback;

}

//------------------------------------------------------------------------------function MessageBoxOKCancelDlg::onSleep( %this ){ %this.callback = "";}

//------------------------------------------------------------------------------// MessageBox Yes/No dialog://------------------------------------------------------------------------------

function MessageBoxYesNo( %title, %message, %yesCallback, %noCallback ){

MBYesNoFrame.setText( %title ); Canvas.pushDialog( MessageBoxYesNoDlg ); MBSetText(MBYesNoText, MBYesNoFrame, %message);

MessageBoxYesNoDlg.yesCallBack = %yesCallback;MessageBoxYesNoDlg.noCallback = %noCallBack;

}

//------------------------------------------------------------------------------function MessageBoxYesNoDlg::onSleep( %this ){ %this.yesCallback = ""; %this.noCallback = "";}

//------------------------------------------------------------------------------// Message popup dialog://------------------------------------------------------------------------------

function MessagePopup( %title, %message, %delay ){ // Currently two lines max. MessagePopFrame.setText( %title );

155

Page 156:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Canvas.pushDialog( MessagePopupDlg ); MBSetText(MessagePopText, MessagePopFrame, %message); if ( %delay !$= "" ) schedule( %delay, 0, CloseMessagePopup );}

//------------------------------------------------------------------------------

function CloseMessagePopup(){ Canvas.popDialog( MessagePopupDlg );}

//-----------------------------------------------------------------------------// player.cs – fps\data\shapes\// //-----------------------------------------------------------------------------

datablock TSShapeConstructor(PlayerDts){ baseShape = "./player.dts"; sequence0 = "./player_root.dsq root"; sequence1 = "./player_forward.dsq run"; sequence2 = "./player_back.dsq back"; sequence3 = "./player_side.dsq side"; sequence4 = "./player_lookde.dsq look"; sequence5 = "./player_head.dsq head"; sequence6 = "./player_fall.dsq fall"; sequence7 = "./player_land.dsq land"; sequence8 = "./player_jump.dsq jump"; sequence9 = "./player_diehead.dsq death1"; sequence10 = "./player_diechest.dsq death2"; sequence11 = "./player_dieback.dsq death3"; sequence12 = "./player_diesidelf.dsq death4"; sequence13 = "./player_diesidert.dsq death5"; sequence14 = "./player_dieleglf.dsq death6"; sequence15 = "./player_dielegrt.dsq death7"; sequence16 = "./player_dieslump.dsq death8"; sequence17 = "./player_dieknees.dsq death9"; sequence18 = "./player_dieforward.dsq death10"; sequence19 = "./player_diespin.dsq death11"; sequence20 = "./player_looksn.dsq looksn"; sequence21 = "./player_lookms.dsq lookms"; sequence22 = "./player_scoutroot.dsq scoutroot"; sequence23 = "./player_headside.dsq headside"; sequence24 = "./player_recoilde.dsq light_recoil"; sequence25 = "./player_sitting.dsq sitting"; sequence26 = "./player_celsalute.dsq celsalute"; sequence27 = "./player_celwave.dsq celwave"; sequence28 = "./player_standjump.dsq standjump"; sequence29 = "./player_looknw.dsq looknw";};

156

Page 157:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// redplayer.cs - fps\data\shapes\// //-----------------------------------------------------------------------------

datablock TSShapeConstructor(RedPlayerDts){ baseShape = "./redplayer.dts"; sequence0 = "./player_root.dsq root"; sequence1 = "./player_forward.dsq run"; sequence2 = "./player_back.dsq back"; sequence3 = "./player_side.dsq side"; sequence4 = "./player_lookde.dsq look"; sequence5 = "./player_head.dsq head"; sequence6 = "./player_fall.dsq fall"; sequence7 = "./player_land.dsq land"; sequence8 = "./player_jump.dsq jump"; sequence9 = "./player_diehead.dsq death1"; sequence10 = "./player_diechest.dsq death2"; sequence11 = "./player_dieback.dsq death3"; sequence12 = "./player_diesidelf.dsq death4"; sequence13 = "./player_diesidert.dsq death5"; sequence14 = "./player_dieleglf.dsq death6"; sequence15 = "./player_dielegrt.dsq death7"; sequence16 = "./player_dieslump.dsq death8"; sequence17 = "./player_dieknees.dsq death9"; sequence18 = "./player_dieforward.dsq death10"; sequence19 = "./player_diespin.dsq death11"; sequence20 = "./player_looksn.dsq looksn"; sequence21 = "./player_lookms.dsq lookms"; sequence22 = "./player_scoutroot.dsq scoutroot"; sequence23 = "./player_headside.dsq headside"; sequence24 = "./player_recoilde.dsq light_recoil"; sequence25 = "./player_sitting.dsq sitting"; sequence26 = "./player_celsalute.dsq celsalute"; sequence27 = "./player_celwave.dsq celwave"; sequence28 = "./player_standjump.dsq standjump"; sequence29 = "./player_looknw.dsq looknw";};

//------------------------------------------------------------------------------// Vehicles.cs – fps\server\scripts\//------------------------------------------------------------------------------

datablock ParticleData(VehicleFoamParticle){ dragCoefficient = 2.0; gravityCoefficient = -0.05; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 1200;

157

Page 158:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

lifetimeVarianceMS = 400; useInvAlpha = false; spinRandomMin = -90.0; spinRandomMax = 500.0; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0.7 0.8 1.0 1.0"; colors[1] = "0.7 0.8 1.0 0.5"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 2; sizes[1] = 4; sizes[2] = 6; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData(VehicleFoamEmitter){ ejectionPeriodMS = 40; periodVarianceMS = 0; ejectionVelocity = 10.0; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 85; thetaMax = 85; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "VehicleFoamParticle";};

datablock ParticleData( VehicleFoamDropletsParticle ){ dragCoefficient = 1; gravityCoefficient = 0.2; inheritedVelFactor = 0.2; constantAcceleration = -0.0; lifetimeMS = 800; lifetimeVarianceMS = 300; textureName = "~/data/shapes/particles/smoke"; colors[0] = "0.7 0.8 1.0 1.0"; colors[1] = "0.7 0.8 1.0 0.5"; colors[2] = "0.7 0.8 1.0 0.0"; sizes[0] = 8; sizes[1] = 3; sizes[2] = 0; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0;};

datablock ParticleEmitterData( VehicleFoamDropletsEmitter ){ ejectionPeriodMS = 34; periodVarianceMS = 0; ejectionVelocity = 10;

158

Page 159:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

velocityVariance = 5.0; ejectionOffset = 0.0; thetaMin = 60; thetaMax = 80; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; particles = "VehicleFoamDropletsParticle";};

function VehicleData::onAdd(%data, %obj){

%obj.setRechargeRate(%data.rechargeRate);

// %obj.mountImage(MissileLauncherImage, 0); // Optional Weapon Mounting

if(%obj.disableMove)%obj.immobilized = true;

}

function VehicleData::onRemove(%this, %obj){

// if there are passengers/driver, kick them outfor(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++){

if (%obj.getMountNodeObject(%i)) {

%passenger = %obj.getMountNodeObject(%i);%passenger.unmount();

}}if(%obj.lastPilot.lastVehicle == %obj)

%obj.lastPilot.lastVehicle = ""; }

function VehicleData::playerDismounted(%data, %obj, %player){

if( %player.client.observeCount > 0 )resetObserveFollow( %player.client, true );

}

function VehicleData::hasDismountOverrides(%data, %obj){ return false;}

function FlyingVehicleData::create(%data, %team, %oldObj){ if(%oldObj $= "") { %obj = new FlyingVehicle() { dataBlock = %data; respawn = "0"; teamBought = %team;

159

Page 160:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

team = %team; }; } else { %obj = new FlyingVehicle() { dataBlock = %data; respawn = "0"; teamBought = %team; team = %team; mountable = %oldObj.mountable; disableMove = %oldObj.disableMove; resetPos = %oldObj.resetPos; deployed = %oldObj.deployed; respawnTime = %oldObj.respawnTime; marker = %oldObj; }; } %obj.mountable = true; return(%obj);}

function WaterCraftData::create(%data, %team, %oldObj){ if(%oldObj $= "") { %obj = new WaterCraft() { dataBlock = %data; respawn = "0"; teamBought = %team; team = %team; }; } else { %obj = new WaterCraft() { dataBlock = %data; respawn = "0"; teamBought = %team; team = %team; mountable = %oldObj.mountable; disableMove = %oldObj.disableMove; resetPos = %oldObj.resetPos; deployed = %oldObj.deployed; respawnTime = %oldObj.respawnTime; marker = %oldObj; }; } %obj.mountable = true;

return(%obj);}

160

Page 161:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

function HoverVehicleData::create(%data, %team, %oldObj){ if(%oldObj $= "") { %obj = new HoverVehicle() { dataBlock = %data; respawn = "0"; teamBought = %team; team = %team; }; } else { %obj = new HoverVehicle() { dataBlock = %data; respawn = "0"; teamBought = %team; team = %team; mountable = %oldObj.mountable; disableMove = %oldObj.disableMove; resetPos = %oldObj.resetPos; deployed = %oldObj.deployed; respawnTime = %oldObj.respawnTime; marker = %oldObj; }; } %obj.mountable = true;

return(%obj);}

//-----------------------------------------------------------------------------// weapon.cs – fps\server\scripts\// //-----------------------------------------------------------------------------

// This file contains Weapon and Ammo Class/"namespace" helper methods// as well as hooks into the inventory system. These functions are not// attached to a specific C++ class or datablock, but define a set of// methods which are part of dynamic namespaces "class". The Items// include these namespaces into their scope using the ItemData and// ItemImageData "className" variable.

// All ShapeBase images are mounted into one of 8 slots on a shape.// This weapon system assumes all primary weapons are mounted into// this specified slot:$WeaponSlot = 0;

//-----------------------------------------------------------------------------// Weapon Class

161

Page 162:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function Weapon::onUse(%data,%obj){ // Default behavoir for all weapons is to mount it into the // this object's weapon slot, which is currently assumed // to be slot 0 if (%obj.getMountedImage($WeaponSlot) != %data.image.getId()) { %obj.mountImage(%data.image, $WeaponSlot); if (%obj.client) messageClient(%obj.client, 'MsgWeaponUsed', '\c0Weapon selected'); }}

function Weapon::onPickup(%this, %obj, %shape, %amount){ // The parent Item method performs the actual pickup. // For player's we automatically use the weapon if the // player does not already have one in hand. if (Parent::onPickup(%this, %obj, %shape, %amount)) { if (%shape.getClassName() $= "Player" && %shape.getMountedImage($WeaponSlot) == 0) { %shape.use(%this); } }}

function Weapon::onInventory(%this,%obj,%amount){ // Weapon inventory has changed, make sure there are no weapons // of this type mounted if there are none left in inventory. if (!%amount && (%slot = %obj.getMountSlot(%this.image)) != -1) %obj.unmountImage(%slot);}

//-----------------------------------------------------------------------------// Weapon Image Class//-----------------------------------------------------------------------------

function WeaponImage::onMount(%this,%obj,%slot){ // Images assume a false ammo state on load. We need to // set the state according to the current inventory. if (%obj.getInventory(%this.ammo)) %obj.setImageAmmo(%slot,true);}

//-----------------------------------------------------------------------------// Ammmo Class

162

Page 163:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

function Ammo::onInventory(%this,%obj,%amount){ // The ammo inventory state has changed, we need to update any // mounted images using this ammo to reflect the new state. for (%i = 0; %i < 8; %i++) { if ((%image = %obj.getMountedImage(%i)) > 0) if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId()) %obj.setImageAmmo(%i,%amount != 0); }}

//-----------------------------------------------------------------------------// WaterCraft.h - \engine\game\vehicles//-----------------------------------------------------------------------------

#ifndef _WATERCRAFT_H_#define _WATERCRAFT_H_

#ifndef _VEHICLE_H_#include "game/vehicles/vehicle.h"#endif

// Forward class declarationsclass ParticleEmitter;class ParticleEmitterData;

// -------------------------------------------------------------------------class WaterCraftData : public VehicleData{ typedef VehicleData Parent;

protected: bool onAdd();

//-------------------------------------- Console set variables public: enum Sounds { JetSound, EngineSound, FloatSound, MaxSounds }; AudioProfile* sound[MaxSounds];

enum Jets { // These enums index into a static name list. ForwardJetEmitter, // Thrust forward BackwardJetEmitter, // Thrust backward DownwardJetEmitter, // Thrust down

163

Page 164:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

MaxJetEmitters, }; ParticleEmitterData* jetEmitter[MaxJetEmitters];

enum JetNodes { // These enums index into a static name list. ForwardJetNode, ForwardJetNode1, BackwardJetNode, BackwardJetNode1, DownwardJetNode, DownwardJetNode1, MaxJetNodes, MaxDirectionJets = 2, ThrustJetStart = ForwardJetNode, MaxTrails = 4, }; static const char *sJetNode[MaxJetNodes]; S32 jetNode[MaxJetNodes];

// --------------------------------- Scriptable data variables F32 dragForce; F32 vertFactor; F32 floatingThrustFactor;

F32 mainThrustForce; F32 reverseThrustForce; F32 strafeThrustForce; F32 turboFactor;

F32 stabLenMin; F32 stabLenMax; F32 stabSpringConstant; F32 stabDampingConstant;

F32 gyroDrag; F32 normalForce; F32 restorativeForce; F32 steeringForce; F32 rollForce; F32 pitchForce;

F32 floatingGravMag;

F32 brakingForce; F32 brakingActivationSpeed; ParticleEmitterData * dustTrailEmitter; S32 dustTrailID; Point3F dustTrailOffset; F32 triggerTrailHeight; F32 dustTrailFreqMod;

//-------------------------------------- load set variables public: F32 maxThrustSpeed;

164

Page 165:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

public: WaterCraftData(); ~WaterCraftData();

void packData(BitStream*); void unpackData(BitStream*); bool preload(bool server, char errorBuffer[256]);

DECLARE_CONOBJECT(WaterCraftData); static void initPersistFields();};

// -------------------------------------------------------------------------class WaterCraft : public Vehicle{ typedef Vehicle Parent;

private: WaterCraftData* mDataBlock; ParticleEmitter * mDustTrailEmitter;

protected: bool onAdd(); void onRemove(); bool onNewDataBlock(GameBaseData*); void updateDustTrail( F32 dt );

// Vehicle overrides protected: void updateMove(const Move *move); void updateWarp();

// Physics protected: void updateForces(F32); F32 getBaseStabilizerLength() const;

bool mFloating; F32 mThrustLevel;

F32 mForwardThrust; F32 mReverseThrust; F32 mLeftThrust; F32 mRightThrust;

// Sounds AUDIOHANDLE mJetSound; AUDIOHANDLE mEngineSound; AUDIOHANDLE mFloatSound;

enum ThrustDirection { // Enums index into sJetActivationTable ThrustForward, ThrustBackward, ThrustDown,

165

Page 166:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

NumThrustDirections, NumThrustBits = 3 }; ThrustDirection mThrustDirection;

// Jet Threads enum Jets { // These enums index into a static name list. BackActivate, BackMaintain, JetAnimCount }; static const char* sJetSequence[WaterCraft::JetAnimCount]; TSThread* mJetThread[JetAnimCount]; S32 mJetSeq[JetAnimCount]; bool mBackMaintainOn;

// Jet Particles struct JetActivation { // Convert thrust direction into nodes & emitters S32 node; S32 emitter; }; static JetActivation sJetActivation[NumThrustDirections]; SimObjectPtr<ParticleEmitter> mJetEmitter[WaterCraftData::MaxJetNodes]; U32 getCollisionMask(); void updateJet(F32 dt); void updateEmitter(bool active,F32 dt,ParticleEmitterData *emitter,S32 idx,S32 count); public: bool nestMountable; bool helmMountable; bool cannonMountable; MatrixF prevTransform; WaterCraft(); ~WaterCraft();

// Time/Move Management public:

void advanceTime(F32);

DECLARE_CONOBJECT(WaterCraft); static void initPersistFields(); static void consoleInit();

U32 packUpdate(NetConnection*, U32 mask, BitStream* stream); void unpackUpdate(NetConnection*, BitStream* stream);};

#endif // _H_WATERCRAFT//-----------------------------------------------------------------------------// Watercraft.cc - \engine\game\vehicles

166

Page 167:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------

#include "game/vehicles/WaterCraft.h"#include "core/bitStream.h"#include "dgl/dgl.h"#include "sceneGraph/sceneState.h"#include "collision/clippedPolyList.h"#include "collision/planeExtractor.h"#include "game/moveManager.h"#include "ts/tsShapeInstance.h"#include "console/consoleTypes.h"#include "terrain/terrData.h"#include "sceneGraph/sceneGraph.h"#include "audio/audio.h"#include "game/fx/particleEngine.h"#include "math/mathIO.h"#include "dgl/materialPropertyMap.h"#include "terrain/waterBlock.h"

IMPLEMENT_CO_DATABLOCK_V1(WaterCraftData);IMPLEMENT_CO_NETOBJECT_V1(WaterCraft);

namespace {

const U32 sIntergrationsPerTick = 1;const F32 sWaterCraftGravity = -20;

const U32 sCollisionMoveMask = (TerrainObjectType | InteriorObjectType | PlayerObjectType | StaticTSObjectType | StaticShapeObjectType | VehicleObjectType | VehicleBlockerObjectType | ForceFieldObjectType);

const U32 sServerCollisionMask = sCollisionMoveMask; // ItemObjectTypeconst U32 sClientCollisionMask = sCollisionMoveMask;

void nonFilter(SceneObject* object,S32 key){ Container::CallbackInfo* info = reinterpret_cast<Container::CallbackInfo*>(key); object->buildPolyList(info->polyList,info->boundingBox,info->boundingSphere);}

} // namespace {}

const char* WaterCraft::sJetSequence[WaterCraft::JetAnimCount] ={ "activateBack", "maintainBack",};

const char* WaterCraftData::sJetNode[WaterCraftData::MaxJetNodes] =

167

Page 168:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ "JetNozzle0", // Thrust Forward "JetNozzle1", "JetNozzleX", // Thrust Backward "JetNozzleX", "JetNozzle2", // Thrust Downward "JetNozzle3",};

// Convert thrust direction into nodes & emittersWaterCraft::JetActivation WaterCraft::sJetActivation[NumThrustDirections] = { { WaterCraftData::ForwardJetNode, WaterCraftData::ForwardJetEmitter }, { WaterCraftData::BackwardJetNode, WaterCraftData::BackwardJetEmitter }, { WaterCraftData::DownwardJetNode, WaterCraftData::DownwardJetEmitter },};//--------------------------------------------------------------------------WaterCraftData::WaterCraftData(){ dragForce = 0; vertFactor = 0.25; floatingThrustFactor = 0.15;

mainThrustForce = 0; reverseThrustForce = 0; strafeThrustForce = 0; turboFactor = 1.0;

stabLenMin = 0.5; stabLenMax = 2.0; stabSpringConstant = 30; stabDampingConstant = 10;

gyroDrag = 10; normalForce = 30; restorativeForce = 10; steeringForce = 25; rollForce = 2.5; pitchForce = 2.5;

dustTrailEmitter = NULL; dustTrailID = 0; dustTrailOffset.set( 0.0, 0.0, 0.0 ); dustTrailFreqMod = 15.0; triggerTrailHeight = 2.5;

floatingGravMag = 1; brakingForce = 0; brakingActivationSpeed = 0; for (S32 k = 0; k < MaxJetNodes; k++) jetNode[k] = -1;

168

Page 169:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

for (S32 j = 0; j < MaxJetEmitters; j++) jetEmitter[j] = 0;

for (S32 i = 0; i < MaxSounds; i++) sound[i] = 0;}

WaterCraftData::~WaterCraftData(){

}

//--------------------------------------------------------------------------void WaterCraftData::initPersistFields(){ Parent::initPersistFields();

addField("dragForce", TypeF32, Offset(dragForce, WaterCraftData)); addField("vertFactor", TypeF32, Offset(vertFactor, WaterCraftData)); addField("floatingThrustFactor", TypeF32, Offset(floatingThrustFactor, WaterCraftData)); addField("mainThrustForce", TypeF32, Offset(mainThrustForce, WaterCraftData)); addField("reverseThrustForce", TypeF32, Offset(reverseThrustForce, WaterCraftData)); addField("strafeThrustForce", TypeF32, Offset(strafeThrustForce, WaterCraftData)); addField("turboFactor", TypeF32, Offset(turboFactor, WaterCraftData));

addField("stabLenMin", TypeF32, Offset(stabLenMin, WaterCraftData)); addField("stabLenMax", TypeF32, Offset(stabLenMax, WaterCraftData)); addField("stabSpringConstant", TypeF32, Offset(stabSpringConstant, WaterCraftData)); addField("stabDampingConstant", TypeF32, Offset(stabDampingConstant, WaterCraftData));

addField("gyroDrag", TypeF32, Offset(gyroDrag, WaterCraftData)); addField("normalForce", TypeF32, Offset(normalForce, WaterCraftData)); addField("restorativeForce", TypeF32, Offset(restorativeForce, WaterCraftData)); addField("steeringForce", TypeF32, Offset(steeringForce, WaterCraftData)); addField("rollForce", TypeF32, Offset(rollForce, WaterCraftData)); addField("pitchForce", TypeF32, Offset(pitchForce, WaterCraftData));

169

Page 170:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

addField("jetSound", TypeAudioProfilePtr, Offset(sound[JetSound], WaterCraftData)); addField("engineSound", TypeAudioProfilePtr, Offset(sound[EngineSound], WaterCraftData)); addField("floatSound", TypeAudioProfilePtr, Offset(sound[FloatSound], WaterCraftData));

addField("dustTrailEmitter", TypeParticleEmitterDataPtr, Offset(dustTrailEmitter, WaterCraftData)); addField("dustTrailOffset", TypePoint3F, Offset(dustTrailOffset, WaterCraftData)); addField("triggerTrailHeight", TypeF32, Offset(triggerTrailHeight, WaterCraftData)); addField("dustTrailFreqMod", TypeF32, Offset(dustTrailFreqMod, WaterCraftData));

addField("floatingGravMag", TypeF32, Offset(floatingGravMag, WaterCraftData)); addField("brakingForce", TypeF32, Offset(brakingForce, WaterCraftData)); addField("brakingActivationSpeed", TypeF32, Offset(brakingActivationSpeed, WaterCraftData));

addField("forwardJetEmitter",TypeParticleEmitterDataPtr, Offset(jetEmitter[ForwardJetEmitter], WaterCraftData));}

//--------------------------------------------------------------------------bool WaterCraftData::onAdd(){ if(!Parent::onAdd()) return false;

return true;}

bool WaterCraftData::preload(bool server, char errorBuffer[256]){ if (Parent::preload(server, errorBuffer) == false) return false;

if (dragForce <= 0.01f) { Con::warnf("WaterCraftData::preload: dragForce must be at least 0.01"); dragForce = 0.01f; } if (vertFactor < 0.0f || vertFactor > 1.0f) { Con::warnf("WaterCraftData::preload: vert factor must be [0, 1]"); vertFactor = vertFactor < 0.0f ? 0.0f : 1.0f; } if (floatingThrustFactor < 0.0f || floatingThrustFactor > 1.0f) { Con::warnf("WaterCraftData::preload: floatingThrustFactor must be [0, 1]"); floatingThrustFactor = floatingThrustFactor < 0.0f ? 0.0f : 1.0f; } if (mainThrustForce <= 0.0f) {

170

Page 171:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Con::warnf("WaterCraftData::preload: mainThrustForce must be [0, 1]"); mainThrustForce = 1.0f; }

maxThrustSpeed = (mainThrustForce + strafeThrustForce) / dragForce;

massCenter = Point3F(0, 0, 0);

// Resolve objects transmitted from server if (!server) { for (S32 i = 0; i < MaxSounds; i++) if (sound[i]) Sim::findObject(SimObjectId(sound[i]),sound[i]); for (S32 j = 0; j < MaxJetEmitters; j++) if (jetEmitter[j]) Sim::findObject(SimObjectId(jetEmitter[j]),jetEmitter[j]); }

if( !dustTrailEmitter && dustTrailID != 0 ) { if( !Sim::findObject( dustTrailID, dustTrailEmitter ) ) { Con::errorf( ConsoleLogEntry::General, "WaterCraftData::preload Invalid packet, bad datablockId(dustTrailEmitter): 0x%x", dustTrailID ); } } // Resolve jet nodes for (S32 j = 0; j < MaxJetNodes; j++) jetNode[j] = shape->findNode(sJetNode[j]);

return true;}

//--------------------------------------------------------------------------void WaterCraftData::packData(BitStream* stream){ Parent::packData(stream);

stream->write(dragForce); stream->write(vertFactor); stream->write(floatingThrustFactor); stream->write(mainThrustForce); stream->write(reverseThrustForce); stream->write(strafeThrustForce); stream->write(turboFactor); stream->write(stabLenMin); stream->write(stabLenMax); stream->write(stabSpringConstant); stream->write(stabDampingConstant); stream->write(gyroDrag); stream->write(normalForce); stream->write(restorativeForce); stream->write(steeringForce); stream->write(rollForce); stream->write(pitchForce);

171

Page 172:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

mathWrite(*stream, dustTrailOffset); stream->write(triggerTrailHeight); stream->write(dustTrailFreqMod);

for (S32 i = 0; i < MaxSounds; i++) if (stream->writeFlag(sound[i])) stream->writeRangedU32(packed? SimObjectId(sound[i]): sound[i]->getId(),DataBlockObjectIdFirst,DataBlockObjectIdLast);

for (S32 j = 0; j < MaxJetEmitters; j++) { if (stream->writeFlag(jetEmitter[j])) { SimObjectId writtenId = packed ? SimObjectId(jetEmitter[j]) : jetEmitter[j]->getId(); stream->writeRangedU32(writtenId, DataBlockObjectIdFirst,DataBlockObjectIdLast); } }

if (stream->writeFlag( dustTrailEmitter )) { stream->writeRangedU32( dustTrailEmitter->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast ); } stream->write(floatingGravMag); stream->write(brakingForce); stream->write(brakingActivationSpeed);}

void WaterCraftData::unpackData(BitStream* stream){ Parent::unpackData(stream);

stream->read(&dragForce); stream->read(&vertFactor); stream->read(&floatingThrustFactor); stream->read(&mainThrustForce); stream->read(&reverseThrustForce); stream->read(&strafeThrustForce); stream->read(&turboFactor); stream->read(&stabLenMin); stream->read(&stabLenMax); stream->read(&stabSpringConstant); stream->read(&stabDampingConstant); stream->read(&gyroDrag); stream->read(&normalForce); stream->read(&restorativeForce); stream->read(&steeringForce); stream->read(&rollForce); stream->read(&pitchForce); mathRead(*stream, &dustTrailOffset); stream->read(&triggerTrailHeight); stream->read(&dustTrailFreqMod);

172

Page 173:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

for (S32 i = 0; i < MaxSounds; i++) sound[i] = stream->readFlag()? (AudioProfile*) stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast): 0;

for (S32 j = 0; j < MaxJetEmitters; j++) { jetEmitter[j] = NULL; if (stream->readFlag()) jetEmitter[j] = (ParticleEmitterData*)stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast); }

if( stream->readFlag() ) { dustTrailID = (S32) stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast); } stream->read(&floatingGravMag); stream->read(&brakingForce); stream->read(&brakingActivationSpeed);}

//--------------------------------------------------------------------------WaterCraft::WaterCraft(){ // Todo: ScopeAlways? mNetFlags.set(Ghostable);

mFloating = false; mForwardThrust = 0; mReverseThrust = 0; mLeftThrust = 0; mRightThrust = 0;

mJetSound = NULL_AUDIOHANDLE; mEngineSound = NULL_AUDIOHANDLE; mFloatSound = NULL_AUDIOHANDLE;

mDustTrailEmitter = NULL;

mBackMaintainOn = false; for (S32 i = 0; i < JetAnimCount; i++) mJetThread[i] = 0;

helmMountable = true; nestMountable = true; cannonMountable = true;

}

WaterCraft::~WaterCraft(){}

173

Page 174:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//--------------------------------------------------------------------------void WaterCraft::initPersistFields(){ Parent::initPersistFields();}

void WaterCraft::consoleInit(){}

//--------------------------------------------------------------------------bool WaterCraft::onAdd(){ if(!Parent::onAdd()) return false; addToScene();

if( !isServerObject() ) { if( mDataBlock->dustTrailEmitter ) { mDustTrailEmitter = new ParticleEmitter; mDustTrailEmitter->onNewDataBlock( mDataBlock->dustTrailEmitter ); if( !mDustTrailEmitter->registerObject() ) { Con::warnf( ConsoleLogEntry::General, "Could not register dust emitter for class: %s", mDataBlock->getName() ); delete mDustTrailEmitter; mDustTrailEmitter = NULL; } } // Jet Sequences for (S32 i = 0; i < JetAnimCount; i++) { TSShape const* shape = mShapeInstance->getShape(); mJetSeq[i] = shape->findSequence(sJetSequence[i]); if (mJetSeq[i] != -1) { if (i == BackActivate) { mJetThread[i] = mShapeInstance->addThread(); mShapeInstance->setSequence(mJetThread[i],mJetSeq[i],0); mShapeInstance->setTimeScale(mJetThread[i],0); } } else mJetThread[i] = 0; } }

if (isServerObject()) scriptOnAdd();

return true;

174

Page 175:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

void WaterCraft::onRemove(){ scriptOnRemove(); removeFromScene();

if (mJetSound != NULL_AUDIOHANDLE) alxStop(mJetSound); if (mEngineSound != NULL_AUDIOHANDLE) alxStop(mEngineSound); if (mFloatSound != NULL_AUDIOHANDLE) alxStop(mFloatSound);

Parent::onRemove();}

bool WaterCraft::onNewDataBlock(GameBaseData* dptr){ mDataBlock = dynamic_cast<WaterCraftData*>(dptr); if (!mDataBlock || !Parent::onNewDataBlock(dptr)) return false;

// Todo: Uncomment if this is a "leaf" class scriptOnNewDataBlock();

return true;}

//--------------------------------------------------------------------------void WaterCraft::advanceTime(F32 dt){ Parent::advanceTime(dt);

// Update jetsound... if (mJetting) { if (mJetSound == NULL_AUDIOHANDLE && mDataBlock->sound[WaterCraftData::JetSound] != NULL) mJetSound = alxPlay(mDataBlock->sound[WaterCraftData::JetSound], &getTransform());

if (mJetSound != NULL_AUDIOHANDLE) alxSourceMatrixF(mJetSound, &getTransform()); } else { if (mJetSound != NULL_AUDIOHANDLE) { alxStop(mJetSound); mJetSound = NULL_AUDIOHANDLE; } }

// Update engine sound... if (mEngineSound == NULL_AUDIOHANDLE && mDataBlock->sound[WaterCraftData::EngineSound] != NULL) mEngineSound = alxPlay(mDataBlock->sound[WaterCraftData::EngineSound], &getTransform());

175

Page 176:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if (mEngineSound != NULL_AUDIOHANDLE) { alxSourceMatrixF(mEngineSound, &getTransform());

F32 denom = mDataBlock->mainThrustForce + mDataBlock->strafeThrustForce; F32 factor = getMin(mThrustLevel, denom) / denom; F32 vol = 0.25 + factor * 0.75; alxSourcef(mEngineSound, AL_GAIN_LINEAR, vol); }

// Are we floating? If so, start the floating sound... if (mFloating) { if (mFloatSound == NULL_AUDIOHANDLE && mDataBlock->sound[WaterCraftData::FloatSound] != NULL) mFloatSound = alxPlay(mDataBlock->sound[WaterCraftData::FloatSound], &getTransform());

if (mFloatSound != NULL_AUDIOHANDLE) alxSourceMatrixF(mFloatSound, &getTransform()); } else { if (mFloatSound != NULL_AUDIOHANDLE) { alxStop(mFloatSound); mFloatSound = NULL_AUDIOHANDLE; } } updateJet(dt); updateDustTrail( dt );}

//--------------------------------------------------------------------------

U32 WaterCraft::packUpdate(NetConnection* con, U32 mask, BitStream* stream){ U32 retMask = Parent::packUpdate(con, mask, stream);

// stream->writeInt(mThrustDirection,NumThrustBits);

return retMask;}

void WaterCraft::unpackUpdate(NetConnection* con, BitStream* stream){ Parent::unpackUpdate(con, stream);

mThrustDirection = ThrustDirection(stream->readInt(NumThrustBits));}

//--------------------------------------------------------------------------void WaterCraft::updateMove(const Move* move){ Parent::updateMove(move);

mForwardThrust = mThrottle > 0.0f ? mThrottle : 0.0f;

176

Page 177:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

mReverseThrust = mThrottle < 0.0f ? -mThrottle : 0.0f; mLeftThrust = move->x < 0.0f ? -move->x : 0.0f; mRightThrust = move->x > 0.0f ? move->x : 0.0f;

mThrustDirection = (!move->y)? ThrustDown: (move->y > 0)? ThrustForward: ThrustBackward;}

F32 WaterCraft::getBaseStabilizerLength() const{ F32 base = mDataBlock->stabLenMin; F32 lengthDiff = mDataBlock->stabLenMax - mDataBlock->stabLenMin; F32 velLength = mRigid.state.linVelocity.len(); F32 minVel = getMin(velLength, mDataBlock->maxThrustSpeed); F32 velDiff = mDataBlock->maxThrustSpeed - minVel; F32 velRatio = velDiff / mDataBlock->maxThrustSpeed; F32 inc = lengthDiff * ( 1.0 - velRatio ); base += inc;

return base;}

struct StabPoint{ Point3F osPoint; // Point3F wsPoint; // F32 extension; Point3F wsExtension; // Point3F wsVelocity; //};

void WaterCraft::updateForces(F32 /*dt*/){

// Point3F gravForce(0, 0, sWaterCraftGravity * mGravityMod); // This line was here pre-head 3/06 - DB Point3F gravForce(0, 0, sWaterCraftGravity * mRigid.mass * mGravityMod); MatrixF currTransform; mRigid.state.getTransform(&currTransform); //mRigid.atRest = false; // If this is uncommented you stutter on the deck but you can move the galleon - DB

mThrustLevel = (mForwardThrust * mDataBlock->mainThrustForce + mReverseThrust * mDataBlock->reverseThrustForce + mLeftThrust * mDataBlock->strafeThrustForce + mRightThrust * mDataBlock->strafeThrustForce);

Point3F thrustForce = ((Point3F( 0, 1, 0) * (mForwardThrust * mDataBlock->mainThrustForce)) + (Point3F( 0, -1, 0) * (mReverseThrust * mDataBlock->reverseThrustForce)) + (Point3F(-1, 0, 0) * (mLeftThrust * mDataBlock->strafeThrustForce)) + (Point3F( 1, 0, 0) * (mRightThrust * mDataBlock->strafeThrustForce))); currTransform.mulV(thrustForce);

177

Page 178:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if (mJetting) thrustForce *= mDataBlock->turboFactor;

Point3F torque(0, 0, 0); Point3F force(0, 0, 0);

Point3F vel = mRigid.state.linVelocity; F32 baseStabLen = getBaseStabilizerLength(); Point3F stabExtend(0, 0, -baseStabLen); currTransform.mulV(stabExtend);

StabPoint stabPoints[2]; stabPoints[0].osPoint = Point3F((mObjBox.min.x + mObjBox.min.x) * 0.5, mObjBox.max.y, (mObjBox.min.z + mObjBox.max.z) * 0.5); stabPoints[1].osPoint = Point3F((mObjBox.min.x + mObjBox.min.x) * 0.5, mObjBox.min.y, (mObjBox.min.z + mObjBox.max.z) * 0.5); U32 j, i; for (i = 0; i < 2; i++) { currTransform.mulP(stabPoints[i].osPoint, &stabPoints[i].wsPoint); stabPoints[i].wsExtension = stabExtend; stabPoints[i].extension = baseStabLen; stabPoints[i].wsVelocity = mRigid.state.linVelocity; }

RayInfo rinfo;

mFloating = true; bool reallyFloating = true; F32 compression[2] = { 0.0f, 0.0f }; F32 normalMod[2] = { 0.0f, 0.0f }; bool normalSet[2] = { false, false }; Point3F normal[2];

for (j = 0; j < 2; j++) { if (getContainer()->castRay(stabPoints[j].wsPoint, stabPoints[j].wsPoint + stabPoints[j].wsExtension * 2.0, TerrainObjectType | InteriorObjectType , &rinfo)) { reallyFloating = false;

mRigid.state.setTransform(prevTransform); }

if (getContainer()->castRay(stabPoints[j].wsPoint, stabPoints[j].wsPoint + stabPoints[j].wsExtension * 2.0, WaterObjectType , &rinfo)) {

reallyFloating = true;mRigid.state.getTransform(&prevTransform);if (rinfo.t <= 0.5) {

// Ok, stab is in contact with the ground, let's calc the forces...

178

Page 179:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

compression[j] = (1.0 - (rinfo.t * 2.0)) * baseStabLen; } normalSet[j] = true; normalMod[j] = rinfo.t < 0.5 ? 1.0 : (1.0 - ((rinfo.t - 0.5) * 2.0));

normal[j] = rinfo.normal;}

// Check the waterblock directly SimpleQueryList sql; mSceneManager->getWaterObjectList(sql); for (U32 i = 0; i < sql.mList.size(); i++) { WaterBlock* pBlock = static_cast<WaterBlock*>(sql.mList[i]); if (pBlock->isPointSubmerged(stabPoints[j].wsPoint)) { compression[j] = baseStabLen; break; } } }

for (j = 0; j < 2; j++) { if (compression[j] != 0.0) { mFloating = false;

// Spring force and damping Point3F springForce = -stabPoints[j].wsExtension; springForce.normalize(); springForce *= compression[j] * mDataBlock->stabSpringConstant;

Point3F springDamping = -stabPoints[j].wsExtension; springDamping.normalize(); springDamping *= -getMin(mDot(springDamping, stabPoints[j].wsVelocity), 0.7f) * mDataBlock->stabDampingConstant;

force += springForce + springDamping; } }

// Gravity if (reallyFloating == false) force += gravForce; else force += gravForce * mDataBlock->floatingGravMag;

// Braking F32 vellen = mRigid.state.linVelocity.len(); if (mThrottle == 0.0f && mLeftThrust == 0.0f && mRightThrust == 0.0f && vellen != 0.0f && vellen < mDataBlock->brakingActivationSpeed) { Point3F dir = mRigid.state.linVelocity;

179

Page 180:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

dir.normalize(); dir.neg(); force += dir * mDataBlock->brakingForce; } // Gyro Drag torque = -mRigid.state.angMomentum * mDataBlock->gyroDrag;

// Move to proper normal Point3F sn, r; currTransform.getColumn(2, &sn); if (normalSet[0] || normalSet[1]) { if (normalSet[0] && normalSet[1]) { F32 dot = mDot(normal[0], normal[1]); if (dot > 0.999) { // Just pick the first normal. They're too close to call if ((sn - normal[0]).lenSquared() > 0.00001) { mCross(sn, normal[0], &r); torque += r * mDataBlock->normalForce * normalMod[0]; } } else { Point3F rotAxis; mCross(normal[0], normal[1], &rotAxis); rotAxis.normalize();

F32 angle = mAcos(dot) * (normalMod[0] / (normalMod[0] + normalMod[1])); AngAxisF aa(rotAxis, angle); QuatF q(aa); MatrixF tempMat(true); q.setMatrix(&tempMat); Point3F newNormal; tempMat.mulV(normal[1], &newNormal);

if ((sn - newNormal).lenSquared() > 0.00001) { mCross(sn, newNormal, &r); torque += r * (mDataBlock->normalForce * ((normalMod[0] + normalMod[1]) * 0.5)); } } } else { Point3F useNormal; F32 useMod; if (normalSet[0]) { useNormal = normal[0]; useMod = normalMod[0]; } else { useNormal = normal[1]; useMod = normalMod[1]; }

if ((sn - useNormal).lenSquared() > 0.00001) { mCross(sn, useNormal, &r); torque += r * mDataBlock->normalForce * useMod; } } } else {

180

Page 181:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if ((sn - Point3F(0, 0, 1)).lenSquared() > 0.00001) { mCross(sn, Point3F(0, 0, 1), &r); torque += r * mDataBlock->restorativeForce; } }

Point3F sn2; currTransform.getColumn(0, &sn); currTransform.getColumn(1, &sn2); mCross(sn, sn2, &r); r.normalize(); torque -= r * (mSteering.x * mDataBlock->steeringForce);

currTransform.getColumn(0, &sn); currTransform.getColumn(2, &sn2); mCross(sn, sn2, &r); r.normalize(); torque -= r * (mSteering.x * mDataBlock->rollForce);

currTransform.getColumn(1, &sn); currTransform.getColumn(2, &sn2); mCross(sn, sn2, &r); r.normalize(); torque -= r * (mSteering.y * mDataBlock->pitchForce);

// Apply drag Point3F vDrag = mRigid.state.linVelocity; if (!mFloating) { vDrag.convolve(Point3F(1, 1, mDataBlock->vertFactor)); } else { vDrag.convolve(Point3F(0.25, 0.25, mDataBlock->vertFactor)); } force -= vDrag * mDataBlock->dragForce;

force += mFloating ? thrustForce * mDataBlock->floatingThrustFactor : thrustForce;

// Add in physical zone force force += mAppliedForce;

// Container buoyancy & drag force += Point3F(0, 0,-mBuoyancy * sWaterCraftGravity * mGravityMod); force -= mRigid.state.linVelocity * mDrag; torque -= mRigid.state.angMomentum * mDrag;

mRigid.state.force = force; mRigid.state.torque = torque;}

void WaterCraft::updateWarp(){ //}

//--------------------------------------------------------------------------

181

Page 182:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

U32 WaterCraft::getCollisionMask(){ if (isServerObject()) return sServerCollisionMask; else return sClientCollisionMask;}

void WaterCraft::updateDustTrail( F32 dt ){ if( !mDustTrailEmitter ) return;

// check if close to ground Point3F startPos = getPosition(); Point3F endPos = startPos + Point3F( 0.0, 0.0, -mDataBlock->triggerTrailHeight );

RayInfo rayInfo; if( !getContainer()->castRay( startPos, endPos, TerrainObjectType, &rayInfo ) ) { return; }

VectorF vel = getVelocity(); TerrainBlock* tBlock = static_cast<TerrainBlock*>(rayInfo.object); S32 mapIndex = tBlock->mMPMIndex[0]; MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap")); const MaterialPropertyMap::MapEntry* pEntry = pMatMap->getMapEntryFromIndex(mapIndex); // emit dust if moving if( vel.len() > 2.0 && pEntry) { VectorF axis = vel; axis.normalize();

S32 x; ColorF colorList[ParticleEngine::PC_COLOR_KEYS]; for(x = 0; x < 2; ++x) colorList[x].set( pEntry->puffColor[x].red, pEntry->puffColor[x].green, pEntry->puffColor[x].blue, pEntry->puffColor[x].alpha ); for(x = 2; x < ParticleEngine::PC_COLOR_KEYS; ++x) colorList[x].set( 1.0, 1.0, 1.0, 0.0 ); mDustTrailEmitter->setColors( colorList ); Point3F contactPoint = rayInfo.point + mDataBlock->dustTrailOffset; mDustTrailEmitter->emitParticles( contactPoint , true, axis, vel, dt * 1000 * (vel.len() / mDataBlock->dustTrailFreqMod) ); }

182

Page 183:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

}

void WaterCraft::updateJet(F32 dt){ if (mJetThread[BackActivate] == NULL) return;

F32 pos = mShapeInstance->getPos(mJetThread[BackActivate]); F32 scale = mShapeInstance->getTimeScale(mJetThread[BackActivate]);

// Thrust Animation threads // Back if (mJetSeq[BackActivate] >=0 ) { if (!mBackMaintainOn || mThrustDirection != ThrustForward) { if (mBackMaintainOn) { mShapeInstance->setPos(mJetThread[BackActivate], 1); mShapeInstance->destroyThread(mJetThread[BackMaintain]); mBackMaintainOn = false; } mShapeInstance->setTimeScale(mJetThread[BackActivate], (mThrustDirection == ThrustForward)? 1: -1); mShapeInstance->advanceTime(dt,mJetThread[BackActivate]); } }

if (mJetSeq[BackMaintain] >= 0 && !mBackMaintainOn && mShapeInstance->getPos(mJetThread[BackActivate]) >= 1.0) { mShapeInstance->setPos(mJetThread[BackActivate], 0); mShapeInstance->setTimeScale(mJetThread[BackActivate], 0); mJetThread[BackMaintain] = mShapeInstance->addThread(); mShapeInstance->setSequence(mJetThread[BackMaintain],mJetSeq[BackMaintain],0); mShapeInstance->setTimeScale(mJetThread[BackMaintain],1); mBackMaintainOn = true; } if(mBackMaintainOn) mShapeInstance->advanceTime(dt,mJetThread[BackMaintain]);

// Jet particles for (S32 j = 0; j < NumThrustDirections; j++) { JetActivation& jet = sJetActivation[j]; updateEmitter(mJetting && j == mThrustDirection,dt,mDataBlock->jetEmitter[jet.emitter], jet.node,WaterCraftData::MaxDirectionJets); }}

void WaterCraft::updateEmitter(bool active,F32 dt,ParticleEmitterData *emitter,S32 idx,S32 count){ if (!emitter) return; for (S32 j = idx; j < idx + count; j++)

183

Page 184:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

if (active) { if (mDataBlock->jetNode[j] != -1) { if (!bool(mJetEmitter[j])) { mJetEmitter[j] = new ParticleEmitter; mJetEmitter[j]->onNewDataBlock(emitter); mJetEmitter[j]->registerObject(); } MatrixF mat; Point3F pos,axis; mat.mul(getRenderTransform(), mShapeInstance->mNodeTransforms[mDataBlock->jetNode[j]]); mat.getColumn(1,&axis); mat.getColumn(3,&pos); mJetEmitter[j]->emitParticles(pos,true,axis,getVelocity(),dt * 1000); } } else { for (S32 j = idx; j < idx + count; j++) if (bool(mJetEmitter[j])) { mJetEmitter[j]->deleteWhenEmpty(); mJetEmitter[j] = 0; } }}

184

Page 185:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// guiCompassCtrl.h - \engine\gui//-----------------------------------------------------------------------------

#ifndef _GUICOMPASSCTRL_H_#define _GUICOMPASSCTRL_H_

#ifndef _GUIBITMAPCTRL_H_#include "gui/guiBitmapCtrl.h"#endif

struct CameraQuery{ SimObject* object; F32 nearPlane; F32 farPlane; F32 fov; MatrixF cameraMatrix;};

class GuiCompassCtrl : public GuiBitmapCtrl{private:

typedef GuiBitmapCtrl Parent;ColorF mFillColor;

protected:bool mIs3d;

public:

//creation methodsDECLARE_CONOBJECT(GuiCompassCtrl);GuiCompassCtrl();static void initPersistFields();static void consoleInit();

//Parental methodsbool onWake();void onSleep();

void setBitmap(const char *name);void setBitmap(const TextureHandle &handle);void setValue(S32 x, S32 y);void setIs3d(bool temp);void onRender(Point2I offset, const RectI &updateRect);

};

#endif //_GUICOMPASSCTRL_H_

185

Page 186:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//-----------------------------------------------------------------------------// guiCompassCtrl.cc - \engine\gui//-----------------------------------------------------------------------------

#include "console/console.h"#include "console/consoleTypes.h"#include "dgl/dgl.h"#include "game/game.h"#include "gui/guiCompassCtrl.h"#include "game/gameConnection.h"

IMPLEMENT_CONOBJECT(GuiCompassCtrl);

GuiCompassCtrl::GuiCompassCtrl(void){

mBitmapName = StringTable->insert("");startPoint.set(0,0);mWrap = false;mIs3d = false;//color of vectors used to represent compass pointermFillColor.set(1.00F,0.00F,0.00F,0.75F);

}

void GuiCompassCtrl::initPersistFields(){

Parent::initPersistFields(); addField("FillColor", TypeColorF, Offset(mFillColor, GuiCompassCtrl)); addField("is3d", TypeBool, Offset(mIs3d,GuiCompassCtrl));}

static void cCompassSetValue(SimObject *obj, S32, const char **argv){ GuiCompassCtrl *ctrl = static_cast<GuiCompassCtrl*>(obj); ctrl->setValue(dAtoi(argv[2]), dAtoi(argv[3]));}

static void cCompassSetBitmap(SimObject *obj, S32, const char **argv){ GuiCompassCtrl *ctrl = static_cast<GuiCompassCtrl*>(obj); ctrl->setBitmap(argv[2]);}

static void cCompassSetIs3d(SimObject *obj, S32, const char **argv){

GuiCompassCtrl *ctrl = static_cast<GuiCompassCtrl*>(obj);ctrl->setIs3d(dAtob(argv[2]));

}

void GuiCompassCtrl::consoleInit(){

Con::addCommand("GuiCompassCtrl", "setIs3d", cCompassSetIs3d, "guiCompassCtrl.setIs3d(bool)", 3, 3);

Con::addCommand("GuiCompassCtrl", "setBitmap", cCompassSetBitmap, "guiCompassCtrl.setBitmap(blah)", 3, 3);

186

Page 187:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Con::addCommand("GuiCompassCtrl", "setValue", cCompassSetValue, "guiCompassCtrl.setValue(xAxis, yAxis)", 4, 4);}

void GuiCompassCtrl::setIs3d(bool temp){

mIs3d = temp;}

void GuiCompassCtrl::setValue(S32 x, S32 y){

Parent::setValue(x,y);}

void GuiCompassCtrl::setBitmap(const char *name){ mBitmapName = StringTable->insert(name); if (*mBitmapName) mTextureHandle = TextureHandle(mBitmapName, BitmapTexture, true); else mTextureHandle = NULL; setUpdate();}

void GuiCompassCtrl::setBitmap(const TextureHandle &handle){

mTextureHandle = handle;}

bool GuiCompassCtrl::onWake(){

if (! Parent::onWake())return false;

setActive(true);setBitmap(mBitmapName);return true;

}

void GuiCompassCtrl::onSleep(){

mTextureHandle = NULL;Parent::onSleep();

}

float Vector2dToDegree(Point3F vector){ float angle;

if (vector.x == 0.0F) { if (vector.y > 0.0F) return 0.0F; else if (vector.y == 0.0F) return -1.0F; else return 180.0F; } if (vector.y == 0.0F)

187

Page 188:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

{ if (vector.x < 0.0F) return 270.0F; else return 90.0F; } angle = atanf((1.0F * vector.x) / (-1.0F * vector.y)) * (180.0F / M_PI); if ((-1.0F * vector.y) < 0.0F) return angle + 180.0F; else { if (vector.x > 0.0F) return angle; else return angle + 360.0F; }}

void DegreeToVector2d(float angle, Point2F &vector){

angle = (angle / 180) * M_PI; vector.x = (1 * sin(angle) );

vector.y = (-1 * cos(angle) );}

void GuiCompassCtrl::onRender(Point2I offset, const RectI &updateRect) {

//Render the compass bitmap if (mTextureHandle) {

dglClearBitmapModulation(); if(mWrap) {

TextureObject* texture = (TextureObject *) mTextureHandle;

RectI srcRegion; RectI dstRegion; float xdone = ((float)mBounds.extent.x/(float)texture-

>bitmapWidth)+1;float ydone = ((float)mBounds.extent.y/(float)texture-

>bitmapHeight)+1;

int xshift = startPoint.x%texture->bitmapWidth; int yshift = startPoint.y%texture->bitmapHeight; for(int y = 0; y < ydone; ++y) for(int x = 0; x < xdone; ++x) {

srcRegion.set(0,0,texture->bitmapWidth,texture->bitmapHeight);

dstRegion.set( ((texture->bitmapWidth*x)+offset.x)-xshift,

((texture->bitmapHeight*y)+offset.y)-yshift,

texture->bitmapWidth, texture->bitmapHeight);

188

Page 189:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);

} } else {

RectI rect(offset, mBounds.extent); dglDrawBitmapStretch(mTextureHandle, rect);

} } else {

RectI rect = mBounds; rect.point += offset;

glColor4f(0, 0, 0, 1); glBegin(GL_LINE_LOOP); glVertex2i(rect.point.x, rect.point.y); glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y); glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y +

rect.extent.y - 1); glVertex2i(rect.point.x, rect.point.y + rect.extent.y - 1); glEnd();

}

//Find distance from top-left corner to center of compass Point2F center(mBounds.extent.x / 2,mBounds.extent.y / 2);

//Query the camera and find out which direction we're facing struct CameraQuery query; GameProcessCameraQuery(&query); Point3F cameraRot;

Point2F cameraRot2d;

Point2F pointA;

MatrixF matrix = query.cameraMatrix; matrix.getRow(1,&cameraRot); // get camera rotation

//Make center the object's coordinate center center.x += mBounds.point.x; center.y += mBounds.point.y; //--dcd-- This is K. Finney's fix to the control to reverse the

compass mapping // This may need to be removed when the terrain problem is

corrected cameraRot.neg(); // <--- this flips the orientation, caused by the

upside down terrains from bitmaps

cameraRot.z = 0; //cameraRot *= (center.x * 0.8f);

//Convert and alter vector based on degree givenfloat cameraAngle = Vector2dToDegree(cameraRot);

DegreeToVector2d(cameraAngle, pointA);

189

Page 190:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

//Sets vector length to fit to gui object's extentpointA.x = 0.390625 * mBounds.extent.x * pointA.x;pointA.y = 0.390625 * mBounds.extent.y * pointA.y;

//Render a pretty Compass Pointer glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_LINES);

//Draw compass pointer/arcglColor4f(1.00F,0.00F,0.00F,0.75F); // Temporarily hard-coded because mFillColor won't work.glVertex2f(center.x, center.y); glColor4f(1.00F,0.00F,0.00F,0.75F);glVertex2f(center.x + pointA.x, center.y + pointA.y);

glEnd();

glDisable(GL_BLEND);

renderChildControls(offset, updateRect); }

190

Page 191:   · Web viewDesign Document. Table of Contents. Executive Summary………………………………………………………………………………..3. Treatment

Conclusion

Competitive Products – There are many games on the market and even though there are few products that hold a pirate theme, there are still major competitors to Full Sail!

Pirates – The Legend of Black Kat Ballistics Medal of Honor – Allied Assault Return to Castle Wolfenstein Counterstrike – Condition Zero Cratered Blood Wake

This Product – Although these other products offer some great features, none of them have what Full Sail! has. Pirates – The Legend of Black Kat may be about pirates, but it lacks any multiplayer mode and Full Sail! will support up to twelve people. Ballistics is a high paced racing title, but doesn’t have combat to keep things evened up like Full Sail! Medal of Honor – Allied Assault, Return to Castle Wolfenstein, and Counterstrike – Condition Zero all have multiplayer combat, but none of them capture the mystery and danger of the eighteenth century where you lived and died by the sword. Cratered and Blood Wake are both high speed, multiplayer, combat games on water, but both also lack the true feeling of danger on the sea and the choice of multiple positions to play on a single ship.

Overall, Full Sail! can and will face up to the challenge of any of the games on the market with its unique feel and spectacular gameplay.

In the Future – In the future we foresee expansions. These expansions will have more pirates, more ships, and more maps to choose from. The world of Full Sail! will never end!

191