View topic - Skripting



All times are UTC + 1 hour


Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Skripting
PostPosted: 23 Aug 2009, 20:10 
User avatar

Joined: 20 Aug 2009, 19:49
How does it work? Where to get examples?
I would like a sample script for a tank if possible.
Would be very nice and helpfull if someone could show something to me.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 20:27 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
http://springrts.com/wiki/Mod_and_Unit_ ... evelopment

There are a number of examples, although I'd be the first to say that nobody's even written a Maestro-level tutorial about BOS for Spring yet.

For an ultra-simple tank (no cool animations, just the basics of turning a turret and a barrel to aim):

Code:
piece turret, barrel;

Create()  //What happens when we get made?
{
  //In this case, nothing, but most scripts set up Pieces here for animation later
}

AimWeapon1(heading, pitch)
{
  turn turret to y-axis heading speed <50>;  //turn the turret towards bad guys
  turn barrel to x-axis 0 - pitch speed <30>;  //turn the barrel up / down
  wait-for-turn turret around y-axis;  //wait for that turret to get there!
  wait-for-turn barrel around x-axis;  //also wait for that barrel!

  return 1;  //returning a value of 1, in the context of AimWeapon scripts, means "shoot a shot now!"  returning 0 means "can't shoot for some reason!"
}

Killed()
{
  explode turret type FALL;  //fall off and bounce around!
  explode barrel type SHATTER;  //turn into tiny flying triangles!
}


Last edited by Argh on 23 Aug 2009, 20:51, edited 1 time in total.

Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 20:34 
Malcontent
User avatar

Joined: 27 Feb 2006, 22:04
Location: Hurrrrrr.
might want to declare the other pieces that are used too


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 20:44 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
Only two pieces are being used. If you want to talk about flares and expand that example a bit, go right ahead, though :-)


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 20:50 
Malcontent
User avatar

Joined: 27 Feb 2006, 22:04
Location: Hurrrrrr.
look very carefully at your script argh

Mistakes like that CANNOT be made when you are tutoring a new scripter.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 20:54 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
Yes, I used "gun" and where I should have used "barrel". Oops!

At any rate, I think we need to develop a training program for this area of Spring, walking people through the concepts.

It's non-obvious, non-trivial, and the existing materials are really fragmentary and hard to learn, and the few people who know how it works don't ever explain it to anybody else, or provide examples that are so advanced that it's hard to understand if you're brand-new.

I tried to do this with NanoBlobs, but I don't think it ever made much of an impact, as most newbies couldn't get their heads wrapped around it.

If nobody gets around to making one, I'll get to it in a month or two.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:05 
Moderator
User avatar

Joined: 29 Apr 2005, 00:14
Location: #moddev - join it!
Hopefully lua will slay the BOS beast anyway


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:05 
Content Developer
User avatar

Joined: 13 Jan 2005, 00:46
Location: ModalitÃ
but no the nub coder :\.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:31 
User avatar

Joined: 20 Aug 2009, 19:49
Quote:
Error (20): Unknown identifier SHATTER [ C:\Dokumente und Einstellungen\ErikMesserli\Desktop\NWO\SPRING\Testmod\Scripts\Testscript.bos ]

One or more errors occured while compiling the script.

Error on compiling it
whats wrong here?
Also whats the name to save it as? Any as long as its stated in the unit file?


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:34 
Kernel Panic Co-Developer
User avatar

Joined: 16 Nov 2004, 13:08
FLOZi wrote:
Hopefully lua will slay the BOS beast anyway
Sure, Lua is such a fierce beast, poor simple bos stands no chance.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:36 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
The compile error is because you're trying to invoke a constant that isn't defined. Again, I apologize, a lot of this is second nature to me.

So, let's talk about constants.

SHATTER is just a pseudonym for a constant. Spring has a large number of constants which have a very specific, engine-based value- i.e., some constants do things in the engine, depending on the context.

Here is my current list of Spring's constants. I think it's up to date with Spring 0.80.2:

Code:
// Argh's Standard Commands Script
// This script is released under the terms of the  WORLDBUILDER license.

#ifndef STANDARD_COMMANDS_WORLDBUILDER_H_
#define STANDARD_COMMANDS_WORLDBUILDER_H_
//
// Vector-based special effects
//
#define   SFXTYPE_WAKE1      3     // Calls Spring to show a standard FX if the Unit is over water (may show on water surface if on land, use with detection methods)
//
// Point-based (piece origin) special effects
//
#define SHATTER         1   // Has odd effects in S3O, due to triangular models.  Use with caution.
#define EXPLODE_ON_HIT      2   // DOES NOT WORK PROPERLY IN SPRING, REFERENCE ONLY
#define FALL         4   // The piece will fall due to gravity, based partially on myGravity value
#define SMOKE         8   // Creates 1 "smoke" particle each frame at the Piece's center, using standard values, as of Spring 0.75b2
#define FIRE         16   // Creates one "flame" and one "smoke" particle at the Piece's center, using standard values, as of Spring 0.75b2
#define BITMAPONLY      32   // DOES NOT WORK PROPERLY IN SPRING, REFERENCE ONLY
#define NOCEGTRAIL      64   // NO CEG FROM PIECE EXPLOSION
//
// Bitmap Explosion Types
//
#define BITMAP_WORLDBUILDER      10000001   //This is for any call to a BITMAP event, however it's not really necessary.  Just for helping out older conversion mods.
//
// Indices for SET/GET value
#define ACTIVATION      1   // SET or GET, used by all scripts that call Activate() through UI or BOS command
#define STANDINGMOVEORDERS   2   // SET or GET, now works in 0.75b to SET all states (Hold Position, Manuever, Roam).  Values 0, 1, 2
#define STANDINGFIREORDERS   3   // SET or GET, now works in 0.75b to SET all states (Hold Fire, Fire at Will, Fire Back).  Values 0, 1, 2
#define HEALTH         4   // GET or SET, in 0.74b or above.  Can set the hitpoints of the relevant Unit.  Use carefully, can create odd behaviors.
#define INBUILDSTANCE      5   // SET or GET, used to tell Spring that a Factory is now able to build objects and emit nano-particles.
#define BUSY         6   // SET or GET, will operate in Spring to pause loading state, for flying transports only.
#define PIECE_XZ         7   // GET, for position calculation, returns two values, XZ, in packed coordinates.
#define PIECE_Y         8   // GET, for position calculation, returns one value, Y.  Good for height changes.
#define UNIT_XZ         9   // GET, for position calculation of Unit, reads from centroid of Base.
#define UNIT_Y         10   // GET, for position calculation of Unit, reads from centroid of Base.
#define UNIT_HEIGHT      11   // GET, for position calculation of Unit, reads from Unit's current height value.
#define XZ_ATAN         12   // GET atan of packed x,z coords.  Good for angular changes over time.  Not fast math, use with care.
#define XZ_HYPOT         13   // GET hypot of packed x,z coords.  Good for angular changes over time.  Not fast math, use with care.
#define ATAN         14   // GET ordinary two-parameter atan, as integer.  Runs most efficiently if sent raw values- i.e., 182 instead of <1.0>
#define HYPOT         15   // GET ordinary two-parameter hypot, as integer.  Runs most efficiently if sent raw values- i.e., 65536 instead of [1.0]
#define GROUND_HEIGHT      16   // GET, asks Spring for value of GROUND_HEIGHT based on map values
#define BUILD_PERCENT_LEFT      17   // GET, returns a value from Spring stating how much of the Unit has been built.  Only returns every SlowUpdate, however.
#define YARD_OPEN         18   // SET or GET.  Spring defines squares as "open" or "closed" for pathfinding purposes based on that state.
#define BUGGER_OFF      19   // SET or GET, causes Units around the Unit if SET to 1 to try to move a minimum distance away, when invoked!
#define ARMORED         20   // SET or GET.  Turns on the Armored state.  Uses value of Armor defined in unit FBI, which is a float multiple of health.
#define IN_WATER            28   // GET only.  If model centroid Y < 0, then returns TRUE (0 Y is the water level).  Better detection methods exist.
#define CURRENT_SPEED        29   // SET or GET.  Can return the current velocity in raw format.  Useful for checking acceleration values, etc.
#define VETERAN_LEVEL        32   // SET or GET.  Can make units super-accurate, or keep them inaccurate, and also effects hitpoints.  Use with care!
#define MAX_ID         70   // GET only.  Returns maximum number of units - 1
#define MY_ID                    71   // GET only.  Returns ID of current unit
#define UNIT_TEAM                  72   // GET only.  Returns team of unit given with parameter
#define UNIT_BUILD_PERCENT_LEFT   73   // GET only.  Like BUILD_PERCENT_LEFT, but comes with a unit parameter.
#define UNIT_ALLIED      74   // GET only.  Is this unit allied to the unit of the current COB script? 1 = allied, 0 = not allied
#define MAX_SPEED          75   // SET only.  Alters MaxVelocity for the given unit.  Can be SET to anything lower than the max. speed in FBI, value of 1 == 0
#define CLOAKED         76   //SET or GET.  GETs current status of cloak.
#define WANT_CLOAK      77   //SET or GET.  GETs current value of WANT_CLOAK (1 or 0)
#define GROUND_WATER_HEIGHT   78   //GET only.  Returns negative values if unit is over water.
#define UPRIGHT         79   //SET or GET.  Can allow you to SET the upRight state of a Unit.
#define POW         80   //GET the power of a number
#define PRINT         81   //Special, read below:

