Mappe

Da Soldat Italia Wiki.

Una mappa è un file che utilizza Soldat per riconoscere un livello (per esempio ctf_B2b.PMS). Queste mappe, con l'estensione .PMS, possono essere create con i Map maker. Fino alla versione 1.05b, si è usata l'estensione .PMP.

Indice

Componenti generali

Una mappa è composta da poligoni, scenario, collider, waypoint (per i bot), spawnpoint, e bonus.

Proprietà

Una mappa contiene anche delle proprietà che includono la condizione atmosferica, il suono dei passi, la quantità di carburante del jet e il colore dello sfondo.

Tipi di mappa

Ci sono vari tipi di mappe in Soldat. Per differenziarle in modo che il gioco capisca che tipo di modalità di gioco far partire in una determinata mappa, è presente nel nome del file mappa un prefisso fatto di un codice di 3 lettere seguito da un underscore e dal nome della mappa, per esempio:

Struttura del file

Ecco la struttura fisica del file della mappa. Il testo, salvato in un file, è utilizzabile in Hex Workshop 4.23 per vedere le componenti della mappa. Con un po' di lavoro, è possibile convertirlo per farlo funzionare con il C++ o con altri linguaggi.


/*
Soldat PMS file format structure defenition file for Hex Workshop
by: Chrisgbk
*/

//#include "standard-types.hsl" // All the standard deftypes (shown below for clarity)

typedef          char    CHAR ;
typedef signed   __int8  BYTE ;
typedef          BYTE    byte ;
typedef unsigned __int8  UBYTE ;
typedef          UBYTE   ubyte ;
typedef unsigned __int16 WORD ;
typedef          WORD    word ;
typedef unsigned __int16 USHORT ;
typedef          USHORT  ushort ;
typedef          short   SHORT ;
typedef unsigned __int32 DWORD ;
typedef          DWORD   dword ;
typedef          long    LONG ;
typedef unsigned __int32 ULONG ;
typedef          ULONG   ulong ;
typedef signed   __int64 QUAD ;
typedef          QUAD    quad ;
typedef unsigned __int64 UQUAD ;
typedef          UQUAD   uquad ;
typedef          float   FLOAT ;
typedef          double  DOUBLE ;

#pragma maxarray(10000) // default max array size is 128(to protect from corrupt data), need this
#pragma byteorder(little_endian) // Intel

#pragma enumsize(1) // 1 byte
#pragma pack(1)
// note: since #pragma pack(4) isnt supported by hex workshop, I had to pad everything manually
// it may be wise to do it this way, even if your compiler supposrt this pragma, due to uncertanties over how a given compiler will allign the members of the data structures.

typedef enum TRUEFALSE {
	FALSE = 0,
	TRUE
} BOOL; // just... yeah

#pragma hide() // don't make these structs visible in Hex Workshop

typedef enum POLYTYPE {
	ptNORMAL = 0,
	ptONLY_BULLETS_COLLIDE,
	ptONLY_PLAYERS_COLLIDE,
	ptNO_COLLIDE,
	ptICE,
	ptDEADLY,
	ptBLOODY_DEADLY,
	ptHURTS,
	ptREGENERATES,
	ptLAVA
} PMS_POLYTYPE;

typedef enum DRAWBEHIND {
	dbBEHIND_ALL = 0,
	dbBEHIND_MAP,
	dbBEHIND_NONE
} PMS_DRAWBEHIND;

typedef enum SPECIALACTIONS {
	saNONE = 0,
	saSTOP_AND_CAMP,
	saWAIT_1_SECOND,
	saWAIT_5_SECONDS,
	saWAIT_10_SECONDS,
	saWAIT_15_SECONDS,
	saWAIT_20_SECONDS
} PMS_SPECIALACTIONS;

typedef enum WEATHERTYPE {
	wtNONE = 0,
	wtRAIN,
	wtSANDSTORM,
	wtSNOW
} PMS_WEATHERTYPE;

typedef enum STEPSTYPE {
	stHARD_GROUND = 0,
	stSOFT_GROUND,
	stNONE
} PMS_STEPSTYPE;

#pragma enumsize(4) // 4 byte

typedef enum SPAWNTEAM {
	stGENERAL = 0,
	stALPHA,
	stBRAVO,
	stCHARLIE,
	stDELTA,
	stALPHA_FLAG,
	stBRAVO_FLAG,
	stGRENADES,
	stMEDKITS,
	stCLUSTERS,
	stVEST,
	stFLAMER,
	stBERSERKER,
	stPREDATOR,
	stYELLOW_FLAG,
	stRAMBO_BOW,
	stSTAT_GUN
} PMS_SPAWNTEAM;

typedef struct tagPMS_VECTOR {
	FLOAT x;
	FLOAT y;
	FLOAT z;
} PMS_VECTOR;

