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; 13const float PLAYERDEMO_MODE_OFF = 0; 14const float PLAYERDEMO_MODE_READING = 1; 15const float PLAYERDEMO_MODE_WRITING = 2; 16void playerdemo_init(entity this) 17{ 18 this.playerdemo_mode = PLAYERDEMO_MODE_OFF; 19} 20void 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} 29void 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 set_movetype(this, MOVETYPE_NONE); 38 LOG_INFO("playerdemo: ", this.netname, " reading from ", f, "\n"); 39} 40void 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 71void playerdemo_write_originvector(entity this, .vector f, string name) 72{ 73 fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n")); 74} 75void playerdemo_write_sizevector(entity this, .vector f, string name) 76{ 77 fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n")); 78} 79void playerdemo_write_vector(entity this, .vector f, string name) 80{ 81 fputs(this.playerdemo_fh, strcat(vtos(this.(f)), "\n")); 82} 83void playerdemo_write_string(entity this, .string f, string name) 84{ 85 fputs(this.playerdemo_fh, strcat(this.(f), "\n")); 86} 87void playerdemo_write_modelstring(entity this, .string f, string name) 88{ 89 fputs(this.playerdemo_fh, strcat(this.(f), "\n")); 90} 91void playerdemo_write_float(entity this, .float f, string name) 92{ 93 fputs(this.playerdemo_fh, strcat(ftos(this.(f)), "\n")); 94} 95void 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} 102void playerdemo_read_originvector(entity this, .vector f, string name) 103{ 104 setorigin(this, stov(fgets(this.playerdemo_fh))); 105} 106void 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} 111void playerdemo_read_vector(entity this, .vector f, string name) 112{ 113 this.(f) = stov(fgets(this.playerdemo_fh)); 114} 115void 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} 127void 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} 133void playerdemo_read_float(entity this, .float f, string name) 134{ 135 this.(f) = stof(fgets(this.playerdemo_fh)); 136} 137float 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} 166