OLIGHTN.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. // Filename : OLIGHTN.CPP
  21. // Description : Lightning class
  22. // Ownership : Gilbert
  23. #include <math.h>
  24. #include <time.h>
  25. #include <OVGABUF.h>
  26. #include <OMISC.h>
  27. #include <OLIGHTN.h>
  28. #include <OWORLDMT.h>
  29. #include <COLOR.h>
  30. //------------ Define constant ----------//
  31. #define PI 3.141592654
  32. #define CORELIGHTNCOLOR (VGA_GRAY+15)
  33. #define INLIGHTNCOLOR (VGA_GRAY+13)
  34. #define OUTLIGHTNCOLOR (VGA_GRAY+10)
  35. //--------- Define static class vars --------//
  36. int Lightning::bound_x1 = ZOOM_X1+4;
  37. int Lightning::bound_y1 = ZOOM_Y1-4;
  38. int Lightning::bound_x2 = ZOOM_X2-4;
  39. int Lightning::bound_y2 = ZOOM_Y2-4;
  40. //---------- Declare static functions ----------//
  41. static double sqr(double x);
  42. //-------- Begin of static function Lightning::dist ----------//
  43. double Lightning::dist(double dx, double dy)
  44. {
  45. return sqrt( dx*dx + dy*dy);
  46. }
  47. //-------- End of static function Lightning::dist ----------//
  48. //-------- Begin of static function Lightning::set_clip ----------//
  49. void Lightning::set_clip(int x1, int y1, int x2, int y2)
  50. {
  51. bound_x1 = x1;
  52. bound_x2 = x2;
  53. bound_y1 = y1;
  54. bound_y2 = y2;
  55. }
  56. //-------- End of static function Lightning::set_clip ----------//
  57. //-------- Begin of function Lightning::~Lightning ----------//
  58. Lightning::~Lightning()
  59. {
  60. }
  61. //-------- End of function Lightning::~Lightning ----------//
  62. //-------- Begin of function Lightning::rand_seed ----------//
  63. unsigned Lightning::rand_seed()
  64. {
  65. #define MULTIPLIER 0x015a4e35L
  66. #define INCREMENT 1
  67. seed = MULTIPLIER * seed + INCREMENT;
  68. return seed;
  69. }
  70. //-------- End of function Lightning::rand_seed ----------//
  71. //-------- Begin of function Lightning::init ----------//
  72. void Lightning::init(double fromX, double fromY, double toX, double toY,
  73. char energy)
  74. {
  75. x = fromX;
  76. y = fromY;
  77. destx = toX;
  78. desty = toY;
  79. energy_level = energy;
  80. v = 6.0;
  81. expect_steps = (int)( dist(desty-y, destx-x) / v * 1.2);
  82. if( expect_steps < 2 )
  83. expect_steps = 2;
  84. steps = 0;
  85. a0 = a = 8.0;
  86. r0 = r = 8.0 * a;
  87. wide = PI / 4;
  88. seed = (unsigned)(fromX + fromY + toX + toY) | 1;
  89. (void) rand_seed();
  90. }
  91. //-------- End of function Lightning::init ----------//
  92. //-------- Begin of function Lightning::goal ----------//
  93. // return TRUE if the point is very near destination
  94. int Lightning::goal()
  95. {
  96. return( dist(destx-x, desty-y) < v );
  97. }
  98. //-------- End of function Lightning::goal ----------//
  99. //-------- Begin of function Lightning::update_parameter ----------//
  100. void Lightning::update_parameter()
  101. {
  102. double progress = (double) steps / expect_steps;
  103. if( progress > 1)
  104. progress = 1;
  105. // a = a0; // constant
  106. r = r0 * (1-progress);
  107. wide = 0.25 * ( 1 + progress ) * PI;
  108. }
  109. //-------- End of function Lightning::update_parameter ----------//
  110. //-------- Begin of function Lightning::move_particle ----------//
  111. void Lightning::move_particle()
  112. {
  113. // determine attraction
  114. double attractionDist = dist(destx-x, desty-y);
  115. if( attractionDist < v)
  116. return;
  117. double aX = a * (destx-x) / attractionDist;
  118. double aY = a * (desty-y) / attractionDist;
  119. // determine random component
  120. double attractionAngle = atan2( desty-y, destx-x);
  121. double randomAngle = ((rand_seed() & 255)/128.0-1.0)*wide+ attractionAngle;
  122. double rX = r * cos(randomAngle);
  123. double rY = r * sin(randomAngle);
  124. // total
  125. double tX = aX + rX;
  126. double tY = aY + rY;
  127. double distt = dist(tX, tY);
  128. // move x and y, along tX, tY but the magnitude is v
  129. if( distt > 0)
  130. {
  131. x += v * tX / distt;
  132. y += v * tY / distt;
  133. }
  134. steps ++;
  135. update_parameter();
  136. }
  137. //-------- End of function Lightning::move_particle ----------//
  138. //-------- Begin of function Lightning::draw_step ----------//
  139. void Lightning::draw_step(VgaBuf *vgabuf)
  140. {
  141. int prex, prey;
  142. if(!goal() )
  143. {
  144. prex = (int) x;
  145. prey = (int) y;
  146. move_particle();
  147. // BUGHERE: ignore if clipped, currently
  148. if( energy_level > 4)
  149. {
  150. if( prex >= bound_x1+2 && (int)x >= bound_x1+2 &&
  151. prex <= bound_x2-2 && (int)x <= bound_x2-2 &&
  152. prey >= bound_y1+2 && (int)y >= bound_y1+2 &&
  153. prey <= bound_y2-2 && (int)y <= bound_y2-2 )
  154. {
  155. vgabuf->line(prex+2, prey, (int) x+2, (int) y, OUTLIGHTNCOLOR);
  156. vgabuf->line(prex, prey+2, (int) x, (int) y+2, OUTLIGHTNCOLOR);
  157. vgabuf->line(prex-2, prey, (int) x-2, (int) y, OUTLIGHTNCOLOR);
  158. vgabuf->line(prex, prey-2, (int) x, (int) y-2, OUTLIGHTNCOLOR);
  159. vgabuf->line(prex+1, prey, (int) x+1, (int) y, INLIGHTNCOLOR);
  160. vgabuf->line(prex, prey+1, (int) x, (int) y+1, INLIGHTNCOLOR);
  161. vgabuf->line(prex-1, prey, (int) x-1, (int) y, INLIGHTNCOLOR);
  162. vgabuf->line(prex, prey-1, (int) x, (int) y-1, INLIGHTNCOLOR);
  163. vgabuf->line(prex, prey, (int) x, (int) y, CORELIGHTNCOLOR);
  164. }
  165. }
  166. else if( energy_level > 2)
  167. {
  168. if( prex >= bound_x1+1 && (int)x >= bound_x1+1 &&
  169. prex <= bound_x2-1 && (int)x <= bound_x2-1 &&
  170. prey >= bound_y1+1 && (int)y >= bound_y1+1 &&
  171. prey <= bound_y2-1 && (int)y <= bound_y2-1 )
  172. {
  173. vgabuf->line(prex+1, prey, (int) x+1, (int) y, OUTLIGHTNCOLOR);
  174. vgabuf->line(prex, prey+1, (int) x, (int) y+1, OUTLIGHTNCOLOR);
  175. vgabuf->line(prex, prey, (int) x, (int) y, INLIGHTNCOLOR);
  176. }
  177. }
  178. else
  179. {
  180. if( prex >= bound_x1 && (int)x >= bound_x1 &&
  181. prex <= bound_x2 && (int)x <= bound_x2 &&
  182. prey >= bound_y1 && (int)y >= bound_y1 &&
  183. prey <= bound_y2 && (int)y <= bound_y2 )
  184. {
  185. vgabuf->line(prex, prey, (int) x, (int) y, OUTLIGHTNCOLOR);
  186. }
  187. }
  188. }
  189. }
  190. //-------- End of function Lightning::draw_step ----------//
  191. //-------- Begin of function Lightning::draw_whole ----------//
  192. void Lightning::draw_whole(VgaBuf *vgabuf)
  193. {
  194. int prex, prey;
  195. while(!goal() )
  196. {
  197. prex = (int) x;
  198. prey = (int) y;
  199. move_particle();
  200. // ignore clipping, currently
  201. if( energy_level > 4)
  202. {
  203. if( prex >= bound_x1+2 && (int)x >= bound_x1+2 &&
  204. prex <= bound_x2-2 && (int)x <= bound_x2-2 &&
  205. prey >= bound_y1+2 && (int)y >= bound_y1+2 &&
  206. prey <= bound_y2-2 && (int)y <= bound_y2-2 )
  207. {
  208. vgabuf->line(prex+2, prey, (int) x+2, (int) y, OUTLIGHTNCOLOR);
  209. vgabuf->line(prex, prey+2, (int) x, (int) y+2, OUTLIGHTNCOLOR);
  210. vgabuf->line(prex-2, prey, (int) x-2, (int) y, OUTLIGHTNCOLOR);
  211. vgabuf->line(prex, prey-2, (int) x, (int) y-2, OUTLIGHTNCOLOR);
  212. vgabuf->line(prex+1, prey, (int) x+1, (int) y, INLIGHTNCOLOR);
  213. vgabuf->line(prex, prey+1, (int) x, (int) y+1, INLIGHTNCOLOR);
  214. vgabuf->line(prex-1, prey, (int) x-1, (int) y, INLIGHTNCOLOR);
  215. vgabuf->line(prex, prey-1, (int) x, (int) y-1, INLIGHTNCOLOR);
  216. vgabuf->line(prex, prey, (int) x, (int) y, CORELIGHTNCOLOR);
  217. }
  218. }
  219. else if( energy_level > 2)
  220. {
  221. if( prex >= bound_x1+1 && (int)x >= bound_x1+1 &&
  222. prex <= bound_x2-1 && (int)x <= bound_x2-1 &&
  223. prey >= bound_y1+1 && (int)y >= bound_y1+1 &&
  224. prey <= bound_y2-1 && (int)y <= bound_y2-1 )
  225. {
  226. vgabuf->line(prex+1, prey, (int) x+1, (int) y, OUTLIGHTNCOLOR);
  227. vgabuf->line(prex, prey+1, (int) x, (int) y+1, OUTLIGHTNCOLOR);
  228. vgabuf->line(prex, prey, (int) x, (int) y, INLIGHTNCOLOR);
  229. }
  230. }
  231. else
  232. {
  233. if( prex >= bound_x1 && (int)x >= bound_x1 &&
  234. prex <= bound_x2 && (int)x <= bound_x2 &&
  235. prey >= bound_y1 && (int)y >= bound_y1 &&
  236. prey <= bound_y2 && (int)y <= bound_y2 )
  237. {
  238. vgabuf->line(prex, prey, (int) x, (int) y, OUTLIGHTNCOLOR);
  239. }
  240. }
  241. }
  242. }
  243. //-------- End of function Lightning::draw_whole ----------//
  244. //-------- Begin of function Lightning::progress ----------//
  245. double Lightning::progress()
  246. {
  247. if(goal())
  248. return 1;
  249. else
  250. return (double) steps / expect_steps;
  251. }
  252. //-------- End of function Lightning::progress ----------//
  253. //-------- Begin of function Lightning::draw_section ----------//
  254. void Lightning::draw_section(VgaBuf *vgabuf, double portion)
  255. {
  256. while( progress() < ( portion< 1.0 ? portion : 1.0 ) )
  257. draw_step(vgabuf);
  258. }
  259. //-------- End of function Lightning::draw_section ----------//
  260. //-------- Begin of static function sqr ----------//
  261. static double sqr(double x)
  262. {
  263. return x*x;
  264. }
  265. //-------- End of static function sqr ----------//