Advertisement
scroton

Untitled

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