279 lines
6.7 KiB
HolyC
Executable File
279 lines
6.7 KiB
HolyC
Executable File
U0 AttackHeader(Unit *tmpu,U8 *st,Unit *target)
|
||
{
|
||
I64 i=9+StrLen(st);
|
||
if (target) {
|
||
i+=9;
|
||
if (target->armor)
|
||
i+=8;
|
||
else
|
||
i+=10;
|
||
}
|
||
'\n\n';
|
||
"$$BLACK$$%h*c$$FG$$\n",i,'-';
|
||
if (tmpu->player)
|
||
"$$PURPLE$$Player 2$$FG$$ ";
|
||
else
|
||
"$$CYAN$$Player 1$$FG$$ ";
|
||
"%s",st;
|
||
if (target) {
|
||
if (target->player)
|
||
" $$PURPLE$$Player 2";
|
||
else
|
||
" $$CYAN$$Player 1";
|
||
if (target->armor)
|
||
" Armored";
|
||
else
|
||
" Unarmored";
|
||
'$$FG$$';
|
||
}
|
||
'\n';
|
||
"$$BLACK$$%h*c$$FG$$\n",i,'-';
|
||
}
|
||
|
||
F64 HitDamage(Unit *tmpu,Unit *target,I64 facing=1,F64 range_factor=0)
|
||
{
|
||
F64 d,res=200.0*Rand;
|
||
"\nRoll Out of 200\t\t:%6.2f Damage\n",res;
|
||
if (target->armor) {
|
||
d=target->armor/100.0*(5-facing)/5.0;
|
||
if (d>=0) {
|
||
"ArmorAttack\t\t:%6.2f\n",ToF64(tmpu->armored_attack);
|
||
res*=(tmpu->armored_attack/100.0)/d;
|
||
} else
|
||
res=0;
|
||
"Armor(%z)Defense\t:%6.2f\n",facing,
|
||
"Front\0FrontSide\0RearSide\0Rear\0",100*d;
|
||
} else {
|
||
d=1.0-range_factor;
|
||
if (d>0) {
|
||
"Unarmored Attack\t:%6.2f\n",ToF64(tmpu->unarmored_attack);
|
||
"Range Adjust\t\t:%6.2f%%\n",100*d;
|
||
res*=(tmpu->unarmored_attack/100.0)*d;
|
||
} else
|
||
res=0;
|
||
}
|
||
"Attack/Defense Adjusted\t:%6.2f Damage\n",res;
|
||
return Round(res);
|
||
}
|
||
|
||
Bool DamageDo(Unit *target,F64 damage)
|
||
{
|
||
if (damage>0) {
|
||
if (target->armor)
|
||
"Armor Hit Score %6.2f\t:",damage;
|
||
else
|
||
"%3d Life - %3f Damage\t=",target->life,damage;
|
||
if (damage>=target->life) {
|
||
"$$RED$$Killed$$FG$$\n";
|
||
Noise(1000*animation_delay,74,98);
|
||
Sleep(1000*animation_delay);
|
||
target->life=0;
|
||
VisRecalc(VR_FRIENDLY_UNIT_DIED,target);
|
||
alive_cnt[target->player]--;
|
||
return TRUE;
|
||
} else {
|
||
if (target->armor) {
|
||
if (damage>0.6*target->life) {
|
||
target->movement=0;
|
||
"$$RED$$Immobilized$$FG$$\n";
|
||
} else
|
||
"$$GREEN$$No Penetration$$FG$$\n";
|
||
} else {
|
||
target->life-=damage;
|
||
"$$RED$$%6.2f Life$$FG$$\n",ToF64(target->life);
|
||
}
|
||
return FALSE;
|
||
}
|
||
} else
|
||
return FALSE;
|
||
}
|
||
|
||
U0 IndirectAdd(Unit *tmpu,I64 row,I64 col)
|
||
{
|
||
IndirectOrders *tmpi;
|
||
if (tmpu->life<=0 || tmpu->range<=0)
|
||
return;
|
||
tmpu->fired=TRUE;
|
||
tmpi=CAlloc(sizeof(IndirectOrders));
|
||
tmpi->attacker=tmpu;
|
||
tmpi->row=row;
|
||
tmpi->col=col;
|
||
QueIns(tmpi,indirect_head.last);
|
||
}
|
||
|
||
Bool BulletPlot(U0,I64 x,I64 y,I64)
|
||
{
|
||
fire_x=x; fire_y=y;
|
||
firing=TRUE;
|
||
Sleep(3*animation_delay);
|
||
return TRUE;
|
||
}
|
||
|
||
U0 UnitDirectFire(Unit *tmpu,Unit *target)
|
||
{
|
||
I64 r,c,facing,
|
||
t1=terrain[tmpu->row][tmpu->col],t2=terrain[target->row][target->col];
|
||
F64 x1,y1,x2,y2,d,a,range_factor;
|
||
if (tmpu->life<=0 || target->life<=0 || tmpu->range<=0)
|
||
return;
|
||
AttackHeader(tmpu,"DirectFire",target);
|
||
RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
|
||
RowCol2XY(&x2,&y2,target->row,target->col);
|
||
d=100*Rand;
|
||
"+%5.2fRoll\n",d;
|
||
d+=tmpu->accuracy;
|
||
"+%2d.00Accuracy\n",tmpu->accuracy;
|
||
|
||
range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
|
||
"-%5.2f%% of Range\n",100*range_factor;
|
||
d-=100*range_factor;
|
||
if (t2==TREES) {
|
||
"-30.00Target in Trees Penalty\n";
|
||
d-=30;
|
||
}
|
||
if (t1==MOUNTAINS && t2!=MOUNTAINS) {
|
||
"+30.00High Ground Bonus\n";
|
||
d+=30;
|
||
}
|
||
"_______\n";
|
||
target_unit=target;
|
||
if (d>=0) {
|
||
"+%5.2fHit\n",d;
|
||
target_hit=TRUE;
|
||
Noise(500*animation_delay,34,41);
|
||
Sleep(500*animation_delay);
|
||
Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
|
||
} else {
|
||
"-%5.2fMiss\n",-d;
|
||
target_hit=FALSE;
|
||
Noise(1000*animation_delay,69,74);
|
||
Sleep(1000*animation_delay);
|
||
a=<EFBFBD>*2*Rand;
|
||
d=(0.5-d/100)*HEX_SIDE;
|
||
Line(NULL,x1,y1,0,x2+d*Cos(a),y2+d*Sin(a),0,&BulletPlot);
|
||
}
|
||
firing=FALSE;
|
||
tmpu->fired=TRUE;
|
||
if (target_hit) {
|
||
r=target->row;c=target->col;
|
||
if ((facing=HexMoveOne(&r,&c,x1,y1))>=0)
|
||
facing=FacingChg(facing,target->facing);
|
||
else
|
||
facing=0;
|
||
DamageDo(target,HitDamage(tmpu,target,facing,range_factor));
|
||
}
|
||
while (scrncast.ona) //see $LK,"Snd",A="MN:Snd"$()
|
||
Yield;
|
||
target_unit=NULL;
|
||
}
|
||
|
||
Bool HexOccupy(Bool overrun,Unit *tmpu,Unit *target)
|
||
{
|
||
I64 t2=terrain[target->row][target->col];
|
||
F64 damage;
|
||
if (tmpu->life<=0 || target->life<=0)
|
||
return FALSE;
|
||
if (overrun)
|
||
AttackHeader(tmpu,"OverRun",target);
|
||
else
|
||
AttackHeader(tmpu,"CloseAssault",target);
|
||
Noise(500*animation_delay,34,41);
|
||
Sleep(500*animation_delay);
|
||
tmpu->fired=TRUE;
|
||
target->fired=TRUE;
|
||
damage=HitDamage(tmpu,target);
|
||
if (overrun) {
|
||
damage*=2.0;
|
||
"x2 OverRun Bonus\t=%6.2f Damage\n",damage;
|
||
if (t2!=PLAINS) {
|
||
damage/=2.0;
|
||
"/2 Terrain Penalty\t=%6.2f Damage\n",damage;
|
||
}
|
||
} else {
|
||
damage*=3.0;
|
||
"x3 CloseAssault Bonus\t=%6.2f Damage\n",damage;
|
||
}
|
||
if (DamageDo(target,Round(damage))) {
|
||
"$$RED$$Success$$FG$$\n";
|
||
while (scrncast.ona) //see $LK,"Snd",A="MN:Snd"$()
|
||
Yield;
|
||
return TRUE;
|
||
} else {
|
||
tmpu->life=0;
|
||
VisRecalc(VR_FRIENDLY_UNIT_DIED,tmpu);
|
||
alive_cnt[tmpu->player]--;
|
||
"$$RED$$Failure$$FG$$\n";
|
||
while (scrncast.ona) //see $LK,"Snd",A="MN:Snd"$()
|
||
Yield;
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
U0 IndirectResolveAll()
|
||
{
|
||
I64 i,r,c;
|
||
F64 x1,y1,x2,y2,d,range_factor;
|
||
Unit *tmpu,*target;
|
||
IndirectOrders *tmpi=indirect_head.next,*tmpi1;
|
||
while (tmpi!=*indirect_head) {
|
||
tmpi1=tmpi->next;
|
||
tmpu=tmpi->attacker;
|
||
AttackHeader(tmpu,"IndirectFire",NULL);
|
||
RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
|
||
RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
|
||
d=100*Rand;
|
||
"+%5.2fRoll\n",d;
|
||
d+=tmpu->accuracy;
|
||
"+%2d.00Accuracy\n",tmpu->accuracy;
|
||
range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
|
||
"-%5.2f%% of Range\n",100*range_factor;
|
||
d-=100*range_factor;
|
||
'_______\n';
|
||
|
||
|
||
if (d>=0) {
|
||
"+%5.2fHit\n",d;
|
||
Noise(500*animation_delay,34,41);
|
||
Sleep(500*animation_delay);
|
||
} else {
|
||
"-%5.2fMiss\n",-d;
|
||
Noise(1000*animation_delay,69,74);
|
||
Sleep(1000*animation_delay);
|
||
i=RandU16%6;
|
||
if (tmpi->row&1)
|
||
tmpi->col+=col_offsets_odd[i];
|
||
else
|
||
tmpi->col+=col_offsets_even[i];
|
||
tmpi->row+=row_offsets[i];
|
||
RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
|
||
}
|
||
|
||
Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
|
||
firing=FALSE;
|
||
tmpu->fired=TRUE;
|
||
indirect_row=tmpi->row;
|
||
indirect_col=tmpi->col;
|
||
indirect_explosion=TRUE;
|
||
for (i=0;i<7;i++) {
|
||
if (tmpi->row&1)
|
||
c=tmpi->col+col_offsets_odd[i];
|
||
else
|
||
c=tmpi->col+col_offsets_even[i];
|
||
r=tmpi->row+row_offsets[i];
|
||
if (0<=r<map_rows && 0<=c<map_cols && (target=UnitFind(r,c))) {
|
||
AttackHeader(tmpu,"IndirectFire",target);
|
||
DamageDo(target,HitDamage(tmpu,target));
|
||
}
|
||
}
|
||
Noise(2000*animation_delay,70,74);
|
||
Sleep(2000*animation_delay);
|
||
while (scrncast.ona) //see $LK,"Snd",A="MN:Snd"$()
|
||
Yield;
|
||
indirect_explosion=FALSE;
|
||
|
||
QueRem(tmpi);
|
||
Free(tmpi);
|
||
tmpi=tmpi1;
|
||
}
|
||
}
|