rendered paste body#include <a_samp> // 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 <model id> - 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 <object id> - 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) );
}
}
}
}
}
}
}
}