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