Advertisement
Guest User

Untitled

a guest
Nov 19th, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.43 KB | None | 0 0
  1. Index: ai/aicode.cpp
  2. ===================================================================
  3. --- ai/aicode.cpp (revision 10126)
  4. +++ ai/aicode.cpp (working copy)
  5. @@ -12200,10 +12200,10 @@
  6. transfer_amount = 0.0f;
  7. transfer_delta = (SHIELD_BALANCE_RATE/2) * max_quadrant_strength;
  8.  
  9. - if (objp->shield_quadrant[quadrant_num] + (MAX_SHIELD_SECTIONS-1)*transfer_delta > max_quadrant_strength)
  10. - transfer_delta = (max_quadrant_strength - objp->shield_quadrant[quadrant_num])/(MAX_SHIELD_SECTIONS-1);
  11. + if (objp->shield_quadrant[quadrant_num] + (objp->n_quadrants-1)*transfer_delta > max_quadrant_strength)
  12. + transfer_delta = (max_quadrant_strength - objp->shield_quadrant[quadrant_num])/(objp->n_quadrants-1);
  13.  
  14. - for (i=0; i<MAX_SHIELD_SECTIONS; i++)
  15. + for (i=0; i<objp->n_quadrants; i++)
  16. if (i != quadrant_num) {
  17. if (objp->shield_quadrant[i] >= transfer_delta) {
  18. objp->shield_quadrant[i] -= transfer_delta;
  19. @@ -12228,17 +12228,17 @@
  20. return;
  21.  
  22.  
  23. - shield_strength_avg = shield_get_strength(objp)/MAX_SHIELD_SECTIONS;
  24. + shield_strength_avg = shield_get_strength(objp)/objp->n_quadrants;
  25.  
  26. delta = SHIELD_BALANCE_RATE * shield_strength_avg;
  27.  
  28. - for (i=0; i<MAX_SHIELD_SECTIONS; i++) {
  29. + for (i=0; i<objp->n_quadrants; i++) {
  30. if (objp->shield_quadrant[i] < shield_strength_avg) {
  31. // only do it the retail way if using smart shields (since that's a bigger thing) - taylor
  32. if (Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT)
  33. shield_add_strength(objp, delta);
  34. else
  35. - objp->shield_quadrant[i] += delta/MAX_SHIELD_SECTIONS;
  36. + objp->shield_quadrant[i] += delta/objp->n_quadrants;
  37.  
  38. if (objp->shield_quadrant[i] > shield_strength_avg)
  39. objp->shield_quadrant[i] = shield_strength_avg;
  40. @@ -12248,7 +12248,7 @@
  41. if (Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT)
  42. shield_add_strength(objp, -delta);
  43. else
  44. - objp->shield_quadrant[i] -= delta/MAX_SHIELD_SECTIONS;
  45. + objp->shield_quadrant[i] -= delta/objp->n_quadrants;
  46.  
  47. if (objp->shield_quadrant[i] < shield_strength_avg)
  48. objp->shield_quadrant[i] = shield_strength_avg;
  49. Index: hud/hudescort.cpp
  50. ===================================================================
  51. --- hud/hudescort.cpp (revision 10126)
  52. +++ hud/hudescort.cpp (working copy)
  53. @@ -246,10 +246,10 @@
  54. }
  55.  
  56. // set flashing color
  57. - if (!timestamp_elapsed(shi->shield_hit_timers[HULL_HIT_OFFSET]))
  58. + if (!timestamp_elapsed(shi->shield_hit_timers[shi->hull_hit_index]))
  59. {
  60. is_flashing = 1;
  61. - if (shi->shield_show_bright & (1 << HULL_HIT_OFFSET))
  62. + if (shi->shield_show_bright & (1 << shi->hull_hit_index))
  63. {
  64. is_bright = 1;
  65. }
  66. @@ -449,12 +449,12 @@
  67. {
  68. shi = &Escort_ships[i].hit_info;
  69.  
  70. - if (!timestamp_elapsed(shi->shield_hit_timers[HULL_HIT_OFFSET]))
  71. + if (!timestamp_elapsed(shi->shield_hit_timers[shi->hull_hit_index]))
  72. {
  73. - if (timestamp_elapsed(shi->shield_hit_next_flash[HULL_HIT_OFFSET]))
  74. + if (timestamp_elapsed(shi->shield_hit_next_flash[shi->hull_hit_index]))
  75. {
  76. - shi->shield_hit_next_flash[HULL_HIT_OFFSET] = timestamp(SHIELD_FLASH_INTERVAL);
  77. - shi->shield_show_bright ^= (1 << HULL_HIT_OFFSET); // toggle between default and bright frames
  78. + shi->shield_hit_next_flash[shi->hull_hit_index] = timestamp(SHIELD_FLASH_INTERVAL);
  79. + shi->shield_show_bright ^= (1 << shi->hull_hit_index); // toggle between default and bright frames
  80. }
  81. }
  82. }
  83. @@ -485,7 +485,7 @@
  84. }
  85. Escort_ships[i].obj_signature = -99;
  86. Escort_ships[i].np_id = -1;
  87. - shield_info_reset(&Escort_ships[i].hit_info);
  88. + shield_info_reset(&Objects[Escort_ships[i].objnum], &Escort_ships[i].hit_info);
  89. }
  90. }
  91.  
  92. @@ -720,7 +720,7 @@
  93. continue;
  94. }
  95. if ( !valid_hit_info[i] ) {
  96. - shield_info_reset(&Escort_ships[i].hit_info);
  97. + shield_info_reset(&Objects[Escort_ships[i].objnum], &Escort_ships[i].hit_info);
  98. }
  99. }
  100. }
  101. @@ -986,7 +986,7 @@
  102. num = Quadrant_xlate[quadrant];
  103. shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION);
  104. } else {
  105. - shi->shield_hit_timers[HULL_HIT_OFFSET] = timestamp(SHIELD_HIT_DURATION);
  106. + shi->shield_hit_timers[shi->hull_hit_index] = timestamp(SHIELD_HIT_DURATION);
  107. }
  108. }
  109. }
  110. Index: hud/hudets.cpp
  111. ===================================================================
  112. --- hud/hudets.cpp (revision 10126)
  113. +++ hud/hudets.cpp (working copy)
  114. @@ -107,7 +107,7 @@
  115. shield_add_strength(objp, shield_delta);
  116.  
  117. if ( (_ss = shield_get_strength(objp)) > ship_p->ship_max_shield_strength ){
  118. - for (int i=0; i<MAX_SHIELD_SECTIONS; i++){
  119. + for (int i=0; i<objp->n_quadrants; i++){
  120. objp->shield_quadrant[i] *= ship_p->ship_max_shield_strength / _ss;
  121. }
  122. }
  123. Index: hud/hudshield.cpp
  124. ===================================================================
  125. --- hud/hudshield.cpp (revision 10126)
  126. +++ hud/hudshield.cpp (working copy)
  127. @@ -117,7 +117,7 @@
  128. static shield_hit_info Shield_hit_data[2];
  129.  
  130. // translate between clockwise-from-top shield quadrant ordering to way quadrants are numbered in the game
  131. -ubyte Quadrant_xlate[MAX_SHIELD_SECTIONS] = {1,0,2,3};
  132. +ubyte Quadrant_xlate[DEFAULT_SHIELD_SECTIONS] = {1,0,2,3};
  133.  
  134. // called at the start of each level from HUD_init. Use Hud_shield_init so we only init Shield_gauges[] once.
  135. void hud_shield_level_init()
  136. @@ -125,7 +125,7 @@
  137. unsigned int i;
  138. hud_frames temp;
  139.  
  140. - hud_shield_hit_reset(1); // reset for the player
  141. + hud_shield_hit_reset(Player_obj, 1); // reset for the player
  142.  
  143. if ( !Hud_shield_inited ) {
  144. for ( i = 0; i < Hud_shield_filenames.size(); i++ ) {
  145. @@ -206,7 +206,7 @@
  146. // ------------------------------------------------------------------
  147. // hud_shield_equalize()
  148. //
  149. -// Equalize the four shield quadrants for an object
  150. +// Equalize all shield quadrants for an object
  151. //
  152. void hud_shield_equalize(object *objp, player *pl)
  153. {
  154. @@ -232,7 +232,7 @@
  155.  
  156. // are all quadrants equal?
  157. all_equal = 1;
  158. - for (idx = 0; idx < MAX_SHIELD_SECTIONS - 1; idx++) {
  159. + for (idx = 0; idx < objp->n_quadrants - 1; idx++) {
  160. if (objp->shield_quadrant[idx] != objp->shield_quadrant[idx + 1]) {
  161. all_equal = 0;
  162. break;
  163. @@ -279,14 +279,25 @@
  164. //
  165. void hud_augment_shield_quadrant(object *objp, int direction)
  166. {
  167. + Assert(objp->type == OBJ_SHIP);
  168. +
  169. + ship *shipp = &Ships[objp->instance];
  170. + ship_info *sip = &Ship_info[shipp->ship_info_index];
  171. float xfer_amount, energy_avail, percent_to_take, delta;
  172. float max_quadrant_val;
  173. int i;
  174.  
  175. - Assert(direction >= 0 && direction < MAX_SHIELD_SECTIONS);
  176. - Assert(objp->type == OBJ_SHIP);
  177. + if (sip->flags2 & SIF2_SHIELD_POINTS) {
  178. + direction = sip->shield_point_augment_ctrls[direction];
  179. +
  180. + // The re-mapped direction can be -1 if this direction cannot be augmented
  181. + if (direction < 0)
  182. + return;
  183. + }
  184. +
  185. + Assert(direction >= 0 && direction < objp->n_quadrants);
  186.  
  187. - xfer_amount = Ships[objp->instance].ship_max_shield_strength * SHIELD_TRANSFER_PERCENT;
  188. + xfer_amount = shipp->ship_max_shield_strength * SHIELD_TRANSFER_PERCENT;
  189. max_quadrant_val = get_max_shield_quad(objp);
  190.  
  191. if ( (objp->shield_quadrant[direction] + xfer_amount) > max_quadrant_val )
  192. @@ -302,7 +313,7 @@
  193. }
  194.  
  195. energy_avail = 0.0f;
  196. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  197. + for ( i = 0; i < objp->n_quadrants; i++ ) {
  198. if ( i == direction )
  199. continue;
  200. energy_avail += objp->shield_quadrant[i];
  201. @@ -312,7 +323,7 @@
  202. if ( percent_to_take > 1.0f )
  203. percent_to_take = 1.0f;
  204.  
  205. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  206. + for ( i = 0; i < objp->n_quadrants; i++ ) {
  207. if ( i == direction )
  208. continue;
  209. delta = percent_to_take * objp->shield_quadrant[i];
  210. @@ -409,25 +420,25 @@
  211. sy = (y_force == -1) ? Shield_mini_coords[gr_screen.res][1]+fl2i(HUD_offset_y) : y_force;
  212.  
  213. // draw the ship first
  214. - hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_HIT_TARGET, HULL_HIT_OFFSET);
  215. + hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_HIT_TARGET, Shield_hit_data[SHIELD_HIT_TARGET].hull_hit_index);
  216. hud_show_mini_ship_integrity(objp, x_force + x_hull_offset,y_force + y_hull_offset);
  217.  
  218. // draw the four quadrants
  219. // Draw shield quadrants at one of NUM_SHIELD_LEVELS
  220. max_shield = get_max_shield_quad(objp);
  221.  
  222. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  223. + for ( i = 0; i < objp->n_quadrants; i++ ) {
  224.  
  225. - if ( objp->flags & OF_NO_SHIELDS ) {
  226. + if ( objp->flags & OF_NO_SHIELDS || i >= DEFAULT_SHIELD_SECTIONS) {
  227. break;
  228. }
  229.  
  230. - if ( objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f ) {
  231. + if (objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f ) {
  232. continue;
  233. }
  234.  
  235. if ( hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_HIT_TARGET, i) ) {
  236. - frame_offset = i+MAX_SHIELD_SECTIONS;
  237. + frame_offset = i+objp->n_quadrants;
  238. } else {
  239. frame_offset = i;
  240. }
  241. @@ -458,13 +469,20 @@
  242. }
  243.  
  244. // reset the shield_hit_info data structure
  245. -void shield_info_reset(shield_hit_info *shi)
  246. +void shield_info_reset(object *objp, shield_hit_info *shi)
  247. {
  248. int i;
  249.  
  250. shi->shield_hit_status = 0;
  251. shi->shield_show_bright = 0;
  252. - for ( i = 0; i < NUM_SHIELD_HIT_MEMBERS; i++ ) {
  253. +
  254. + shi->members = objp->n_quadrants + 1;
  255. + shi->hull_hit_index = shi->members - 1;
  256. +
  257. + shi->shield_hit_timers.resize(shi->members);
  258. + shi->shield_hit_next_flash.resize(shi->members);
  259. +
  260. + for ( i = 0; i < shi->members; i++ ) {
  261. shi->shield_hit_timers[i] = 1;
  262. shi->shield_hit_next_flash[i] = 1;
  263. }
  264. @@ -477,7 +495,7 @@
  265. // input: player => optional parameter (default value 0). This is to indicate that player shield hit
  266. // info should be reset. This is normally not the case.
  267. // is for the player's current target
  268. -void hud_shield_hit_reset(int player)
  269. +void hud_shield_hit_reset(object *objp, int player)
  270. {
  271. shield_hit_info *shi;
  272.  
  273. @@ -487,7 +505,7 @@
  274. shi = &Shield_hit_data[SHIELD_HIT_TARGET];
  275. }
  276.  
  277. - shield_info_reset(shi);
  278. + shield_info_reset(objp, shi);
  279. }
  280.  
  281. // called once per frame to update the state of Shield_hit_status based on the Shield_hit_timers[]
  282. @@ -501,7 +519,7 @@
  283. }
  284.  
  285. for ( i = 0; i < limit; i++ ) {
  286. - for ( j = 0; j < NUM_SHIELD_HIT_MEMBERS; j++ ) {
  287. + for ( j = 0; j < Shield_hit_data[i].members; j++ ) {
  288. if ( timestamp_elapsed(Shield_hit_data[i].shield_hit_timers[j]) ) {
  289. Shield_hit_data[i].shield_hit_status &= ~(1<<j);
  290. Shield_hit_data[i].shield_show_bright &= ~(1<<j);
  291. @@ -541,10 +559,14 @@
  292. }
  293.  
  294. if ( quadrant >= 0 ) {
  295. - num = Quadrant_xlate[quadrant];
  296. + if ( !(Ship_info[Ships[objp->instance].ship_info_index].flags2 & SIF2_SHIELD_POINTS) )
  297. + num = Quadrant_xlate[quadrant];
  298. + else
  299. + num = quadrant;
  300. +
  301. shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION_SHORT);
  302. } else {
  303. - shi->shield_hit_timers[HULL_HIT_OFFSET] = timestamp(SHIELD_HIT_DURATION_SHORT);
  304. + shi->shield_hit_timers[shi->hull_hit_index] = timestamp(SHIELD_HIT_DURATION_SHORT);
  305. hud_targetbox_start_flash(TBOX_FLASH_HULL);
  306. }
  307. }
  308. @@ -613,7 +635,7 @@
  309. sy += fl2i(HUD_offset_y);
  310.  
  311. // draw the ship first
  312. - maybeFlashShield(SHIELD_HIT_PLAYER, HULL_HIT_OFFSET);
  313. + maybeFlashShield(SHIELD_HIT_PLAYER, Shield_hit_data[SHIELD_HIT_PLAYER].hull_hit_index);
  314.  
  315. if(sip->shield_icon_index != 255)
  316. {
  317. @@ -687,25 +709,33 @@
  318. if(!sip->max_shield_strength)
  319. return;
  320.  
  321. - // draw the four quadrants
  322. + // draw the quadrants
  323. //
  324. // Draw shield quadrants at one of NUM_SHIELD_LEVELS
  325. max_shield = get_max_shield_quad(objp);
  326.  
  327. coord2d shield_icon_coords[6];
  328.  
  329. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  330. + for ( i = 0; i < objp->n_quadrants; i++ ) {
  331.  
  332. if ( objp->flags & OF_NO_SHIELDS ) {
  333. break;
  334. }
  335.  
  336. - if ( objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f ) {
  337. - continue;
  338. - }
  339. + if ( !(sip->flags2 & SIF2_SHIELD_POINTS) )
  340. + if ( objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f )
  341. + continue;
  342. + else
  343. + if ( objp->shield_quadrant[i] < 0.1f )
  344. + continue;
  345.  
  346. range = MAX(HUD_COLOR_ALPHA_MAX, HUD_color_alpha + 4);
  347. - hud_color_index = fl2i( (objp->shield_quadrant[Quadrant_xlate[i]] / max_shield) * range);
  348. +
  349. + if ( !(sip->flags2 & SIF2_SHIELD_POINTS) )
  350. + hud_color_index = fl2i( (objp->shield_quadrant[Quadrant_xlate[i]] / max_shield) * range);
  351. + else
  352. + hud_color_index = fl2i( (objp->shield_quadrant[i] / max_shield) * range);
  353. +
  354. Assert(hud_color_index >= 0 && hud_color_index <= range);
  355.  
  356. if ( hud_color_index < 0 ) {
  357. @@ -726,7 +756,9 @@
  358.  
  359. if(sip->shield_icon_index != 255)
  360. {
  361. - renderBitmap(sgp->first_frame+i+1, sx, sy);
  362. + int framenum = sgp->first_frame+i+1;
  363. + if (framenum < sgp->first_frame+sgp->num_frames)
  364. + renderBitmap(framenum, sx, sy);
  365. }
  366. else
  367. {
  368. @@ -962,14 +994,14 @@
  369. sy = position[1]+fl2i(HUD_offset_y);
  370.  
  371. // draw the ship first
  372. - maybeFlashShield(SHIELD_HIT_TARGET, HULL_HIT_OFFSET);
  373. + maybeFlashShield(SHIELD_HIT_TARGET, Shield_hit_data[SHIELD_HIT_TARGET].hull_hit_index);
  374. showIntegrity(get_hull_pct(objp));
  375.  
  376. // draw the four quadrants
  377. // Draw shield quadrants at one of NUM_SHIELD_LEVELS
  378. max_shield = get_max_shield_quad(objp);
  379.  
  380. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  381. + for ( i = 0; i < objp->n_quadrants; i++ ) {
  382.  
  383. if ( objp->flags & OF_NO_SHIELDS ) {
  384. break;
  385. @@ -980,7 +1012,7 @@
  386. }
  387.  
  388. if ( maybeFlashShield(SHIELD_HIT_TARGET, i) ) {
  389. - frame_offset = i+MAX_SHIELD_SECTIONS;
  390. + frame_offset = i+objp->n_quadrants;
  391. } else {
  392. frame_offset = i;
  393. }
  394. @@ -1004,7 +1036,8 @@
  395. setGaugeColor(hud_color_index);
  396. }
  397.  
  398. - renderBitmap(Shield_mini_gauge.first_frame + frame_offset, sx, sy);
  399. + if (frame_offset < Shield_mini_gauge.num_frames)
  400. + renderBitmap(Shield_mini_gauge.first_frame + frame_offset, sx, sy);
  401. }
  402.  
  403. // hud_set_default_color();
  404. Index: hud/hudshield.h
  405. ===================================================================
  406. --- hud/hudshield.h (revision 10126)
  407. +++ hud/hudshield.h (working copy)
  408. @@ -18,12 +18,12 @@
  409. #define SHIELD_HIT_DURATION 1400 // time a shield quadrant flashes after being hit
  410. #define SHIELD_FLASH_INTERVAL 200 // time between shield quadrant flashes
  411.  
  412. -#define NUM_SHIELD_HIT_MEMBERS 5
  413. -#define HULL_HIT_OFFSET 4 // used to access the members in shield_hit_info that pertain to the hull
  414. typedef struct shield_hit_info
  415. {
  416. - int shield_hit_timers[NUM_SHIELD_HIT_MEMBERS]; // timestamps that get set for SHIELD_FLASH_TIME when a quadrant is hit
  417. - int shield_hit_next_flash[NUM_SHIELD_HIT_MEMBERS];
  418. + int members;
  419. + int hull_hit_index; // used to access the members in shield_hit_info that pertain to the hull
  420. + SCP_vector<int> shield_hit_timers; // timestamps that get set for SHIELD_FLASH_TIME when a quadrant is hit
  421. + SCP_vector<int> shield_hit_next_flash;
  422. int shield_hit_status; // bitfield, if offset for shield quadrant is set, that means shield is being hit
  423. int shield_show_bright; // bitfield, if offset for shield quadrant is set, that means play bright frame
  424. } shield_hit_info;
  425. @@ -44,9 +44,9 @@
  426. void hud_shield_show_mini(object *objp, int x_force = -1, int y_force = -1, int x_hull_offset = 0, int y_hull_offset = 0);
  427. void hud_shield_hit_update();
  428. void hud_shield_quadrant_hit(object *objp, int quadrant);
  429. -void hud_shield_hit_reset(int player=0);
  430. +void hud_shield_hit_reset(object *objp, int player=0);
  431.  
  432. -void shield_info_reset(shield_hit_info *shi);
  433. +void shield_info_reset(object *objp, shield_hit_info *shi);
  434.  
  435. // random page in stuff - moved here by Goober5000
  436. extern void hud_ship_icon_page_in(ship_info *sip);
  437. Index: hud/hudtarget.cpp
  438. ===================================================================
  439. --- hud/hudtarget.cpp (revision 10126)
  440. +++ hud/hudtarget.cpp (working copy)
  441. @@ -946,6 +946,7 @@
  442.  
  443. if ( Player_obj != target->objp ){
  444. set_target_objnum( Player_ai, OBJ_INDEX(target->objp) );
  445. + hud_shield_hit_reset(target->objp);
  446. }
  447.  
  448. Players[Player_num].current_hotkey_set = k;
  449. @@ -1223,6 +1224,7 @@
  450. if ( Player_ai->target_objnum != A-Objects ) {
  451. target_found = TRUE;
  452. set_target_objnum( Player_ai, OBJ_INDEX(A) );
  453. + hud_shield_hit_reset(A);
  454. // if ship is BIG|HUGE and last subsys is NULL, get turret
  455. hud_maybe_set_sorted_turret_subsys(shipp);
  456. hud_restore_subsystem_target(shipp);
  457. @@ -1230,6 +1232,7 @@
  458. } else {
  459. target_found = TRUE;
  460. set_target_objnum( Player_ai, OBJ_INDEX(A) );
  461. + hud_shield_hit_reset(A);
  462. }
  463.  
  464. break;
  465. @@ -1479,6 +1482,7 @@
  466. // if we've reached here, got a new target
  467. target_found = TRUE;
  468. set_target_objnum( aip, OBJ_INDEX(A) );
  469. + hud_shield_hit_reset(A);
  470. break;
  471. } // end for
  472.  
  473. @@ -1526,6 +1530,7 @@
  474. // found a good one
  475. target_found = TRUE;
  476. set_target_objnum( aip, OBJ_INDEX(A) );
  477. + hud_shield_hit_reset(A);
  478. break;
  479. }
  480. }
  481. @@ -1600,6 +1605,7 @@
  482. if ( Player_ai->target_objnum != OBJ_INDEX(A) ) {
  483. target_found = TRUE;
  484. set_target_objnum( Player_ai, OBJ_INDEX(A) );
  485. + hud_shield_hit_reset(A);
  486. }
  487. }
  488.  
  489. @@ -1661,6 +1667,7 @@
  490.  
  491. if (newest_obj) {
  492. set_target_objnum( Player_ai, OBJ_INDEX(newest_obj) );
  493. + hud_shield_hit_reset(newest_obj);
  494. // if BIG|HUGE and no selected subsystem, get sorted turret
  495. hud_maybe_set_sorted_turret_subsys(&Ships[newest_obj->instance]);
  496. hud_restore_subsystem_target(&Ships[newest_obj->instance]);
  497. @@ -1950,6 +1957,7 @@
  498. if (nearest_dist < 10000.0f) {
  499. Assert(nearest_obj);
  500. set_target_objnum( Player_ai, OBJ_INDEX(nearest_obj) );
  501. + hud_shield_hit_reset(nearest_obj);
  502. target_found = TRUE;
  503. }
  504.  
  505. @@ -2285,6 +2293,7 @@
  506.  
  507. if (target_found) {
  508. set_target_objnum(Player_ai, OBJ_INDEX(nearest_obj));
  509. + hud_shield_hit_reset(nearest_obj);
  510. if ( check_nearest_turret ) {
  511.  
  512. // if former subobject was not a turret do, not change subsystem
  513. @@ -2415,6 +2424,7 @@
  514.  
  515. // if we've reached here, found player target's target
  516. set_target_objnum( Player_ai, tt_objnum );
  517. + hud_shield_hit_reset(&Objects[tt_objnum]);
  518. if (Objects[tt_objnum].type == OBJ_SHIP) {
  519. hud_maybe_set_sorted_turret_subsys(&Ships[Objects[tt_objnum].instance]);
  520. }
  521. @@ -2636,6 +2646,7 @@
  522. target_obj = hud_reticle_pick_target();
  523. if ( target_obj != NULL ) {
  524. set_target_objnum( Player_ai, OBJ_INDEX(target_obj) );
  525. + hud_shield_hit_reset(target_obj);
  526. if ( target_obj->type == OBJ_SHIP ) {
  527. // if BIG|HUGE, maybe set subsys to turret
  528. hud_maybe_set_sorted_turret_subsys(&Ships[target_obj->instance]);
  529. @@ -4429,7 +4440,7 @@
  530. }
  531.  
  532. player_stop_cargo_scan_sound();
  533. - hud_shield_hit_reset();
  534. + hud_shield_hit_reset(&Objects[Player_ai->target_objnum]);
  535. hud_targetbox_init_flash();
  536. hud_targetbox_start_flash(TBOX_FLASH_NAME);
  537. hud_gauge_popup_start(HUD_TARGET_MINI_ICON);
  538. @@ -4662,6 +4673,7 @@
  539. if (nearest_object != NULL) {
  540. // set new target
  541. set_target_objnum( Player_ai, OBJ_INDEX(nearest_object) );
  542. + hud_shield_hit_reset(nearest_object);
  543.  
  544. // maybe set new turret subsystem
  545. hud_maybe_set_sorted_turret_subsys(&Ships[nearest_object->instance]);
  546. @@ -4894,6 +4906,7 @@
  547.  
  548. if (nearest_obj != &obj_used_list) {
  549. set_target_objnum( Player_ai, OBJ_INDEX(nearest_obj) );
  550. + hud_shield_hit_reset(nearest_obj);
  551. hud_restore_subsystem_target(&Ships[nearest_obj->instance]);
  552. rval=1;
  553. }
  554. @@ -4956,6 +4969,7 @@
  555.  
  556. if (nearest_obj != NULL) {
  557. set_target_objnum( Player_ai, OBJ_INDEX(nearest_obj) );
  558. + hud_shield_hit_reset(nearest_obj);
  559. hud_restore_subsystem_target(&Ships[nearest_obj->instance]);
  560. }
  561. else {
  562. @@ -5058,6 +5072,7 @@
  563.  
  564. if (nearest_obj != NULL) {
  565. set_target_objnum( Player_ai, OBJ_INDEX(nearest_obj) );
  566. + hud_shield_hit_reset(nearest_obj);
  567. hud_restore_subsystem_target(&Ships[nearest_obj->instance]);
  568. }
  569. else {
  570. @@ -5177,6 +5192,7 @@
  571.  
  572. if ((targeted_objnum >= 0) && (targeted_objnum < MAX_OBJECTS)) {
  573. set_target_objnum( Player_ai, Transmit_target_list[transmit_index].objnum );
  574. + hud_shield_hit_reset(&Objects[Transmit_target_list[transmit_index].objnum]);
  575. hud_restore_subsystem_target(&Ships[Objects[Transmit_target_list[transmit_index].objnum].instance]);
  576. }
  577. }
  578. @@ -5223,6 +5239,7 @@
  579. set_target_objnum(Player_ai, -1);
  580. } else {
  581. set_target_objnum(Player_ai, objnum);
  582. + hud_shield_hit_reset(&Objects[objnum]);
  583. }
  584. }
  585. }
  586. Index: io/keycontrol.cpp
  587. ===================================================================
  588. --- io/keycontrol.cpp (revision 10126)
  589. +++ io/keycontrol.cpp (working copy)
  590. @@ -58,6 +58,7 @@
  591. #include "network/multi_endgame.h"
  592. #include "autopilot/autopilot.h"
  593. #include "cmdline/cmdline.h"
  594. +#include "object/objectshield.h"
  595.  
  596. #define MAX_NUM_SLOTS 6
  597.  
  598. @@ -1954,28 +1955,28 @@
  599. if(at_self){
  600. control_used(SHIELD_XFER_TOP);
  601. }
  602. - hud_augment_shield_quadrant(objp, 1);
  603. + hud_augment_shield_quadrant(objp, FRONT_QUAD);
  604. break;
  605.  
  606. // transfer shield energy to rear
  607. case SHIELD_XFER_BOTTOM:
  608. if(at_self)
  609. control_used(SHIELD_XFER_BOTTOM);
  610. - hud_augment_shield_quadrant(objp, 2);
  611. + hud_augment_shield_quadrant(objp, REAR_QUAD);
  612. break;
  613.  
  614. // transfer shield energy to left
  615. case SHIELD_XFER_LEFT:
  616. if(at_self)
  617. control_used(SHIELD_XFER_LEFT);
  618. - hud_augment_shield_quadrant(objp, 3);
  619. + hud_augment_shield_quadrant(objp, LEFT_QUAD);
  620. break;
  621.  
  622. // transfer shield energy to right
  623. case SHIELD_XFER_RIGHT:
  624. if(at_self)
  625. control_used(SHIELD_XFER_RIGHT);
  626. - hud_augment_shield_quadrant(objp, 0);
  627. + hud_augment_shield_quadrant(objp, RIGHT_QUAD);
  628. break;
  629.  
  630. // transfer energy to shield from weapons
  631. Index: mission/missionparse.cpp
  632. ===================================================================
  633. --- mission/missionparse.cpp (revision 10126)
  634. +++ mission/missionparse.cpp (working copy)
  635. @@ -2236,7 +2236,7 @@
  636. int max_allowed_sparks, num_sparks, iLoop;
  637.  
  638. Objects[objnum].hull_strength = p_objp->initial_hull * shipp->ship_max_hull_strength / 100.0f;
  639. - for (iLoop = 0; iLoop<MAX_SHIELD_SECTIONS; iLoop++)
  640. + for (iLoop = 0; iLoop<Objects[objnum].n_quadrants; iLoop++)
  641. {
  642. Objects[objnum].shield_quadrant[iLoop] = (float) (p_objp->initial_shields * get_max_shield_quad(&Objects[objnum]) / 100.0f);
  643. }
  644. Index: model/model.h
  645. ===================================================================
  646. --- model/model.h (revision 10126)
  647. +++ model/model.h (working copy)
  648. @@ -381,10 +381,13 @@
  649.  
  650. vec3d render_box_min;
  651. vec3d render_box_max;
  652. + vec3d render_box_offset;
  653. float render_sphere_radius;
  654. vec3d render_sphere_offset;
  655. int use_render_box; // 0==do nothing, 1==only render this object if you are inside the box, -1==only if you're outside
  656. + bool use_render_box_offset; // whether an offset has been defined; needed because one can't tell just by looking at render_box_offset
  657. int use_render_sphere; // 0==do nothing, 1==only render this object if you are inside the sphere, -1==only if you're outside
  658. + bool use_render_sphere_offset;// whether an offset has been defined; needed because one can't tell just by looking at render_sphere_offset
  659. bool gun_rotation; // for animated weapon models
  660. bool no_collisions; // for $no_collisions property - kazan
  661. bool nocollide_this_only; //SUSHI: Like no_collisions, but not recursive. For the "replacement" collision model scheme.
  662. @@ -733,6 +736,7 @@
  663. shield_info shield; // new shield information
  664. ubyte *shield_collision_tree;
  665. int sldc_size;
  666. + SCP_vector<vec3d> shield_points;
  667.  
  668. int n_paths;
  669. model_path *paths;
  670. Index: model/modelread.cpp
  671. ===================================================================
  672. --- model/modelread.cpp (revision 10126)
  673. +++ model/modelread.cpp (working copy)
  674. @@ -2050,8 +2050,11 @@
  675. char type[64];
  676.  
  677. get_user_prop_value(p+9, type);
  678. - if ( !stricmp(type, "subsystem") ) // if we have a subsystem, put it into the list!
  679. + if ( !stricmp(type, "subsystem") ) { // if we have a subsystem, put it into the list!
  680. do_new_subsystem( n_subsystems, subsystems, -1, radius, &pnt, props_spcl, &name[1], pm->id ); // skip the first '$' character of the name
  681. + } else if ( !stricmp(type, "shieldpoint") ) {
  682. + pm->shield_points.push_back(pnt);
  683. + }
  684. } else if ( strstr(name, "$enginelarge") || strstr(name, "$enginehuge") ){
  685. do_new_subsystem( n_subsystems, subsystems, -1, radius, &pnt, props_spcl, &name[1], pm->id ); // skip the first '$' character of the name
  686. } else {
  687. Index: network/multi_ingame.cpp
  688. ===================================================================
  689. --- network/multi_ingame.cpp (revision 10126)
  690. +++ network/multi_ingame.cpp (working copy)
  691. @@ -1818,10 +1818,11 @@
  692. objp = &Objects[sp->objnum];
  693. ADD_USHORT(objp->net_signature);
  694. ADD_UINT(objp->flags);
  695. + ADD_INT(objp->n_quadrants);
  696. ADD_FLOAT(objp->hull_strength);
  697.  
  698. // shield percentages
  699. - for(idx=0; idx<MAX_SHIELD_SECTIONS; idx++){
  700. + for(idx=0; idx<objp->n_quadrants; idx++){
  701. f_tmp = objp->shield_quadrant[idx];
  702. ADD_FLOAT(f_tmp);
  703. }
  704. @@ -1835,6 +1836,7 @@
  705. float garbage;
  706. int flags;
  707. int idx;
  708. + int n_quadrants;
  709. ushort net_sig;
  710. object *lookup;
  711. float f_tmp;
  712. @@ -1843,14 +1845,15 @@
  713. // get the net sig for the ship and do a lookup
  714. GET_USHORT(net_sig);
  715. GET_INT(flags);
  716. -
  717. + GET_INT(n_quadrants);
  718. +
  719. // get the object
  720. lookup = multi_get_network_object(net_sig);
  721. if(lookup == NULL){
  722. // read in garbage values if we can't find the ship
  723. nprintf(("Network","Got ingame ship update for unknown object\n"));
  724. GET_FLOAT(garbage);
  725. - for(idx=0;idx<MAX_SHIELD_SECTIONS;idx++){
  726. + for(idx=0;idx<n_quadrants;idx++){
  727. GET_FLOAT(garbage);
  728. }
  729.  
  730. @@ -1859,8 +1862,9 @@
  731. }
  732. // otherwise read in the ship values
  733. lookup->flags = flags;
  734. + lookup->n_quadrants = n_quadrants;
  735. GET_FLOAT(lookup->hull_strength);
  736. - for(idx=0;idx<MAX_SHIELD_SECTIONS;idx++){
  737. + for(idx=0;idx<n_quadrants;idx++){
  738. GET_FLOAT(f_tmp);
  739. lookup->shield_quadrant[idx] = f_tmp;
  740. }
  741. Index: network/multi_obj.cpp
  742. ===================================================================
  743. --- network/multi_obj.cpp (revision 10126)
  744. +++ network/multi_obj.cpp (working copy)
  745. @@ -455,25 +455,12 @@
  746.  
  747. float quad = get_max_shield_quad(objp);
  748.  
  749. - // pack 2 shield values into each byte
  750. -
  751. - // pack quadrant 1
  752. - temp = (objp->shield_quadrant[0] / quad);
  753. - PACK_PERCENT(temp);
  754. + for (int i = 0; i < objp->n_quadrants; i++) {
  755. + temp = (objp->shield_quadrant[i] / quad);
  756. + PACK_PERCENT(temp);
  757. + }
  758.  
  759. - // pack quadrant 2
  760. - temp = (objp->shield_quadrant[1] / quad);
  761. - PACK_PERCENT(temp);
  762. -
  763. - // pack quadrant 3
  764. - temp = (objp->shield_quadrant[2] / quad);
  765. - PACK_PERCENT(temp);
  766. -
  767. - // pack quadrant 2
  768. - temp = (objp->shield_quadrant[3] / quad);
  769. - PACK_PERCENT(temp);
  770. -
  771. - multi_rate_add(NET_PLAYER_NUM(pl), "shl", 4);
  772. + multi_rate_add(NET_PLAYER_NUM(pl), "shl", objp->n_quadrants);
  773. }
  774.  
  775. // subsystem info
  776. @@ -874,20 +861,12 @@
  777. UNPACK_PERCENT(fpct);
  778. pobjp->hull_strength = fpct * Ships[pobjp->instance].ship_max_hull_strength;
  779.  
  780. - float shield_0, shield_1, shield_2, shield_3;
  781. -
  782. - // unpack the 4 quadrants
  783. - UNPACK_PERCENT(shield_0);
  784. - UNPACK_PERCENT(shield_1);
  785. - UNPACK_PERCENT(shield_2);
  786. - UNPACK_PERCENT(shield_3);
  787. -
  788. float quad = get_max_shield_quad(pobjp);
  789.  
  790. - pobjp->shield_quadrant[0] = (shield_0 * quad);
  791. - pobjp->shield_quadrant[1] = (shield_1 * quad);
  792. - pobjp->shield_quadrant[2] = (shield_2 * quad);
  793. - pobjp->shield_quadrant[3] = (shield_3 * quad);
  794. + for (int i = 0; i < pobjp->n_quadrants; i++) {
  795. + UNPACK_PERCENT(fpct);
  796. + pobjp->shield_quadrant[i] = fpct * quad;
  797. + }
  798. }
  799.  
  800. if ( oo_flags & OO_SUBSYSTEMS_AND_AI_NEW ) {
  801. Index: network/multimsgs.cpp
  802. ===================================================================
  803. --- network/multimsgs.cpp (revision 10126)
  804. +++ network/multimsgs.cpp (working copy)
  805. @@ -7000,7 +7000,7 @@
  806. // when not paused, send hull/shield/subsystem updates to all clients (except for ingame joiners)
  807. if ( val & UPDATE_HULL_INFO ) {
  808. object *objp;
  809. - ubyte percent, ns, threats;
  810. + ubyte percent, ns, threats, n_quadrants;
  811. ship_info *sip;
  812. ship *shipp;
  813. ship_subsys *subsysp;
  814. @@ -7023,8 +7023,11 @@
  815. }
  816. ADD_DATA( percent );
  817.  
  818. - for (i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  819. + n_quadrants = (ubyte)objp->n_quadrants;
  820. + ADD_DATA( n_quadrants );
  821. + for (i = 0; i < n_quadrants; i++ ) {
  822. percent = (ubyte)(objp->shield_quadrant[i] / get_max_shield_quad(objp) * 100.0f);
  823. +
  824. ADD_DATA( percent );
  825. }
  826.  
  827. @@ -7098,7 +7101,8 @@
  828. float fl_val;
  829. ship_info *sip;
  830. ship *shipp;
  831. - ubyte hull_percent, shield_percent[MAX_SHIELD_SECTIONS], n_subsystems, subsystem_percent[MAX_MODEL_SUBSYSTEMS], threats;
  832. + ubyte hull_percent, n_quadrants, n_subsystems, subsystem_percent[MAX_MODEL_SUBSYSTEMS], threats;
  833. + SCP_vector<ubyte> shield_percent;
  834. ubyte ub_tmp;
  835. ship_subsys *subsysp;
  836. object *objp;
  837. @@ -7108,7 +7112,9 @@
  838. // percentage value since that should be close enough
  839. GET_DATA( hull_percent );
  840.  
  841. - for (i = 0; i < MAX_SHIELD_SECTIONS; i++ ){
  842. + GET_DATA( n_quadrants );
  843. + shield_percent.resize(n_quadrants);
  844. + for (i = 0; i < n_quadrants; i++ ){
  845. GET_DATA(ub_tmp);
  846. shield_percent[i] = ub_tmp;
  847. }
  848. @@ -7142,9 +7148,11 @@
  849. fl_val = hull_percent * shipp->ship_max_hull_strength / 100.0f;
  850. objp->hull_strength = fl_val;
  851.  
  852. - for ( i = 0; i < MAX_SHIELD_SECTIONS; i++ ) {
  853. - fl_val = (shield_percent[i] * get_max_shield_quad(objp) / 100.0f);
  854. - objp->shield_quadrant[i] = fl_val;
  855. + for ( i = 0; i < n_quadrants; i++ ) {
  856. + if (i < objp->n_quadrants) {
  857. + fl_val = (shield_percent[i] * get_max_shield_quad(objp) / 100.0f);
  858. + objp->shield_quadrant[i] = fl_val;
  859. + }
  860. }
  861.  
  862. // for sanity, be sure that the number of susbystems that I read in matches the player. If not,
  863. Index: object/collideshipship.cpp
  864. ===================================================================
  865. --- object/collideshipship.cpp (revision 10126)
  866. +++ object/collideshipship.cpp (working copy)
  867. @@ -937,7 +937,7 @@
  868.  
  869. vm_vec_sub(&tpos, global_pos, &objp->pos);
  870. vm_vec_rotate(&rotpos, &tpos, &objp->orient);
  871. - return get_quadrant(&rotpos);
  872. + return get_quadrant(&rotpos, objp);
  873. }
  874.  
  875. #define MIN_REL_SPEED_FOR_LOUD_COLLISION 50 // relative speed of two colliding objects at which we play the "loud" collide sound
  876. Index: object/collideshipweapon.cpp
  877. ===================================================================
  878. --- object/collideshipweapon.cpp (revision 10126)
  879. +++ object/collideshipweapon.cpp (working copy)
  880. @@ -326,7 +326,7 @@
  881.  
  882. if (shield_collision) {
  883. // pick out the shield quadrant
  884. - quadrant_num = get_quadrant(&mc_shield.hit_point);
  885. + quadrant_num = get_quadrant(&mc_shield.hit_point, ship_objp);
  886.  
  887. // make sure that the shield is active in that quadrant
  888. if (shipp->flags & SF_DYING || !ship_is_shield_up(ship_objp, quadrant_num))
  889. Index: object/object.cpp
  890. ===================================================================
  891. --- object/object.cpp (revision 10126)
  892. +++ object/object.cpp (working copy)
  893. @@ -129,7 +129,7 @@
  894. orient = last_orient = vmd_identity_matrix;
  895. radius = hull_strength = sim_hull_strength = 0.0f;
  896. physics_init( &phys_info );
  897. - memset(shield_quadrant, 0, MAX_SHIELD_SECTIONS * sizeof(float));
  898. + shield_quadrant.clear();
  899. objsnd_num.clear();
  900. net_signature = 0;
  901.  
  902. @@ -259,7 +259,7 @@
  903. return 0.0f;
  904. }
  905.  
  906. - return Ships[objp->instance].ship_max_shield_strength / MAX_SHIELD_SECTIONS;
  907. + return Ships[objp->instance].ship_max_shield_strength / objp->n_quadrants;
  908. }
  909.  
  910. // Goober5000
  911. @@ -503,6 +503,8 @@
  912. }
  913. obj->radius = radius;
  914.  
  915. + obj->n_quadrants = DEFAULT_SHIELD_SECTIONS; // Might be changed by the ship creation code
  916. + obj->shield_quadrant.resize(obj->n_quadrants);
  917. return objnum;
  918. }
  919.  
  920. Index: object/object.h
  921. ===================================================================
  922. --- object/object.h (revision 10126)
  923. +++ object/object.h (working copy)
  924. @@ -21,7 +21,7 @@
  925. * CONSTANTS
  926. */
  927.  
  928. -#define MAX_SHIELD_SECTIONS 4 // Number of sections in shield.
  929. +#define DEFAULT_SHIELD_SECTIONS 4 // Number of sections in standard shields.
  930.  
  931. #ifndef NDEBUG
  932. #define OBJECT_CHECK
  933. @@ -154,7 +154,8 @@
  934. vec3d last_pos; // where object was last frame
  935. matrix last_orient; // how the object was oriented last frame
  936. physics_info phys_info; // a physics object
  937. - float shield_quadrant[MAX_SHIELD_SECTIONS]; // Shield is broken into components. Quadrants on 4/24/97.
  938. + int n_quadrants; // how many shield quadrants the ship has
  939. + SCP_vector<float> shield_quadrant; // Shield is broken into components, quadrants by default.
  940. float hull_strength; // Remaining hull strength.
  941. float sim_hull_strength; // Simulated hull strength - used with training weapons.
  942. SCP_vector<int> objsnd_num; // Index of persistant sound struct.
  943. Index: object/objectshield.cpp
  944. ===================================================================
  945. --- object/objectshield.cpp (revision 10126)
  946. +++ object/objectshield.cpp (working copy)
  947. @@ -27,7 +27,7 @@
  948. int i;
  949. float strength = 0.0f;
  950.  
  951. - for (i = 0; i < MAX_SHIELD_SECTIONS; i++)
  952. + for (i = 0; i < objp->n_quadrants; i++)
  953. strength += shield_get_quad(objp, i);
  954.  
  955. return strength;
  956. @@ -37,12 +37,12 @@
  957. {
  958. int i;
  959.  
  960. - for (i = 0; i < MAX_SHIELD_SECTIONS; i++)
  961. - shield_set_quad(objp, i, strength / MAX_SHIELD_SECTIONS);
  962. + for (i = 0; i < objp->n_quadrants; i++)
  963. + shield_set_quad(objp, i, strength / objp->n_quadrants);
  964. }
  965.  
  966. // Recharge whole shield.
  967. -// Apply delta/MAX_SHIELD_SECTIONS to each shield section.
  968. +// Apply delta/n_quadrants to each shield section.
  969. void shield_add_strength(object *objp, float delta)
  970. {
  971. // if we aren't going to change anything anyway then just bail
  972. @@ -53,8 +53,8 @@
  973. if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT)
  974. || delta <= 0.0f) //SUSHI: We don't want smart shield management for negative delta
  975. {
  976. - for (int i = 0; i < MAX_SHIELD_SECTIONS; i++)
  977. - shield_add_quad(objp, i, delta / MAX_SHIELD_SECTIONS);
  978. + for (int i = 0; i < objp->n_quadrants; i++)
  979. + shield_add_quad(objp, i, delta / objp->n_quadrants);
  980. }
  981. else
  982. {
  983. @@ -68,7 +68,7 @@
  984. int weakest_idx = -1;
  985.  
  986. // find weakest shield quadrant
  987. - for (int i = 0; i < MAX_SHIELD_SECTIONS; i++)
  988. + for (int i = 0; i < objp->n_quadrants; i++)
  989. {
  990. float quad = shield_get_quad(objp, i);
  991. if (weakest_idx < 0 || quad < weakest)
  992. @@ -126,8 +126,8 @@
  993. return 0.0f;
  994.  
  995. // check array bounds
  996. - Assert(quadrant_num >= 0 && quadrant_num < MAX_SHIELD_SECTIONS);
  997. - if (quadrant_num < 0 || quadrant_num >= MAX_SHIELD_SECTIONS)
  998. + Assert(quadrant_num >= 0 && quadrant_num < objp->n_quadrants);
  999. + if (quadrant_num < 0 || quadrant_num >= objp->n_quadrants)
  1000. return 0.0f;
  1001.  
  1002. if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
  1003. @@ -180,8 +180,8 @@
  1004. void shield_set_quad(object *objp, int quadrant_num, float strength)
  1005. {
  1006. // check array bounds
  1007. - Assert(quadrant_num >= 0 && quadrant_num < MAX_SHIELD_SECTIONS);
  1008. - if (quadrant_num < 0 || quadrant_num >= MAX_SHIELD_SECTIONS)
  1009. + Assert(quadrant_num >= 0 && quadrant_num < objp->n_quadrants);
  1010. + if (quadrant_num < 0 || quadrant_num >= objp->n_quadrants)
  1011. return;
  1012.  
  1013. // check range
  1014. @@ -202,8 +202,8 @@
  1015. return;
  1016.  
  1017. // check array bounds
  1018. - Assert(quadrant_num >= 0 && quadrant_num < MAX_SHIELD_SECTIONS);
  1019. - if (quadrant_num < 0 || quadrant_num >= MAX_SHIELD_SECTIONS)
  1020. + Assert(quadrant_num >= 0 && quadrant_num < objp->n_quadrants);
  1021. + if (quadrant_num < 0 || quadrant_num >= objp->n_quadrants)
  1022. return;
  1023.  
  1024. // important: don't use shield_get_quad here
  1025. @@ -239,7 +239,7 @@
  1026. // Goober5000
  1027. float shield_get_max_quad(object *objp)
  1028. {
  1029. - return shield_get_max_strength(objp) / MAX_SHIELD_SECTIONS;
  1030. + return shield_get_max_strength(objp) / objp->n_quadrants;
  1031. }
  1032.  
  1033. // ***** This is the version that works on a quadrant basis.
  1034. @@ -254,8 +254,8 @@
  1035. return damage;
  1036.  
  1037. // check array bounds
  1038. - Assert(quadrant_num >= 0 && quadrant_num < MAX_SHIELD_SECTIONS);
  1039. - if ((quadrant_num < 0) || (quadrant_num >= MAX_SHIELD_SECTIONS))
  1040. + Assert(quadrant_num >= 0 && quadrant_num < objp->n_quadrants);
  1041. + if ((quadrant_num < 0) || (quadrant_num >= objp->n_quadrants))
  1042. return damage;
  1043.  
  1044. if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
  1045. @@ -282,7 +282,7 @@
  1046. // just one quadrant
  1047. int shield_is_up(object *objp, int quadrant_num)
  1048. {
  1049. - if ((quadrant_num >= 0) && (quadrant_num < MAX_SHIELD_SECTIONS))
  1050. + if ((quadrant_num >= 0) && (quadrant_num < objp->n_quadrants))
  1051. {
  1052. // Just check one quadrant
  1053. float quad = shield_get_quad(objp, quadrant_num);
  1054. @@ -295,40 +295,10 @@
  1055. // Check all quadrants
  1056. float strength = shield_get_strength(objp);
  1057.  
  1058. - if (strength > MAX(2.0f * MAX_SHIELD_SECTIONS, 0.1f * shield_get_max_strength(objp)))
  1059. + if (strength > MAX(2.0f * objp->n_quadrants, 0.1f * shield_get_max_strength(objp)))
  1060. return 1;
  1061. }
  1062.  
  1063. return 0; // no shield strength
  1064. }
  1065.  
  1066. -// return quadrant containing hit_pnt.
  1067. -// \ 1 /.
  1068. -// 3 \ / 0
  1069. -// / \.
  1070. -// / 2 \.
  1071. -// Note: This is in the object's local reference frame. Do _not_ pass a vector in the world frame.
  1072. -int shield_get_quadrant(vec3d *hit_pnt)
  1073. -{
  1074. - int result = 0;
  1075. -
  1076. - if (hit_pnt->xyz.x < hit_pnt->xyz.z)
  1077. - result |= 1;
  1078. -
  1079. - if (hit_pnt->xyz.x < -hit_pnt->xyz.z)
  1080. - result |= 2;
  1081. -
  1082. - return result;
  1083. -}
  1084. -
  1085. -// Given a global point and an object, get the quadrant number the point belongs to.
  1086. -int shield_get_quadrant_global(object *objp, vec3d *global_pos)
  1087. -{
  1088. - vec3d tpos;
  1089. - vec3d rotpos;
  1090. -
  1091. - vm_vec_sub(&tpos, global_pos, &objp->pos);
  1092. - vm_vec_rotate(&rotpos, &tpos, &objp->orient);
  1093. -
  1094. - return shield_get_quadrant(&rotpos);
  1095. -}
  1096. Index: object/objectshield.h
  1097. ===================================================================
  1098. --- object/objectshield.h (revision 10126)
  1099. +++ object/objectshield.h (working copy)
  1100. @@ -31,7 +31,5 @@
  1101.  
  1102. float shield_apply_damage(object *objp, int quadrant, float damage);
  1103. int shield_is_up(object *objp, int quadrant_num);
  1104. -int shield_get_quadrant(vec3d *hit_pnt);
  1105. -int shield_get_quadrant_global(object *objp, vec3d *global_pos);
  1106.  
  1107. #endif //_OBJECTSHIELD_H
  1108. Index: parse/lua.cpp
  1109. ===================================================================
  1110. --- parse/lua.cpp (revision 10126)
  1111. +++ parse/lua.cpp (working copy)
  1112. @@ -4940,7 +4940,7 @@
  1113. //WMC - copy shields
  1114. if(ADE_SETTING_VAR && sobjh != NULL && sobjh->IsValid())
  1115. {
  1116. - for(int i = 0; i < MAX_SHIELD_SECTIONS; i++)
  1117. + for(int i = 0; i < objh->objp->n_quadrants; i++)
  1118. shield_set_quad(objh->objp, i, shield_get_quad(sobjh->objp, i));
  1119. }
  1120.  
  1121. @@ -8264,6 +8264,9 @@
  1122. aip->target_objnum = OBJ_INDEX(newh->objp);
  1123. aip->target_signature = newh->sig;
  1124. aip->target_time = 0.0f;
  1125. +
  1126. + if (aip == Player_ai)
  1127. + hud_shield_hit_reset(newh->objp);
  1128. }
  1129. else
  1130. {
  1131. @@ -8300,13 +8303,17 @@
  1132. {
  1133. if(newh->IsValid())
  1134. {
  1135. + if (aip == Player_ai) {
  1136. + if (aip->target_signature != newh->sig)
  1137. + hud_shield_hit_reset(newh->objp);
  1138. +
  1139. + Ships[newh->ss->parent_objnum].last_targeted_subobject[Player_num] = newh->ss;
  1140. + }
  1141. +
  1142. aip->target_objnum = OBJ_INDEX(newh->objp);
  1143. aip->target_signature = newh->sig;
  1144. aip->target_time = 0.0f;
  1145. set_targeted_subsys(aip, newh->ss, aip->target_objnum);
  1146. -
  1147. - if (aip == Player_ai)
  1148. - Ships[newh->ss->parent_objnum].last_targeted_subobject[Player_num] = newh->ss;
  1149. }
  1150. else
  1151. {
  1152. Index: parse/sexp.cpp
  1153. ===================================================================
  1154. --- parse/sexp.cpp (revision 10126)
  1155. +++ parse/sexp.cpp (working copy)
  1156. @@ -15287,7 +15287,7 @@
  1157. check = (float)eval_num(CDR(node));
  1158.  
  1159. // check his quadrants
  1160. - for(idx=0; idx<MAX_SHIELD_SECTIONS; idx++){
  1161. + for(idx=0; idx<objp->n_quadrants; idx++){
  1162. if( ((objp->shield_quadrant[idx] / max_quad) * 100.0f) <= check ){
  1163. return SEXP_TRUE;
  1164. }
  1165. @@ -16077,7 +16077,7 @@
  1166.  
  1167. // ...and shields
  1168. target_shipp->ship_max_shield_strength = source_shipp->ship_max_shield_strength;
  1169. - for (i = 0; i < MAX_SHIELD_SECTIONS; i++)
  1170. + for (i = 0; i < MIN(target_objp->n_quadrants, source_objp->n_quadrants); i++)
  1171. target_objp->shield_quadrant[i] = source_objp->shield_quadrant[i];
  1172.  
  1173.  
  1174. @@ -19205,16 +19205,14 @@
  1175. return SEXP_FALSE;
  1176. }
  1177.  
  1178. -#define RIGHT_QUAD 0
  1179. -#define FRONT_QUAD 1
  1180. -#define LEFT_QUAD 3
  1181. -#define REAR_QUAD 2
  1182. -
  1183. // Return SEXP_TRUE if quadrant quadnum is near max.
  1184. int shield_quad_near_max(int quadnum)
  1185. {
  1186. + if (quadnum >= Player_obj->n_quadrants)
  1187. + return SEXP_FALSE;
  1188. +
  1189. float remaining = 0.0f;
  1190. - for (int i=0; i<MAX_SHIELD_SECTIONS; i++) {
  1191. + for (int i=0; i<Player_obj->n_quadrants; i++) {
  1192. if (i == quadnum){
  1193. continue;
  1194. }
  1195. @@ -19274,55 +19272,90 @@
  1196. break;
  1197.  
  1198. case 3: // Player ship suffering shield damage on front.
  1199. - apply_damage_to_shield(Player_obj, FRONT_QUAD, 10.0f);
  1200. - hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1201. - return SEXP_TRUE;
  1202. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1203. + apply_damage_to_shield(Player_obj, FRONT_QUAD, 10.0f);
  1204. + hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1205. + return SEXP_TRUE;
  1206. + } else {
  1207. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1208. + return SEXP_FALSE;
  1209. + }
  1210. break;
  1211.  
  1212. case 4: // Player ship suffering much damage.
  1213. - nprintf(("AI", "Frame %i\n", Framecount));
  1214. - apply_damage_to_shield(Player_obj, FRONT_QUAD, 10.0f);
  1215. - hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1216. - if (Player_obj->shield_quadrant[FRONT_QUAD] < 2.0f)
  1217. - return SEXP_TRUE;
  1218. - else
  1219. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1220. + nprintf(("AI", "Frame %i\n", Framecount));
  1221. + apply_damage_to_shield(Player_obj, FRONT_QUAD, 10.0f);
  1222. + hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1223. + if (Player_obj->shield_quadrant[FRONT_QUAD] < 2.0f)
  1224. + return SEXP_TRUE;
  1225. + else
  1226. + return SEXP_FALSE;
  1227. + } else {
  1228. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1229. return SEXP_FALSE;
  1230. + }
  1231. break;
  1232.  
  1233. case 5: // Player's shield is quick repaired
  1234. - nprintf(("AI", "Frame %i, recharged to %7.3f\n", Framecount, Player_obj->shield_quadrant[FRONT_QUAD]));
  1235. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1236. + nprintf(("AI", "Frame %i, recharged to %7.3f\n", Framecount, Player_obj->shield_quadrant[FRONT_QUAD]));
  1237.  
  1238. - apply_damage_to_shield(Player_obj, FRONT_QUAD, -flFrametime*200.0f);
  1239. + apply_damage_to_shield(Player_obj, FRONT_QUAD, -flFrametime*200.0f);
  1240.  
  1241. - if (Player_obj->shield_quadrant[FRONT_QUAD] > get_max_shield_quad(Player_obj))
  1242. + if (Player_obj->shield_quadrant[FRONT_QUAD] > get_max_shield_quad(Player_obj))
  1243. Player_obj->shield_quadrant[FRONT_QUAD] = get_max_shield_quad(Player_obj);
  1244.  
  1245. - if (Player_obj->shield_quadrant[FRONT_QUAD] > Player_obj->shield_quadrant[(FRONT_QUAD+1)%MAX_SHIELD_SECTIONS] - 2.0f)
  1246. - return SEXP_TRUE;
  1247. - else
  1248. + if (Player_obj->shield_quadrant[FRONT_QUAD] > Player_obj->shield_quadrant[(FRONT_QUAD+1)%DEFAULT_SHIELD_SECTIONS] - 2.0f)
  1249. + return SEXP_TRUE;
  1250. + else
  1251. + return SEXP_FALSE;
  1252. + } else {
  1253. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1254. return SEXP_FALSE;
  1255. + }
  1256. break;
  1257.  
  1258. case 6: // 3 of player's shield quadrants are reduced to 0.
  1259. - Player_obj->shield_quadrant[1] = 1.0f;
  1260. - Player_obj->shield_quadrant[2] = 1.0f;
  1261. - Player_obj->shield_quadrant[3] = 1.0f;
  1262. - hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1263. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1264. + Player_obj->shield_quadrant[1] = 1.0f;
  1265. + Player_obj->shield_quadrant[2] = 1.0f;
  1266. + Player_obj->shield_quadrant[3] = 1.0f;
  1267. + hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1268. + } else {
  1269. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1270. + return SEXP_FALSE;
  1271. + }
  1272. return SEXP_TRUE;
  1273.  
  1274. case 7: // Make sure front quadrant has been maximized, or close to it.
  1275. - if (shield_quad_near_max(FRONT_QUAD)) return SEXP_TRUE; else return SEXP_FALSE;
  1276. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1277. + if (shield_quad_near_max(FRONT_QUAD)) return SEXP_TRUE; else return SEXP_FALSE;
  1278. + } else {
  1279. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1280. + return SEXP_FALSE;
  1281. + }
  1282. break;
  1283.  
  1284. case 8: // Make sure rear quadrant has been maximized, or close to it.
  1285. - if (shield_quad_near_max(REAR_QUAD)) return SEXP_TRUE; else return SEXP_FALSE;
  1286. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1287. + if (shield_quad_near_max(REAR_QUAD)) return SEXP_TRUE; else return SEXP_FALSE;
  1288. + } else {
  1289. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1290. + return SEXP_FALSE;
  1291. + }
  1292. break;
  1293.  
  1294. case 9: // Zero left and right quadrants in preparation for maximizing rear quadrant.
  1295. - Player_obj->shield_quadrant[LEFT_QUAD] = 0.0f;
  1296. - Player_obj->shield_quadrant[RIGHT_QUAD] = 0.0f;
  1297. - hud_shield_quadrant_hit(Player_obj, LEFT_QUAD);
  1298. - return SEXP_TRUE;
  1299. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1300. + Player_obj->shield_quadrant[LEFT_QUAD] = 0.0f;
  1301. + Player_obj->shield_quadrant[RIGHT_QUAD] = 0.0f;
  1302. + hud_shield_quadrant_hit(Player_obj, LEFT_QUAD);
  1303. + return SEXP_TRUE;
  1304. + } else {
  1305. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1306. + return SEXP_FALSE;
  1307. + }
  1308. break;
  1309.  
  1310. case 10: // Return true if player is low on Interceptors.
  1311. @@ -19347,9 +19380,14 @@
  1312. break;
  1313.  
  1314. case 13: // Zero front shield quadrant. Added for Jim Boone on August 26, 1999 by MK.
  1315. - Player_obj->shield_quadrant[FRONT_QUAD] = 0.0f;
  1316. - hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1317. - return SEXP_TRUE;
  1318. + if (!(Player_ship->flags2 & SIF2_SHIELD_POINTS)) {
  1319. + Player_obj->shield_quadrant[FRONT_QUAD] = 0.0f;
  1320. + hud_shield_quadrant_hit(Player_obj, FRONT_QUAD);
  1321. + return SEXP_TRUE;
  1322. + } else {
  1323. + nprintf(("Warning", "Shield-related Special-check SEXPs do not work on ship %s because it uses model point shields.\n", Player_ship->ship_name));
  1324. + return SEXP_FALSE;
  1325. + }
  1326. break;
  1327.  
  1328. case 100: // Return true if player is out of countermeasures.
  1329. Index: ship/shield.cpp
  1330. ===================================================================
  1331. --- ship/shield.cpp (revision 10126)
  1332. +++ ship/shield.cpp (working copy)
  1333. @@ -646,7 +646,7 @@
  1334. return damage;
  1335. }
  1336.  
  1337. - if ( (quadrant < 0) || (quadrant >= MAX_SHIELD_SECTIONS) ) return damage;
  1338. + if ( (quadrant < 0) || (quadrant >= objp->n_quadrants) ) return damage;
  1339.  
  1340. Assert(objp->type == OBJ_SHIP);
  1341. aip = &Ai_info[Ships[objp->instance].ai_index];
  1342. @@ -959,7 +959,7 @@
  1343. */
  1344. int ship_is_shield_up( object *obj, int quadrant )
  1345. {
  1346. - if ( (quadrant >= 0) && (quadrant < MAX_SHIELD_SECTIONS)) {
  1347. + if ( (quadrant >= 0) && (quadrant < obj->n_quadrants)) {
  1348. // Just check one quadrant
  1349. if (obj->shield_quadrant[quadrant] > MAX(2.0f, 0.1f * get_max_shield_quad(obj))) {
  1350. return 1;
  1351. @@ -981,15 +981,31 @@
  1352. // / \.
  1353. // / 2 \.
  1354. // Note: This is in the object's local reference frame. Do _not_ pass a vector in the world frame.
  1355. -int get_quadrant(vec3d *hit_pnt)
  1356. +int get_quadrant(vec3d *hit_pnt, object *shipobjp)
  1357. {
  1358. - int result = 0;
  1359. + if (shipobjp != NULL && Ship_info[Ships[shipobjp->instance].ship_info_index].flags2 & SIF2_SHIELD_POINTS) {
  1360. + int closest = -1;
  1361. + float closest_dist = FLT_MAX;
  1362.  
  1363. - if (hit_pnt->xyz.x < hit_pnt->xyz.z)
  1364. - result |= 1;
  1365. + for (unsigned int i=0; i<Ships[shipobjp->instance].shield_points.size(); i++) {
  1366. + float dist = vm_vec_dist(hit_pnt, &Ships[shipobjp->instance].shield_points.at(i));
  1367.  
  1368. - if (hit_pnt->xyz.x < -hit_pnt->xyz.z)
  1369. - result |= 2;
  1370. + if (dist < closest_dist) {
  1371. + closest = i;
  1372. + closest_dist = dist;
  1373. + }
  1374. + }
  1375.  
  1376. - return result;
  1377. + return closest;
  1378. + } else {
  1379. + int result = 0;
  1380. +
  1381. + if (hit_pnt->xyz.x < hit_pnt->xyz.z)
  1382. + result |= 1;
  1383. +
  1384. + if (hit_pnt->xyz.x < -hit_pnt->xyz.z)
  1385. + result |= 2;
  1386. +
  1387. + return result;
  1388. + }
  1389. }
  1390. Index: ship/ship.cpp
  1391. ===================================================================
  1392. --- ship/ship.cpp (revision 10126)
  1393. +++ ship/ship.cpp (working copy)
  1394. @@ -306,6 +306,7 @@
  1395. { "no ets", SIF2_NO_ETS, 1 },
  1396. { "no lighting", SIF2_NO_LIGHTING, 1 },
  1397. { "auto spread shields", SIF2_AUTO_SPREAD_SHIELDS, 1 },
  1398. + { "model shield points", SIF2_SHIELD_POINTS, 1 },
  1399.  
  1400. // to keep things clean, obsolete options go last
  1401. { "ballistic primaries", -1, 255 }
  1402. @@ -2509,6 +2510,34 @@
  1403. }
  1404. }
  1405.  
  1406. + if(optional_string("$Model Shield Point Controls:")) {
  1407. + SCP_vector<SCP_string> ctrl_strings;
  1408. + int num_strings = stuff_string_list(ctrl_strings);
  1409. +
  1410. + // Init all to -1 in case some aren't supplied...
  1411. + sip->shield_point_augment_ctrls[FRONT_QUAD] = -1;
  1412. + sip->shield_point_augment_ctrls[REAR_QUAD] = -1;
  1413. + sip->shield_point_augment_ctrls[LEFT_QUAD] = -1;
  1414. + sip->shield_point_augment_ctrls[RIGHT_QUAD] = -1;
  1415. +
  1416. + for (int i = 0; i < num_strings; i++) {
  1417. + const char *str = ctrl_strings[i].c_str();
  1418. +
  1419. + if (!stricmp(str, "front"))
  1420. + sip->shield_point_augment_ctrls[FRONT_QUAD] = i;
  1421. + else if (!stricmp(str, "rear"))
  1422. + sip->shield_point_augment_ctrls[REAR_QUAD] = i;
  1423. + else if (!stricmp(str, "left"))
  1424. + sip->shield_point_augment_ctrls[LEFT_QUAD] = i;
  1425. + else if (!stricmp(str, "right"))
  1426. + sip->shield_point_augment_ctrls[RIGHT_QUAD] = i;
  1427. + else if (!stricmp(str, "none"))
  1428. + sip->shield_point_augment_ctrls[RIGHT_QUAD] = -1;
  1429. + else
  1430. + Warning(LOCATION, "Unrecognized value \"%s\" passed to $Shield Point Controls, ignoring...", str);
  1431. + }
  1432. + }
  1433. +
  1434. // optional shield color
  1435. if(optional_string("$Shield Color:")){
  1436. stuff_ubyte(&sip->shield_color[0]);
  1437. @@ -4886,6 +4915,8 @@
  1438. special_hitpoints = 0;
  1439. special_shield = -1;
  1440.  
  1441. + shield_points.clear();
  1442. +
  1443. ship_max_shield_strength = 0.0f;
  1444. ship_max_hull_strength = 0.0f;
  1445.  
  1446. @@ -5148,6 +5179,7 @@
  1447. object *objp = &Objects[objnum];
  1448. ship_info *sip = &(Ship_info[ship_type]);
  1449. ship_weapon *swp = &shipp->weapons;
  1450. + polymodel *pm = model_get(sip->model_num);
  1451.  
  1452. extern int oo_arrive_time_count[MAX_SHIPS];
  1453. extern int oo_interp_count[MAX_SHIPS];
  1454. @@ -5181,6 +5213,12 @@
  1455. shield_set_strength(objp, shipp->ship_max_shield_strength);
  1456. }
  1457.  
  1458. + if (sip->flags2 & SIF2_SHIELD_POINTS) {
  1459. + objp->n_quadrants = pm->shield_points.size();
  1460. + shipp->shield_points = pm->shield_points;
  1461. + objp->shield_quadrant.resize(objp->n_quadrants);
  1462. + }
  1463. +
  1464. shipp->orders_accepted = ship_get_default_orders_accepted( sip );
  1465.  
  1466. if (!subsys_set(objnum))
  1467. @@ -5258,8 +5296,6 @@
  1468. shipp->collision_damage_type_idx = sip->collision_damage_type_idx;
  1469. shipp->debris_damage_type_idx = sip->debris_damage_type_idx;
  1470.  
  1471. - polymodel *pm = model_get(sip->model_num);
  1472. -
  1473. if(pm != NULL && pm->n_view_positions > 0)
  1474. ship_set_eye(objp, 0);
  1475. else
  1476. @@ -9110,10 +9146,12 @@
  1477. ship_info *sip;
  1478. ship *sp;
  1479. polymodel * pm;
  1480. + object *objp;
  1481.  
  1482. Assert( n >= 0 && n < MAX_SHIPS );
  1483. sp = &Ships[n];
  1484. sip = &(Ship_info[ship_type]);
  1485. + objp = &Objects[sp->objnum];
  1486.  
  1487. // get new model
  1488. if (sip->model_num == -1) {
  1489. @@ -9161,6 +9199,14 @@
  1490. for ( i=0; i<pm->n_detail_levels; i++ )
  1491. pm->detail_depth[i] = (i < sip->num_detail_levels) ? i2fl(sip->detail_distance[i]) : 0.0f;
  1492.  
  1493. + if (sip->flags2 & SIF2_SHIELD_POINTS) {
  1494. + objp->n_quadrants = pm->shield_points.size();
  1495. + sp->shield_points = pm->shield_points;
  1496. + } else {
  1497. + objp->n_quadrants = DEFAULT_SHIELD_SECTIONS;
  1498. + }
  1499. + objp->shield_quadrant.resize(objp->n_quadrants);
  1500. +
  1501. if (sp->shield_integrity != NULL) {
  1502. vm_free(sp->shield_integrity);
  1503. sp->shield_integrity = NULL;
  1504. @@ -14293,7 +14339,7 @@
  1505. // convert hitpos to position in model coordinates
  1506. vm_vec_sub(&tmpv1, hitpos, &hit_objp->pos);
  1507. vm_vec_rotate(&tmpv2, &tmpv1, &hit_objp->orient);
  1508. - quadrant_num = get_quadrant(&tmpv2);
  1509. + quadrant_num = get_quadrant(&tmpv2, hit_objp);
  1510.  
  1511. if ( quadrant_num < 0 )
  1512. quadrant_num = 0;
  1513. Index: ship/ship.h
  1514. ===================================================================
  1515. --- ship/ship.h (revision 10126)
  1516. +++ ship/ship.h (working copy)
  1517. @@ -649,6 +649,8 @@
  1518.  
  1519. int shield_hits; // Number of hits on shield this frame.
  1520.  
  1521. + SCP_vector<vec3d> shield_points;
  1522. +
  1523. float wash_intensity;
  1524. vec3d wash_rot_axis;
  1525. int wash_timestamp;
  1526. @@ -919,8 +921,9 @@
  1527. #define SIF2_NO_LIGHTING (1 << 14) // Valathil - No lighting for this ship
  1528. #define SIF2_DYN_PRIMARY_LINKING (1 << 15) // RSAXVC - Dynamically generate weapon linking options
  1529. #define SIF2_AUTO_SPREAD_SHIELDS (1 << 16) // zookeeper - auto spread shields
  1530. +#define SIF2_SHIELD_POINTS (1 << 17) // zookeeper - uses model-defined shield points instead of quadrants
  1531. // !!! IF YOU ADD A FLAG HERE BUMP MAX_SHIP_FLAGS !!!
  1532. -#define MAX_SHIP_FLAGS 17 // Number of distinct flags for flags field in ship_info struct
  1533. +#define MAX_SHIP_FLAGS 18 // Number of distinct flags for flags field in ship_info struct
  1534. #define SIF_DEFAULT_VALUE 0
  1535. #define SIF2_DEFAULT_VALUE 0
  1536.  
  1537. @@ -1288,6 +1291,8 @@
  1538. bool auto_shield_spread_bypass;
  1539. int auto_shield_spread_from_lod;
  1540.  
  1541. + int shield_point_augment_ctrls[4]; // Re-mapping of shield augmentation controls for model point shields
  1542. +
  1543. float hull_repair_rate; //How much of the hull is repaired every second
  1544. float subsys_repair_rate; //How fast
  1545.  
  1546. @@ -1710,7 +1715,7 @@
  1547. extern int ship_class_query_general_type(int ship_class);
  1548. extern int ship_query_general_type(ship *shipp);
  1549. extern int ship_docking_valid(int docker, int dockee);
  1550. -extern int get_quadrant(vec3d *hit_pnt); // Return quadrant num of last hit ponit.
  1551. +extern int get_quadrant(vec3d *hit_pnt, object *shipobjp = NULL); // Return quadrant num of given hit point.
  1552.  
  1553. extern void ship_obj_list_rebuild(); // only called by save/restore code
  1554. extern int ship_query_state(char *name);
  1555. Index: ship/shiphit.cpp
  1556. ===================================================================
  1557. --- ship/shiphit.cpp (revision 10126)
  1558. +++ ship/shiphit.cpp (working copy)
  1559. @@ -2498,7 +2498,7 @@
  1560. vm_vec_rotate( &local_hitpos, &tmp, &ship_objp->orient );
  1561.  
  1562. // shield_quad = quadrant facing the force_center
  1563. - shield_quad = get_quadrant(&local_hitpos);
  1564. + shield_quad = get_quadrant(&local_hitpos, ship_objp);
  1565.  
  1566. // world_hitpos use force_center for shockwave
  1567. // Goober5000 check for NULL
  1568. @@ -2515,8 +2515,8 @@
  1569. // radius of the object.
  1570. vm_vec_scale_add( &world_hitpos, &ship_objp->pos, &ship_objp->orient.vec.fvec, ship_objp->radius );
  1571.  
  1572. - for (int i=0; i<MAX_SHIELD_SECTIONS; i++){
  1573. - ship_do_damage(ship_objp, other_obj, &world_hitpos, damage/MAX_SHIELD_SECTIONS, i, -1);
  1574. + for (int i=0; i<ship_objp->n_quadrants; i++){
  1575. + ship_do_damage(ship_objp, other_obj, &world_hitpos, damage/ship_objp->n_quadrants, i, -1);
  1576. }
  1577. }
  1578.  
  1579. Index: weapon/beam.cpp
  1580. ===================================================================
  1581. --- weapon/beam.cpp (revision 10126)
  1582. +++ weapon/beam.cpp (working copy)
  1583. @@ -2392,9 +2392,9 @@
  1584. {
  1585. // pick out the shield quadrant
  1586. if (shield_collision)
  1587. - quadrant_num = get_quadrant(&mc_shield.hit_point);
  1588. + quadrant_num = get_quadrant(&mc_shield.hit_point, ship_objp);
  1589. else if (hull_enter_collision && (sip->flags2 & SIF2_SURFACE_SHIELDS))
  1590. - quadrant_num = get_quadrant(&mc_hull_enter.hit_point);
  1591. + quadrant_num = get_quadrant(&mc_hull_enter.hit_point, ship_objp);
  1592.  
  1593. // make sure that the shield is active in that quadrant
  1594. if ((quadrant_num >= 0) && ((shipp->flags & SF_DYING) || !ship_is_shield_up(ship_objp, quadrant_num)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement