Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit uBot;
- interface
- uses uActor, uProdList, uDefs;
- const
- MaxPinValue = 10000;
- type
- //Bots special Building Function Variables
- TBuildItem = Record
- PointerID : integer;
- DesignQty : int64;
- ActualQty : int64;
- DesignOffSet : real;
- PercentageOfBuild : integer;
- BuildWeight : integer;
- end;
- TBuildMatrix = class( TObject )
- Ratios : array of TBuildItem;
- DesignTotal : int64;
- ActualTotal : int64;
- DesignToActualOffset : real;
- DesignOffSetTotal : real;
- TotalMatrixLines : integer;
- constructor Create;
- destructor Destroy; //override;
- procedure Clear;
- procedure CalcDesignToActualOffset;
- end; //Bots special Initing Function Variables
- TBotBrain = class( TObject )
- public
- ProductionMatrix : TBuildMatrix;
- ConstructionMatrix : TBuildMatrix;
- ResearchMatrix : TBuildMatrix;
- BotPerform : TBotPerforms;
- BotProdRatio : TProdRatios;
- BotID : integer;
- constructor Create;
- destructor Destroy;//override;
- procedure AddPerform(const nPerform:TBotPerform);
- procedure RemovePerform(const nPerform:TBotPerform);
- procedure ThinkRoids();
- function ThinkProductionDesign():boolean;
- procedure ThinkProduction();
- function ThinkPowerplantChance(Yield:integer):integer;
- function ThinkGetDesignQty(nPointerID:integer):integer;
- function ThinkStructureDesign():boolean;
- procedure ThinkStructures();
- procedure ThinkResearchDesign(nT,nP,nW,nM,nC,nR,nB:integer);
- function ThinkGetPriority(const nResearchID:integer):integer;
- procedure ThinkResearch();
- function ThinkFindDefender(var Hostile, Target,Defender:TActor):boolean;
- procedure ThinkDefenceCall(var Hostile, Target:TActor;DefenceTries:integer);
- procedure ThinkInvaders();
- function ThinkViableTarget(var Sender, Receiver:TActor):boolean;
- procedure ThinkLaunch(var Sender, Receiver:TActor);
- procedure ThinkAttack(AttackTries,AttackChance:integer);
- function ThinkGotPods():boolean;
- procedure Think(nBotID:integer);
- procedure CycleBots();
- function AIBot():TActor;
- end;
- implementation
- uses uGame, uDebug.common, SysUtils, uBase, Math, uFuncs.common;
- {=========================================================================}
- { BuildMatrix - Used to create the build chance lists, very complex! }
- {=========================================================================}
- constructor TBuildMatrix.Create;
- begin
- inherited Create;
- Clear;
- end;
- destructor TBuildMatrix.Destroy;
- begin
- Ratios := nil;
- inherited Destroy;
- end;
- procedure TBuildMatrix.Clear;
- begin
- SetLength( Ratios, 0 );
- DesignTotal := 0;
- ActualTotal := 0;
- DesignToActualOffset := 0;
- DesignOffSetTotal := 0;
- end;
- procedure TBuildMatrix.CalcDesignToActualOffset;
- var I : integer; nStr:string;
- begin
- nStr := '';
- DesignToActualOffSet := DesignTotal / ActualTotal; // Basically Fixs the difference in Design/Acutal quantitys.
- DesignOffSetTotal := 0;
- if (DesignToActualOffSet > 0) then
- begin
- for I := 0 to TotalMatrixLines-1 do
- begin
- with Ratios[I] do
- begin
- DesignOffSet := DesignQty / (ActualQty * DesignToActualOffSet);
- DesignOffSetTotal := DesignOffSetTotal + DesignOffSet;
- end;
- end;{if}
- end;
- for I := 0 to TotalMatrixLines-1 do
- begin
- with Ratios[I] do
- begin
- PercentageOfBuild := 0;
- BuildWeight := 0;
- if (DesignOffSet > 0)and(DesignOffSetTotal > 0) then
- begin
- PercentageOfBuild := ceil(MaxPinValue * (DesignOffSet / DesignOffSetTotal));
- case I of // Because of the negative index
- 0 : BuildWeight := PercentageOfBuild;
- else BuildWeight := PercentageOfBuild + Ratios[I-1].BuildWeight;
- end; {case}
- if (BuildWeight > MaxPinValue) then BuildWeight := MaxPinValue;
- end;{if}
- end;{with}
- end;{for}
- end;
- {=========================================================================}
- { BotBrain }
- {=========================================================================}
- constructor TBotBrain.Create;
- begin
- inherited Create;
- DevConsole.Msg(ES_DEBUG,'<< TBotBrain.Create >>');
- ProductionMatrix := TBuildMatrix.Create;
- ConstructionMatrix := TBuildMatrix.Create;
- ResearchMatrix := TBuildMatrix.Create;
- BotPerform := [bpPLAYER]+[bpATTACK]+[bpDEFEND]+[bpRESEARCH]+[bpINIT]+[bpBUILD];
- SetLength(ConstructionMatrix.Ratios, Game.MAX_STRUCTURES+1);
- SetLength(ResearchMatrix.Ratios, 7);
- ThinkResearchDesign(36,14,74,11,74,61,37);
- BotID := 0;
- end;
- destructor TBotBrain.Destroy;
- begin
- FreeAndNil( ProductionMatrix );
- FreeAndNil( ConstructionMatrix );
- FreeAndNil( ResearchMatrix );
- inherited Destroy;
- end;
- {=========================================================================}
- { AutoBot Features }
- {=========================================================================}
- procedure TBotBrain.AddPerform(const nPerform:TBotPerform);
- begin
- BotPerform := BotPerform + [nPerform];
- end;
- procedure TBotBrain.RemovePerform(const nPerform:TBotPerform);
- begin
- BotPerform := BotPerform - [nPerform];
- end;
- {=========================================================================}
- { HOME - Roids }
- {=========================================================================}
- procedure TBotBrain.ThinkRoids();
- begin
- while (AIBot.Asteroids.GetNextAsteroidCost(Game.BASE_ROID_COST, Game.ROID_COST_MULITPLIER) <= AIBot.Credits.Value) do
- AIBot.BuyRoid( 1 );
- end;
- {=========================================================================}
- { HOME - Production }
- {=========================================================================}
- function TBotBrain.ThinkProductionDesign():boolean;
- var
- L : integer;
- nUnitID : integer;
- begin
- with ProductionMatrix do
- begin
- TotalMatrixLines := 0; //Only will go up to include total ships that can be built
- DesignTotal := 0;
- ActualTotal := 0;
- for L := 0 to BotProdRatio.TotalRatios-1 do
- begin
- nUnitID := BotProdRatio.Ratios[ L ].UnitID;
- if ( AIBot().Credits.Value >= Game.wbUnit( nUnitID ).Cost.Value ) and //Enough resource?
- ( AIBot().isUnitResearchReady( nUnitID ) ) and
- (AIBot().isUnitFactoryReady( nUnitID ) ) and //can build?
- not( aNONE in Game.wbUnit( nUnitID ).Attributes ) then//Want to build?
- begin
- Inc( TotalMatrixLines );
- with Ratios[TotalMatrixLines-1] do
- begin
- PointerID := nUnitID;
- //======================= Included until can import ratios
- DesignQty := round( Ceil( 100000 / Game.wbUnit( nUnitID ).Armor ));// + Random(Ceil(1000/Armor))+100 ); // Precentage of Armor and add a little bit of random
- if ( Game.wbUnit( nUnitID ).isPod ) then
- DesignQty := ceil( DesignQty / 50); // Build less Pods
- if ( Game.wbUnit( nUnitID ).isStruct ) then
- DesignQty := ceil( DesignQty / 200); // Build Less Structure Killers
- //========================================================
- ActualQty := AIBot().FleetList.Fleet[ Game.MAX_FLEETS ].Units[nUnitID];
- if (ActualQty <= 0) then ActualQty := 1; //Bah!!! Cant get away from this BAD bug fix!!! Div by ZERO error otherwise
- Inc( ActualTotal, ActualQty );
- Inc( DesignTotal, DesignQty );
- end;{with}
- end;{with|if}
- end;{for}
- if (TotalMatrixLines <= 0) then // No Design so lets try and leave the Production area
- result := FALSE
- else
- begin
- CalcDesignToActualOffset;
- result := TRUE;
- end;
- end;{with}
- end;
- procedure TBotBrain.ThinkProduction();
- // NOTE:
- // Units to be built will be based upon cost of unit (Armor per Cost Ratio) modified roids income.
- // Also Matrix calcs are reperformed when the bot can not afford a unit and the DesignQty > 0
- // Once DesignFleetTotal = 0 then bot can no longer afford any units and will quit this procedure
- var
- I, Counter,
- nUnitID,
- InfiniteLoopTrap : integer;
- PinLine : integer;
- ContinueMatrix : boolean;
- begin
- DevConsole.ClearBuffer;
- DevConsole.AddToBuffer('(TBotBrain.ThinkProduction) '+AIBot.Name+' #'+IntToStr(AIBot.ActorID));
- BotProdRatio := Game.ProdRatiosList.Items[ AIBot.FactionID ];
- DevConsole.AddToBuffer('BotProdRatio '+IntToStr(BotProdRatio.TotalRatios));
- SetLength(ProductionMatrix.Ratios, BotProdRatio.TotalRatios);
- with ProductionMatrix do
- begin
- Counter := 0;// Infinite Loop Trap
- InfiniteLoopTrap := 75;
- repeat
- ContinueMatrix := ThinkProductionDesign(); //Will return FALSE if no design was created.
- if (ContinueMatrix) then
- begin
- DevConsole.AddToBuffer('[Credits] '+IntToStr(AIBot.Credits.Value));
- DevConsole.AddToBuffer('[DesignTotal] '+IntToStr(DesignTotal)+
- ' [ActualTotal] '+IntToStr(ActualTotal)+
- ' [D2A %] '+FormatFloat('0.00', DesignToActualOffSet)
- );
- PinLine:= Random(MaxPinValue); // Random line in the sand
- I:= -1;
- nUnitID := -1;
- repeat // Scans through BuildList looking for where the Random value resides.
- Inc( I );
- if (PinLine <= Ratios[ I ].BuildWeight) then
- nUnitID := Ratios[ I ].PointerID;
- DevConsole.AddToBuffer('[nUnitID] '+IntToStr(nUnitID)+
- ' [Name] '+Game.wbUnit( Ratios[ I ].PointerID ).Name+
- ' [Pin] '+IntToStr( PinLine )+
- ' [Weight] '+IntToStr( Ratios[ I ].BuildWeight ) );
- until (I >= TotalMatrixLines-1)or(nUnitID >= 0);
- if (nUnitID > Game.MAX_UNITS)or(nUnitID < 0) then
- begin
- DevConsole.Msg(ES_CRITICAL, 'nUnitID outrange Items :'+
- IntToStr(nUnitID)+' T/F:'+BoolToStr2(ContinueMatrix)+' '+
- ' Matrix: '+IntToStr(TotalMatrixLines));
- DevConsole.FlushBuffer( ES_DEBUG );
- end;
- // DevConsole.FlushBuffer;
- if (nUnitID >= 0) then
- with Game.wbUnit( nUnitID ) do
- AIBot.BuyUnit(nUnitID, (Ceil(Random(5000)/Armor)+Ceil(5000/Armor))*AIBot.Asteroids.Value);
- end;{IF (ContinueMatrix)}
- Inc(Counter);
- until (not ContinueMatrix)or(Counter > InfiniteLoopTrap);
- if (Counter >= InfiniteLoopTrap) then
- begin
- DevConsole.Msg(ES_CRITICAL, 'Possible Infinite Loop Detected.');
- DevConsole.FlushBuffer( ES_DEBUG );
- end;
- Ratios := nil;
- end;{With}
- end;
- {=========================================================================}
- { HOME - Structure }
- {=========================================================================}
- function TBotBrain.ThinkPowerPlantChance(Yield:integer):integer;
- var Chance,Rand : real;
- begin
- result := 1;
- //Chance = ((UsedPW/OutputPW) * (Yield / (OutputPW-UsedPW)))*100
- Rand := random(10000)/100;
- with AIBot() do
- Chance := ((UsedPW/OutputPW) * (Yield /(OutputPW-UsedPW)))*100;
- if (Rand <= Chance) then
- result := 10000000;
- // DevConsole.Msg(ES_DEBUG, '(BotBrain.ThinkPowerPlantChance) Rand:'+FormatFloat('0.00', Rand)+' Chance:'+FormatFloat('0.00', ThinkPowerPlantChance( Yield )) );
- end;
- function TBotBrain.ThinkGetDesignQty(nPointerID:integer):integer;
- begin
- with Game.wbStructure( nPointerID ) do
- begin
- case StructureType of
- stFactory : result := 10;
- stOreMine : result := 1000;
- stFinance : begin
- if (AIBot().Structures.Items[ nPointerID ].Level >= 60) then result := 1
- else
- result := 10000;
- end;
- stPower : result := ThinkPowerPlantChance( Yield );
- stConYard : result := 5;
- stResearch : result := 5;
- stWave : result := 1;
- stDist : result := 1;
- else result := 2;
- end;
- end;
- end;
- function TBotBrain.ThinkStructureDesign():boolean;
- var I : integer;
- begin
- DevConsole.AddToBuffer('(BotBrain.ThinkStructureDesign) '+AIBot().Name);
- with ConstructionMatrix do
- begin
- TotalMatrixLines := 0;
- DesignTotal := 0;
- ActualTotal := 0;
- for I := 0 to Game.MAX_STRUCTURES do
- begin
- if (AIBot().Structures.IsComplete( I )) then // Cant use item yet so quit.
- begin
- Inc( TotalMatrixLines );
- with Ratios[TotalMatrixLines-1] do
- begin
- PointerID := I;
- //======================= Included until can import ratios
- if (AIBot().Structures.Items[PointerID].Level <= 0) then
- DesignQty := 1000000 //force the bot to build at least 1 of every structure
- else
- DesignQty := ThinkGetDesignQty( PointerID );
- { if ( AIBot.Credits.Value < Game.wbStructure( PointerID ).Cost.Value) then
- begin
- Wait := TRUE;
- result := FALSE;
- exit;//Not enough Credits to produce item
- end;
- }
- //========================================================
- Inc( DesignTotal, DesignQty );
- ActualQty := AIBot().Structures.Items[I].Level;
- if (ActualQty <= 0)and(DesignQty > 0) then
- ActualQty := 1; //Bah!!! Cant get away from this BAD bug fix!!! Div by ZERO error otherwise
- Inc( ActualTotal, ActualQty );
- end;
- end;{with}
- end;{for}
- DevConsole.AddToBuffer('--Design #'+IntToStr(DesignTotal)+' Actual #'+IntToStr(ActualTotal));
- if (DesignTotal <= 0) then // No Design so lets try and leave the Production area
- begin
- result := FALSE;
- end
- else
- begin
- CalcDesignToActualOffset;
- result := TRUE;
- end;
- end;{with}
- end;
- procedure TBotBrain.ThinkStructures();
- // NOTE:
- // Units to be built will be based upon cost of unit (Armor per Cost Ratio) modified roids income.
- // Also Matrix calcs are reperformed when the bot can not afford a unit and the DesignQty > 0
- // Once DesignFleetTotal = 0 then bot can no longer afford any units and will quit this procedure
- var
- I, nStructureID : integer;
- PinLine : integer;
- nStr : string;
- begin
- if (AIBot().Structures.CurrentDev.CurID >= 0 ) then exit;
- if (AIBot().TotalStructures >= Game.STRUCTURES_LIMIT) then exit; //Max you can build
- DevConsole.ClearBuffer;
- DevConsole.AddToBuffer('(TBotBrain.ThinkStructures) '+AIBot().Name);
- with ConstructionMatrix do
- begin
- if not( ThinkStructureDesign() ) then exit; //No design list been created
- PinLine:= Random(10000); // Random line in the sand
- nStructureID := -1;
- nStr := '--Ratio Design: #'+IntToStr(PinLine)+' ->';
- for I := 0 to TotalMatrixLines-1 do
- begin // Scans through Ratios List looking for where the Random pin value resides.
- if (PinLine <= Ratios[I].BuildWeight)and(nStructureID < 0) then
- begin
- nStructureID:= Ratios[I].PointerID;
- nStr := nStr + ' >#'+IntToStr( Ratios[I].BuildWeight )+'<';
- end
- else
- nStr := nStr + ' #'+IntToStr( Ratios[I].BuildWeight );
- end;
- DevConsole.AddToBuffer( nStr );
- if (nStructureID >= 0) then
- DevConsole.Msg(ES_DEBUG, AIBot().Structures.StartDev(AIBot().Structures.CurrentDev, nStructureID) )
- else
- begin
- DevConsole.Msg(ES_CRITICAL, 'Selected StructureID Invalid #'+IntToStr(nStructureID));
- DevConsole.FlushBuffer( ES_DEBUG );
- end;
- end;{With}
- end;
- {=========================================================================}
- procedure TBotBrain.ThinkResearchDesign(nT,nP,nW,nM,nC,nR,nB:integer);
- begin
- ResearchMatrix.Ratios[0].DesignQty := nT;
- ResearchMatrix.Ratios[1].DesignQty := nP;
- ResearchMatrix.Ratios[2].DesignQty := nW;
- ResearchMatrix.Ratios[3].DesignQty := nM;
- ResearchMatrix.Ratios[4].DesignQty := nC;
- ResearchMatrix.Ratios[5].DesignQty := nR;
- ResearchMatrix.Ratios[6].DesignQty := nB;
- end;
- function TBotBrain.ThinkGetPriority(const nResearchID:integer):integer;
- var Priority : integer;
- begin
- Priority := 0;
- if (Game.wbResearch( nResearchID ).Branch = 'TRAVEL' ) then Priority := ResearchMatrix.Ratios[0].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'PRODUCTION') then Priority := ResearchMatrix.Ratios[1].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'WAVES' ) then Priority := ResearchMatrix.Ratios[2].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'MINING' ) then Priority := ResearchMatrix.Ratios[3].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'COVERT' ) then Priority := ResearchMatrix.Ratios[4].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'ROIDEFF' ) then Priority := ResearchMatrix.Ratios[5].DesignQty else
- if (Game.wbResearch( nResearchID ).Branch = 'BUILDING' ) then Priority := ResearchMatrix.Ratios[6].DesignQty
- else
- Priority := 50;
- if (Priority > 0) then
- begin
- with AIBot() do
- begin
- Priority := Structures.CalcMaxETA( nResearchID, OutputRU, Game.wbResearch( nResearchID ).Points ) * (result+Random(Priority));// Offsets the ETA by priority
- end;
- end;
- result := Priority;
- // result := ceil( 1000*( AIBot.CalcResearchETA( nResearchID ) * ((100-result)/100)) );// Offsets the ETA by priority
- end;
- procedure TBotBrain.ThinkResearch();
- var
- R,
- TestETA,
- LowestETA,
- TryResearchID : integer;
- begin
- // if (AIBot.CharType <> BOT)and(frmDebug.chkPlayerAutoResearch.Checked = FALSE) then exit;
- if (AIBot.Research.CurrentDev.CurID >= 0 ) then exit;
- LowestETA := 99999999;
- TryResearchID := -1;
- for R:= 0 to Game.MAX_RESEARCH do
- begin
- if (AIBot.Research.Items[ R ].Status = IsVisible) then
- begin
- //================= Will be included in the BotBrain.Skills ==========================
- TestETA := ThinkGetPriority( R );
- //====================================================================================
- if (TestETA < LowestETA) then
- begin
- LowestETA := TestETA;
- TryResearchID := R;
- end;{if}
- end;{if}
- end;{for}
- if (TryResearchID >= 0) then
- AIBot.Research.StartDev( AIBot.Research.CurrentDev, TryResearchID );
- end;
- {=========================================================================}
- { MILITARY - Defence }
- {=========================================================================}
- function TBotBrain.ThinkFindDefender(var Hostile, Target,Defender:TActor):boolean;
- begin
- with Game do
- begin
- result:= FALSE;
- if (Random(100) >= 33) then // Try uni for alliance
- Defender := Stage.Actors[Random(Game.MAX_PLAYERS+1)]
- else
- begin//Next is a galaxy defence!!
- with Hostile.Coords do
- with Game.Galaxy.SolarSystem[Cluster][Solar] do
- with Planet[Random( High( Planet )+1 ) ] do
- Defender := Stage.Actors[ActorID];
- end;
- if (Defender.AllianceID <> Target.AllianceID) then exit; //Same Alliance Dont defend, unless Sender is same alliance...
- if not (Defender.FleetList.Fleet[1].IsHome) then exit; //Fleet is home
- if (Incoming.Items[Defender.ActorID].iEnemies) then exit; //I have no problems of my own
- if (Game.isPeaceTime) then exit; //Out of Peace Time
- result := TRUE; //Defender must be a good candidate
- end;
- end;
- procedure TBotBrain.ThinkDefenceCall(var Hostile, Target:TActor; DefenceTries:integer);
- var
- Defender : TActor;
- P, I,
- HostileETA,
- DefenderETA,
- UnitETA : integer;
- begin
- with Game do
- begin
- if (Random(100)*0.01 >= Target.GetSkill) then exit;
- for P:= 0 to Ceil(DefenceTries * (Target.GetSkill) )+1 do
- begin
- if (ThinkFindDefender(Hostile, Target, Defender)) then
- begin
- with Defender.FleetList do //Move all ships to home fleet
- begin
- doTransferUnits ( -999, '', 0, 0, 1 );
- doTransferUnits ( -999, '', 0, 2, 1 );
- doTransferUnits ( -999, '', 0, 3, 1 );
- end;
- if (Hostile.FleetList.Fleet[1].TargetID = Target.ActorID)and
- (Hostile.FleetList.Fleet[1].ActionTask = fATTACK) then
- begin
- HostileETA := Hostile.FleetList.Fleet[1].CalcETA;
- with Defender.FleetList do
- DefenderETA := Fleet[1].TimeToTarget(Defender.ActorID, Target.ActorID, TravelResearch, fDEFEND);
- if (DefenderETA > HostileETA) then
- begin
- for I := 0 to Game.MAX_UNITS do //Seperate units in to fleets to reach destination in time
- begin
- if (Defender.FleetList.Fleet[0].Units[I] > 0) then
- begin
- with WorldBase.UnitList do
- UnitETA := Items[ I ].TimeToTarget(Defender.ActorID, Target.ActorID, Defender.FleetList.TravelResearch);
- with Defender.FleetList do
- if (UnitETA > HostileETA) then
- doTransferUnits(I, '', Fleet[1].Units[I], 1, 0 );
- end;
- end;
- end;
- with Defender.FleetList do
- begin
- if (Fleet[1].FleetQty > 0) then
- if (Fleet[1].TimeToTarget(Defender.ActorID, Target.ActorID, TravelResearch, fDEFEND) = Hostile.FleetList.Fleet[1].CalcETA) then
- begin
- Fleet[1].SendFleet (Defender.ActorID, Target.ActorID, TravelResearch, fDEFEND, 1);
- Stage.Actors[Defender.ActorID]:= Defender;
- end;
- end;
- end;
- end;
- end;
- end;
- end;
- procedure TBotBrain.ThinkInvaders();
- var I : integer;
- begin
- with Game.Incoming.Items[ AIBot.ActorID ] do
- begin
- if not (iEnemies) then exit;
- if (iCount <= 0) then exit;
- for I := 0 to iCount - 1 do //Go through all incoming and calls for defence for each individual incoming
- begin
- with Game.GetFleet( iIncoming[I].iActorID, iIncoming[I].iFleetID) do
- begin
- if (ActionTask = fATTACK) then //Incoming Fleet is attacking so find defence
- ThinkDefenceCall(Game.Stage.Actors[ iIncoming[I].iActorID ], Game.Stage.Actors[BotID], 502);
- end;
- end;
- end;
- end;
- {=========================================================================}
- { MILITARY - Attack }
- {=========================================================================}
- function TBotBrain.ThinkViableTarget(var Sender, Receiver:TActor):boolean;
- var
- pScoreChance,
- Rand : real;
- // sAlly, rAlly : TAllianceItem;
- // sBlock, rBlock : integer;
- begin
- result := FALSE;
- if (not Sender.FleetList.Fleet[1].isHome)and
- (not Sender.FleetList.Fleet[2].isHome)and
- (not Sender.FleetList.Fleet[3].isHome) then exit;
- if (( Sender.AllianceID = Receiver.AllianceID )and
- (Receiver.AllianceID <> 0)) then exit; //Same Alliance and Alliance not ZERO
- if (Sender.Coords.ToXY = Receiver.Coords.ToXY) then exit; //Same Gal
- if (Receiver.Asteroids.Value < Sender.Asteroids.Value/10) then exit; //Receiver has less than 10% of sender roids
- result := TRUE;
- pScoreChance := 0;
- if (pScoreChance < 15) then pScoreChance:= 15;
- if (Sender.ActorScore * 1.75 <= Receiver.ActorScore) then //Avoids Crashing
- pScoreChance:= 5;
- if (Sender.ActorScore * 0.65 >= Receiver.ActorScore) then //Avoids Bashing
- pScoreChance:= 5;
- Rand := (Random(10000)+1)/100;
- if (Rand > pScoreChance) then
- result := FALSE;
- end;
- procedure TBotBrain.ThinkLaunch(var Sender, Receiver:TActor);
- begin
- // Find fTarget to attack
- with Sender.FleetList do
- begin
- doTransferUnits (-999, '', 0, 0, 1);
- doTransferUnits (-999, '', 0, 2, 1);
- doTransferUnits (-999, '', 0, 3, 1);
- Fleet[1].SendFleet(Sender.ActorID, Receiver.ActorID, TravelResearch, fATTACK, 1)
- end;
- end;
- function TBotBrain.ThinkGotPods():boolean;
- var
- U :integer;
- begin
- result:= FALSE;
- U:= -1;
- while (U < Game.MAX_UNITS)and(not result) do
- begin
- Inc(U);
- if (Game.wbUnit( U ).isPod)and
- (AIBot.FleetList.Fleet[Game.MAX_FLEETS].Units[U] > 0) then
- result := TRUE;
- end;
- end;
- procedure TBotBrain.ThinkAttack(AttackTries,AttackChance:integer);
- var
- Counter : integer;
- Rand : integer;
- CanAttack : Boolean;
- begin
- // if not (ThinkGotPods( AIBot )) then exit;
- AttackChance := Ceil(AttackChance * AIBot.GetSkill);
- if (AttackChance <= 0) then AttackChance := 2;
- if (Random(100)+1 > AttackChance*AIBot.GetSkill) then exit; //How aggressive
- if (Game.GetIncoming( AIBot.ActorID ).iEnemies) then exit; //Dont launch if bot is under attack
- if (Game.isPeaceTime) then exit;
- AttackTries := Ceil(AttackTries * AIBot.GetSkill);
- Counter := 0;
- repeat
- Rand := Random(Game.MAX_PLAYERS+1);
- CanAttack := ThinkViableTarget( Game.Stage.Actors[BotID], Game.Stage.Actors[ Rand ] );
- if (CanAttack = TRUE) then
- ThinkLaunch( Game.Stage.Actors[BotID], Game.Stage.Actors[ Rand ] );
- Inc(Counter);
- until (CanAttack = TRUE)or(Counter >= AttackTries);
- end;
- {=========================================================================}
- { MAIN }
- {=========================================================================}
- procedure TBotBrain.Think(nBotID:integer);
- var Rand, nRoids : integer;
- begin
- BotID := nBotID;
- // DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) '+AIBot.Name+' '+IntToStr(Rand));
- DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Research');
- ThinkResearch();
- DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Structure');
- ThinkStructures();
- // DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Invaders');
- // ThinkInvaders();
- DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Attack');
- ThinkAttack( 125, 15);
- nRoids := AIBot.Asteroids.Value;
- Rand := Random(100)+1;
- if ((nRoids <= 100+( 40*AIBot.GetSkill)+Random(floor(20*AIBot.GetSkill)))and(Rand <= 99))or
- ((nRoids <= 200+( 75*AIBot.GetSkill)+Random(floor(25*AIBot.GetSkill)))and(Rand <= 90))or
- ((nRoids <= 350+(200*AIBot.GetSkill)+Random(floor(40*AIBot.GetSkill)))and(Rand <= 80)) then // chance of initing if below 220 roids
- begin
- DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Roids');
- ThinkRoids();
- end
- else
- DevConsole.Msg(ES_DEBUG,'(TBotBrain.Think) Production');
- ThinkProduction();
- end;
- {=========================================================================}
- procedure TBotBrain.CycleBots;
- var P : integer;
- begin
- // DevConsole.Msg(MSG_DEBUG, frmDebug.rchConsole,'TICKER >> TBotBrain.Ticker!');
- try
- if (Random(100) < 50) then
- for P := 0 to Game.MAX_PLAYERS do
- Think( P )
- else
- for P := Game.MAX_PLAYERS downto 0 do
- Think( P );
- except
- DevConsole.SaveLog;
- end;
- end;
- function TBotBrain.AIBot():TActor;
- begin
- result := Game.GetActor(BotID);
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement