Quakeworld skins confusion

Discuss programming in the QuakeC language.
Post Reply
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Quakeworld skins confusion

Post by OneManClan »

Hi all,

Quakeworld seems to be loading skins which don't exist (?) in my folders. I'm trying to understand how qw + skins work. IIUC, there are two 'multiple skin' 'systems':

1. Include the multiple skins as part of the definition of the foo.mdl, and reference them via the float: foo.skin; eg: foo.skin = 1;
2. Have a separate foo.pcx file and refer to it by its name/string; eg: 'setinfo skin foo'.

Skin changes in CustomTF seem to be done via stuffcmds, but where does the server tell the client where (eg) 'tf_scout' skin is? I typed 'setinfo' at the client console and the skin was indeed listed as 'tf_scout'.

In skins.qc we have (eg) the line:

Code: Select all

#define TEAM1_SCOUT_SKIN "tf_scout\n"
But I cant see such a skin in either
/qw/skins
or
/fortress/skins

To test, I commented out all the defines in 'skins.qc', it compiled and... it made no difference.. wtf? I commented out 'skins.qc' in preprogs.qc, and the compiler (fteqcc) said that tf_scout, tf_sniper etc were not defined!(?) How could it have compiled earlier when I had commented out everything in skins.qc?

The only .pcx in my (perfectly working) TF client is: '/zelTF/fortress/skins/base.pcx'. The folder '/zelTF/qw' is ... empty.

Q:Where are the TF skins coming from?

please explain,

OneManClan
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Quakeworld skins confusion

Post by OneManClan »

A: the skins are in pak1.pak
[credit: xavior]
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Quakeworld skins confusion

Post by Spike »

with fte,
flocate skins/tf_scout.pcx
that'll say which path/pak they're in, if it can be found.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Quakeworld skins confusion

Post by OneManClan »

[Hijacking my own thread, but it still comes under the same the same subject so...]

CORPSE CONFUSION
Hey people.

I'm working on a new mod/feature which involves multiple player skins, including (eg) a different skin for each level of blood. It's working well, except for the situation when a player dies. Their corpse (which remains visible on the ground for a while after they have respawned) changes skin, and mimicks the skin of the (now respawned) player. This has always IIUC been a problem with Q1TF and spies, where if a spy respawns and disguises as (eg) 'soldier', his corpse (which stays on the ground for at least 15 (?) seconds), ALSO switches to 'soldier' skin - so the two are connected. What I'd like is to be able to use a new skin, specifically for player corpses, but am having trouble understanding the code.

Can someone explain to me how to change a corpses skin, as distinct from a (respawned) player's skin?

IIUC PutClientInServer() doesnt actually 'spawn' anything, just resets the players 'settings', and PlayerDie() also doesn't spawn anything, so how can there be a player AND his corpse - somewhere a corpse entity was made - which is still responding to skin changes in the living 'version'?


thanks,

OneManClan
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Quakeworld skins confusion

Post by Spike »

There are players, with their colours and their skins.
And there are entities.


Each entity has a .colormap field. This .colormap field refers to a player slot.
When the player dies, the model and colormap of the player is copied over to a new entity (part of the bodyqueue).

When drawing the entity, the client looks at the colormap field. if its set, it recolours the entity according to the colour of the player indicated, and if its player.mdl then it also gets the player's skin too.
(note: vanilla glqw does not support colouring of models other than player.mdl).
The gamecode has no real control over the skin or colours used. Any checks (which are pretty common) are basically hacks for the simple reason that it cannot control skins on entities individually, it can traditionally only ask the client to update its settings.


There are some extensions that you can use, but you're not going to like them...
DP_ENT_CUSTOMCOLORMAP:
self.colourmap = 1024 + (shirt*16) + (pants);
That line will set explicit colours on an entity. This means that colours can persist on the corpse without changing if eg the spy changes his team colours.
This extension is rather NQ centric in that it ignores player skins - this is a good thing, as it means the skin won't animate on corpses, but you will loose your class-specific skins if you don't have a copy of that skin within the player.mdl and don't do .skin stuff too to match it, etc.
FTE has supported this for a brief while, but only on non-player entities (debug_pext_replacementdeltas should enable it on player entities also). No other QuakeWorld client supports this (including DP as a QW client).


Side note: with QuakeWorld protocols, players have a hardcoded .colormap field equal to their own player slot.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Quakeworld skins confusion

Post by OneManClan »

Spike wrote: Each entity has a .colormap field. This .colormap field refers to a player slot.
When the player dies, the model and colormap of the player is copied over to a new entity (part of the bodyqueue).
Ok, I'm a little confused at this point as to what a "colormap" actually is.

I thought 'colormap' referred to: "the colour to change lines 2 and 7 of the quake palette to". So when a player joins the Blue team, their 'colormap' is Blue (or something), then if a Blue engineer builds a SentryGun, we display the sentry mdl, and then go:

