player model / skin problem

Discuss programming in the QuakeC language.
Post Reply
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

player model / skin problem

Post by Cobalt »

Thought this would be cake, but not !

I have a mod that is using the player.mdl file, but has extra skins and frames that are put over bot clients. (ctfbot)

Have set up a darkplaces ded server, and since files can be dl, I believe what I have to do was to rename this player model file and have it dl , just like I did with the female player model (player_f.mdl) which was as simple as renaming the file in the code and in the filename. But the player model seems to have more to it. No matter what I try, it still loads up with the regular player model. The model I set the bot clients to use is: player_b.mdl and have precached it, and set it in the bot spawn and respawn code, but still its either not switching to that model, or it is, and the skins are not setting correctly. Also tried: r_restart for the rendering, and still no good.

Tried increasing the value of (bot) self.skin in the mod, and it changed the shirt and pants colors for all the bots. I have a Qme model vewer, but cant see much wrong....I know there is a better model viewer out there, but I cant figure why the female player model was a snap, and the player model renamed wont work...its the same exact file -
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Post by leileilol »

You have to use modelindex for it.

oh, that is a hack!
i should not be here
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Post by Cobalt »

Ok, went through modelindex like crazy, still cant get this. For example here is some of the original code to set modelindexes etc:

Code: Select all

//TONY Part of: void() PutClientInServer =

//multi player model support
	if(self.sex == 0)
		self.sex = 1;
	if(temp1 & TEMP1_SUPPORT_PLAYER2)
	{
		setmodel (self, "progs/player2.mdl");
		modelindex_player2 = self.modelindex;
	}
	if(temp1 & TEMP1_SUPPORT_PLAYER3)
	{
		setmodel (self, "progs/player3.mdl");
		modelindex_player3 = self.modelindex;
	}
	if(temp1 & TEMP1_SUPPORT_PLAYER4)
	{
		setmodel (self, "progs/player4.mdl");
		modelindex_player4 = self.modelindex;
	}
	setmodel (self, "progs/player.mdl");
	modelindex_player = self.modelindex;
Lets say we flag to use player2 (female) model, its setting the model of the player to the player2 / female model and index, but at the end, no matter what, its setting the model to the original player model and index - yet, this code DOES work somehow.
There is a seperate impulse to change to the female player model, but it merely changes self.model and does not mess with modelindex. What is modelindex actually doing?
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

setmodel(modname) does:
self.model = modname;
self.modelindex = modelindexforname(modname);

'modelindexforname' is some made up name for some internal part of the setmodel function, based upon the order precache_model calls were made in.
there is no other hidden state.
the engine does not use the .model field for much, specifically, it checks only if it is empty or not. never anything else.

the function putclientinserver uses setmodel to do the modelindexforname lookup, but otherwise doesn't really care.

there is powerups/ring-of-invis code which leaves the model set to progs/player.mdl, and overrides only the modelindex as required. its a hack. a big ugly hack. but means that there's no scan through the precache lists for every single frame (not that there would need to be anyway if it were written less lazily).

look for where modelindex_player is used to figure out id's hack.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Post by Cobalt »

Ok, that helps a little. Found the original Zoid code for putclientinserver to look like this:

Code: Select all

// oh, this is a hack!
	setmodel (self, "progs/eyes.mdl");
	modelindex_eyes = self.modelindex;

	setmodel (self, "progs/player.mdl");
	modelindex_player = self.modelindex;

So you are saying the setmodel /self.model does not mean much, then I am guessing this is a fast way to call the eyes modelindex up by declaring: self.modelindex = modelindex_eyes; ? Because the next set of code is doing the same thing for the playermodel.

Another odd thing is that the original mod uses another player.mdl file that has 4 new skins for the player model that are for the bots to wear. The model name is the same, but its located in a pak folder in the -game directory , so when we run that mod, the QC skin code points to the skins for the bots in the right situations. So , when we load the game, we also have a player.mdl in the basic ID1 pak files. Is this additional player model just imposed in as a 'library' for lack of a better guessword, or are we exclusively now using the player,mdl in the -game directory?
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