typedef struct tagPMS_COLOR {
	UBYTE blue;
	UBYTE green;
	UBYTE red;
	UBYTE alpha;
} PMS_COLOR;

typedef struct tagPMS_HEADER {
	LONG version;
} PMS_HEADER;

typedef struct tagPMS_OPTIONS {
	UBYTE nameLen;
	CHAR name[nameLen];
	CHAR nameFiller[38-nameLen];
	UBYTE texLen;
	CHAR texture[texLen];
	CHAR textureFiller[24 - texLen];
	PMS_COLOR bgColorTop;
	PMS_COLOR bgColorBottom;
	LONG jetAmount;
	UBYTE grenades;
	UBYTE medikits;
	PMS_WEATHERTYPE weather;
	PMS_STEPSTYPE steps;
	LONG randID;
} PMS_OPTIONS;

typedef struct tagPMS_VERTEX {
	FLOAT x;
	FLOAT y;
	FLOAT z;
	FLOAT rhw;
	PMS_COLOR color;
	FLOAT tu;
	FLOAT tv;
} PMS_VERTEX;

typedef struct tagPMS_POLYGON {
	PMS_VERTEX vetex[3];
	PMS_VECTOR perpendicular[3];
	PMS_POLYTYPE polyType;
} PMS_POLYGON;

typedef struct tagPMS_SECTOR {
	WORD polyCount;
	WORD polys[polyCount];
} PMS_SECTOR;

typedef struct tagPMS_PROP {
	BOOL active;
	UBYTE filler1;
	WORD style;
	LONG width;
	LONG height;
	FLOAT x;
	FLOAT y;
	FLOAT rotation;
	FLOAT scaleX;
	FLOAT scaleY;
	UBYTE alpha;
	UBYTE filler2[3];
	PMS_COLOR color;
	PMS_DRAWBEHIND level;
	UBYTE filler3[3];
} PMS_PROP;
/*
found out that these are already defined ^_^

typedef struct tagDOSTIME {
	WORD second  : 5;  
	WORD minute : 6;    
	WORD hour    : 5;   
} DOSTIME;

typedef struct tagDOSDATE {
	WORD day  : 5;  
	WORD month : 4;    
	WORD year    : 7;   
} DOSDATE;
*/
typedef struct tagPMS_TIMESTAMP {
	DOSTIME time;
	DOSDATE date;
} PMS_TIMESTAMP;

typedef struct tagPMS_SCENERY {
	UBYTE nameLen;
	CHAR name[nameLen];
	CHAR nameFiller[50-nameLen];
	PMS_TIMESTAMP timestamp;
} PMS_SCENERY;

typedef struct tagPMS_COLLIDER {
	BOOL active;
	UBYTE filler[3];
	FLOAT x;
	FLOAT y;
	FLOAT radius;
} PMS_COLLIDER;

typedef struct tagPMS_SPAWNPOINT {
	BOOL active;
	UBYTE filler[3];
	LONG x;
	LONG y;
	PMS_SPAWNTEAM team;
} PMS_SPAWNPOINT;

typedef struct tagPMS_WAYPOINT {
	BOOL active;
	UBYTE filler1[3];
	LONG id;
	LONG x;
	LONG y;
	BOOL left;
	BOOL right;
	BOOL up;
	BOOL down;
	BOOL jet;
	UBYTE path;
	PMS_SPECIALACTIONS specialAction;
	UBYTE c2;
	UBYTE c3;
	UBYTE filler2[3];
	LONG numConnections;
	LONG connections[20];
} PMS_WAYPOINT;

#pragma show()

struct PMS_FILE {
	PMS_HEADER header;
	PMS_OPTIONS options;
	LONG polygonCount;
	PMS_POLYGON polygon[polygonCount];
	LONG sectorDivision;
	LONG numSectors;
	//PMS_SECTOR sector[(numSectors*2)+1][(numSectors*2)+1]; // unlike VB/Delphi, can't define the lower bound; only the length. -25 to 25 is the same as 0 to 50, or length of 51 ((2*25)+1)
	PMS_SECTOR sector[((numSectors*2)+1)*((numSectors*2)+1)]; // same as above, but as a single flat array. Use whatever you feel most comfortable with.
	LONG propCount;
	PMS_PROP prop[propCount];
	LONG sceneryCount;
	PMS_SCENERY scenery[sceneryCount];
	LONG colliderCount;
	PMS_COLLIDER collider[colliderCount];
	LONG spawnpointCount;
	PMS_SPAWNPOINT spawnpoint[spawnpointCount];
	LONG waypointCount;
	PMS_WAYPOINT waypoint[waypointCount];
};

Vedi anche

Una guida per imparare a creare mappe.

Programmi necessari per creare mappe.

Strumenti personali