]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/csqcmodel_hooks.qc
forcemodels: also, if client lacks a model file, force model to default player model
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / csqcmodel_hooks.qc
1 .vector glowmod;
2 .float lodmodelindex0;
3 .float lodmodelindex1;
4 .float lodmodelindex2;
5
6 .entity tag_entity;
7 .float tag_index;
8
9 void CSQCModel_Hook_PreDraw(float isplayer)
10 {
11         // auto glowmod from colormap
12         if(isplayer)
13         {
14                 if(self.colormap > 0)
15                         self.glowmod = colormapPaletteColor(((self.colormap >= 1024) ? (self.colormap & 0xFF) : stof(getplayerkeyvalue(self.colormap - 1, "colors"))), TRUE) * 2;
16                 else
17                         self.glowmod = '1 1 1';
18
19                 if(self.modelindex && self.model != "null")
20                 {
21                         if(autocvar_cl_playerdetailreduction <= 0)
22                         {
23                                 if(autocvar_cl_playerdetailreduction <= -2)
24                                         self.modelindex = self.lodmodelindex2;
25                                 else if(autocvar_cl_playerdetailreduction <= -1)
26                                         self.modelindex = self.lodmodelindex1;
27                                 else
28                                         self.modelindex = self.lodmodelindex0;
29                         }
30                         else
31                         {
32                                 float distance = vlen(self.origin - other.origin);
33                                 float f = (distance + 100.0) * autocvar_cl_playerdetailreduction;
34                                 f *= 1.0 / bound(0.01, view_quality, 1);
35                                 if(f > autocvar_cl_loddistance2)
36                                         self.modelindex = self.lodmodelindex2;
37                                 else if(f > autocvar_cl_loddistance1)
38                                         self.modelindex = self.lodmodelindex1;
39                                 else
40                                         self.modelindex = self.lodmodelindex0;
41                         }
42                 }
43         }
44
45         if(!isplayer)
46         {
47                 if(self.tag_entity && wasfreed(self.tag_entity))
48                         self.tag_entity = world;
49
50                 if(self.tag_networkentity)
51                 {
52                         // we are ATTACHED!
53                         if(self.tag_entity.entnum == self.tag_networkentity)
54                         {
55                                 // already good
56                                 self.drawmask = MASK_NORMAL;
57                         }
58                         else
59                         {
60                                 // to something NEW NEW NEW NEW!
61                                 self.tag_entity = findfloat(world, entnum, self.tag_networkentity);
62                                 if(self.tag_entity)
63                                 {
64                                         // the best part is: IT EXISTS
65                                         self.drawmask = MASK_NORMAL;
66
67                                         if(substring(self.model, 0, 17) == "models/weapons/v_")
68                                                 if(substring(self.tag_entity.model, 0, 17) == "models/weapons/h_")
69                                                 {
70                                                         self.tag_index = gettagindex(self.tag_entity, "weapon");
71                                                         if(!self.tag_index)
72                                                                 self.tag_index = gettagindex(self.tag_entity, "tag_weapon");
73                                                         if(!self.tag_index)
74                                                         {
75                                                                 // we need to prevent this from 'appening
76                                                                 self.tag_entity = world;
77                                                                 self.drawmask = 0;
78                                                                 dprint("h_ model lacks weapon attachment, but v_ model is attached to it\n");
79                                                         }
80                                                 }
81
82                                         if(substring(self.model, 0, 17) == "models/weapons/v_")
83                                                 if(substring(self.tag_entity.model, 0, 14) == "models/player/")
84                                                 {
85                                                         self.tag_index = gettagindex(self.tag_entity, "tag_weapon");
86                                                         if(!self.tag_index)
87                                                                 self.tag_index = gettagindex(self.tag_entity, "bip01 r hand");
88                                                 }
89
90                                         if(substring(self.tag_entity.model, 0, 17) == "models/weapons/v_")
91                                         {
92                                                 self.tag_index = gettagindex(self.tag_entity, "shot");
93                                                 if(!self.tag_index)
94                                                         self.tag_index = gettagindex(self.tag_entity, "tag_shot");
95                                         }
96                                 }
97                                 else
98                                 {
99                                         // damn, see you next frame
100                                         self.drawmask = 0;
101                                 }
102                         }
103                 }
104                 else
105                 {
106                         // no brain no pain
107                         self.drawmask = MASK_NORMAL;
108                 }
109         }
110 }
111
112 string forceplayermodels_model;
113 float forceplayermodels_modelindex;
114 float forceplayermodels_skin;
115 .string forceplayermodels_savemodel;
116 .float forceplayermodels_savemodelindex;
117 .float forceplayermodels_saveskin;
118 void CSQCModel_Hook_PreUpdate(float isplayer, float islocalplayer)
119 {
120         if(isplayer)
121         {
122                 // revert to values from server
123                 self.model = self.forceplayermodels_savemodel;
124                 self.modelindex = self.forceplayermodels_savemodelindex;
125                 self.skin = self.forceplayermodels_saveskin;
126         }
127 }
128
129 void CSQCModel_Hook_PostUpdate(float isplayer, float islocalplayer)
130 {
131         if(isplayer)
132         {
133                 // save values set by server
134                 self.forceplayermodels_savemodel = self.model;
135                 self.forceplayermodels_savemodelindex = self.modelindex;
136                 self.forceplayermodels_saveskin = self.skin;
137
138                 if(self.modelindex && self.model != "null")
139                 {
140                         if(islocalplayer)
141                         {
142                                 // trust server's idea of "own player model"
143                                 forceplayermodels_model = self.model;
144                                 forceplayermodels_modelindex = self.modelindex;
145                                 forceplayermodels_skin = self.skin;
146                         }
147                         if(!forceplayermodels_modelindex)
148                         {
149                                 // only if this failed, find it out on our own
150                                 setmodel(self, autocvar__cl_playermodel); // this is harmless, see below
151                                 forceplayermodels_model = self.model;
152                                 forceplayermodels_modelindex = self.modelindex;
153                                 forceplayermodels_skin = autocvar__cl_playerskin;
154                         }
155                 }
156
157                 if(autocvar_cl_forceplayermodels)
158                 {
159                         self.model = forceplayermodels_model;
160                         self.modelindex = forceplayermodels_modelindex;
161                         self.skin = forceplayermodels_skin;
162                 }
163
164                 // LOD model loading
165                 if(self.lodmodelindex0 != self.modelindex)
166                 {
167                         string modelname = self.model;
168                         string s;
169
170                         if(!fexists(modelname))
171                         {
172                                 print(sprintf(_("Trying to use non existing model %s. "), modelname));
173                                 modelname = cvar_defstring("_cl_playermodel");
174                                 print(sprintf(_("Reverted to %s."), modelname));
175                         }
176
177                         // set modelindex
178                         self.lodmodelindex0 = self.modelindex;
179                         self.lodmodelindex1 = self.modelindex;
180                         self.lodmodelindex2 = self.modelindex;
181
182                         // FIXME: this only supports 3-letter extensions
183                         s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod1", substring(modelname, -4, 4));
184                         if(fexists(s))
185                         {
186                                 precache_model(s);
187                                 setmodel(self, s);
188                                 if(self.modelindex)
189                                         self.lodmodelindex1 = self.modelindex;
190                         }
191
192                         s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod2", substring(modelname, -4, 4));
193                         if(fexists(s))
194                         {
195                                 precache_model(s);
196                                 setmodel(self, s);
197                                 if(self.modelindex)
198                                         self.lodmodelindex2 = self.modelindex;
199                         }
200
201                         setmodel(self, modelname); // make everything normal again
202                 }
203         }
204 }