setmodel () is important because at startup time it precaches the models as required. But alas during gameplay the engine will use .modelindex all the time. Check how the ring of invisibility code swaps only .modelindex and use the same trick in your mod.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Post by Cobalt »

I (thought) I understood the modelindex swap with the ring in the original code, but this ones still kicking my butt. I am manually spawning a bot via its impulse command, and I merely renamed the old player.mdl file to bot.mdl , precached it, floated modelindex_bot in the defs, and hard coded this to the bot spawn:

Code: Select all

setmodel (newbot, "progs/bot.mdl");
modelindex_bot = newbot.modelindex; 
newbot.modelindex = modelindex_bot;

So I am setting the model of the newbot to the correct file, telling the botmodelindes to look there for its index, then (I hope) I am
assigning the entity (newbot) that is being created the corresponding index for the bot file. However, its still not working. The file is downloaded before the server connects, and I have the debug code telling me when the bot spawns, what model its using, and its saying: bot.mdl , but the regular player model is still being shown when it spawns. I cannot find another area where its using the player_modelindex.......?

So, I looked at the code again, and the bot thinking is using an animation think that is calling things like: W_FireAxe (); and other model fram animation routines, that MAY be references to the player model. If so, will this switch the model back to the player model?
frag.machine wrote:setmodel () is important because at startup time it precaches the models as required. But alas during gameplay the engine will use .modelindex all the time. Check how the ring of invisibility code swaps only .modelindex and use the same trick in your mod.
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Post by ceriux »

this has been a good discussion, iv been reading and am insterested to read some more. please, someone post a new knowledgeable reply!

also, cobalt, your initial code was confusing.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

Spike wrote: there is powerups/ring-of-invis code which leaves the model set to progs/player.mdl, and overrides only the modelindex as required.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Post by Cobalt »

I guess I may as well line by line, remove code, and see what happens to determine whats going on....kind of a time consuming way of doing it, but cant seem to find an experienced person who understands the way I am confronting the problem.

I did disable the bots think and nextthink , and found that when it spawns, its got the correct model. Soon as I enable the think, it reverts to the player default model. There is a bot animation think routine that is calling what I think are default ID self.frames and player_run() type scenes. So something embedded in those routines is causing it to switch to the player model. Really strange, because the female bot model (player2 in the posted code) does not have any speciall references in the botanimation think and uses the same code it seems. That model was a simple case of
setting the model name in setmodel command, there was no code I could find so far that set it to a modelindex for that specific model.....I suppose the frame count and other details of the model match the original player model in stand, fight, etc.
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Post by ceriux »

im pretty sure your problem has to do with how your using modelindex i would suggest you take a look at the invis ring code and see how they do it. then adapt your code to it and how it's setting works. cause how ever id did it, it worked. If you think it has to do with the animations, go through all of the animation code and see if anything there is making a mention of setting a model. as far as i know that's the only thing that could alter your model. Be sure to check and functions within the animation code to see if any of those functions are setting a model. it's the only way to make sure. you could also bprint things when your model setting code is supposted to be working to see if it's calling the correct things at the right times.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Post by Cobalt »

Close!

The botthink was calling checkpowerups, which always called setplayermodelindex at the end. That routine checked for the female model, else defaulted always to the modelindex_player.
I had to include the new bot index reference, and that was it !

Glad the problem happened, cause it gives you a chance to know the code better...modeling and such was one aspect I never toyed with much. Thanks to all for the replies.
ceriux wrote:im pretty sure your problem has to do with how your using modelindex i would suggest you take a look at the invis ring code and see how they do it. then adapt your code to it and how it's setting works. cause how ever id did it, it worked. If you think it has to do with the animations, go through all of the animation code and see if anything there is making a mention of setting a model. as far as i know that's the only thing that could alter your model. Be sure to check and functions within the animation code to see if any of those functions are setting a model. it's the only way to make sure. you could also bprint things when your model setting code is supposted to be working to see if it's calling the correct things at the right times.
Post Reply