templeos-info/public/Wb/Apps/ToTheFront/TTFFire.HC

279 lines
6.7 KiB
HolyC
Raw Normal View History

2024-03-16 10:26:19 +00:00
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;
}
}