Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bots

Development::Bots Forum for bots.

Reply
 
Thread Tools Display Modes
  #1  
Old 02-08-2014, 04:24 PM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Question Expanded race options for bots?

Hi everyone,

I'm trying to make it so that I can use some additional races for bots on my server, and also so that any bot can use any standard class regardless of race.

I've gotten all the changes in place to allow the #bot create command to not fail when using one of the additional races (such as race 439 for example for cats), and to allow any class for any race. I've also set it up for proper race to race_string values, and to use standard human base stats for the non-standard races. All of that works, and I can spawn bots of any of the additional races that I've added.

The problem I'm running into is that the bots refuse to display the actual appearance of the non-standard race when they are spawned. Some of them are global races, but I've also edited my GlobalLoad.txt file on my client to make sure that the additional races are explicitly made global. Nevertheless, they always show up as a generic human as though the race was not global.

I did a #showstats on a couple of them and noticed that the texture and helmtexture values were set to 255. This makes sense for standard playable races, as that setting basically means "show appearance based on worn equipment". So I looked through the code and found that the code does, in fact, automatically set the texture and helmtexture values to 255 precisely so that bots will display their equipped items. I tried using #texture on the spawned bots, and viola, they display correct race and skin when texture and helmtexture are set to the same as their face entry value. So, for example, for a cat using race 439 with texture and helmtexture of 0 you get a puma, with value of 3 you get a black panther, etc.


Now, the basic code process when you use the #bot spawn command is this (skipping over much of the details, and stuff that doesn't relate to bot appearance when spawned):

1 - Checks against multiple reasons that would cause bot spawn to fail.
2 - Makes a call to the LoadBot function.
3 - The LoadBot function creates an NPCTypeStruct, fills it with values from the database, and creates a Bot object based on the NPCTypeStruct.
4 - If we have successfully loaded a Bot object with the LoadBot function, then call the Spawn function.
5 - The Spawn function gets some basic information like bot name, and sets up for an entity spawn, then sets the helmtexture and texture values to 255, saves the bot object, generates position and orientation for the bot, adds the bot to the entity list, loads the bot's pet (if it has one), and then sends a position packet to create the actual bot spawn at the generated position. At this point the bot exists in the zone and should be visible.
6 - The spawn command processing then makes the bot state that it is ready for battle, and the command is finished processing.

