Advertisement
scroton

Untitled

Mar 2nd, 2015
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.00 KB | None | 0 0
  1.  
  2. function int ProjInt_Brute(int stid, int ttid, int spd, int ptid, int xoff, int yoff, int zoff, str ptype, int axoff, int ayoff, int azoff, int angoff, int rand, int input_t)
  3. {
  4. int sX, sY, sZ, s_ang, tX, tY, tZ, tVelX, tVelY, tVelZ;
  5. int tXf, tYf, tZf;
  6. int Z_spd_t, X_spd_t, Y_spd_t, XY_spd_t, spd_t, p_ang;
  7. int t, tt, t_inc, sml_t, n, nmax, i, imax, diff, smldiff;
  8. int X_spd, Y_spd, Z_spd, XY_spd;
  9. int CheckGrav, tCZ, tFZ, tG, tHeight, tZf_delta, tZ_OG, t_ceil;
  10. int check = 1, check2 = 1;
  11. int oldstid, oldttid, stid_z, ttid_z;
  12. int check_t, t1, t2, tttid;
  13.  
  14. if(!stid || ThingCount(T_NONE,stid) > 1){
  15. stid_z = 1;
  16. oldstid = ActivatorTID();
  17. stid = UniqueTID();
  18. Thing_ChangeTID(0, stid); }
  19. else{ oldstid = stid; }
  20.  
  21. sX = GetActorX(stid);
  22. sY = GetActorY(stid);
  23. sZ = GetActorZ(stid);
  24. s_ang = GetActorAngle(stid);
  25.  
  26. sZ += zoff;
  27.  
  28. if(xoff > 0){
  29. sX += FixedMul(cos(FixedAngMod(s_ang - 0.25)),xoff);
  30. sY += FixedMul(sin(FixedAngMod(s_ang - 0.25)),xoff); }
  31. else if(xoff < 0){
  32. sX += FixedMul(cos(FixedAngMod(s_ang + 0.25)),xoff);
  33. sY += FixedMul(sin(FixedAngMod(s_ang + 0.25)),xoff); }
  34.  
  35. if(yoff > 0){
  36. sX += FixedMul(cos(s_ang),yoff);
  37. sY += FixedMul(sin(s_ang),yoff); }
  38. else if(yoff < 0){
  39. sX -= FixedMul(cos(s_ang),yoff);
  40. sY -= FixedMul(sin(s_ang),yoff); }
  41.  
  42. if(!ttid || ThingCount(T_NONE,ttid) > 1){
  43. ttid_z = 1;
  44. SetActivator(0, AAPTR_TARGET);
  45. oldttid = ActivatorTID();
  46. ttid = UniqueTID();
  47. Thing_ChangeTID(0, ttid); }
  48. else{ oldttid = ttid; }
  49.  
  50. tX = GetActorX(ttid);
  51. tY = GetActorY(ttid);
  52. tZ_OG = GetActorZ(ttid);
  53.  
  54. tZ += 36.0;
  55. //tZ += 26.5; for comparison with Thing_ProjectileIntercept
  56.  
  57. tttid= UniqueTID();
  58.  
  59. SpawnForced("ActorSpaceChecker",tX,tY,tZ_OG,tttid,0); //cause with the normal radius it sometimes messes floor and ceiling height checks
  60.  
  61. tFZ = GetActorFloorZ(tttid);
  62. tCZ = GetActorCeilingZ(tttid);
  63.  
  64. tVelX = GetActorVelX(ttid);
  65. tVelY = GetActorVelY(ttid);
  66. tVelZ = GetActorVelZ(ttid);
  67.  
  68. CheckGrav = 0;
  69.  
  70. if(!CheckFlag(ttid,"NOGRAVITY") && !CheckActorInventory(ttid,"IsFlying") && (abs(tVelZ) > 1.0) && (tVelZ || tZ_OG > tFZ)){
  71. CheckGrav = 1;
  72. tHeight = GetActorProperty(ttid, APROP_Height);
  73. if(!GetActorProperty(ttid, APROP_Waterlevel)){ tG = GetActorProperty(ttid, APROP_Gravity); }
  74. else if(GetActorProperty(ttid, APROP_Waterlevel) == 1){ tG = GetActorProperty(ttid, APROP_Gravity) / 8; }
  75. else{ tG = GetActorProperty(ttid, APROP_Gravity) / 16; }}
  76. else{ tVelZ = 0; }
  77.  
  78. while(check){
  79. t = sml_t - (t_inc / 2);
  80. if(!i){
  81. t = 1.0;
  82. t_inc = 10.0;
  83. nmax = 40; }
  84. else if(i == 1){
  85. if(sml_t > 400.0){ check = 0; } //stop trying to get closer if it's out of range, it's just a waste
  86. else{
  87. t_inc = 1.0;
  88. nmax = 10; }}
  89. else if(i == 2){
  90. t_inc = 0.1;
  91. nmax = 10; }
  92. else if(i == 3){
  93. t_inc = 0.01;
  94. nmax = 10; }
  95. else if(i == 4){
  96. t_inc = 0.001;
  97. nmax = 10; }
  98. else if(i == 5){
  99. t_inc = 1;
  100. nmax = 66; }
  101. else if(i == 6){ check = 0; }
  102. ++i;
  103. n = 0;
  104. check2 = 1;
  105.  
  106. while(check && check2){
  107. tXf = tX + FixedMul(t,tVelX);
  108. tYf = tY + FixedMul(t,tVelY);
  109.  
  110. if(CheckGrav){ //sum of numbers from 1 to n = (n(n+1))/2
  111. tZf_delta = FixedMul(tVelZ, t) + FixedMul((FixedMul(t + 1.0, t) / 2), tG); //can't really know if they have the first tic of gravity, so don't worry about it
  112. if(tZf_delta > (tCZ - (tZ_OG + tHeight))){ //if actor hit ceiling
  113. /* when did they hit the ceiling
  114. /* use quadratic formula to solve, with t as x in y = ax^2 + bx + c = 0
  115. 0 = t*t*-tG + t(2 * velz - tG) - 2(tCZ - (tZ_OG + tHeight))
  116. a = -tG
  117. b = 2 * tVelZ - tG
  118. c = -2 * (tCZ - (tZ_OG + tHeight)) */
  119. t1 = FixedDiv( (-(2 * tVelZ - tG) + FixedSqrt(sq(2 * tVelZ - tG) - (4 * FixedMul(-tG, -2 * (tCZ - (tZ_OG + tHeight)))))) , (2 * -tG) );
  120. t2 = FixedDiv( (-(2 * tVelZ - tG) - FixedSqrt(sq(2 * tVelZ - tG) - (4 * FixedMul(-tG, -2 * (tCZ - (tZ_OG + tHeight)))))) , (2 * -tG) );
  121. if(t1 > 0){ check_t = t1; }
  122. else if(t2 > 0){ check_t = t2; }
  123. tZf_delta = FixedMul(tVelZ, t - check_t) + FixedMul((FixedMul(t - check_t + 1.0, t - check_t) / 2), tG); //how far did they fall after they hit the ceiling
  124. tZf = tZ + (tCZ - (tZ + tHeight)) + tZf_delta; }
  125. else if(tZf_delta < (tFZ - tZ_OG)){ //if actor hit floor
  126. tZf = tZ + (tFZ - tZ); }
  127. else { tZf = tZ + tZf_delta; }}
  128. //May add floor checks for +NOGRAVITY targets in the future, right now don't worry about it because it's only applicable for infighting
  129. else{ tZf = tZ + FixedMul(t,tVelZ); }
  130.  
  131. //tZf = tZ + FixedMul(t,tVelZ);
  132. Z_spd_t = FixedDiv(tZf - sZ, t);
  133. X_spd_t = FixedDiv(tXf - sx, t);
  134. Y_spd_t = FixedDiv(tYf - sy, t);
  135. XY_spd_t = VectorLength(X_spd_t, Y_spd_t);
  136. spd_t = VectorLength(XY_spd_t, Z_spd_t);
  137. diff = abs(spd - spd_t);
  138. if((diff < smldiff) || n == 0){
  139. smldiff = diff;
  140. sml_t = t; }
  141. ++n;
  142. t += t_inc;
  143. if(n > nmax){ check2 = 0; }}}
  144.  
  145. if(input_t){ t = input_t; }
  146. else{
  147. if(rand){ random(1, sml_t); }
  148. else{ t = sml_t; }}
  149. tt = sml_t;
  150. tXf = tX + FixedMul(t,tVelX);
  151. tYf = tY + FixedMul(t,tVelY);
  152. if(CheckGrav){
  153. tZf_delta = FixedMul(tVelZ, t) + FixedMul((FixedMul(t + 1.0, t) / 2), tG); //can't really know if they have the first tic of gravity, so don't worry about it
  154. if(tZf_delta > (tCZ - (tZ_OG + tHeight))){ //if actor hit ceiling
  155. /* when did they hit the ceiling
  156. /* use quadratic formula to solve, with t as x in y = ax^2 + bx + c = 0
  157. 0 = t*t*tG + t(2 * velz + tG) - 2(tCZ - (tZ_OG + tHeight))
  158. a = tG
  159. b = 2 * tVelZ + tG
  160. c = -2 * (tCZ - (tZ_OG + tHeight)) */
  161. t1 = FixedDiv( (-(2 * tVelZ - tG) - FixedSqrt(sq(2 * tVelZ - tG) - (4 * FixedMul(-tG, -2 * (tCZ - (tZ_OG + tHeight)))))) , (2 * -tG) );
  162. t2 = FixedDiv( (-(2 * tVelZ - tG) - FixedSqrt(sq(2 * tVelZ - tG) - (4 * FixedMul(-tG, -2 * (tCZ - (tZ_OG + tHeight)))))) , (2 * -tG) );
  163. if(t1 > 0){ check_t = t1; }
  164. else if(t2 > 0){ check_t = t2; }
  165. tZf_delta = FixedMul(tVelZ, t - check_t) + FixedMul((FixedMul(t - check_t + 1.0, t - check_t) / 2), tG); //how far did they fall after they hit the ceiling
  166. tZf = tZ + (tCZ - (tZ + tHeight)) + tZf_delta; }
  167. else if(tZf_delta < (tFZ - tZ_OG)){ //if actor hit floor
  168. tZf = tZ + (tFZ - tZ); }
  169. else { tZf = tZ + tZf_delta; }}
  170. else{ tZf = tZ + FixedMul(t,tVelZ); }
  171.  
  172. if(rand || input_t){
  173. Z_spd = FixedDiv(tZf - sZ, tt);
  174. p_ang = VectorAngle(tXf - sX, tYf - sY);
  175. XY_spd = FixedSqrt(sq(spd) - sq(Z_spd));
  176. X_spd = FixedMul(cos(p_ang), XY_spd);
  177. Y_spd = FixedMul(sin(p_ang), XY_spd); }
  178. else{
  179. Z_spd = FixedDiv(tZf - sZ, t);
  180. X_spd = FixedDiv(tXf - sX, t);
  181. Y_spd = FixedDiv(tYf - sY, t);
  182. p_ang = VectorAngle(tXf - sX, tYf - sY); }
  183.  
  184. SetActorAngle(stid, p_ang);
  185.  
  186. sZ += azoff;
  187.  
  188. if(axoff > 0){
  189. sX -= FixedMul(cos(FixedAngMod(s_ang - 0.25)),axoff);
  190. sY -= FixedMul(sin(FixedAngMod(s_ang - 0.25)),axoff); }
  191. else if(axoff < 0){
  192. sX += FixedMul(cos(FixedAngMod(s_ang + 0.25)),axoff);
  193. sY += FixedMul(sin(FixedAngMod(s_ang + 0.25)),axoff); }
  194.  
  195. if(ayoff > 0){
  196. sX += FixedMul(cos(s_ang),ayoff);
  197. sY += FixedMul(sin(s_ang),ayoff); }
  198. else if(ayoff < 0){
  199. sX -= FixedMul(cos(s_ang),ayoff);
  200. sY -= FixedMul(sin(s_ang),ayoff); }
  201.  
  202. if(angoff != 0){
  203. p_ang = FixedAngMod(p_ang + angoff);
  204. XY_spd = FixedSqrt(sq(X_spd) + sq(Y_spd));
  205. X_spd = FixedMul(cos(FixedAngMod(p_ang + angoff)), XY_spd);
  206. Y_spd = FixedMul(sin(FixedAngMod(p_ang + angoff)), XY_spd); }
  207.  
  208. if(!ptid || ThingCount(T_NONE,stid) > 1){ ptid = UniqueTID(); }
  209.  
  210. SpawnProjectile (stid, ptype, 0, 0, 0, 0, ptid);
  211. SetActivator(ptid);
  212. SetPointer(AAPTR_TARGET, stid); //so doesn't collide with it
  213. SetPointer(AAPTR_TRACER, ttid);
  214. SetActorPosition(ptid, sX, sY, sZ, 0);
  215. SetActorAngle(ptid, p_ang);
  216. SetActorVelocity(ptid,X_spd,Y_spd,Z_spd,0,0);
  217.  
  218. SetActivator(stid);
  219. if(stid_z){ Thing_ChangeTID(stid, oldstid); }
  220. if(ttid_z){ Thing_ChangeTID(ttid, oldttid); }
  221. return t;
  222. }
  223.  
  224. /* This below script doesn't work, because I'm dumb, and since I don't know
  225. C++ yet I can't copy the code Thing_ProjectileIntercept uses. (Here it is on
  226. the ZDoom git (https://github.com/rheit/zdoom/blob/master/src/p_things.cpp)
  227. I've tried to comment this code well enough to explain what I'm trying to do
  228. here, so if you're reading this and can figure out what I'm doing wrong please
  229. help me. */
  230.  
  231. function int ProjectileInterceptNoWork(int stid, int ttid, int spd, int ptid)
  232. {
  233. /* stid is the shooter tid, ttid is the target tid, spd is the speed of the projectile in fixed point, ptid is the tid the projectile will have */
  234.  
  235. int t, last_t, sml_t, n, diff, lastdiff, smldiff, check;
  236.  
  237. int a, b, c, t1, t2;
  238.  
  239. int sX = GetActorX(stid);
  240. int sY = GetActorY(stid);
  241. int sZ = GetActorZ(stid);
  242.  
  243. int tX = GetActorX(ttid);
  244. int tY = GetActorY(ttid);
  245. int tZ = GetActorZ(ttid);
  246.  
  247. //tZ = tZ + 26.5; This was just here for comparison with Thing_ProjectileIntercept, which fires above the target's Z approximately 26.5 map units.
  248.  
  249. int tVelX = GetActorVelX(ttid);
  250. int tVelY = GetActorVelY(ttid);
  251. int tVelZ = GetActorVelZ(ttid);
  252.  
  253. //Triangle STI, where S is shooter position, T is target position and I is where the target and fired projectile will intercept
  254.  
  255. int S_T_len = FixedSqrt(sq(sX - tX) + sq(sY - tY) + sq(sZ - tZ)); //Distance between shooter and target, or S_T
  256. int tVel_len = FixedSqrt(sq(tVelX) + sq(tVelY) + sq(tVelZ)); //Vector length for the shooter's velocity
  257.  
  258. int alg_dot_STI = FixedMul(sX-tX, tVelX) + FixedMul(sY-tY, tVelY) + FixedMul(sZ-tZ, tVelZ); /* The algebraic dot product, which is:
  259. //log(s: "alg_dot_STI:", f: alg_dot_STI);
  260.  
  261. http://en.wikipedia.org/wiki/Dot_product
  262. http://math.oregonstate.edu/home/programs/undergrad/CalculusQuestStudyGuides/vcalc/dotprod/dotprod.html
  263.  
  264. Vector0 * Vector1 =
  265. [x0,y0,z0] * [x1,y1,z1] =
  266. (x0 * x1) + (y0 * y1) + (z0 * z1)
  267.  
  268. which is equal to the geometric dot product, which is:
  269.  
  270. Vector0 * Vector1 =
  271. |V0| * |V1| * cos(###) where ### is the angle between the vectors and |x| denotes "length of x"
  272.  
  273. so
  274.  
  275. sqrt(x0*x0 + y0*y0 + z0*z0) * sqrt(x1*x1 + y1*y1 + z1*z1) * cos(###) = (x0 * x1 ) + (y0 * y1) + (z0 * z1)
  276.  
  277. so
  278.  
  279. cos(###) = [(x0 * x1 ) + (y0 * y1) + (z0 * z1)] / [sqrt(x0*x0 + y0*y0 + z0*z0) * sqrt(x1*x1 + y1*y1 + z1*z1)]
  280.  
  281. */
  282.  
  283. int cos_STI = FixedDiv(alg_dot_STI, FixedMul(S_T_len, tVel_len));
  284.  
  285. /*
  286. Then using the Law of Cosines,
  287. http://en.wikipedia.org/wiki/Law_of_cosines
  288. which is:
  289.  
  290. c*c = a*a + b*b - 2*a*b*cos(C), where a, b, and c are sides of a triangle and C is the angle opposite side c.
  291.  
  292. in this case
  293.  
  294. a = S_T = S_T_len | S_T_len = FixedSqrt(sq(sX - tX) + sq(sY - tY) + sq(sZ - tZ));
  295.  
  296. b = T_I = target veloctiy * t = tVel_len * t | tVel_len = FixedSqrt(sq(tVelX) + sq(tVelY) + sq(tVelZ));
  297.  
  298. c = S_I = projectile veloctiy * t = spd * t | function argument
  299.  
  300. C = angle S_T_I = arccos(cos_STI) | cos_STI = FixedDiv(alg_dot_STI, FixedMul(S_T_len, tVel_len));
  301.  
  302. where t is time to impact, in tics.
  303.  
  304. We can then substitute
  305.  
  306. c*c = a*a + b*b - 2*a*b*cos(C)
  307.  
  308. (spd * t)*(spd * t) = (S_T_len)*(S_T_len) + (tVel_len * t)*(tVel_len * t) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  309.  
  310. set it equal to zero by subtracting from the left
  311.  
  312. 0 = (S_T_len)*(S_T_len) + (tVel_len * t)*(tVel_len * t) - 2*(S_T_len)*(tVel_len * t)*(cos_STI) - (spd * t)*(spd * t)
  313.  
  314. then factor for t
  315.  
  316. 0 = (tVel_len * t)*(tVel_len * t) - (spd * t)*(spd * t) + (S_T_len)*(S_T_len) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  317.  
  318. 0 = (tVel_len * t)*(tVel_len * t) - (spd * t)*(spd * t) + (S_T_len)*(S_T_len) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  319.  
  320. 0 = (t*t)*(tVel_len)*(tVel_len) - (t*t)*(spd)*(spd) - (t)*2*(S_T_len)*(tVel_len)*(cos_STI) + (S_T_len)*(S_T_len)
  321.  
  322. 0 = (t^2)*((tVel_len)*(tVel_len) - (spd)*(spd)) + (t)*(-2*(S_T_len)*(tVel_len)*(cos_STI)) + (S_T_len)*(S_T_len)
  323.  
  324. since the expression is now in the form
  325.  
  326. y = ax^2 + bx + c = 0
  327.  
  328. we can use the quadratic formula
  329. http://en.wikipedia.org/wiki/Quadratic_formula
  330.  
  331. [-b +/- sqrt(b^2 - 4*a*c)] / (2*a)
  332.  
  333. to find when the two paths intersect
  334.  
  335. to make it easier, isolate a, b, and c from the expression
  336.  
  337. 0 = (t^2)*((tVel_len)*(tVel_len) - (spd)*(spd)) + (t)*(-2*(S_T_len)*(tVel_len)*(cos_STI)) + (S_T_len)*(S_T_len)
  338.  
  339. a = (tVel_len)*(tVel_len) - (spd)*(spd)
  340.  
  341. b = -2*(S_T_len)*(tVel_len)*(cos_STI)
  342.  
  343. c = (S_T_len)*(S_T_len)
  344.  
  345. */
  346.  
  347. a = sq(tVel_len) - sq(spd);
  348. b = -2 * FixedMul(FixedMul(S_T_len, tVel_len), cos_STI);
  349. c = sq(S_T_len);
  350.  
  351. t1 = FixedDiv( (-b + FixedSqrt(sq(b) - (4 * FixedMul(a,c)))) , (2 * a) );
  352.  
  353. t2 = FixedDiv( (-b - FixedSqrt(sq(b) - (4 * FixedMul(a,c)))) , (2 * a) );
  354.  
  355. log(s: "t1 = ", f: t1);
  356. log(s: "t2 = ", f: t2);
  357.  
  358. /* in this case only positive values for t can be used, so */
  359.  
  360. if(t1 > t2 && t1 > 0){ t = t1; }
  361. else if (t2 > 0){ t = t2; }
  362. else{ t = 99.0; }
  363.  
  364. log(s: "t = ", f: t);
  365.  
  366. int tVelX_t = FixedMul(t,tVelX);
  367. int tVelY_t = FixedMul(t,tVelY);
  368. int tVelZ_t = FixedMul(t,tVelZ);
  369. int tXf = tX + tVelX_t;
  370. int tYf = tY + tVelY_t;
  371. int tZf = tZ + tVelZ_t;
  372.  
  373. int Z_spd = FixedDiv(tZf - sZ, t);
  374. int X_spd = FixedDiv(tXf - sX, t);
  375. int Y_spd = FixedDiv(tYf - sY, t);
  376.  
  377. /* below is only used to have the firing actor be the firer of the projectile
  378. and allow assigning of a tid to that projectile */
  379.  
  380. Thing_ProjectileIntercept (stid, 201, 0, ttid, ptid);
  381.  
  382. SetActorAngle(ptid,VectorAngle(tXf - sX, tYf - sY));
  383. SetActorVelocity(ptid,X_spd,Y_spd,Z_spd,0,0);
  384.  
  385. return t;
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement