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