04.01.2015, 19:47
I just made an interesting billboard, from photoshop to sa-mp. I like the plugin but I'll wait to actually implement it...
No, its not maybe you forget to upload it. I need it because i think that i found a way of calling CreateDynamicObject without using the GDK (using amx_Callback)
|
Q: How to use it? A: 1. Download this archive with .... |
Another thing dude you should add some functions to get the objectids then you could easily add rotation to your include.
|
double up[3] = {sin(ra[1])*cos(ra[2]) + sin(ra[0])*sin(ra[2])*cos(ra[1]), sin(ra[2])*sin(ra[1]) - sin(ra[0])*cos(ra[1])*cos(ra[2]), -cos(ra[0])*cos(ra[1])}; double right[3] = {-sin(ra[2])*cos(ra[0]), cos(ra[0])*cos(ra[2]), -sin(ra[0])}; double forward[3] = {cos(ra[1])*cos(ra[2]) - sin(ra[0])*sin(ra[2])*sin(ra[1]), sin(ra[2])*cos(ra[1]) + sin(ra[0])*sin(ra[1])*cos(ra[2]), cos(ra[0])*sin(ra[1])};
// Credits: Stylock
stock AttachPoint(Float:offx, Float:offy, Float:offz, Float:offrx, Float:offry, Float:offrz, Float:px, Float:py, Float:pz, Float:prx, Float:pry, Float:prz, &Float:RetX, &Float:RetY, &Float:RetZ, &Float:RetRX, &Float:RetRY, &Float:RetRZ, sync_rotation = 1)
{
new
Float:g_sin[3],
Float:g_cos[3],
Float:off_x,
Float:off_y,
Float:off_z;
EDIT_FloatEulerFix(prx, pry, prz);
off_x = offx - px; // static offset
off_y = offy - py; // static offset
off_z = offz - pz; // static offset
// Calculate the new position
EDIT_FloatConvertValue(prx, pry, prz, g_sin, g_cos);
RetX = px + off_x * g_cos[1] * g_cos[2] - off_x * g_sin[0] * g_sin[1] * g_sin[2] - off_y * g_cos[0] * g_sin[2] + off_z * g_sin[1] * g_cos[2] + off_z * g_sin[0] * g_cos[1] * g_sin[2];
RetY = py + off_x * g_cos[1] * g_sin[2] + off_x * g_sin[0] * g_sin[1] * g_cos[2] + off_y * g_cos[0] * g_cos[2] + off_z * g_sin[1] * g_sin[2] - off_z * g_sin[0] * g_cos[1] * g_cos[2];
RetZ = pz - off_x * g_cos[0] * g_sin[1] + off_y * g_sin[0] + off_z * g_cos[0] * g_cos[1];
if (sync_rotation)
{
// Calculate the new rotation
EDIT_FloatConvertValue(asin(g_cos[0] * g_cos[1]), atan2(g_sin[0], g_cos[0] * g_sin[1]) + offrz, atan2(g_cos[1] * g_cos[2] * g_sin[0] - g_sin[1] * g_sin[2], g_cos[2] * g_sin[1] - g_cos[1] * g_sin[0] * -g_sin[2]), g_sin, g_cos);
EDIT_FloatConvertValue(asin(g_cos[0] * g_sin[1]), atan2(g_cos[0] * g_cos[1], g_sin[0]), atan2(g_cos[2] * g_sin[0] * g_sin[1] - g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
EDIT_FloatConvertValue(atan2(g_sin[0], g_cos[0] * g_cos[1]) + offrx, asin(g_cos[0] * g_sin[1]), atan2(g_cos[2] * g_sin[0] * g_sin[1] + g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] - g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
RetRX = asin(g_cos[1] * g_sin[0]);
RetRY = atan2(g_sin[1], g_cos[0] * g_cos[1]) + offry;
RetRZ = atan2(g_cos[0] * g_sin[2] - g_cos[2] * g_sin[0] * g_sin[1], g_cos[0] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]);
}
}
stock EDIT_FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, Float:sin[3], Float:cos[3])
{
sin[0] = floatsin(rot_x, degrees);
sin[1] = floatsin(rot_y, degrees);
sin[2] = floatsin(rot_z, degrees);
cos[0] = floatcos(rot_x, degrees);
cos[1] = floatcos(rot_y, degrees);
cos[2] = floatcos(rot_z, degrees);
return 1;
}
/*
* Fixes a bug that causes objects to not rotate
* correctly when rotating on the Z axis only.
*/
stock EDIT_FloatEulerFix(&Float:rot_x, &Float:rot_y, &Float:rot_z)
{
EDIT_FloatGetRemainder(rot_x, rot_y, rot_z);
if((!floatcmp(rot_x, 0.0) || !floatcmp(rot_x, 360.0))
&& (!floatcmp(rot_y, 0.0) || !floatcmp(rot_y, 360.0)))
{
rot_y = 0.00000002;
}
return 1;
}
stock EDIT_FloatGetRemainder(&Float:rot_x, &Float:rot_y, &Float:rot_z)
{
EDIT_FloatRemainder(rot_x, 360.0);
EDIT_FloatRemainder(rot_y, 360.0);
EDIT_FloatRemainder(rot_z, 360.0);
return 1;
}
stock EDIT_FloatRemainder(&Float:remainder, Float:value)
{
if(remainder >= value)
{
while(remainder >= value)
{
remainder = remainder - value;
}
}
else if(remainder < 0.0)
{
while(remainder < 0.0)
{
remainder = remainder + value;
}
}
return 1;
}
struct a_vectors
{
std::map<int, int> arts_array;
};
std::vector<a_vectors*> vectors;
cell AMX_NATIVE_CALL DestroyArt(AMX* amx, cell* params)
{
for (auto& i : vectors.at(params[1])->arts_array)
{
if (i.second != -1)
{
g_Invoke->callNative(&PAWN::DestroyObject, i.second);
}
}
vectors.erase((vectors.begin() + params[1])-1);
return 1;
}
//CreateArt(path, sX, sY, sZ, aX, aY, aZ, dist, type)
cell AMX_NATIVE_CALL CreateArt(AMX* amx, cell* params)
{
int cre_f = 0;
PNG_Struct picture;
char *text = new char;
amx_StrParam(amx, params[1],text);
int open_result = picture.Init(text);
free(text);
if(open_result == 1)
{
logprintf("FAILED to create art: can't load PNG picture");
return -1;
}
if(open_result == -1)
{
logprintf("FAILED to create art: PNG isn't 24-bit type");
return -1;
}
float pos[3] = {amx_ctof(params[2]), amx_ctof(params[3]), amx_ctof(params[4])};
float ang[3] = {amx_ctof(params[5]), amx_ctof(params[6]), amx_ctof(params[7])};
double ra[3] = {atr(ang[0]), atr(ang[1]), atr(ang[2])};
float dist = amx_ctof(params[8]);
//just few simple formulas ^_^
double up[3] = {sin(ra[1])*cos(ra[2]) + sin(ra[0])*sin(ra[2])*cos(ra[1]), sin(ra[2])*sin(ra[1]) - sin(ra[0])*cos(ra[1])*cos(ra[2]), -cos(ra[0])*cos(ra[1])};
double right[3] = {-sin(ra[2])*cos(ra[0]), cos(ra[0])*cos(ra[2]), -sin(ra[0])};
float ws, hs; cell oid; cell type = params[9];
switch (type)
{
case 0: oid = 19464; ws = 5.875f; hs = 5.075f; break;
case 2: oid = 2814; ws = 0.51f; hs = 0.51f; break;
default: oid = 19372; ws = 3.18f; hs = 3.48f; break;
}
int blockx = (int)floor(float(picture.width()) / 15 + 0.999);
int blocky = (int)floor(float(picture.height()) / 15 + 0.999);
if(blockx*blocky > 1000)
{
logprintf("FAILED to create art: too large image");
return 10;
}
unsigned int *temp_block = (unsigned int*)malloc(15*15*sizeof(unsigned int));
a_vectors* vectores = new a_vectors();
for (int i = 0; i < blockx; i++)
{
for(int j = 0; j < blocky; j++)
{
memset(temp_block, 0, sizeof(unsigned int)*15*15);
CutBlock15(picture, temp_block, i, j);
int index= i+j*blockx;
float start[3] = { (i - blockx/2.0)*ws*right[0] + (j - blocky/2.0)*(hs)*up[0] + pos[0],
(i - blockx/2.0)*ws*right[1] + (j - blocky/2.0)*(hs)*up[1] + pos[1],
(i - blockx/2.0)*ws*right[2] + (j - blocky/2.0)*(hs)*up[2] + pos[2]};
int cur_w = CLIP(picture.width() - i*15,0,15);
int cur_h = CLIP(picture.height() - j*15,0,15);
char colors[4096] = {0};
BuildString(colors, temp_block, cur_w, cur_h);
cell cobid = 0;
//let's create an object! [format: oid, sX, sY, sZ, aX, aY, aZ, dist]
float add_rot = 0;
if (oid == 2814)
{
add_rot = -94.65;
cobid = g_Invoke->callNative(&PAWN::CreateObject, oid, start[0], start[1], start[2], ang[0], ang[1] + add_rot, 180 + ang[2], dist);
vectores->arts_array.emplace(1, cobid);
g_Invoke->callNative(&PAWN::SetObjectMaterialText, cobid, colors, 0, 140, "Webdings", 35, 0, 0, 0, 0);
g_Invoke->callNative(&PAWN::SetObjectMaterial, cobid, 1, -1, "none", "none", 1);
}
}
}
free(temp_block);
vectors.push_back(vectores);
delete vectores;
return vectors.size()-1;
}
Do not want to open an image file on Linux (CentOS). I tried different ways ("/home/myprofile/img.png", "img.png", etc), all to no avail - FAILED to create art: can't load PNG picture
|
Until memory leak on client side is fixed, I recommend to not use this.
|
Hello! Some time ago I made the tool for using pictures in your gamemodes. Now I present the plugin with that feature!
It wasn't easy to use the tool, but now is't VERY easy. Just use CreateArt / DestroyArt functions like CreateObject / DestroyObject ones: I changed the pattern, now second parameter is the art type: CreateArt(path_to_png_image, art_type, other_default_parameters...) example: Код:
#include <s-art> ....... new art = CreateArt("D:\\my_image.png", 2, -704.1531, 1849.0200, 18, 45, 45, 45, 100); //picture should be in 24-bit PNG type ....... DestroyArt(art); I'm total noob in plugin writing, so you can modify, improve or do whatever you want with it. SOURCE CODE (include and DLL files are in /build/ folder) demo: yeah, that's what this thing was made for. To place the photo of Redirect_Left (owner and creator of sumo server) to the map. currently plugin supports 4 size types: type 2, size = X type 3, size ~= 3*X type 1, size ~= 6*X type 0, size ~= 12*X (it's not easy to find not-shadowed almost square single-textured objexts!!) (if you do REALLY need another sizes, ask me, there're few less convenient objects unused) size types: The result isn't perfect, the objects I've used aren't square, so resize your original pictures to achieve better results. It's still VERY recommended to use pictures with dimensions multiple of 15 |