SRL Archive - Senior News and General

Getting NPC and Object ID's with SMART?


The Claw

2008-01-21 21:06:40

well its said to be possible, but i have no clue how, lol. does anyone have any idea on how to do this? it would be cool if there were functions like FindAllObjects(Object ID, Length, Width: Integer): ATPA/TPA. just wanna mess around with smart v2.

Bobarkinator

2008-01-21 21:44:26

I don't think Ben has put it in yet. But I'm not sure

Renax

2008-01-21 22:38:57

yes its possible, but no one has bothered to go through and find the necessary fields yet (?)

Bobarkinator

2008-01-22 07:46:54

Whoops, I forgot you could get your own field ints, I'll look into it but I don't think I'll get far.

Yakman

2008-01-22 08:09:31

i wouldnt say they havent bothered, i think people just dont know.

btw, in my opinion you shouldnt use IDs for NPCs, they have a field for their name, check their name instead of ID, unless there are NPCs which are different but have the same name (like in the freaky forester random)

i dont remember the exact names for functions which Scar/Smart has, ill just describe what you should do.
all field names are for client build #484
heres how to get the names of NPCs

get the npcArray which is 'th.g'
get the npcIndexArray which is 'a.h'
get the npcCount which is 'a.j'

with these, you can go through every npc the client has loaded at the time, like this

for f:=0 to npcCount - 1 do
variableOfTypeNPC = npcArray[npcIndexArray[f]];

notice how you have to get the value from the indexArray to get the value from the npcArray, it looks unnessacary but it has a purpose, ill tell you it later.

then you need to get the variable of type NPCDef (npc definition) which is 'xc'
when you have the NPCDef object, it has its name in a field of type StringWrap which is 'N'

once you have the StringWrap object, get its bytes with the field 'Y' which you can then turn into a string :)

check the string to see if it is the npc you want to attack, if it is
get the npc x,y and height which is 'fb', 'nc' and 'T' respectively. which you can then feed into that calculation function which tells you the screen position to click on!

note: you get x,y and height from the NPC object, you get the name from the NPCDef object.

^^ thats the gist of it, it should be enough for you to auto, but there might be some things you'll find puzzeling.:p

Markus

2008-01-22 08:47:16

