hschumann2/TempleOS-Source-Code
0847
1 2U0 AttackHeader(Unit *tmpu,U8 *st,Unit *target)3{4 I64 i=9+StrLen(st);5 if (target) {6 i+=9;7 if (target->armor)8 i+=8;9 else10 i+=10;11 }12 '\n\n';13 "$BLACK$%h*c$FG$\n",i,'-';14 if (tmpu->player)15 "$PURPLE$Player 2$FG$ ";16 else17 "$CYAN$Player 1$FG$ ";18 "%s",st;19 if (target) {20 if (target->player)21 " $PURPLE$Player 2";22 else23 " $CYAN$Player 1";24 if (target->armor)25 " Armored";26 else27 " Unarmored";28 '$FG$';29 }30 '\n';31 "$BLACK$%h*c$FG$\n",i,'-';32}33 34F64 HitDamage(Unit *tmpu,Unit *target,I64 facing=1,F64 range_factor=0)35{36 F64 d,res=200.0*Rand;37 "\nRoll Out of 200\t\t:%6.2f Damage\n",res;38 if (target->armor) {39 d=target->armor/100.0*(5-facing)/5.0;40 if (d>=0) {41 "Armor Attack\t\t:%6.2f\n",ToF64(tmpu->armored_attack);42 res*=(tmpu->armored_attack/100.0)/d;43 } else44 res=0;45 "Armor(%z) Defense\t:%6.2f\n",facing,46 "Front\0FrontSide\0RearSide\0Rear\0",100*d;47 } else {48 d=1.0-range_factor;49 if (d>0) {50 "Unarmored Attack\t:%6.2f\n",ToF64(tmpu->unarmored_attack);51 "Range Adjust\t\t:%6.2f%%\n",100*d;52 res*=(tmpu->unarmored_attack/100.0)*d;53 } else54 res=0;55 }56 "Attack/Defense Adjusted\t:%6.2f Damage\n",res;57 return Round(res);58}59 60Bool DamageDo(Unit *target,F64 damage)61{62 if (damage>0) {63 if (target->armor)64 "Armor Hit Score %6.2f\t:",damage;65 else66 "%3d Life - %3f Damage\t=",target->life,damage;67 if (damage>=target->life) {68 "$RED$Killed$FG$\n";69 Noise(1000*animation_delay,74,98);70 Sleep(1000*animation_delay);71 target->life=0;72 VisRecalc(VR_FRIENDLY_UNIT_DIED,target);73 alive_cnt[target->player]--;74 return TRUE;75 } else {76 if (target->armor) {77 if (damage>0.6*target->life) {78 target->movement=0;79 "$RED$Immobilized$FG$\n";80 } else81 "$GREEN$No Penetration$FG$\n";82 } else {83 target->life-=damage;84 "$RED$%6.2f Life$FG$\n",ToF64(target->life);85 }86 return FALSE;87 }88 } else89 return FALSE;90}91 92U0 IndirectAdd(Unit *tmpu,I64 row,I64 col)93{94 IndirectOrders *tmpi;95 if (tmpu->life<=0 || tmpu->range<=0)96 return;97 tmpu->fired=TRUE;98 tmpi=CAlloc(sizeof(IndirectOrders));99 tmpi->attacker=tmpu;100 tmpi->row=row;101 tmpi->col=col;102 QueIns(tmpi,indirect_head.last);103}104 105Bool BulletPlot(U0,I64 x,I64 y,I64)106{107 fire_x=x; fire_y=y;108 firing=TRUE;109 Sleep(3*animation_delay);110 return TRUE;111}112 113U0 UnitDirectFire(Unit *tmpu,Unit *target)114{115 I64 r,c,facing,116 t1=terrain[tmpu->row][tmpu->col],t2=terrain[target->row][target->col];117 F64 x1,y1,x2,y2,d,a,range_factor;118 if (tmpu->life<=0 || target->life<=0 || tmpu->range<=0)119 return;120 AttackHeader(tmpu,"DirectFire",target);121 RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);122 RowCol2XY(&x2,&y2,target->row,target->col);123 d=100*Rand;124 "+%5.2f Roll\n",d;125 d+=tmpu->accuracy;126 "+%2d.00 Accuracy\n",tmpu->accuracy;127 128 range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);129 "-%5.2f%% of Range\n",100*range_factor;130 d-=100*range_factor;131 if (t2==TREES) {132 "-30.00 Target in Trees Penalty\n";133 d-=30;134 }135 if (t1==MOUNTAINS && t2!=MOUNTAINS) {136 "+30.00 High Ground Bonus\n";137 d+=30;138 }139 "_______\n";140 target_unit=target;141 if (d>=0) {142 "+%5.2f Hit\n",d;143 target_hit=TRUE;144 Noise(500*animation_delay,34,41);145 Sleep(500*animation_delay);146 Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);147 } else {148 "-%5.2f Miss\n",-d;149 target_hit=FALSE;150 Noise(1000*animation_delay,69,74);151 Sleep(1000*animation_delay);152 a=pi*2*Rand;153 d=(0.5-d/100)*HEX_SIDE;154 Line(NULL,x1,y1,0,x2+d*Cos(a),y2+d*Sin(a),0,&BulletPlot);155 }156 firing=FALSE;157 tmpu->fired=TRUE;158 if (target_hit) {159 r=target->row;c=target->col;160 if ((facing=HexMoveOne(&r,&c,x1,y1))>=0)161 facing=FacingChg(facing,target->facing);162 else163 facing=0;164 DamageDo(target,HitDamage(tmpu,target,facing,range_factor));165 }166 while (snd.ona!=ONA_REST) //see Snd()167 Yield;168 target_unit=NULL;169}170 171Bool HexOccupy(Bool overrun,Unit *tmpu,Unit *target)172{173 I64 t2=terrain[target->row][target->col];174 F64 damage;175 if (tmpu->life<=0 || target->life<=0)176 return FALSE;177 if (overrun)178 AttackHeader(tmpu,"OverRun",target);179 else180 AttackHeader(tmpu,"CloseAssault",target);181 Noise(500*animation_delay,34,41);182 Sleep(500*animation_delay);183 tmpu->fired=TRUE;184 target->fired=TRUE;185 damage=HitDamage(tmpu,target);186 if (overrun) {187 damage*=2.0;188 "x2 OverRun Bonus\t=%6.2f Damage\n",damage;189 if (t2!=PLAINS) {190 damage/=2.0;191 "/2 Terrain Penalty\t=%6.2f Damage\n",damage;192 }193 } else {194 damage*=3.0;195 "x3 CloseAssault Bonus\t=%6.2f Damage\n",damage;196 }197 if (DamageDo(target,Round(damage))) {198 "$RED$Success$FG$\n";199 while (snd.ona!=ONA_REST) //see Snd()200 Yield;201 return TRUE;202 } else {203 tmpu->life=0;204 VisRecalc(VR_FRIENDLY_UNIT_DIED,tmpu);205 alive_cnt[tmpu->player]--;206 "$RED$Failure$FG$\n";207 while (snd.ona!=ONA_REST) //see Snd()208 Yield;209 return FALSE;210 }211}212 213U0 IndirectResolveAll()214{215 I64 i,r,c;216 F64 x1,y1,x2,y2,d,range_factor;217 Unit *tmpu,*target;218 IndirectOrders *tmpi=indirect_head.next,*tmpi1;219 while (tmpi!=*indirect_head) {220 tmpi1=tmpi->next;221 tmpu=tmpi->attacker;222 AttackHeader(tmpu,"IndirectFire",NULL);223 RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);224 RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);225 d=100*Rand;226 "+%5.2f Roll\n",d;227 d+=tmpu->accuracy;228 "+%2d.00 Accuracy\n",tmpu->accuracy;229 range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);230 "-%5.2f%% of Range\n",100*range_factor;231 d-=100*range_factor;232 '_______\n';233 234 235 if (d>=0) {236 "+%5.2f Hit\n",d;237 Noise(500*animation_delay,34,41);238 Sleep(500*animation_delay);239 } else {240 "-%5.2f Miss\n",-d;241 Noise(1000*animation_delay,69,74);242 Sleep(1000*animation_delay);243 i=RandU16%6;244 if (tmpi->row&1)245 tmpi->col+=col_offsets_odd[i];246 else247 tmpi->col+=col_offsets_even[i];248 tmpi->row+=row_offsets[i];249 RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);250 }251 252 Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);253 firing=FALSE;254 tmpu->fired=TRUE;255 indirect_row=tmpi->row;256 indirect_col=tmpi->col;257 indirect_explosion=TRUE;258 for (i=0;i<7;i++) {259 if (tmpi->row&1)260 c=tmpi->col+col_offsets_odd[i];261 else262 c=tmpi->col+col_offsets_even[i];263 r=tmpi->row+row_offsets[i];264 if (0<=r<map_rows && 0<=c<map_cols && (target=UnitFind(r,c))) {265 AttackHeader(tmpu,"IndirectFire",target);266 DamageDo(target,HitDamage(tmpu,target));267 }268 }269 Noise(2000*animation_delay,70,74);270 Sleep(2000*animation_delay);271 while (snd.ona!=ONA_REST) //see Snd()272 Yield;273 indirect_explosion=FALSE;274 275 QueRem(tmpi);276 Free(tmpi);277 tmpi=tmpi1;278 }279}280 