So to try and get the system to automatically use the correct texture and helmtexture values for the bots, I modified the code for the Spawn function so that after texture and helmtexture were defined as 255, it would then check for non-standard race, and if the bot is non-standard race, then reset texture and helmtexture to be equal to the face entry value (a value that is actually saved in the bots table, unlike texture and helmtexture, and can be changed as desired with the #bot face command). This should make it so that when the bot is spawned, it will have a texture and helmtexture appropriate to the race.

I then tried a bot spawn again, and the bot still looked like a generic human. I used #showstats again and found that the texture and helmtexture were correct. They were no longer set to 255, but were identical to the face entry value for the bot. So that doesn't work, but I have no idea why.

Now then, the #texture command actually sends an illusion packet to the targeted MOB to change their appearance. So I thought, why not try and send an illusion packet to the bot after the Spawn function has finished, and before we exit out of the #bot spawn command processing. So I added in code to send an illusion packet that would reset texture and helmtexture to be equal to the face entry value. I set up this code after the "I am ready for battle." message, and then checked everything out again. I found that now the spawned bot model would change size immediately after spawning, but that it would still be a generic human model.


I really do not understand why the #texture command works in-game to make the non-standard races appear correctly after they have been spawned, but that I cannot make the bots spawn with a correct appearance.

Anyone have any ideas or suggestions? I'd really appreciate some help. While I could make it so that players can simply use #texture on their bots, they would have to do this every time they zone, and that really isn't what I want.

Thanks,
Drake Phoenix
Reply With Quote
  #2  
Old 02-08-2014, 04:40 PM
Taurinus2
Sarnak
 
Join Date: Nov 2009
Posts: 45
Default

Skimmed over your post, so if you touched this base already please don't be put off.

Are you ensuring that the gender is correct (i.e. 2 for monster races)?
Reply With Quote
  #3  
Old 02-08-2014, 05:40 PM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

Hmmm, I actually have not tried that. Does the #texture command change gender values? If it does not, then I'm not sure why #texture would work if the gender value makes that much difference. I'll try it though, and see what happens

Thanks for the suggestion,
Drake Phoenix


[EDIT] I just looked at the code, and the #texture command *does* affect gender when it sends the illusion packet, and for monster races, it defaults the gender to 2, so this could actually be the issue and solve my problem. Coding it in now, and will test it in the next few minutes.
Reply With Quote
  #4  
Old 02-08-2014, 07:25 PM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

OK, I coded in a couple of changes...

First, I commented out the section in the Spawn function that sets texture and helmtexture to 255.

Second, I added code into the LoadBot function after the bot object is created. This new code checks for non-standard race, and if the race is non-standard it sets texture and helmtexture to equal face value, and sets gender to 2. If, however, it is a standard race, then it sets texture and helmtexture to 255 and leaves gender unchanged.

I compiled and tested with that setup. I found that non-standard race models now work correctly instead of displaying generic humans, so the issue was definitely because the bots were using a gender value other than 2. However, I also found that the face value for the bots affects their skin texture. So taking the puma/panther race as an example again, race 439, setting up so that it has face 3 the LoadBot function will set texture to 3, helmtexture to 3, and race to 2, but when the bot spawns it has the standard puma skin, not the black panther skin that it should have from texture 3 and helmtexture 3. Using #bot face command to set face to 0 then causes the skin to change and correctly display as a black panther, but also overrides the bot size value to the race default size value. This also results in having a face value for the bot database entry changed to a 0 as well, so future spawn would have the wrong skin texture either way.

This suggests that it may not be possible to have a bot that is of a non-standard race, and that also has a skin texture other than the default of 0. I thought I might be able to correct this by sending an illusion packet for the correct values (3 for texture and helmtexture, but 0 for face), but I found that this also modifies the bot entry in the database. I tried modifying the SendIllusionPacket function so that it stores the original face value from the MOB, modifies it per the parameters in the function call, and then sets it back to original again after the entity_list has been updated. Unfortunately, that resulted in still having the wrong skin texture in-game, as though the face value being reset back to original affects the MOB even after the entity_list entry has been updated.

I'm not sure I can make the necessary changes to make it work with the desired texture and helmtexture values for values other than 0. I'd definitely like some suggestions on how that might be accomplished. In the meantime I'm going to look through the bot command for #bot face and see if that gives me any ideas.

Drake Phoenix
Reply With Quote
  #5  
Old 02-08-2014, 10:36 PM
dagulus2
Hill Giant
 
Join Date: Feb 2013
Posts: 220
Default

Don't know if this will help, but have you looked at how the code works for setting Beastlord Warders, as I am pretty sure they are set upon spawn to textures other than 0 and in the database they all share one entry (set to race 0).
Reply With Quote
  #6  
Old 02-09-2014, 01:20 AM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

Quote:
Originally Posted by dagulus2 View Post
Don't know if this will help, but have you looked at how the code works for setting Beastlord Warders, as I am pretty sure they are set upon spawn to textures other than 0 and in the database they all share one entry (set to race 0).
I hadn't looked at the code for Beastlord warders, no. I knew that their race is chosen based on the race of their master, but I hadn't looked at how that works.

I just poked through it a bit, thanks to your suggestion, and it looks like it sets the the race and texture by changing the npctype before the pet object is created. But you're right, it does use textures other than 0 for some of them. So basically, it creates a basic NPCTypeStruct, the same as with bots, then it fills and modifies the values of the NPCTypeStruct, and then it creates the Pet object and eventually does an entity_list update to create a spawn based on the Pet object.

That suggests that if we were to change the NPCTypeStruct variable values *before* we create the Bot object, then it might work. The problem, though, is that in order for us to be able to save the texture as a variable, without completely changing the bot table structure to include it (and everything that goes with changing the structure), then we would have to either hard code the texture, or make the system choose a texture based on the database information. And then we would still need to change the face value to 0 for when we spawn the bot, but still have it save the original face value to the database when it makes updates through the Save() function.


Anyway, I played around with the code some more before I read dagulus2's reply, and tried the following...

I removed all of my previous code changes related to this issue, so bots were reverted back to "normal", and displaying generic human models for the non-standard races. I then edited the Spawn function only. I set it up to create two local variables, race and face, and to set the value of those variables by getting the data from the base Bot object (this would be the data retrieved from the database by the LoadBot function). I then checked for non-standard race. If race is non-standard, then set texture = face, helmtexture = face, gender = 2, and luclinface = 0. If the race is a standard race, then set texture = 0xFF, helmtexture = 0xFF, no other changes. All of this was added in *before* the Save() call, which means that when the Save() call is made, the database is updated with the new values (so we need to change face back again at a later point). Then, *after* the entity_list update, I added in a line to change luclinface = face to reset back to the original value that was in the database before we started, then I added a duplicate of the Save() call to update the database again.

Now in theory, it seems to me that should have worked. The basic process was to get the bot set up fairly normally, then set texture, helmtexture, gender, and face as necessary, and then, after the entity_list had been updated, reset the face value back to what it was and save it back to the database so that future spawns will not automatically revert to texture and helmtexture of 0. Following the code, it is the entity_list.AddBot function that actually creates and manifests the spawn in world, and the spawn is not a linked clone of the Bot object, but is a separate Spawn instance that was simply based on the Bot object. That being the case, any changes to the Bot object after the entity_list update should have no impact on the spawn itself.

That seemed to me like it *should* work to do what I want. Unfortunately, it does not seem to have actually worked. Instead, I still get a bot spawn that displays the default skin texture that would be expected with texture and helmtexture of 0.


I just don't get it, and it's really pissing me off. I'm thinking at this point that it might be easiest to change the #bot spawn command to accept a texture parameter. Then we can ignore the face value set in the database and always set it to 0 and leave it at 0 for non-standard races, but use the player-provided texture parameter to determine what texture and helmtexture to use. That way the texture doesn't have to be retrieved from the database or manipulated by the code in any way, we simply take the parameter and use it. I would have to include checks for invalid inputs, and ideally I would make it so that the texture and helmtexture parameters would be optional in the command input and only used if provided, but that shouldn't be too hard. The downside is that players would have to provide the texture and helmtexture parameters every time they spawn their bot if they want a non-standard race with a non-default texture, but since they can always write a social macro for the #bot spawn call, that shouldn't be an issue, and it would also allow them to change the texture of the bot if they get bored, without having to create a new bot. So I think I'll try that next.


If anyone has any other suggestions for something I could try, then I'd certainly like to hear it

Thanks,
Drake Phoenix
Reply With Quote
  #7  
Old 02-09-2014, 02:01 AM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

It's sounding like this is turning into a 'shroud' pre-cursor.

Just remember, that not all npc types have textures for armor types.

So, if you try changing their armor, you may run into these issues all over again..though, you can probably just check to see if the npc type is a
playable race before sending a wearchange packet.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #8  
Old 02-09-2014, 02:33 AM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

Quote:
Originally Posted by Uleat View Post
It's sounding like this is turning into a 'shroud' pre-cursor.

Just remember, that not all npc types have textures for armor types.

So, if you try changing their armor, you may run into these issues all over again..though, you can probably just check to see if the npc type is a
playable race before sending a wearchange packet.
I was thinking of making that check in the command process itself. Basically, if textureparam is provided, then check race to see if it is standard playable race or not. If it is standard playable race, then check textureparam value against acceptable values, and if it is not an acceptable value, then send error message to client and provide information about acceptable values. I know some acceptable values include 0, 1, 2, 3, 255, and some robe textures, like 16. I've seen a list somewhere before, but I can't remember where and can't seem to find it (guess I shouldn't have cleared my internet history this morning). If anyone knows where to find such a list, please let me know.

Then for non-standard races, I'm going to add in a "#bot help spawn" command that provides a lot of additional information about the command and how to use it, plus a warning that not all textures will work for all races.

Anyway, this is going to take some work and may or may not be finished before I go back to work on Monday, so I guess we'll see if I get it done before next weekend or not .

Later,
Drake Phoenix
Reply With Quote
  #9  
Old 02-09-2014, 05:30 AM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

Quote:
Originally Posted by DrakePhoenix View Post
I know some acceptable values include 0, 1, 2, 3, 255, and some robe textures, like 16. I've seen a list somewhere before, but I can't remember where and can't seem to find it (guess I shouldn't have cleared my internet history this morning). If anyone knows where to find such a list, please let me know.
OK, I found it. Actually I found 2. The one I had seen before and was thinking of was from the EQEmuGuideBook, Appendix D, page 64 (version downloaded from GeorgeS's web site). The other one is in the items schema wiki page description for the material column values. Both are likely to be incomplete, outdated, and/or inaccurate, but it's a start

DrakePhoenix
Reply With Quote
  #10  
Old 02-09-2014, 08:05 PM
DrakePhoenix
Fire Beetle
 
Join Date: Jan 2014
Posts: 22
Default

[TL;DR] -- I finally got it working. It is imperfect, but it is good enough for my current purposes at this time. I will post details on how others can make this work at a later date. I'll try to post those details by the end of the week, but make no promises.


Now the long version...

OK, so there is a problem with trying to check for acceptable valid texture parameter values for the different races. While there is a finite set of textures that are valid for playable races, it seems that not all races have the same set of usable textures. The Vah Shir, for example, do not seem to be able to use robes textures, the client simply has no way to display them properly, because the display resources were never developed (Vah Shir on live always wear leather or better armor, never robes). Additionally, each non-standard race (a.k.a. monster race, a.k.a. non-playable race) has it's own limited set of acceptable texture values, and which values are acceptable changes from one race to the next and generally ranges somewhere between 0 and 7 (inclusive), with most capping out at 3 or 4, and many having only 0.

So unless I hard-code limits for each specific race (which is far more work than I'm willing to do), then there is no way to properly guarantee that the valid texture value check would be accurate all the time. Also, it seems to me, based on limited experimentation, that if an invalid texture value is provided, then the system will default to the baseline texture for the given race. That is, for playable races, it will display as though they are naked of equipment, and for non-standard races it will display them as though they used texture 0.

Based on all of that, I don't think that a check for valid texture parameter value is a workable idea, nor particularly necessary. So what I've done instead is to simply try to provide clear information and warning values in the help messages. I've also added processing for a new bot command, "#bot help spawn", that provides still further information, and warnings about the texture display limitations and how it might behave.


Anyway, I went ahead and re-coded to allow the #bot spawn command to accept optional parameters of texture and helmtexture. I then changed the Spawn function to accept those values as parameters for itself... rewrote the function declaration in bot.h, rewrote the function definition in bot.cpp, and rewrote all calls to the function to provide the new parameters.

I set the #bot spawn command to determine values for the textureparam and helmtextureparam values used by the revised Spawn function. If the command provides a value, then those values are used, if not, they default to 0 for non-standard races, and to 255 for standard races. Then the Spawn function itself now checks those values. For non-standard races it sets texture = textureparam, helmtexture = textureparam (helmtextureparam is ignored), gender = 2, and face = 0. For standard races it sets texture = textureparam, and helmtexture = helmtextureparam, no other changes.


I tested with that setup and found it still doesn't work. So I added in a SendIllusionPacket call at the end of the Spawn function, after the entity_list.AddBot function call. I set the illusion packet to use all of the values previously set for the Bot object (no changes).

I've also added command processing for #bot texture, #bot helmtexture, and #bot size commands to modify those values on a bot that has already been spawned. I also had to modify the SendIllusionPacket function to force it to use the texture, helmtexture, and size values provided, rather than defaulting them to 255 and race npc_type default size. Not sure why that wasn't addressed before, but now on my server illusion packets, such as that resulting from the #texture command, will not incorrectly reset texture, helmtexture, and size.

I didn't expect the addition of the SendIllusionPacket call to actually work, since it doesn't seem that it actually changes any values (I wrote the call to use all of the values already present on the Bot object), but I thought I'd try it anyway. I was quite pleasantly surprised to find that it actually does work this way.


So at this point I have a setup that allows players to spawn bots using any race they choose (though I could also limit this to specific races if I wanted), and they can specify the skin texture when they use the #bot spawn command. The resulting bot should successfully display the correct race model (if it's global, or has been made global), and if the texture parameter is provided and is valid for that specific race, then it should also display the correct skin texture.


Since there might be someone else who may at some point be interested in doing this for their own setup, I'll post the code changes themselves, but before I do that, I need to clean them up a bit. I need a break from staring at code though, so I'm not going to do that right away. I'll try to have them posted by the end of the week though.


Later,
Drake Phoenix
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 04:50 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3