I think TileToWorld is broken, I tried switching the pitch+yaw, but no result :(
I do get the tiles of the NPC, run this in Lumby bank, it'll writeln the tile of the banker:

program New;
var
npcstuff, npccount, i : integer;
const
//Global Static Hooks
SettingsArray = 'uc.ub'; //int[]
CurrentLevels = 'bg.t'; //int[]
MaxLevels = 'ua.R'; //int[]
Experiances = 'va.Z'; //int[]
BaseX = 'fb.m'; //int
BaseY = 'ea.h'; //int
MyPlayer = 'r.X'; //Player
CompassAngle = 'h.l'; //int (MinimapInt1)
MapOffsetAngle = 'ef.c'; //int (MinimapInt2)
BaseLayer = 'hc.pb'; //int (plane/terrainInt)
GroundSettings = 'jc.q'; //byte[][][] (groundByteArray)
GroundHeights = 'u.wc'; //int[][][] (groundIntArray)
CamX = 'dh.i'; //int
CamY = 'mb.A'; //int
CamZ = 'nd.y'; //int
CamPitch = 'pd.c'; //int (CamCurveX)
CamYaw = 'hc.hb'; //int (CamCurveY)

//Character Hooks
CurrentX = 'fb'; //int
CurrentY = 'nc'; //int
CharAnim = 'bc'; //int
{Not updated}CharMotion = 'T'; //int
CharName = 'rc'; //StringWrap

//StringWrap Hooks
StringBytes = 'lf'; //byte[]
procedure TileToWorld(tileX, tileY, height: integer; var screenX, screenY: integer);
var
cx, cy, cz, dx, dy, dz, locX, locY, layer: Integer;
pitch, yaw, sinYaw, cosYaw, sinPitch, cosPitch, rotation: extended;
begin
locX:= tileX - SmartGetFieldInt(0,BaseX);
locY:= tileY - SmartGetFieldInt(0,BaseY);
if (locX < 0) or (locY < 0) or (locX > 103) or (locY > 103) then
Exit;
layer:= SmartGetFieldInt(0,BaseLayer);
if (layer < 3) and ((2 and SmartGetFieldArray3DByte(0,GroundSettings,1,locX,locY)) = 2) then
Inc(layer);
cz:= SmartGetFieldArray3DInt(0,GroundHeights,layer,locX,locY) +
SmartGetFieldArray3DInt(0,GroundHeights,layer,locX+1,locY) +
SmartGetFieldArray3DInt(0,GroundHeights,layer,locX,locY+1) +
SmartGetFieldArray3DInt(0,GroundHeights,layer,locX+1,locY+1);
cx:= locX * 128 + 64 - SmartGetFieldInt(0,CamX);
cy:= locY * 128 + 64 - SmartGetFieldInt(0,CamY);
cz:= (cz / 4) - height - SmartGetFieldInt(0,CamZ);
pitch:= SmartGetFieldInt(0,CamPitch) * Pi / 1024;
yaw:= SmartGetFieldInt(0,CamYaw) * Pi / 1024;
sinYaw:= sin(yaw);
cosYaw:= cos(yaw);
sinPitch:= sin(pitch);
cosPitch:= cos(pitch);
rotation:= cosYaw*cy-sinYaw*cx;
dx:= Round(sinYaw*cy+cosYaw*cx);
dy:= Round(sinPitch*cz+cosPitch*rotation);
dz:= Round(cosPitch*cz-sinPitch*rotation);
screenX:= (dx * 512) / dy + 256;
screenY:= (dz * 512) / dy + 167;
end;
procedure GetMyPos(var x, y: Integer);
var
me: Integer;
begin
me:= SmartGetFieldObject(0,MyPlayer);
x:= SmartGetFieldInt(0,BaseX) + SmartGetFieldInt(me,CurrentX) shr 7;
y:= SmartGetFieldInt(0,BaseY) + SmartGetFieldInt(me,CurrentY) shr 7;
SmartFreeObject(me);
end;
var x, y : integer;
begin
SmartSetup('me10', false, true);
GetMyPos(x, y);
writeln(inttostr(x));
writeln(inttostr(y));
npccount := SmartGetFieldInt(0, 'a.j');
writeln('There are/is '+inttostr(npccount)+' NPC(''s)');
for i := 0 to npccount-1 do
writeln(inttostr(SmartGetFieldArrayInt(0, 'a.h', i)));
npcstuff := SmartGetFieldArrayObject(0, 'th.g', 11055);
writeln(inttostr(npcstuff));
Writeln(IntToStr(SmartGetFieldInt(0,BaseX)+SmartGetFieldInt(npcstuff, 'fb') shr 7));
Writeln(IntToStr(SmartGetFieldInt(0,BaseY)+SmartGetFieldInt(npcstuff, 'nc') shr 7));
TileToWorld(SmartGetFieldInt(0,BaseX)+SmartGetFieldInt(npcstuff, 'fb') shr 7,SmartGetFieldInt(0,BaseY)+SmartGetFieldInt(npcstuff, 'nc') shr 7, 0, x, y);
//smartMoveMouse(x, y);
SmartFreeObject(npcstuff);
end.
Returns:
Successfully compiled
3208
3220
There are/is 1 NPC('s)
11055
217341412
3207 //npc X
3222 //npc Y
Successfully executed

The Claw

2008-01-22 19:57:24

sweet as, hopefully the tiletoworld gets fixed..so how would we do objects, like rocks or trees? something similar im guessing, just with different fields? im no good at this java stuff lol