From 840312f8ea01e0ab59c243ddd1d272aaada84fa1 Mon Sep 17 00:00:00 2001 From: Roman C Date: Sun, 17 Dec 2006 17:12:14 +0000 Subject: [PATCH] Patch by Watermelon with slight modifications: -new ORDER_CIRCLE VTOL command - will defend a certain position flying over it and engaging enemies nearby -adds additional armor types for all sides of a droid (rear, front, top, bottom, left, right) - additional armor definitions are in body.txt. Droid damage is now also a function of the impact side. -adds multi-turret support for VTOLs -modifies connectors in bodies: first 5 connectors are for ground units, the rest is for VTOL. -introduces some fixes git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@901 4a71c877-e1ca-e34f-864e-861f7616d084 --- data/components/bodies/drhbod09.pie | 8 +- data/components/bodies/drhbod10.pie | 8 +- data/components/bodies/drhbod11.pie | 8 +- data/components/bodies/drhbod12.pie | 6 +- data/components/bodies/drlbod01.pie | 8 +- data/components/bodies/drlbod02.pie | 8 +- data/components/bodies/drlbod03.pie | 8 +- data/components/bodies/drlbod04.pie | 8 +- data/components/bodies/drmbod05.pie | 8 +- data/components/bodies/drmbod06.pie | 8 +- data/components/bodies/drmbod07.pie | 8 +- data/components/bodies/drmbod08.pie | 8 +- data/mp/components/bodies/drhbod14.pie | 8 +- data/mp/components/bodies/drmbod13.pie | 8 +- data/mp/stats/body.txt | 100 ++++++------- data/stats/body.txt | 72 +++++----- src/action.c | 76 +++++----- src/action.h | 2 + src/ai.c | 1 - src/combat.c | 11 ++ src/component.c | 123 ++++------------ src/design.c | 22 +-- src/display3d.c | 4 +- src/droid.c | 192 +++++++++++++++++++------ src/droid.h | 8 +- src/droiddef.h | 4 +- src/game.c | 26 +++- src/intorder.c | 18 ++- src/move.c | 1 - src/movedef.h | 8 +- src/multibot.c | 48 ++++--- src/order.c | 133 ++++++++++++++++- src/order.h | 5 + src/projectile.c | 147 +++++++++++++++---- src/stats.c | 28 ++-- src/stats.h | 3 +- src/statsdef.h | 19 ++- src/structure.c | 29 ++-- 38 files changed, 812 insertions(+), 378 deletions(-) diff --git a/data/components/bodies/drhbod09.pie b/data/components/bodies/drhbod09.pie index b77af4ad2..b8428a750 100644 --- a/data/components/bodies/drhbod09.pie +++ b/data/components/bodies/drhbod09.pie @@ -60,8 +60,12 @@ POLYGONS 15 200 4 36 35 34 33 254 102 252 130 244 124 244 102 200 4 38 36 33 37 251 92 254 102 244 102 244 88 200 3 34 39 37 244 124 240 87 244 88 -CONNECTORS 4 +CONNECTORS 8 0 23 35 - 0 -33 9 0 -33 25 0 23 55 + 0 0 0 + 0 0 0 + 0 -33 9 + 0 23 9 + 0 23 -11 diff --git a/data/components/bodies/drhbod10.pie b/data/components/bodies/drhbod10.pie index 4b72260ca..9d8b40123 100644 --- a/data/components/bodies/drhbod10.pie +++ b/data/components/bodies/drhbod10.pie @@ -74,8 +74,12 @@ POLYGONS 15 200 4 47 46 45 44 111 60 102 60 102 65 111 65 200 4 51 50 49 48 153 39 169 39 169 47 153 47 200 4 53 52 50 51 157 37 164 37 169 39 153 39 -CONNECTORS 4 +CONNECTORS 8 0 32 27 - 0 -52 3 0 -52 17 0 32 47 + 0 0 0 + 0 0 0 + 0 -52 3 + 0 32 3 + 0 32 -17 diff --git a/data/components/bodies/drhbod11.pie b/data/components/bodies/drhbod11.pie index 0165b2483..688f7195a 100644 --- a/data/components/bodies/drhbod11.pie +++ b/data/components/bodies/drhbod11.pie @@ -60,8 +60,12 @@ POLYGONS 13 a00 4 38 37 36 35 186 91 186 48 181 60 181 85 a00 4 40 39 37 38 196 84 196 55 186 48 186 91 a00 3 37 39 41 186 48 196 55 191 48 -CONNECTORS 4 +CONNECTORS 8 0 12 34 - 0 -29 9 0 -29 24 0 12 54 + 0 0 0 + 0 0 0 + 0 -29 9 + 0 12 9 + 0 12 -11 diff --git a/data/components/bodies/drhbod12.pie b/data/components/bodies/drhbod12.pie index 7ae1b3fd3..af291d14f 100644 --- a/data/components/bodies/drhbod12.pie +++ b/data/components/bodies/drhbod12.pie @@ -66,8 +66,12 @@ POLYGONS 17 200 4 42 40 38 41 251 31 254 40 247 40 247 31 200 3 35 43 41 240 40 243 36 247 31 200 3 35 41 38 240 40 247 31 247 40 -CONNECTORS 4 +CONNECTORS 8 0 -2 34 0 -32 9 0 -32 24 + 0 0 0 + 0 0 0 0 -2 54 + 0 -32 54 + 0 -32 34 diff --git a/data/components/bodies/drlbod01.pie b/data/components/bodies/drlbod01.pie index 773c25554..7eebcbdad 100644 --- a/data/components/bodies/drlbod01.pie +++ b/data/components/bodies/drlbod01.pie @@ -48,8 +48,12 @@ POLYGONS 11 200 4 25 24 17 18 13 24 1 24 1 1 13 1 200 4 29 28 27 26 26 24 38 24 38 1 26 0 200 4 31 30 28 29 26 35 31 35 38 24 26 24 -CONNECTORS 4 +CONNECTORS 8 0 10 23 - 0 -25 9 0 -25 13 0 10 43 + 0 0 0 + 0 0 0 + 0 -25 9 + 0 10 9 + 0 10 -11 diff --git a/data/components/bodies/drlbod02.pie b/data/components/bodies/drlbod02.pie index a4d0b4f7e..09224391b 100644 --- a/data/components/bodies/drlbod02.pie +++ b/data/components/bodies/drlbod02.pie @@ -55,8 +55,12 @@ POLYGONS 10 200 4 31 30 29 28 69 85 51 88 48 94 69 94 200 4 35 34 33 32 87 73 87 85 100 84 100 75 200 4 39 38 37 36 218 129 218 130 239 131 239 127 -CONNECTORS 4 +CONNECTORS 8 0 20 27 - 0 -25 10 0 -25 17 0 20 47 + 0 0 0 + 0 0 0 + 0 -25 10 + 0 20 10 + 0 20 -10 diff --git a/data/components/bodies/drlbod03.pie b/data/components/bodies/drlbod03.pie index 7cf3a8e20..e567fc605 100644 --- a/data/components/bodies/drlbod03.pie +++ b/data/components/bodies/drlbod03.pie @@ -43,8 +43,12 @@ POLYGONS 18 200 4 15 12 2 4 83 0 91 0 91 16 83 16 200 4 12 13 1 2 91 0 100 0 100 16 91 16 200 4 13 10 0 1 184 0 173 0 173 16 184 16 -CONNECTORS 4 +CONNECTORS 8 0 -12 29 - 0 -33 8 0 -33 19 0 -12 49 + 0 0 0 + 0 0 0 + 0 -33 8 + 0 -12 8 + 0 -12 -12 diff --git a/data/components/bodies/drlbod04.pie b/data/components/bodies/drlbod04.pie index 3d9a21faf..89d83d423 100644 --- a/data/components/bodies/drlbod04.pie +++ b/data/components/bodies/drlbod04.pie @@ -64,8 +64,12 @@ POLYGONS 15 a00 3 37 35 36 143 102 166 102 143 101 a00 4 41 40 39 38 172 123 172 102 167 105 167 120 a00 4 43 42 40 41 176 120 176 105 172 102 172 123 -CONNECTORS 4 +CONNECTORS 8 0 8 26 - 0 -33 17 0 -33 16 0 8 46 + 0 0 0 + 0 0 0 + 0 -33 17 + 0 8 17 + 0 8 -3 diff --git a/data/components/bodies/drmbod05.pie b/data/components/bodies/drmbod05.pie index c68ea0031..2e9ae2c06 100644 --- a/data/components/bodies/drmbod05.pie +++ b/data/components/bodies/drmbod05.pie @@ -81,8 +81,12 @@ POLYGONS 20 200 4 49 48 47 43 117 31 135 31 134 39 108 39 200 4 53 52 51 50 154 25 176 25 176 34 154 34 200 4 55 54 52 53 158 16 172 16 176 25 154 25 -CONNECTORS 4 +CONNECTORS 8 0 1 31 - 0 -21 8 0 -21 21 0 1 51 + 0 0 0 + 0 0 0 + 0 -21 8 + 0 1 8 + 0 1 -12 diff --git a/data/components/bodies/drmbod06.pie b/data/components/bodies/drmbod06.pie index ee29b8da8..a67e5f6b4 100644 --- a/data/components/bodies/drmbod06.pie +++ b/data/components/bodies/drmbod06.pie @@ -65,8 +65,12 @@ POLYGONS 12 200 4 39 38 37 36 151 35 171 35 170 47 152 47 200 4 43 42 41 40 218 98 218 92 235 92 236 98 200 4 47 46 45 44 216 126 217 121 237 121 237 126 -CONNECTORS 4 +CONNECTORS 8 0 2 33 - 0 -20 6 0 -20 23 0 2 53 + 0 0 0 + 0 0 0 + 0 -20 6 + 0 2 6 + 0 2 -14 diff --git a/data/components/bodies/drmbod07.pie b/data/components/bodies/drmbod07.pie index ebb15fa12..85bd424c7 100644 --- a/data/components/bodies/drmbod07.pie +++ b/data/components/bodies/drmbod07.pie @@ -81,8 +81,12 @@ POLYGONS 16 a00 4 53 52 51 50 121 100 146 100 143 85 124 85 a00 3 56 55 54 224 20 224 29 235 29 a00 3 59 58 57 224 29 224 20 235 29 -CONNECTORS 4 +CONNECTORS 8 0 -1 33 - 0 -19 7 0 -19 23 0 -1 53 + 0 0 0 + 0 0 0 + 0 -19 7 + 0 -1 7 + 0 -1 -13 diff --git a/data/components/bodies/drmbod08.pie b/data/components/bodies/drmbod08.pie index 791ee328c..9e34c5962 100644 --- a/data/components/bodies/drmbod08.pie +++ b/data/components/bodies/drmbod08.pie @@ -91,8 +91,12 @@ POLYGONS 20 a00 4 59 58 57 56 28 125 19 129 20 113 22 112 a00 3 62 61 60 120 113 130 105 130 113 a00 3 65 64 63 130 113 130 105 120 113 -CONNECTORS 4 +CONNECTORS 8 0 11 32 - 0 -22 5 0 -22 22 0 11 52 + 0 0 0 + 0 0 0 + 0 -22 5 + 0 11 5 + 0 11 -15 diff --git a/data/mp/components/bodies/drhbod14.pie b/data/mp/components/bodies/drhbod14.pie index a6d382fa3..c06f09fb4 100644 --- a/data/mp/components/bodies/drhbod14.pie +++ b/data/mp/components/bodies/drhbod14.pie @@ -63,8 +63,12 @@ POLYGONS 26 200 4 23 24 27 2 253 247 231 247 231 256 253 256 200 4 24 25 26 27 211 204 211 194 220 194 220 204 200 4 0 3 12 11 214 256 189 256 189 204 214 204 -CONNECTORS 4 +CONNECTORS 8 0 -2 45 - 0 -37 13 0 -37 35 0 -2 65 + 0 0 0 + 0 0 0 + 0 -37 13 + 0 -2 13 + 0 -2 -7 diff --git a/data/mp/components/bodies/drmbod13.pie b/data/mp/components/bodies/drmbod13.pie index aa4db25fd..5f0a5776f 100644 --- a/data/mp/components/bodies/drmbod13.pie +++ b/data/mp/components/bodies/drmbod13.pie @@ -54,8 +54,12 @@ POLYGONS 21 200 3 27 21 22 221 225 216 224 220 245 200 4 27 26 24 21 245 252 239 252 239 252 245 252 200 3 26 25 24 221 225 220 245 216 224 -CONNECTORS 4 +CONNECTORS 8 0 2 43 - 0 -41 11 0 -41 33 0 2 63 + 0 0 0 + 0 0 0 + 0 -41 11 + 0 2 11 + 0 -41 -9 diff --git a/data/mp/stats/body.txt b/data/mp/stats/body.txt index 9cea66852..719632b6b 100644 --- a/data/mp/stats/body.txt +++ b/data/mp/stats/body.txt @@ -1,50 +1,50 @@ -ZNULLBODY,Level All,LIGHT,0,0,0,0,MIBNKBOD.PIE,20,1,0,0,0,0,0 -TransporterBody,Level All,MEDIUM,325,637,250,200,drcytran.pie,100,1,2000,20,9,0,0 -Superbody,Level All,HEAVY,10,10,2700,9000,DRHBOD11.PIE,500,1,40000,999,999,0,0 -FireBody,Level One,LIGHT,4,75,3000,200,EXFIRE.PIE,50,1,4000,4,1,0,0 -CybRotMgGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CyborgRkt1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgFlamerGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgChn1CCGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CyborgChain1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgCannonGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgCan1CGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CybNXRail1Jmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybNXPulseLasJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybNXMissJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybFlamer01CGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -Cyb-Hvybod-TK,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-RailGunner,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-PulseLsr,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-Mcannon,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-HPV,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-Acannon,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Hvybod-A-T,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,0,0 -Cyb-Bod-Thermite,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Rail1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Mechanic,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Las1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Grenade,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-ComEng,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Atmiss,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -BusBody,Level One,LIGHT,4,75,2000,200,EXSCHOOL.PIE,50,1,4000,4,1,0,0 -Body9REC,Level All,HEAVY,90,420,3300,225,DRHBOD09.PIE,500,3,18000,22,15,fxvtl09.pie,1 -Body8MBT,Level All,MEDIUM,37,250,1500,125,DRMBOD08.PIE,250,2,15000,12,12,fxvtl5to8.pie,1 -Body7ABT,Level Three,MEDIUM,150,600,1500,200,DRMBOD07.PIE,250,2,15000,24,20,fxvtl5to8.pie,1 -Body6SUPP,Level Two-Three,MEDIUM,70,300,2500,145,DRMBOD06.PIE,250,2,13000,18,9,fxvtl5to8.pie,1 -Body5REC,Level All,MEDIUM,50,250,2000,130,DRMBOD05.PIE,250,2,15000,15,6,fxvtl5to8.pie,1 -Body4ABT,Level All,LIGHT,20,100,450,55,DRLBOD04.PIE,100,1,5000,8,8,fxvtl04.pie,1 -Body3MBT,Level Three,LIGHT,100,400,450,100,DRLBOD03.PIE,100,1,5000,20,15,fxvtl2and3.pie,1 -Body2SUP,Level All,LIGHT,50,220,750,85,DRLBOD02.PIE,100,1,4000,12,6,fxvtl2and3.pie,1 -Body1REC,Level All,LIGHT,30,150,600,65,DRLBOD01.PIE,100,1,5000,10,4,fxvtl01.pie,1 -Body14SUP,Level Three,HEAVY,300,1000,6000,400,DRHBOD14.PIE,500,3,30000,30,30,fxvtl12.pie,1 -Body13SUP,Level Three,HEAVY,250,900,5000,350,DRMBOD13.PIE,500,3,25000,28,28,fxvtl12.pie,1 -Body12SUP,Level All,HEAVY,55,350,2100,180,DRHBOD12.PIE,500,3,20000,18,18,fxvtl12.pie,1 -Body11ABT,Level All,HEAVY,70,350,2700,200,DRHBOD11.PIE,500,3,20000,20,9,fxvtl11.pie,1 -Body10MBT,Level Three,HEAVY,200,800,2500,300,DRHBOD10.PIE,500,3,23000,28,25,fxvtl10.pie,1 -B4body-sml-trike01,Level One,LIGHT,2,65,675,80,extrike.PIE,35,1,2100,1,1,0,0 -B3bodyRKbuggy01,Level One,LIGHT,3,80,900,100,exbugRK.PIE,50,1,2200,3,1,0,0 -B3body-sml-buggy01,Level One,LIGHT,3,80,900,100,exbuggy.PIE,50,1,2200,3,1,0,0 -B2RKJeepBody,Level One,LIGHT,4,75,900,120,EXjeepRK.PIE,50,1,2200,4,1,0,0 -B2JeepBody,Level One,LIGHT,4,75,900,120,EXjeep.PIE,50,1,2200,4,1,0,0 -B1BaBaPerson01,Level All,HEAVY,1,20,100,29,EXBLOKE.PIE,50,1,125,1,1,0,0 +ZNULLBODY,Level All,LIGHT,0,0,0,0,MIBNKBOD.PIE,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +TransporterBody,Level All,MEDIUM,325,637,250,200,drcytran.pie,100,1,2000,20,9,20,9,20,9,20,9,20,9,20,9,0,0 +Superbody,Level All,HEAVY,10,10,2700,9000,DRHBOD11.PIE,500,1,40000,999,999,999,999,999,999,999,999,999,999,999,999,0,0 +FireBody,Level One,LIGHT,4,75,3000,200,EXFIRE.PIE,50,1,4000,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +CybRotMgGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgRkt1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgFlamerGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgChn1CCGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgChain1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgCannonGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgCan1CGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CybNXRail1Jmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybNXPulseLasJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybNXMissJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybFlamer01CGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Hvybod-TK,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-RailGunner,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-PulseLsr,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-Mcannon,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-HPV,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-Acannon,Level Two,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Hvybod-A-T,Level Three,LIGHT,60,240,150,300,scbd_std.pie,100,1,500,15,8,15,8,15,8,15,8,15,8,15,8,0,0 +Cyb-Bod-Thermite,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Rail1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Mechanic,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Las1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Grenade,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-ComEng,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Atmiss,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +BusBody,Level One,LIGHT,4,75,2000,200,EXSCHOOL.PIE,50,1,4000,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +Body9REC,Level All,HEAVY,90,420,3300,225,DRHBOD09.PIE,500,3,18000,22,15,22,15,22,15,22,15,22,15,22,15,fxvtl09.pie,1 +Body8MBT,Level All,MEDIUM,37,250,1500,125,DRMBOD08.PIE,250,2,15000,12,12,12,12,12,12,12,12,12,12,12,12,fxvtl5to8.pie,1 +Body7ABT,Level Three,MEDIUM,150,600,1500,200,DRMBOD07.PIE,250,2,15000,24,20,24,20,24,20,24,20,24,20,24,20,fxvtl5to8.pie,1 +Body6SUPP,Level Two-Three,MEDIUM,70,300,2500,145,DRMBOD06.PIE,250,2,13000,18,9,18,9,18,9,18,9,18,9,18,9,fxvtl5to8.pie,1 +Body5REC,Level All,MEDIUM,50,250,2000,130,DRMBOD05.PIE,250,2,15000,15,6,15,6,15,6,15,6,15,6,15,6,fxvtl5to8.pie,1 +Body4ABT,Level All,LIGHT,20,100,450,55,DRLBOD04.PIE,100,1,5000,8,8,8,8,8,8,8,8,8,8,8,8,fxvtl04.pie,1 +Body3MBT,Level Three,LIGHT,100,400,450,100,DRLBOD03.PIE,100,1,5000,20,15,20,15,20,15,20,15,20,15,20,15,fxvtl2and3.pie,1 +Body2SUP,Level All,LIGHT,50,220,750,85,DRLBOD02.PIE,100,1,4000,12,6,12,6,12,6,12,6,12,6,12,6,fxvtl2and3.pie,1 +Body1REC,Level All,LIGHT,30,150,600,65,DRLBOD01.PIE,100,1,5000,10,4,10,4,10,4,10,4,10,4,10,4,fxvtl01.pie,1 +Body14SUP,Level Three,HEAVY,300,1000,6000,400,DRHBOD14.PIE,500,3,30000,30,30,30,30,30,30,30,30,30,30,30,30,fxvtl12.pie,1 +Body13SUP,Level Three,HEAVY,250,900,5000,350,DRMBOD13.PIE,500,3,25000,28,28,28,28,28,28,28,28,28,28,28,28,fxvtl12.pie,1 +Body12SUP,Level All,HEAVY,55,350,2100,180,DRHBOD12.PIE,500,3,20000,18,18,18,18,18,18,18,18,18,18,18,18,fxvtl12.pie,1 +Body11ABT,Level All,HEAVY,70,350,2700,200,DRHBOD11.PIE,500,3,20000,20,9,20,9,20,9,20,9,20,9,20,9,fxvtl11.pie,1 +Body10MBT,Level Three,HEAVY,200,800,2500,300,DRHBOD10.PIE,500,3,23000,28,25,28,25,28,25,28,25,28,25,28,25,fxvtl10.pie,1 +B4body-sml-trike01,Level One,LIGHT,2,65,675,80,extrike.PIE,35,1,2100,1,1,1,1,1,1,1,1,1,1,1,1,0,0 +B3bodyRKbuggy01,Level One,LIGHT,3,80,900,100,exbugRK.PIE,50,1,2200,3,1,3,1,3,1,3,1,3,1,3,1,0,0 +B3body-sml-buggy01,Level One,LIGHT,3,80,900,100,exbuggy.PIE,50,1,2200,3,1,3,1,3,1,3,1,3,1,3,1,0,0 +B2RKJeepBody,Level One,LIGHT,4,75,900,120,EXjeepRK.PIE,50,1,2200,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +B2JeepBody,Level One,LIGHT,4,75,900,120,EXjeep.PIE,50,1,2200,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +B1BaBaPerson01,Level All,HEAVY,1,20,100,29,EXBLOKE.PIE,50,1,125,1,1,1,1,1,1,1,1,1,1,1,1,0,0 diff --git a/data/stats/body.txt b/data/stats/body.txt index dd4111b5d..204c5e118 100644 --- a/data/stats/body.txt +++ b/data/stats/body.txt @@ -1,37 +1,37 @@ -ZNULLBODY,Level All,LIGHT,0,0,0,0,MIBNKBOD.PIE,20,1,0,0,0,0,0 +ZNULLBODY,Level All,LIGHT,0,0,0,0,MIBNKBOD.PIE,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 TransporterBody,Level All,SUPER HEAVY,0,5000,150,5000,drtrans.pie,100,1,2000,100,100,0,0 -Superbody,Level All,HEAVY,10,10,2700,9000,DRHBOD11.PIE,500,1,40000,999,999,0,0 -FireBody,Level One,LIGHT,4,75,3000,200,EXFIRE.PIE,50,1,4000,4,1,0,0 -CybRotMgGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CyborgRkt1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgFlamerGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgChn1CCGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CyborgChain1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgCannonGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -CyborgCan1CGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -CybNXRail1Jmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybNXPulseLasJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybNXMissJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,0,0 -CybFlamer01CGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0 -Cyb-Bod-Rail1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Las1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -Cyb-Bod-Atmiss,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,0,0 -BusBody,Level One,LIGHT,4,75,2000,200,EXSCHOOL.PIE,50,1,4000,4,1,0,0 -Body9REC,Level All,HEAVY,90,420,3300,225,DRHBOD09.PIE,500,1,18000,22,15,fxvtl09.pie,1 -Body8MBT,Level All,MEDIUM,37,250,1500,125,DRMBOD08.PIE,250,1,15000,12,12,fxvtl5to8.pie,1 -Body7ABT,Level Three,MEDIUM,150,600,1500,200,DRMBOD07.PIE,250,1,15000,24,20,fxvtl5to8.pie,1 -Body6SUPP,Level Two-Three,MEDIUM,70,300,2500,145,DRMBOD06.PIE,250,1,13000,18,9,fxvtl5to8.pie,1 -Body5REC,Level All,MEDIUM,50,250,2000,130,DRMBOD05.PIE,250,1,15000,15,6,fxvtl5to8.pie,1 -Body4ABT,Level All,LIGHT,20,100,450,55,DRLBOD04.PIE,100,1,5000,8,8,fxvtl04.pie,1 -Body3MBT,Level Three,LIGHT,100,400,450,100,DRLBOD03.PIE,100,1,5000,20,15,fxvtl2and3.pie,1 -Body2SUP,Level All,LIGHT,50,220,750,85,DRLBOD02.PIE,100,1,4000,12,6,fxvtl2and3.pie,1 -Body1REC,Level All,LIGHT,30,150,600,65,DRLBOD01.PIE,100,1,5000,10,4,fxvtl01.pie,1 -Body12SUP,Level All,HEAVY,55,350,2100,180,DRHBOD12.PIE,500,1,20000,18,18,fxvtl12.pie,1 -Body11ABT,Level All,HEAVY,70,350,2700,200,DRHBOD11.PIE,500,1,20000,20,9,fxvtl11.pie,1 -Body10MBT,Level Three,HEAVY,200,800,2500,300,DRHBOD10.PIE,500,1,23000,28,25,fxvtl10.pie,1 -B4body-sml-trike01,Level One,LIGHT,2,65,675,80,extrike.PIE,35,1,2100,1,1,0,0 -B3bodyRKbuggy01,Level One,LIGHT,3,80,900,100,exbugRK.PIE,50,1,2200,3,1,0,0 -B3body-sml-buggy01,Level One,LIGHT,3,80,900,100,exbuggy.PIE,50,1,2200,3,1,0,0 -B2RKJeepBody,Level One,LIGHT,4,75,900,120,EXjeepRK.PIE,50,1,2200,4,1,0,0 -B2JeepBody,Level One,LIGHT,4,75,900,120,EXjeep.PIE,50,1,2200,4,1,0,0 -B1BaBaPerson01,Level All,HEAVY,1,20,100,29,EXBLOKE.PIE,50,1,125,1,1,0,0 +Superbody,Level All,HEAVY,10,10,2700,9000,DRHBOD11.PIE,500,1,40000,999,999,999,999,999,999,999,999,999,999,999,999,0,0 +FireBody,Level One,LIGHT,4,75,3000,200,EXFIRE.PIE,50,1,4000,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +CybRotMgGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgRkt1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgFlamerGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgChn1CCGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgChain1Ground,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgCannonGrd,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CyborgCan1CGround,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +CybNXRail1Jmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybNXPulseLasJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybNXMissJmp,Level All,LIGHT,30,125,150,370,cybd_std.pie,100,1,675,18,15,18,15,18,15,18,15,18,15,18,15,0,0 +CybFlamer01CGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Rail1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Las1,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +Cyb-Bod-Atmiss,Level All,LIGHT,30,125,150,200,cybd_std.pie,100,1,500,12,6,12,6,12,6,12,6,12,6,12,6,0,0 +BusBody,Level One,LIGHT,4,75,2000,200,EXSCHOOL.PIE,50,1,4000,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +Body9REC,Level All,HEAVY,90,420,3300,225,DRHBOD09.PIE,500,1,18000,22,15,22,15,22,15,22,15,22,15,22,15,fxvtl09.pie,1 +Body8MBT,Level All,MEDIUM,37,250,1500,125,DRMBOD08.PIE,250,1,15000,12,12,12,12,12,12,12,12,12,12,12,12,fxvtl5to8.pie,1 +Body7ABT,Level Three,MEDIUM,150,600,1500,200,DRMBOD07.PIE,250,1,15000,24,20,24,20,24,20,24,20,24,20,24,20,fxvtl5to8.pie,1 +Body6SUPP,Level Two-Three,MEDIUM,70,300,2500,145,DRMBOD06.PIE,250,1,13000,18,9,18,9,18,9,18,9,18,9,18,9,fxvtl5to8.pie,1 +Body5REC,Level All,MEDIUM,50,250,2000,130,DRMBOD05.PIE,250,1,15000,15,6,15,6,15,6,15,6,15,6,15,6,fxvtl5to8.pie,1 +Body4ABT,Level All,LIGHT,20,100,450,55,DRLBOD04.PIE,100,1,5000,8,8,8,8,8,8,8,8,8,8,8,8,fxvtl04.pie,1 +Body3MBT,Level Three,LIGHT,100,400,450,100,DRLBOD03.PIE,100,1,5000,20,15,20,15,20,15,20,15,20,15,20,15,fxvtl2and3.pie,1 +Body2SUP,Level All,LIGHT,50,220,750,85,DRLBOD02.PIE,100,1,4000,12,6,12,6,12,6,12,6,12,6,12,6,fxvtl2and3.pie,1 +Body1REC,Level All,LIGHT,30,150,600,65,DRLBOD01.PIE,100,1,5000,10,4,10,4,10,4,10,4,10,4,10,4,fxvtl01.pie,1 +Body12SUP,Level All,HEAVY,55,350,2100,180,DRHBOD12.PIE,500,1,20000,18,18,18,18,18,18,18,18,18,18,18,18,fxvtl12.pie,1 +Body11ABT,Level All,HEAVY,70,350,2700,200,DRHBOD11.PIE,500,1,20000,20,9,20,9,20,9,20,9,20,9,20,9,fxvtl11.pie,1 +Body10MBT,Level Three,HEAVY,200,800,2500,300,DRHBOD10.PIE,500,1,23000,28,25,28,25,28,25,28,25,28,25,28,25,fxvtl10.pie,1 +B4body-sml-trike01,Level One,LIGHT,2,65,675,80,extrike.PIE,35,1,2100,1,1,1,1,1,1,1,1,1,1,1,1,0,0 +B3bodyRKbuggy01,Level One,LIGHT,3,80,900,100,exbugRK.PIE,50,1,2200,3,1,3,1,3,1,3,1,3,1,3,1,0,0 +B3body-sml-buggy01,Level One,LIGHT,3,80,900,100,exbuggy.PIE,50,1,2200,3,1,3,1,3,1,3,1,3,1,3,1,0,0 +B2RKJeepBody,Level One,LIGHT,4,75,900,120,EXjeepRK.PIE,50,1,2200,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +B2JeepBody,Level One,LIGHT,4,75,900,120,EXjeep.PIE,50,1,2200,4,1,4,1,4,1,4,1,4,1,4,1,0,0 +B1BaBaPerson01,Level All,HEAVY,1,20,100,29,EXBLOKE.PIE,50,1,125,1,1,1,1,1,1,1,1,1,1,1,1,0,0 diff --git a/src/action.c b/src/action.c index bef195e94..94c3b027a 100644 --- a/src/action.c +++ b/src/action.c @@ -891,7 +891,7 @@ BOOL actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, UWORD *p ( proj_Direct( psWeapStats ) || ( (psAttacker->type == OBJ_DROID) && !proj_Direct( psWeapStats ) && - (actionInsideMinRange(psDroid, psDroid->psActionTarget[weapon_slot]) > 1) )) ) + (actionInsideMinRange(psDroid, psDroid->psActionTarget[0]) & (1 << (1 + weapon_slot))) )) ) { // difference between muzzle position and droid origin is unlikely to affect aiming // particularly as target origin is used @@ -975,24 +975,10 @@ BOOL actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, UWORD *p int actionVisibleTarget(DROID *psDroid, BASE_OBJECT *psTarget) { WEAPON_STATS *psStats; - //Watermelon:weapon_slot - int num_weapons = 0; int result = 1; int i; - //if (psDroid->numWeaps == 0) - /* Watermelon:if I am a multi-turret droid */ - if (psDroid->numWeaps > 0) - { - for(i = 0;i < psDroid->numWeaps;i++) - { - if (psDroid->asWeaps[i].nStat != 0) - { - num_weapons += (1 << (i+1)); - } - } - } - else + if (psDroid->numWeaps == 0) { if (psDroid->asWeaps[0].nStat == 0) { @@ -1008,39 +994,41 @@ int actionVisibleTarget(DROID *psDroid, BASE_OBJECT *psTarget) { if ( visibleObject((BASE_OBJECT*)psDroid, psTarget) ) { - return 2; + for (i = 0;i < psDroid->numWeaps;i++) + { + result += (1 << (i + 1)); + } + return result; } + return result; } for(i = 0;i < psDroid->numWeaps;i++) { - if (num_weapons & (1 << (i+1))) + psStats = asWeaponStats + psDroid->asWeaps[i].nStat; + if (proj_Direct(psStats)) { - psStats = asWeaponStats + psDroid->asWeaps[i].nStat; - if (proj_Direct(psStats)) + if (visibleObjWallBlock((BASE_OBJECT*)psDroid, psTarget)) { - if (visibleObjWallBlock((BASE_OBJECT*)psDroid, psTarget)) + result += (1 << (i+1)); + } + } + else + { + // indirect can only attack things they can see unless attacking + // through a sensor droid - see DORDER_FIRESUPPORT + if (orderState(psDroid, DORDER_FIRESUPPORT)) + { + if (psTarget->visible[psDroid->player]) { result += (1 << (i+1)); } } else { - // indirect can only attack things they can see unless attacking - // through a sensor droid - see DORDER_FIRESUPPORT - if (orderState(psDroid, DORDER_FIRESUPPORT)) + if (visibleObject((BASE_OBJECT*)psDroid, psTarget)) { - if (psTarget->visible[psDroid->player]) - { - result += (1 << (i+1)); - } - } - else - { - if (visibleObject((BASE_OBJECT*)psDroid, psTarget)) - { - result += (1 << (i+1)); - } + result += (1 << (i+1)); } } } @@ -1115,7 +1103,7 @@ static void actionAddVtolAttackRun( DROID *psDroid ) static void actionUpdateVtolAttack( DROID *psDroid ) { - WEAPON_STATS *psWeapStats = NULL; + WEAPON_STATS *psWeapStats[DROID_MAXWEAPS]; int i; /* don't do attack runs whilst returning to base */ @@ -1132,7 +1120,7 @@ static void actionUpdateVtolAttack( DROID *psDroid ) { if (psDroid->asWeaps[i].nStat != 0) { - psWeapStats = asWeaponStats + psDroid->asWeaps[i].nStat; + psWeapStats[i] = asWeaponStats + psDroid->asWeaps[i].nStat; ASSERT( PTRVALID(psWeapStats, sizeof(WEAPON_STATS)), "actionUpdateVtolAttack: invalid weapon stats pointer" ); break; @@ -1143,14 +1131,14 @@ static void actionUpdateVtolAttack( DROID *psDroid ) { if (psDroid->asWeaps[0].nStat > 0) { - psWeapStats = asWeaponStats + psDroid->asWeaps[0].nStat; + psWeapStats[0] = asWeaponStats + psDroid->asWeaps[0].nStat; ASSERT( PTRVALID(psWeapStats, sizeof(WEAPON_STATS)), "actionUpdateVtolAttack: invalid weapon stats pointer" ); } } /* order back to base after fixed number of attack runs */ - if ( psWeapStats != NULL ) + if ( psWeapStats[0] != NULL ) { //if ( psDroid->sMove.iAttackRuns >= psWeapStats->vtolAttackRuns ) if (vtolEmpty(psDroid)) @@ -2085,7 +2073,7 @@ void actionUpdateDroid(DROID *psDroid) psWeapStats = asWeaponStats + psDroid->asWeaps[i].nStat; if (avtResult & (1 << (i+1))) { - if ( (actionInRange(psDroid, psDroid->psActionTarget[i]) & (1 << i)) ) + if ( (actionInRange(psDroid, psDroid->psActionTarget[0]) & (1 << i)) ) { if ( psDroid->player == selectedPlayer ) { @@ -2093,19 +2081,19 @@ void actionUpdateDroid(DROID *psDroid) VTOL_ATTACK_AUDIO_DELAY ); } - if (actionTargetTurret((BASE_OBJECT*)psDroid, psDroid->psActionTarget[i], + if (actionTargetTurret((BASE_OBJECT*)psDroid, psDroid->psActionTarget[0], &(psDroid->turretRotation[i]), &(psDroid->turretPitch[i]), &asWeaponStats[psDroid->asWeaps[i].nStat], bInvert,i)) { // In range - fire !!! combFire(&psDroid->asWeaps[i], (BASE_OBJECT *)psDroid, - psDroid->psActionTarget[i], i); + psDroid->psActionTarget[0], i); } } else { - actionTargetTurret((BASE_OBJECT*)psDroid, psDroid->psActionTarget[i], + actionTargetTurret((BASE_OBJECT*)psDroid, psDroid->psActionTarget[0], &(psDroid->turretRotation[i]), &(psDroid->turretPitch[i]), &asWeaponStats[psDroid->asWeaps[i].nStat], bInvert,i); @@ -3468,6 +3456,7 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction) psDroid->psActionTarget[0] = psDroid->psTarget[0]; moveDroidTo(psDroid, psAction->x, psAction->y); break; + default: ASSERT( FALSE, "actionUnitBase: unknown action" ); break; @@ -3712,3 +3701,4 @@ exit: + diff --git a/src/action.h b/src/action.h index 92a2a44a1..8e211b0fb 100644 --- a/src/action.h +++ b/src/action.h @@ -59,6 +59,7 @@ typedef enum _droid_action DACTION_RETURNTOPOS, // (38) used by scout/patrol order when returning to route DACTION_FIRESUPPORT_RETREAT, // (39) used by firesupport order when sensor retreats DACTION_ATTACK_M, // (40) attack with multiple weapons + DACTION_CIRCLE, // (41) circling while engaging } DROID_ACTION; // after failing a route ... this is the amount of time that the droid goes all defensive untill it can start going aggressive @@ -135,3 +136,4 @@ extern BOOL actionVTOLLandingPos(DROID *psDroid, UDWORD *px, UDWORD *py); + diff --git a/src/ai.c b/src/ai.c index 2158b684f..88fb849ab 100644 --- a/src/ai.c +++ b/src/ai.c @@ -349,7 +349,6 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BOOL bCommanderBlock; UDWORD sensorRange; //Watermelon:weapon_slot to store which turrent is InAttackRange - int i; /* Get the sensor range */ switch (psObj->type) diff --git a/src/combat.c b/src/combat.c index 154264f95..59accc8a6 100644 --- a/src/combat.c +++ b/src/combat.c @@ -114,6 +114,17 @@ void combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in ASSERT( PTRVALID(psTarget, sizeof(BASE_OBJECT)), "combFire: Invalid target pointer" ); + /* Watermelon:dont shoot if the weapon_slot of a vtol is empty */ + if (psAttacker->type == OBJ_DROID && + vtolDroid(((DROID *)psAttacker))) + { + if (((DROID *)psAttacker)->sMove.iAttackRuns[weapon_slot] >= getNumAttackRuns(((DROID *)psAttacker), weapon_slot)) + { + debug(LOG_NEVER, "VTOL slot %d is empty", weapon_slot); + return; + } + } + /* Get the stats for the weapon */ psStats = asWeaponStats + psWeap->nStat; diff --git a/src/component.c b/src/component.c index 622b7927e..9203788a1 100644 --- a/src/component.c +++ b/src/component.c @@ -49,11 +49,14 @@ void setMatrix(iVector *Position,iVector *Rotation,iVector *CameraPos,BOOL RotXY #define DROID_EMP_SPREAD (20 - rand()%40) +//Watermelon:VTOL weapon connector start +#define VTOL_CONNECTOR_START 5 + UDWORD droidScale = 100; void displayComponentTemplate(DROID_TEMPLATE *psTemplate); //void displayComponentObject(BASE_OBJECT *psObj); -//Watermelon:updated protocol for displayCompObj -static void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], BOOL bButton); +//Watermelon:updated prototype for displayCompObj again +static void displayCompObj(BASE_OBJECT *psObj, BOOL bButton); static iIMDShape *getLeftPropulsionIMD(DROID *psDroid); static iIMDShape *getRightPropulsionIMD(DROID *psDroid); @@ -717,18 +720,7 @@ void displayComponentButtonTemplate(DROID_TEMPLATE *psTemplate, { static DROID Droid; // Made static to reduce stack usage. SDWORD difference; - //Watermelon:make it contain DROID_MAXWEAPS Vector info - iVector mountRotation[DROID_MAXWEAPS]; iVector TmpCamPos = {0,0,0}; - int i; - - //Watermelon:I need to initialise the values of this,since DROID_MAXWEAPS is not a 'constant' - for(i = 0;i < psTemplate->numWeaps;i++) - { - mountRotation[i].x = 0; - mountRotation[i].y = 0; - mountRotation[i].z = 0; - } /* init to NULL */ memset( &Droid, 0, sizeof(DROID) ); @@ -755,7 +747,7 @@ void displayComponentButtonTemplate(DROID_TEMPLATE *psTemplate, Droid.x = Droid.y = Droid.z = 0; //draw multi component object as a button object - displayCompObj((BASE_OBJECT*)&Droid,&mountRotation,TRUE); + displayCompObj((BASE_OBJECT*)&Droid, TRUE); unsetMatrix(); @@ -768,18 +760,7 @@ void displayComponentButtonObject(DROID *psDroid, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { SDWORD difference; - //Watermelon:make it contain DROID_MAXWEAPS Vector info - iVector mountRotation[DROID_MAXWEAPS]; iVector TmpCamPos = {0,0,0}; - int i; - - //Watermelon:I need to initialise the values of this,since DROID_MAXWEAPS is not a 'constant' - for(i = 0;i < psDroid->numWeaps;i++) - { - mountRotation[i].x = 0; - mountRotation[i].y = 0; - mountRotation[i].z = 0; - } setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); @@ -798,7 +779,7 @@ void displayComponentButtonObject(DROID *psDroid, // And render the composite object. //draw multi component object as a button object - displayCompObj((BASE_OBJECT*)psDroid,&mountRotation,TRUE); + displayCompObj((BASE_OBJECT*)psDroid, TRUE); unsetMatrix(); } @@ -806,14 +787,12 @@ void displayComponentButtonObject(DROID *psDroid, /* Assumes matrix context is already set */ -// Watermelon:multiple turrets display +// Watermelon:multiple turrets display removed the pointless mountRotation void displayComponentObject(BASE_OBJECT *psObj) { DROID *psDroid; //iIMDShape *psShape; -//Watermelon:mountRotation is array now iVector position,rotation; //,null; -iVector mountRotation[DROID_MAXWEAPS]; //iPoint screenCoords; //SDWORD dummyZ; int32 xShift,zShift; @@ -823,20 +802,10 @@ SDWORD frame; PROPULSION_STATS *psPropStats; UDWORD tileX,tileY; MAPTILE *psTile; -//Watermelon:added int iWeapons,i; -int iWeapons = 0; -int i = 0; psDroid = (DROID *)psObj; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; - for(i = 0;i < psDroid->numWeaps;i++) - { - mountRotation[i].x = 0; - mountRotation[i].y = 0; - mountRotation[i].z = 0; - } - worldAngle = (UDWORD) ((UDWORD)player.r.y/DEG_1)%360; difference = (worldAngle-psObj->direction); @@ -880,31 +849,7 @@ int i = 0; /* Get rotation info for the mounting too (holds the gun */ - // Watermelon:added check against droid type - if ( psDroid->type == OBJ_DROID ) - { - if ( psDroid->droidType == DROID_WEAPON ) - { - for(iWeapons = 0;iWeapons < psDroid->numWeaps;iWeapons++) - { - mountRotation[iWeapons].y = -(SDWORD)psDroid->turretRotation[iWeapons]; - mountRotation[iWeapons].x = psDroid->turretPitch[iWeapons]; - mountRotation[iWeapons].z = 0; - } - } - else - { - mountRotation[0].y = -(SDWORD)((DROID *)psObj)->turretRotation[0]; - mountRotation[0].x = ((DROID *)psObj)->turretPitch[0]; - mountRotation[0].z = 0; - } - } - else - { - mountRotation[0].y = -(SDWORD)((DROID *)psObj)->turretRotation[0]; - mountRotation[0].x = ((DROID *)psObj)->turretPitch[0]; - mountRotation[0].z = 0; - } + // Watermelon:obsolete,since I move it to displayCompObj /* Translate origin */ pie_TRANSLATE(position.x,position.y,position.z); @@ -936,7 +881,7 @@ int i = 0; { //ingame not button object //Watermelon:should render 3 mounted weapons now - displayCompObj(psObj,&mountRotation,FALSE); + displayCompObj(psObj,FALSE); } else { @@ -968,8 +913,8 @@ int i = 0; /* Assumes matrix context is already set */ // Watermelon:this is able to handle multiple weapon graphics now -// mountRotation is iVector array contains mountRotation from all weapons now!!! -void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], BOOL bButton) +// removed mountRotation,they get such stuff from psObj directly now +void displayCompObj(BASE_OBJECT *psObj, BOOL bButton) { DROID *psDroid; //Watermelon:I need another temp pointer to Shape @@ -1170,10 +1115,12 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], { /* vtol weapons attach to connector 2 (underneath); * all others to connector 1 */ + /* Watermelon:VTOL's now skip the first 5 connectors(0 to 4), + VTOL's use 5,6,7,8 etc now */ if ( (psPropStats->propulsionType == LIFT) && psDroid->droidType == DROID_WEAPON ) { - iConnector = 1; + iConnector = VTOL_CONNECTOR_START; } else { @@ -1237,8 +1184,8 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); - //Watermelon:to skip connectors[1](VOTL hardpoint) - if ( i == 0 ) + //Watermelon:to skip number of VTOL_CONNECTOR_START ground unit connectors + if ( iConnector < VTOL_CONNECTOR_START ) { //Watermelon:midpoint for heavybody with only 1 weapon if ( psDroid->numWeaps == 1 && @@ -1251,25 +1198,16 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], } else { - pie_TRANSLATE( psShapeTemp->connectors[iConnector].x, - psShapeTemp->connectors[iConnector].z, - psShapeTemp->connectors[iConnector].y ); + pie_TRANSLATE( psShapeTemp->connectors[i].x, + psShapeTemp->connectors[i].z, + psShapeTemp->connectors[i].y ); } } - else if ( i > 0 ) + else { - if ( iConnector == 1 ) - { - pie_TRANSLATE( psShapeTemp->connectors[iConnector].x, - psShapeTemp->connectors[iConnector].z, - psShapeTemp->connectors[iConnector].y ); - } - else - { - pie_TRANSLATE( psShapeTemp->connectors[i+1].x, - psShapeTemp->connectors[i+1].z, - psShapeTemp->connectors[i+1].y ); - } + pie_TRANSLATE( psShapeTemp->connectors[iConnector + i].x, + psShapeTemp->connectors[iConnector + i].z, + psShapeTemp->connectors[iConnector + i].y ); } if ( psDroid->turretRotation[i] ) @@ -1279,7 +1217,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } @@ -1312,7 +1250,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], } /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { //pitch the barrel down pie_MatRotX(DEG( (-(psDroid->turretPitch[i])) )); @@ -1382,7 +1320,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } @@ -1427,7 +1365,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } @@ -1474,7 +1412,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } @@ -1513,7 +1451,7 @@ void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ - if ( iConnector == 1 ) + if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } @@ -1830,3 +1768,4 @@ SDWORD rescaleButtonObject(SDWORD radius, SDWORD baseScale,SDWORD baseRadius) + diff --git a/src/design.c b/src/design.c index 61f2a71f6..5609f05ab 100644 --- a/src/design.c +++ b/src/design.c @@ -1471,7 +1471,6 @@ static COMP_BASE_STATS * intChooseSystemStats( DROID_TEMPLATE *psTemplate ) { COMP_BASE_STATS *psStats = NULL; - int i; // Check for a command droid @@ -1630,7 +1629,7 @@ char *GetDefaultTemplateName(DROID_TEMPLATE *psTemplate) if ( psTemplate->numWeaps > 1 ) { - strcat( aCurrName, " hydra " ); + strcat( aCurrName, "Hydra " ); } psStats = (COMP_BASE_STATS *) (asBodyStats + psTemplate->asParts[COMP_BODY]); @@ -3569,11 +3568,11 @@ static void intSetBodyStats(BODY_STATS *psStats) //do kinetic armour //widgSetBarSize(psWScreen, IDDES_BODYARMOUR_K, psStats->armourValue[WC_KINETIC]); widgSetBarSize(psWScreen, IDDES_BODYARMOUR_K, bodyArmour(psStats, - (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_KINETIC)); + (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_KINETIC, 0)); //do heat armour //widgSetBarSize(psWScreen, IDDES_BODYARMOUR_H, psStats->armourValue[WC_HEAT] ); widgSetBarSize(psWScreen, IDDES_BODYARMOUR_H, bodyArmour(psStats, - (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_HEAT)); + (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_HEAT, 0)); /* body points */ /*size = WBAR_SCALE * psStats->body/DBAR_BODYMAXPOINTS; if (size > WBAR_SCALE) @@ -3613,11 +3612,11 @@ static void intSetBodyShadowStats(BODY_STATS *psStats) //size = WBAR_SCALE * psStats->armourValue/DBAR_BODYMAXARMOUR; //widgSetMinorBarSize(psWScreen, IDDES_BODYARMOUR_K,psStats->armourValue[WC_KINETIC]); widgSetMinorBarSize(psWScreen, IDDES_BODYARMOUR_K, bodyArmour(psStats, - (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_KINETIC)); + (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_KINETIC, 0)); //armour - heat //widgSetMinorBarSize(psWScreen, IDDES_BODYARMOUR_H,psStats->armourValue[WC_HEAT]); widgSetMinorBarSize(psWScreen, IDDES_BODYARMOUR_H,bodyArmour(psStats, - (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_HEAT)); + (UBYTE)selectedPlayer, DROID_BODY_UPGRADE, WC_HEAT, 0)); /* body points */ // size = WBAR_SCALE * psStats->bodyPoints/DBAR_BODYMAXPOINTS; // if (size > WBAR_SCALE) @@ -4452,8 +4451,7 @@ void intProcessDesign(UDWORD id) sCurrDesign.asParts[COMP_REPAIRUNIT] = 0; sCurrDesign.asParts[COMP_BRAIN] = 0; //Watemelon:weaponslots >= 2 - if( (asBodyStats + sCurrDesign.asParts[COMP_BODY])->weaponSlots >= 2 && - !checkTemplateIsVtol(&sCurrDesign) ) + if( (asBodyStats + sCurrDesign.asParts[COMP_BODY])->weaponSlots >= 2 ) { /* reveal turret_a button if hidden */ widgReveal( psWScreen, IDDES_WPABUTTON ); @@ -4481,8 +4479,7 @@ void intProcessDesign(UDWORD id) sCurrDesign.asParts[COMP_REPAIRUNIT] = 0; sCurrDesign.asParts[COMP_BRAIN] = 0; //Watemelon:weaponSlots > 2 - if( (asBodyStats + sCurrDesign.asParts[COMP_BODY])->weaponSlots > 2 && - !checkTemplateIsVtol(&sCurrDesign) ) + if( (asBodyStats + sCurrDesign.asParts[COMP_BODY])->weaponSlots > 2 ) { /* reveal turret_b button if hidden */ widgReveal( psWScreen, IDDES_WPBBUTTON ); @@ -4556,6 +4553,8 @@ void intProcessDesign(UDWORD id) /* Set the new stats on the display */ intSetPropulsionStats((PROPULSION_STATS *)apsComponentList[id - IDDES_COMPSTART]); + //Watermelon:no need to do this now + /* if(checkTemplateIsVtol(&sCurrDesign)) { //Watermelon:hide WeaponA and WeaponB button,or it will problematic @@ -4563,6 +4562,7 @@ void intProcessDesign(UDWORD id) widgHide( psWScreen, IDDES_WPABUTTON ); widgHide( psWScreen, IDDES_WPBBUTTON ); } + */ //check that the weapon is valid for this propulsion if (!intCheckValidWeaponForProp()) @@ -4578,6 +4578,7 @@ void intProcessDesign(UDWORD id) //Reset slot 2,3 weapons so it wont cause more than one weapon on VTOL problem sCurrDesign.asWeaps[1] = 0; sCurrDesign.asWeaps[2] = 0; + /* if(checkTemplateIsVtol(&sCurrDesign)) { //Watermelon:hide WeaponA and WeaponB button,or it will problematic @@ -4585,6 +4586,7 @@ void intProcessDesign(UDWORD id) widgHide( psWScreen, IDDES_WPABUTTON ); widgHide( psWScreen, IDDES_WPBBUTTON ); } + */ } //not valid weapon so initialise the weapon stat sCurrDesign.asWeaps[0] = 0; diff --git a/src/display3d.c b/src/display3d.c index 235da56ee..851c94861 100644 --- a/src/display3d.c +++ b/src/display3d.c @@ -3540,9 +3540,9 @@ static void drawWeaponReloadBar(BASE_OBJECT *psObj, WEAPON *psWeap, int weapon_s vtolDroid((DROID *)psObj)) { //deal with VTOLs - firingStage = getNumAttackRuns((DROID *)psObj) - ((DROID *)psObj)->sMove.iAttackRuns; + firingStage = getNumAttackRuns((DROID *)psObj, weapon_slot) - ((DROID *)psObj)->sMove.iAttackRuns[weapon_slot]; //compare with max value - interval = getNumAttackRuns((DROID *)psObj); + interval = getNumAttackRuns((DROID *)psObj, weapon_slot); } else { diff --git a/src/droid.c b/src/droid.c index 824e6acb8..0f39bcf53 100644 --- a/src/droid.c +++ b/src/droid.c @@ -145,20 +145,18 @@ BOOL droidInit(void) */ #define UNIT_LOST_DELAY (5*GAME_TICKS_PER_SEC) -BOOL droidDamage(DROID *psDroid, UDWORD damage, UDWORD weaponClass, UDWORD weaponSubClass) +BOOL droidDamage(DROID *psDroid, UDWORD damage, UDWORD weaponClass, UDWORD weaponSubClass, int angle) { UDWORD penDamage, armourDamage; BOOL penetrated = FALSE; UDWORD armour=0; SECONDARY_STATE state; SDWORD level, cmdLevel; + DROID_HIT_SIDE impact_side; ASSERT( PTRVALID(psDroid, sizeof(DROID)), "unitDamage: Invalid Unit pointer" ); - debug( LOG_ATTACK, "unitDamage(%d): body %d armour %d damage: %d\n", - psDroid->id, psDroid->body, psDroid->armour[WC_KINETIC], damage); - //EMP cannons do not do body damage if (weaponSubClass == WSC_EMP) { @@ -206,23 +204,58 @@ BOOL droidDamage(DROID *psDroid, UDWORD damage, UDWORD weaponClass, UDWORD weapo } } + //Watermelon:use 361 for TOP and 362 for BOTTOM + //TOP + if (angle == HIT_ANGLE_TOP) + { + impact_side = HIT_SIDE_TOP; //4 + } + //BOTTOM + else if (angle == HIT_ANGLE_BOTTOM) + { + impact_side = HIT_SIDE_BOTTOM; //5 + } + //FRONT + else if (angle <= 45 || angle >= 315) + { + impact_side = HIT_SIDE_FRONT; //0 + } + //RIGHT + else if (angle > 45 && angle < 135) + { + impact_side = HIT_SIDE_RIGHT; //3 + } + //REAR + else if (angle >= 135 && angle <= 225) + { + impact_side = HIT_SIDE_REAR; //1 + } + //LEFT + else if (angle > 225 && angle < 315) + { + impact_side = HIT_SIDE_LEFT; //2 + } + + debug( LOG_ATTACK, "unitDamage(%d): body %d armour %d damage: %d\n", + psDroid->id, psDroid->body, psDroid->armour[impact_side][WC_KINETIC], damage); + switch (weaponClass) { case WC_KINETIC: //case WC_EXPLOSIVE: - if (damage > psDroid->armour[WC_KINETIC]) + if (damage > psDroid->armour[impact_side][WC_KINETIC]) { penetrated = TRUE; } - armour = psDroid->armour[WC_KINETIC]; + armour = psDroid->armour[impact_side][WC_KINETIC]; break; case WC_HEAT: //case WC_MISC: - if (damage > psDroid->armour[WC_HEAT]) + if (damage > psDroid->armour[impact_side][WC_HEAT]) { penetrated = TRUE; } - armour = psDroid->armour[WC_HEAT]; + armour = psDroid->armour[impact_side][WC_HEAT]; break; } @@ -1442,7 +1475,8 @@ void droidUpdate(DROID *psDroid) psDroid->burnDamage += damageToDo; //psDroid->damage(psDroid, damageToDo, WC_HEAT); - (void)droidDamage(psDroid, damageToDo, WC_HEAT,WSC_FLAME); + //Watermelon:just assume the burn damage is from FRONT + (void)droidDamage(psDroid, damageToDo, WC_HEAT,WSC_FLAME, 0); } } @@ -3582,7 +3616,7 @@ BOOL loadDroidWeapons(char *pWeaponData, UDWORD bufferSize) //if weapon not found - error if (incW[j] == -1) { - debug( LOG_ERROR, "Unable to find Weapon %s for template %s", WeaponNameA[i], TemplateName ); + debug( LOG_ERROR, "Unable to find Weapon %s for template %s", WeaponNameA, TemplateName ); abort(); return FALSE; } @@ -4113,6 +4147,7 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, // UDWORD tileX,tileY; // BOOL gotPos; // UDWORD numIts; + DROID_HIT_SIDE impact_side; /* @@ -4360,17 +4395,23 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player, { for (inc = 0; inc < NUM_WEAPON_CLASS; inc++) { - //psDroid->armour[inc] = (asBodyStats + pTemplate->asParts[COMP_BODY])->armourValue[inc]; - psDroid->armour[inc] = bodyArmour(asBodyStats + pTemplate-> - asParts[COMP_BODY], (UBYTE)player, CYBORG_BODY_UPGRADE, (WEAPON_CLASS)inc); + for (impact_side = 0;impact_side < NUM_HIT_SIDES;impact_side++) + { + //psDroid->armour[inc] = (asBodyStats + pTemplate->asParts[COMP_BODY])->armourValue[inc]; + psDroid->armour[impact_side][inc] = bodyArmour(asBodyStats + pTemplate-> + asParts[COMP_BODY], (UBYTE)player, CYBORG_BODY_UPGRADE, (WEAPON_CLASS)inc, impact_side); + } } } else { for (inc = 0; inc < NUM_WEAPON_CLASS; inc++) { - psDroid->armour[inc] = bodyArmour(asBodyStats + pTemplate-> - asParts[COMP_BODY], (UBYTE)player, DROID_BODY_UPGRADE, (WEAPON_CLASS)inc); + for (impact_side = 0;impact_side < NUM_HIT_SIDES;impact_side++) + { + psDroid->armour[impact_side][inc] = bodyArmour(asBodyStats + pTemplate-> + asParts[COMP_BODY], (UBYTE)player, DROID_BODY_UPGRADE, (WEAPON_CLASS)inc, impact_side); + } } } @@ -6518,6 +6559,11 @@ BOOL vtolDroid(DROID *psDroid) /*returns TRUE if a VTOL Weapon Droid which has completed all runs*/ BOOL vtolEmpty(DROID *psDroid) { + int i; + int numVtolWeaps = 0; + int emptyWeaps = 0; + BOOL bEmpty = TRUE; + if (!vtolDroid(psDroid)) { return FALSE; @@ -6527,14 +6573,30 @@ BOOL vtolEmpty(DROID *psDroid) return FALSE; } - if (psDroid->sMove.iAttackRuns >= getNumAttackRuns(psDroid)) + if (psDroid->numWeaps > 0) { - return TRUE; + for (i = 0;i < psDroid->numWeaps;i++) + { + if (asWeaponStats[psDroid->asWeaps[i].nStat].vtolAttackRuns > 0) + { + numVtolWeaps += (1 << (1 + i)); + if (psDroid->sMove.iAttackRuns[i] >= getNumAttackRuns(psDroid, i)) + { + emptyWeaps += (1 << (1 + i)); + } + } + } } - else + + for (i = 0;i < psDroid->numWeaps;i++) { - return FALSE; + if ((numVtolWeaps & (1 << (1 + i))) && !(emptyWeaps & (1 << (1 + i)))) + { + bEmpty = FALSE; + break; + } } + return bEmpty; } // true if a vtol is waiting to be rearmed by a particular rearm pad @@ -6653,7 +6715,8 @@ BOOL allVtolsRearmed(DROID *psDroid) /*returns a count of the base number of attack runs for the weapon attached to the droid*/ -UWORD getNumAttackRuns(DROID *psDroid) +//Watermelon:adds int weapon_slot +UWORD getNumAttackRuns(DROID *psDroid, int weapon_slot) { UWORD numAttackRuns; @@ -6661,14 +6724,14 @@ UWORD getNumAttackRuns(DROID *psDroid) /*if weapon attached to the droid is a salvo weapon, then number of shots that can be fired = vtolAttackRuns*numRounds */ - if (asWeaponStats[psDroid->asWeaps[0].nStat].reloadTime) + if (asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].reloadTime) { - numAttackRuns = (UWORD)(asWeaponStats[psDroid->asWeaps[0].nStat].numRounds * - asWeaponStats[psDroid->asWeaps[0].nStat].vtolAttackRuns); + numAttackRuns = (UWORD)(asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].numRounds * + asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].vtolAttackRuns); } else { - numAttackRuns = asWeaponStats[psDroid->asWeaps[0].nStat].vtolAttackRuns; + numAttackRuns = asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].vtolAttackRuns; } return numAttackRuns; @@ -6678,29 +6741,65 @@ UWORD getNumAttackRuns(DROID *psDroid) leave reArm pad */ BOOL vtolHappy(DROID *psDroid) { + int i; + int numVtolWeaps = 0; + int rearmedWeaps = 0; + BOOL bHappy = TRUE; + ASSERT( vtolDroid(psDroid), "vtolHappy: not a VTOL droid" ); ASSERT( psDroid->droidType == DROID_WEAPON, "vtolHappy: not a weapon droid" ); //check full complement of ammo - if (psDroid->sMove.iAttackRuns == 0) + if (psDroid->numWeaps > 0) { - //check fully repaired - if (psDroid->body == psDroid->originalBody) + for (i = 0;i < psDroid->numWeaps;i++) + { + if (asWeaponStats[psDroid->asWeaps[i].nStat].vtolAttackRuns > 0) + { + numVtolWeaps += (1 << (1 + i)); + if (psDroid->sMove.iAttackRuns[i] == 0) + { + rearmedWeaps += (1 << (1 + i)); + } + } + } + + for (i = 0;i < psDroid->numWeaps;i++) + { + if ((numVtolWeaps & (1 << (1 + i))) && !(rearmedWeaps & (1 << (1 + i)))) + { + bHappy = FALSE; + break; + } + } + + if (bHappy && + psDroid->body == psDroid->originalBody) { return TRUE; } + else + { + return FALSE; + } } return FALSE; } /*checks if the droid is a VTOL droid and updates the attack runs as required*/ -void updateVtolAttackRun(DROID *psDroid) +void updateVtolAttackRun(DROID *psDroid , int weapon_slot) { if (vtolDroid(psDroid)) { - psDroid->sMove.iAttackRuns++; - //quick check doesn't go over limit - ASSERT( psDroid->sMove.iAttackRuns < UWORD_MAX, "updateVtolAttackRun: too many attack runs" ); + if (psDroid->numWeaps > 0) + { + if (asWeaponStats[psDroid->asWeaps[weapon_slot].nStat].vtolAttackRuns > 0) + { + psDroid->sMove.iAttackRuns[weapon_slot]++; + //quick check doesn't go over limit + ASSERT( psDroid->sMove.iAttackRuns[weapon_slot] < UWORD_MAX, "updateVtolAttackRun: too many attack runs" ); + } + } } } @@ -6708,14 +6807,18 @@ void updateVtolAttackRun(DROID *psDroid) offworld mission*/ void mendVtol(DROID *psDroid) { + int i; ASSERT( vtolEmpty(psDroid), "mendVtol: droid is not an empty weapon VTOL!" ); /* set rearm value to no runs made */ - psDroid->sMove.iAttackRuns = 0; - //reset ammo and lastTimeFired - psDroid->asWeaps[0].ammo = asWeaponStats[psDroid-> - asWeaps[0].nStat].numRounds; - psDroid->asWeaps[0].lastFired = 0; + for (i = 0;i < psDroid->numWeaps;i++) + { + psDroid->sMove.iAttackRuns[i] = 0; + //reset ammo and lastTimeFired + psDroid->asWeaps[i].ammo = asWeaponStats[psDroid-> + asWeaps[i].nStat].numRounds; + psDroid->asWeaps[i].lastFired = 0; + } /* set droid points to max */ psDroid->body = psDroid->originalBody; } @@ -6874,7 +6977,8 @@ DROID * giftSingleDroid(DROID *psD, UDWORD to) UWORD x, y, numKills, direction, i; DROID *psNewDroid, *psCurr; STRUCTURE *psStruct; - UDWORD body, armourK, armourH; + UDWORD body, armourK[NUM_HIT_SIDES], armourH[NUM_HIT_SIDES]; + DROID_HIT_SIDE impact_side; //leave any group it belongs to - this gets called in droidRemove() /*if(psD->psGroup) @@ -7000,8 +7104,11 @@ DROID * giftSingleDroid(DROID *psD, UDWORD to) x = psD->x; y = psD->y; body = psD->body; - armourK = psD->armour[WC_KINETIC]; - armourH = psD->armour[WC_HEAT]; + for (impact_side = 0;impact_side < NUM_HIT_SIDES;impact_side++) + { + armourK[impact_side] = psD->armour[impact_side][WC_KINETIC]; + armourH[impact_side] = psD->armour[impact_side][WC_HEAT]; + } numKills = psD->numKills; direction = psD->direction; //only play the sound if unit being taken over is selectedPlayer's but not going to the selectedPlayer @@ -7022,8 +7129,11 @@ DROID * giftSingleDroid(DROID *psD, UDWORD to) { addDroid(psNewDroid, apsDroidLists); psNewDroid->body = body; - psNewDroid->armour[WC_KINETIC] = armourK; - psNewDroid->armour[WC_HEAT] = armourH; + for (impact_side = 0;impact_side < NUM_HIT_SIDES;impact_side++) + { + psNewDroid->armour[impact_side][WC_KINETIC] = armourK[impact_side]; + psNewDroid->armour[impact_side][WC_HEAT] = armourH[impact_side]; + } psNewDroid->numKills = numKills; psNewDroid->direction = direction; if(!(psNewDroid->droidType == DROID_PERSON OR diff --git a/src/droid.h b/src/droid.h index 342fd30c0..69ddc99aa 100644 --- a/src/droid.h +++ b/src/droid.h @@ -123,7 +123,8 @@ BOOL idfDroid(DROID *psDroid); /* Do damage to a droid */ -extern BOOL droidDamage(DROID *psDroid, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass); +//Watermelon:added int angle,no need to use float since the difference between them is superficial. +extern BOOL droidDamage(DROID *psDroid, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass, int angle); /* The main update routine for all droids */ @@ -327,9 +328,9 @@ extern BOOL vtolHappy(DROID *psDroid); offworld mission*/ extern void mendVtol(DROID *psDroid); /*checks if the droid is a VTOL droid and updates the attack runs as required*/ -extern void updateVtolAttackRun(DROID *psDroid); +extern void updateVtolAttackRun(DROID *psDroid, int weapon_slot); /*returns a count of the base number of attack runs for the weapon attached to the droid*/ -extern UWORD getNumAttackRuns(DROID *psDroid); +extern UWORD getNumAttackRuns(DROID *psDroid, int weapon_slot); //assign rearmPad to the VTOL extern void assignVTOLPad(DROID *psNewDroid, STRUCTURE *psReArmPad); //don't use this function any more - the droid checks each frame for this to have died @@ -388,3 +389,4 @@ extern BOOL cyborgDroid(DROID *psDroid); #endif + diff --git a/src/droiddef.h b/src/droiddef.h index 134c57f4d..c8e576351 100644 --- a/src/droiddef.h +++ b/src/droiddef.h @@ -32,6 +32,7 @@ + /* The different types of droid */ // NOTE, if you add to, or change this list then you'll need // to update the DroidSelectionWeights lookup table in Display.c @@ -164,7 +165,8 @@ typedef struct _droid UDWORD ECMMod; UDWORD originalBody; //the original body points UDWORD body; // the current body points - UDWORD armour[NUM_WEAPON_CLASS]; + //Watermleon:armour of all sides + UDWORD armour[NUM_HIT_SIDES][NUM_WEAPON_CLASS]; //UDWORD power; //tjc UDWORD imdNum; UWORD numKills; diff --git a/src/game.c b/src/game.c index ed6753db2..cf3637240 100644 --- a/src/game.c +++ b/src/game.c @@ -587,7 +587,10 @@ typedef struct _save_move_control /* vtol movement - GJ */ SWORD iVertSpeed; - UWORD iAttackRuns; + /* Watermelon:I need num of DROID_MAXWEAPS of iAttackRuns */ + UWORD iAttackRuns[DROID_MAXWEAPS]; + /* Watermelon:guard radius */ + //UDWORD iGuardRadius; /* Only needed for Alex's movement update ? */ // UDWORD timeStarted; @@ -5962,7 +5965,18 @@ BOOL loadSaveDroidV(char *pFileData, UDWORD filesize, UDWORD numDroids, UDWORD v endian_uword(&psSaveDroid->sMove.bumpY); endian_udword(&psSaveDroid->sMove.shuffleStart); endian_sword(&psSaveDroid->sMove.iVertSpeed); - endian_uword(&psSaveDroid->sMove.iAttackRuns); + if( version == CURRENT_VERSION_NUM ) + { + for(i = 0;i < psSaveDroid->numWeaps;i++) + { + endian_uword(&psSaveDroid->sMove.iAttackRuns[i]); + } + //endian_uword(&psSaveDroid->sMove.iGuardRadius); + } + else + { + endian_uword(&psSaveDroid->sMove.iAttackRuns[0]) + } for(i = 0; i < TEMP_DROID_MAXPROGS; i++) { /* SAVE_WEAPON */ endian_udword(&psSaveDroid->asWeaps[i].hitPoints); @@ -6355,7 +6369,13 @@ static BOOL buildSaveDroidFromDroid(SAVE_DROID* psSaveDroid, DROID* psCurr, DROI } */ endian_sword(&psSaveDroid->sMove.iVertSpeed); - endian_uword(&psSaveDroid->sMove.iAttackRuns); + + for(i = 0;i < psSaveDroid->numWeaps;i++) + { + endian_uword(&psSaveDroid->sMove.iAttackRuns[i]); + } + //endian_uword(&psSaveDroid->sMove.iGuardRadius); + endian_sword(&psSaveDroid->formationDir); endian_sdword(&psSaveDroid->formationX); endian_sdword(&psSaveDroid->formationY); diff --git a/src/intorder.c b/src/intorder.c index cba72a783..ab61ce869 100644 --- a/src/intorder.c +++ b/src/intorder.c @@ -47,7 +47,7 @@ #define MAX_AVAILABLE_ORDERS 16 // Max available orders list. #define MAX_DISPLAYABLE_ORDERS 11 // Max number of displayable orders. #define MAX_ORDER_BUTS 5 // Max number of buttons for a given order. -#define NUM_ORDERS 11 // Number of orders in OrderButtons list. +#define NUM_ORDERS 12 // Number of orders in OrderButtons list. #define IDORDER_ATTACK_RANGE 8010 #define IDORDER_REPAIR_LEVEL 8020 @@ -60,6 +60,7 @@ #define IDORDER_ASSIGN_CYBORG_PRODUCTION 8090 #define IDORDER_FIRE_DESIGNATOR 8100 #define IDORDER_ASSIGN_VTOL_PRODUCTION 8110 +#define IDORDER_CIRCLE 8120 //#define IDORDER_RETURN_TO_BASE 8050 //#define IDORDER_DESTRUCT 8060 @@ -203,6 +204,21 @@ ORDERBUTTONS OrderButtons[NUM_ORDERS]= {DSS_PATROL_SET, 0, 0} }, + { + ORDBUTCLASS_NORMAL, + DSO_CIRCLE, + DSS_CIRCLE_MASK, + ORD_BTYPE_BOOLEAN, + ORD_JUSTIFY_COMBINE, + IDORDER_CIRCLE, + 1,0, + {IMAGE_ORD_PATROLUP, 0, 0}, + {IMAGE_ORD_PATROLUP, 0, 0}, + {IMAGE_DES_HILIGHT, 0, 0}, + {STR_DORD_PATROL, 0, 0}, + {DSS_CIRCLE_SET, 0, 0} + }, + { ORDBUTCLASS_NORMAL, DSO_HALTTYPE, diff --git a/src/move.c b/src/move.c index 148eb436c..c0adcf82c 100644 --- a/src/move.c +++ b/src/move.c @@ -4820,7 +4820,6 @@ void moveUpdateDroid(DROID *psDroid) // } // } break; - default: ASSERT( FALSE, "moveUpdateUnit: unknown move state" ); break; diff --git a/src/movedef.h b/src/movedef.h index cf4be56f9..dcfd45d6c 100644 --- a/src/movedef.h +++ b/src/movedef.h @@ -10,6 +10,8 @@ #define TRAVELSIZE 100 +//Watermelon:num of VTOL weapons should be same as DROID_MAXWEAPS +#define VTOL_MAXWEAPS 3 typedef struct _path_point { @@ -64,7 +66,10 @@ typedef struct _move_control /* vtol movement - GJ */ SWORD iVertSpeed; - UWORD iAttackRuns; + /* Watermelon:I need num of DROID_MAXWEAPS of iAttackRuns */ + UDWORD iAttackRuns[VTOL_MAXWEAPS]; + /* Watermelon:guard radius */ + //UDWORD iGuardRadius; // added for vtol movement @@ -84,3 +89,4 @@ typedef struct _move_control #endif + diff --git a/src/multibot.c b/src/multibot.c index 592f83fa8..b25ccaca5 100644 --- a/src/multibot.c +++ b/src/multibot.c @@ -101,6 +101,7 @@ BOOL recvHappyVtol(NETMSG *pMsg) DROID *pD; UBYTE player; UDWORD id; + int i; NetGet(pMsg,0,player); NetGet(pMsg,1,id); @@ -110,10 +111,13 @@ BOOL recvHappyVtol(NETMSG *pMsg) return FALSE; } - pD->sMove.iAttackRuns =0; // finish it for next time round. - pD->body = pD->originalBody; - pD->asWeaps[0].ammo = asWeaponStats[pD->asWeaps[0].nStat].numRounds; - pD->asWeaps[0].lastFired = 0; + for (i = 0;i < pD->numWeaps;i++) + { + pD->sMove.iAttackRuns[i] =0; // finish it for next time round. + pD->body = pD->originalBody; + pD->asWeaps[i].ammo = asWeaponStats[pD->asWeaps[i].nStat].numRounds; + pD->asWeaps[i].lastFired = 0; + } return TRUE; } @@ -123,8 +127,9 @@ BOOL sendVtolRearm(DROID *psDroid,STRUCTURE *psStruct, UBYTE chosen) { NETMSG msg; UDWORD blank=0; - UBYTE attackRuns, ammo; + UBYTE attackRuns[DROID_MAXWEAPS], ammo[DROID_MAXWEAPS]; UBYTE player; + int i = 0; if(!myResponsibility(psDroid->player)) { @@ -144,12 +149,15 @@ BOOL sendVtolRearm(DROID *psDroid,STRUCTURE *psStruct, UBYTE chosen) NetAdd(msg,6,blank); } - attackRuns = (UBYTE)(psDroid->sMove.iAttackRuns); - ammo = (UBYTE)(psDroid->asWeaps[0].ammo); - NetAdd(msg,10,attackRuns); - NetAdd(msg,11,ammo); + for (i = 0;i < psDroid->numWeaps;i ++) + { + attackRuns[i] = (UBYTE)(psDroid->sMove.iAttackRuns[i]); + ammo[i] = (UBYTE)(psDroid->asWeaps[i].ammo); + NetAdd(msg,(10 + i),attackRuns[i]); + NetAdd(msg,(11 + i),ammo[i]); + } - msg.size = 12; + msg.size = (12 + i); msg.type = NET_VTOLREARM; return TRUE; } @@ -158,23 +166,27 @@ BOOL sendVtolRearm(DROID *psDroid,STRUCTURE *psStruct, UBYTE chosen) BOOL recvVtolRearm(NETMSG *pMsg) { DROID *psDroid; - UBYTE player,chosen,aruns,amm; + UBYTE player,chosen,aruns[DROID_MAXWEAPS],amm[DROID_MAXWEAPS]; UDWORD id,ids; STRUCTURE *psStruct = NULL; + int i; NetGet(pMsg,0,player); NetGet(pMsg,1,id); NetGet(pMsg,5,chosen); NetGet(pMsg,6,ids); - NetGet(pMsg,10,aruns); - NetGet(pMsg,11,amm); - if(!IdToDroid(id,player,&psDroid)) //find droid. { return FALSE; } + for (i = 0;i < psDroid->numWeaps;i++) + { + NetGet(pMsg,(10 + i),aruns[i]); + NetGet(pMsg,(11 + i),amm[i]); + } + if(ids) // find rearm pad. { psStruct = IdToStruct(id,psDroid->player); @@ -188,8 +200,11 @@ BOOL recvVtolRearm(NETMSG *pMsg) } } - psDroid->sMove.iAttackRuns = aruns; - psDroid->asWeaps[0].ammo = amm; + for (i = 0;i < psDroid->numWeaps;i++) + { + psDroid->sMove.iAttackRuns[i] = aruns[i]; + psDroid->asWeaps[i].ammo = amm[i]; + } turnOffMultiMsg(TRUE); switch(chosen) @@ -1346,3 +1361,4 @@ BOOL recvRequestDroid(NETMSG *pMsg) + diff --git a/src/order.c b/src/order.c index 455fdfa18..8c241f2b3 100644 --- a/src/order.c +++ b/src/order.c @@ -83,6 +83,9 @@ void orderClearDroidList(DROID *psDroid); void orderDroidStatsTwoLocAdd(DROID *psDroid, DROID_ORDER order, BASE_STATS *psStats, UDWORD x1, UDWORD y1, UDWORD x2, UDWORD y2); +//Watermelon:add a timestamp to order circle +static UDWORD orderStarted; + ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// @@ -264,6 +267,8 @@ void orderUpdateDroid(DROID *psDroid) DROID *psSpotter; //Watermelon:int i int i; + float radToAction; + SDWORD xoffset,yoffset; // clear the target if it has died @@ -638,6 +643,94 @@ if(!bMultiPlayer || myResponsibility(psDroid->player)) } } break; +case DORDER_CIRCLE: + // if there is an enemy around, attack it + if ( (psDroid->action == DACTION_MOVE) && + (secondaryGetState(psDroid, DSO_ATTACK_LEVEL, &state) && (state == DSS_ALEV_ALWAYS)) && + aiBestNearestTarget(psDroid, &psObj, 0) ) + { + switch (psDroid->droidType) + { + case DROID_WEAPON: + case DROID_CYBORG: + case DROID_CYBORG_SUPER: + case DROID_PERSON: + case DROID_COMMAND: + actionDroidObj(psDroid, DACTION_ATTACK, psObj); + break; + case DROID_SENSOR: + actionDroidObj(psDroid, DACTION_OBSERVE, psObj); + break; + default: + actionDroid(psDroid, DACTION_NONE); + break; + } + } + else if (psDroid->action == DACTION_NONE || psDroid->action == DACTION_MOVE) + { + if (psDroid->action == DACTION_MOVE) + { + if ( orderStarted && ((orderStarted + 500) > gameTime) ) + { + break; + } + orderStarted = gameTime; + } + psDroid->action = DACTION_NONE; + + xdiff = (SDWORD)psDroid->x - (SDWORD)psDroid->orderX; + ydiff = (SDWORD)psDroid->y - (SDWORD)psDroid->orderY; + //if (xdiff*xdiff + ydiff*ydiff < psDroid->sMove.iGuardRadius * psDroid->sMove.iGuardRadius) + if (xdiff*xdiff + ydiff*ydiff <= 2000 * 2000) + { + if (psDroid->order == DORDER_CIRCLE) + { + //Watermelon:use orderX,orderY as local space origin and calculate droid direction in local space + radToAction = atan2f((float)xdiff, (float)ydiff); + xoffset = sinf(radToAction) * 1500; + yoffset = cosf(radToAction) * 1500; + xdiff = (SDWORD)psDroid->x - (SDWORD)(psDroid->orderX + xoffset); + ydiff = (SDWORD)psDroid->y - (SDWORD)(psDroid->orderY + yoffset); + if (xdiff*xdiff + ydiff*ydiff < TILE_UNITS * TILE_UNITS) + { + //Watermelon:conter-clockwise 30 degree's per action + radToAction -= pi * 30 / 180; + xoffset = sinf(radToAction) * 1500; + yoffset = cosf(radToAction) * 1500; + actionDroidLoc(psDroid, DACTION_MOVE, (psDroid->orderX + xoffset),(psDroid->orderY + yoffset)); + } + else + { + actionDroidLoc(psDroid, DACTION_MOVE, (psDroid->orderX + xoffset),(psDroid->orderY + yoffset)); + } + } + else + { + psDroid->order = DORDER_NONE; + } + } + else + { + + } + } + else if ((psDroid->action == DACTION_ATTACK) || + (psDroid->action == DACTION_MOVETOATTACK) || + (psDroid->action == DACTION_ROTATETOATTACK) || + (psDroid->action == DACTION_OBSERVE) || + (psDroid->action == DACTION_MOVETOOBSERVE)) + { + // attacking something - see if the droid has gone too far + xdiff = (SDWORD)psDroid->x - (SDWORD)psDroid->actionX; + ydiff = (SDWORD)psDroid->y - (SDWORD)psDroid->actionY; + //if (xdiff*xdiff + ydiff*ydiff > psDroid->sMove.iGuardRadius * psDroid->sMove.iGuardRadius) + if (xdiff*xdiff + ydiff*ydiff > 2000 * 2000) + { + // head back to the target location + actionDroidLoc(psDroid, DACTION_RETURNTOPOS, psDroid->orderX,psDroid->orderY); + } + } + break; case DORDER_HELPBUILD: case DORDER_DEMOLISH: case DORDER_OBSERVE: @@ -2319,6 +2412,16 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder) actionDroidObj( psDroid,DACTION_MOVETOREARM, psOrder->psObj); assignVTOLPad(psDroid, (STRUCTURE *)psOrder->psObj); break; + case DORDER_CIRCLE: + if (!vtolDroid(psDroid)) + { + break; + } + psDroid->order = psOrder->order; + psDroid->orderX = psOrder->x; + psDroid->orderY = psOrder->y; + actionDroidLoc(psDroid, DACTION_MOVE, psOrder->x,psOrder->y); + break; default: ASSERT( FALSE, "orderUnitBase: unknown order" ); break; @@ -2395,7 +2498,8 @@ void orderDroidLoc(DROID *psDroid, DROID_ORDER order, UDWORD x, UDWORD y) order == DORDER_TRANSPORTOUT || order == DORDER_TRANSPORTIN || order == DORDER_TRANSPORTRETURN || - order == DORDER_DISEMBARK, + order == DORDER_DISEMBARK || + order == DORDER_CIRCLE, "orderUnitLoc: Invalid order for location" ); orderClearDroidList(psDroid); @@ -2990,6 +3094,12 @@ DROID_ORDER chooseOrderLoc(DROID *psDroid, UDWORD x,UDWORD y) order = DORDER_DISEMBARK; } } + else if (secondaryGetState(psDroid, DSO_CIRCLE, &state) && + state == DSS_CIRCLE_SET) + { + order = DORDER_CIRCLE; + secondarySetState(psDroid, DSO_CIRCLE, DSS_NONE); + } else if (secondaryGetState(psDroid, DSO_PATROL, &state) && state == DSS_PATROL_SET) { @@ -3622,6 +3732,13 @@ BOOL secondarySupported(DROID *psDroid, SECONDARY_ORDER sec) } break; + case DSO_CIRCLE: + if (!vtolDroid(psDroid)) + { + supported = FALSE; + } + break; + case DSO_REPAIR_LEVEL: case DSO_PATROL: case DSO_HALTTYPE: @@ -3688,6 +3805,9 @@ BOOL secondaryGetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE *pSt case DSO_PATROL: *pState = (SECONDARY_STATE)(state & DSS_PATROL_MASK); break; + case DSO_CIRCLE: + *pState = (SECONDARY_STATE)(state & DSS_CIRCLE_MASK); + break; case DSO_HALTTYPE: *pState = (SECONDARY_STATE)(state & DSS_HALT_MASK); break; @@ -3997,7 +4117,16 @@ BOOL secondarySetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE Stat CurrState &= ~DSS_RECYCLE_MASK; } break; - + case DSO_CIRCLE: + if (State & DSS_CIRCLE_SET) + { + CurrState |= DSS_CIRCLE_SET; + } + else + { + CurrState &= ~DSS_CIRCLE_MASK; + } + break; case DSO_PATROL: if (State & DSS_PATROL_SET) { diff --git a/src/order.h b/src/order.h index 8d628dd11..bab9023f9 100644 --- a/src/order.h +++ b/src/order.h @@ -57,6 +57,7 @@ typedef enum _droid_order DORDER_RTR_SPECIFIED, // return to repair at a specified repair center DORDER_ATTACK_M, // 38 - attack with multiple weapons DORDER_ATTACKTARGET_M, // 39 - attack multiple targets + DORDER_CIRCLE, // circles target location and engage } DROID_ORDER; // secondary orders for droids @@ -74,6 +75,7 @@ typedef enum _secondary_order DSO_RETURN_TO_LOC, // return to various locations DSO_FIRE_DESIGNATOR, // command droid controlling IDF structures DSO_ASSIGN_VTOL_PRODUCTION, + DSO_CIRCLE, // circling target position and engage } SECONDARY_ORDER; // the state of secondary orders @@ -100,6 +102,7 @@ typedef enum _secondary_state DSS_RTL_BASE = 0x100000, DSS_RTL_TRANSPORT = 0x200000, DSS_PATROL_SET = 0x400000, + DSS_CIRCLE_SET = 0x400100, DSS_FIREDES_SET = 0x800000, DSS_VTOLPROD_START = 0x01000000, DSS_VTOLPROD_END = 0x10000000, @@ -121,6 +124,7 @@ typedef enum _secondary_state #define DSS_RTL_MASK 0x380000 #define DSS_PATROL_MASK 0x400000 #define DSS_FIREDES_MASK 0x800000 +#define DSS_CIRCLE_MASK 0x400100 //call this *AFTER* every mission so it gets reset extern void initRunData(void); @@ -233,3 +237,4 @@ extern void orderStructureObj(UDWORD player, BASE_OBJECT *psObj); + diff --git a/src/projectile.c b/src/projectile.c index 91949520e..1ad965ffe 100644 --- a/src/projectile.c +++ b/src/projectile.c @@ -123,7 +123,7 @@ static void proj_PostImpactFunc( PROJ_OBJECT *psObj ); static void proj_checkBurnDamage( BASE_OBJECT *apsList, PROJ_OBJECT *psProj, FIRE_BOX *pFireBox ); -static BOOL objectDamage(BASE_OBJECT *psObj, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass); +static BOOL objectDamage(BASE_OBJECT *psObj, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass,int angle); /***************************************************************************/ BOOL gfxVisible(PROJ_OBJECT *psObj) @@ -319,7 +319,7 @@ proj_SendProjectile( WEAPON *psWeap, BASE_OBJECT *psAttacker, SDWORD player, { calcDroidMuzzleLocation( (DROID *) psAttacker, &muzzle, weapon_slot); /*update attack runs for VTOL droid's each time a shot is fired*/ - updateVtolAttackRun((DROID *)psAttacker); + updateVtolAttackRun((DROID *)psAttacker, weapon_slot); } else if (psAttacker->type == OBJ_STRUCTURE && weapon_slot >= 0) { @@ -593,7 +593,7 @@ proj_InFlightDirectFunc( PROJ_OBJECT *psObj ) //esp the AAGun,or it will never hit anything with the new hit system UDWORD wpRadius = 1; //Watermelon:Penetrate or not - BOOL bPenetrate = FALSE; + BOOL bPenetrate; WEAPON asWeap; DROID *psTempDroid; @@ -808,27 +808,27 @@ proj_InFlightDirectFunc( PROJ_OBJECT *psObj ) switch (psTempDroid->droidType) { case DROID_CONSTRUCT: - zdiff -= (asConstructStats[psTempDroid->asBits[COMP_CONSTRUCT].nStat]).pIMD->ymax; + zdiff -= abs((asConstructStats[psTempDroid->asBits[COMP_CONSTRUCT].nStat]).pIMD->ymax); break; case DROID_REPAIR: - zdiff -= (asRepairStats[psTempDroid->asBits[COMP_REPAIRUNIT].nStat]).pIMD->ymax; + zdiff -= abs((asRepairStats[psTempDroid->asBits[COMP_REPAIRUNIT].nStat]).pIMD->ymax); break; case DROID_SENSOR: - zdiff -= (asSensorStats[psTempDroid->asBits[COMP_SENSOR].nStat]).pIMD->ymax; + zdiff -= abs((asSensorStats[psTempDroid->asBits[COMP_SENSOR].nStat]).pIMD->ymax); break; case DROID_COMMAND: - zdiff -= (asBrainStats[psTempDroid->asBits[COMP_BRAIN].nStat]).pIMD->ymax; + zdiff -= abs((asBrainStats[psTempDroid->asBits[COMP_BRAIN].nStat]).pIMD->ymax); break; case DROID_ECM: - zdiff -= (asECMStats[psTempDroid->asBits[COMP_ECM].nStat]).pIMD->ymax; + zdiff -= abs((asECMStats[psTempDroid->asBits[COMP_ECM].nStat]).pIMD->ymax); break; } } } } - if ( (UDWORD)(xdiff*xdiff + ydiff*ydiff) < ( wpRadius * (SDWORD)establishTargetRadius(psTempObj) * (SDWORD)establishTargetRadius(psTempObj) ) && - zdiff < psTempObj->sDisplay.imd->ymax ) + if ( zdiff < abs(psTempObj->sDisplay.imd->ymax) && + (UDWORD)(xdiff*xdiff + ydiff*ydiff) < ( wpRadius * (SDWORD)establishTargetRadius(psTempObj) * (SDWORD)establishTargetRadius(psTempObj) ) ) { psNewTarget = psTempObj; psObj->psDest = psNewTarget; @@ -926,11 +926,14 @@ proj_InFlightIndirectFunc( PROJ_OBJECT *psObj ) SDWORD xdiff,ydiff,zdiff,extendRad; UDWORD wpRadius = 3; DROID *psTempDroid; + BOOL bPenetrate; + WEAPON asWeap; ASSERT( PTRVALID(psObj, sizeof(PROJ_OBJECT)), "proj_InFlightIndirectFunc: invalid projectile pointer" ); psStats = psObj->psWStats; + bPenetrate = psStats->penetrate; ASSERT( PTRVALID(psStats, sizeof(WEAPON_STATS)), "proj_InFlightIndirectFunc: Invalid weapon stats pointer" ); @@ -1071,31 +1074,43 @@ proj_InFlightIndirectFunc( PROJ_OBJECT *psObj ) switch (psTempDroid->droidType) { case DROID_CONSTRUCT: - zdiff -= (asConstructStats[psTempDroid->asBits[COMP_CONSTRUCT].nStat]).pIMD->ymax; + zdiff -= abs((asConstructStats[psTempDroid->asBits[COMP_CONSTRUCT].nStat]).pIMD->ymax); break; case DROID_REPAIR: - zdiff -= (asRepairStats[psTempDroid->asBits[COMP_REPAIRUNIT].nStat]).pIMD->ymax; + zdiff -= abs((asRepairStats[psTempDroid->asBits[COMP_REPAIRUNIT].nStat]).pIMD->ymax); break; case DROID_SENSOR: - zdiff -= (asSensorStats[psTempDroid->asBits[COMP_SENSOR].nStat]).pIMD->ymax; + zdiff -= abs((asSensorStats[psTempDroid->asBits[COMP_SENSOR].nStat]).pIMD->ymax); break; case DROID_COMMAND: - zdiff -= (asBrainStats[psTempDroid->asBits[COMP_BRAIN].nStat]).pIMD->ymax; + zdiff -= abs((asBrainStats[psTempDroid->asBits[COMP_BRAIN].nStat]).pIMD->ymax); break; case DROID_ECM: - zdiff -= (asECMStats[psTempDroid->asBits[COMP_ECM].nStat]).pIMD->ymax; + zdiff -= abs((asECMStats[psTempDroid->asBits[COMP_ECM].nStat]).pIMD->ymax); break; } } } } - if ( (UDWORD)(xdiff*xdiff + ydiff*ydiff) < ( wpRadius * (SDWORD)establishTargetRadius(psTempObj) * (SDWORD)establishTargetRadius(psTempObj) ) && - zdiff < psTempObj->sDisplay.imd->ymax ) + if ( zdiff < abs(psTempObj->sDisplay.imd->ymax) && + (UDWORD)(xdiff*xdiff + ydiff*ydiff) < ( wpRadius * (SDWORD)establishTargetRadius(psTempObj) * (SDWORD)establishTargetRadius(psTempObj) ) ) { psNewTarget = psTempObj; psObj->psDest = psNewTarget; - psObj->state = PROJ_IMPACT; + + if (bPenetrate) + { + asWeap.nStat = psObj->psWStats - asWeaponStats; + //Watermelon:just assume we damaged the chosen target + psObj->psDamaged = psNewTarget; + + proj_SendProjectile( &asWeap, (BASE_OBJECT*)psObj, psObj->player, (psObj->startX + extendRad * dx / iRad), (psObj->startY + extendRad * dy / iRad), psObj->z, NULL, TRUE, bPenetrate, -1 ); + } + else + { + psObj->state = PROJ_IMPACT; + } return; } } @@ -1128,8 +1143,9 @@ proj_InFlightIndirectFunc( PROJ_OBJECT *psObj ) } if ( (UDWORD)(xdiff*xdiff + ydiff*ydiff) < ( wpRadius * (SDWORD)establishTargetRadius(psObj->psDest) * (SDWORD)establishTargetRadius(psObj->psDest) ) && - zdiff < psObj->psDest->sDisplay.imd->ymax ) + zdiff < abs(psObj->psDest->sDisplay.imd->ymax) ) { + psObj->state = PROJ_IMPACT; } else { @@ -1188,6 +1204,7 @@ proj_ImpactFunc( PROJ_OBJECT *psObj ) UDWORD damage; //optimisation - were all being calculated twice on PC //Watermelon: tarZ0,tarZ1,zDiff for AA AOE weapons; SDWORD tarZ0,tarZ1,zDiff; + int impact_angle; ASSERT( PTRVALID(psObj, sizeof(PROJ_OBJECT)), @@ -1412,7 +1429,32 @@ proj_ImpactFunc( PROJ_OBJECT *psObj ) psObj->psDest->id, psObj->psDest->player); /*the damage depends on the weapon effect and the target propulsion type or structure strength*/ - bKilled = objectDamage(psObj->psDest,damage , psStats->weaponClass,psStats->weaponSubClass); + if (psObj->psDest->type == OBJ_DROID) + { + if (psObj->altChange > 300) + { + impact_angle = HIT_ANGLE_TOP; + } + else if (psObj->z < (psObj->psDest->z - 50)) + { + impact_angle = HIT_ANGLE_BOTTOM; + } + else + { + xDiff = psObj->startX - psObj->psDest->x; + yDiff = psObj->startY - psObj->psDest->y; + impact_angle = abs(psObj->psDest->direction - (180 * atan2f((float)xDiff, (float)yDiff) /PI)); + if (impact_angle >= 360) + { + impact_angle -= 360; + } + } + } + else + { + impact_angle = 0; + } + bKilled = objectDamage(psObj->psDest,damage , psStats->weaponClass,psStats->weaponSubClass, impact_angle); if(bKilled) { @@ -1456,7 +1498,16 @@ proj_ImpactFunc( PROJ_OBJECT *psObj ) } debug(LOG_NEVER, "Damage to object %d, player %d\n", psObj->psDest->id, psObj->psDest->player); - bKilled = objectDamage(psObj->psDest, damage, psStats->weaponClass,psStats->weaponSubClass); + //Watermelon:just assume it as from TOP for indirect artillery + if (psObj->psDest->type == OBJ_DROID) + { + impact_angle = HIT_ANGLE_TOP; + } + else + { + impact_angle = HIT_SIDE_FRONT; + } + bKilled = objectDamage(psObj->psDest, damage, psStats->weaponClass,psStats->weaponSubClass, impact_angle); if(bKilled) { @@ -1582,7 +1633,27 @@ proj_ImpactFunc( PROJ_OBJECT *psObj ) turnOffMultiMsg(TRUE); } - bKilled = droidDamage(psCurrD, damage, psStats->weaponClass,psStats->weaponSubClass); + //Watermelon:uses a slightly different check for angle, + // since fragment of a project is from the explosion spot not from the projectile start position + if (psObj->altChange > 300) + { + impact_angle = HIT_ANGLE_TOP; + } + else if (psObj->z < (psCurrD->z - 50)) + { + impact_angle = HIT_ANGLE_BOTTOM; + } + else + { + xDiff = psObj->x - psCurrD->x; + yDiff = psObj->y - psCurrD->y; + impact_angle = abs(psCurrD->direction - (180 * atan2f((float)xDiff, (float)yDiff) /PI)); + if (impact_angle >= 360) + { + impact_angle -= 360; + } + } + bKilled = droidDamage(psCurrD, damage, psStats->weaponClass,psStats->weaponSubClass, impact_angle); turnOffMultiMsg(FALSE); // multiplay msgs back on. @@ -1644,7 +1715,27 @@ proj_ImpactFunc( PROJ_OBJECT *psObj ) turnOffMultiMsg(TRUE); } - bKilled = droidDamage(psCurrD, damage, psStats->weaponClass,psStats->weaponSubClass); + //Watermelon:uses a slightly different check for angle, + // since fragment of a project is from the explosion spot not from the projectile start position + if (psObj->altChange > 300) + { + impact_angle = HIT_ANGLE_TOP; + } + else if (psObj->z < (psCurrD->z - 50)) + { + impact_angle = HIT_ANGLE_BOTTOM; + } + else + { + xDiff = psObj->x - psCurrD->x; + yDiff = psObj->y - psCurrD->y; + impact_angle = abs(psCurrD->direction - (180 * atan2f((float)xDiff, (float)yDiff) /PI)); + if (impact_angle >= 360) + { + impact_angle -= 360; + } + } + bKilled = droidDamage(psCurrD, damage, psStats->weaponClass,psStats->weaponSubClass, impact_angle); turnOffMultiMsg(FALSE); // multiplay msgs back on. @@ -1967,7 +2058,8 @@ proj_checkBurnDamage( BASE_OBJECT *apsList, PROJ_OBJECT *psProj, //bKilled = psCurr->damage(psCurr, damageToDo, psStats->weaponClass); - bKilled = objectDamage(psCurr, damageToDo, psStats->weaponClass,psStats->weaponSubClass); + //Watermelon:just assume the burn damage is from FRONT + bKilled = objectDamage(psCurr, damageToDo, psStats->weaponClass,psStats->weaponSubClass, 0); psCurr->burnDamage += damageToDo; @@ -2062,7 +2154,7 @@ FEATURE *psFeat; case DROID_CYBORG_REPAIR: case DROID_CYBORG_SUPER: //Watermelon:'hitbox' size is now based on imd size - radius = (psTarget->sDisplay.imd->xmax + psTarget->sDisplay.imd->zmax)/2; + radius = abs(psTarget->sDisplay.imd->radius); break; case DROID_DEFAULT: case DROID_TRANSPORTER: @@ -2166,12 +2258,12 @@ UDWORD calcDamage(UDWORD baseDamage, WEAPON_EFFECT weaponEffect, BASE_OBJECT *ps } -BOOL objectDamage(BASE_OBJECT *psObj, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass) +BOOL objectDamage(BASE_OBJECT *psObj, UDWORD damage, UDWORD weaponClass,UDWORD weaponSubClass, int angle) { switch (psObj->type) { case OBJ_DROID: - return droidDamage((DROID *)psObj, damage, weaponClass,weaponSubClass); + return droidDamage((DROID *)psObj, damage, weaponClass,weaponSubClass, angle); break; case OBJ_STRUCTURE: return structureDamage((STRUCTURE *)psObj, damage, weaponClass, weaponSubClass); @@ -2334,3 +2426,4 @@ void projGetNaybors(PROJ_OBJECT *psObj) + diff --git a/src/stats.c b/src/stats.c index f2f1481aa..d744e39f8 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1051,14 +1051,21 @@ BOOL loadBodyStats(char *pBodyData, UDWORD bufferSize) size[0] = '\0'; GfxFile[0] = '\0'; flameIMD[0] = '\0'; + //Watermelon:added 10 %d to store FRONT,REAR,LEFT,RIGHT,TOP,BOTTOM armour values //read the data into the storage - the data is delimeted using comma's sscanf(pBodyData,"%[^','],%[^','],%[^','],%d,%d,%d,%d,%[^','],\ - %d,%d,%d,%d,%d,%[^','],%d", + %d,%d,%d, \ + %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%[^','],%d", (char*)&BodyName, (char*)&techLevel, (char*)&size, &psStats->buildPower,&psStats->buildPoints, &psStats->weight, &psStats->body, (char*)&GfxFile, &psStats->systemPoints, &psStats->weaponSlots, &psStats->powerOutput, - &psStats->armourValue[WC_KINETIC], - &psStats->armourValue[WC_HEAT], (char*)&flameIMD, &designable);//, &psStats->armourValue[WC_EXPLOSIVE], + (int*)&psStats->armourValue[HIT_SIDE_FRONT][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_FRONT][WC_HEAT],(int*)&psStats->armourValue[HIT_SIDE_REAR][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_REAR][WC_HEAT],(int*)&psStats->armourValue[HIT_SIDE_LEFT][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_LEFT][WC_HEAT],(int*)&psStats->armourValue[HIT_SIDE_RIGHT][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_RIGHT][WC_HEAT],(int*)&psStats->armourValue[HIT_SIDE_TOP][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_TOP][WC_HEAT],(int*)&psStats->armourValue[HIT_SIDE_BOTTOM][WC_KINETIC], + (int*)&psStats->armourValue[HIT_SIDE_BOTTOM][WC_HEAT], (char*)&flameIMD, &designable);//, &psStats->armourValue[WC_EXPLOSIVE], //&psStats->armourValue[WC_MISC]); #if (MAX_PLAYERS!=4 && MAX_PLAYERS!=8) @@ -1141,8 +1148,9 @@ BOOL loadBodyStats(char *pBodyData, UDWORD bufferSize) //set the max stat values for the design screen if (psStats->design) { - setMaxBodyArmour(psStats->armourValue[WC_KINETIC]); - setMaxBodyArmour(psStats->armourValue[WC_HEAT]); + //use front armour value to prevent bodyStats corrupt problems + setMaxBodyArmour(psStats->armourValue[HIT_SIDE_FRONT][WC_KINETIC]); + setMaxBodyArmour(psStats->armourValue[HIT_SIDE_FRONT][WC_HEAT]); setMaxBodyPower(psStats->powerOutput); setMaxBodyPoints(psStats->body); setMaxComponentWeight(psStats->weight); @@ -3955,20 +3963,20 @@ UDWORD bodyPower(BODY_STATS *psStats, UBYTE player, UBYTE bodyType) } UDWORD bodyArmour(BODY_STATS *psStats, UBYTE player, UBYTE bodyType, - WEAPON_CLASS weaponClass) + WEAPON_CLASS weaponClass, int side) { switch (weaponClass) { case WC_KINETIC: //case WC_EXPLOSIVE: - return (psStats->armourValue[WC_KINETIC] + (psStats-> - armourValue[WC_KINETIC] * asBodyUpgrade[player][bodyType]. + return (psStats->armourValue[side][WC_KINETIC] + (psStats-> + armourValue[side][WC_KINETIC] * asBodyUpgrade[player][bodyType]. armourValue[WC_KINETIC])/100); break; case WC_HEAT: //case WC_MISC: - return (psStats->armourValue[WC_HEAT] + (psStats-> - armourValue[WC_HEAT] * asBodyUpgrade[player][bodyType]. + return (psStats->armourValue[side][WC_HEAT] + (psStats-> + armourValue[side][WC_HEAT] * asBodyUpgrade[player][bodyType]. armourValue[WC_HEAT])/100); break; default: diff --git a/src/stats.h b/src/stats.h index 1dde61648..da8fbb4b3 100644 --- a/src/stats.h +++ b/src/stats.h @@ -316,7 +316,7 @@ extern UDWORD constructorPoints(CONSTRUCT_STATS *psStats, UBYTE player); /*Access functions for the upgradeable stats of a body*/ extern UDWORD bodyPower(BODY_STATS *psStats, UBYTE player, UBYTE bodyType); extern UDWORD bodyArmour(BODY_STATS *psStats, UBYTE player, UBYTE bodyType, - WEAPON_CLASS weaponClass); + WEAPON_CLASS weaponClass, int side); /*dummy function for John*/ extern void brainAvailable(BRAIN_STATS *psStat); @@ -338,3 +338,4 @@ extern UDWORD getMaxPropulsionSpeed(void); #endif + diff --git a/src/statsdef.h b/src/statsdef.h index b20f40e59..e25f9893b 100644 --- a/src/statsdef.h +++ b/src/statsdef.h @@ -179,6 +179,23 @@ typedef enum _weapon_effect #define SHOOT_ON_GROUND 0x01 #define SHOOT_IN_AIR 0x02 + +//Sides used for droid impact +typedef enum _droid_hit_sides +{ + HIT_SIDE_FRONT, + HIT_SIDE_REAR, + HIT_SIDE_LEFT, + HIT_SIDE_RIGHT, + HIT_SIDE_TOP, + HIT_SIDE_BOTTOM, + NUM_HIT_SIDES //should be last one +}DROID_HIT_SIDE; + +//Special angles representing top or bottom hit +#define HIT_ANGLE_TOP 361 +#define HIT_ANGLE_BOTTOM 362 + typedef struct _body_stats { /* common stats - N.B. system points for a body @@ -193,7 +210,7 @@ typedef struct _body_stats UBYTE size; // How big the body is - affects how hit //UDWORD bodyPoints; // How much damage the body can take before destruction UDWORD weaponSlots; // The number of weapon slots on the body - UDWORD armourValue[NUM_WEAPON_CLASS]; // A measure of how much protection the armour provides + UDWORD armourValue[NUM_HIT_SIDES][NUM_WEAPON_CLASS]; // A measure of how much protection the armour provides // cross-ref with the weapon types // Watermelon:you just got trolled,sir... // A measure of how much energy the power plant outputs diff --git a/src/structure.c b/src/structure.c index 5a00ded60..027e82018 100644 --- a/src/structure.c +++ b/src/structure.c @@ -4844,23 +4844,34 @@ static void aiUpdateStructure(STRUCTURE *psStructure) //amount required is a factor of the droids' weight pointsRequired = psDroid->weight / REARM_FACTOR; - pointsToAdd = psReArmPad->reArmPoints * (gameTime - psReArmPad->timeStarted) / + //Watermelon:take numWeaps into consideration + pointsToAdd = psReArmPad->reArmPoints * (gameTime - psReArmPad->timeStarted) * psDroid->numWeaps / GAME_TICKS_PER_SEC; //if ((SDWORD)(psDroid->sMove.iAttackRuns - pointsToAdd) <= 0) if (pointsToAdd >= pointsRequired) { - /* set rearm value to no runs made */ - psDroid->sMove.iAttackRuns = 0; - //reset ammo and lastTimeFired - psDroid->asWeaps[0].ammo = asWeaponStats[psDroid-> - asWeaps[0].nStat].numRounds; - psDroid->asWeaps[0].lastFired = 0; + for (i = 0;i < psDroid->numWeaps;i++) + { + /* set rearm value to no runs made */ + psDroid->sMove.iAttackRuns[i] = 0; + //reset ammo and lastTimeFired + psDroid->asWeaps[i].ammo = asWeaponStats[psDroid-> + asWeaps[i].nStat].numRounds; + psDroid->asWeaps[i].lastFired = 0; + } } else { - if (pointsToAdd >= pointsRequired/psDroid->sMove.iAttackRuns) + for (i = 0;i < psDroid->numWeaps;i++) { - psDroid->sMove.iAttackRuns--; + //Watermelon:make sure that slot is depleted and dont divide integer by zero + if ( psDroid->sMove.iAttackRuns[i] > 0 ) + { + if (pointsToAdd >= pointsRequired/psDroid->sMove.iAttackRuns[i]) + { + psDroid->sMove.iAttackRuns[i]--; + } + } } } }