/*Prints the value of up to 4 vars / static-vars into the Spring chat.  Very useful for debugging. 

Usage is:

var myTest;
myTest = GET POW (262144, 32768);
GET PRINT (myTest)

Would return:
"Value 1: 131072, 2: 0, 3: 0, 4: 0" to the Chat interface.*/

#define HEADING         82   //SET and GET.  Allows unit HEADING to be returned, SET to value of previous HEADING every frame to keep units from turning.
#define TARGET_ID         83   //GET.  Returns ID of currently targeted Unit.  -1 if none, -2 if force-fire, -3 if Intercept, -4 if the Weapon doesn't exist.
#define LAST_ATTACKER_ID      84   //GET.  Returns ID of last Unit to attack, or -1 if never attacked.  Could theoretically be used to implement special control over weapon systems for a Unit, but I have never seen this done yet.

#define LOS_RADIUS         85   //SET.  SETs the LOS Radius (per Ground).  Could be used in conjunction with Activate().
#define AIR_LOS_RADIUS      86   //SET.  SETs the LOS Radius (per Air).  Could be used in conjunction with Activate().
#define RADAR_RADIUS                87    // SET or GET, just like the Unit def.
#define JAMMER_RADIUS             88    // SET or GET, just like the Unit def.
#define SONAR_RADIUS                89    // SET or GET, just like the Unit def.
#define SONAR_JAM_RADIUS          90    // SET or GET, just like the Unit def.
#define SEISMIC_RADIUS                91    // SET or GET, just like the Unit def.
#define DO_SEISMIC_PING      92   //GET (GET DO_SEISMIC_PING(size)) Emits a Seismic Ping.  Can be seen by all players regardless of LOS.
#define CURRENT_FUEL                93    // SET or GET, Fuel level is currently (0.75b2) being used for Aircraft only- when 0, Aircraft return to an Air Repair location.  Could be used for dynamic fuel based on time of flight (as opposed to weapons use) or for more detailed control over weapons than Spring's defaults.

#define TRANSPORT_ID      94   // GET.  Returns ID of the Transport the Unit is in.  -1 if not loaded.
#define SHIELD_POWER      95   // GET / SET.  Manipulates Shield, if Unit has one, good for timed Shield disruptions.  Set to 0 every frame if you want to keep a Shield down for some reason.
#define STEALTH                         96    // set or get
#define CRASHING                        97    // set or get, returns whether aircraft isCrashing state
#define CHANGE_TARGET                98    // set, the value it's set to determines the affected weapon
#define CEG_DAMAGE                   99    // set
#define COB_ID                         100    // get
#define PLAY_SOUND      101   //GET only.  Plays sounds via these instructions:

/*
1) Adds a new get call, PLAY_SOUND, to play a sound that can be heard only by allies, enemy, in los, etc.
2) changes get health to allow a unit ID to be passed
3) adds a call to create() at the end of ReloadCOB

GET PLAY_SOUND(sound number, volume, who hears the sound, where to play the sound)

To set up sounds to use with GET PLAY_SOUND, put a function like this near the top of your bos:
Sounds()
{
play-sound ("movement", 10);
play-sound ("pew", 10);
play-sound ("reporting", 10);
}
The sound number is based on the order the sounds appear, staring from 0. To call the songs by name, add #defines like this:
Sounds()
{
play-sound ("movement", 10);
#define movement 0
play-sound ("pew", 10);
#define pew 1
play-sound ("reporting", 10);
#define reporting 2
}

To actually call the sound, you use a line such as this:
GET PLAY_SOUND (pew, 655360);

1) sound number - as above

2) volume - similar to the volume for play-sound, more affecting the distance where it is audible than actual volume
- given as a float multiplied by 65536

3) who hears the sound
0 = anyone with the unit in ALOS
1 = anyone with the unit in LOS
2 = anyone with the unit in ALOS or radar
3 = anyone with the unit in LOS or radar
4 = everyone
5 = the unit's allies
6 = the unit's team
7 = the unit's enemies

4) where to play the sound
- if 0, the sound is played from the unit's position
- if 1, the sound is played directly from the speakers, the same way unit replies are*/

#define KILL_UNIT         102   //GET.  Kills the Unit this frame.  Supplying no unit number kills the calling unit (for convenience). Returns zero if the target doesn't exist.
#define ALPHA_THRESHOLD      103   //SET or GET.  Changes the glAlphaFunc to use that alpha value as its minimum.
#define REVERSING      109   //GET.  Returns Reversing state.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////LuaCOB
#define LUA0         110  // All are SET / GET, for passing args to LuaCOB interface.
#define LUA1         111
#define LUA2         112
#define LUA3         113
#define LUA4         114
#define LUA5         115
#define LUA6         116
#define LUA7         117
#define LUA8         118
#define LUA9         119
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define FLANK_B_MODE                120    // set or get
#define FLANK_B_DIR                    121    // set or get, set is through get for multiple args
#define FLANK_B_MOBILITY_ADD        122    // set or get
#define FLANK_B_MAX_DAMAGE          123    // set or get
#define FLANK_B_MIN_DAMAGE          124    // set or get

//Weapon Modifications, via COB
/*All of these use the first param (starting at 1) as the weapon index whereby positive means read and negative means write the second param to the value.
In the latter case the previous value is returned.*/
#define WEAPON_RELOADSTATE    125 //(frame number of the next shot/burst)
#define WEAPON_RELOADTIME    126 //(in frames)
#define WEAPON_ACCURACY       127
#define WEAPON_SPRAY       128
#define WEAPON_RANGE       129
#define WEAPON_PROJECTILESPEED    130

/////////////////////////////////////////////////////////////////////////////////////////Signal Definitions below.  Can be any power-of-two for OTA, may in Spring be any integer.
#define SIG_AIM1      2
#define SIG_AIM2      4
#define SIG_AIM3      8
#define SIG_AIM4      16
#define SIG_AIM5      32
//////////////////////////////////////////////////////////////////////////////////////////////////////////////LuaCOB, standard calls (mod-specific, this needs to be hacked by designer, unfortunately poorly documented by me)
lua_PlayUnitSound() { return 0; }
lua_PlayLocalSound() { return 0; }
lua_PlayWorldSound() { return 0; }
#endif // STANDARD_COMMANDS_WORLDBUILDER_H_



Usually, I just use an include statement, to include this big chunk of script every time I compile an animation. This means that I don't have this giant wall of text in every script, and can maintain it all in one place. When Spring adds new constants, or changes the behaviors of old ones, I update the file. The include file, which I've attached to this message, can just be dropped into your scripts/ folder of your game.

To get the specific animation to use it, you'll need to change that script a little bit.

Here is an example, using that first example to build on:

Code:
#include "STANDARD_COMMANDS_WORLDBUILDER.h"

piece turret, barrel;

Create()  //What happens when we get made?
{
  //In this case, nothing, but most scripts set up Pieces here for animation later
}

AimWeapon1(heading, pitch)
{
  turn turret to y-axis heading speed <50>;  //turn the turret towards bad guys
  turn barrel to x-axis 0 - pitch speed <30>;  //turn the barrel up / down
  wait-for-turn turret around y-axis;  //wait for that turret to get there!
  wait-for-turn barrel around x-axis;  //also wait for that barrel!

  return 1;  //returning a value of 1, in the context of AimWeapon scripts, means "shoot a shot now!"  returning 0 means "can't shoot for some reason!"
}

Killed()
{
  explode turret type FALL;  //fall off and bounce around!
  explode barrel type SHATTER;  //turn into tiny flying triangles!
}


Attachments:
STANDARD_COMMANDS_WORLDBUILDER.h [11.32 KiB]
Downloaded 10 times


Last edited by Argh on 23 Aug 2009, 21:41, edited 1 time in total.
Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:37 
Kernel Panic Co-Developer
User avatar

Joined: 16 Nov 2004, 13:08
Erik wrote:
Quote:
Error: Unknown identifier SHATTER
I doesn't know what does SHATTER mean. Copy that file into the same folder as your bos, and write #include "springdefs.h" at the top of our your bos.


Attachments:
springdefs.h [7.22 KiB]
Downloaded 33 times
Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:42 
Moderator
User avatar

Joined: 29 Apr 2005, 00:14
Location: #moddev - join it!
zwzsg wrote:
FLOZi wrote:
Hopefully lua will slay the BOS beast anyway
Sure, Lua is such a fierce beast, poor simple bos stands no chance.


