This PASCAL/Delphi code is converted into HTML using Pas_Colorizator v1.0 (c) 2001 by Alexander Yanuar Koentjara (lexzeus@hotmail.com)
{ By : Alexander Yanuar Koentjara (lexzeus@hotmail.com) SYSTEM DEVELOPER of www.globalsources.com File : WAR.PAS Title : The Wild Families Genre : Strategy Game Language : Borland Delphi 4.0, DGC's DirectX Discription : Basic units functionality : - Attack - Charge (like Patrol in StarCraft) - Move/Follow - Guard (ready to help or attack) - Retreat - Stop (no movement) Basic building functionality : - Attack (turret only) - Special (Nuclear silo only) - Automatic Heal (to heal organic troop, can up to fix 4 units at the same time, other must queue) - Automatic Fix (to repair robotic unit and aircraft, can fix up to 4 units at the same time, other must queue) - Repair (to repair building) - Build (for Base, Barrack, Factory, Airport, and Mineral Silo only) Player Logic : - Real guard, if friend unit is seen being attacked in sight range, the unit will be allocated to help automatically. - The rest must be controlled by player. Enemy Logic : - Auto retreat, and seek hospital/repair facility if needed. But keeping attack if the chance of winning is obvious. - Attacking in group not one by one, grouping in certain area, and attack at once. - All unit autohelp other unit if idle, but keep watching on base buildings. - Reproducing army forces (ground and air units) when necessary Path-finding Algorithm (for ground units only) : - 8 Filling Square : An algorithm that guarantee will find the path to the target (if it really exist), or try to find the nearest spot as possible if the path doesn't exist. - While unit walking, it recheck automatically periodically to seek if there's probablility of another alternative/nearest path if the current path is blocked or modified. Sorry if my many of my comments are written in Indonesian ... ************************************************************************************************* Kondisi kalah (defend) : 1. Com Center hancur 2. Musuh hancur selain wall 3. Duit musuh habis, tidak ada pasukan & turret 4. barrack & factory hancur, tak ada pasukan & turret Kondisi kalah (attack) : 1. Com Center hancur 2. Duit musuh habis 3. barrack & factory hancur Penyerang | Diserang Player | Computer -------------|------------ Equal - | - Player Win - | Kalo memungkinkan retreat, ya retreat -> EnemyRetreat() Com Win - | - Penyerang | Diserang Computer | Player -------------|------------ Equal Retreat | - Player Win Retreat | - Com Win - | - Pow Armor Speed Reload MaxBlood Missle Silo Research for HellFire -> fire, good damage, good armor, low speed 30 10 12 20 85 Meson Beam Hell Fire, Meson Beam Anaconda -> Spread poisonous gas, lowering curblood for moments 10 10 30 60 Poisonous Gas AnaConda, Radioactive gas TechBoot -> high speed, double-quad missile both air and ground target 20-30 10 8 20 80 - Air Ground Missle, Quad Missle } Unit war; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DGCILib, DGC, ExtCtrls, ComCtrls, DDraw, dgcslib, DGCSnd, MPlayer, StdCtrls, Buttons; Const MM_Title_MainBattleMenu =1; MM_Title_ExitProgram=2; MM_ExitProgram=3; MM_Title_CancelAttack=4; MM_CancelAttack=5; MM_Title_Retreat=6; MM_Retreat=7; MM_AreYouSure=21; MM_Yes=22; MM_No=23; MM_Ok=24; MM_Others=11; CUp = 0; CRUp = 1; CRight = 2; CRDown = 3; CDown = 4; CLDown = 5; CLeft = 6; CLUp = 7; DeadID = 30; ScrX = 16; ScrY = 11; MaxEnemyWait=90; MaxImgSBullet = 60; MaxSBullet = 250; MaxSPEffect = 1000; MaxTaskBuild = 50; MapMinX = 1; MapMinY = 1; MapMaxX = 120; MapMaxY = 120; MaxSquare = 1000; MaxSEffect= 50; MaxSoils = 39; MaxTask = 30; MaxCamera = 5; MaxMosGroup = 5; MaxCreature = 1000; MaxMosCount = 30; MaxImgTroop = 300; MaxImgBld = 20; MaxSight = 7; SoilFlag = 9999; TileSize = 40; TimeBuilding = 6600; MaxDelayDelivery =700; type TUpgrade = Record Power : Byte; Armor : Byte; Speed : Byte; Money : Byte; Blood : Byte; End; THint = Record Msg : String[20]; Color : Integer; Exist : Boolean; Ctr : Byte; End; PObjCreature = ^ObjCreature; // Pointer of OBJCreature TCmdBuild = Record Active : Byte; Isi,Speed,price: Array [1..9] of Byte; Oke : Array [1..9] of Boolean; End; RecPal = Record Dir : ShortInt; Value : Byte; End; MapPosition = Record MapX,MapY, PrevX,PrevY, HomeX,HomeY, Height,Width : Byte; CameraX, CameraY : Array [1..MaxCamera] of Byte; ComCenter : PObjCreature; RepairHouse : Array [1..2,1..4] of PObjCreature; End; RecTiles = Record Ok : Boolean; Ptr : PObjCreature; AirUnit, Soil,Fog : Byte; End; TBtnMenu = record PosX,PosY,PosX2,PosY2 : SmallInt; Title : String[30]; Visible : Boolean; Enable : Boolean; End; TGrandMenu = Record MenuVisible : Boolean; BtMenu : Array [1..30] of TBtnMenu; Focus : SmallInt; End; TTarget = Record Ptr : PObjCreature; X,Y, PrevX,PrevY : SmallInt; End; TMissle = Record Power, Ammo, Speed : Byte; Counter : SmallInt; End; TBoolInfinite = Record PoisonCtr : Byte; PoisonPower : Byte; SelfHealing, Range, UnTouchable, Armor, Power : Boolean; End; TCirc = Record Exist : Boolean; CircType : Byte; Ptr : PObjCreature; MapX,MapY : Byte; TileX,TileY : ShortInt; Width : Byte; Height : Byte; Count : Byte; End; SpecialBull = record Idx : SmallInt; Exist : Boolean; Target : TTarget; From : PObjCreature; Ammo, Omni, // enable single, double, triple , quad, missle Power, Speed, Height,Width : Byte; Effect : TBoolInfinite; // cause something happened ? ExplodeRange : Byte; // exploded range, for nuclear launcher ? WithDirection : Boolean; // bullet with direction heading DynamicForm, // enable dynamic form if set above 0 LoopForm, // enable circular looping form if set above 0 ContinousForm, // enable sequenced form if set above 0 Resting : Byte; // effect after bullet hit creature TileX,TileY : Array [1..4] of SmallInt; Task,Task2 : Array [1..4] of Byte; // task -> for current idx // task2-> counter that make task increase End; PSBullet = ^SpecialBull; Bullet = Record Target : TTarget; MapX, MapY : Byte; Power : Byte; // kekuatan Range : Byte; Area : Byte; ReFill : SmallInt; Loops : SmallInt; // berapa langkah Ellapsed : SmallInt; Speed : Byte; // faktor Speed Exist : Boolean; GroundToAir : Byte; Ammo : Byte; // 1 - Gun 2 - Shell 3 - Machine Gun 4..9 undefined // >10 - special End; TEffect = Record TxEffect , TyEffect : ShortInt; // posisi relatif x dan y IDEffect , // Index gambar CurEffect , // Gambar skarang CtrEffect, // Delay Counter SpdEffect, // Kecepatan frame CtrLoop, // Berapa kali looping MaxEffect : Byte; // Index max gambar Exist : Boolean; // visual effect : meledak, etc End; ObjCreature = Record Id : SmallInt;// less than DeadID means dying, Above DeadID : Creature // Above 9900 : Id for Air Unit SpecialID : Byte; // Identifier points index corresponds to BigGameZ Name : String[20]; Active : Boolean; // disorot atau tidak BelongTo : Byte; // milik side siapa TypeCreature : Byte; // 1 - Soldiers // 2 - Tank // 3 - Tank without head // 4 - Great Tank // 5,6 - Ground Unit, undefined yet, for expansion // 7 - Air Unit // 8 - Air Unit, undefined yet // 9 - Air Unit, undefined yet // 10 - Building 1x1 // 15 - Building 1,5x1,5 // 20 - Building 2x2 ClassCreature: Byte; // 1 - On foot living creatures, soldiers // 2 - All kind of Tanks // 3 - AirPlanes // 4..9 - Undefined yet, for expansion // 20 - Building with no Ability // 30 - Building with Power Supply Ability // 40 - Building with Turret Ability // 50 - Building with Repair Ability // 60 - Building with Missile Launcher Ability // 70 - Building with Build Troop Ability // 80 - Building with Command Center Ability // 90... - Building with undefined Ability, for expansion TileX,TileY, // tile pergerakan TileX2,TileY2, // tile asli HTileX,HTileY : ShortInt; // tile head, utk headded tank & turret MapX, MapY : Byte; // posisi pada peta MaxBlood : Byte; CurBlood : Byte; Moving : Boolean; // apakah creature benda bergerak StopAirEngine : Boolean; // Khusus untuk air unit, guard atau tidak NowRepaired : Boolean; // apakah sedang di reparasi Height : SmallInt; // tinggi creature, untuk air unit dianggap sbg pos y relatif Width : SmallInt; // tinggi creature, untuk air unit dianggap sbg pos x relatif Sight : Byte; // jangkauan pandangan Speed : Byte; // kecepatan gerakan -> speed besar ground unit lambat tapi air unit cepat Armor : Byte; Bull : Bullet; BodyHeading : SmallInt; // Body Direction HeadHeading : SmallInt; // Head Direction, biasanya untuk tank ActTask1 : Byte; ActTask2 : Byte; ActTask3, MovTask1, MovTask2 : SmallInt; MovingTask : Array [0..MaxTask] of Byte; // task gerakan MainTask : Byte; // task utama, untuk enemy unit GeneralTask : Byte; // task sekarang Target : TTarget; // Target OtherTarget : Array [1..4] of PObjCreature; // Other target, exp : for repair house and hospital TargetChange: Boolean; // apakah ada interupsi saat melaksanakan general task MakeItGuard : Boolean; // dipaksa untuk guard Idx : SmallInt; // show idx images IdxT : SmallInt; // show idx images, special image index for "building" that has body // and head separated, exp : turret UseAs : Byte ; // untuk comm panel, 1 - enable 0 - Disable 1-1-1-1-1-1 Prior : Byte; // shoot priority Force : Boolean; // Force to do something ? Infinite : TBoolInfinite; // Untuk Infinite, Cheat, special condition Effect : TEffect; // visual effect that carried by creature, exp : smoke, flickers, fireburn, etc ... End; SPEffect = Record TileX,TileY : SmallInt; Exist : Boolean; Effect : TEffect; End; PtrSPEffect = ^SPEffect; TPath = Array[MapMinX..MapMaxX,MapMinY..MapMaxY] of SmallInt; TMouse = Record UseAs : Byte; MouseX,MouseY,StartX,StartY,EndX,EndY, DelayMouse,DirMovingX,DirMovingY,PrevX,PrevY : SmallInt; ArrMos : Array [1..MaxMosCount] of PObjCreature; ArrMosCount : SmallInt; BelongTo : Byte; End; TCreateTroop = Record BelongTo : Byte; MakeWhat : SmallInt; WhoIsMaking : PObjCreature; Price : byte; Count : byte; // for build End; TForm1 = class(TForm) Scr1: TDGCScreen; LogicTime: TTimer; DGCAudio1: TDGCAudio; DGCSoundLib1: TDGCSoundLib; FlipTimer: TTimer; BuildTimer: TTimer; // Path finding algorithm Function CariPath(Var Who:PObjcreature;Rn:SmallInt;PathTile:TPath;MaxIterasi:SmallInt):Boolean; // sub Artificial ... procedure EnemyLogic; procedure AirUnit_MakeRivalShoot(Ptr:Pobjcreature); procedure AirUnit_SubLogic(Var Ptr:Pobjcreature); Procedure Building_SubLogic(Var Ptr:PObjCreature); Procedure AirAndGround_SubLogic(Var Ptr:PObjCreature); procedure Timer_MainLogic(Sender: TObject); // sub Making Creatures ....... function NewCreature : SmallInt; function NewSBullet:SmallInt; function NewSPEffect:SmallInt; procedure NewSpecialEffect(Idx:Byte;x,y:SmallInt); procedure NewSpecialBullet(Ptr:PObjCreature;x,y:SmallInt); procedure NewTroop(Side:Byte;MapX,MapY,Blood:SmallInt;idx:SmallInt); procedure NewAirUnit(Side:Byte;PosX,PosY,Blood,Idx:SmallInt); procedure NewDelivery(Side:Byte); Procedure BuildTroops(Who:Byte;WhatToBuild:Integer;Which:PObjCreature;Count:Byte;Duit:byte); // sub disposing creature .... procedure RemoveCreature(Var Ptr:PObjCreature); Procedure BeingHit(Var TG:TTarget;Var PtrShooter:PObjCreature;Power:Byte); // sub drawing .... procedure ToBigMap(Who:PObjCreature;Exist:Boolean); procedure DrawComPanel; procedure DrawBullets; procedure DrawSBull; procedure DrawSPEffect; Procedure DrawPlane(Ptr:PobjCreature); Procedure DrawFog; procedure DrawAllToScreen; procedure DrawCirc; procedure BoxLine; procedure ShowMenu; procedure Scr1Flip(Sender: TObject); procedure ExploreMap(x,y,area:Byte); // sub Hardware Control ... procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure InsCreatureToMouse(Var Moz:TMouse;Ptr:PObjCreature); procedure ModiTaskToMouse(Var Moz:TMouse;Task:SmallInt; Tar:TTarget); procedure EmptyMos; Procedure Cekmouse; procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); // sub Exteded function ... function Expon(a,b:SmallInt):SmallInt; function Inside(x,lbound,ubound:real):boolean; function ReturnComPanel(x:SmallInt):SmallInt; procedure MakeSound(What,x,y:Byte); procedure Debuger(a:string;x,y:SmallInt); procedure Scr1Initialize(Sender: TObject); procedure SwapValue(Var x,y:SmallInt); procedure NewPosition(Ptr:PobjCreature;Var x1,y1:smallint); procedure NewAirUnitPosition(Ptr:PobjCreature;Var x1,y1:smallint); Procedure WhoIsThere(Var Temp:PObjCreature;xx,yy:SmallInt); Function Distance(x1,y1,x2,y2:SmallInt):Real; Function RangeOK2Creature(T1:PObjCreature;T2:PObjCreature;R:Byte):Boolean; Function RangeOK(T:PObjCreature;R:SmallInt):Boolean; Procedure ValidTarget(Var TG:TTarget); procedure ValidateSPEffect(Var Eff:TEffect); Procedure CheckNear(Var Ptr:PObjCreature); Procedure CloseApplication; // sub Direction ... Function TrueHeading(x,y:SmallInt):Byte; function Heading(Who:PObjCreature):Byte; function SBullHeading(SBWidth,SBHeight:Byte;xx,yy:SmallInt;tg:TTarget):Byte; function ShortHeading(Who:PObjCreature;Hd:Byte):SmallInt; // sub Timer ... procedure OnTimeFlip(Sender: TObject); procedure BuildTimerTimer(Sender: TObject); private { Private declarations } WhoAmI, WhoEnemy, AllySide, EnemySide : Byte; Geser,ResultX,ResultY : Byte; TempImage : TImage; TempSurf,HBar,Vbar,MainMenu,MissileImg,Shadow, RoundShadow,FixShadow,DarkShadow,BackLayer, Text1,Text2,text3 : TDGCSurface; Missle : Array [1..3] of TMissle; Upgrade : Array [1..3] of TUpgrade; SiloX : Array [1..3] of smallInt; SiloY : Array [1..3] of smallInt; SourMoney : Array [1..3] of Integer; Money : Array [1..3] of Integer; DelAppear : Array [1..3] of Integer; SEffect : Array [0..MaxSEffect] of TDGCSurface; Soils : Array [1..MaxSoils] of TDGCSurface; MPointer : Array [1..4,1..6] of TDGCSurface; Commands : Array [1..3] of TDGCSurface; ImgTroop : Array [1..3,0..MaxImgTroop] of TDGCSurface; ImgBld : Array [1..3,0..MaxImgBld] of TDGCSurface; ImgSBullet : Array [1..MaxImgSBullet] of TDGCSurface; TabelBld : Array [1..3,1..100] of SmallInt; AllUnits : Array [1..3,1..50] of ObjCreature; AllSBulet : Array [1..20] of SpecialBull; CmdBuildImg : Array [1..3] of TDGCSurface; CmdBuild : Array [1..3,1..3] of TCmdBuild; TaskBuild : Array [1..MaxTaskBuild] of TCreateTroop; IdxTurrStart : Array [1..3] of Integer; AllyScreen : MapPosition; EnemyScreen : MapPosition; AllPtrSPEffect: Array [1..MaxSPEffect] of PtrSPEffect; AllPtrSBullet : Array [1..MaxSBullet] of PSBullet; AllCreature : Array [1..MaxCreature] of PObjCreature; PartTiles : Array [MapMinX-1..MapMaxX+1,MapMinY-1..MapMaxY+1] of RecTiles; Tiles : Array [MapMinX-1..MapMaxX+1,MapMinY-1..MapMaxY+1] of PObjCreature; CurCreature : SmallInt; Palet : Array [1..5] of RecPal; R1Bound,R2Bound,D1Bound,D2Bound : Integer; PathTile : TPath; public { Public declarations } end; TMap = Record Map, ShadowMap : TDGCSurface; Left, Top, Width, Height : Integer; End; var Form1 : TForm1; Idx,Idxp,Cidx,IdxCom : SmallInt; Mos : TMouse; Hints : THint; MosGroup : Array [1..MaxMosGroup+1] of TMouse; PunchLong : Boolean; Circ : TCirc; BigMap : TMap; TimeExpired,ZZZ : SmallInt; EnemyTurn : Byte; // kalo sudah = 7 maka do enemy logic EnemyWait : Integer; // tunggu untuk berkumpul sebelum menyerang OtherTime : Byte; // waktu untuk repair PtrTargetUnit : PObjCreature; PtrTarget : PObjCreature; PtrAttacker : PObjCreature; PtrZZZ : PObjCreature; CreaCount : Array [1..3] of smallint; Debugers : Boolean; EFactory,EBarrack,EAirPort,EComCenter,AComCenter, WeAreTheInvader, EnemyRetreat, PlayerRetreat, PlayerQuit, EnemyLoose, PlayerLoose, RepairOn, ForceToFlip : Boolean; MM : TGrandMenu; implementation {$R *.DFM} function tform1.inside(x,lbound,ubound:real):boolean; var t :boolean; begin t:=false; if (x>=lbound) and (x<=ubound) then t:=true; inside:=t; end; function TForm1.NewCreature:SmallInt; var i : SmallInt; Oke : Boolean; Temp : PObjCreature; Begin Oke:=False; i:=0; Repeat inc(i); If (AllCreature[i]<>nil) and (AllCreature[i]^.Id=0) then Oke:=True; If AllCreature[i]=nil then Begin New(Temp); Fillchar(Temp^,Sizeof(Temp^),0); AllCreature[i]:=Temp; Oke:=True; Inc(CurCreature); End; Until (i=MaxCreature) or (Oke); If Oke then NewCreature:=i else NewCreature:=MaxCreature; End; function TForm1.NewSBullet:SmallInt; var i : SmallInt; Oke : Boolean; Temp : PSBullet; Begin Oke:=False; i:=0; Repeat inc(i); If (AllPtrSBullet[i]<>nil) and (not AllPtrSBullet[i]^.Exist) then Oke:=True; If AllPtrSBullet[i]=nil then Begin New(Temp); Fillchar(Temp^,Sizeof(Temp^),0); AllPtrSBullet[i]:=Temp; Oke:=True; End; Until (i=MaxSBullet) or (Oke); If Oke then NewSBullet:=i else NewSBullet:=MaxSBullet; End; Function TForm1.NewSPEffect:SmallInt; var i : SmallInt; Oke : Boolean; Temp : PtrSPEffect; Begin Oke:=False; i:=0; Repeat inc(i); If (AllPtrSPEffect[i]<>nil) and (not AllPtrSPEffect[i]^.Exist) then Oke:=True; If AllPtrSPEffect[i]=nil then Begin New(Temp); Fillchar(Temp^,Sizeof(Temp^),0); AllPtrSPEffect[i]:=Temp; Oke:=True; End; Until (i=MaxSPEffect) or (Oke); If Oke then NewSPEffect:=i else NewSPEffect:=MaxSPEffect; End; procedure Tform1.NewSpecialEffect(Idx:Byte;x,y:SmallInt); var n:SmallInt; Begin n:=NewSPEffect; AllPtrSPEffect[n]^.Exist:=True; AllPtrSPEffect[n]^.TileX:=x; AllPtrSPEffect[n]^.TileY:=Y; With AllPtrSPEffect[n]^.Effect do Begin Exist:=True; SpdEffect:=1+Random(3); MakeSound(4,x div 40, y div 40); Case Idx of 1 : Begin // Ledakan kecil krn misil IDEffect:=21; CurEffect:=21; MaxEffect:=1; CtrLoop:=1; TxEffect:=-25; TyEffect:=-22; End; 2 : Begin // Ledakan kecil krn misil besar IDEffect:=15; CurEffect:=15; CtrLoop:=1; MaxEffect:=1; TxEffect:=-45; TyEffect:=-35; End; 3 : Begin // Ledakan biasa IDEffect:=17; CurEffect:=17; CtrLoop:=1; MaxEffect:=5; TxEffect:=-25; TyEffect:=-22; End; 4 : Begin // Ledakan besar IDEffect:=11; CurEffect:=11; CtrLoop:=1; MaxEffect:=5; TxEffect:=-45; TyEffect:=-35; End; 5 : Begin // Asap IDEffect:=3; CurEffect:=3; CtrLoop:=1+Random(20); MaxEffect:=2; TxEffect:=-17; TyEffect:=-40; End; 6 : Begin // Poisonous Gas IDEffect:=23; CurEffect:=23; CtrLoop:=1; MaxEffect:=2; TxEffect:=-30; TyEffect:=-28; End; End; End; End; Procedure TForm1.NewSpecialBullet(Ptr:PObjCreature;x,y:SmallInt); var n,i:SmallInt; Begin n:=NewSBullet; move(AllSBulet[Ptr^.Bull.Ammo mod 20],AllPtrSBullet[n]^,sizeof(AllSBulet[1])); AllPtrSBullet[n]^.ExplodeRange:=Ptr^.Bull.Ammo div 20; AllPtrSBullet[n]^.Exist:=True; AllPtrSBullet[n]^.Target:=Ptr^.Target; AllPtrSBullet[n]^.From:=Ptr; AllPtrSBullet[n]^.Ammo:=Ptr^.Bull.Ammo-10; AllPtrSBullet[n]^.Power:=Ptr^.Bull.Power; AllPtrSBullet[n]^.Speed:=Ptr^.Bull.Speed; For i:=1 to AllPtrSBullet[n]^.Omni do Begin AllPtrSBullet[n]^.TileX[i]:=X - AllPtrSBullet[n]^.Width div 2; AllPtrSBullet[n]^.TileY[i]:=Y - AllPtrSBullet[n]^.Height div 2; If AllPtrSBullet[n]^.TileY[i]<>0 then AllCreature[n]^.CurBlood:=Blood else AllCreature[n]^.CurBlood:=AllCreature[n]^.MaxBlood; Tiles[AllCreature[n]^.MapX,AllCreature[n]^.MapY]:=AllCreature[n]; ToBigMap(AllCreature[n],True); BigMap.Map.Canvas.Release; End; procedure TForm1.NewDelivery(Side:Byte); var n,x,y:SmallInt; L1,L2:real; Begin DelAppear[Side]:=0; n:=NewCreature; AllCreature[n]^.Infinite.UnTouchable:=True; AllCreature[n]^.TypeCreature:=7; AllCreature[n]^.ClassCreature:=3; AllCreature[n]^.BelongTo:=Side; AllCreature[n]^.GeneralTask:=0; AllCreature[n]^.Idx:=1; AllCreature[n]^.Id:=9999; // id for delivery AllCreature[n]^.Armor:=255; AllCreature[n]^.CurBlood:=20; AllCreature[n]^.MaxBlood:=20; AllCreature[n]^.Moving:=True; AllCreature[n]^.ActTask1:=0; AllCreature[n]^.ActTask2:=0; AllCreature[n]^.ActTask3:=MaxDelayDelivery-25; AllCreature[n]^.Speed:=3; AllCreature[n]^.Active:=False; AllCreature[n]^.TileX:=-10; AllCreature[n]^.TileY:=-13; AllCreature[n]^.UseAs:=0; AllCreature[n]^.Prior:=0; y:=-1; L1:=3500; Repeat Inc(y); L2:=Distance(SiloX[Side],SiloY[Side],TileSize,y*TileSize); If (L21200 then Repeat Inc(x); L2:=Distance(SiloX[Side],SiloY[Side],x*TileSize,TileSize); If (L2<>0 then AllCreature[n]^.CurBlood:=Blood else AllCreature[n]^.CurBlood:=AllCreature[n]^.MaxBlood; if Ptrzzz=nil then Ptrzzz:=AllCreature[n]; End; procedure TForm1.Scr1Initialize(Sender: TObject); Procedure InitPicture; var i,j,k,l,x,y,w,z,x1,y1,x2,y2,a,b,c,whonow,u : SmallInt; s1,s2,s3,stemp : string; _who, idxRep : array [1..2] of byte; Fz : File of char; ch : char; Seen : MapPosition; f,f2 : textfile; Ptr : Array [1..3] of PObjCreature; PtrDummy : PObjCreature; Begin MM.MenuVisible:=False; EnemyRetreat := False; PlayerRetreat:= False; PlayerQuit:= False; EnemyLoose:=False; PlayerLoose:=False; TimeExpired:=0; PtrZZZ:=Nil; zzz:=0; Debugers:=False; EnemyTurn:=5; EnemyWait:=0; OtherTime:=0; PtrTargetUnit:=Nil; PtrTarget:=Nil; PtrDummy:=Nil; For j:=1 to MaxMosGroup do For i:=1 to 10 do MosGroup[j].ArrMos[i]:=Nil; // initializing Main Menu, pres ESC to activate this menu during application is running For i:=1 to 30 do Begin MM.BtMenu[i].Visible:=False; MM.BtMenu[i].Enable:=True; End; MM.BtMenu[1].Title:= '[Main Battle Menu]'; MM.BtMenu[1].PosX:=230; MM.BtMenu[1].PosY:=145; MM.BtMenu[2].Title:=' [Exit Program] '; MM.BtMenu[2].PosX:=250; MM.BtMenu[2].PosY:=145; MM.BtMenu[3].Title:='Exit Program'; MM.BtMenu[3].PosX:=250; MM.BtMenu[3].PosY:=175; MM.BtMenu[4].Title:=' [Cancel Attack] '; MM.BtMenu[4].PosX:=245; MM.BtMenu[4].PosY:=145; MM.BtMenu[5].Title:='Cancel Attack'; MM.BtMenu[5].PosX:=250; MM.BtMenu[5].PosY:=195; MM.BtMenu[6].Title:=' [Retreat] '; MM.BtMenu[6].PosX:=265; MM.BtMenu[6].PosY:=145; MM.BtMenu[7].Title:='Retreat'; MM.BtMenu[7].PosX:=250; MM.BtMenu[7].PosY:=195; MM.BtMenu[21].Title:=' Are you sure ? '; MM.BtMenu[21].PosX:=250; MM.BtMenu[21].PosY:=205; MM.BtMenu[22].Title:='Yes'; MM.BtMenu[22].PosX:=235; MM.BtMenu[22].PosY:=265; MM.BtMenu[23].Title:='No!'; MM.BtMenu[23].PosX:=365; MM.BtMenu[23].PosY:=265; MM.BtMenu[24].Title:='Ok'; MM.BtMenu[24].PosX:=365; MM.BtMenu[24].PosY:=265; For i:=1 to 30 do Begin MM.BtMenu[i].PosX2:=MM.BtMenu[i].PosX+Length(MM.BtMenu[i].Title)*9; MM.BtMenu[i].PosY2:=MM.BtMenu[i].PosY+13; End; for i:=1 to 3 do Begin Silox[i]:=0; CreaCount[i]:=0; FillChar(Upgrade[i],SizeOf(Upgrade[i]),0); End; for i:=1 to MaxTaskBuild do TaskBuild[i].BelongTo:=0; TempImage := TImage.Create(Self); Scr1.CreateSurface(TempSurf,800,480); Scr1.CreateSurface(BigMap.Map,MapMaxX,MapMaxY); // bigmap - the radar map BigMap.Map.Canvas.Brush.Color:=ClBlack; BigMap.Map.Canvas.FillRect(Rect(0,0,MapMaxX,MapMaxY)); BigMap.Map.Canvas.Release; Scr1.CreateSurface(BigMap.ShadowMap,MapMaxX,MapMaxY); // bigmap shadow - unexplored area BigMap.ShadowMap.Canvas.Brush.Color:=$101010; BigMap.ShadowMap.Canvas.FillRect(Rect(0,0,MapMaxX,MapMaxY)); BigMap.ShadowMap.Canvas.Release; //******** Image for command panel ************ Scr1.CreateSurface(Text1,170,18); Text1.Canvas.Brush.Color:=0; Text1.Canvas.Font.Color:=ClWhite; Text1.Canvas.Font.Name:='Verdana'; Text1.Canvas.Font.Size:=10; Text1.Canvas.Release; Scr1.CreateSurface(Text2,230,18); Text2.Canvas.Brush.Color:=0; Text2.Canvas.Font.Color:=ClWhite; Text2.Canvas.Font.Name:='Verdana'; Text2.Canvas.Font.Size:=10; Text2.Canvas.Release; Scr1.CreateSurface(Text3,200,18); Text3.Canvas.Brush.Color:=0; Text3.Canvas.Font.Color:=$cc0000; Text3.Canvas.Font.Name:='Verdana'; Text3.Canvas.Font.Size:=10; Text3.Canvas.Release; Scr1.CreateSurface(BackLayer,ScrX*TileSize+3,ScrY*TileSize+3); BackLayer.Canvas.Brush.Color:=0; BackLayer.Canvas.FillRect(Rect(0,0,ScrX*TileSize,ScrY*TileSize)); BackLayer.Canvas.Release; Scr1.CreateSurface(Shadow,TileSize,TileSize); Shadow.Canvas.Brush.Color:=0; Shadow.Canvas.FillRect(Rect(0,0,TileSize,TileSize)); For j:=0 to TileSize do For i:=0 to TileSize do If (j+i) mod 2 = 0 then Shadow.Canvas.Pixels[i,j]:=$101010; Shadow.Canvas.Release; TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\HVBar.bmp'); Scr1.CreateSurface(MainMenu,320,250); MainMenu.Canvas.Draw(0,0,TempImage.Picture.Graphic); MainMenu.Canvas.Release; TempImage.Canvas.Brush.Color:=0; TempImage.Canvas.FillRect(Rect(0,0,800,200)); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\HorBar.bmp'); Scr1.CreateSurface(HBar,800,200); HBar.Canvas.Brush.Color:=0; HBar.Canvas.FillRect(Rect(0,0,800,200)); HBar.Canvas.Draw(0,0,TempImage.Picture.Graphic); HBar.Canvas.Release; TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\VerBar.bmp'); Scr1.CreateSurface(VBar,160,460); VBar.Canvas.Brush.Color:=0; VBar.Canvas.FillRect(Rect(0,0,160,460)); VBar.Canvas.Draw(0,0,TempImage.Picture.Graphic); VBar.Canvas.Release; TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\com.bmp'); // true command panel image TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Scr1.CreateSurface(Commands[1],500,20); Commands[1].Surface.BltFast(0,0,TempSurf.Surface,rect(4,5,499,23),0); Scr1.CreateSurface(Commands[2],85,26); Commands[2].Surface.BltFast(0,0,TempSurf.Surface,rect(25,73,102,93),0); Scr1.CreateSurface(Commands[3],90,30); Commands[3].Surface.BltFast(0,0,TempSurf.Surface,rect(23,37,104,59),0); // **** Pointer Mouse Image **** TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\mpointer.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; for y:=1 to 6 do Begin Scr1.CreateSurface(MPointer[1,y],30,30); MPointer[1,y].Surface.BltFast(0,0,TempSurf.Surface,rect(27+(y-1)*60+1,10,57+(y-1)*60+1,40),0); Scr1.CreateSurface(MPointer[2,y],30,30); MPointer[2,y].Surface.BltFast(0,0,TempSurf.Surface,rect(27+(y-1)*60+1,70,57+(y-1)*60+1,100),0); Scr1.CreateSurface(MPointer[3,y],TileSize,TileSize); MPointer[3,y].Surface.BltFast(0,0,TempSurf.Surface,rect(25+(y-1)*60+1,127,65+(y-1)*60+1,167),0); End; Scr1.CreateSurface(MPointer[4,1],41,41); MPointer[4,1].Surface.BltFast(0,0,TempSurf.Surface,rect(31,189,72,230),0); Scr1.CreateSurface(MPointer[4,2],41,41); MPointer[4,2].Surface.BltFast(0,0,TempSurf.Surface,rect(92,192,133,233),0); Scr1.CreateSurface(MPointer[4,3],41,41); MPointer[4,3].Surface.BltFast(0,0,TempSurf.Surface,rect(31,189,72,230),0); Scr1.CreateSurface(MPointer[4,4],41,41); MPointer[4,4].Surface.BltFast(0,0,TempSurf.Surface,rect(227,188,268,229),0); Scr1.CreateSurface(MPointer[4,5],41,41); MPointer[4,5].Surface.BltFast(0,0,TempSurf.Surface,rect(292,189,333,230),0); Scr1.CreateSurface(MPointer[4,6],41,41); MPointer[4,6].Surface.BltFast(0,0,TempSurf.Surface,rect(227,188,268,229),0); // ******** soil texture images ************* TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\FixShadow.bmp'); Scr1.CreateSurface(FixShadow,40,40); FixShadow.Canvas.Draw(0,0,TempImage.Picture.Graphic); FixShadow.Canvas.Release; TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\RoundShadow.bmp'); Scr1.CreateSurface(RoundShadow,60,60); RoundShadow.Canvas.Draw(0,0,TempImage.Picture.Graphic); RoundShadow.Canvas.Release; Scr1.CreateSurface(DarkShadow,40,40); DarkShadow.Canvas.Brush.Color:=ClBlack; DarkShadow.Canvas.FillRect(Rect(0,0,40,40)); DarkShadow.Canvas.Release; for x:=1 to MaxSoils do if x in [1..13,17..39] then // load soil image Begin TempImage.Picture.LoadFromFile(Application.Getnamepath+'textures\s'+IntToStr(x)+'.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; case x of 8,37:Begin Scr1.CreateSurface(Soils[x],TileSize,77); Soils[x].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,TileSize,77),0); End; 9: Begin Scr1.CreateSurface(Soils[x],TileSize,23); Soils[x].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,TileSize,23),0); End; 10: Begin Scr1.CreateSurface(Soils[x],23,TileSize); Soils[x].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,23,TileSize),0); End; 11: Begin Scr1.CreateSurface(Soils[x],21,20); Soils[x].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,21,20),0); End; else Begin Scr1.CreateSurface(Soils[x],TileSize,TileSize); Soils[x].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,TileSize,TileSize),0); End; end; End; // ********** other image, such as special effect, explosion image TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\Missile.bmp'); // tampilan missle di com panel Scr1.CreateSurface(MissileImg,40,40); MissileImg.Canvas.Draw(0,0,TempImage.Picture.Graphic); MissileImg.Canvas.Release; Assignfile(f,Application.GetNamePath+'Data\Others.Dat'); Reset(f); Assignfile(f2,Application.GetNamePath+'Data\Others.Twf'); Reset(f2); Readln(f2,Stemp); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\others.bmp'); // missle, nuclear strike, etc TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Readln(f,y); z:=0; FillChar(AllsBulet,Sizeof(AllsBulet),0); For x:=1 to y do Begin Readln(f,Stemp); AllSBulet[x].Idx:=z+1; Readln(f,AllSBulet[x].Omni); Readln(f,AllSBulet[x].Effect.PoisonCtr); Readln(f,AllSBulet[x].Effect.PoisonPower); Readln(f,w); If w=1 then AllSBulet[x].Effect.SelfHealing:=True; Readln(f,w); If w=1 then AllSBulet[x].Effect.Range:=True; Readln(f,w); If w=1 then AllSBulet[x].Effect.UnTouchable:=True; Readln(f,w); If w=1 then AllSBulet[x].Effect.Armor:=True; Readln(f,w); If w=1 then AllSBulet[x].Effect.Power:=True; Readln(f,AllSBulet[x].ExplodeRange); Readln(f,w); If w=1 then AllSBulet[x].WithDirection:=True; Readln(f,AllSBulet[x].DynamicForm); Readln(f,AllSBulet[x].LoopForm); Readln(f,AllSBulet[x].ContinousForm); Readln(f,AllSBulet[x].Resting); x1:=0; y1:=0; x2:=0; y2:=0; If AllSBulet[x].WithDirection then Begin If AllSBulet[x].ContinousForm>0 then w:=AllSBulet[x].ContinousForm; If AllSBulet[x].LoopForm>0 then w:=AllSBulet[x].LoopForm; For i:=1 to 8 do for j:=1 to w do Begin Inc(z); Readln(f2,Stemp); Readln(f2,x1); Readln(f2,y1); Readln(f2,x2); Readln(f2,y2); Scr1.CreateSurface(ImgSBullet[z],x2-x1+1,y2-y1+1); ImgSBullet[z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End End Else Begin j:=0; If AllSBulet[x].DynamicForm>0 then j:=AllSBulet[x].DynamicForm; If AllSBulet[x].ContinousForm>0 then j:=AllSBulet[x].ContinousForm; If AllSBulet[x].LoopForm>0 then j:=AllSBulet[x].LoopForm; For i:=1 to j do Begin Inc(z); Readln(f2,Stemp); Readln(f2,x1); Readln(f2,y1); Readln(f2,x2); Readln(f2,y2); Scr1.CreateSurface(ImgSBullet[z],x2-x1+1,y2-y1+1); ImgSBullet[z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End End; AllSBulet[x].Width:= x2-x1+1; AllSBulet[x].Height:=y2-y1+1; End; CloseFile(f); Assignfile(f,Application.GetNamePath+'Data\Seffect.Dat'); Reset(f); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\seffect.bmp'); // visual effect TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); // like smoke, fire, etc TempSurf.Canvas.Release; Readln(f,c); for z:=0 to c-1 do Begin Readln(f,stemp); Readln(f,x1); Readln(f,y1); Readln(f,x2); Readln(f,y2); Scr1.CreateSurface(SEffect[z],x2-x1+1,y2-y1+1); SEffect[z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End; CloseFile(f); // ******************************************** Start to access War DATA CurCreature:=0; Assignfile(f,Application.GetNamePath+'Data\WarData.Dat'); Reset(f); Readln(f,u); If u=1 then WeAreTheInvader:=True else WeAreTheInvader:=False; Readln(f,_who[1]); Readln(f,_who[2]); WhoAmi:=_Who[1]; AllySide:=WhoAmi; WhoEnemy:=_Who[2]; EnemySide:=WhoEnemy; Readln(f,Stemp); Readln(f,Stemp); Readln(f,Stemp); // ************************** Make Tile ********************************** AssignFile(Fz,Application.GetNamePath+'Data\'+Stemp); Reset(fz); Read(Fz,Ch); Read(Fz,Ch); Randomize; For j:=1 to MapMaxY do For I:=1 to MapMaxX do Begin Read(Fz,Ch); PartTiles[i,j].Soil:=Ord(Ch); If PartTiles[i,j].Soil=1 then case Random(30) of 1,2:PartTiles[i,j].Soil:=32; 0:PartTiles[i,j].Soil:=38; End; If PartTiles[i,j].Soil=3 then case Random(7) of 1,2:PartTiles[i,j].Soil:=31; 0:PartTiles[i,j].Soil:=39; End; If PartTiles[i,j].Soil=4 then if Random(2)=0 then PartTiles[i,j].Soil:=33; If PartTiles[i,j].Soil=5 then if Random(2)=0 then PartTiles[i,j].Soil:=34; If PartTiles[i,j].Soil=6 then if Random(2)=0 then PartTiles[i,j].Soil:=35; If PartTiles[i,j].Soil=7 then if Random(2)=0 then PartTiles[i,j].Soil:=36; If PartTiles[i,j].Soil=8 then if Random(2)=0 then PartTiles[i,j].Soil:=37; End; closefile(fz); closefile(f); // ************************** UpGrade Information ********************************** AssignFile(F,Application.GetNamePath+'Data\Upgrade.Dat'); Reset(f); For u:=1 to 2 do Begin Readln(f,j); For i:=1 to j do Begin Readln(f,w); If inside(w,110,119) then Upgrade[_Who[u]].Money:=w-110; If inside(w,120,129) then Upgrade[_Who[u]].Power:=w-120; If inside(w,130,139) then Upgrade[_Who[u]].Armor:=w-130; If inside(w,140,149) then Upgrade[_Who[u]].Speed:=w-140; If inside(w,150,159) then Upgrade[_Who[u]].Blood:=w-140; End; End; CloseFile(f); // ********* Accessing all parameter about each units of both attacker and defender side ************** For u:=1 to 2 do Begin whonow:=_who[u]; Case whonow of 1 : s1:='Star'; 2 : s1:='Daem'; 3 : s1:='Mill'; End; For c:=1 to 3 do Begin Case c of 1 : STemp:='barrack'; 2 : STemp:='factory'; 3 : STemp:='airport'; End; If Whonow=WhoAmi then // Caution : enemy don't do this !!!!! Begin TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+s1+stemp+'.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Scr1.CreateSurface(CmdBuildImg[c],120,120); CmdBuildImg[c].Surface.BltFast(0,0,TempSurf.Surface,rect(0,0,120,120),0); End; Assignfile(f,Application.GetNamePath+'Data\'+s1+Stemp+'.dat'); Reset(f); Readln(F,w); for x:=1 to w do Begin Readln(F,CmdBuild[WhoNow,c].Isi[x]); Readln(F,CmdBuild[WhoNow,c].Speed[x]); Readln(F,CmdBuild[WhoNow,c].price[x]); End; CmdBuild[WhoNow,c].Active:=0; for x:=1 to 9 do Begin Readln(F,y); If y=1 then Begin CmdBuild[WhoNow,c].Oke[x]:=True; If CmdBuild[WhoNow,c].Active=0 then CmdBuild[WhoNow,c].Active:=x; End Else Begin CmdBuild[WhoNow,c].Oke[x]:=False; If WhoNow=WhoAmi then // Caution : enemy don't do this !!!!! Begin x1:=((x-1) mod 3)+1; y1:=((x-1) div 3)+1; CmdBuildImg[c].Canvas.Brush.Color:=ClBlack; CmdBuildImg[c].Canvas.FillRect(Rect((x1-1)*TileSize,(y1-1)*TileSize,x1*TileSize,y1*TileSize)); CmdBuildImg[c].Canvas.Release; End; End; End; closefile(f); End; TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+s1+'tex.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Assignfile(f,Application.GetNamePath+'Data\'+s1+'tex.dat'); Reset(f); Readln(f,w); for x:=1 to w do Begin Readln(f,x1); Readln(f,y1); Readln(f,y); y:=y*TileSize; Scr1.CreateSurface(ImgBld[WhoNow,x],y,y); ImgBld[WhoNow,x].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x1+y,y1+y),0); End; for x:=1 to w do Begin Readln(f,x1); TabelBld[WhoNow,x1]:=x; End; Readln(f,stemp); Readln(f,Missle[WhoNow].Power); Readln(f,Missle[WhoNow].Ammo); Readln(f,Missle[WhoNow].Speed); Readln(f,Missle[WhoNow].Counter); CloseFile(f); z:=1; // idx, start from 1 because index 1 is for delivery c:=1; // creature TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+s1+'del.bmp'); //delivery TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Scr1.CreateSurface(ImgTroop[WhoNow,z],59,59); ImgTroop[WhoNow,z].Surface.BltFast(0,0,TempSurf.Surface,rect(1,1,59,59),0); Assignfile(f,Application.GetNamePath+'Data\'+s1+'troop.dat'); Reset(f); Readln(f,b); for a:=1 to b do Begin Inc(c); AllUnits[WhoNow,c].Idx:=z+1; Readln(f,AllUnits[WhoNow,c].Name); Readln(f,stemp); Readln(f,AllUnits[WhoNow,c].TypeCreature); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+stemp+'.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Assignfile(f2,Application.GetNamePath+'Data\'+stemp+'.twf'); Reset(f2); For x:=1 to 6 do Readln(f2,stemp); Case AllUnits[WhoNow,c].TypeCreature of 1,3 : y:=40; // 40 sprites 2 : y:=20; // 20 sprites End; for x:=1 to y do Begin inc(z); Readln(f2,stemp); Readln(f2,x1); Readln(f2,y1); Readln(f2,x2); Readln(f2,y2); Scr1.CreateSurface(ImgTroop[WhoNow,z],x2-x1+1,y2-y1+1); ImgTroop[WhoNow,z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End; closefile(f2); Readln(f,AllUnits[WhoNow,c].TileX); Readln(f,AllUnits[WhoNow,c].TileY); Readln(f,AllUnits[WhoNow,c].HTileX); Readln(f,AllUnits[WhoNow,c].HTileY); Readln(f,AllUnits[WhoNow,c].Speed); Readln(f,AllUnits[WhoNow,c].Armor); Readln(f,AllUnits[WhoNow,c].Sight); Readln(f,AllUnits[WhoNow,c].Height); Readln(f,AllUnits[WhoNow,c].Width); Readln(f,AllUnits[WhoNow,c].MaxBlood); Readln(f,AllUnits[WhoNow,c].Bull.Power); Readln(f,AllUnits[WhoNow,c].Bull.Range); Readln(f,AllUnits[WhoNow,c].Bull.Ammo); Readln(f,AllUnits[WhoNow,c].Bull.Speed); Readln(f,AllUnits[WhoNow,c].Bull.Refill); Readln(f,AllUnits[WhoNow,c].Bull.GroundToAir); Readln(f,AllUnits[WhoNow,c].Prior); AllUnits[WhoNow,c].ClassCreature:=1; AllUnits[WhoNow,c].TileX2:=AllUnits[WhoNow,c].TileX; AllUnits[WhoNow,c].TileY2:=AllUnits[WhoNow,c].TileY; End; CloseFile(f); Assignfile(f,Application.GetNamePath+'Data\'+s1+'jet.dat'); Reset(f); Readln(f,b); for a:=1 to b do Begin Inc(c); AllUnits[WhoNow,c].Idx:=z+1; Readln(f,AllUnits[WhoNow,c].Name); Readln(f,stemp); Readln(f,AllUnits[WhoNow,c].TypeCreature); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+stemp+'.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Assignfile(f2,Application.GetNamePath+'Data\'+stemp+'.twf'); Reset(f2); For x:=1 to 6 do Readln(f2,stemp); for x:=1 to 24 do Begin inc(z); Readln(f2,stemp); Readln(f2,x1); Readln(f2,y1); Readln(f2,x2); Readln(f2,y2); Scr1.CreateSurface(ImgTroop[WhoNow,z],x2-x1+1,y2-y1+1); ImgTroop[WhoNow,z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End; closefile(f2); Readln(f,AllUnits[WhoNow,c].TileX); Readln(f,AllUnits[WhoNow,c].TileY); Readln(f,AllUnits[WhoNow,c].Speed); Readln(f,AllUnits[WhoNow,c].Armor); Readln(f,AllUnits[WhoNow,c].Sight); Readln(f,AllUnits[WhoNow,c].MaxBlood); Readln(f,AllUnits[WhoNow,c].Bull.Power); Readln(f,AllUnits[WhoNow,c].Bull.Range); Readln(f,AllUnits[WhoNow,c].Bull.Ammo); Readln(f,AllUnits[WhoNow,c].Bull.Speed); Readln(f,AllUnits[WhoNow,c].Bull.Refill); Readln(f,AllUnits[WhoNow,c].Bull.GroundToAir); Readln(f,AllUnits[WhoNow,c].Prior); AllUnits[WhoNow,c].ClassCreature:=3; End; CloseFile(f); IdxTurrStart[WhoNow]:=c+1;// IdxTurrStart = idx terakhir untuk semua troops atau dgn kata lain // idx pertama untuk turret, selangnya delapan-delapan... Assignfile(f,Application.GetNamePath+'Data\'+s1+'turret.dat'); Reset(f); Readln(f,b); for a:=1 to b do Begin Inc(c); AllUnits[WhoNow,c].IdxT:=z+1; Readln(f,AllUnits[WhoNow,c].Name); Readln(f,stemp); TempImage.Picture.LoadFromFile(Application.Getnamepath+'Picture\'+stemp+'.bmp'); TempSurf.Canvas.Draw(0,0,TempImage.Picture.Graphic); TempSurf.Canvas.Release; Assignfile(f2,Application.GetNamePath+'Data\'+stemp+'.twf'); Reset(f2); Readln(f2,stemp); for x:=1 to 16 do Begin inc(z); Readln(f2,stemp); Readln(f2,x1); Readln(f2,y1); Readln(f2,x2); Readln(f2,y2); Scr1.CreateSurface(ImgTroop[WhoNow,z],x2-x1+1,y2-y1+1); ImgTroop[WhoNow,z].Surface.BltFast(0,0,TempSurf.Surface,rect(x1,y1,x2+1,y2+1),0); End; closefile(f2); Readln(f,AllUnits[WhoNow,c].HTileX); Readln(f,AllUnits[WhoNow,c].HTileY); Readln(f,AllUnits[WhoNow,c].Armor); Readln(f,AllUnits[WhoNow,c].MaxBlood); AllUnits[WhoNow,c].CurBlood:=AllUnits[WhoNow,c].MaxBlood; Readln(f,AllUnits[WhoNow,c].Bull.Power); Readln(f,AllUnits[WhoNow,c].Bull.Range); Readln(f,AllUnits[WhoNow,c].Bull.Ammo); Readln(f,AllUnits[WhoNow,c].Bull.Speed); Readln(f,AllUnits[WhoNow,c].Bull.Refill); Readln(f,AllUnits[WhoNow,c].Bull.GroundToAir); AllUnits[WhoNow,c].Sight:=AllUnits[WhoNow,c].Bull.Range-1; AllUnits[WhoNow,c].HeadHeading:=0; AllUnits[WhoNow,c].Bull.Exist:=false; End; CloseFile(f); End; // end of for u:=1 to 2 Assignfile(f,Application.GetNamePath+'Data\WarData.Dat'); // make buildings : silos, factory, etc Reset(f); Readln(f,u); Readln(f,u); Readln(f,u); For u:=1 to 2 do Begin WhoNow:=_Who[u]; Ptr[WhoNow]:=Nil; Readln(F,stemp); Assignfile(f2,Application.GetNamePath+'Data\'+stemp); Reset(f2); Readln(f2,Seen.HomeX); Readln(f2,Seen.HomeY); Readln(f2,Seen.Width); Readln(f2,Seen.Height); Seen.MapX:=Seen.HomeX+(Seen.Width-ScrX) div 2; Seen.MapY:=Seen.HomeY+(Seen.Height-ScrY) div 2; for a:=1 to 4 do Begin Seen.RepairHouse[1,a]:=nil; Seen.RepairHouse[2,a]:=nil; End; Seen.ComCenter:=nil; IdxRep[1]:=0; IdxRep[2]:=0; For j:=Seen.HomeY to Seen.HomeY+Seen.Height-1 do For i:=Seen.HomeX to Seen.HomeX+Seen.Width-1 do Begin If PartTiles[i,j].Soil in [8,37] then PartTiles[i,j].Soil:=2; Readln(F2,k); If k>0 then Begin l:=NewCreature; If inside(k,2,9) then move(AllUnits[WhoNow,IdxTurrStart[WhoNow]+k-2], AllCreature[l]^,sizeof(AllUnits[WhoNow,IdxTurrStart[WhoNow]+k-3])); If (k>10) and ((Ptr[WhoNow]=nil) or (Random(2)=1)) then Ptr[WhoNow]:=AllCreature[l]; // cari tempat deploy pasukan If k=71 then Seen.ComCenter:=AllCreature[l]; AllCreature[l]^.ID:=500+Random(500); AllCreature[l]^.Moving:=False; AllCreature[l]^.Idx:=k; AllCreature[l]^.BelongTo:=WhoNow; AllCreature[l]^.SpecialID:=k; If k>10 then Readln(f2,AllCreature[l]^.name) else Readln(f2,stemp); Readln(f2,AllCreature[l]^.TypeCreature); If not inside(k,2,9) then Readln(f2,AllCreature[l]^.MaxBlood) else Readln(f2,stemp); If not inside(k,2,9) then Readln(f2,AllCreature[l]^.CurBlood) else Readln(f2,stemp); If not inside(k,2,9) then Readln(f2,AllCreature[l]^.Armor) else Readln(f2,stemp); Readln(f2,AllCreature[l]^.UseAs); Readln(f2,AllCreature[l]^.ClassCreature); Readln(f2,AllCreature[l]^.Prior); If AllCreature[l]^.ClassCreature in [50..59] then Begin Inc(IdxRep[AllCreature[l]^.ClassCreature-50]); Seen.RepairHouse[AllCreature[l]^.ClassCreature-50, IdxRep[AllCreature[l]^.ClassCreature-50]]:=AllCreature[l]; End; AllCreature[l]^.MapY:=j; AllCreature[l]^.MapX:=i; AllCreature[l]^.TileX:=0; AllCreature[l]^.TileY:=0; If AllCreature[l]^.TypeCreature>10 then Begin PartTiles[i+1,j].Ok:=True; PartTiles[i+1,j].Ptr:=AllCreature[l]; PartTiles[i,j+1].Ok:=True; PartTiles[i,j+1].Ptr:=AllCreature[l]; PartTiles[i+1,j+1].Ok:=True; PartTiles[i+1,j+1].Ptr:=AllCreature[l]; End; AllCreature[l]^.Height:=Round(AllCreature[l]^.TypeCreature/10*TileSize); AllCreature[l]^.Width:=AllCreature[l]^.Height; AllCreature[l]^.Force:=True; If inside(k,2,9) then Begin AllCreature[l]^.Force:=False; AllCreature[l]^.TypeCreature:=255; // Turret End; AllCreature[l]^.GeneralTask:=0; Tiles[i,j]:=AllCreature[l]; ToBigMap(AllCreature[l],True); BigMap.Map.Canvas.Release; If WhoNow=WhoAmi then ExploreMap(i,j,4); If AllCreature[l]^.Idx = 81 then Begin Silox[WhoNow]:=AllCreature[l]^.MapX*TileSize+10; Siloy[WhoNow]:=AllCreature[l]^.Mapy*TileSize-3; End; End; End; Closefile(f2); If WhoNow=WhoAmi then move(seen,AllyScreen,sizeof(seen)) else move(seen,EnemyScreen,sizeof(seen)); End; Readln(F,STemp); // build map : trees, grass, soil Readln(F,SourMoney[WhoAmi]); Readln(F,SourMoney[WhoEnemy]); Readln(F,Money[WhoAmi]); Readln(F,Money[WhoEnemy]); readln(F,j); // make delivery For i:=1 to j do NewDelivery(WhoAmI); readln(F,j); For i:=1 to j do NewDelivery(WhoEnemy); If Ptr[WhoAmI]=nil then Begin i:=NewCreature; PtrDummy:=AllCreature[i]; PtrDummy^.MapX:=AllyScreen.HomeX+AllyScreen.Width div 2; PtrDummy^.MapY:=AllyScreen.HomeY+AllyScreen.Height div 2; AllCreature[i]:=nil; Ptr[WhoAmI]:=PtrDummy; End; readln(F,j); // make previous troops For i:=1 to j do Begin Readln(F,c); Readln(F,u); If AllUnits[WhoAmI,c].ClassCreature<>3 then Begin NewPosition(Ptr[WhoAmI],a,b); NewTroop(WhoAmI,a,b,0,c); End Else Begin NewAirUnitPosition(Ptr[WhoAmI],a,b); NewAirUnit(WhoAmI,a,b,0,c); End; End; If PtrDummy<>nil then Dispose(PtrDummy); PtrDummy:=Nil; If Ptr[WhoEnemy]=nil then Begin i:=NewCreature; PtrDummy:=AllCreature[i]; PtrDummy^.MapX:=EnemyScreen.HomeX+EnemyScreen.Width div 2; PtrDummy^.MapY:=EnemyScreen.HomeY+EnemyScreen.Height div 2; AllCreature[i]:=nil; Ptr[WhoEnemy]:=PtrDummy; End; readln(F,j); // make previous troops For i:=1 to j do Begin Readln(F,c); Readln(F,u); If AllUnits[WhoEnemy,c].ClassCreature<>3 then Begin NewPosition(Ptr[WhoEnemy],a,b); NewTroop(WhoEnemy,a,b,0,c); End Else Begin NewAirUnitPosition(Ptr[WhoEnemy],a,b); NewAirUnit(WhoEnemy,a,b,0,c); End; End; If PtrDummy<>nil then Dispose(PtrDummy); TempSurf.Free; TempImage.Free; End; Var i,j,l:smallint; k:integer; Begin for i:=1 to MapMaxY do for j:=1 to MapMaxX do PathTile[j,i]:=SoilFlag; // untuk CariPath() LogicTime.Enabled:=False; Form1.Top:=0; Form1.Left:=0; Form1.Width:=Screen.Width; Form1.Height:=Screen.Height; R1Bound:=TileSize*(ScrX+1)-10-TileSize; R2Bound:=TileSize*(ScrX+1)+10-TileSize; D1Bound:=TileSize*(ScrY)-5; D2Bound:=TileSize*(ScrY)+5; For i:=1 to MaxCreature do AllCreature[i]:=nil; For i:=1 to MaxSBullet do AllPtrSBullet[i]:=nil; For i:=0 to MapMaxY+1 do for j:=0 to MapMaxX+1 do Tiles[j,i]:=nil; For j:=0 to MapMaxY+1 do For I:=0 to MapMaxX+1 do Begin PartTiles[i,j].Fog:=3; PartTiles[i,j].Ok:=False; PartTiles[i,j].Soil:=3; PartTiles[i,j].AirUnit:=0; End; InitPicture; EmptyMos; Geser:=40; Mos.MouseX:=0;Mos.MouseY:=0;Mos.DelayMouse:=0; Mos.DirMovingX:=0;Mos.DirMovingY:=0; IdxP:=1;Idx:=1;CIdx:=0; PtrAttacker:=Nil; For l:=1 to MaxCamera do Begin AllyScreen.CameraX[l]:=AllyScreen.HomeX; AllyScreen.CameraY[l]:=AllyScreen.HomeY; End; Palet[1].Dir:=20; Palet[1].Value:=100; Palet[2].Dir:=15; Palet[2].Value:=100; Palet[3].Dir:=-35; Palet[3].Value:=100; k:=0; for j:=1 to MapMaxY do // gambar original map di vbar; for i:=1 to MapMaxX do Begin Case PartTiles[i,j].Soil of 1,32,38 : k:=$152510; 2 : k:=$116611; 3,31,39,21..24: k:=$224422; 8,37 : k:=$229911; 4..7,12,13, 17..20,25..30, 33..36 : k:=$333333; End; VBar.Canvas.Pixels[15 + i , 20 + j ]:=k; End; VBar.Canvas.Release; DrawAllToScreen; Scr1.Flip; Scr1.FlippingEnabled:=True; LogicTime.Enabled:=True; FlipTimer.Enabled:=True; BuildTimer.Enabled:=True; Hints.Exist:=False; Hints.Ctr:=0; end; Function TForm1.Expon(a,b:SmallInt) : SmallInt; Var c,d:SmallInt; Begin d:=1; For c:=1 to b do d:=d*a; Expon:=d; End; Procedure TForm1.DrawComPanel; Var k,i,j : SmallInt; Begin Scr1.Back.Draw(R1Bound+11,0,VBar,false); // com vertical panel Scr1.Back.Draw(0,D1Bound+6,HBar,false); // com horizontal panel Scr1.Back.Draw(R1Bound+27,21,BigMap.Map,True); // Big Map Scr1.Back.Draw(R1Bound+27,21,BigMap.ShadowMap,True); // Big Map scr1.Back.Canvas.Brush.Color:=$ffffff; scr1.Back.Canvas.FrameRect(Rect(R1Bound+25+AllyScreen.MapX, // current sight of bigmap 20+AllySCreen.MapY,R1Bound+27+AllyScreen.MapX+ScrX,21+AllySCreen.MapY+ScrY+1)); If RepairOn then Begin Scr1.Back.Canvas.Brush.Color:=Palet[3].Value*255; Scr1.Back.Canvas.FrameRect(Rect(ScrX*TileSize+115,465,ScrX*TileSize+147,505)); Scr1.Back.Canvas.Brush.Color:=Palet[3].Value; Scr1.Back.Canvas.FrameRect(Rect(ScrX*TileSize+120,470,ScrX*TileSize+140,498)); End; scr1.Back.Canvas.Release; If (Mos.ArrMosCount>0) and (Mos.BelongTo=WhoAmi) then Begin If (Mos.ArrMos[1]^.ClassCreature in [60..69]) then Begin Scr1.Back.Canvas.Brush.Color:=ClNavy; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+39,255,R1Bound+140,260)); // Process Bar i:=Round(100*Mos.ArrMos[1]^.ActTask3/Missle[Mos.ArrMos[1]^.BelongTo].Counter); Scr1.Back.Canvas.Brush.Color:=ClRed; Scr1.Back.Canvas.FillRect(Rect(R1Bound+TileSize,256,R1Bound+39+i-1,259)); Scr1.Back.Canvas.Release; Scr1.Back.Draw(R1Bound+30,270,MissileImg,true); // Draw Troop Panel If (Mos.ArrMos[1]^.GeneralTask=0) then Begin i:=1; j:=1; Scr1.Back.Canvas.Brush.Color:=Palet[3].Value*255; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+33+(i-1)*TileSize,273+(j-1)*TileSize,R1Bound+27+i*TileSize,267+j*TileSize)); Scr1.Back.Canvas.Brush.Color:=Palet[2].Value; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+37+(i-1)*TileSize,277+(j-1)*TileSize,R1Bound+23+i*TileSize,263+j*TileSize)); Scr1.Back.Canvas.Release; End; End; k:=0; Case Mos.UseAs of 2 : k:=1; // barrack 66 : k:=2; // factory 130 : k:=3; // AirPort End; If k>0 then Begin Scr1.Back.Draw(R1Bound+30,270,CmdBuildImg[k],true); // Draw Troop Panel Scr1.Back.Canvas.Brush.Color:=ClNavy; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+39,255,R1Bound+140,260)); // Process Bar If Mos.ArrMos[1]^.GeneralTask=0 then // If The building don't have any job Begin i:=((CmdBuild[WhoAmi,k].Active-1) mod 3)+1; j:=((CmdBuild[WhoAmi,k].Active-1) div 3)+1; Scr1.Back.Canvas.Brush.Color:=Palet[3].Value; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+30+(i-1)*TileSize,270+(j-1)*TileSize,R1Bound+30+i*TileSize,270+j*TileSize)); Scr1.Back.Canvas.FrameRect(Rect(R1Bound+31+(i-1)*TileSize,271+(j-1)*TileSize,R1Bound+31+i*TileSize,269+j*TileSize)); End Else Begin // If The building has a job i:=((Mos.ArrMos[1]^.ActTask2-1) mod 3)+1; j:=((Mos.ArrMos[1]^.ActTask2-1) div 3)+1; Scr1.Back.Canvas.Brush.Color:=Palet[3].Value*255; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+33+(i-1)*TileSize,273+(j-1)*TileSize,R1Bound+27+i*TileSize,267+j*TileSize)); Scr1.Back.Canvas.Brush.Color:=Palet[2].Value; Scr1.Back.Canvas.FrameRect(Rect(R1Bound+37+(i-1)*TileSize,277+(j-1)*TileSize,R1Bound+23+i*TileSize,263+j*TileSize)); i:=Round(100*Mos.ArrMos[1]^.ActTask3/TimeBuilding); Scr1.Back.Canvas.Brush.Color:=ClRed; Scr1.Back.Canvas.FillRect(Rect(R1Bound+TileSize,256,R1Bound+39+i-1,259)); End; Scr1.Back.Canvas.Release; End; Scr1.Back.Draw(12,D1Bound+21,Commands[1],true); for k:=6 downto 1 do If (Mos.UseAs and Expon(2,(6-k))) = 0 then Scr1.Back.Draw(round((82.5*(k-1))+2)+10,D1Bound+19,Commands[3],true); If IdxCom>0 then Scr1.Back.Draw(Round(83.5*(IdxCom-1)+13),D1Bound+20,Commands[2],true); End; End; Function TForm1.ReturnComPanel(x:SmallInt):SmallInt; Var k : SmallInt; Begin ReturnComPanel:=0; If (Mos.ArrMosCount>0) and (Mos.BelongTo=WhoAmi) then Begin k:=Trunc(x/83.5)+1; If (Mos.UseAs and Expon(2,(6-k))) > 0 then ReturnComPanel:=k; End; End; Procedure TForm1.RemoveCreature(Var Ptr:PObjCreature); Var i : integer; Begin ToBigMap(Ptr,False); BigMap.Map.Canvas.Release; BigMap.ShadowMap.Canvas.Release; If Ptr^.moving then Dec(CreaCount[Ptr^.BelongTo]); Ptr^.Id:=DeadID; If Ptr^.Moving then Begin If Ptr^.TypeCreature=1 then with Ptr^.Effect do begin Exist:=True; IDEffect:=6; CurEffect:=6; // dead visual eff. of troops TxEffect:=-5; TyEffect:=5; CtrLoop:=1; SpdEffect:=2; MaxEffect:=4; MakeSound(5,Ptr^.MapX,Ptr^.Mapy); End; If Ptr^.TypeCreature in [2,3] then with Ptr^.Effect do begin Exist:=True; IDEffect:=17; CurEffect:=17; // dead visual eff. of tanks TxEffect:=2; TyEffect:=5; CtrLoop:=1; SpdEffect:=3; MaxEffect:=5; MakeSound(4,Ptr^.MapX,Ptr^.Mapy); If Random(3)=0 then // beri asap NewSpecialEffect(5,Ptr^.MapX*TileSize+Ptr^.TileX+Ptr^.Width div 2, Ptr^.MapY*TileSize+Ptr^.TileY+Ptr^.Height div 2 ); End; If Ptr^.ClassCreature=3 then // dead visual eff. of air unit Begin NewSpecialEffect(3,Ptr^.Width+TileSize div 2,Ptr^.Height+TileSize div 2); MakeSound(4,Ptr^.MapX,Ptr^.Mapy); End; End Else Begin If (Ptr^.Height>Tilesize) then with Ptr^.Effect do begin Exist:=True; IDEffect:=11; CurEffect:=11; // dead visual eff. of big building TxEffect:=-5; TyEffect:=0; CtrLoop:=1; SpdEffect:=4; MaxEffect:=5; PartTiles[Ptr^.MapX+1,Ptr^.MapY].Ok:=False; PartTiles[Ptr^.MapX,Ptr^.MapY+1].Ok:=False; PartTiles[Ptr^.MapX+1,Ptr^.MapY+1].Ok:=False; For i:=1 to 5 do If Random(3)=0 then // beri asap NewSpecialEffect(5,Ptr^.MapX*TileSize+Random(TileSize*2), Ptr^.MapY*TileSize+Random(TileSize*2)); MakeSound(4,Ptr^.MapX,Ptr^.Mapy); End else with Ptr^.Effect do begin Exist:=True; IDEffect:=17; CurEffect:=17; // dead visual eff. of small building TxEffect:=-7; TyEffect:=-3; CtrLoop:=1; SpdEffect:=3; MaxEffect:=5; If Random(3)=0 then // beri asap NewSpecialEffect(5,Ptr^.MapX*TileSize+TileSize div 2,Ptr^.MapY*TileSize+TileSize div 2); MakeSound(4,Ptr^.MapX,Ptr^.Mapy); End; End; If Ptr^.Idx=81 then Begin SiloX[Ptr^.BelongTo]:=0; For i:=1 to MaxCreature do if (Allcreature[i]<>nil) and (Allcreature[i]<>Ptr) then if (Allcreature[i]^.Id>DeadID) and (Allcreature[i]^.BelongTo=Ptr^.BelongTo) and (AllCreature[i]^.Idx=81) then Begin SiloX[Ptr^.BelongTo]:=Allcreature[i]^.MapX*TileSize+10; SiloY[Ptr^.BelongTo]:=Allcreature[i]^.MapY*TileSize-3; Exit; End; End; End; Procedure TForm1.BeingHit(Var TG:TTarget;Var PtrShooter:PObjCreature;Power:Byte); Var x1 : integer; Begin x1:=Power-TG.Ptr^.Armor; If x1<>TG.Ptr^.BelongTo) then PTRAttacker:=PtrShooter; If TG.Ptr^.CurBlood-x1<=0 then RemoveCreature(TG.Ptr) else Begin Dec(TG.Ptr^.CurBlood,x1); // ,-> beri asap or api kalo kebakaran If TG.Ptr^.CurBloodTilesize then Begin Inc(Effect.TxEffect,20); Inc(Effect.TyEffect,20); End; Effect.Exist:=True; End; End; // ,--> Creature yang sanggup attack If (TG.Ptr^.UseAs and 32 > 0) and (not (TG.Ptr^.GeneralTask in [1,7]) or ( (Tg.Ptr^.Target.Ptr<>nil) and (Tg.Ptr^.Target.Ptr^.ID>DeadID) and (Tg.Ptr^.Target.Ptr^.UseAs and 32 = 0) ) ) and not TG.Ptr^.Force then // counter attack if the creature isn't forced to do something If (PtrShooter^.BelongTo<>TG.Ptr^.BelongTo) and (PtrShooter^.Id>DeadId) and not ((PtrShooter^.ClassCreature=3) and (TG.Ptr^.Bull.GroundToAir=3)) and not ((PtrShooter^.ClassCreature<>3) and (TG.Ptr^.Bull.GroundToAir=1)) and (TG.Ptr^.Moving or RangeOk2Creature(TG.Ptr,PtrShooter,TG.Ptr^.Bull.Range)) and not(PtrShooter^.ClassCreature in [60..69]) then Begin TG.Ptr^.Target.Ptr:=PtrShooter; TG.Ptr^.Target.X:=PtrShooter^.MapX; TG.Ptr^.Target.Y:=PtrShooter^.MapY; TG.Ptr^.TargetChange:=True; TG.Ptr^.GeneralTask:=1; End; End; End; Procedure TForm1.MakeSound(What,x,y:Byte); Var vol2: Integer; Begin Vol2:=Round(-1000 + Distance(X,Y,AllyScreen.MapX+ScrX div 2,AllyScreen.MapY+ScrY div 2)*-75); If Vol2<-3980 then Vol2:=-3980; // range -4000<x<>nil) and (AllCreature[i]^.Bull.Exist) and (AllCreature[i]^.Bull.Ammo0) then With AllCreature[i]^ do Begin If (Mos.DelayMouse=0) then Begin Inc(Bull.Ellapsed); // If (Bull.Ellapsed=1) then PlaySound; End; If Inside(Bull.Target.Ptr^.MapX,AllyScreen.MapX, AllyScreen.MapX+ScrX) and Inside(Bull.Target.Ptr^.MapY,AllyScreen.MapY, AllyScreen.MapY+ScrY) then Begin xx:=(Bull.Target.Ptr^.MapX-AllyScreen.MapX)*TileSize+Bull.Target.Ptr^.TileX; yy:=(Bull.Target.Ptr^.MapY-AllyScreen.MapY)*TileSize+Bull.Target.Ptr^.TileY; if Bull.Target.Ptr^.Id0 then Scr1.Back.Canvas.Pen.Color:=ClYellow else Scr1.Back.Canvas.Pen.Color:=$aaff; Scr1.Back.Canvas.Arc(xx-x1+y1,yy-x1+y1,xx+x1+y1,yy+x1+y1,xx+x1+y1,yy+y1,xx+x1+y1,yy+y1); End; End; 3 : Begin For x1:=1 to 15 do // rifle If Random(3)>0 then Scr1.Back.Canvas.Pixels[xx+Random(16)-8,yy+Random(12)-6]:=ClYellow else Scr1.Back.Canvas.Pixels[xx+Random(16)-8,yy+Random(12)-6]:=ClWhite; End; End; Scr1.Back.Canvas.Release; End; If (Mos.DelayMouse=0) then Begin Dec(Bull.Loops); If (Bull.Loops=0) then Bull.Exist:=False; If (Bull.Loops=0) and (Bull.Target.Ptr^.Id>DeadID) then BeingHit(Bull.Target,AllCreature[i],Bull.Power); Case Bull.Ammo of // Draw Visual Effect of Bullet 1 : MakeSound(0,Bull.MapX,Bull.Mapy); 3 : MakeSound(1,Bull.MapX,Bull.Mapy); End; End; End; End; procedure TForm1.ValidateSPEffect(Var Eff:TEffect); Begin If Mos.DelayMouse=0 then Inc(Eff.CtrEffect); If Eff.CtrEffect>Eff.SpdEffect then Begin Inc(Eff.CurEffect); Eff.CtrEffect:=0; If Eff.CurEffect>Eff.IDEffect+Eff.MaxEffect then Begin Eff.CurEffect:=Eff.IDEffect; Dec(Eff.CtrLoop); If Eff.CtrLoop<>nil) then if AllPtrSPEffect[i]^.Exist then Begin ValidateSPEffect(AllPtrSPEffect[i]^.Effect); If AllPtrSPEffect[i]^.Effect.Exist then Scr1.Back.Draw(AllPtrSPEffect[i]^.TileX+AllPtrSPEffect[i]^.Effect.TxEffect-(AllyScreen.MapX*TileSize), AllPtrSPEffect[i]^.TileY+AllPtrSPEffect[i]^.Effect.TyEffect-(AllyScreen.MapY*TileSize), SEffect[AllPtrSPEffect[i]^.Effect.CurEffect],True) else AllPtrSPEffect[i]^.Exist:=False; End; End; Procedure TForm1.DrawSBull; // draw special bullets Var i,j,k,x,y,x2,y2 : Smallint; hd,idx : byte; Ptr : PSBullet; TG : TTarget; Flag : Boolean; Begin If MM.MenuVisible then Exit; For i:=1 to MaxSBullet do Begin If (AllPtrSBullet[i]<>nil) then if AllPtrSBullet[i]^.Exist then Begin x:=0; y:=0; Ptr:=AllPtrSBullet[i]; If Ptr^.ContinousForm>0 then idx:=Ptr^.ContinousForm else // cari idx If Ptr^.LoopForm>0 then idx:=Ptr^.LoopForm else idx:=Ptr^.DynamicForm; ValidTarget(Ptr^.Target); If Mos.DelayMouse=0 then Begin x:=Ptr^.Target.X*TileSize + TileSize; y:=Ptr^.Target.Y*TileSize + TileSize; If (Ptr^.Target.Ptr<>nil) then If (Ptr^.Target.Ptr^.TypeCreature<>20) then Begin x:=Ptr^.Target.X*TileSize + TileSize div 2; y:=Ptr^.Target.Y*TileSize + TileSize div 2; End; End; for j:=1 to Ptr^.Omni do Begin // ,-> bullet yang berjalan lambat If (mos.DelayMouse=0) and (Ptr^.Speed49) then Begin If not( inside(x2 , x - Ptr^.Speed div 2 - 2, x + Ptr^.Speed div 2 + 2) and // bullet masih belum mengenai sasaran inside(y2 , y - Ptr^.Speed div 2 - 2, y + Ptr^.Speed div 2 + 2) ) and (Ptr^.Task[j]<>255) then Begin If (Distance(x,y,x2,y2)>0) then // special bullet Begin // dan manipulasi koordinatnya If ABS(x-x2)< y then TileY[j]:=TileY[j]+Ptr^.Speed; If y2 > y then TileY[j]:=TileY[j]-Ptr^.Speed; End Else With Ptr^ do Begin TileY[j]:=TileY[j]+Round((y-y2)/ABS(x-x2)*Ptr^.Speed); If x2 < x then TileX[j]:=TileX[j]+Ptr^.Speed; If x2 > x then TileX[j]:=TileX[j]-Ptr^.Speed; End; End; hd:=0; If Ptr^.WithDirection then // cari ke mana arah headingnya bulletnya hd:=SBullHeading(Ptr^.Width,Ptr^.Height,Ptr^.TileX[j],Ptr^.TileY[j],Ptr^.Target); Scr1.Back.Draw(Ptr^.TileX[j]-(AllyScreen.MapX*TileSize), Ptr^.TileY[j]-(Allyscreen.MapY*TileSize), ImgSBullet[Ptr^.Idx + hd * idx + Ptr^.Task[j] - 50],True); Scr1.Back.Canvas.Release; If Ptr^.ContinousForm>0 then // steady continous form Begin Inc(Ptr^.Task2[j]); If Ptr^.Task2[j]>3 then Begin Ptr^.Task2[j]:=0; Inc(Ptr^.Task[j]); If Ptr^.Task[j]>49+Idx then Ptr^.Task[j]:=49+Idx; End; End Else If Ptr^.LoopForm>0 then // circular looping form Begin Inc(Ptr^.Task2[j]); If Ptr^.Task2[j]>1 then Begin Ptr^.Task2[j]:=0; Ptr^.Task[j]:=Ptr^.Task[j]+1; If Ptr^.Task[j]>49+Idx then Ptr^.Task[j]:=50; End; End Else If Ptr^.DynamicForm>0 then // dynamic or random form Ptr^.Task[j]:=50+Random(Ptr^.DynamicForm); End // Sudah Kena ... inside(x2..... Else If (Ptr^.Task[j]<>255) then Begin Ptr^.Task[j]:=255; If (Ptr^.Resting=2) and (j49 End; // end of if delaymouse=0 End; // end of for Flag:=True; If (Ptr^.Target.Ptr<>nil) and (Ptr^.Target.Ptr^.Id15) // ---> peluru cepat ) then Begin // Bullet hit enemy Ptr^.Exist:=False; Ptr^.From^.Bull.Exist:=False; If Ptr^.ExplodeRange<>nil then If Ptr^.Target.Ptr^.Id>DeadID then Begin BeingHit(Ptr^.Target,Ptr^.From,Ptr^.Power); If (Ptr^.Effect.PoisonCtr>0) or (Ptr^.Effect.SelfHealing) or (Ptr^.Effect.Range) or (Ptr^.Effect.UnTouchable) or (Ptr^.Effect.Armor) or (Ptr^.Effect.Power) then Move(Ptr^.Effect,Ptr^.Target.Ptr^.Infinite,Sizeof(Ptr^.Effect)); End; End Else Begin If Ptr^.Power=0 then ExploreMap(Ptr^.Target.X,Ptr^.Target.Y,10) Else Begin For y:=1 to MaxCreature do If (AllCreature[y]<>nil) then // check all air unit dalam explode range If (AllCreature[y]^.Id>DeadID) and inside(AllCreature[y]^.Id,9900,9998) and inside(AllCreature[y]^.MapX,Ptr^.Target.X+1-Ptr^.ExplodeRange,Ptr^.Target.X-1+Ptr^.ExplodeRange) and inside(AllCreature[y]^.MapY,Ptr^.Target.Y+1-Ptr^.ExplodeRange,Ptr^.Target.Y-1+Ptr^.ExplodeRange) then Begin Tg.Ptr:=AllCreature[y]; Tg.X:=AllCreature[y]^.MapX; Tg.Y:=AllCreature[y]^.MapY; BeingHit(Tg,Ptr^.From,Ptr^.Power); If (Ptr^.Effect.PoisonCtr>0) or (Ptr^.Effect.SelfHealing) or (Ptr^.Effect.Range) or (Ptr^.Effect.UnTouchable) or (Ptr^.Effect.Armor) or (Ptr^.Effect.Power) then Move(Ptr^.Effect,Tg.Ptr^.Infinite,Sizeof(Ptr^.Effect)); End; For y:=Ptr^.Target.Y+1-Ptr^.ExplodeRange to Ptr^.Target.Y-1+Ptr^.ExplodeRange do For x:=Ptr^.Target.X+1-Ptr^.ExplodeRange to Ptr^.Target.X-1+Ptr^.ExplodeRange do Begin k:=Ptr^.Resting; // exploded in a range If k=4 then k:=Random(4)+1; NewSpecialEffect(k,x * TileSize + TileSize div 2,y * TileSize + TileSize div 2); Tg.Ptr:=Tiles[x,y]; Tg.X:=X; Tg.Y:=Y; If PartTiles[x,y].Ok then Tg.Ptr:=PartTiles[x,y].Ptr; If Tg.Ptr<>nil then if Tg.Ptr^.Id>DeadID then Begin If Tg.Ptr^.Moving then BeingHit(Tg,Ptr^.From,Ptr^.Power) else BeingHit(Tg,Ptr^.From,Ptr^.Power div 2); If (Ptr^.Effect.PoisonCtr>0) or (Ptr^.Effect.SelfHealing) or (Ptr^.Effect.Range) or (Ptr^.Effect.UnTouchable) or (Ptr^.Effect.Armor) or (Ptr^.Effect.Power) then Move(Ptr^.Effect,Tg.Ptr^.Infinite,Sizeof(Ptr^.Effect)); End; End; End; End; End; If (Ptr^.ExplodeRange=1) and (Ptr^.Target.Ptr^.Id<>9999 then With Ptr^ do Begin x:=width div TileSize; y:=height div TileSize; If inside(x, AllyScreen.MapX-1, AllyScreen.MapX+ScrX) and inside(y, AllyScreen.MapY-1, AllyScreen.MapY+ScrY) then Begin xx:=width-(AllyScreen.MapX*TileSize); yy:=height-(Allyscreen.MapY*TileSize); If Id=10000 then Scr1.Back.Draw(xx+TileX,yy+TileY,ImgTroop[BelongTo,Idx],True) // Delivery else Begin Scr1.Back.Draw(xx+TileX,yy+TileY+20,ImgTroop[BelongTo,Idx+BodyHeading+8],True); // Ordinay Air Units If ActTask1=0 then Scr1.Back.Draw(xx+TileX,yy+TileY-15+ActTask2,ImgTroop[BelongTo,Idx+BodyHeading],True) else Scr1.Back.Draw(xx+TileX,yy+TileY-15,ImgTroop[BelongTo,Idx+BodyHeading+16],True); End; If Ptr^.Active then Begin If (Ptr^.BelongTo=WhoAmi) or (Ptr^.BelongTo=AllySide) then scr1.Back.Canvas.Brush.Color:=Palet[2].Value*256 else scr1.Back.Canvas.Brush.Color:=Palet[3].Value*256+Palet[3].Value; scr1.Back.Canvas.FrameRect(Rect(xx,yy,xx+TileSize,yy+TileSize)); If Ptr^.Infinite.PoisonCtr=0 then scr1.Back.Canvas.Brush.Color:=255 else scr1.Back.Canvas.Brush.Color:=255*256; If not Ptr^.Infinite.UnTouchable then scr1.Back.Canvas.FillRect(Rect(xx,yy-4 ,xx+(TileSize * Ptr^.CurBlood div Ptr^.MaxBlood),yy-2)); scr1.Back.Canvas.Release; End; End; end; End; Procedure TForm1.DrawFog; Var x,y :SmallInt; Begin For y:=AllyScreen.MapY-1 to AllyScreen.MapY+ScrY+1 do For x:=AllyScreen.MapX-1 to AllyScreen.MapX+ScrX+1 do If PartTiles[x,y].Fog>0 then Case PartTiles[x,y].Fog of 1 : Scr1.Back.Draw(TileSize*(x-AllyScreen.MapX)-10, TileSize*(Y-AllyScreen.MapY)-10,RoundShadow,true); 2 : Scr1.Back.Draw(TileSize*(x-AllyScreen.MapX), TileSize*(Y-AllyScreen.MapY),FixShadow,true); End; For y:=AllyScreen.MapY-1 to AllyScreen.MapY+ScrY+1 do For x:=AllyScreen.MapX-1 to AllyScreen.MapX+ScrX+1 do If PartTiles[x,y].Fog=3 then Scr1.Back.Draw(TileSize*(x-AllyScreen.MapX),TileSize*(Y-AllyScreen.MapY),DarkShadow,false); End; Procedure TForm1.DrawAllToScreen; Var x,y,i,j,k,xx,yy,col: SmallInt; Pt_ : PObjCreature; WRefresh : Boolean; Begin // ******************* Initialize palets ***************** If not MM.MenuVisible then For i:=1 to 5 do Begin Inc(Palet[i].Value,Palet[i].Dir); If (Palet[i].Value>230) or (Palet[i].Value<>AllyScreen.PrevX) or (AllyScreen.MapY<>AllyScreen.PrevY) then Begin AllyScreen.PrevX:=AllyScreen.MapX; AllyScreen.PrevY:=AllyScreen.MapY; WRefresh:=True; End; x:=-1; y:=-1; If WRefresh then For j:=AllyScreen.MapY-1 to AllyScreen.MapY+ScrY do Begin For i:=AllyScreen.MapX-1 to AllyScreen.MapX+ScrX+1 do Begin xx:=TileSize*x; yy:=TileSize*y; k:=PartTiles[i,j].Soil; Case k of 1..7, 12,13, 17..36,38,39 : Scr1.Back.Draw(xx,yy,Soils[k],false); 8,37 : Scr1.Back.Draw(xx,yy,Soils[2],false); End; If k in [1,3,31,32,38,39] then Begin if PartTiles[i+1,j].Soil in [2,8,37] then Scr1.Back.Draw(xx+28,yy,Soils[10],true); if PartTiles[i-1,j].Soil in [2,8,37] then Scr1.Back.Draw(xx-10,yy,Soils[10],true); if PartTiles[i,j+1].Soil in [2,8,37] then Scr1.Back.Draw(xx,yy+28,Soils[9],true); if PartTiles[i,j-1].Soil = 2 then Scr1.Back.Draw(xx,yy-12,Soils[9],true); End; Inc(x); End; Inc(y); x:=-1; End; If Mos.DelayMouse=0 then If WRefresh then BackLayer.BltFast(0,0,Scr1.Back,rect(0,0,ScrX*TileSize+3,ScrY*TileSize+3),False) else Scr1.Back.Draw(0,0,BackLayer,False); // ********************** Draw Creature : Buildings and Ground Units ********************* For j:=AllyScreen.MapY-1 to AllyScreen.MapY+ScrY do For i:=AllyScreen.MapX-1 to AllyScreen.MapX+ScrX+1 do If PartTiles[i,j].Fog<> nil then Begin xx:=TileSize*(i-AllyScreen.MapX); // Calculate yy:=TileSize*(j-AllyScreen.MapY); // position xx and yy Inc(xx,Pt_^.TileX); Inc(yy,Pt_^.TileY); If not Pt_^.Moving and (Pt_^.Id>DeadID) then Scr1.Back.Draw(TileSize*(i-AllyScreen.MapX)+Pt_^.TileX, TileSize*(j-AllyScreen.MapY)+Pt_^.TileY, ImgBld[Pt_^.BelongTo,TabelBld[Pt_^.BelongTo,Pt_^.idx]],True); // Draw building If (((Pt_^.Moving) and (Pt_^.TypeCreatureDeadID) then // moving creature or turret Begin Case Pt_^.TypeCreature of 1,3 : Begin // Soldier k:=Pt_^.Idx+Pt_^.BodyHeading*5 + Pt_^.ActTask2; If Pt_^.Bull.Exist then Inc(k); Scr1.Back.Draw(xx,yy,ImgTroop[Pt_^.BelongTo,k],True); End; 2 : Begin // Tank k:=Pt_^.BodyHeading; If k>3 then k:=k-4; k:=Pt_^.Idx + k; Scr1.Back.Draw(xx,yy,ImgTroop[Pt_^.BelongTo,k],True); k:=Pt_^.Idx + 4 + Pt_^.HeadHeading; If Pt_^.Bull.Exist then Inc(k,8); Scr1.Back.Draw(xx+Pt_^.HTileX,yy+Pt_^.HTileY,ImgTroop[Pt_^.BelongTo,k],True); End; 255 : Begin // Turret k:=Pt_^.IdxT+Pt_^.HeadHeading; If Pt_^.Bull.Exist then Inc(k,8); Scr1.Back.Draw(xx+Pt_^.HTileX,yy++Pt_^.HTileY,ImgTroop[Pt_^.BelongTo,k],True); End; End; { Case } End; If Pt_^.CurBlood>=Round(Pt_^.MaxBlood * 3/4) then Pt_^.Effect.CtrLoop:=1; // for fire effect If Not MM.MenuVisible then ValidateSPEffect(Pt_^.Effect); If Pt_^.Effect.Exist then Scr1.Back.Draw(xx+Pt_^.Effect.TxEffect,yy+Pt_^.Effect.TyEffect,SEffect[Pt_^.Effect.CurEffect],True); If Pt_^.NowRepaired then Begin If Pt_^.TypeCreature=20 then Scr1.Back.Draw(xx+26,yy+23,MPointer[4,1+Random(2)],true) else Scr1.Back.Draw(xx+2,yy+2,MPointer[4,1+Random(2)],true); End; End; End; // ***************** Active Unit ************** For j:=AllyScreen.MapY-1 to AllyScreen.MapY+ScrY do For i:=AllyScreen.MapX-1 to AllyScreen.MapX+ScrX+1 do If (PartTiles[i,j].Fog<>nil) and (Tiles[i,j]^.Active) and (Tiles[i,j]^.Id>DeadID) then Begin Pt_:=Tiles[i,j]; xx:=TileSize*(i-AllyScreen.MapX); // Calculate yy:=TileSize*(j-AllyScreen.MapY); // position xx and yy Inc(xx,Pt_^.TileX); Inc(yy,Pt_^.TileY); If (Pt_^.BelongTo=WhoAmi) or (Pt_^.BelongTo=AllySide) then scr1.Back.Canvas.Brush.Color:=Palet[2].Value*256 else scr1.Back.Canvas.Brush.Color:=Palet[3].Value*256+Palet[3].Value; scr1.Back.Canvas.FrameRect(Rect(xx+6,yy+6,xx+Pt_^.Width-6,yy+Pt_^.Height-6)); If (Pt_^.Infinite.PoisonCtr=0) or (not Pt_^.Moving) then scr1.Back.Canvas.Brush.Color:=255 else scr1.Back.Canvas.Brush.Color:=65280; If (not Pt_^.Infinite.UnTouchable) and (Pt_^.Prior>1) then scr1.Back.Canvas.FrameRect(Rect(xx,yy+2,xx+(Pt_^.Width * Pt_^.CurBlood div Pt_^.MaxBlood),yy+4)); End; scr1.Back.Canvas.Release; // ********************** Draw Air Units ********************* Inc(DelAppear[1]); Inc(DelAppear[2]); Inc(DelAppear[3]); For i:=1 to MaxCreature do If AllCreature[i]<>nil then If AllCreature[i]^.Id>9900 then DrawPlane(AllCreature[i]); // *********************** Draw Boxline while area is being selected ******************** If PunchLong and ((Mos.StartX-Mos.EndX<>0) or (Mos.StartY-Mos.EndY<>0)) then BoxLine; DrawBullets; DrawSPEffect; DrawSBull; DrawFog; DrawCirc; If MM.MenuVisible then // Shadows all if Main Menu is visible For j:=1 to ScrY do For i:=1 to ScrX do Scr1.Back.Draw((i-1)*TileSize,(j-1)*TileSize,Shadow,True); DrawComPanel; End; // *********************** Draw Circle , vis. effect of mouse pointer ******************** Procedure TForm1.DrawCirc; Var Xx,Yy : SmallInt; Begin If Not MM.MenuVisible and Circ.Exist then // draw circle If ((Circ.Ptr<>nil) and (Circ.Ptr^.Id>DeadID)) or (Circ.Ptr=nil) then // kalo ptr=nil or ptr menunjuk benda hidup Begin If Circ.Ptr<>nil then Begin Circ.MapY:= Circ.Ptr^.MapY; Circ.MapX:= Circ.Ptr^.MapX; Circ.TileX:=Circ.Ptr^.TileX; Circ.TileY:= Circ.Ptr^.TileY; End; xx:=TileSize*(Circ.MapX-AllyScreen.MapX)+Circ.TileX; yy:=TileSize*(Circ.MapY-AllyScreen.MapY)+Circ.TileY; Case Circ.CircType of 1,2 : Begin // vis. effect bentuk I Scr1.Back.Canvas.Brush.Color:=ClLime; If Circ.CircType=1 then Scr1.Back.Canvas.Brush.Color:=ClRed; scr1.Back.Canvas.FrameRect(Rect(xx+Circ.Count,yy+Circ.Count, xx+Circ.Width-Circ.Count,yy+Circ.Height-Circ.Count)); Scr1.Back.Canvas.Brush.Color:=ClGreen; If Circ.CircType=1 then Scr1.Back.Canvas.Brush.Color:=ClRed; scr1.Back.Canvas.FrameRect(Rect(xx+Circ.Count-2,yy+Circ.Count-2, xx+Circ.Width-Circ.Count+2,yy+Circ.Height-Circ.Count+2)); Scr1.Back.Canvas.Release; End; 6 : Begin Scr1.Back.Canvas.Brush.Color:=ClWhite; // vis. effect bentuk I scr1.Back.Canvas.FrameRect(Rect(xx,yy,xx+Circ.Width,yy+Circ.Height)); Scr1.Back.Canvas.Brush.Color:=ClRed; scr1.Back.Canvas.FrameRect(Rect(xx+3,yy+3,xx+Circ.Width-3,yy+Circ.Height-3)); Scr1.Back.Canvas.Release; End; End; If Circ.Count>Round(Circ.Width/2) then Circ.Exist:=False; End; End; Procedure TForm1.BoxLine; Var p,q,r,s,x1,y1,x2,y2 : SmallInt; Begin p:=Mos.StartX; q:=Mos.StartY; r:=Mos.EndX; s:=Mos.EndY; If Mos.StartX>Mos.EndX then SwapValue(Mos.StartX,Mos.EndX); If Mos.StartY>Mos.EndY then SwapValue(Mos.StartY,Mos.EndY); With Mos do Begin x1:=TileSize*(StartX-AllyScreen.MapX); y1:=TileSize*(StartY-AllyScreen.MapY); x2:=TileSize*(EndX-AllyScreen.MapX)+TileSize; y2:=TileSize*(EndY-AllyScreen.MapY)+TileSize; scr1.Back.Canvas.Brush.Color:=Palet[1].Value; scr1.Back.Canvas.FrameRect(Rect(x1,y1,x2,y2)); Scr1.Back.Canvas.Release; End; Mos.StartX:=p; Mos.StartY:=q; Mos.EndX:=r; Mos.EndY:=s; End; Procedure TForm1.CekMouse; Var xx,yy,zz: SmallInt; Ptr : PObjCreature; Flag : Boolean; Begin If Not MM.MenuVisible then Begin If inside(Mos.MouseX,6,R1Bound+159) and Inside(Mos.MouseY,10,D1Bound+69) then CIdx:=0; AllyScreen.MapX := AllyScreen.MapX - Mos.DirMovingX div 40; AllyScreen.MapY := AllyScreen.MapY - Mos.DirMovingY div 40; Mos.DirMovingX:=0;Mos.DirMovingY:=0;Mos.DelayMouse := 0; If (Mos.DelayMouse = 0) Then if ( ((Mos.MouseX>R1Bound+159)and(AllyScreen.MapX1)) or ((Mos.MouseY>D1Bound+69)and(AllyScreen.MapY1)) ) and not PunchLong Then Inc(Cidx); If (CIdx>7) or ((CIdx>5) and ForceToFlip) then Begin Mos.DelayMouse:=1; CIdx:=7; End; If Mos.DelayMouse = 1 Then Begin Flag:=False; If (Mos.MouseX>R1Bound+159)and (AllyScreen.MapX < MapMaxX-ScrX) Then Begin Mos.DirMovingX:=-Geser; Flag:=True; End; If (Mos.MouseX 1) Then Begin Mos.DirMovingX := Geser; Flag:=True; End; If (Mos.MouseY>D1Bound+69)and (AllyScreen.MapY < MapMaxY - ScrY) Then Begin Mos.DirMovingY:=-Geser; Flag:=True; End; If (Mos.MouseY 1) Then Begin Mos.DirMovingY := Geser; Flag:=True; End; If not flag then Mos.DelayMouse:=0; End; zz:=IdxP; Xx:=(Mos.MouseX) div TileSize + AllyScreen.MapX; Yy:=(Mos.MouseY) div TileSize + AllyScreen.MapY; Ptr:=Nil; If (Inside(Mos.MouseX,0,R1Bound) and Inside(Mos.MouseY,0,D1Bound)) then Begin WhoIsThere(Ptr,Xx,Yy); // nentuin bentuk gambar mouse If PartTiles[Xx,Yy].Fog=3 then IdxP:=1 else // terhalangi unexplored shadow If RepairOn then IdxP:=4 else // Obeng If IdxP=100 then IdxP:=2 else // Musuh, Enemy aircraft If (IdxCom=1) or (IdxCom=6) then IdxP:=2 else Begin IdxP:=1; If (Ptr<>nil) and ((Ptr^.BelongTo=WhoEnemy) or (Ptr^.BelongTo=EnemySide)) then IdxP:=2; End; End Else IdxP:=3; // gambar handy pointer inc(idx); if idx>=13 then idx:=2; Scr1.Back.Draw(Mos.MouseX,Mos.MouseY,MPointer[idxp,idx div 2],true); IdxP:=ZZ; If (Mos.MouseX=Mos.PrevX) and (Mos.MouseY=Mos.PrevY) and (Inside(Mos.MouseX,0,R1Bound) and Inside(Mos.MouseY,0,D1Bound)) then Begin Inc(Hints.Ctr); If Hints.Ctr>30 then If (Ptr<>nil) and (PartTiles[xx,yy].Fog<>3) and (Ptr^.Id>DeadId) then Begin If Ptr^.Prior>1 then Begin Hints.Exist:=True; Hints.Ctr:=31; If Ptr^.BelongTo=WhoAmi then Begin Hints.Msg:=Ptr^.Name; Hints.Color:=$ff00 End else Begin Hints.Color:=ClYellow; If Ptr^.Moving then Hints.Msg:='Enemy Unit' else Hints.Msg:='Enemy Structure'; End; End; End else Begin Hints.Ctr:=0; Hints.Exist:=False; End; End Else Begin Hints.Exist:=False; Hints.Ctr:=0; Mos.PrevX:=Mos.MouseX; Mos.PrevY:=Mos.MouseY; End; End Else // if MM.MenuVisible Begin inc(idx); if idx>=13 then idx:=2; Scr1.Back.Draw(Mos.MouseX,Mos.MouseY,MPointer[3,idx div 2],true); End; End; Procedure Tform1.Debuger(a:string;x,y:SmallInt); Function intto0(z:Integer):String; var s:string; i:SmallInt; Begin s:=''; For i:=1 to 8-length(inttostr(z)) do s:=s+'0'; intto0:=s+inttostr(z); End; var Stemp1,Stemp2 : string[2]; begin With Scr1.back.canvas do Begin Text1.Canvas.FillRect(Rect(0,0,170,18)); Text1.Canvas.Textout(1,1,'Mineral : '+IntTo0(Money[WhoAmI])); Text1.Canvas.Release; Scr1.Back.Draw(ScrX*TileSize-130,5,Text1,True); If TimeExpired div 700 > 1 then Stemp1:='s ' else Stemp1:=' '; If (TimeExpired mod 700) div 31 + 1 > 1 then Stemp2:='s ' else Stemp2:=' '; Text2.Canvas.FillRect(Rect(0,0,230,18)); Text2.Canvas.Textout(1,1,' Time expired : '+ IntToStr(TimeExpired div 700) + ' day' + stemp1 + IntToStr((TimeExpired mod 700) div 31 + 1) + ' hour' + stemp2); Text2.Canvas.Release; Scr1.Back.Draw(5,5,Text2,True); Scr1.back.canvas.Font.Size:=10; Scr1.back.canvas.Font.Name:='Verdana'; Scr1.back.canvas.Font.Color:=ClWhite; Scr1.back.canvas.Brush.Color:=$800000; Scr1.back.canvas.brush.Color:=ClBlack; If Hints.Exist and not MM.MenuVisible then Begin Scr1.back.canvas.Font.Size:=10; Scr1.back.canvas.Font.Color:=Hints.Color; Textout(Mos.MouseX+20,Mos.MouseY+15,' '+Hints.Msg+' '); End; If Debugers then Begin { Textout(10,10, 'Idx : '+IntToStr(AllPtrSBullet[ZZZ]^.Idx)); Textout(10,30, 'Ammo : '+IntToStr(AllPtrSBullet[ZZZ]^.Ammo)); Textout(10,50, 'ExRan: '+IntToStr(AllPtrSBullet[ZZZ]^.ExplodeRange)); Textout(10,70, 'Resti: '+IntToStr(AllPtrSBullet[ZZZ]^.Resting)); Textout(10,90, 'T.X : '+IntToStr(AllPtrSBullet[ZZZ]^.Target.X)); Textout(10,110,'T.Y : '+IntToStr(AllPtrSBullet[ZZZ]^.Target.Y)); Textout(10,130,'X : '+IntToStr(AllPtrSBullet[ZZZ]^.TileX[1])); Textout(10,150,'Y : '+IntToStr(AllPtrSBullet[ZZZ]^.tileY[1])); } Textout(10,10, 'ID : '+IntToStr(PtrZZZ^.Id)); Textout(10,30, 'GenT : '+IntToStr(PtrZZZ^.GeneralTask)); Textout(10,50, 'MaiT : '+IntToStr(PtrZZZ^.MainTask)); Textout(10,70, 'Act1 : '+IntToStr(PtrZZZ^.ActTask1)); Textout(10,90, 'Act2 : '+IntToStr(PtrZZZ^.ActTask2)); Textout(10,110,'Act3 : '+IntToStr(PtrZZZ^.ActTask3)); Textout(10,130,'Mov1 : '+IntToStr(PtrZZZ^.MovTask1)); Textout(10,150,'Mov2 : '+IntToStr(PtrZZZ^.MovTask2)); Textout(10,170,'BelTo: '+IntToStr(PtrZZZ^.BelongTo)); Textout(10,190,'Class: '+IntToStr(PtrZZZ^.ClassCreature)); Textout(10,190,'Ctr : '+IntToStr(PtrZZZ^.Effect.CtrLoop)); Textout(10,210,'ZZZ : '+IntToStr(zzz)); Textout(10,230,'x : '+IntToStr(PtrZZZ^.MapX)+' '+IntToStr(PtrZZZ^.Width)); Textout(10,250,'Y : '+IntToStr(PtrZZZ^.MapY)+' '+IntToStr(PtrZZZ^.Height)); Textout(10,290,'tx : '+IntToStr(PtrZZZ^.Target.X)); Textout(10,310,'ty : '+IntToStr(PtrZZZ^.Target.Y)); if MM.BtMenu[MM_Title_Retreat].Visible then Textout(10,310,'Retreat '); if MM.BtMenu[MM_Title_CancelAttack].Visible then Textout(10,330,'Cancel '); if MM.BtMenu[MM_Title_ExitProgram].Visible then Textout(10,350,'Exit '); Textout(10,10, 'Delay : '+IntToStr(DelAppear[WhoAmI])); End; Scr1.back.canvas.Font.Size:=12; release; end; end; procedure TForm1.ExploreMap(x,y,area:Byte); Var x1,y1,x2,y2,i,j: SmallInt; Begin x1:=x-Area; If X1MapMaxX then x2:=MapMaxX+1; y1:=y-Area; If Y1MapMaxY then y2:=MapMaxY+1; For j:=y1+1 to y2-1 do For i:=x1+1 to x2-1 do If PartTiles[i,j].Fog<>0 then Begin PartTiles[i,j].Fog:=0; BigMap.ShadowMap.Canvas.Pixels[i,j]:=0; BigMap.ShadowMap.Canvas.Release; End; For j:=y1 to y2 do Begin If PartTiles[x1,j].Fog<>0 then PartTiles[x1,j].Fog:=1; If PartTiles[x2,j].Fog<>0 then PartTiles[x2,j].Fog:=1; End; For i:=x1 to x2 do Begin If PartTiles[i,y1].Fog<>0 then PartTiles[i,y1].Fog:=1; If PartTiles[i,y2].Fog<>0 then PartTiles[i,y2].Fog:=1; End; End; procedure TForm1.ShowMenu; Var i,col : integer; Begin Scr1.Back.Draw(150,95,MainMenu,true); Scr1.Back.Canvas.Brush.Color:=50*256*256; Scr1.Back.Canvas.Font.Name:='Verdana'; Scr1.Back.Canvas.Font.Size:=13; For i:=1 to 30 do If MM.BtMenu[i].Visible then begin If inside(Mos.MouseX,MM.BtMenu[i].PosX,MM.BtMenu[i].PosX2) and inside(Mos.MouseY,MM.BtMenu[i].PosY,MM.BtMenu[i].PosY2) then col:=ClWhite else Col:=ClGray; If not MM.BtMenu[i].Enable then col:=$333399; If MM.BtMenu[i].PosY=145 then Begin Col:=ClYellow; MM.BtMenu[i].Enable:=False; End; If i=MM_Others then Col:=$0000ff; Scr1.Back.Canvas.Font.Color:=Col; Scr1.Back.Canvas.TextOut(MM.BtMenu[i].PosX,MM.BtMenu[i].PosY,MM.BtMenu[i].Title); End; Scr1.Back.Canvas.Release; End; procedure TForm1.Scr1Flip(Sender: TObject); begin DrawAllToScreen; Debuger('a',1,1); If MM.MenuVisible then ShowMenu; CekMouse; end; procedure TForm1.SwapValue(Var x,y:SmallInt); Var z:SmallInt; Begin z:=x; x:=y; y:=z; End; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Mos.MouseX := X;Mos.MouseY := Y; if Mos.MouseXR1Bound+160 then Mos.MouseX:=R1Bound+160; if Mos.MouseY>D1Bound+70 then Mos.MouseY:=D1Bound+70; If (Inside(Mos.MouseX,0,R1Bound) and Inside(Mos.MouseY,0,D1Bound)) then Begin If (ssleft in Shift) then Begin Mos.EndX:=(Mos.MouseX) div TileSize + AllyScreen.MapX; Mos.EndY:=(Mos.MouseY) div TileSize + AllyScreen.MapY; End Else PunchLong:=False; End; end; procedure TForm1.InsCreatureToMouse(Var Moz:TMouse;Ptr:PObjCreature); var i:SmallInt; Begin IdxCom:=0; If Moz.ArrMosCount<>nil then If (ArrMos[i]^.Moving) or (ArrMos[i]^.TypeCreature=255) then Begin ArrMos[i]^.TargetChange:=True; If Task=5 then ArrMos[i]^.Force:=False else ArrMos[i]^.Force:=True; If Task=0 then ArrMos[i]^.MakeItGuard:=True else Begin ArrMos[i]^.MakeItGuard:=False; ArrMos[i]^.GeneralTask:=Task; ArrMos[i]^.Target:=Tar; End; ArrMos[i]^.Active:=True; end; End; procedure TForm1.EmptyMos; Var i:SmallInt; Begin With mos do begin UseAs:=255; ArrMosCount:=0; For i:=1 to MaxMosCount do Begin If ArrMos[i]<>nil then If ArrMos[i]^.Id>0 then ArrMos[i]^.Active:=False; ArrMos[i]:=nil; End; End; End; Procedure TForm1.BuildTroops(Who:Byte;WhatToBuild:Integer;Which:PObjCreature;count:byte;Duit:byte); Function SearEmpty:Integer; Var i : integer; Begin SearEmpty:=MaxTaskBuild; For i:=1 to MaxTaskBuild do if TaskBuild[i].BelongTo=0 then begin SearEmpty:=i; Exit; End; End; Var i : integer; Begin If Who=WhoAmi then Begin i:=0; Case mos.UseAs of 2 : i:=1; 66 : i:=2; 130 : i:=3; End; WhatToBuild:=CmdBuild[Who,i].Active; Count:=CmdBuild[Who,i].speed[WhatToBuild]; Duit:=CmdBuild[Who,i].Price[WhatToBuild]; WhatToBuild:=CmdBuild[Who,i].isi[WhatToBuild]; Which^.ActTask2:=CmdBuild[Who,i].Active; End; If Which^.GeneralTask>0 then Exit; i:=SearEmpty; Which^.GeneralTask:=100; // Build Which^.ActTask1:=i; Which^.ActTask3:=0; TaskBuild[i].BelongTo:=Who; TaskBuild[i].Price:=Duit; TaskBuild[i].MakeWhat:=WhatToBuild; TaskBuild[i].WhoIsMaking:=Which; TaskBuild[i].Count:=Count; End; Procedure Tform1.WhoIsThere(Var Temp:PObjCreature;xx,yy:SmallInt); Var zz : smallint; procedure Valid(var x,y:SmallInt); // Pada waktu click, mungkin tidak tepat pada obj nya, maka var cx,cy,xs,ys:smallint; // cari sekitarnya ... Begin for cy:=y-1 to y+1 do for cx:=x-1 to x+1 do If Tiles[cx,cy]<>nil then Begin xs:=(Tiles[cx,cy]^.MapX-AllyScreen.MapX)*TileSize+Tiles[cx,cy]^.TileX; ys:=(Tiles[cx,cy]^.MapY-AllyScreen.MapY)*TileSize+Tiles[cx,cy]^.TileY; if inside(mos.MouseX,xs,xs+Tiles[cx,cy]^.Width) and inside(mos.MouseY,ys,ys+Tiles[cx,cy]^.Height) then Begin x:=cx; y:=cy; exit; End; End; End; Begin Temp:=Nil; For zz:=1 to MaxCreature do if AllCreature[zz]<>nil then // Apakah yang diklik pesawat if inside(AllCreature[zz]^.Id,9900,9998) then // Over 9998 is delivery Id If (AllCreature[zz]^.MapX=Xx) and (AllCreature[zz]^.MapY=Yy) then {Break;} Temp:=AllCreature[zz]; If Temp=nil then // Yang diklik bukan pesawat Begin Valid(xx,yy); // Cari tepatnya klik di mana Temp:=Tiles[Xx,Yy]; If PartTiles[xx,yy].Ok then Temp:=PartTiles[xx,yy].Ptr; // Unutk bangunan 2x2 End; End; procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Var Xx,Yy,Zz: SmallInt; Tar : TTarget; Temp : PObjCreature; procedure ModiCirc(ptr:PObjCreature;px,py,ts:SmallInt); // Timbulkan Effek Circle atau Box pada layar Begin Circ.Exist:=True; Circ.Count:=5; Circ.CircType:=ts; Circ.Ptr:=Ptr; If ptr=nil then Begin Circ.MapY:=py; Circ.MapX:=px; Circ.Width:=TileSize; Circ.Height:=TileSize; Circ.TileX:=0; Circ.TileY:=0; End else Begin If Ptr^.Id0 then Begin If xx<>nil) then MM.BtMenu[MM_Retreat].Enable:=False; End; End; MM_Yes : Begin If (MM.BtMenu[MM_Title_Retreat].Visible) or (MM.BtMenu[MM_Title_CancelAttack].Visible) then PlayerRetreat:=True; If (MM.BtMenu[MM_Title_ExitProgram].Visible) then PlayerQuit:=True; MM.MenuVisible:=False; LogicTime.Enabled:=True; End; MM_Ok : CloseApplication; End; End; End Else Begin If (Button = mbRight) and (IdxCom>0) then Begin IdxCom:=0; Exit; End; Xx:=Mos.MouseX div TileSize + AllyScreen.MapX; Yy:=Mos.MouseY div TileSize + AllyScreen.MapY; If Button = mbRight then PunchLong:=False; With Mos do Begin If Inside(MouseX,ScrX*TileSize+112,ScrX*TileSize+145) and Inside(MouseY,462,503) then RepairOn:=Not RepairOn; // repair button If Inside(MouseX,10,520) and Inside(MouseY,D1Bound+20,D1Bound+50) then // for command panel Begin IdxCom:=ReturnComPanel(Mos.MouseX); If IdxCom=2 then Begin ModiTaskToMouse(Mos,0,Tar); IdxCom:=0; End; // guard If IdxCom=5 then Begin BuildTroops(WhoAmi,0,Mos.ArrMos[1],0,0); IdxCom:=0; End; // buildtroops If IdxCom=6 then If (Mos.ArrMos[1]^.GeneralTask<>0) or (Mos.ArrMos[1]^.ActTask3=R1Bound+27 then // Corner map Begin xx:=MouseX+1-R1Bound-27; yy:=MouseY+1-20; If Xx>MapMaxX then Xx:=MapMaxX; If XxMapMaxY then Yy:=MapMaxY; If YyMapMaxX-ScrX then xx:=MapMaxX-ScrX; yy:=yy-ScrY div 2; If yyMapMaxY-scrY then yy:=MapMaxY-ScrY; AllyScreen.MapY:=yy; AllyScreen.MapX:=xx; Exit; End; End; WhoIsThere(Temp,xx,yy); If RepairOn and (Button = mbRight) then Begin RepairOn:=False; Exit; End; If RepairOn and (Temp<>nil) then Begin If (not Temp^.Moving) and (Temp^.Prior>1) then Begin Temp^.NowRepaired:=not Temp^.NowRepaired; End; Exit; End; If Button = mbLeft then // klik kiri Begin StartX:=Xx; StartY:=Yy; EndX:=Xx; EndY:=Yy; If IdxCom=0 then Begin PunchLong:=True; EmptyMos; If Temp<>nil then InsCreatureToMouse(Mos,Temp); end else Begin Tar.X:=Xx; Tar.Y:=Yy; Case IdxCom of 1 : If (Temp<>nil) and (PartTiles[Xx,Yy].Fog<>3) then Begin Tar.Ptr:=Temp; // Attack ModiTaskToMouse(Mos,1,Tar); ModiCirc(Temp,Xx,Yy,1); End; 3 : Begin // Charge Tar.Ptr:=nil; ModiTaskToMouse(Mos,5,Tar); ModiCirc(nil,XX,YY,2); End; 4 : Begin Tar.Ptr:=nil; // Move ModiTaskToMouse(Mos,2,Tar); ModiCirc(nil,XX,YY,2); End; 6 : Begin Tar.Ptr:=Nil; // Missle ModiCirc(nil,XX,YY,1); Mos.ArrMos[1]^.Bull.Ammo:=Missle[Mos.ArrMos[1]^.BelongTo].Ammo; Mos.ArrMos[1]^.Bull.Speed:=Missle[Mos.ArrMos[1]^.BelongTo].Speed; Mos.ArrMos[1]^.Bull.Power:=Missle[Mos.ArrMos[1]^.BelongTo].Power; Mos.ArrMos[1]^.Target:=Tar; Mos.ArrMos[1]^.Bull.Target:=Tar; NewSpecialBullet(Mos.ArrMos[1],Tar.X*TileSize + TileSize div 2,(Tar.Y-10)*TileSize + TileSize div 2); If Missle[Mos.ArrMos[1]^.BelongTo].Power>0 then Mos.ArrMos[1]^.GeneralTask:=1 else Missle[Mos.ArrMos[1]^.BelongTo].Counter:=Round(Missle[Mos.ArrMos[1]^.BelongTo].Counter*1.5); Mos.ArrMos[1]^.ActTask3:=0; End; End; IdxCom:=0; End; End; // 0 - guard 1 - chase attack // 2 - move 3 - retreat // 4 - special 5 - charge // 6 - Follow 7 - real attack if (Button = mbRight) And (ArrMosCount>0) and (Mos.BelongTo=WhoAmi) then // click kanan Begin Tar.X:=XX; Tar.Y:=YY; If Temp=nil then // Move ! Begin Tar.Ptr:=nil; ModiTaskToMouse(Mos,2,Tar); ModiCirc(nil,XX,YY,2); End Else Begin Tar.Ptr:=Temp; If (Temp^.BelongTo=WhoAmi) or (Temp^.BelongTo=AllySide) then Zz:=6 else Zz:=1; // zz=6 -> follow, zz=1 -> attack ModiTaskToMouse(Mos,Zz,Tar); If PartTiles[Tar.X,Tar.Y].Fog=3 then Begin Zz:=2; Temp:=Nil; End; ModiCirc(Temp,Tar.X,Tar.Y,Zz); End; End; End; // End of If in GameArea End; End; // of not MM.MenuVisible end; Function TForm1.RangeOK2Creature(T1:PObjCreature;T2:PObjCreature;R:Byte):Boolean; Begin RangeOK2Creature:= Round(sqrt(sqr(T1^.MapX-T2^.MapX)+sqr(T1^.MapY-T2^.MapY)))<=R; End; Function TForm1.RangeOK(T:PObjCreature;R:SmallInt):Boolean; Var rr : Boolean; pt:PObjCreature; Begin rr:=False; Pt:=T^.Target.Ptr; If Pt=Nil then Begin If Round(sqrt(sqr(T^.MapX-T^.Target.X)+sqr(T^.MapY-T^.Target.Y)))<=R then rr:=True else rr:=false; End Else IF Pt^.Id>DeadID then Begin If Round(sqrt(sqr(T^.MapX-Pt^.MapX)+sqr(T^.MapY-Pt^.MapY)))<=R then rr:=True else rr:=false; End; RangeOk:=rr; End; Function TForm1.Distance(x1,y1,x2,y2:SmallInt):Real; Begin Distance:=(sqrt(sqr(x2-x1)+sqr(y2-y1))); End; procedure Tform1.AirUnit_MakeRivalShoot(Ptr:Pobjcreature); Var x,y,x1,x2,y1,y2 : integer; Begin For x:=1 to MaxCreature do If AllCreature[x]<>nil then If AllCreature[x]^.Moving and (AllCreature[x]^.ClassCreature=3) and (AllCreature[x]^.BelongTo<>Ptr^.BelongTo) and (AllCreature[x]^.Bull.GroundToAir<>3) and (AllCreature[x]^.UseAs And 32 >0) and (AllCreature[x]^.GeneralTask in [0,5]) and RangeOK2Creature(Ptr,AllCreature[x],AllCreature[x]^.Bull.Range) then Begin AllCreature[x]^.Target.Ptr:=Ptr; AllCreature[x]^.Target.X:=Ptr^.MapX; AllCreature[x]^.Target.Y:=Ptr^.MapY; AllCreature[x]^.TargetChange:=True; AllCreature[x]^.GeneralTask:=1; End; x1:=Ptr^.MapX-MaxSight; if x1MapMaxX then x2:=MapMaxX; y2:=Ptr^.MapY+MaxSight; if y2>MapMaxY then y2:=MapMaxY; For y:=y1 to y2 do For x:=x1 to x2 do If Tiles[x,y]<>nil then If (Tiles[x,y]^.BelongTo<>Ptr^.BelongTo) and (Tiles[x,y]^.GeneralTask in [0,5]) and (Tiles[x,y]^.UseAs And 32 >0) and (Tiles[x,y]^.Bull.GroundToAir<>3) and RangeOK2Creature(Ptr,Tiles[x,y],Tiles[x,y]^.Bull.Range) then Begin Tiles[x,y]^.Target.Ptr:=Ptr; Tiles[x,y]^.Target.X:=Ptr^.MapX; Tiles[x,y]^.Target.Y:=Ptr^.MapY; Tiles[x,y]^.TargetChange:=True; Tiles[x,y]^.GeneralTask:=1; End; End; procedure Tform1.AirUnit_SubLogic(Var Ptr:Pobjcreature); Var x,y:Smallint; Begin With Ptr^ do Begin If Id>=9999 then // Delivery 9999 -> invisible 10000 -> visible Begin Inc(ActTask3); If SiloX[BelongTo]=0 then Begin ActTask3:=0; If Id=10000 then ActTask1:=3; End; If (ActTask3>MaxDelayDelivery) and (Id=9999) and (ActTask1=0) and (DelAppear[BelongTo]>250) then Begin DelAppear[BelongTo]:=0; ActTask3:=0; Id:=10000; Width:=MovTask1*TileSize; // replace posx Height:=MovTask2*TileSize; // replace posy ActTask1:=1; // move to silo End; If ActTask1=1 then Begin y:=Speed; if Inside(Distance(Width,Height,SiloX[BelongTo],SiloY[BelongTo]),0,20) then y:=1; If WidthSiloX[BelongTo] then Width:=Width-y; If HeightSiloY[BelongTo] then Height:=Height-y; If (Width=SiloX[BelongTo]) and (Height=SiloY[BelongTo]) then Begin ActTask1:=2; ActTask2:=0; Id:=9999; End; End; If ActTask1=2 then Begin If SourMoney[BelongTo]>40 then Begin SourMoney[BelongTo]:=SourMoney[BelongTo]-40; Money[BelongTo]:=Money[BelongTo]+40+Upgrade[BelongTo].Money; End; If SourMoney[BelongTo]=50 then Begin ActTask1:=3; Id:=10000; End; End; If ActTask1=3 then Begin y:=speed+1; if Inside(Distance(Width,Height,MovTask1*TileSize,(MovTask2+2)*TileSize),0,10) then y:=1; If WidthMovTask1*TileSize then Width:=Width-y; If Height(MovTask2+2)*TileSize then Height:=Height-y; If (Width=MovTask1*TileSize) and (Height=(MovTask2+2)*TileSize) then Begin ActTask1:=4; Id:=9999; End; End; End Else Begin ToBigMap(Ptr,False); Ptr^.MapX:=(Width+(Tilesize div 2)) div TileSize; Ptr^.MapY:=(Height+(Tilesize div 2)) div TileSize; AirAndGround_SubLogic(Ptr); AirUnit_MakeRivalShoot(Ptr); x:=(AllyScreen.MapX*TileSize); Y:=(AllyScreen.MapY*TileSize); If (BelongTo<>WhoAmI) and Inside(Mos.MouseX,Width-x,Width-x+TileSize) and Inside(Mos.MouseY,Height-y,Height-y+TileSize) then IdxP:=100; If GeneralTask=0 then // guard Begin ToBigMap(Ptr,True); If StopAirEngine then Begin Inc(PartTiles[MapX,MapY].AirUnit); StopAirEngine:=False; End; If PartTiles[MapX,MapY].AirUnit>1 then // Kalo Bertumpukan Begin x:=0; NewAirUnitPosition(Ptr,x,y); // berpencar, jangan sampai bertumpuk If x>0 then Begin Dec(PartTiles[MapX,MapY].AirUnit); StopAirEngine:=True; GeneralTask:=2; Target.Ptr:=nil; Target.X:=x; Target.Y:=y; End; End else Force:=False; ActTask1:=0; If Random(50)=0 then Begin If Random(2)=0 then Inc(BodyHeading) else Dec(BodyHeading); If BodyHeading>cLUp then BodyHeading:=cUp; If BodyHeading3 then Begin MovTask1:=0; Inc(MovTask2); If MovTask2>4 then MovTask2:=1; ActTask2:=MovTask2; If ActTask2=4 then ActTask2:=2; End; End; // 0 - guard 1 - chase attack // 2 - move 3 - retreat // 4 - special 5 - charge // 6 - Follow 7 - real attack If (GeneralTask=1) then // Kalo disuruh nembak, and dalam jangkauan ya langsung saja if RangeOk(Ptr,Bull.Range) then GeneralTask := 7; If GeneralTask = 7 then // real attack Begin If BelongTo<>WhoAmI then ExploreMap(MapX,MapY,1); ActTask1:=0; If RangeOK(Ptr,Bull.Range) then Begin // enemy is in range, then shoot him ! HeadHeading:=Heading(Ptr); BodyHeading:=HeadHeading; Inc(ActTask3); // ActTask3 -> untuk refill, kalo udah = refill and // Bull.exist then tembak !!! If (ActTask3>=Bull.ReFill) and (not Bull.Exist) then Begin // Ok, it's ok now to make out the bullet !!! ActTask3:=0; ValidTarget(Target); Bull.Target:=Target; Bull.Exist:=True; Bull.MapX:=MapX; Bull.MapY:=MapY; NewSpecialBullet(Ptr,Width+TileSize div 2,Height+TileSize div 2); End; End Else GeneralTask:=1; // enemy is over range, then chase him ! End; If GeneralTask in [1,2,5,6] then // Att, Move,charge,follow Begin If BelongTo=WhoAmi then ExploreMap(MapX,MapY,Sight); Inc(ActTask3); If ActTask3>20000 then ActTask3:=20000; // untuk refill senjata ValidTarget(Target); y:=2; x:=Round(Distance(Width,Height,Target.X*TileSize,Target.Y*TileSize)); If (GeneralTask = 1) or (MakeItGuard) then x:=x-TileSize*(Sight); Inc(ActTask1); If x 22 then Begin ActTask1:=23; y:=Speed*2 End; If x>0 then Begin If xTarget.Y*TileSize then Height:=Height-y; End Else Begin Height:=Height+Round((Target.Y*TileSize-Height)/ABS(Target.X*TileSize-Width)*y); If WidthTarget.X*TileSize then Width:=Width-y; End; End else Begin If GeneralTask=1 then GeneralTask:=7 else GeneralTask:=0; End; ToBigMap(Ptr,True); End; End; End; End; procedure Tform1.EnemyLogic; Var i,j,k,m:integer; bu,att,BuT:boolean; x1,y1,x2,y2 : Byte; MasihAda : Boolean; Function IdxRepairBuilding(Side,tipe:Byte):Integer; Var A,B:integer; Begin For A:=1 to 4 do If EnemyScreen.RepairHouse[Tipe,A]<> nil then If (EnemyScreen.RepairHouse[Tipe,A]^.Id>DeadId) and (EnemyScreen.RepairHouse[Tipe,A]^.ClassCreature in [50..59]) then for B:=1 to 4 do If EnemyScreen.RepairHouse[Tipe,A]^.OtherTarget[b]=nil then Begin IdxRepairBuilding:=A; Exit; End; IdxRepairBuilding:=0; End; Begin If AllyScreen.HomeX 4900 + Random(50) then // Equality Begin If WeAreTheInvader then PlayerRetreat:=True else EnemyRetreat:=True; End; If (CreaCount[WhoEnemy]15) and (EnemyScreen.ComCenter=nil) and ( ((EBarrack=False) and (EFactory=False) and (EAirPort=False)) or ((Money[WhoEnemy]500)) ) then EnemyRetreat:=True; If (AllyScreen.ComCenter<>nil) and ((AllyScreen.ComCenter^.Id<=DeadId) or (AllyScreen.ComCenter^.ClassCreature<>80)) then PlayerLoose:=True; If (EnemyScreen.ComCenter<>nil) and ((EnemyScreen.ComCenter^.Id<=DeadId) or (EnemyScreen.ComCenter^.ClassCreature<>80)) then EnemyLoose:=True; Att:=False; EnemyTurn:=0; If PtrAttacker<>nil then Begin if PtrAttacker^.IdRound(CreaCount[WhoAmI]*2)) or (TimeExpired > 3000) then Begin Att:=True; If (EnemyWait=0) then EnemyWait:=1; // Attack is Confirmed End Else EnemyWait:=0; If EnemyWait>0 then Inc(EnemyWait); ZZZ:=EnemyWait; Bu:=False; // build all type troops BuT:=False; // build human troops If (CreaCount[WhoEnemy]<=Round(CreaCount[WhoAmI]*2.5)) or (CreaCount[WhoEnemy]<>nil) then Bu:=True; // Build all type troops is Confirmed If (CreaCount[WhoAmI]-CreaCount[WhoEnemy]>5) or (PtrAttacker<>nil) then BuT:=True; // Build human troops is Confirmed If (Not EFactory) and (not EAirPort) then BuT:=True; // kalo factory musuh hancur, boleh buat human troops EBarrack:=False; EFactory:=False; EAirPort:=False; MasihAda:=False; For k:=1 to MaxCreature do If (AllCreature[k]<>nil) then If (AllCreature[k]^.BelongTo=WhoEnemy) then Begin If (AllCreature[k]^.Prior>1) and (AllCreature[k]^.Id>DeadID) then MasihAda:=True; If (TimeExpired > 6250) and (AllCreature[k]^.GeneralTask=0) and (AllCreature[k]^.MainTask in [10,30]) then Dec(AllCreature[k]^.MainTask,10); If (not AllCreature[k]^.Moving) and (AllCreature[k]^.CurBlood1) and (Money[AllCreature[k]^.BelongTo]>10) then AllCreature[k]^.NowRepaired:=True; If (AllCreature[k]^.Useas=66) then EFactory:=True; If (AllCreature[k]^.Useas=130) then EAirPort:=True; If (AllCreature[k]^.Moving) then Begin If (PtrAttacker<>nil) and (AllCreature[k]^.GeneralTask=0) and (AllCreature[k]^.MainTask in [0,1,10]) then Begin AllCreature[k]^.Target.X:=PtrAttacker^.MapX; // serang musuh yang menyerang markas AllCreature[k]^.Target.Y:=PtrAttacker^.MapY; AllCreature[k]^.Target.Ptr:=Nil; If AllCreature[k]^.Classcreature<>3 then AllCreature[k]^.GeneralTask:=5 else Begin AllCreature[k]^.GeneralTask:=1; AllCreature[k]^.Target.Ptr:=PtrAttacker; End; End; If (AllCreature[k]^.GeneralTask=0) and (AllCreature[k]^.MainTask in [0,1,10]) and (AllCreature[k]^.CurBlood100) then // pergi ke tempat repair Begin i:=IdxRepairBuilding(AllCreature[k]^.BelongTo,AllCreature[k]^.ClassCreature); If i>0 then Begin AllCreature[k]^.Target.PrevX:=AllCreature[k]^.MapX; AllCreature[k]^.Target.PrevY:=AllCreature[k]^.MapY; AllCreature[k]^.Target.X:=EnemyScreen.RepairHouse[AllCreature[k]^.ClassCreature,i]^.MapX; AllCreature[k]^.Target.Y:=EnemyScreen.RepairHouse[AllCreature[k]^.ClassCreature,i]^.MapY; AllCreature[k]^.Target.Ptr:=Tiles[AllCreature[k]^.Target.X,AllCreature[k]^.Target.Y]; AllCreature[k]^.GeneralTask:=5; Inc(AllCreature[k]^.MainTask,20); If EnemyWait in [1..115] then EnemyWait:=1; End; End; If (AllCreature[k]^.GeneralTask=0) and (AllCreature[k]^.MainTask>=20) Then Begin If (AllCreature[k]^.CurBlood>=AllCreature[k]^.MaxBlood) or (Money[AllCreature[k]^.BelongTo]100) and (not AllCreature[k]^.NowRepaired)) then Begin AllCreature[k]^.Target.X:=AllCreature[k]^.Target.PrevX; AllCreature[k]^.Target.Y:=AllCreature[k]^.Target.PrevY; AllCreature[k]^.Target.Ptr:=Nil; AllCreature[k]^.GeneralTask:=5; Dec(AllCreature[k]^.MainTask,20); // cancel repair if low resources or well repaired End; End; If AllCreature[k]^.GeneralTask in [1,7] then // cek yang ditembak jangan wall If AllCreature[k]^.Target.Ptr^.PriorMaxEnemyWait+60) and (AllCreature[k]^.MainTaskMaxEnemyWait) and (AllCreature[k]^.MainTask=1) and (AllCreature[k]^.GeneralTask=0)) or (not Att and (AllCreature[k]^.MainTask=2) and (distance(x2,y2,AllCreature[k]^.MapX,AllCreature[k]^.MapY)>5)) Then Begin // menentukan tempat strategis untuk enemy berkumpul II ( menyerang ) AllCreature[k]^.Target.X:=x2; AllCreature[k]^.Target.Y:=y2; AllCreature[k]^.Target.Ptr:=Nil; // berkumpul dulu di tempat Kedua AllCreature[k]^.GeneralTask:=5; AllCreature[k]^.MainTask:=2; End; If ((AllCreature[k]^.MainTask=0) and (AllCreature[k]^.GeneralTask=0)) or ((EnemyWait mod 15 = 5) and (AllCreature[k]^.MainTask=1) and (AllCreature[k]^.GeneralTask=0) and Inside(AllCreature[k]^.MapX,EnemyScreen.HomeX-5,EnemyScreen.HomeX+EnemyScreen.Width+4) and Inside(AllCreature[k]^.MapY,EnemyScreen.HomeY-5,EnemyScreen.HomeY+EnemyScreen.Height+4)) Then Begin // menentukan tempat strategis untuk enemy berkumpul I ( menyerang ) AllCreature[k]^.Target.X:=x1; AllCreature[k]^.Target.Y:=y1; AllCreature[k]^.Target.Ptr:=Nil; // berkumpul dulu di tempat pertama AllCreature[k]^.GeneralTask:=5; AllCreature[k]^.MainTask:=1; End; If (AllCreature[k]^.MainTask in [3..5]) and (AllCreature[k]^.GeneralTask=0) and (EnemyWait mod 2=0) then Begin If (PtrTarget<>nil) then if (PtrTarget^.Id<>nil) then // serang kalo sudah ngumpul Begin AllCreature[k]^.Target.X:=PtrTarget^.MapX; AllCreature[k]^.Target.Y:=PtrTarget^.MapY; AllCreature[k]^.Target.Ptr:=PtrTarget; if random(5)>0 then AllCreature[k]^.GeneralTask:=5 // charge else AllCreature[k]^.GeneralTask:=1; // attack if AllCreature[k]^.ClassCreature=3 then AllCreature[k]^.GeneralTask:=1; AllCreature[k]^.MainTask:=3; AllCreature[k]^.TargetChange:=True; AllCreature[k]^.Force:=False; End; End; End; End Else Begin If (PtrTargetUnit<>nil) then if (PtrTargetUnit^.Id<>nil) and (AllCreature[k]^.GeneralTask=0) and (AllCreature[k]^.ActTask3>=Missle[AllCreature[k]^.BelongTo].Counter) and (Missle[AllCreature[k]^.BelongTo].Power>0) then // missile Begin AllCreature[k]^.Bull.Ammo:=Missle[AllCreature[k]^.BelongTo].Ammo; AllCreature[k]^.Bull.Speed:=Missle[AllCreature[k]^.BelongTo].Speed; AllCreature[k]^.Bull.Power:=Missle[AllCreature[k]^.BelongTo].Power; AllCreature[k]^.Target.Ptr:=Nil; AllCreature[k]^.Target.X:=PtrTargetUnit^.MapX; AllCreature[k]^.Target.Y:=PtrTargetUnit^.MapY; AllCreature[k]^.Bull.Target:=AllCreature[k]^.Target; NewSpecialBullet(AllCreature[k],PtrTargetUnit^.MapX*TileSize + TileSize div 2, PtrTargetUnit^.MapY-(Random(20)+10)*TileSize + TileSize div 2); AllCreature[k]^.GeneralTask:=1; AllCreature[k]^.ActTask3:=0; End; If Bu and (AllCreature[k]^.Useas in [2,66,130]) and (AllCreature[k]^.BelongTo=WhoEnemy) and (AllCreature[k]^.GeneralTask=0) then // buat troops Begin If (AllCreature[k]^.UseAs=2) and BuT and (Random(3)=0) then // buat on foot unit Begin j:=1; For i:=9 downto 1 do If (CmdBuild[WhoEnemy,1].Oke[i]) and (Random(3)>0) then Begin j:=i; Break; End; BuildTroops(WhoEnemy,CmdBuild[WhoEnemy,1].isi[j],AllCreature[k],CmdBuild[WhoEnemy,1].speed[j],CmdBuild[WhoEnemy,1].Price[j]); End Else If (AllCreature[k]^.UseAs in [66,130]) then // make tank unit Begin If AllCreature[k]^.UseAs=66 then m:=2 else m:=3; j:=1; For i:=9 downto 1 do If (CmdBuild[WhoEnemy,m].Oke[i]) and (Random(3)>0) then Begin j:=i; Break; End; BuildTroops(WhoEnemy,CmdBuild[WhoEnemy,m].isi[j],AllCreature[k],CmdBuild[WhoEnemy,m].speed[j],CmdBuild[WhoEnemy,m].Price[j]); End; End; End; End; If not MasihAda then EnemyLoose:=True; End; Procedure TForm1.ValidTarget(Var TG:TTarget); Begin If Tg.Ptr<>nil then if TG.Ptr^.Id>DeadID then Begin TG.X:=TG.Ptr^.MapX; TG.Y:=TG.Ptr^.MapY; End; End; Procedure TForm1.CheckNear(Var Ptr:PObjCreature); var s,xx,yy,x,y:integer; Prior: Byte; RPtr,PtrTemp : PObjCreature; Mt : Array [0..MaxTask] of Byte; TG : TTarget; Procedure CheckUnit(rx,ry:integer;ptr:PObjCreature); Begin If Inside(rx,1,mapmaxX) and Inside(ry,1,mapmaxY) and (Tiles[rx,ry]<>nil) then If (Tiles[rx,ry]^.Id>DeadID) then Begin If (Tiles[rx,ry]^.BelongTo<>Ptr^.BelongTo) and not ((Tiles[rx,ry]^.ClassCreature<>3) and (Ptr^.Bull.GroundToAir=1)) // not (sasaran=ground unit and kita tidak bisa nembak ground unit ) then // utk musuh biasa yang terlihat Begin if RangeOk2Creature(Ptr,Tiles[rx,ry],Ptr^.Sight) then if prior<>Ptr^.BelongTo) and // yang menyerang dari kubu lain not ((Tiles[rx,ry]^.Target.Ptr^.ClassCreature=3) and (Ptr^.Bull.GroundToAir=3)) and // not (yang menyerang=pesawat and kita tidak bisa nembak pesawat ) not ((Tiles[rx,ry]^.Target.Ptr^.ClassCreature<>3) and (Ptr^.Bull.GroundToAir=1)) // not (yang menyerang=ground unit and kita tidak bisa nembak ground unit ) then Begin RPtr:=Tiles[rx,ry]^.Target.Ptr; Prior:=Tiles[rx,ry]^.Target.Ptr^.Prior; ForceToFlip:=True; end; End; End; begin // ****************** Isi Check Near prior:=0; x:=Ptr^.MapX; y:=Ptr^.MapY; for s:=1 to Ptr^.Sight do Begin For xx:=x-s to x+s do begin checkunit(xx,y-s,ptr); checkunit(xx,y+s,ptr); End; For yy:=y-s+1 to y+s-1 do begin checkunit(x-s,yy,ptr); checkunit(x+s,yy,ptr); end; End; If ((Prior=1) and (Ptr^.BelongTo=WhoAmI)) or (Prior=0) then exit; /// ????????????????????????????????/ If ForceToFlip and not RangeOk2Creature(Ptr,RPtr,Ptr^.Bull.Range) then Begin PtrTemp:=Tiles[RPtr^.MapX,RPtr^.MapY]; Tiles[RPtr^.MapX,RPtr^.MapY]:=Nil; Move(Ptr^.MovingTask,MT,SizeOf(MT)); TG:=Ptr^.Target; Ptr^.Target.Ptr:=Nil; Ptr^.Target.X:=RPtr^.MapX; Ptr^.Target.Y:=RPtr^.MapY; If CariPath(Ptr,Ptr^.Bull.Range,PathTile,40) then Begin Ptr^.Target.Ptr:=RPtr; Ptr^.TargetChange:=True; Ptr^.GeneralTask:=1; End Else Ptr^.Target:=TG; Move(MT,Ptr^.MovingTask,SizeOf(MT)); Tiles[RPtr^.MapX,RPtr^.MapY]:=PtrTemp; End Else Begin Ptr^.Target.Ptr:=RPtr; Ptr^.Target.X:=RPtr^.MapX; Ptr^.Target.Y:=RPtr^.MapY; Ptr^.TargetChange:=True; Ptr^.GeneralTask:=1; End; End; Procedure TForm1.Building_SubLogic(Var Ptr:PObjCreature); Var i,x,y : integer; Begin If Ptr^.ClassCreature in [50..59] then // building with repairing troop ability Begin For i:=1 to 4 do If Ptr^.OtherTarget[i]<>nil then // hapus othertarget yang tidak mungkin lagi Begin If not(Inside(Ptr^.OtherTarget[i]^.MapX,Ptr^.MapX-2,Ptr^.MapX+3) and Inside(Ptr^.OtherTarget[i]^.MapY,Ptr^.MapY-2,Ptr^.MapY+3)) then Begin Ptr^.OtherTarget[i]^.NowRepaired:=False; Ptr^.OtherTarget[i]:=nil; Continue; End; If Ptr^.OtherTarget[i]^.Id=Ptr^.OtherTarget[i]^.MaxBlood then Begin Ptr^.OtherTarget[i]^.NowRepaired:=False; Ptr^.OtherTarget[i]:=nil; Continue; End; End; For i:=1 to 4 do If Ptr^.OtherTarget[i]=nil then // cari othertarget yang baru jika nil For y:=Ptr^.MapY-2 to Ptr^.MapY+3 do For x:=Ptr^.MapX-2 to Ptr^.MapX+3 do If Ptr^.OtherTarget[i]=nil then If (x in [MapMinX..MapMaxX]) and (y in [MapMinY..MapMaxY]) then If Tiles[x,y]<>nil then If (Tiles[x,y]^.BelongTo=Ptr^.BelongTo) and (not Tiles[x,y]^.NowRepaired) and (Tiles[x,y]^.ClassCreature=Ptr^.ClassCreature-50) and (Tiles[x,y]^.CurBloodDeadId+1) and not ((Tiles[x,y]^.BelongTo<>Ptr^.BelongTo) and (Tiles[x,y]^.MainTaskMissle[Ptr^.BelongTo].Counter then Ptr^.ActTask3:=Missle[Ptr^.BelongTo].Counter; End; End; Procedure TForm1.AirAndGround_SubLogic(Var Ptr:PObjCreature); Begin If ((Ptr^.GeneralTask=0) or (Ptr^.GeneralTask=5)) then // guard and charge CheckNear(Ptr); If Ptr^.Target.Ptr<>nil then // remove dead target or delivery from target If (Ptr^.Target.Ptr^.Id<>7 then Ptr^.MakeItGuard:=True else Begin Ptr^.GeneralTask:=0; Ptr^.MovTask2:=0; Ptr^.ActTask2:=0; Ptr^.ActTask1:=0; End; End; If Ptr^.GeneralTask in [1,6] then // menghindari tembak diri sendiri if (Ptr^.Target.Ptr=Ptr) or (Ptr^.MakeItGuard) then Ptr^.GeneralTask:=2; If (Ptr^.GeneralTask=7) and (Ptr^.MakeItGuard) then Begin Ptr^.GeneralTask:=0; Ptr^.ActTask2:=0; End; // guard untuk real attack If (Ptr^.TypeCreature=255) then // untuk turret, jangan sampe move, charge, dll Begin If not (Ptr^.GeneralTask in [0,1,7]) then Ptr^.GeneralTask:=0; If Ptr<>nil then if not RangeOK(Ptr,Ptr^.Bull.Range) then Ptr^.GeneralTask:=0; End; End; procedure TForm1.Timer_MainLogic(Sender: TObject); Var i,j,x,y,cx1,cy1,EnemyTarget,EnemyTargetUnit : SmallInt; Ptr : PObjCreature; Oke : Boolean; h,m,s1,m1,s2,m2:word; Begin LogicTime.Interval:=100; If MM.MenuVisible then Exit; If Mos.DelayMouse=0 then Begin DecodeTime(Now,h,m,s1,m1); Inc(EnemyTurn); Inc(OtherTime); If (EnemyTurn>6) then EnemyLogic; If (OtherTime>100) then OtherTime:=0; If OtherTime mod 10 = 0 then For j:=1 to MaxMosGroup do For i:=1 to 10 do If MosGroup[j].ArrMos[i]<>nil then if MosGroup[j].ArrMos[i]^.ID<>nil then Begin If ArrMos[i]^.Id>DeadID then Inc(ArrMosCount) else ArrMos[i]:=nil; If (ArrMos[1]=nil) and (ArrMos[i]<>nil) then Begin ArrMos[1]:=ArrMos[i]; ArrMos[i]:=nil; End; End; End; Mos:=MosGroup[MaxMosGroup+1]; PtrTargetUnit:=Nil; EnemyTargetUnit:=0; PtrTarget:=Nil; EnemyTarget:=0; IdxP:=0; for i:=1 to MaxCreature do if AllCreature[i]<>nil then If Inside(AllCreature[i]^.Id,1,DeadID) then Begin AllCreature[i]^.NowRepaired:=False; Dec(AllCreature[i]^.Id); // dispose dead body slowly ... If AllCreature[i]^.Id<>3 then Tiles[AllCreature[i]^.MapX,AllCreature[i]^.MapY]:=nil; End Else Begin Ptr:=AllCreature[i]; If (Ptr^.Id>=9900) then AirUnit_SubLogic(Ptr); // Logic pesawat terbang If (Ptr^.Id>DeadID) and (not Ptr^.Moving) then // Logic untuk building Building_SubLogic(Ptr); If (Ptr^.BelongTo=WhoAmi) and (EnemyTargetDeadID) then Begin PtrTarget:=Ptr; // cari sasaran untuk musuh EnemyTarget:=Ptr^.Prior; End; If (Ptr^.BelongTo=WhoAmi) and (EnemyTargetUnitDeadID) and (Ptr^.Moving) then Begin // cari sasaran untuk musuh khusus troops j:=0; For y:=Ptr^.MapY-3 to Ptr^.MapY+3 do // apakah mengelompok atau tidak For x:=Ptr^.MapX-3 to Ptr^.MapX+3 do If (MapMinX<=x) and (x<=MapMaxX) and (MapMinY<=y) and (y<=MapMaxY) then if (Tiles[x,y]<>nil) and (Tiles[x,y]^.Id>DeadID) and (Tiles[x,y]^.Moving) and (Tiles[x,y]^.BelongTo<>WhoEnemy) then j:=j+Tiles[x,y]^.Prior; If j>=110 then Begin PtrTargetUnit:=Ptr; EnemyTargetUnit:=Ptr^.Prior; End; End; If (Ptr^.CurBlood>=Ptr^.MaxBlood) then Ptr^.NowRepaired:=False; If (OtherTime mod 20=0) and (Ptr^.Moving) and (Ptr^.Infinite.PoisonCtr>0) then Begin Dec(Ptr^.Infinite.PoisonCtr); If Ptr^.CurBlood>=Ptr^.Infinite.PoisonPower then Ptr^.CurBlood:=Ptr^.CurBlood-Ptr^.Infinite.PoisonPower; If Ptr^.CurBlood=Ptr^.MaxBlood) then Ptr^.NowRepaired:=False else Begin Inc(Ptr^.CurBlood); Dec(Money[Ptr^.BelongTo],Ptr^.Armor div 2); If not Ptr^.ClassCreature > 1 then Dec(Money[Ptr^.BelongTo],2); If not Ptr^.Moving then Dec(Money[Ptr^.BelongTo]); End; End; // **************** Bellow are logic statements for actions, like guard, move, charge, etc. If ( ((Ptr^.Moving) and (Ptr^.TypeCreatureDeadID) then Begin If (Ptr^.BelongTo=WhoAmi) then ExploreMap(Ptr^.MapX,Ptr^.MapY,Ptr^.Sight); AirAndGround_SubLogic(Ptr); If Ptr^.GeneralTask=0 then // Guard Begin Ptr^.MakeItGuard:=False; Ptr^.Force:=False; Inc(Ptr^.MovTask1); If Ptr^.MovTask1>Random(20)+35 then Begin Ptr^.MovTask1:=0; If Random(2)=0 then Inc(Ptr^.HeadHeading) else Dec(Ptr^.HeadHeading); If Ptr^.HeadHeading>cLUp then Ptr^.HeadHeading:=cUp; If Ptr^.HeadHeading<>3) and (Ptr^.Bull.GroundToAir=1))) then Begin Ptr^.GeneralTask:=0; Ptr^.ActTask2:=0; End; If Ptr^.GeneralTask = 7 then // real attack Begin If Ptr^.BelongTo<>WhoAmI then ExploreMap(Ptr^.MapX,Ptr^.MapY,1); If Ptr^.MainTask>19 then Dec(Ptr^.MainTask,20); If RangeOK(Ptr,Ptr^.Bull.Range) then With Ptr^ do Begin // enemy is in range, then shoot him ! If TypeCreature in [1,3] then Begin HeadHeading:=Heading(Ptr); BodyHeading:=HeadHeading; End; If (TypeCreature in [2,255]) and (HeadHeading<>Heading(Ptr)) then Begin // kalo tank HeadHeading:=HeadHeading+ShortHeading(Ptr,HeadHeading); // and heading<>sesungguhnya If HeadHeading7 then HeadHeading:=0; end else Begin // Heading is ok, ready to shoot ActTask2:=3; // untuk idx troop Inc(ActTask3); // ActTask3 -> untuk refill, kalo udah = refill and // Bull.exist then tembak !!! If (ActTask3>=Bull.ReFill) and (not Bull.Exist) then Begin // Ok, it's ok now to make out the bullet !!! ActTask3:=0; ValidTarget(Ptr^.Target); Ptr^.Bull.Target:=Ptr^.Target; Bull.Exist:=True; Bull.MapX:=MapX; Bull.MapY:=MapY; Bull.Ellapsed:=0; case Bull.Ammo of 1:Bull.Loops:=4; 2:Bull.Loops:=8; 3:Bull.Loops:=2; else If Bull.Ammo>9 then Begin NewSpecialBullet(Ptr,Ptr^.MapX*TileSize+Ptr^.TileX+Ptr^.Width div 2, Ptr^.MapY*TileSize+Ptr^.TileX+Ptr^.Height div 2); End; End; // end of case End; // of if End; End Else Begin // enemy is over range, then chase him ! Ptr^.GeneralTask:=1; Ptr^.MovTask2:=0; Ptr^.ActTask1:=0; Ptr^.ActTask2:=0; If Ptr^.TypeCreature=255 then Ptr^.GeneralTask:=0; // don't make turret chase !!! End; End; If Ptr^.GeneralTask in [1,2,5,6] then with Ptr^ do // attack, walk, charge, and follow Begin cx1:=0; If TypeCreature=2 then cx1:=Heading(Ptr); // typecreature = 2 If (TypeCreature=2) and (BodyHeading<>cx1) and // means the creature is a tank, (BodyHeading+4<>cx1) and (BodyHeading<>cx1+4) and // so its body must rotate to (MovTask2=0) and (not TargetChange) then // destination Begin BodyHeading:=BodyHeading+ShortHeading(Ptr,BodyHeading); If BodyHeading7 then BodyHeading:=0; end else Begin Inc(ActTask3); If ActTask3>25000 then ActTask3:=25000; // sambil jalan refill senjata If TypeCreature in [1,3] then Begin Inc(MovingTask[0]); if(MovingTask[0])>3 then MovingTask[0]:=0; Case MovingTask[0] of // idx jalan untuk troops 0 : ActTask2:=0; 1 : ActTask2:=1; 2 : ActTask2:=0; 3 : ActTask2:=2; End; End; If TypeCreature=2 then Begin HeadHeading:=HeadHeading+ShortHeading(Ptr,HeadHeading); If HeadHeading7 then HeadHeading:=0; End; If MovTask2=0 then // first time to move Begin ActTask1:=Speed-1; ValidTarget(Ptr^.Target); If GeneralTask>1 then CariPath(Ptr,1,PathTile,MaxSquare) else CariPath(Ptr,Bull.Range,PathTile,MaxSquare); TargetChange:=False; TileX:=TileX2; TileY:=TileY2; End; Inc(ActTask1); If ActTask1>=Speed then // sudah walk 1 langkah Begin ActTask1:=0; Inc(MovTask2); If GeneralTask=6 then if RangeOk(Ptr,1) then MovingTask[MovTask2]:=9; If GeneralTask=1 then if RangeOk(Ptr,Bull.Range) then MovingTask[MovTask2]:=9; If (MovingTask[MovTask2])<=CLUp then Begin BodyHeading:=MovingTask[MovTask2]; If TypeCreature in [1,3] then HeadHeading:=BodyHeading; ToBigMap(Tiles[MapX,MapY],False); Tiles[MapX,MapY]:=nil; cx1:=0; cy1:=0; Case (MovingTask[MovTask2]) of CUp : cy1:=-1; CRight: cx1:=1; CLeft : cx1:=-1; CDown : cy1:=1; CRUp : Begin cx1:=1; cy1:=-1; End; CLUp : Begin cx1:=-1;cy1:=-1; End; CRDown: Begin cx1:=1; cy1:=1; End; CLDown: Begin cx1:=-1;cy1:=1; End; End; If (Tiles[MapX+Cx1,MapY+Cy1]<>nil) or TargetChange then Begin TargetChange:=True; MovTask2:=0; ActTask1:=Speed; TileX:=TileX2; TileY:=TileY2; If MakeItGuard then Begin MakeItGuard:=False; GeneralTask:=0; ActTask2:=0; ActTask1:=0; End; end else Begin MapX:=MapX+Cx1; MapY:=MapY+Cy1; TileX:=TileX2-(Cx1*TileSize); TileY:=TileY2-(Cy1*TileSize); end; Tiles[MapX,MapY]:=Ptr; ToBigMap(Tiles[MapX,MapY],True); End Else // if MovingTask[MovTask2])>CLUp Begin // berarti path sudah berakhir j:=GeneralTask; GeneralTask:=0; ValidTarget(Ptr^.Target); case j of 1 : Begin GeneralTask:=7; // real attack Oke:=CariPath(Ptr,Bull.Range,PathTile,MaxSquare); If Not RangeOK(Ptr,Bull.Range) then Begin If Oke then GeneralTask:=1 else GeneralTask:=0; End; End; 2,5,6 : If Not RangeOK(Ptr,1) and CariPath(Ptr,1,PathTile,MaxSquare) then GeneralTask:=j; End; ActTask1:=0; ActTask2:=0; MovTask2:=0; TileX:=TileX2; TileY:=TileY2; End; End; If (MovingTask[MovTask2]<=CLUp) and (GeneralTask in [1,2,5,6]) and (MovTask2>0) then Case (MovingTask[MovTask2]) of CUp : TileY:=(TileY2+TileSize)-Round(TileSize*ActTask1/speed); CRight: TileX:=(TileX2-TileSize)+Round(TileSize*ActTask1/speed); CLeft : TileX:=(TileX2+TileSize)-Round(TileSize*ActTask1/speed); CDown : TileY:=(TileY2-TileSize)+Round(TileSize*ActTask1/speed); CRUp : Begin TileY:=(TileY2+TileSize)-Round(TileSize*ActTask1/speed); TileX:=(TileX2-TileSize)+Round(TileSize*ActTask1/speed); End; CLUp : Begin TileY:=(TileY2+TileSize)-Round(TileSize*ActTask1/speed); TileX:=(TileX2+TileSize)-Round(TileSize*ActTask1/speed); End; CRDown: Begin TileY:=(TileY2-TileSize)+Round(TileSize*ActTask1/speed); TileX:=(TileX2-TileSize)+Round(TileSize*ActTask1/speed); End; CLDown: Begin TileY:=(TileY2-TileSize)+Round(TileSize*ActTask1/speed); TileX:=(TileX2+TileSize)-Round(TileSize*ActTask1/speed); End; End; If ActTask1>=Speed then ActTask1:=0; End; End; // End of If GeneralTask=1,2,5,6 End; // End of if Creature moving or turret End; // End of for BigMap.Map.Canvas.Release; BigMap.ShadowMap.Canvas.Release; If EnemyTarget untuk berputar ( counter kalo udah 15 kali, putar kepala ) // movtask2 -> indikasi untuk path, path ke berapa yan sedang di // jalankan, bila 0 berarti belum digenerate path, harus generate // dulu... // ActTask1 -> untuk berjalan, kalo udah >= speed then berjalan // ActTask2 -> idx untuk picture // ActTask3 -> utk refill peluru Function TForm1.CariPath(Var Who:PObjCreature;Rn:SmallInt;PathTile:TPath;MaxIterasi:SmallInt):Boolean; type recs = record x,y:byte; end; Var x,y,i,j,k,xx,yy,zz,dx,dy : SmallInt; Til31 : Array[0..MaxSquare] of recs; Til32 : Array[0..MaxSquare] of recs; CTil31 : SmallInt; CTil32 : SmallInt; MovingTask : Array[0..MaxSquare] of byte; NotBerhasil, PrevNotBerhasil : Boolean; Iterasi : Byte; Mul,Akhir : TTarget; PTemp : PObjCreature; Function OkBack(qq,ww:SmallInt):Boolean; Begin OkBack:=(MapMinX<=qq) and (qq<=MapMaxX) and (MapMinY<=ww) and (ww<=MapMaxY); End; Procedure Square(a,b,c:SmallInt); Function Ok(d,e:SmallInt):Boolean; Begin If OkBack(d,e) and (PathTile[d,e]=SoilFlag) and (PartTiles[d,e].Soil in [1..3,31,32,21..24,38,39]) and (Tiles[d,e]=nil) and (not PartTiles[d,e].Ok) then Begin Til32[CTil32].X:=d;Til32[CTil32].Y:=e; Inc(CTil32); If CTil32<>nil) or (PartTiles[Akhir.X,Akhir.Y].Ok) then Begin iterasi:=1; zz:=1; xx:=Akhir.X+1; yy:=Akhir.y; Repeat Case zz of 1 : Begin Dec(yy); if yy=Akhir.Y-iterasi then inc(zz); End; 2 : Begin Dec(xx); if xx=Akhir.X-iterasi then inc(zz); End; 3 : Begin Inc(yy); if yy=Akhir.Y+iterasi then inc(zz); End; 4 : Begin Inc(xx); if xx=Akhir.X+iterasi then Begin zz:=1; Inc(Iterasi) End; End; End; Until OkBack(xx,yy) and (Tiles[xx,yy]=nil) and (not PartTiles[xx,yy].Ok) and (PartTiles[xx,yy].Soil in [1..3,31,32,21..24,38,39]); If Iterasi>1 then PrevNotBerhasil:=True; Akhir.x:=Xx; Akhir.Y:=Yy; End; End; If Not((Akhir.X=Mul.X) and (Akhir.Y=Mul.Y)) then Begin i:=0; PathTile[Akhir.X,Akhir.Y]:=SoilFlag; PathTile[Mul.X,Mul.Y]:=0; CTil31:=0; CTil32:=0; Til31[0].X:=Mul.X; Til31[0].Y:=Mul.Y; PTemp:=Tiles[Akhir.X,Akhir.Y]; Iterasi:=0; Repeat Inc(Iterasi); If Iterasi>200 then Iterasi:=200; NotBerhasil:=True; For j:=0 to Ctil31 do Square(Til31[j].X,Til31[j].Y,i); CTil31:=CTil32; CTil32:=0; Move(Til32,Til31,2*CTil31); Inc(i); If CTil31<>SoilFlag) or NotBerhasil; If (((Iterasi=1) or RangeOk(Who,Rn)) And NotBerhasil) or ((MaxIterasi<>nil then if PTemp^.TypeCreature=20 then Begin PathTile[Akhir.X+1,Akhir.Y]:=SoilFlag; PathTile[Akhir.X,Akhir.Y+1]:=SoilFlag; PathTile[Akhir.X+1,Akhir.Y+1]:=SoilFlag; k:=1; End; Repeat y:=Akhir.Y-i; if y<>SoilFlag then If PathTile[x,y]MapMaxX then X:=MapMaxX; If PathTile[x,y]<>SoilFlag then If PathTile[x,y]MapMaxY); x:=Akhir.X-i; if X<>SoilFlag then If PathTile[x,y]MapMaxY then y:=MapMaxY; If PathTile[x,y]<>SoilFlag then If PathTile[x,y]MapMaxX); i:=i+1; Until (zz0 then Begin Repeat Dec(i); BackTrack(X,Y,i); Until i=0; End; Move(MovingTask,Who^.MovingTask,SizeOf(Who^.MovingTask)); Who^.MovingTask[MaxTask]:=9; ResultX:=Akhir.X; ResultY:=Akhir.Y; If NotBerhasil and (j=0) then CariPath:=false else CariPath:=true; If PrevNotBerhasil then CariPath:=false; End Else Begin // pos mul = pos akhir Who^.MovingTask[0]:=0; Who^.MovingTask[1]:=9; CariPath:=False; End; End; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Var i,j:SmallInt; flag:boolean; begin If Punchlong and not MM.MenuVisible then With mos do Begin Flag:=False; PunchLong:=False; If StartX>EndX then SwapValue(StartX,EndX); If StartY>EndY then SwapValue(StartY,EndY); For j:=1 to MaxCreature do If AllCreature[j]<>nil then if Inside(AllCreature[j]^.Id,9900,9998) and (AllCreature[j]^.BelongTo=WhoAmi) and (ArrMosCount<>Nil) and not Flag then Begin EmptyMos; InsCreatureToMouse(Mos,PartTiles[EndX,EndY].Ptr); Exit; End; If (StartX-EndX<>0) or (StartY-EndY<>0) then Begin If not Flag then EmptyMos; For j:=StartY to EndY do For i:=StartX to EndX do If (Tiles[i,j]<>nil) and (ArrMosCount<>nil then Mos.ArrMos[j]^.Active:=false; End; Procedure ShMouse; Var j:SmallInt; Begin IdxCom:=0; Mos.UseAs:=$ff; Mos.ArrMosCount:=0; for j:=1 to MaxMosCount do If Mos.ArrMos[j]<>nil then Begin If Mos.ArrMos[j]^.Id>DeadID then Begin Mos.UseAs:=Mos.UseAs And Mos.ArrMos[j]^.UseAs; Mos.ArrMos[j]^.Active:=true; Inc(Mos.ArrMosCount); End ELse Mos.ArrMos[j]:=Nil; End; End; begin If Key=27 then If IdxCom>0 then IdxCom:=0 Else If RepairOn then RepairOn:=False Else Begin MM.MenuVisible:=Not MM.MenuVisible; BuildTimer.Enabled:=not MM.MenuVisible; LogicTime.Enabled:=not MM.MenuVisible; If MM.MenuVisible then Begin For xx:=1 to 30 do Begin MM.BtMenu[xx].Visible:=False; MM.BtMenu[xx].Enable:=True; End; MM.BtMenu[1].Visible:=True; MM.BtMenu[3].Visible:=True; MM.BtMenu[3].Enable:=True; MM.BtMenu[21].Enable:=False; If WeAreTheInvader then Begin MM.BtMenu[MM_CancelAttack].Visible:=True; MM.BtMenu[MM_CancelAttack].Enable:=True; End; If not WeAreTheInvader then Begin MM.BtMenu[MM_Retreat].Visible:=True; MM.BtMenu[MM_Retreat].Enable:=True; If (AllyScreen.ComCenter<>nil) then MM.BtMenu[MM_Retreat].Enable:=False; End; End; End; If Not MM.MenuVisible then Begin { If Key=13 then Begin CloseApplication; Exit; End;} If (ssCtrl in shift) or (ssShift in shift) or (ssAlt in shift) then Begin If (ssCtrl in shift) and inside(key,49,49-1+MaxMosGroup) then Begin HdMouse; Move(Mos.ArrMos,MosGroup[key-48].ArrMos,sizeof(Mos.ArrMos)); MosGroup[key-48].ArrMos:=Mos.ArrMos; ShMouse; End; If (ssCtrl in shift) and inside(key,112,112-1+MaxCamera) then Begin AllyScreen.CameraX[Key-111]:=AllyScreen.MapX; AllyScreen.CameraY[Key-111]:=AllyScreen.MapY; End; If (ssCtrl in shift) and ((key=65) or (key=97)) then Begin EmptyMos; For xx:=1 to MaxCreature do If AllCreature[xx]<>nil then if Inside(AllCreature[xx]^.Id,9900,9998) and (AllCreature[xx]^.BelongTo=WhoAmi) and (Mos.ArrMosCount<>nil) and (Mos.ArrMosCount<>nil then Begin If Ptr^.BelongTo=WhoAmi then Ptr^.BelongTo:=EnemySide else Ptr^.BelongTo:=WhoAmi; End; end; 69,101: begin // tekan 'E' utk Detail Debuger ... Xx:=(Mos.MouseX) div TileSize + AllyScreen.MapX; Yy:=(Mos.MouseY) div TileSize + AllyScreen.MapY; Ptr:=Nil; WhoIsThere(Ptr,Xx,Yy); If Ptr<>nil then PtrZZZ:=Ptr; end; 72,104: Debugers:=not Debugers; // tekan 'H' utk toggle debuger... 78,110: Begin For yy:=0 to MapMaxY+1 do // explore all map For xx:=0 to MapMaxX+1 do PartTiles[xx,yy].Fog:=0; BigMap.ShadowMap.Canvas.Brush.Color:=0; BigMap.ShadowMap.Canvas.FillRect(Rect(0,0,MapMaxX,MapMaxY)); BigMap.ShadowMap.Canvas.Release; End; // ************************************** 82,114: RepairOn:=not RepairOn; // tekan 'R' utk toggle Repair button... 70,102: {f6} Begin IdxCom:=ReturnComPanel(84*5); If IdxCom>0 then If (Mos.ArrMos[1]^.GeneralTask<>0) or (Mos.ArrMos[1]^.ActTask31 then TrueHeading:=2 else TrueHeading:=6; Exit; End; if inside(z,0.41,2.41) then Begin If x>1 then TrueHeading:=3 else TrueHeading:=7; Exit; End; if inside(z,-2.41,-0.41) then Begin If x>1 then TrueHeading:=1 else TrueHeading:=5; Exit; End; If y>1 then TrueHeading:=4 else TrueHeading:=0; End; function TForm1.Heading(Who:PObjCreature):Byte; Var x,y: SmallInt; Begin if Who^.Target.Ptr=nil then Begin x:=(Who^.Target.X)*TileSize + TileSize div 2; y:=(Who^.Target.Y)*TileSize + TileSize div 2; End Else Begin If Who^.Target.Ptr^.Id<>z do Begin Inc(w); if w>CLUp then w:=CUp; Inc(x); End; w:=Hd; y:=0; While w<>z do Begin Dec(w); if w<>20 then z:=0 else z:=1; If Who^.ClassCreature=3 then Begin If (PartTiles[Who^.MapX,Who^.MapY].Fog=3) then Exit; BigMap.ShadowMap.Canvas.Brush.Color:=c; BigMap.ShadowMap.Canvas.Pixels[Who^.MapX,Who^.MapY]:=C; End ELse Begin BigMap.Map.Canvas.Brush.Color:=c; For y:=0 to z do For x:=0 to z do BigMap.Map.Canvas.Pixels[Who^.MapX+x,Who^.MapY+y]:=C; End; End; procedure TForm1.OnTimeFlip(Sender: TObject); begin If ForceToFlip then Scr1.Flip else CekMouse; If not LogicTime.Enabled then LogicTime.Enabled:=True; end; procedure TForm1.BuildTimerTimer(Sender: TObject); Var i,x1,y1:smallint; begin If Mos.DelayMouse=0 then Begin Inc(TimeExpired); For i:=1 to MaxTaskBuild do if TaskBuild[i].BelongTo>0 then With TaskBuild[i] do begin If WhoIsMaking^.Id=TaskBuild[i].Price then Begin Money[TaskBuild[i].BelongTo]:=Money[TaskBuild[i].BelongTo]-TaskBuild[i].Price; Inc(WhoIsMaking^.ActTask3,Count); If WhoIsMaking^.ActTask3>=TimeBuilding then Begin If WhoIsMaking^.UseAs in [2,66] then Begin NewPosition(WhoIsMaking,x1,y1); NewTroop(BelongTo,x1,y1,0,MakeWhat); End Else Begin NewAirUnitPosition(WhoIsMaking,x1,y1); NewAirUnit(BelongTo,x1,y1,0,MakeWhat); End; WhoIsMaking^.GeneralTask:=0; BelongTo:=0; End; End; End; End; End; procedure TForm1.NewPosition(Ptr:PobjCreature;Var x1,y1:smallint); Var j,x2,y2:smallint; Begin j:=0; Repeat Inc(j); For y2:=ptr^.MapY-j to ptr^.MapY+j do For x2:=ptr^.MapX-j to ptr^.MapX+j do If inside(x2,1,MapMaxX) and inside(y2,1,MapMaxY) then If (Tiles[x2,y2]=nil) and (not PartTiles[x2,y2].Ok) and (PartTiles[x2,y2].Soil in [1..3,32,31,38,39]) then Begin x1:=x2; y1:=y2; Exit; End Until j>200; End; procedure TForm1.NewAirUnitPosition(Ptr:PObjCreature;Var x1,y1:smallint); Var j,k,x2,y2:smallint; LX,LY :Array[1..50] of byte; Begin j:=0; Repeat Inc(j); k:=0; For y2:=ptr^.MapY-j to ptr^.MapY+j do For x2:=ptr^.MapX-j to ptr^.MapX+j do If inside(x2,1,MapMaxX) and inside(y2,1,MapMaxY) and (k0 then Begin k:=Random(k)+1; x1:=LX[k]; y1:=LY[k]; Exit End; Until j>200; End; procedure TForm1.CloseApplication; Var i,j: integer; f : TextFile; Begin Scr1.FlippingEnabled:=False; LogicTime.Enabled:=False; FlipTimer.Enabled:=False; BuildTimer.Enabled:=False; //************************* Saving Data Assignfile(f,Application.GetNamePath+'Data\WarResult.Dat'); Rewrite(f); If PlayerRetreat then Writeln(f,'1') else If EnemyRetreat then Writeln(f,'2') else IF PlayerLoose then Writeln(f,'3') else IF EnemyLoose then Writeln(f,'4') else If PlayerQuit then Writeln(f,'5'); Writeln(F,SourMoney[WhoAmi]); Writeln(F,SourMoney[WhoEnemy]); Writeln(F,Money[WhoAmi]); Writeln(F,Money[WhoEnemy]); j:=0; For i:=1 to MaxCreature do If AllCreature[i]<>nil then If (AllCreature[i]^.BelongTo=WhoAmi) and (AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) and (AllCreature[i]^.Id<>nil then If (AllCreature[i]^.BelongTo=WhoAmi) and (AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) and (AllCreature[i]^.Id<>nil then If (AllCreature[i]^.BelongTo=WhoAmi) and (not AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) then Inc(j); Writeln(f,j); For i:=1 to MaxCreature do If AllCreature[i]<>nil then If (AllCreature[i]^.BelongTo=WhoAmi) and (not AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) then Begin Writeln(F,AllCreature[i]^.SpecialID); Writeln(F,AllCreature[i]^.CurBlood); Writeln(F,AllCreature[i]^.MapX-AllyScreen.HomeX+1); Writeln(F,AllCreature[i]^.MapY-AllyScreen.HomeY+1); End; j:=0; For i:=1 to MaxCreature do If AllCreature[i]<>nil then If (AllCreature[i]^.BelongTo=WhoEnemy) and (AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) and (AllCreature[i]^.Id<>nil then If (AllCreature[i]^.BelongTo=WhoEnemy) and (AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) and (AllCreature[i]^.Id<>nil then If (AllCreature[i]^.BelongTo=WhoEnemy) and (not AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) then Inc(j); Writeln(f,j); For i:=1 to MaxCreature do If AllCreature[i]<>nil then If (AllCreature[i]^.BelongTo=WhoEnemy) and (not AllCreature[i]^.Moving) and (AllCreature[i]^.Id>DeadId) then Begin Writeln(F,AllCreature[i]^.SpecialID); Writeln(F,AllCreature[i]^.CurBlood); Writeln(F,AllCreature[i]^.MapX-EnemyScreen.HomeX+1); Writeln(F,AllCreature[i]^.MapY-EnemyScreen.HomeY+1); End; CloseFile(f); //************************** Set Free all pointer For i:=1 to MaxSEffect do If Seffect[i]<>nil then Seffect[i].Free; For i:=1 to MaxSoils do If Soils[i]<>nil then Soils[i].Free; For i:=1 to MaxImgSBullet do if ImgSBullet[i]<>nil then ImgSBullet[i].Free; For i:=1 to 3 do if Commands[i]<>nil then Commands[i].Free; For i:=1 to 3 do If CmdBuildImg[i]<>nil then CmdBuildImg[i].Free; for j:=1 to 3 do Begin for i:=1 to MaxImgTroop do If ImgTroop[j,i]<>nil then ImgTroop[j,i].Free; for i:=1 to MaxImgBld do If ImgBld[j,i]<>nil then ImgBld[j,i].Free; End; MainMenu.Free; BigMap.Map.Free; BigMap.ShadowMap.Free; Text1.Free; Text2.Free; Text3.Free; For i:=1 to MaxSPEffect do if AllPtrSPEffect[i]<>nil then Dispose(AllPtrSPEffect[i]); For i:=1 to MaxSBullet do if AllPtrSBullet[i]<>nil then Dispose(AllPtrSBullet[i]); For i:=1 to MaxCreature do if AllCreature[i]<>nil then dispose(AllCreature[i]); For j:=1 to 4 do For i:=1 to 6 do If MPointer[j,i]<>nil then MPointer[j,i].Free; Close; End; end.