1#include "util.qh" 2/* 3* Update this.tur_shotorg by getting up2date bone info 4* NOTICE this func overwrites the global v_forward, v_right and v_up vectors. 5*/ 6float turret_tag_fire_update(entity this) 7{ 8 if(!this.tur_head) 9 { 10 LOG_DEBUG("Call to turret_tag_fire_update with this.tur_head missing!"); 11 this.tur_shotorg = '0 0 0'; 12 return false; 13 } 14 15 this.tur_shotorg = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_fire")); 16 v_forward = normalize(v_forward); 17 18 return true; 19} 20 21/* 22* Railgun-like beam, but has thickness and suppots slowing of target 23*/ 24void FireImoBeam(entity this, vector start, vector end, vector smin, vector smax, 25 float bforce, float f_dmg, float f_velfactor, int deathtype) 26 27{ 28 vector hitloc, force, endpoint, dir; 29 entity ent; 30 31 dir = normalize(end - start); 32 force = dir * bforce; 33 34 // go a little bit into the wall because we need to hit this wall later 35 end = end + dir; 36 37 // trace multiple times until we hit a wall, each obstacle will be made unsolid. 38 // note down which entities were hit so we can damage them later 39 while (1) 40 { 41 tracebox(start, smin, smax, end, false, this); 42 43 // if it is NULL we can't hurt it so stop now 44 if (trace_ent == NULL || trace_fraction == 1) 45 break; 46 47 if (trace_ent.solid == SOLID_BSP) 48 break; 49 50 // make the entity non-solid so we can hit the next one 51 trace_ent.railgunhit = true; 52 trace_ent.railgunhitloc = end; 53 trace_ent.railgunhitsolidbackup = trace_ent.solid; 54 55 // stop if this is a wall 56 57 // make the entity non-solid 58 trace_ent.solid = SOLID_NOT; 59 } 60 61 endpoint = trace_endpos; 62 63 // find all the entities the railgun hit and restore their solid state 64 ent = findfloat(NULL, railgunhit, true); 65 while (ent) 66 { 67 // restore their solid type 68 ent.solid = ent.railgunhitsolidbackup; 69 ent = findfloat(ent, railgunhit, true); 70 } 71 72 // find all the entities the railgun hit and hurt them 73 ent = findfloat(NULL, railgunhit, true); 74 while (ent) 75 { 76 // get the details we need to call the damage function 77 hitloc = ent.railgunhitloc; 78 ent.railgunhitloc = '0 0 0'; 79 ent.railgunhitsolidbackup = SOLID_NOT; 80 ent.railgunhit = false; 81 82 // apply the damage 83 if (ent.takedamage) 84 { 85 Damage (ent, this, this, f_dmg, deathtype, hitloc, force); 86 ent.velocity = ent.velocity * f_velfactor; 87 //ent.alpha = 0.25 + random() * 0.75; 88 } 89 90 // advance to the next entity 91 ent = findfloat(ent, railgunhit, true); 92 } 93 trace_endpos = endpoint; 94} 95 96#ifdef TURRET_DEBUG 97void marker_think(entity this, ) 98{ 99 if(this.cnt) 100 if(this.cnt < time) 101 { 102 setthink(this, SUB_Remove); 103 this.nextthink = time; 104 return; 105 } 106 107 this.frame += 1; 108 if(this.frame > 29) 109 this.frame = 0; 110 111 this.nextthink = time; 112} 113 114void mark_error(vector where,float lifetime) 115{ 116 entity err = new(error_marker); 117 setmodel(err, MDL_MARKER); 118 setorigin(err, where); 119 set_movetype(err, MOVETYPE_NONE); 120 setthink(err, marker_think); 121 err.nextthink = time; 122 err.skin = 0; 123 if(lifetime) 124 err.cnt = lifetime + time; 125} 126 127void mark_info(vector where,float lifetime) 128{ 129 entity err = spawn(info_marker); 130 setmodel(err, MDL_MARKER); 131 setorigin(err, where); 132 set_movetype(err, MOVETYPE_NONE); 133 setthink(err, marker_think); 134 err.nextthink = time; 135 err.skin = 1; 136 if(lifetime) 137 err.cnt = lifetime + time; 138} 139 140entity mark_misc(vector where,float lifetime) 141{ 142 entity err = spawn(mark_misc); 143 setmodel(err, MDL_MARKER); 144 setorigin(err, where); 145 set_movetype(err, MOVETYPE_NONE); 146 setthink(err, marker_think); 147 err.nextthink = time; 148 err.skin = 3; 149 if(lifetime) 150 err.cnt = lifetime + time; 151 return err; 152} 153 154MODEL(TUR_C512, "models/turrets/c512.md3"); 155 156/* 157* Paint a v_color colord circle on target onwho 158* that fades away over f_time 159*/ 160void paint_target(entity onwho, float f_size, vector v_color, float f_time) 161{ 162 entity e; 163 164 e = spawn(); 165 setmodel(e, MDL_TUR_C512); // precision set above 166 e.scale = (f_size/512); 167 //setsize(e, '0 0 0', '0 0 0'); 168 //setattachment(e,onwho,""); 169 setorigin(e, onwho.origin + '0 0 1'); 170 e.alpha = 0.15; 171 set_movetype(e, MOVETYPE_FLY); 172 173 e.velocity = (v_color * 32); // + '0 0 1' * 64; 174 175 e.colormod = v_color; 176 SUB_SetFade(e,time,f_time); 177} 178 179void paint_target2(entity onwho, float f_size, vector v_color, float f_time) 180{ 181 entity e; 182 183 e = spawn(); 184 setmodel(e, MDL_TUR_C512); // precision set above 185 e.scale = (f_size/512); 186 setsize(e, '0 0 0', '0 0 0'); 187 188 setorigin(e, onwho.origin + '0 0 1'); 189 e.alpha = 0.15; 190 set_movetype(e, MOVETYPE_FLY); 191 192 e.velocity = (v_color * 32); // + '0 0 1' * 64; 193 e.avelocity_x = -128; 194 195 e.colormod = v_color; 196 SUB_SetFade(e,time,f_time); 197} 198 199void paint_target3(vector where, float f_size, vector v_color, float f_time) 200{ 201 entity e; 202 e = spawn(); 203 setmodel(e, MDL_TUR_C512); // precision set above 204 e.scale = (f_size/512); 205 setsize(e, '0 0 0', '0 0 0'); 206 setorigin(e, where + '0 0 1'); 207 set_movetype(e, MOVETYPE_NONE); 208 e.velocity = '0 0 0'; 209 e.colormod = v_color; 210 SUB_SetFade(e,time,f_time); 211} 212#endif 213