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