It is better in the long run to have 1 scripting format for unit animations, defs, and game scripting code for newbies to learn than a multitude of formats most of which are specific to a 12 year old game and won't be seen anywhere else - even if some of us are well adapted to them, and even if some of us have wracked near impossible things from them. :P


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:48 

Joined: 27 Jun 2009, 00:32
Location: Germany
An advantage of the Lua system probably is you no longer are bound to a decade old Windows software. I'm still curious how good it will perform...

BTW:
I decided to start the Wiki cleanup with a good guide / manual about all the COB scripting. Who would be the scripting gurus here I can ask some in-depth question like about signals and if things like the Bitmap1-5 definitions being just there for TA compatibility...


Last edited by Master-Athmos on 23 Aug 2009, 21:52, edited 1 time in total.

Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 21:50 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
If you all want to talk about that, we can start another thread.

My opinion is that one of the primary goals of Spring 0.9 is to either get MD5 support working, or a new, Blender-friendly format working, that finally allows for IK and vertex animation techniques (that aren't a monster pain in the arse).

Hell. All we technically need is vertex interpolation code between one mesh and another, and I think S3O could be animated with BOS and show / hide, because IIRC the tristripping always operates in the same order (iow, the display lists would remain the same, if you have two different poses of the same base mesh).

But that's a side issue, and well outside the scope of this newbie's requests, k?


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 23:00 
User avatar

Joined: 20 Aug 2009, 19:49
ok so i followed the "simple mod tutorial"
i added all the required files ( at least i hope so) but on running it it gives me multiple errors:


Quote:
[ 0] missing return table from gamedata/modrules.lua
[ 0] Error loading modrules, using defaults
[ 0] missing return table from gamedata/modrules.lua
[ 0] Parsing definitions
[ 0] [string "gamedata/parse_tdf.lua"]:58: could not find key
[ 0] Failed to load moveDefs
[ 0] error = 2, gamedata/defs.lua, [string "gamedata/defs.lua"]:37: [string "gamedata/defs.lua"]:25: error = 2, gamedata/moveDefs.lua, [string "gamedata/moveDefs.lua"]:21: Error parsing moveinfo.tdf: missing file
[ 0] Caught content exception: [string "gamedata/defs.lua"]:37: [string "gamedata/defs.lua"]:25: error = 2, gamedata/moveDefs.lua, [string "gamedata/moveDefs.lua"]:21: Error parsing moveinfo.tdf: missing file

what do these mean?


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 23 Aug 2009, 23:41 
P.U.R.E. Developer
User avatar

Joined: 21 Feb 2005, 03:38
Location: Herding cats uphill whilst wearing roller skates.
Those errors mean you're missing a few files that you need.

There are several minimal game packages available, which contain all of the basics.

This one is something I built to for a tech demo, but is equally useful for your purpose of getting something working for the first time.

Simply download the file, and change out the references to "glsl_test" to whatever you want to call your first Unit. You need to write a Unit TDF or Lua file, and change the reference in Gamedata/SIDEDATA.TDF to make things work.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 24 Aug 2009, 07:20 
Engines Of War Developer

Joined: 09 Jun 2005, 22:39
Location: Germany, the EU
I'm probably a day or two late in saying this (as you've already put some effort into cob from what I can see) + I have no experience with either cob or the new Lua animation system (so this is NOT coming from an expert).

Nevertheless I would still advise you to use the new Lua animation system... http://springrts.com/wiki/Animation-LuaScripting.

Edit: I was mistaken in saying Spring: 1944 has unit's using it already (was confused as they are making use of the new reverse driving function). I guess if there are no examples round yet, that might be an argument for sticking to cob for now...
Edit2: hah, found one after all, in a branch of their SVN. So go for it, be at the cutting edge of Spring animation ;) !


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 24 Aug 2009, 10:46 
User avatar

Joined: 20 Aug 2009, 19:49
I tried the above example mod but it doesnt show up in the spring lobby.

Edit: nvm i got it.


Top
 Offline Profile  
 
 Post subject: Re: Skripting
PostPosted: 25 Aug 2009, 00:07 
Engines Of War Developer

Joined: 09 Jun 2005, 22:39
Location: Germany, the EU
Glad to hear you got it running (that's how I understood you anyhow). If you get a few of your own set up, give a shout - I'm thinking of learning it as well!


Top
 Offline Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group

Site layout created by Roflcopter et al.