Guest User

Untitled

a guest
Apr 2nd, 2015
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.14 KB | None | 0 0
  1. /*==============================================================================
  2.  
  3.  
  4. Southclaw's Line Segment Generation Script v1.0.0
  5.  
  6. Generates a line of objects between start point and destination. Useful
  7. for ziplines, tunnels, police tape, funky neon strips, etc.
  8.  
  9. Dependencies:
  10. y_iterate
  11. streamer plugin
  12.  
  13.  
  14. ==============================================================================*/
  15. #include <streamer>
  16. #include <YSI\y_iterate>
  17.  
  18. #define MAX_LINE (1024)
  19. #define MAX_OBJECTS_PER_LINE (512)
  20. #define INVALID_LINE_SEGMENT_ID (-1)
  21.  
  22.  
  23. enum E_LINE_DATA
  24. {
  25. lin_model,
  26. lin_objCount,
  27. Float: lin_objLength,
  28. Float: lin_objLengthOffset,
  29. Float: lin_maxLength,
  30.  
  31. Float: lin_posX,
  32. Float: lin_posY,
  33. Float: lin_posZ,
  34.  
  35. Float: lin_dstX,
  36. Float: lin_dstY,
  37. Float: lin_dstZ,
  38.  
  39. Float: lin_rotX,
  40. Float: lin_rotY,
  41. Float: lin_rotZ,
  42.  
  43. lin_world,
  44. lin_interior,
  45. lin_playerid
  46. }
  47.  
  48.  
  49. static
  50. lin_Data[MAX_LINE][E_LINE_DATA],
  51. lin_Objects[MAX_LINE][MAX_OBJECTS_PER_LINE],
  52. Iterator: lin_Index<MAX_LINE>;
  53.  
  54.  
  55. /*==============================================================================
  56.  
  57. Core
  58.  
  59. ==============================================================================*/
  60.  
  61.  
  62. stock CreateLineSegment(modelid, Float:objlength, Float:PointX, Float:PointY, Float:PointZ, Float:DestX, Float:DestY, Float:DestZ, Float:RotX = 0.0, Float:RotY = 0.0, Float:RotZ = 0.0, Float:objlengthoffset = 0.0, worldid = -1, interiorid = -1, playerid = -1, Float:maxlength = 100.0)
  63. {
  64. new id = Iter_Free(lin_Index);
  65.  
  66. if(id == -1)
  67. {
  68. print("ERROR: MAX_LINE limit reached.");
  69. return 0;
  70. }
  71.  
  72. lin_Data[id][lin_maxLength] = maxlength;
  73. lin_Data[id][lin_model] = modelid;
  74. lin_Data[id][lin_objLength] = objlength;
  75. lin_Data[id][lin_objLengthOffset] = objlengthoffset;
  76.  
  77. lin_Data[id][lin_posX] = PointX;
  78. lin_Data[id][lin_posY] = PointY;
  79. lin_Data[id][lin_posZ] = PointZ;
  80.  
  81. lin_Data[id][lin_dstX] = DestX;
  82. lin_Data[id][lin_dstY] = DestY;
  83. lin_Data[id][lin_dstZ] = DestZ;
  84.  
  85. lin_Data[id][lin_rotX] = RotX;
  86. lin_Data[id][lin_rotY] = RotY;
  87. lin_Data[id][lin_rotZ] = RotZ;
  88.  
  89. lin_Data[id][lin_world] = worldid;
  90. lin_Data[id][lin_interior] = interiorid;
  91. lin_Data[id][lin_playerid] = playerid;
  92.  
  93. Iter_Add(lin_Index, id);
  94.  
  95. UpdateLineSegment(id);
  96.  
  97. return id;
  98. }
  99.  
  100. stock DestroyLineSegment(lineid)
  101. {
  102. if(!Iter_Contains(lin_Index, lineid))
  103. return 0;
  104.  
  105. for(new i; i < lin_Data[lineid][lin_objCount]; i++)
  106. {
  107. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  108. {
  109. DestroyDynamicObject(lin_Objects[lineid][i]);
  110. lin_Objects[lineid][i] = INVALID_OBJECT_ID;
  111. }
  112. }
  113.  
  114. Iter_Remove(lin_Index, lineid);
  115.  
  116. return 1;
  117. }
  118.  
  119.  
  120. /*==============================================================================
  121.  
  122. Internal
  123.  
  124. ==============================================================================*/
  125.  
  126.  
  127. UpdateLineSegment(lineid)
  128. {
  129. new
  130. Float:rx,
  131. Float:ry,
  132. Float:rz,
  133. Float:vx = lin_Data[lineid][lin_dstX] - lin_Data[lineid][lin_posX],
  134. Float:vy = lin_Data[lineid][lin_dstY] - lin_Data[lineid][lin_posY],
  135. Float:vz = lin_Data[lineid][lin_dstZ] - lin_Data[lineid][lin_posZ],
  136. Float:tmpdist,
  137. Float:distToDest,
  138. count;
  139.  
  140. rz = -(atan2(vy, vx)-90.0);
  141. rx = -(floatabs(atan2(floatsqroot(floatpower(vx, 2.0) + floatpower(vy, 2.0)), vz))-90.0);
  142.  
  143. distToDest = floatsqroot( (vx*vx) + (vy*vy) + (vz*vz) );
  144. count = floatround(distToDest / lin_Data[lineid][lin_objLength], floatround_ceil) + 1;
  145.  
  146. for(new i; i < count; i++)
  147. {
  148. if(i == 0)
  149. tmpdist = (lin_Data[lineid][lin_objLength] / 2.0) + lin_Data[lineid][lin_objLengthOffset];
  150.  
  151. else if(i == count - 1)
  152. tmpdist = (distToDest - (lin_Data[lineid][lin_objLength] / 2.0)) + lin_Data[lineid][lin_objLengthOffset];
  153.  
  154. else
  155. tmpdist = (lin_Data[lineid][lin_objLength] * (i - 1)) + (lin_Data[lineid][lin_objLength] / 2.0) + lin_Data[lineid][lin_objLengthOffset];
  156.  
  157.  
  158. if(tmpdist > distToDest)
  159. break;
  160.  
  161. if(!IsValidDynamicObject(lin_Objects[lineid][i]))
  162. {
  163. lin_Objects[lineid][i] = CreateDynamicObject(lin_Data[lineid][lin_model],
  164. lin_Data[lineid][lin_posX] + ( tmpdist * floatsin(rz, degrees) * floatcos(rx, degrees) ),
  165. lin_Data[lineid][lin_posY] + ( tmpdist * floatcos(rz, degrees) * floatcos(rx, degrees) ),
  166. lin_Data[lineid][lin_posZ] + ( tmpdist * floatsin(rx, degrees) ),
  167. rx + lin_Data[lineid][lin_rotX],
  168. ry + lin_Data[lineid][lin_rotY],
  169. -rz + lin_Data[lineid][lin_rotZ],
  170. lin_Data[lineid][lin_world], lin_Data[lineid][lin_interior], lin_Data[lineid][lin_playerid]);
  171. }
  172. else
  173. {
  174. SetDynamicObjectPos(lin_Objects[lineid][i],
  175. lin_Data[lineid][lin_posX] + ( tmpdist * floatsin(rz, degrees) * floatcos(rx, degrees) ),
  176. lin_Data[lineid][lin_posY] + ( tmpdist * floatcos(rz, degrees) * floatcos(rx, degrees) ),
  177. lin_Data[lineid][lin_posZ] + ( tmpdist * floatsin(rx, degrees) ) );
  178.  
  179. SetDynamicObjectRot(lin_Objects[lineid][i],
  180. rx + lin_Data[lineid][lin_rotX],
  181. ry + lin_Data[lineid][lin_rotY],
  182. -rz + lin_Data[lineid][lin_rotZ]);
  183. }
  184.  
  185. if(tmpdist > lin_Data[lineid][lin_maxLength])
  186. {
  187. break;
  188. }
  189. }
  190. if(count < lin_Data[lineid][lin_objCount])
  191. {
  192. for(new i = count; i < MAX_OBJECTS_PER_LINE; i++)
  193. {
  194. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  195. {
  196. DestroyDynamicObject(lin_Objects[lineid][i]);
  197. lin_Objects[lineid][i] = INVALID_OBJECT_ID;
  198. }
  199. }
  200. }
  201.  
  202. lin_Data[lineid][lin_objCount] = count;
  203.  
  204. return 1;
  205. }
  206.  
  207.  
  208. /*==============================================================================
  209.  
  210. Interface
  211.  
  212. ==============================================================================*/
  213.  
  214.  
  215. stock IsValidLineSegment(lineid)
  216. {
  217. if(!Iter_Contains(lin_Index, lineid))
  218. return 0;
  219.  
  220. return 1;
  221. }
  222.  
  223.  
  224. // lin_model
  225. stock GetLineSegmentModel(lineid)
  226. {
  227. if(!Iter_Contains(lin_Index, lineid))
  228. return 0;
  229.  
  230. return lin_Data[lineid][lin_model];
  231. }
  232.  
  233. stock SetLineSegmentModel(lineid, modelid, Float:objlength, Float:objlengthoffset)
  234. {
  235. if(!Iter_Contains(lin_Index, lineid))
  236. return 0;
  237.  
  238. lin_Data[lineid][lin_model] = modelid;
  239. lin_Data[lineid][lin_objLength] = objlength;
  240. lin_Data[lineid][lin_objLengthOffset] = objlengthoffset;
  241.  
  242. for(new i; i < lin_Data[lineid][lin_objCount]; i++)
  243. {
  244. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  245. Streamer_SetIntData(STREAMER_TYPE_OBJECT, lin_Objects[lineid][i], E_STREAMER_MODEL_ID, modelid);
  246. }
  247.  
  248. UpdateLineSegment(lineid);
  249.  
  250. return 1;
  251. }
  252.  
  253. // lin_objCount
  254. stock GetLineSegmentObjectCount(lineid)
  255. {
  256. if(!Iter_Contains(lin_Index, lineid))
  257. return 0;
  258.  
  259. return lin_Data[lineid][lin_objCount];
  260. }
  261.  
  262. // lin_objLength
  263. stock Float:GetLineSegmentObjectLength(lineid)
  264. {
  265. if(!Iter_Contains(lin_Index, lineid))
  266. return 0.0;
  267.  
  268. return lin_Data[lineid][lin_objLength];
  269. }
  270.  
  271. stock SetLineSegmentObjectLength(lineid, Float:objlength)
  272. {
  273. if(!Iter_Contains(lin_Index, lineid))
  274. return 0;
  275.  
  276. lin_Data[lineid][lin_objLength] = objlength;
  277.  
  278. return 1;
  279. }
  280.  
  281. // lin_objLengthOffset
  282. stock Float:GetLineSegmentObjectOffset(lineid)
  283. {
  284. if(!Iter_Contains(lin_Index, lineid))
  285. return 0.0;
  286.  
  287. return lin_Data[lineid][lin_objLengthOffset];
  288. }
  289.  
  290. stock SetLineSegmentObjectOffset(lineid, Float:objlengthoffset)
  291. {
  292. if(!Iter_Contains(lin_Index, lineid))
  293. return 0;
  294.  
  295. lin_Data[lineid][lin_objLengthOffset] = objlengthoffset;
  296.  
  297. return 1;
  298. }
  299.  
  300. // lin_maxLength
  301. stock Float:GetLineSegmentMaxLength(lineid)
  302. {
  303. if(!Iter_Contains(lin_Index, lineid))
  304. return 0.0;
  305.  
  306. return lin_Data[lineid][lin_maxLength];
  307. }
  308.  
  309. stock SetLineSegmentMaxLength(lineid, Float:maxlength)
  310. {
  311. if(!Iter_Contains(lin_Index, lineid))
  312. return 0;
  313.  
  314. lin_Data[lineid][lin_maxLength] = maxlength;
  315.  
  316. UpdateLineSegment(lineid);
  317.  
  318. return 1;
  319. }
  320.  
  321. // lin_posX
  322. // lin_posY
  323. // lin_posZ
  324. stock GetLineSegmentPoint(lineid, &Float:PointX, &Float:PointY, &Float:PointZ)
  325. {
  326. if(!Iter_Contains(lin_Index, lineid))
  327. return 0;
  328.  
  329. PointX = lin_Data[lineid][lin_posX];
  330. PointY = lin_Data[lineid][lin_posY];
  331. PointZ = lin_Data[lineid][lin_posZ];
  332.  
  333. UpdateLineSegment(lineid);
  334.  
  335. return 1;
  336. }
  337.  
  338. stock SetLineSegmentPoint(lineid, Float:PointX, Float:PointY, Float:PointZ)
  339. {
  340. if(!Iter_Contains(lin_Index, lineid))
  341. return 0;
  342.  
  343. lin_Data[lineid][lin_posX] = PointX;
  344. lin_Data[lineid][lin_posY] = PointY;
  345. lin_Data[lineid][lin_posZ] = PointZ;
  346.  
  347. UpdateLineSegment(lineid);
  348.  
  349. return 1;
  350. }
  351.  
  352. // lin_dstX
  353. // lin_dstY
  354. // lin_dstZ
  355. stock GetLineSegmentDest(lineid, &Float:DestX, &Float:DestY, &Float:DestZ)
  356. {
  357. if(!Iter_Contains(lin_Index, lineid))
  358. return 0;
  359.  
  360. DestX = lin_Data[lineid][lin_dstX];
  361. DestY = lin_Data[lineid][lin_dstY];
  362. DestZ = lin_Data[lineid][lin_dstZ];
  363.  
  364. UpdateLineSegment(lineid);
  365.  
  366. return 1;
  367. }
  368.  
  369. stock SetLineSegmentDest(lineid, Float:DestX, Float:DestY, Float:DestZ)
  370. {
  371. if(!Iter_Contains(lin_Index, lineid))
  372. return 0;
  373.  
  374. lin_Data[lineid][lin_dstX] = DestX;
  375. lin_Data[lineid][lin_dstY] = DestY;
  376. lin_Data[lineid][lin_dstZ] = DestZ;
  377.  
  378. UpdateLineSegment(lineid);
  379.  
  380. return 1;
  381. }
  382.  
  383. // lin_rotX
  384. // lin_rotY
  385. // lin_rotZ
  386. stock GetLineSegmentModelAngles(lineid, &Float:RotX, &Float:RotY, &Float:RotZ)
  387. {
  388. if(!Iter_Contains(lin_Index, lineid))
  389. return 0;
  390.  
  391. RotX = lin_Data[lineid][lin_rotX];
  392. RotY = lin_Data[lineid][lin_rotY];
  393. RotZ = lin_Data[lineid][lin_rotZ];
  394.  
  395. UpdateLineSegment(lineid);
  396.  
  397. return 1;
  398. }
  399.  
  400. stock SetLineSegmentModelAngles(lineid, Float:RotX, Float:RotY, Float:RotZ)
  401. {
  402. if(!Iter_Contains(lin_Index, lineid))
  403. return 0;
  404.  
  405. lin_Data[lineid][lin_rotX] = RotX;
  406. lin_Data[lineid][lin_rotY] = RotY;
  407. lin_Data[lineid][lin_rotZ] = RotZ;
  408.  
  409. UpdateLineSegment(lineid);
  410.  
  411. return 1;
  412. }
  413.  
  414. // lin_world
  415. stock GetLineSegmentWorld(lineid)
  416. {
  417. if(!Iter_Contains(lin_Index, lineid))
  418. return 0;
  419.  
  420. return lin_Data[lineid][lin_world];
  421. }
  422.  
  423. stock SetLineSegmentWorld(lineid, world)
  424. {
  425. if(!Iter_Contains(lin_Index, lineid))
  426. return 0;
  427.  
  428. lin_Data[lineid][lin_world] = world;
  429.  
  430. for(new i; i < lin_Data[lineid][lin_objCount]; i++)
  431. {
  432. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  433. Streamer_SetIntData(STREAMER_TYPE_OBJECT, lin_Objects[lineid][i], E_STREAMER_WORLD_ID, world);
  434. }
  435.  
  436. UpdateLineSegment(lineid);
  437.  
  438. return 1;
  439. }
  440.  
  441. // lin_interior
  442. stock GetLineSegmentInterior(lineid)
  443. {
  444. if(!Iter_Contains(lin_Index, lineid))
  445. return 0;
  446.  
  447. return lin_Data[lineid][lin_interior];
  448. }
  449. stock SetLineSegmentInterior(lineid, interior)
  450. {
  451. if(!Iter_Contains(lin_Index, lineid))
  452. return 0;
  453.  
  454. lin_Data[lineid][lin_interior] = interior;
  455.  
  456. for(new i; i < lin_Data[lineid][lin_objCount]; i++)
  457. {
  458. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  459. Streamer_SetIntData(STREAMER_TYPE_OBJECT, lin_Objects[lineid][i], E_STREAMER_INTERIOR_ID, interior);
  460. }
  461.  
  462. UpdateLineSegment(lineid);
  463.  
  464. return 1;
  465. }
  466.  
  467. // lin_playerid
  468. stock GetLineSegmentPlayerID(lineid)
  469. {
  470. if(!Iter_Contains(lin_Index, lineid))
  471. return 0;
  472.  
  473. return lin_Data[lineid][lin_playerid];
  474. }
  475. stock SetLineSegmentPlayerID(lineid, playerid)
  476. {
  477. if(!Iter_Contains(lin_Index, lineid))
  478. return 0;
  479.  
  480. lin_Data[lineid][lin_playerid] = playerid;
  481.  
  482. for(new i; i < lin_Data[lineid][lin_objCount]; i++)
  483. {
  484. if(IsValidDynamicObject(lin_Objects[lineid][i]))
  485. Streamer_SetIntData(STREAMER_TYPE_OBJECT, lin_Objects[lineid][i], E_STREAMER_PLAYER_ID, playerid);
  486. }
  487.  
  488. UpdateLineSegment(lineid);
  489.  
  490. return 1;
  491. }
  492.  
  493.  
  494. /*==============================================================================
  495.  
  496. Utility
  497.  
  498. ==============================================================================*/
  499.  
  500.  
  501. stock GetLineSegmentVector(lineid, &Float:x, &Float:y, &Float:z)
  502. {
  503. if(!Iter_Contains(lin_Index, lineid))
  504. return 0;
  505.  
  506. new
  507. Float:vx = lin_Data[lineid][lin_dstX] - lin_Data[lineid][lin_posX],
  508. Float:vy = lin_Data[lineid][lin_dstY] - lin_Data[lineid][lin_posY],
  509. Float:vz = lin_Data[lineid][lin_dstZ] - lin_Data[lineid][lin_posZ],
  510. Float:rx,
  511. Float:rz;
  512.  
  513. rx = -(floatabs(atan2(floatsqroot(floatpower(vx, 2.0) + floatpower(vy, 2.0)), vz))-90.0);
  514. rz = -(atan2(vy, vx)-90.0);
  515.  
  516. x = floatsin(rz, degrees) * floatcos(rx, degrees);
  517. y = floatcos(rz, degrees) * floatcos(rx, degrees);
  518. z = floatsin(rx, degrees);
  519.  
  520. return 1;
  521. }
  522.  
  523. stock Float:GetDistanceToLineSegmentPoint(lineid, Float:FromX, Float:FromY, Float:FromZ)
  524. {
  525. if(!Iter_Contains(lin_Index, lineid))
  526. return 0.0;
  527.  
  528. new
  529. Float:vx = FromX - lin_Data[lineid][lin_posX],
  530. Float:vy = FromY - lin_Data[lineid][lin_posY],
  531. Float:vz = FromZ - lin_Data[lineid][lin_posZ];
  532.  
  533. return floatsqroot( (vx * vx) + (vy * vy) + (vz * vz) );
  534. }
  535.  
  536. stock Float:GetDistanceToLineSegmentDest(lineid, Float:FromX, Float:FromY, Float:FromZ)
  537. {
  538. if(!Iter_Contains(lin_Index, lineid))
  539. return 0.0;
  540.  
  541. new
  542. Float:vx = FromX - lin_Data[lineid][lin_dstX],
  543. Float:vy = FromY - lin_Data[lineid][lin_dstY],
  544. Float:vz = FromZ - lin_Data[lineid][lin_dstZ];
  545.  
  546. return floatsqroot( (vx * vx) + (vy * vy) + (vz * vz) );
  547. }
  548.  
  549. stock Float:GetLineSegmentLength(lineid)
  550. {
  551. if(!Iter_Contains(lin_Index, lineid))
  552. return 0.0;
  553.  
  554. new
  555. Float:vx = lin_Data[lineid][lin_dstX] - lin_Data[lineid][lin_posX],
  556. Float:vy = lin_Data[lineid][lin_dstY] - lin_Data[lineid][lin_posY],
  557. Float:vz = lin_Data[lineid][lin_dstZ] - lin_Data[lineid][lin_posZ];
  558.  
  559. return floatsqroot( (vx * vx) + (vy * vy) + (vz * vz) );
  560. }
Advertisement
Add Comment
Please, Sign In to add comment