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

279 lines
6.7 KiB
HolyC
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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