]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/playerdemo.qc
Merge branch 'master' into Mario/showspecs
[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(entity this)
21 {
22         if(this.playerdemo_mode != PLAYERDEMO_MODE_OFF)
23         {
24                 LOG_INFO("playerdemo: ", this.netname, " closed\n");
25                 fclose(this.playerdemo_fh);
26         }
27         this.playerdemo_mode = 0;
28 }
29 void playerdemo_open_read(entity this, string f)
30 {
31         playerdemo_shutdown(this);
32         this.playerdemo_mode = PLAYERDEMO_MODE_READING;
33         this.playerdemo_fh = fopen(f, FILE_READ);
34         this.playerdemo_starttime = time - 1;
35         this.playerdemo_time = stof(fgets(this.playerdemo_fh));
36         this.playerdemo_time += this.playerdemo_starttime;
37         this.movetype = MOVETYPE_NONE;
38         LOG_INFO("playerdemo: ", this.netname, " reading from ", f, "\n");
39 }
40 void playerdemo_open_write(entity this, string f)
41 {
42         playerdemo_shutdown(this);
43         this.playerdemo_mode = PLAYERDEMO_MODE_WRITING;
44         this.playerdemo_fh = fopen(f, FILE_WRITE);
45         this.playerdemo_starttime = time - 1;
46         LOG_INFO("playerdemo: ", this.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(ent,func,t,f) func##t(ent,f,#f);
50 #define PLAYERDEMO_FIELDS(ent,func) \
51         PLAYERDEMO_FIELD(ent,func,originvector,origin) \
52         PLAYERDEMO_FIELD(ent,func,vector,angles) \
53         PLAYERDEMO_FIELD(ent,func,sizevector,mins) \
54         PLAYERDEMO_FIELD(ent,func,sizevector,maxs) \
55         PLAYERDEMO_FIELD(ent,func,vector,v_angle) \
56         PLAYERDEMO_FIELD(ent,func,modelstring,model) \
57         PLAYERDEMO_FIELD(ent,func,string,playermodel) \
58         PLAYERDEMO_FIELD(ent,func,float,skin) \
59         PLAYERDEMO_FIELD(ent,func,string,playerskin) \
60         PLAYERDEMO_FIELD(ent,func,float,frame) \
61         PLAYERDEMO_FIELD(ent,func,float,effects) \
62         /* PLAYERDEMO_FIELD(ent,func,float,switchweapon) */ \
63         PLAYERDEMO_FIELD(ent,func,float,button0) /* TODO: PHYS_INPUT_BUTTON_ATCK */ \
64         PLAYERDEMO_FIELD(ent,func,float,button3) /* TODO: PHYS_INPUT_BUTTON_ATCK2 */ \
65         PLAYERDEMO_FIELD(ent,func,float,button5) /* TODO: PHYS_INPUT_BUTTON_CROUCH */ \
66         PLAYERDEMO_FIELD(ent,func,float,button6) /* TODO: PHYS_INPUT_BUTTON_HOOK */ \
67         PLAYERDEMO_FIELD(ent,func,float,buttonuse) /* TODO: PHYS_INPUT_BUTTON_USE */ \
68         PLAYERDEMO_FIELD(ent,func,float,flags) \
69         // end of list
70
71 void playerdemo_write_originvector(entity this, .vector f, string name)
72 {
73         fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n"));
74 }
75 void playerdemo_write_sizevector(entity this, .vector f, string name)
76 {
77         fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n"));
78 }
79 void playerdemo_write_vector(entity this, .vector f, string name)
80 {
81         fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n"));
82 }
83 void playerdemo_write_string(entity this, .string f, string name)
84 {
85         fputs(this.playerdemo_fh, strcat(this.(f), "\n"));
86 }
87 void playerdemo_write_modelstring(entity this, .string f, string name)
88 {
89         fputs(this.playerdemo_fh, strcat(this.(f), "\n"));
90 }
91 void playerdemo_write_float(entity this, .float f, string name)
92 {
93         fputs(this.playerdemo_fh, strcat(ftos(this.(f)), "\n"));
94 }
95 void playerdemo_write(entity this)
96 {
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(this, playerdemo_write_)
101 }
102 void playerdemo_read_originvector(entity this, .vector f, string name)
103 {
104         setorigin(this, stov(fgets(this.playerdemo_fh)));
105 }
106 void playerdemo_read_sizevector(entity this, .vector f, string name)
107 {
108         this.(f) = stov(fgets(this.playerdemo_fh));
109         setsize(this, this.mins, this.maxs);
110 }
111 void playerdemo_read_vector(entity this, .vector f, string name)
112 {
113         this.(f) = stov(fgets(this.playerdemo_fh));
114 }
115 void playerdemo_read_string(entity this, .string f, string name)
116 {
117         string s = fgets(this.playerdemo_fh);
118         if (s != this.(f))
119         {
120                 /*
121                 if(this.f)
122                         strunzone(this.f);
123                 */
124                 this.(f) = strzone(s);
125         }
126 }
127 void playerdemo_read_modelstring(entity this, .string f, string name)
128 {
129         string s = fgets(this.playerdemo_fh);
130         if (s != this.(f))
131                 _setmodel(this, s);
132 }
133 void playerdemo_read_float(entity this, .float f, string name)
134 {
135         this.(f) = stof(fgets(this.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(this, playerdemo_read_)
148                 {
149                         time = this.playerdemo_time;
150                         PlayerPreThink(this);
151                         // not running physics though... this is just so we can run weapon stuff
152                         PlayerPostThink(this);
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 }