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
master
Roman C 2006-12-17 17:12:14 +00:00
parent cee8ff2da9
commit 840312f8ea
38 changed files with 812 additions and 378 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -4820,7 +4820,6 @@ void moveUpdateDroid(DROID *psDroid)
// }
// }
break;
default:
ASSERT( FALSE, "moveUpdateUnit: unknown move state" );
break;

View File

@ -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

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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]--;
}
}
}
}
}