Merge remote branch 'refs/remotes/origin/fruitiex/racefixes'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / playerdemo.qc
1 .float playerdemo_fh;
2 .float playerdemo_mode;
3 .float playerdemo_starttime;
4 .float playerdemo_time;
5 #define PLAYERDEMO_MODE_OFF 0
6 #define PLAYERDEMO_MODE_READING 1
7 #define PLAYERDEMO_MODE_WRITING 2
8 void playerdemo_init()
9 {
10         self.playerdemo_mode = PLAYERDEMO_MODE_OFF;
11 }
12 void playerdemo_shutdown()
13 {
14         if(self.playerdemo_mode != PLAYERDEMO_MODE_OFF)
15         {
16                 print("playerdemo: ", self.netname, " closed\n");
17                 fclose(self.playerdemo_fh);
18         }
19         self.playerdemo_mode = 0;
20 }
21 void playerdemo_open_read(string f)
22 {
23         playerdemo_shutdown();
24         self.playerdemo_mode = PLAYERDEMO_MODE_READING;
25         self.playerdemo_fh = fopen(f, FILE_READ);
26         self.playerdemo_starttime = time - 1;
27         self.playerdemo_time = stof(fgets(self.playerdemo_fh));
28         self.playerdemo_time += self.playerdemo_starttime;
29         self.movetype = MOVETYPE_NONE;
30         print("playerdemo: ", self.netname, " reading from ", f, "\n");
31 }
32 void playerdemo_open_write(string f)
33 {
34         playerdemo_shutdown();
35         self.playerdemo_mode = PLAYERDEMO_MODE_WRITING;
36         self.playerdemo_fh = fopen(f, FILE_WRITE);
37         self.playerdemo_starttime = time - 1;
38         print("playerdemo: ", self.netname, " writing to ", f, "\n");
39         print("WARNING: playerdemo file format is incomplete and not stable yet. DO NOT RELY ON IT!\n");
40 }
41 #define PLAYERDEMO_FIELD(func,t,f) func##t(f,#f);
42 #define PLAYERDEMO_FIELDS(func) \
43         PLAYERDEMO_FIELD(func,originvector,origin) \
44         PLAYERDEMO_FIELD(func,vector,angles) \
45         PLAYERDEMO_FIELD(func,sizevector,mins) \
46         PLAYERDEMO_FIELD(func,sizevector,maxs) \
47         PLAYERDEMO_FIELD(func,vector,v_angle) \
48         PLAYERDEMO_FIELD(func,modelstring,model) \
49         PLAYERDEMO_FIELD(func,string,playermodel) \
50         PLAYERDEMO_FIELD(func,float,skin) \
51         PLAYERDEMO_FIELD(func,string,playerskin) \
52         PLAYERDEMO_FIELD(func,float,frame) \
53         PLAYERDEMO_FIELD(func,float,effects) \
54         PLAYERDEMO_FIELD(func,float,switchweapon) \
55         PLAYERDEMO_FIELD(func,float,BUTTON_ATCK) \
56         PLAYERDEMO_FIELD(func,float,BUTTON_ATCK2) \
57         PLAYERDEMO_FIELD(func,float,BUTTON_CROUCH) \
58         PLAYERDEMO_FIELD(func,float,BUTTON_HOOK) \
59         PLAYERDEMO_FIELD(func,float,BUTTON_USE) \
60         PLAYERDEMO_FIELD(func,float,flags) \
61         // end of list
62
63 void playerdemo_write_originvector(.vector f, string name)
64 {
65         fputs(self.playerdemo_fh, strcat(vtos(self.f), "\n"));
66 }
67 void playerdemo_write_sizevector(.vector f, string name)
68 {
69         fputs(self.playerdemo_fh, strcat(vtos(self.f), "\n"));
70 }
71 void playerdemo_write_vector(.vector f, string name)
72 {
73         fputs(self.playerdemo_fh, strcat(vtos(self.f), "\n"));
74 }
75 void playerdemo_write_string(.string f, string name)
76 {
77         fputs(self.playerdemo_fh, strcat(self.f, "\n"));
78 }
79 void playerdemo_write_modelstring(.string f, string name)
80 {
81         fputs(self.playerdemo_fh, strcat(self.f, "\n"));
82 }
83 void playerdemo_write_float(.float f, string name)
84 {
85         fputs(self.playerdemo_fh, strcat(ftos(self.f), "\n"));
86 }
87 void playerdemo_write()
88 {
89         if(self.playerdemo_mode != PLAYERDEMO_MODE_WRITING)
90                 return;
91         fputs(self.playerdemo_fh, strcat(ftos(time - self.playerdemo_starttime), "\n"));
92         PLAYERDEMO_FIELDS(playerdemo_write_)
93 }
94 void playerdemo_read_originvector(.vector f, string name)
95 {
96         setorigin(self, stov(fgets(self.playerdemo_fh)));
97 }
98 void playerdemo_read_sizevector(.vector f, string name)
99 {
100         self.f = stov(fgets(self.playerdemo_fh));
101         setsize(self, self.mins, self.maxs);
102 }
103 void playerdemo_read_vector(.vector f, string name)
104 {
105         self.f = stov(fgets(self.playerdemo_fh));
106 }
107 void playerdemo_read_string(.string f, string name)
108 {
109         string s;
110         s = fgets(self.playerdemo_fh);
111         if(s != self.f)
112         {
113                 /*
114                 if(self.f)
115                         strunzone(self.f);
116                 */
117                 self.f = strzone(s);
118         }
119 }
120 void playerdemo_read_modelstring(.string f, string name)
121 {
122         string s;
123         s = fgets(self.playerdemo_fh);
124         if(s != self.f)
125                 setmodel(self, s);
126 }
127 void playerdemo_read_float(.float f, string name)
128 {
129         self.f = stof(fgets(self.playerdemo_fh));
130 }
131 float playerdemo_read()
132 {
133         if(self.playerdemo_mode != PLAYERDEMO_MODE_READING)
134                 return 0;
135         if(self.playerdemo_time < 0)
136                 return 1;
137         float t;
138         t = time;
139         while(time >= self.playerdemo_time)
140         {
141                 PLAYERDEMO_FIELDS(playerdemo_read_)
142                 {
143                         time = self.playerdemo_time;
144                         PlayerPreThink();
145                         // not running physics though... this is just so we can run weapon stuff
146                         PlayerPostThink();
147                 }
148                 self.playerdemo_time = stof(fgets(self.playerdemo_fh));
149                 if(self.playerdemo_time == 0)
150                 {
151                         self.playerdemo_time = -1;
152                         return 1;
153                 }
154                 self.playerdemo_time += self.playerdemo_starttime;
155         }
156         self.velocity = '0 0 0';
157         time = t;
158         return 1;
159 }