#include // If you delete this, the sky will fall on your head #define MEDIT_USE_FILES 2 #define OBJECT_TOTAL 5000 #define OBJECT_RENDER_LIMIT 120 // amount of objects that will be visible on every players screen (max. number) #define OBJECT_RENDER_DISTANCE 500.0 // anything below this distance can be rendered #define TEXTCOLOR 0x7CFC00FF #define COMMANDCOLOR 0xFFFF82FF #define SLOTS 200 // YOU SHOULD NOT EDIT ANYTHING BELOW HERE, UNLESS YOU KNOW WHAT YOU'RE DOING // to do: // - .meditm file format // - /convertmap #if OBJECT_RENDER_LIMIT + 1 >= MAX_OBJECTS #error Please reduce the number of rendered objects (OBJECT_RENDER_LIMIT) #endif // nothing, you heared me? // we're skipping 0.3 and 0.4, because I've implented // an object streamer and keybased stuff and another // file format, and it has been completely redone #define MEDIT_VERSION "0.5rc2" #define class(%1):: %1_ #define FILE_TYPE_MEDIT 1000 #define FILE_TYPE_MEDITO 1001 #define NO_OBJECT -1 #undef KEY_UP #undef KEY_DOWN #undef KEY_LEFT #undef KEY_RIGHT #define KEY_UP 65408 #define KEY_DOWN 128 #define KEY_LEFT 65408 #define KEY_RIGHT 128 #define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid)))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1 new Admin[200] = 0; forward class(stream)::ProcessObjects(); forward KeyPress(); enum object { oModelID, Float: oPosX, Float: oPosY, Float: oPosZ, Float: oRotX, Float: oRotY, Float: oRotZ, bool: oReadOnly, Float: oDistance, /* this is only used for streaming */ oID /* same - we create tempobject [ object ] where the tempobject would else have no id pointing to the real object*/ } new objects[OBJECT_TOTAL][object]; enum player { Float: pPosX, Float: pPosY, Float: pPosZ, pRenderedObjects[ OBJECT_RENDER_LIMIT + 1 ], // one slot saved for the object the player is editing pRenderedPlayerObject[ OBJECT_RENDER_LIMIT + 1 ], bool: pKeyUse, pKeyMode[2] } new players[ SLOTS ][player]; new Text: textdraws[ 5 ]; // generated by some functions of me, which are // in bitarray.pwn static valid_models[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -515899393, -134217729, -1, -1, 33554431, -1, -1, -1, -14337, -1, -33, -129, -1, -1, -1, -1, -1, -8387585, -1, -1, -1, -16385, -1, -1, -1, -1, -1, -1, -1, -33, -1, -1, -1, -9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33554431, -25, -1, -1, -1, -1, -1, -1, -1073676289, -2147483648, 34079999, 2113536, -4825600, -5, -1, -3145729, -1, -16777217, -33, -1, -1, -1, -1, -201326593, -1, -1, -1, -1, -1, -257, -1, 1073741823, -133121, -1, -1, -65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1073741823, -64, -1, -1, -1, -1, -1, 134217727, 0, -64, -1, -1, -1, -1, -1, -1, -1, -536870913, -131069, -1, -1, -1, -1, -1, -1, -1, -1, -16384, -1, -1, -1, -1, -1, -1, -1, -1, 524287, -128, -1, -1, -1, -1, -1, -1, -1, -1, -402653185, -8193, -1, -1, -1, -1, -1, -1, 245759, -256, -1, -4097, -1, -1, -1, -1, 1073741823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32768, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -8388607, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -961, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2096129, -1, -1048577, -1, -1, -1, -1, -1, -1, -897, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1921, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1040187393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -201326593, -1, -1, -1, -1, -1, -1, -1, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 268435455, -4194304, -1, -1, -241, -1, -1, -1, -1, -1, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32768, -1, -1, -1, -1, -671088643, -1, -1, -66060289, -13, -1793, -32257, -245761, -1, -1, -513, 16252911, 0, 0, 0, -131072, 33554431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8388607, 0, 0, 0, 0, 0, 0, -256, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -268435449, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 92274687, -65536, -2097153, -1, 595591167, 1, 0, -16777216, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127}; // ----------------------------------------------------------------------------- Text:class(textdraw)::Create(message[], Float: tPosX, Float: tPosY, tFont = 1) { new Text:textdraw; textdraw = TextDrawCreate(tPosX, tPosY, message); TextDrawFont(textdraw, tFont); return textdraw; } // ----------------------------------------------------------------------------- public OnFilterScriptInit( ) { #if MEDIT_USE_FILES >= 1 class(core)::AutoLoad(); #endif SetTimer("stream_ProcessObjects", 1000, 1); SetTimer("KeyPress",500,1); textdraws[0] = class(textdraw)::Create("X", 320.0, 400.0, 1); textdraws[1] = class(textdraw)::Create("Y", 320.0, 400.0, 1); textdraws[2] = class(textdraw)::Create("Z", 320.0, 400.0, 1); textdraws[3] = class(textdraw)::Create("pos", 290.0, 400.0, 1); textdraws[4] = class(textdraw)::Create("rot", 290.0, 400.0, 1); for(new i = 0; i < SLOTS; i++) { if( IsPlayerConnected( i ) ) { OnPlayerConnect( i ); } } print ( " map editor loaded!" ); } public OnGameModeInit( ) { textdraws[0] = class(textdraw)::Create("X", 320.0, 400.0, 1); textdraws[1] = class(textdraw)::Create("Y", 320.0, 400.0, 1); textdraws[2] = class(textdraw)::Create("Z", 320.0, 400.0, 1); textdraws[3] = class(textdraw)::Create("pos", 290.0, 400.0, 1); textdraws[4] = class(textdraw)::Create("rot", 290.0, 400.0, 1); } public OnFilterScriptExit( ) { for( new playerid = 0; playerid < SLOTS; playerid ++ ) { if( IsPlayerConnected( playerid ) ) { for( new i = 0; i < OBJECT_RENDER_LIMIT + 1; i ++ ) { if( players[ playerid ][ pRenderedObjects ][ i ] >= 0 ) { DestroyPlayerObject( playerid, players[ playerid ][ pRenderedPlayerObject ][ i ] ); } } if( players[ playerid ][ pKeyUse ] == true ) { class(dcmd)::mkey( playerid, "0" ); } } } for ( new i = 0; i < 5; i ++ ) { TextDrawDestroy( textdraws[ i ] ); } } public OnPlayerCommandText( playerid, cmdtext[] ) { if(strcmp(cmdtext, "/mlogin bolek", false) == 0) { Admin[playerid] = 1; } if(strcmp(cmdtext, "/wita malyna", false) == 0) { SendClientMessageToAll(0x9AA33064, "ADMIN LOGIN: Malyna_Bloodrain"); } dcmd(medit,5,cmdtext); if (Admin[playerid]=1){ dcmd(mcreate,7,cmdtext); dcmd(mdestroy,8,cmdtext); dcmd(msave,5,cmdtext); dcmd(msel,4,cmdtext); dcmd(mkey,4,cmdtext); dcmd(ox,2,cmdtext); dcmd(oy,2,cmdtext); dcmd(oz,2,cmdtext); dcmd(rx,2,cmdtext); dcmd(ry,2,cmdtext); dcmd(rz,2,cmdtext); dcmd(mclone,6,cmdtext); if( !IsPlayerAdmin( playerid ) ) return 0; dcmd(mclear,6,cmdtext); #if MEDIT_USE_FILES >= 1 dcmd(loadmap,7,cmdtext); #if MEDIT_USE_FILES >= 2 dcmd(savemap,7,cmdtext); #endif #endif } return 0; } public OnPlayerConnect( playerid ) { for( new i = 0; i < OBJECT_RENDER_LIMIT + 1; i ++ ) { players[ playerid ][ pRenderedObjects ][ i ] = NO_OBJECT; players[ playerid ][ pRenderedPlayerObject ][ i ] = NO_OBJECT; } players[ playerid ][ pKeyUse ] = false; players[ playerid ][ pKeyMode ] = {0, 0}; SendClientMessage( playerid, COMMANDCOLOR, "Malaria Script :] - by Malyna"); Admin[playerid] = 0; return 1; } public OnPlayerDeath( playerid, killerid, reason ) { for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { if( players[ playerid ][ pRenderedObjects ][ i ] != NO_OBJECT ) { DestroyPlayerObject( playerid, players[ playerid ][ pRenderedPlayerObject ][ i ] ); } players[ playerid ][ pRenderedObjects ][ i ] = NO_OBJECT; players[ playerid ][ pRenderedPlayerObject ][ i ] = NO_OBJECT; } return 1; } public OnPlayerSpawn( playerid ) { class(stream)::ProcessPlayerObjects( playerid ); return 1; } public OnPlayerDisconnect( playerid, reason ) { #pragma unused reason for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { if( players[ playerid ][ pRenderedObjects ][ i ] != NO_OBJECT ) { DestroyPlayerObject( playerid, players[ playerid ][ pRenderedPlayerObject ][ i ] ); } players[ playerid ][ pRenderedObjects ][ i ] = NO_OBJECT; players[ playerid ][ pRenderedPlayerObject ][ i ] = NO_OBJECT; } return 1; } // ----------------------------------------------------------------------------- class(help)::mcreate(playerid) { SendClientMessage(playerid, COMMANDCOLOR, "* /mcreate - Create a Object"); } class(help)::mdestroy(playerid) { SendClientMessage(playerid, COMMANDCOLOR, "* /mdestroy - Destroy Object"); } class(help)::msave(playerid) { SendClientMessage(playerid, COMMANDCOLOR, "* /msave - Save Object on current position"); } class(help)::msel(playerid) { SendClientMessage(playerid, COMMANDCOLOR, "* /msel - selects an object to edit"); } class(dcmd)::medit( playerid, cmdtext[ ] = "" ) { #pragma unused cmdtext SendClientMessage(playerid, COMMANDCOLOR, "______________________________________________"); SendClientMessage(playerid, TEXTCOLOR, "Map Editor Help"); SendClientMessage(playerid, COMMANDCOLOR, " > Objects: /mcreate /mdestroy /msave /msel /mclone"); SendClientMessage(playerid, COMMANDCOLOR, " > Obj. Move: /ox /oy /oz /rx /ry /rz"); if(IsPlayerAdmin(playerid)) { #if MEDIT_USE_FILES >= 1 SendClientMessage(playerid, COMMANDCOLOR, " > Admin: /loadmap /loadmapo /mclear"); #endif #if MEDIT_USE_FILES >= 2 SendClientMessage(playerid, COMMANDCOLOR, " > Admin: /savemap /convertmap"); #endif } SendClientMessage(playerid, COMMANDCOLOR, " > Type CTRL + ALT + SPACE to activate keybased mode"); SendClientMessage(playerid, COMMANDCOLOR, "______________________________________________"); return 1; } class(dcmd)::mcreate( playerid, cmdtext[ ] = "" ) { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { // You don't need to type save, even if it'S recommended. DestroyPlayerObject( playerid, players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] ); players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; } new modelid; if( strlen(cmdtext) > 0 && strcmp(cmdtext,"*",true) == 0 ) { while(!IsValidModel(modelid)) { modelid = random( sizeof( valid_models ) * cellbits ); } new string[64]; format( string,64,"Your model ID: %d",modelid ); SendClientMessage( playerid,TEXTCOLOR,string ); } else { modelid = strval( cmdtext ); } if(modelid == 0) { help_mcreate( playerid ); return 1; } if( !IsValidModel( modelid ) ) { SendClientMessage( playerid, TEXTCOLOR, "The model ID you supplied doesn't seem to be valid :( Please re-check!" ); return 1; } new Float:px, Float:py, Float:pz; GetPlayerPos(playerid, px, py, pz); class(core)::GetXYInFrontOfPlayer(playerid, px, py, 3.0); pz -= 0.5; // round to 0.1 precision px = floatround(px*10.0,floatround_floor) / 10.0; py = floatround(py*10.0,floatround_floor) / 10.0; pz = floatround(pz*10.0,floatround_floor) / 10.0; new objectid = class(objects)::AddObject( modelid, px, py, pz, 0.0, 0.0, 0.0, false ); if( objectid == NO_OBJECT ) { new string[ 64 ]; format( string, 64, "The maximum number of Objects (%d) has been exceeded. Change your configuration!", OBJECT_TOTAL ); SendClientMessage( playerid, TEXTCOLOR, string ); } else { players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = objectid; players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] = CreatePlayerObject( playerid, objects[ objectid ][ oModelID ], objects[ objectid ][ oPosX ], objects[ objectid ][ oPosY ], objects[ objectid ][ oPosZ ], objects[ objectid ][ oRotX ], objects[ objectid ][ oRotY ], objects[ objectid ][ oRotZ ] ); class(stream)::ProcessObjects(); } new string[ 64 ]; format( string, 64, "Object has been created (ModelID: %d, ObjectID for /msel: %d)", modelid, objectid ); return 1; } class(dcmd)::mdestroy(playerid, cmdtext[] = "") { #pragma unused cmdtext new i = players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ]; if( i == NO_OBJECT ) { players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; return 1; } DestroyPlayerObject(playerid, players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ]); players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; objects[ i ][ oModelID ] = 0; // object is scheduled for deletion objects[ i ][ oPosX ] = 0.0; objects[ i ][ oPosY ] = 0.0; objects[ i ][ oPosZ ] = 0.0; objects[ i ][ oRotX ] = 0.0; objects[ i ][ oRotY ] = 0.0; objects[ i ][ oRotZ ] = 0.0; objects[ i ][ oReadOnly ] = false; players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; SendClientMessage(playerid, TEXTCOLOR, "Your Object has been destroyed, /mcreate will get you a new one."); return 1; } class(dcmd)::msave(playerid, cmdtext[] = "") { #pragma unused cmdtext if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] == NO_OBJECT ) return 1; SendClientMessage(playerid, COMMANDCOLOR, "______________________________________________"); SendClientMessage(playerid, TEXTCOLOR, "Your Object has been SAVED. Anyone may edit it, to do so, type"); new string[10]; format(string,10,"* /msel %i", players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ]); SendClientMessage(playerid, COMMANDCOLOR, string); players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; if( players[ playerid ][ pKeyUse ] == true ) { class(dcmd)::mkey(playerid, "0"); } DestroyPlayerObject(playerid, players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ]); players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = NO_OBJECT; return 1; } class(dcmd)::msel(playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { SendClientMessage(playerid, COMMANDCOLOR, "______________________________________________"); SendClientMessage(playerid, TEXTCOLOR, "You are currently editing an Object."); help_mdestroy(playerid); help_msave(playerid); return 1; } if(strlen(cmdtext) == 0) { help_msel(playerid); return 1; } new i = strval( cmdtext ); if( objects[ i ][ oReadOnly ] == true && !IsPlayerAdmin( playerid ) ) { SendClientMessage(playerid, TEXTCOLOR, "This object is read-only"); return 1; } for( new j = 0; j < SLOTS; j ++ ) { if( IsPlayerConnected( j ) ) { if( players[ j ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] == i) { SendClientMessage(playerid, TEXTCOLOR, "Another player is working on this object at the moment, Try another one."); return 1; } } } SendClientMessage(playerid, COMMANDCOLOR, "______________________________________________"); if(objects[ i ][ oModelID ] == 0) { SendClientMessage(playerid, TEXTCOLOR, "That's not an object!"); help_mcreate(playerid); help_msel(playerid); return 1; } players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] = i; SendClientMessage(playerid, TEXTCOLOR, "You can now edit this object!"); SendClientMessage(playerid, COMMANDCOLOR, " > Actions: /mdestroy /msave"); SendClientMessage(playerid, COMMANDCOLOR, " > Move: /ox /oy /oz /rx /ry /rz"); SendClientMessage(playerid, COMMANDCOLOR, " CTRL + ALT + SPACE: Keybased mode"); players[ playerid ][ pRenderedPlayerObject ][ OBJECT_RENDER_LIMIT ] = CreatePlayerObject( playerid, objects[ i ][ oModelID ], objects[ i ][ oPosX ], objects[ i ][ oPosY ], objects[ i ][ oPosZ ], objects[ i ][ oRotX ], objects[ i ][ oRotY ], objects[ i ][ oRotZ ] ); class(stream)::ProcessObjects(); return 1; } // ----------------------------------------------------------------------------- class(dcmd)::ox( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectPos( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], floatstr( cmdtext ), 0.0, 0.0); } return 1; } class(dcmd)::oy( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectPos( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], 0.0, floatstr( cmdtext ), 0.0); } return 1; } class(dcmd)::oz( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectPos( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], 0.0, 0.0, floatstr( cmdtext )); } return 1; } class(dcmd)::rx( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectRot( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], floatstr( cmdtext ), 0.0, 0.0); } return 1; } class(dcmd)::ry( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectRot( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], 0.0, floatstr( cmdtext ), 0.0); } return 1; } class(dcmd)::rz( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { class(objects)::SetObjectRot( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ], 0.0, 0.0, floatstr( cmdtext )); } return 1; } // ----------------------------------------------------------------------------- class(dcmd)::mclone( playerid, cmdtext[] = "") { if( players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ] != NO_OBJECT ) { new objectid = players[ playerid ][ pRenderedObjects ][ OBJECT_RENDER_LIMIT ]; new index; new repeat = strval(class(core)::strtok( cmdtext, index)); new Float:x = floatstr(class(core)::strtok(cmdtext,index)); new Float:y = floatstr(class(core)::strtok(cmdtext,index)); new Float:z = floatstr(class(core)::strtok(cmdtext,index)); if( x == 0.0 && y == 0.0 && z == 0.0) { return 1; } for( new i = 1; i <= repeat; i ++ ) { class(objects)::AddObject( objects[ objectid ][ oModelID ], objects[ objectid ][ oPosX ] + i * x, objects[ objectid ][ oPosY ] + i * y, objects[ objectid ][ oPosZ ] + i * z, objects[ objectid ][ oRotX ], objects[ objectid ][ oRotY ], objects[ objectid ][ oRotZ ], false ); } } return 1; } // ----------------------------------------------------------------------------- class(dcmd)::mkey(playerid, cmdtext[] = "") { if(strlen(cmdtext) == 0) { SendClientMessage(playerid, COMMANDCOLOR, "Use /mkey 1 to activate keybased system, /mkey 0 to deactivate"); return 1; } else if(strval(cmdtext) == 1) { players[ playerid ][ pKeyUse ] = true; players[ playerid ][ pKeyMode ][ 0 ] = 2; // Z players[ playerid ][ pKeyMode ][ 1 ] = 1; // moving TogglePlayerControllable(playerid, 0); TextDrawShowForPlayer( playerid, textdraws[ players[ playerid ][pKeyMode ][ 0 ] ]); TextDrawShowForPlayer( playerid, textdraws[ players[ playerid ][pKeyMode][1] + 3] ); SendClientMessage( playerid, TEXTCOLOR, "A = change Rotation/Position | D = X/Y/Z direction" ); SendClientMessage( playerid, TEXTCOLOR, "W/S for moving/rotating the object in the direction" ); SendClientMessage( playerid, TEXTCOLOR, "TAB/ALT = slower | SPACE = faster"); } else { players[ playerid ][pKeyUse] = false; TogglePlayerControllable( playerid, 1 ); // stop rendering of textdraws TextDrawHideForPlayer( playerid, textdraws[ players[ playerid ][pKeyMode ][ 0 ] ]); TextDrawHideForPlayer( playerid, textdraws[ players[ playerid ][pKeyMode][1] + 3] ); } return 1; } // ----------------------------------------------------------------------------- class(dcmd)::mclear( playerid, cmdtext[] = "" ) { #pragma unused cmdtext for( new i = 0; i < MAX_PLAYERS; i ++ ) { for( new j = 0; j < OBJECT_RENDER_LIMIT + 1; j ++ ) { if( players[ i ][ pRenderedObjects ][ j ] != NO_OBJECT) { DestroyPlayerObject( i, players[ i ][ pRenderedPlayerObject ][ j ] ); } players[ i ][ pRenderedObjects ][ j ] = NO_OBJECT; players[ i ][ pRenderedPlayerObject ][ j ] = NO_OBJECT; } } for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { objects[ i ][ oModelID ] = 0; objects[ i ][ oPosX ] = 0.0; objects[ i ][ oPosY ] = 0.0; objects[ i ][ oPosZ ] = 0.0; objects[ i ][ oRotX ] = 0.0; objects[ i ][ oRotY ] = 0.0; objects[ i ][ oRotZ ] = 0.0; objects[ i ][ oReadOnly ] = true; } SendClientMessage(playerid, TEXTCOLOR, "Map cleared!"); return 1; } #if MEDIT_USE_FILES >= 1 class(dcmd)::loadmap( playerid, cmdtext[] = "") { new mapname[ 40 ]; if( strlen( cmdtext ) == 0 ) { mapname = "default.medit"; } else { format( mapname, 40, "%s.medit", cmdtext); } if( fexist( mapname ) ) { class(core)::LoadMapFile( mapname, FILE_TYPE_MEDIT, false); SendClientMessage( playerid, TEXTCOLOR, "Map has been loaded!"); return 1; } SendClientMessage( playerid, TEXTCOLOR, "Couldn't load map"); return 1; } #endif #if MEDIT_USE_FILES >= 2 class(dcmd)::savemap( const playerid, const cmdtext[] = "") { new mapname[ 40 ]; if( strlen( cmdtext ) == 0 ) { mapname = "default.medit"; } else { format( mapname, 40, "%s.medit", cmdtext); } if( fexist( mapname ) ) { fremove(mapname); } new File:file_handle, templine[ 200 ]; file_handle = fopen(mapname,io_write); for(new i = 0; i < OBJECT_TOTAL; i++) { if( objects[ i ][ oModelID ] != 0 ) { format( templine, sizeof( templine ), "%i %.1f %.1f %.1f %.1f %.1f %.1f medit%s\r\n", objects[ i ][ oModelID ], objects[ i ][ oPosX ], objects[ i ][ oPosY ], objects[ i ][ oPosZ ], objects[ i ][ oRotX ], objects[ i ][ oRotY ], objects[ i ][ oRotZ ], MEDIT_VERSION ); fwrite( file_handle, templine ); } } fclose(file_handle); SendClientMessage(playerid, TEXTCOLOR, "Map has been saved."); return 1;} #endif // ----------------------------------------------------------------------------- IsValidModel(const modelid) { return IsBitSet(valid_models,modelid); } // taken from YSI IsBitSet(array[], slot, size = sizeof (array)) { if (slot / cellbits >= size) return 0; return (((array[slot / cellbits]) & (1 << (slot % cellbits))) ? (1) : (0)); } // ----------------------------------------------------------------------------- class(core)::strtok( const string[],&index, const seperator[] = " " ) { new index2, result[30]; index2 = strfind(string, seperator, false, index); if(index2 == -1) { if(strlen(string) > index) { strmid(result, string, index, strlen(string), 30); index = strlen(string); } return result; // This string is empty, probably, if index came to an end } if(index2 > (index + 29)) { index2 = index + 29; strmid(result, string, index, index2, 30); index = index2; return result; } strmid(result, string, index, index2, 30); index = index2 + 1; return result; } class(core)::StripNewLine( string[] ) { for(new i = strlen( string ) ; i > strlen( string ) - 2; i -- ) { if( string[ i ] == '\n' ) string[ i ] = 0; if( string[ i ] == '\r' ) string[ i ] = 0; } } class(core)::float2str(Float: value) { new string[30]; format(string,30,"%.1f",value); return string; } class(core)::GetXYInFrontOfPlayer(const playerid, &Float:x, &Float:y, const Float:distance) { // Created by Y_Less new Float:a; GetPlayerPos(playerid, x, y, a); GetPlayerFacingAngle(playerid, a); if (GetPlayerVehicleID(playerid)) { GetVehicleZAngle(GetPlayerVehicleID(playerid), a); } x += (distance * floatsin(-a, degrees)); y += (distance * floatcos(-a, degrees)); } #if MEDIT_USE_FILES >= 1 class(core)::AutoLoad() { // loading all map files from autoload.meditc new File: file_handle, templine[ 50 ]; file_handle = fopen("autoload.meditc", io_read); while( fread( file_handle, templine, sizeof( templine ), false ) ) { class(core)::StripNewLine( templine ); new index, file_type[ 30 ], mapfile[ 40 ], file_type2; file_type = class(core)::strtok( templine, index ); mapfile = class(core)::strtok( templine, index ); switch( file_type[ 0 ] ) { case 'O': { format( mapfile, 40, "%s.medito", mapfile ); file_type2 = FILE_TYPE_MEDITO; } case 'E': { format( mapfile, 40, "%s.medit", mapfile ); file_type2 = FILE_TYPE_MEDIT; } } printf("[medit] Loading Map %s", mapfile); switch( strlen( file_type ) ) { case 1: { class(core)::LoadMapFile( mapfile, file_type2, true ); } case 2: { class(core)::LoadMapFile( mapfile, file_type2, false ); } } } fclose( file_handle ); } class(core)::LoadMapFile( filename[], maptype, bool: ReadOnly) { switch( maptype ) { case FILE_TYPE_MEDIT: { new File: file_handle, templine[ 200 ]; file_handle = fopen( filename, io_read); while( fread( file_handle, templine, sizeof( templine ), false ) ) { class(core)::StripNewLine( templine ); new index, tempobject[ object ]; tempobject[ oModelID ] = strval( class(core)::strtok( templine, index, " " ) ); tempobject[ oPosX ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oPosY ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oPosZ ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oRotX ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oRotY ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oRotZ ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, " " ) ) ) / 10.0; tempobject[ oReadOnly ] = ReadOnly; class(objects)::AddObject( tempobject[oModelID], tempobject[oPosX], tempobject[oPosY], tempobject[oPosZ], tempobject[oRotX], tempobject[oRotY], tempobject[oRotZ], tempobject[oReadOnly] ); } fclose( file_handle ); } case FILE_TYPE_MEDITO: { new File: file_handle, templine[ 200 ]; file_handle = fopen( filename, io_read); while( fread( file_handle, templine, sizeof( templine ), false ) ) { class(core)::StripNewLine( templine ); // let's modify it a bit... if( strfind( templine, "CreateObject(", false, 0 ) != -1 ) { // there's a createobject line... new index, tempobject[object]; strdel(templine, 0, strfind( templine, "CreateObject(", false, 0 ) + strlen( "CreateObject(" ) ); while( strfind( templine, " ", true, 0 ) != -1 ) { // now we need to delete all spaces new position = strfind( templine, " ", true, 0 ); strdel( templine, position, position + 1 ); } tempobject[ oModelID ] = strval( class(core)::strtok( templine, index, "," ) ); tempobject[ oPosX ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oPosY ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oPosZ ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oRotX ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oRotY ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oRotZ ] = floatround( 10.0 * floatstr( class(core)::strtok( templine, index, "," ) ) ) / 10.0; tempobject[ oReadOnly ] = ReadOnly; class(objects)::AddObject( tempobject[oModelID], tempobject[oPosX], tempobject[oPosY], tempobject[oPosZ], tempobject[oRotX], tempobject[oRotY], tempobject[oRotZ], tempobject[oReadOnly] ); } } fclose( file_handle ); } } } #endif // ----------------------------------------------------------------------------- class(objects)::AddObject( modelid, Float: PosX, Float: PosY, Float: PosZ, Float: RotX, Float: RotY, Float: RotZ, bool: ReadOnly = false ) { // find an object ID of where no object is in cache for( new i = 0; i < OBJECT_TOTAL; i ++ ) { if( objects[ i ][ oModelID ] == 0 ) { objects[ i ][ oModelID ] = modelid; objects[ i ][ oPosX ] = PosX; objects[ i ][ oPosY ] = PosY; objects[ i ][ oPosZ ] = PosZ; objects[ i ][ oRotX ] = RotX; objects[ i ][ oRotY ] = RotY; objects[ i ][ oRotZ ] = RotZ; objects[ i ][ oReadOnly ] = ReadOnly; class(stream)::ProcessObjects(); return i; } } // all objects ARE used... Change OBJECT_TOTAL to something higher // and recompile return NO_OBJECT; } class(objects)::SetObjectPos( objectid, Float: diffPosX, Float: diffPosY, Float: diffPosZ ) { if( objects[ objectid ][ oModelID ] > 0 ) { objects[ objectid ][ oPosX ] += diffPosX; objects[ objectid ][ oPosY ] += diffPosY; objects[ objectid ][ oPosZ ] += diffPosZ; for( new playerid = 0; playerid < SLOTS; playerid ++ ) { for( new j = 0; j < OBJECT_RENDER_LIMIT + 1; j ++ ) { if( objectid == players[ playerid ][ pRenderedObjects ][ j ] ) { SetPlayerObjectPos( playerid, players[ playerid ][ pRenderedPlayerObject ][ j ], objects[ objectid ][ oPosX ], objects[ objectid ][ oPosY ], objects[ objectid ][ oPosZ ] ); } } } } } class(objects)::SetObjectRot( objectid, Float: diffRotX, Float: diffRotY, Float: diffRotZ ) { if( objects[ objectid ][ oModelID ] > 0 ) { objects[ objectid ][ oRotX ] += diffRotX; objects[ objectid ][ oRotY ] += diffRotY; objects[ objectid ][ oRotZ ] += diffRotZ; for( new playerid = 0; playerid < SLOTS; playerid ++ ) { for( new j = 0; j < OBJECT_RENDER_LIMIT + 1; j ++ ) { if( objectid == players[ playerid ][ pRenderedObjects ][ j ] ) { SetPlayerObjectRot( playerid, objectid, objects[ objectid ][ oRotX ], objects[ objectid ][ oRotY ], objects[ objectid ][ oRotZ ] ); } } } } } // ----------------------------------------------------------------------------- Float:class(stream)::GetDistance( Float: x1, Float: y1, Float: z1, Float: x2, Float: y2, Float: z2 ) { new Float:d; d += floatpower(x1-x2, 2.0); d += floatpower(y1-y2, 2.0); d += floatpower(z1-z2, 2.0); d = floatsqroot(d); return d; } public class(stream)::ProcessObjects() { for( new playerid = 0; playerid < SLOTS; playerid ++ ) { if( IsPlayerConnected( playerid ) ) { class(stream)::ProcessPlayerObjects( playerid ); } } } class(stream)::ProcessPlayerObjects( playerid ) { new nearestobjects[ OBJECT_RENDER_LIMIT ][ object ]; for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { nearestobjects[ i ][ oDistance ] = OBJECT_RENDER_DISTANCE; nearestobjects[ i ][ oID ] = -1; } GetPlayerPos( playerid, players[ playerid ][ pPosX ], players[ playerid ][ pPosY ], players[ playerid ][ pPosZ ] ); for( new i = 0; i < OBJECT_TOTAL; i ++ ) { if( i != players[ playerid ][pRenderedObjects ][ OBJECT_RENDER_LIMIT ] ) { if( objects[ i ][ oModelID ] > 0 ) { if( class(stream)::GetDistance( players[ playerid ][ pPosX ], players[ playerid ][ pPosY ], players[ playerid ][ pPosZ ], objects[ i ][ oPosX ], objects[ i ][ oPosY ], objects[ i ][ oPosZ ] ) < nearestobjects[ OBJECT_RENDER_LIMIT - 1][ oDistance ]) { nearestobjects[ OBJECT_RENDER_LIMIT - 1 ] = objects[ i ]; nearestobjects[ OBJECT_RENDER_LIMIT - 1 ][ oDistance ] = class(stream)::GetDistance( players[ playerid ][ pPosX ], players[ playerid ][ pPosY ], players[ playerid ][ pPosZ ], objects[ i ][ oPosX ], objects[ i ][ oPosY ], objects[ i ][ oPosZ ] ); nearestobjects[ OBJECT_RENDER_LIMIT - 1 ][ oID ] = i; for ( new j = OBJECT_RENDER_LIMIT - 2; j >= 0; j -- ) { if( nearestobjects[ j ][ oDistance ] > nearestobjects[ j + 1 ][ oDistance ] ) { new tempobject[ object ]; tempobject = nearestobjects[ j + 1 ]; nearestobjects[ j + 1 ] = nearestobjects[ j ]; nearestobjects[ j ] = tempobject; } } } } } } new bool: NoRemoveObjects[ OBJECT_RENDER_LIMIT ]; for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { // loop through all near objects if( nearestobjects[ i ][ oModelID ] > 0 && nearestobjects[ i ][ oID ] >= 0 ) { // this model can be rendered for( new j = 0; j < OBJECT_RENDER_LIMIT; j ++ ) { if( players[ playerid ][ pRenderedObjects ][ j ] != NO_OBJECT ) { if( players[ playerid ][ pRenderedObjects ][ j ] == nearestobjects[ i ][ oID ] ) { // don't render this another time nearestobjects[ i ][ oID ] = NO_OBJECT; nearestobjects[ i ][ oDistance ] = OBJECT_RENDER_DISTANCE; NoRemoveObjects[ j ] = true; break; } } } } } for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { if( NoRemoveObjects[ i ] == false ) { DestroyPlayerObject( playerid, players[ playerid ][ pRenderedPlayerObject ][ i ] ); players[ playerid ][ pRenderedObjects ][ i ] = NO_OBJECT; players[ playerid ][ pRenderedPlayerObject ][ i ] = NO_OBJECT; } } for( new i = 0; i < OBJECT_RENDER_LIMIT; i ++ ) { // loop through all near objects if( nearestobjects[ i ][ oModelID ] > 0 && nearestobjects[ i ][ oID ] >= 0 ) { // this model can be rendered for( new j = 0; j < OBJECT_RENDER_LIMIT; j ++ ) { if( players[ playerid ][ pRenderedObjects ][ j ] == NO_OBJECT ) { players[ playerid ][ pRenderedObjects ][ j ] = nearestobjects[ i ][ oID ]; players[ playerid ][ pRenderedPlayerObject ][ j ] = CreatePlayerObject( playerid, nearestobjects[ i ][ oModelID ], nearestobjects[ i ][ oPosX ], nearestobjects[ i ][ oPosY ], nearestobjects[ i ][ oPosZ ], nearestobjects[ i ][ oRotX ], nearestobjects[ i ][ oRotY ], nearestobjects[ i ][ oRotZ ] ); break; } } } } } // ----------------------------------------------------------------------------- public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) { // now again, we need to start KEYMODE by pressing CTRL + ALT + SPACE if(newkeys == KEY_SPRINT + KEY_FIRE + KEY_WALK && newkeys != oldkeys) { if( players[ playerid ][ pKeyUse ] == false ) { dcmd_mkey(playerid, "1"); } else { dcmd_mkey(playerid, "0"); } } } public KeyPress() { new Keys[3]; for( new playerid; playerid < SLOTS; playerid ++ ) { if( IsPlayerConnected( playerid ) ) { if( players[ playerid ][ pKeyUse ] == true ) { GetPlayerKeys( playerid, Keys[0], Keys[1], Keys[2]) ; if(Keys[2] != 0) // Left or right pressed, those change the mode { if( Keys[2]== KEY_RIGHT ) { TextDrawHideForPlayer( playerid, textdraws[ players[ playerid ][ pKeyMode ][ 0 ] ]); players[ playerid ][ pKeyMode ][0] ++; if( players[ playerid ][ pKeyMode ][ 0 ] > 2 ) { players[ playerid ][ pKeyMode ][ 0 ] = 0; } TextDrawShowForPlayer( playerid, textdraws[ players[ playerid ][ pKeyMode ][ 0 ] ]); } else { TextDrawHideForPlayer( playerid, textdraws[ players[ playerid ][ pKeyMode ][ 1 ] + 3]); players[ playerid ][ pKeyMode ][1] ++; if( players[ playerid ][ pKeyMode ][ 1 ] > 1 ) { players[ playerid ][ pKeyMode ][ 1 ] = 0; } TextDrawShowForPlayer( playerid, textdraws[ players[ playerid ][ pKeyMode ][ 1 ] + 3]); } } else if(Keys[1] != 0) { // Up/Down pressed new Float:speed = 2.0; if(Keys[0] > 0) { // Speed modifiers switch(Keys[0]) { case KEY_SPRINT: speed = 8.0; case KEY_ACTION: speed = 0.5; case KEY_JUMP: speed = 0.1; } } if(Keys[1] != KEY_UP) { // You can only press one key at once... speed *= -1.0; } switch( players[ playerid ][ pKeyMode ][ 1 ]) { case 0: { switch( players[ playerid][ pKeyMode ][ 0 ] ) { case 0: dcmd_ox( playerid, class(core)::float2str(speed) ); case 1: dcmd_oy( playerid, class(core)::float2str(speed) ); case 2: dcmd_oz( playerid, class(core)::float2str(speed) ); } } case 1: { switch( players[ playerid][ pKeyMode ][ 0 ] ) { case 0: dcmd_rx( playerid, class(core)::float2str(speed) ); case 1: dcmd_ry( playerid, class(core)::float2str(speed) ); case 2: dcmd_rz( playerid, class(core)::float2str(speed) ); } } } } } } } }