PDA

View Full Version : Help/Suggestions - Obtaining my character's current modelID



rkroxpunk
05-11-2016, 10:45 AM
Hi all,

Currently working on a Draynor willow tree chopper and banker just as an easy project to fill in time. I'm looking for people's thoughts on the best way to figure out if my current player is chopping or not, the obvious choice is using the player's model ID and this is where I'm having issues.

The problem: My player's model ID is obtained fine, and this is checked roughly every 1000ms when I've started to chop a tree to make sure it doesn't match the model ID of my player when it's idle. However if I let my script run for a while (at most two hours) this will eventually be the thing that breaks my script, for some reason it will error out:

The code:
function getPlayerModel():uint32;
var
pModel:glModelArray;

begin

playerBox := intToBox(screenCentre.X-113, screenCentre.Y-100, screenCentre.X-109, screenCentre.Y-80); //My TBox co-ordinates
pModel := ogl.getModels(playerBox); //playerBox is just a TBox around my players feet where the model ID of my player is located
result := pModel[high(pModel)].id; //The line causing the below error (line 214)
end;

The error:

Error: Access violation at line 214
Execution failed.
The following bitmaps were not freed: [0]

The cause: I can only assume that my player's model ID can't be found in the TBox I've supplied for some reason. This is strange because like I said, the script can work for a few hours before the error occurs. I've made the TBox the exact length I believe it needs to be, if it's any bigger it starts to retrieve models of other players/objects.
My other thought was maybe sometimes my script searches for my player's model ID just at the second the ID changes (from idle to animated) and perhaps at the second it checks/the ID changes there isn't a model to return and causes it to crash, is this possible?

The solution: This is where I need suggestions, have I done this the most efficient way? Is there a better way to be looking for my players model, or is this the best way to figure out if my player is chopping a tree in general?

I have two thoughts at the moment, 1) I saw Obscurity's (I think) post/function which is used to shift a model to a different position, I thought maybe if I shift the model ID of my player from being on the ground/character's feet to in the middle of my character's body I might be able to increase the TBox size a bit (if the TBox size is the issue). Although I'm not sure how to implement this...

Other more obvious thought was to stop the script just erroring out when this occurs and instead implement a failsafe. My issue is it happens so infrequently and I don't really know what the cause of it is so I don't really know where to begin with debugging and then implementing. Does the above just look like the array might be empty? And if so I would assume a simple check of the length of the array before assigning the value of it to my function could fix the issue?

Sorry for the long post but I hope I can get some good feedback/suggestions.

Thanks!

fady
05-11-2016, 11:33 AM
Ross; did this in most of his scripts! I'm sure you can take a look at how he did it. Another way I would assume this is doable, you only need to get your ID once at the beginning of the script. Then after that you only need to check if that ID is visible or not, not try to match your current ID with the old ID, I feel that would be an easier solution.

Also, make sure you have a length check before using pModel in the result, that should prevent the access violation but it shouldn't fix the empty model!

Edit:
DISCLAIMER: I have limited knowledge/experience with oglib, so don't take my word as gospel lol. I see no reason why it shouldn't work tho.

Ross
05-11-2016, 12:22 PM
...


...
Thanks for the mention :)

I actually have an AIO Woodcutter in the Jr. Mems section if you want to check out how I did it for reference, but to quickly solve your issue I would do it like this:


Get idle player ID on script start -> store as global int32
At certain intervals check entire screen to see if that ID exists anywhere (I have it reset this timer every time the inventory changes count)
if ogl.getModels(playerID).isEmpty() then
chopTree;


That's the easiest way to do it, and checking the entire screen for one ID probably takes less than 5ms :)

rkroxpunk
05-11-2016, 01:23 PM
......

Thanks! I explained it poorly but I collect the idle ID at the start of the script, the only check I'm doing throughout the rest of the script is to find what the current ID is and if it matches the ID collected at the start of the script I know it's idle.
Excellent, do you think that access violation is the result of an empty model?


Thanks for the mention :)

I actually have an AIO Woodcutter in the Jr. Mems section if you want to check out how I did it for reference, but to quickly solve your issue I would do it like this:


Get idle player ID on script start -> store as global int32
At certain intervals check entire screen to see if that ID exists anywhere (I have it reset this timer every time the inventory changes count)
if ogl.getModels(playerID).isEmpty() then
chopTree;


That's the easiest way to do it, and checking the entire screen for one ID probably takes less than 5ms :)

Thanks Ross, I have already downloaded your script and forgot to look at it :/ I'll get onto that although I think I'll try and implement your suggestions before I do that!
Your method makes a lot more sense, I made the mistake of thinking other players could share the same model ID as my idle player and therefore searching the entire screen would yield false results if someone else was idling, I'm guessing I was incorrect and that model ID's are unique to the character?

Clarity
05-11-2016, 01:39 PM
FYI there are two player IDs for any given character appearance, the second can be obtained by eating a piece of food which changes it (once only), but it also changes randomly in other circumstances that may or may not occur during your script run.

I don't think it's relevant to your current access violation issue but it's something to keep in mind.

https://i.gyazo.com/54ac5c3c158bb8fadf20179b9ecc631f.gif

Ross
05-12-2016, 03:29 AM
Thanks! I explained it poorly but I collect the idle ID at the start of the script, the only check I'm doing throughout the rest of the script is to find what the current ID is and if it matches the ID collected at the start of the script I know it's idle.
Excellent, do you think that access violation is the result of an empty model?



Thanks Ross, I have already downloaded your script and forgot to look at it :/ I'll get onto that although I think I'll try and implement your suggestions before I do that!
Your method makes a lot more sense, I made the mistake of thinking other players could share the same model ID as my idle player and therefore searching the entire screen would yield false results if someone else was idling, I'm guessing I was incorrect and that model ID's are unique to the character?

Technically two players can have the same model ID, but need to have the exact same appearance in every way including armour and weapons so it is very highly unlikely just by randomizing your character at account creation.

rkroxpunk
05-12-2016, 07:24 AM
Technically two players can have the same model ID, but need to have the exact same appearance in every way including armour and weapons so it is very highly unlikely just by randomizing your character at account creation.

Interesting! So including haircut, character creation clothes etc?
Also, how did you figure this out? Haha

Ross
05-12-2016, 02:55 PM
Interesting! So including haircut, character creation clothes etc?
Also, how did you figure this out? Haha

Others can explain this better than I can but essentially those things contribute different polygons towards the model which is how the ID comes about. Which is why all of one kind of monster (usually ones without a recent graphical update) can have the same ID but something like fire giants can have many.

Clarity
05-12-2016, 04:30 PM
Interesting! So including haircut, character creation clothes etc?
Also, how did you figure this out? Haha

Another element to consider is a model's TID, which is basically the count of triangles present in the model. Notice how players and recently added models have higher triangle counts because they are naturally more intricate objects.

An effective player detector in many situations is to simply check for any models with a TID greater than 1000 (although as the game gets more graphically complex this will change).

In Oria/ogLib-2, models will be easier to work with and you won't need to do a lot of deductive/inductive reasoning in your code.


{ORIA MODELS}
type tModel=record
bounds: tBox;
height: integer;
id: integer;
index: integer;
position: tPoint;
scale: integer;
vertices: tPointArray;
width: integer;
end;