/*----------------------------------------------------------------------------*- ============================== Y Server Includes - MTA Loader ============================== Description: Loads MTA XML format map files for use with the object and race systems. Legal: Copyright (C) 2007 Alex "Y_Less" Cole This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Changelog: 12/10/07: Added Loader_AddHandler. Added Loader_GetRace. 24/08/07: First version. Functions: Public: Loader_Spawn - Processes a loaded spawn point. Loader_Check - Processes a loaded checkpoint. Loader_Obj - Processes a loaded object. Core: Loader_Loader - Initialises data. Stock: Loader_Parse - Loads a file. Loader_AddHandler - Adds a custom handle for the race file. Loader_GetRace - Returns the current race handle. Static: - Inline: - API: - Callbacks: - Definitions: - Enums: - Macros: - Tags:-e_RACE_FLAGS - Race data flag. Variables: Global: - Static: YSI_g_sXMLRules - Handle to the XML parse rule set. YSI_g_sCurRace - Handle to the current race being built. Commands: - Compile options: - Operators: - -*----------------------------------------------------------------------------*/ static stock XML:YSI_g_sXMLRules = NO_XML_FILE, #if defined _YSI_VISUAL_OBJECTS YSI_g_sRaceObjects[ceildiv(MAX_DYN_OBJECTS, 4)] = {-1, ...}, #endif YSI_g_sCurRace, YSI_g_sCurWorld; forward Loader_Spawn(); forward Loader_Check(); forward Loader_Obj(); /*----------------------------------------------------------------------------*- Function: Loader_Loader Params: - Return: - Notes: Defines the parsing rules for reading MTA XML maps. -*----------------------------------------------------------------------------*/ Loader_Loader() { if (YSI_g_sXMLRules == NO_XML_FILE) { YSI_g_sXMLRules = XML_New(); if (YSI_g_sXMLRules != NO_XML_FILE) { XML_AddHandler(YSI_g_sXMLRules, "object", "Loader_Obj"); XML_AddHandler(YSI_g_sXMLRules, "checkpoint", "Loader_Check"); XML_AddHandler(YSI_g_sXMLRules, "spawnpoint", "Loader_Spawn"); } } return 1; } /*----------------------------------------------------------------------------*- Function: Loader_Parse Params: filename[] - File to parse as an XML race file. laps - Number of laps to race for. entry - Cost of entry. countdown - Time to count down from for start. bool:arial - Use arial checkpoints instead. bool:fixedPrize - Set prize amounts manually. exitTime - Time allowed out a vehicle before fail. interior - The interior of the race. world - The world of the race. bool:restart - Don't destroy the race on completion. Return: Created race. Notes: Tries to create a new race to save to then parses the file. -*----------------------------------------------------------------------------*/ stock Loader_Parse(filename[], laps = 0, entry = 0, countdown = 3, bool:arial = false, bool:fixedPrize = true, exitTime = 0, interior = 0, world = 0, bool:restart = false) { if (!fexist(filename)) return NO_RACE; new race = Race_Create(laps, entry, countdown, arial, fixedPrize, exitTime, interior, world, restart); if (race != NO_RACE) { YSI_g_sCurRace = race; YSI_g_sCurWorld = world; XML_Parse(YSI_g_sXMLRules, filename); } YSI_g_sCurWorld = 0; YSI_g_sCurRace = NO_RACE; return race; } /*----------------------------------------------------------------------------*- Function: Loader_ParseObjects Params: filename[] - File to parse. world - World for the objects to appear in or -1 for all. Return: - Notes: Parses a map file, loading only the objects. -*----------------------------------------------------------------------------*/ stock Loader_ParseObjects(filename[], world = -1) { YSI_g_sCurWorld = world; return XML_Parse(YSI_g_sXMLRules, filename); } /*----------------------------------------------------------------------------*- Function: Loader_Unload Params: race - Race to remove objects for. Return: - Notes: Destroys all the objects created for a race loaded with the loader. -*----------------------------------------------------------------------------*/ stock Loader_Unload(race) { #if defined _YSI_VISUAL_OBJECTS new race1 = race << 8, race2 = race << 16, race3 = race << 24; for (new i = 0; i < sizeof (YSI_g_sRaceObjects); i++) { if (YSI_g_sRaceObjects[i] & 0xFF000000 == race3) { YSI_g_sRaceObjects[i] |= 0xFF000000; DestroyDynamicObject((i * 4) + 3); } if (YSI_g_sRaceObjects[i] & 0x00FF0000 == race2) { YSI_g_sRaceObjects[i] |= 0x00FF0000; DestroyDynamicObject((i * 4) + 2); } if (YSI_g_sRaceObjects[i] & 0x0000FF00 == race1) { YSI_g_sRaceObjects[i] |= 0x0000FF00; DestroyDynamicObject((i * 4) + 1); } if (YSI_g_sRaceObjects[i] & 0x000000FF == race) { YSI_g_sRaceObjects[i] |= 0x000000FF; DestroyDynamicObject((i * 4)); } } #else #pragma unused race #endif } /*----------------------------------------------------------------------------*- Function: Loader_Convert Params: Float:radians - Radian angle to convert to degrees. Return: Float Notes: Based on mtarad2deg made by Trix and fixed by Mike. Converts radians to degrees and rationalises. -*----------------------------------------------------------------------------*/ stock Float:Loader_Convert(Float:radians) { if (radians == 0.0) { return 0.0; } new Float:retval = (360.0 + (radians / 0.0174532925)); while (retval >= 360.0) retval -= 360.0; while (retval < 0.0) retval += 360.0; return retval; } /*----------------------------------------------------------------------------*- Function: Loader_Obj Params: - Return: CreateDynamicObject Notes: Called when an end object tag is reached to create an object. -*----------------------------------------------------------------------------*/ public Loader_Obj() { #if defined _YSI_VISUAL_OBJECTS static name[MAX_XML_ENTRY_NAME], val[MAX_XML_ENTRY_TEXT]; new Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, model; while (XML_GetKeyValue(name, val)) { if (!strcmp(name, "position", true)) { new pos; x = floatstr(val); pos = chrfind(' ', val, pos); y = floatstr(val[++pos]); pos = chrfind(' ', val, pos); z = floatstr(val[++pos]); } else if (!strcmp(name, "rotation", true)) { new pos; rz = floatstr(val); pos = chrfind(' ', val, pos); ry = floatstr(val[++pos]); pos = chrfind(' ', val, pos); rx = floatstr(val[++pos]); } else if (!strcmp(name, "model", true)) { model = strval(val); } } new obj = CreateDynamicObject(model, x, y, z, Loader_Convert(rx), Loader_Convert(ry), Loader_Convert(rz)); if (YSI_g_sCurWorld != -1) { Object_RemoveFromAllWorlds(obj); Object_AddToWorld(obj, YSI_g_sCurWorld); } #if defined _YSI_VISUAL_RACE new shift = (8 * (obj & 3)), mul = obj >>> 2; if (YSI_g_sCurRace != NO_RACE) { YSI_g_sRaceObjects[mul] = (YSI_g_sRaceObjects[mul] & ~(0xFF << shift)) | YSI_g_sCurRace << shift; } #endif return obj; #else return -1; #endif } /*----------------------------------------------------------------------------*- Function: Loader_Check Params: - Return: Race_AddCheckpoint Notes: Called when an end checkpoint tag is reached to add a checkpoint to a race. -*----------------------------------------------------------------------------*/ public Loader_Check() { #if defined _YSI_VISUAL_RACE if (YSI_g_sCurRace == NO_RACE) return -1; static name[MAX_XML_ENTRY_NAME], val[MAX_XML_ENTRY_TEXT]; new Float:x, Float:y, Float:z; while (XML_GetKeyValue(name, val)) { if (!strcmp(name, "position", true)) { new pos; x = floatstr(val); pos = chrfind(' ', val, pos); y = floatstr(val[++pos]); pos = chrfind(' ', val, pos); z = floatstr(val[++pos]); } } return Race_AddCheckpoint(YSI_g_sCurRace, x, y, z); #else return -1; #endif } /*----------------------------------------------------------------------------*- Function: Loader_Spawn Params: - Return: Race_AddStart Notes: Called when an end spawnpoint tag is reached to add a startpoint to a race. -*----------------------------------------------------------------------------*/ public Loader_Spawn() { #if defined _YSI_VISUAL_RACE if (YSI_g_sCurRace == NO_RACE) return -1; static name[MAX_XML_ENTRY_NAME], val[MAX_XML_ENTRY_TEXT]; new Float:x, Float:y, Float:z, Float:rz; while (XML_GetKeyValue(name, val)) { if (!strcmp(name, "position", true)) { new pos; x = floatstr(val); pos = chrfind(' ', val, pos); y = floatstr(val[++pos]); pos = chrfind(' ', val, pos); z = floatstr(val[++pos]); } else if (!strcmp(name, "rotation", true)) { rz = floatstr(val); } } return Race_AddStart(YSI_g_sCurRace, x, y, z, rz); #else return 1; #endif } /*----------------------------------------------------------------------------*- Function: Loader_AddHandler Params: trigger[] - Tag to trigger the callback. function[] - Function to call for the tag. Return: - Notes: Used to add custom handlers to non-default tags in the race file format. -*----------------------------------------------------------------------------*/ stock Loader_AddHandler(trigger[], function[]) { if (YSI_g_sXMLRules != NO_XML_FILE) return XML_AddHandler(YSI_g_sXMLRules, trigger, function); return 0; } /*----------------------------------------------------------------------------*- Function: Loader_GetRace Params: - Return: Current race handle. Notes: - -*----------------------------------------------------------------------------*/ stock Loader_GetRace() { return YSI_g_sCurRace; }