EDIT:
I just went trough the code, thing is that file regulating MD strings is around 18000 lines off code so I might have missed something but I think this is what regulates capturing:
Code
OneObject* SearchCapturers(int cell,byte mmask){
cell+=VAL_MAXCX+1;
int NMon=MCount[cell];
if(!NMon)return NULL;
int ofs1=cell<<SHFCELL;
word MID;
for(int i=0;i<NMon;i++){
MID=GetNMSL(ofs1+i);
if(MID!=0xFFFF){
OneObject* OB=Group[MID];
if(OB){
NewMonster* NM=OB->newMons;
if(!(OB->NMask&mmask||NM->Capture||NM->CantCapture||OB->NNUM==7))return OB;
};
};
};
return NULL;
};
OneObject* SearchProtectors(int cell,byte mmask){
cell+=VAL_MAXCX+1;
int NMon=MCount[cell];
if(!NMon)return NULL;
int ofs1=cell<<SHFCELL;
word MID;
for(int i=0;i<NMon;i++){
MID=GetNMSL(ofs1+i);
if(MID!=0xFFFF){
OneObject* OB=Group[MID];
if(OB&&(OB->NMask&mmask)&&!(OB->newMons->Capture||OB->Sdoxlo)){
if(OB->BrigadeID!=0xFFFF||(!EngSettings.DefendOnlyWithFormations)){
return OB;
}
}
};
};
return NULL;
};
bool CheckProtectors_Walls(int x,int y,byte mask){
return false;
};
int GetProtectors(int cell,byte mmask){
cell+=VAL_MAXCX+1;
int NMon=MCount[cell];
if(!NMon)return NULL;
int ofs1=cell<<SHFCELL;
word MID;
int N=0;
for(int i=0;i<NMon;i++){
MID=GetNMSL(ofs1+i);
if(MID!=0xFFFF){
OneObject* OB=Group[MID];
if(OB&&(OB->NMask&mmask)&&!(OB->newMons->Capture||OB->Sdoxlo)){
if(OB->BrigadeID!=0xFFFF||(!EngSettings.DefendOnlyWithFormations))N++;
}
};
};
return N;
};
word GetNearestDefender(OneObject* OBJ){
int cell=((OBJ->RealY>>11)<<VAL_SHFCX)+(OBJ->RealX>>11);
int CELL0=cell;
int rx1=3;
int rx2=rx1+rx1+1;
int stcell=cell-rx1-(rx1<<VAL_SHFCX);
byte NMASK=OBJ->NMask;
byte* bpt=NPresence+stcell;
for(int nx=0;nx<rx2;nx++){
for(int ny=0;ny<rx2;ny++){
if(stcell>=0&&stcell<VAL_MAXCX*VAL_MAXCX){
if(bpt[0]&NMASK){
OneObject* EOB=SearchProtectors(stcell,NMASK);
if(EOB)return EOB->Index;
};
};
stcell++;
bpt++;
};
stcell+=VAL_MAXCX-rx2;
bpt+=VAL_MAXCX-rx2;
};
return 0xFFFF;
};
bool CheckObjectForCapture(OneObject* OB);
int TestCapture(OneObject* OBJ){
if(!EngSettings.EnableCapturing){
if(OBJ->Stage<OBJ->NStages&&OBJ->Ref.General->MoreCharacter->MaxR_Attack){
return true;
}
return false;
}
if(!(CheckObjectForCapture(OBJ)||!(OBJ->Ready||OBJ->LocalOrder)))return -1;
switch(CaptState){
case 1:
if(OBJ->newMons->Peasant)return -1;
break;
case 2:
if(OBJ->newMons->Peasant||OBJ->newMons->Usage==CenterID||OBJ->newMons->Usage==MineID)return -1;
break;
case 3:
if(!OBJ->newMons->Artilery)return -1;
break;
};
int cell=((OBJ->RealY>>11)<<VAL_SHFCX)+(OBJ->RealX>>11);
int X0=OBJ->RealX>>10;
int Y0=OBJ->RealY>>10;
int CELL0=cell;
NewMonster* NM=OBJ->newMons;
byte nmask=~OBJ->NMask;
byte NMASK=OBJ->NMask;
OneObject* DestObj=NULL;
int mindist=10000000;
int rx1=3+((NM->AddShotRadius+64)/128);
int rcap=(120*3+NM->AddShotRadius)*16;
//X0-=rx1+rx1;
//Y0-=rx1+rx1;
bool Capture=true;
int rx2=rx1+rx1+1;
int stcell=cell-rx1-(rx1<<VAL_SHFCX);
byte* bpt=NPresence+stcell;
//byte MyMask=OBJ->NMask;
if(!(OBJ->Wall&&OBJ->Life<OBJ->MaxLife/3)){
if(OBJ->NewBuilding){
rx1+=4;
rcap+=128*16*4;
}else{
rx1++;
rcap+=128*16;
}
rx2=rx1+rx1+1;
stcell=CELL0-rx1-(rx1<<VAL_SHFCX);
//checking help
bpt=NPresence+stcell;
for(int nx=0;nx<rx2&&Capture;nx++){
for(int ny=0;ny<rx2&&Capture;ny++){
if(stcell>=0&&stcell<VAL_MAXCX*VAL_MAXCX){
if(bpt[0]&NMASK){
OneObject*OB=SearchProtectors(stcell,NMASK);
if(OB&&!OB->newMons->Capture){
int dist=Norma(OB->RealX-OBJ->RealX,OB->RealY-OBJ->RealY);
if(dist<rcap){
Capture=false;
}
}
//if(CheckProtectors_Walls(X0+nx+nx,Y0+ny+ny,MyMask))Capture=false;
};
};
stcell++;
bpt++;
};
stcell+=VAL_MAXCX-rx2;
bpt+=VAL_MAXCX-rx2;
};
};
if(Capture)return 0;
else return -1;
};
extern int LastAttackDelay;
extern short AlarmSoundID;
extern int LastAttackX;
extern int LastAttackY;
extern int AlarmDelay;
void CheckCapture(OneObject* OBJ){
NewMonster* NM=OBJ->newMons;
if(NM->NeverCapture)return;
switch(CaptState){
case 1:
if(OBJ->newMons->Peasant)return;
break;
case 2:
if(OBJ->newMons->Peasant||OBJ->newMons->Usage==CenterID||OBJ->newMons->Usage==MineID)return;
break;
case 3:
if(!(OBJ->newMons->Artilery||OBJ->Wall))return;
break;
};
int cell=((OBJ->RealY>>11)<<VAL_SHFCX)+(OBJ->RealX>>11);
//int X0=OBJ->RealX>>10;
//int Y0=OBJ->RealY>>10;
int CELL0=cell;
byte nmask=~OBJ->NMask;
byte NMASK=OBJ->NMask;
OneObject* DestObj=NULL;
int mindist=10000000;
int dist;
int rx1=3+((NM->AddShotRadius+64)/128);
int rcap=(120*3+NM->AddShotRadius)*16;
//X0-=rx1+rx1;
//Y0-=rx1+rx1;
bool Capture=false;
int rx2=rx1+rx1+1;
int stcell=cell-rx1-(rx1<<VAL_SHFCX);
byte CapNation;
byte* bpt=NPresence+stcell;
int NCapt=0;
OneObject* CAPUNIT=NULL;
//byte MyMask=OBJ->NMask;
for(int nx=0;nx<rx2;nx++){
for(int ny=0;ny<rx2;ny++){
if(stcell>=0&&stcell<VAL_MAXCX*VAL_MAXCX){
if(bpt[0]&nmask){
OneObject*OB=SearchCapturers(stcell,NMASK);
if(OB&&OB->BrigadeID!=0xFFFF&&!OB->newMons->Capture){
dist=Norma(OB->RealX-OBJ->RealX,OB->RealY-OBJ->RealY);
if(dist<rcap){
if(OB->BrigadeID!=0xFFFF||(!EngSettings.CaptureOnlyWithFormations)){
Capture=true;
CapNation=OB->NNUM;
NCapt++;
CAPUNIT=OB;
}
}
}
}
}
stcell++;
bpt++;
};
stcell+=VAL_MAXCX-rx2;
bpt+=VAL_MAXCX-rx2;
};
int npro=0;
if(Capture){
int ac1=GetUnitActivity(OBJ);
if(ac1==1&&!CAPUNIT)return;
if(CAPUNIT){
int ac2=GetUnitActivity(CAPUNIT);
if(ac1==1){
CAPUNIT->Die();
return;
};
};
};
if(Capture&&!(OBJ->Wall&&OBJ->Life<OBJ->MaxLife/3)){
if(!OBJ->newMons->Peasant){
OBJ->delay=100;
OBJ->MaxDelay=100;
addname(OBJ->Index);
};
if(OBJ->NewBuilding){
rx1+=4;
rcap+=128*16*4;
}else{
rx1++;
rcap+=128*16;
}
rx2=rx1+rx1+1;
stcell=CELL0-rx1-(rx1<<VAL_SHFCX);
//checking help
bpt=NPresence+stcell;
for(nx=0;nx<rx2;nx++){
for(int ny=0;ny<rx2;ny++){
if(stcell>=0&&stcell<VAL_MAXCX*VAL_MAXCX){
if(bpt[0]&NMASK){
OneObject*OB=SearchProtectors(stcell,NMASK);
if(OB&&!OB->newMons->Capture){
dist=Norma(OB->RealX-OBJ->RealX,OB->RealY-OBJ->RealY);
if(dist<rcap){
Capture=false;
npro++;
}
}
//if(CheckProtectors_Walls(X0+nx+nx,Y0+ny+ny,MyMask))Capture=false;
}
}
stcell++;
bpt++;
};
stcell+=VAL_MAXCX-rx2;
bpt+=VAL_MAXCX-rx2;
};
if(OBJ->Nat->AI_Enabled&&OBJ->newMons->Artilery){
if(npro&&(NCapt>=npro&&npro==1)||(NCapt>3&&npro==2)||(NCapt>7&&npro==3)||(NCapt>10&&npro==4)){
OBJ->Die();
return;
};
};
};
if(Capture){
if(!EngSettings.EnableCapturing){
if(OBJ->Stage<OBJ->NStages&&OBJ->Ref.General->MoreCharacter->MaxR_Attack){
return;
}
return;
}
byte OldNat=OBJ->NNUM;
bool Easy=CITY[OldNat].Difficulty<3;
if(OBJ->UnlimitedMotion&&!OBJ->Hidden){
OBJ->Die();
return;
};
if(OBJ->AutoKill||OBJ->Wall){
int idx=OBJ->Index;
DestructBuilding(OBJ);
if(Group[idx]&&OBJ->Sdoxlo)return;
}else{
/*
if(NATIONS[OldNat].AI_Enabled){
int ttt=tmtmt&63;
if(OBJ->NewBuilding&&ttt>16)DestructBuilding(OBJ);
else{
byte use=OBJ->newMons->Usage;
if(use==PeasantID&&!Easy){
DestructBuilding(OBJ);
}else{
if((use==SupMortID&&ttt>30)||(use==PushkaID&&ttt>20)||
(use==MortiraID&&ttt>8)||(use==PeasantID&&ttt>35)){
DestructBuilding(OBJ);
return;
};
};
};
}else{
*/
//};
};
if(!ext_OnUnitCapture(OBJ,CAPUNIT))return;
LogBattle(OldNat,"^ST_BCAPT^ %s(%d)",GetSt_UName(CAPUNIT->NIndex),CITY[OldNat].ReadyAmount[CAPUNIT->NIndex]-1);
NATIONS[OldNat].NKilled[OBJ->NIndex]++;
OBJ->Nat->CITY->Account-=OBJ->newMons->Ves*5;
CITY[CapNation].Account+=OBJ->newMons->Ves*5;
if(OBJ->NNUM==MyNation&&OBJ->NewBuilding){
char ccc[200];
sprintf(ccc,CAPBLD,OBJ->Ref.General->Message);
AssignHint1(ccc,100,32);
};
if(OBJ->NNUM==MyNation){
LastActionX=OBJ->RealX>>4;
LastActionY=OBJ->RealY>>4;
LastAttackX=OBJ->RealX;
LastAttackY=OBJ->RealY;
AlarmDelay=60;
};
if(OBJ->newMons->Usage==PeasantID)OBJ->ClearOrders();
//if(OBJ->NewBuilding&&(!OBJ->Ready)&&OBJ->Stage>=OBJ->Ref.General->MoreCharacter->ProduceStages)
// OBJ->Ready=true;
DelObject(OBJ);
OBJ->Nat->CITY->UnRegisterNewUnit(OBJ);
int oldst=OBJ->Stage;
int oldmax=OBJ->Ref.General->MoreCharacter->ProduceStages;
OBJ->Ref.General=NATIONS[CapNation].Mon[OBJ->NIndex];
OBJ->Nat=&NATIONS[CapNation];
OBJ->NMask=OBJ->Nat->NMask;
OBJ->Serial^=1;
OBJ->Selected=0;
OBJ->ImSelected=0;
OBJ->Zombi=false;
if(NATIONS[OldNat].AI_Enabled){
if(OBJ->NewBuilding && OBJ->CObjIndex==0xFFFF){
DestructBuilding(OBJ);
return;
};
};
if(OBJ->NewBuilding&&OldNat==MyNation){
LastAttackDelay=900;
if(AlarmSoundID!=-1){
//AddEffect((mapx<<5)+500,(mapy<<4)+300,AlarmSoundID);
void PlaySound(char* Name);
PlaySound("ZAHVAT_ZDANIYA");
LastActionX=OBJ->RealX>>4;
LastActionY=OBJ->RealY>>4;
AlarmDelay=60;
};
};
OBJ->NNUM=CapNation;
OBJ->Nat->CITY->RegisterNewUnit(OBJ);
AddObject(OBJ);
if(OBJ->NewBuilding)
OBJ->Stage=(oldst*int(OBJ->Ref.General->MoreCharacter->ProduceStages))/oldmax;
if(OBJ->NInside){
if(!CaptState){
word* Uni=OBJ->Inside;
for(int j=0;j<OBJ->NInside;j++){
word MID=Uni[j];
if(MID!=0xFFFF){
OneObject* OB=Group[MID];
if(OB){
OB->Nat->CITY->Account-=OB->newMons->Ves*5;
CITY[CapNation].Account+=OB->newMons->Ves*5;
if(OB->newMons->Usage==PeasantID)OB->ClearOrders();
DelObject(OB);
OB->Nat->CITY->UnRegisterNewUnit(OB);
OB->Ref.General=NATIONS[CapNation].Mon[OB->NIndex];
OB->Nat=&NATIONS[CapNation];
OB->NMask=OB->Nat->NMask;
OB->Serial^=1;
OB->Selected=false;
OB->ImSelected=false;
OB->Zombi=false;
byte OldNat=OB->NNUM;
OB->NNUM=CapNation;
OB->Nat->CITY->RegisterNewUnit(OB);
AddObject(OB);
if(OB->LocalOrder)OB->Ready=1;
OB->ClearOrders();
};
};
};
}else DestructBuilding(OBJ);
};
if(NATIONS[CapNation].AI_Enabled)DestructBuilding(OBJ);
};
};
Note that this is from Cossacks 2, but C2 was build over C1 and only contains new features and disabling off old features. What is in C1 is in C2.
I cant seem to find a real difference between CAPTURE and CANBECAPTUREDWHENFREE however, but then again, the file is long and I may have missed it.