sentrygun.owner = <the blue engineer>
sentrygun.colormap = sentrygun.owners.colormap;

.. and this will switch ('map') all the colours used (in the sentry skin) from lines 2 and 7 of the Quake palette, to their Blue equivalents.

But Frag Machine recently saidhowever said that 'colormap' refers to the whole skin/texture: "In graphic programming terms, the colormap is the array of pixels that describe the colors. Modern game engines don't use just color pixels in skins: usually you can have additional images to represent bumpmapping, luminosity, transparency and other effects"
Spike wrote: When drawing the entity, the client looks at the colormap field. if its set, it recolours the entity according to the colour of the player indicated, and if its player.mdl then it also gets the player's skin too.
(note: vanilla glqw does not support colouring of models other than player.mdl).
The gamecode has no real control over the skin or colours used. Any checks (which are pretty common) are basically hacks for the simple reason that it cannot control skins on entities individually, it can traditionally only ask the client to update its settings.
Spike wrote:
Side note: with QuakeWorld protocols, players have a hardcoded .colormap field equal to their own player slot.
When a player respawns, is there an 'update' on what skins the other players are wearing, or does that information 'persist' beyond the respawning process? I'm dealing w a bug at the moment in my 'DoomFace' mod, [EDIT: The bug has since been fixed, BIG thanks to Spike and Taniwha for their help! The prob was related to the 'SkinBlind' mod with a section I had written (and forgotten about!) which restored all skins in case a player died whilst in a hallucinogenic state. It of course restored skins to the default skins. I also overlooked it because it was in PlayerDeathThink() which for some reason I missed whilst tracing the death related functions] where respawning clients see other players with default TF skins, rather than the new versions I made.

Here's a step by step description:
Game begins
Player1 has skinA
Player2 has skinB
They can see each other wearing the correct skins.
Player1 dies.
As he's lying there dead, Player1 can still see Player2 still wearing skinB.
BUT (!!) after Player1 respawns, he now sees Player2 (and all other players) wearing 'regular' TF skins... why?

Note: to an observer ( ie a Player3), nothing has changed (ie Player1 has skinA and Player2 has skinB), so somehow, somewhere, during his 'respawn procedure' Player1 was told to 'change the skins he is looking at'. But where... how? I've looked at respawn related functions like clientconnect() and bodyque stuff but cannot see anywhere that tells a respawning client to change/check *other* players skins. Any ideas?
Last edited by OneManClan on Thu Mar 14, 2013 12:02 pm, edited 3 times in total.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Quakeworld skins confusion

Post by Spike »

quickly written qc-esque pseudo code, running on the client.

Code: Select all

for (i = 1; i < numentities; i++)
{
  local float topcolor, bottomcolor;
  local string skintouse;
  self = entity_for_number(i);
  skintouse = skinfrommodel(self.modelindex, self.skin);
  if ((entity.colormap & 1024) && checkextension("DP_ENT_CUSTOMCOLORMAP"))
  {
    bottomcolor = entity.colormap & 15;
    topcolor = (entity.colormap/16) & 15;
  }
  else if (entity.colormap)
  {
    local entity p = entity_for_number(entity.colormap);
    topcolor = infokey(p, "topcolor");
    bottomcolor = infokey(p, "bottomcolor");
    if (p.modelindex == modelindex_player && isquakeworld)
        skintouse = infokey(p, "skin");
  }
  else
  {
    topcolor = 1;
    bottomcolor = 6;
  }
  somemagicdrawmodelfunction(self.modelindex, self.origin, self.angles, topcolor, bottomcolor, skin);
}
<Pedantic>
In reality, FTE's somemagicdrawmodelfunction doesn't take a skin name, but rather the skin index and the player index, and does the lookup itself. This means static entities are truely static, even if they've a colormap and the colormap still works.
Most other engines do the colors lookup in the renderer too. Older GLQuake(World) engines use only the player index as a texture lookup and reload/recolour that texture on each skin/colour userinfo change.
I don't include animation, particle, dlight, interpolation, etc, info because all that stuff is crazy, weird, and offtopic.
</Pedantic>

<UselessInfo>
somemagicdrawmodelfunction is equivelent to csqc's addentity function.
The ents are actually only added to a list, to be drawn later with a call to 'renderscene' once all the other properties and ents/particles/polys are configured/added.
In fte there is a forceshader csqc field which can be set to some shader to override the shader used to draw the entity with any shader/texture you want. This is not accessible to ssqc at this time, but does go some way to nullify the point in the pedantic part above. :P
</UselessInfo>

<hexen2>
hexen2 (and thus also fte) has a 'global skins' feature. skins between 100 and 110 use 'gfx/skin%d.lmp' instead of the texture stored in the model. This overrides even quakeworld skins, but is not likely in your case.
</hexen2>
Post Reply