library AARdata; {$mode objfpc}{$H+} {$R *.res} uses Classes { you can add units after this } ,uHCDefines ,uHCGCI, uHCGlobals, uHCTypeDefs, uHCEventHelpers ,uHCDateTime, uHCAnnexDefs, uHCAnnexHelpers, uLazGUIGlobals ,Windows, IniFiles, forms ,ShellAPI ,SysUtils ,Types ,Dialogs, Controls, Interfaces; // end classes const DLLVERN = 2; DLLVERINTN = 13; var intGameTime: Long; intGameTimeLeft: Long; strUnitSink, strDateNow, strMsgLog, strTimeFact, strTimeNow: string; dtNow: THCDateTimeRec; Pdt_scen_start: PHCDateTimeRec; RepFile, Inifile:TINIfile; frstStart, scenLoaded: Boolean; PAllDeadUnits: PHCDeadListItem; HCdisk_id_to_annex_id: THCdisk_id_to_annex_id; HCannex_id_to_disk_id: THCannex_id_to_disk_id; function DLLVer():word;export;cdecl; begin result := DLLVERN; end; {*** Return DLL interface version, i.e. revision 1 of my HCE interface spec ***} function DLLVerInt():word;export;cdecl; begin result := DLLVERINTN; end; {*** Return DLL description, 255 characters max ***} function DLLDesc():PAnsiChar;export;cdecl; begin result := 'data collection for After Action Reports'; end; Function FullDate(dtshort: THCDateTimeRec): string; var mnth: string; begin case dtshort.month of 1: mnth:= 'Jan'; 2: mnth:= 'Feb'; 3: mnth:= 'March'; 4: mnth:= 'April'; 5: mnth:= 'May'; 6: mnth:= 'Jume'; 7: mnth:= 'July'; 8: mnth:= 'Aug'; 9: mnth:= 'Sep'; 10: mnth:= 'Oct'; 11:mnth:= 'Nov'; 12:mnth:= 'Dec'; end; Result:= Format('%d %s %4.4d, %2.2d:%2.2d:%2.2d',[dtshort.day, mnth, dtshort.year, dtshort.hour, dtshort.minute, dtshort.second]); end; procedure GetLastKill(); var PThisDeadUnit: PHCDeadListItem; strDeadUnit, strClass, strUname, strSide, strDateTime: String; intCarrierKill, intShipKill, intSubKill, intPlaneKill, intHeloKill, intBaseKill, intFixKill, intMobKill, intArmKill, intUnarmKill, intS: integer; begin for intS := 0 to 2 do begin case intS of 0: strSide:= 'Blue Side '; 1: strSide:= 'Red Side '; 2: strSide:= 'Neutral Side '; end; PThisDeadUnit:= PAllDeadUnits; intCarrierKill:= 0; intShipKill:= 0; intSubKill:= 0; intPlaneKill:= 0; intHeloKill:=0; intBaseKill:= 0; intFixKill:= 0; intMobKill:= 0; intArmKill:= 0; intUnarmKill:= 0; while PThisDeadUnit <> nil do begin if PThisDeadUnit^.side = intS then begin case PThisDeadUnit^.typeindex of 0: begin strClass:= 'Carrier'; intCarrierKill:= intCarrierKill + PThisDeadUnit^.count; end; 1: begin strClass:= 'Ship'; intShipKill:= intShipKill + PThisDeadUnit^.count; end; 2: begin strClass:= 'Submarine'; intSubKill:= intSubKill + PThisDeadUnit^.count; end; 3: begin strClass:= 'Plane'; intPlaneKill:= intPlaneKill + PThisDeadUnit^.count; end; 4: begin strClass:= 'Helicopter'; intHeloKill:= intHeloKill + PThisDeadUnit^.count; end; 5: begin strClass:= 'Base'; intBaseKill:= intBaseKill + PThisDeadUnit^.count; end; 6: begin strClass:= 'AD Fixed'; intFixKill:= intFixKill + PThisDeadUnit^.count; end; 7: begin strClass:= 'AD Mobile'; intMobKill:= intMobKill + PThisDeadUnit^.count; end; 8: begin strClass:= 'Armoured'; intArmKill:= intArmKill + PThisDeadUnit^.count; end; 9: begin strClass:= 'Unarmoured'; intUnarmKill:= intUnarmKill + PThisDeadUnit^.count; end; end; // insert look for class details case HCAnnexShift(PThisDeadUnit^.Annex) of SHIP_FLAG: begin strUname:= PHCAnnexA1_disk(HCAnnexHelper.HCGetAnnexA1(PThisDeadUnit^.Annex))^.ClassName; end; PLANE_FLAG: begin strUname:= PHCAnnexB1_disk(HCAnnexHelper.HCGetAnnexB1(PThisDeadUnit^.Annex))^.ClassName; end; BASE_FLAG: strUname:= PHCAnnexP1_disk(HCAnnexHelper.HCGetAnnexP1(PThisDeadUnit^.Annex))^.Name; SUB_FLAG: strUname:= PHCAnnexA2_disk(HCAnnexHelper.HCGetAnnexA2(PThisDeadUnit^.Annex))^.ClassName; else strUname:= 'unknown'; end; // end look for class detail // now write data RepFile.WriteInteger('Kill Detail ' + strSide, strUname + '/' + strClass, PThisDeadUnit^.count); end; PThisDeadUnit:= PThisDeadUnit^.next; end; // end loop deadunitptr if intCarrierKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Carriers:', intCarrierKill); if intShipKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Ships:', intShipKill); if intSubKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Submarines:', intSubKill); if intPlaneKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Planes:', intPlaneKill); if intHeloKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Helicopters:', intHeloKill); if intMobKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'AD mobile:', intMobKill); if intFixKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'AD fixed:', intFixKill); if intArmKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Armoured:', intArmKill); if intUnarmKill > 0 then RepFile.WriteInteger('Kill Summary ' + strSide,'Unarmoured:', intUnarmKill); end; // finished all sides RepFile.UpdateFile; end; procedure DLLInit(hwndHC: HWND; pathHC: PAnsiChar; verHC: PAnsiChar; verSaveGame: LongWord; funcRefs: PHCDLL_FUNC_REF; PGEClosing: Pointer; PDLLBusy: Pointer; verInterface: LongWord);export;cdecl; var funcTmp: PHCDLL_FUNC_REF; begin // here we initialize globals and such for the life of the DLL Application.Initialize; uLazGUIGlobals.PGEClosing:=PGEClosing; uLazGUIGlobals.PDLLBusy:=PDLLBusy; uLazGUIGlobals.intVerInterface:=verInterface; uLazGUIGlobals.intVerSaveGame:=verSaveGame; funcTmp := funcRefs; while (funcTmp <> nil) do begin //if (funcTmp^.funcName = 'NewPtr') then // frmMain.NewPtr := funcTmp^.funcPtr //else if (funcTmp^.funcName = 'QueueHarpoonEvent') then // frmMain.HCQueueHarpoonEvent := THCQueueHarpoonEvent(funcTmp^.funcPtr) //else if (funcTmp^.funcName = 'dllCheckLatLonDepth') then // frmMain.HCdllCheckLatLonDepth := THCdllCheckLatLonDepth(funcTmp^.funcPtr) if (funcTmp^.funcName = 'annex_id_to_disk_id') then HCannex_id_to_disk_id := THCannex_id_to_disk_id(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'disk_id_to_annex_id') then HCdisk_id_to_annex_id := THCdisk_id_to_annex_id(funcTmp^.funcPtr) ; funcTmp := funcTmp^.next; end; If Not FileExists(Application.Location+'\AARdata.txt') then begin RepFile:=Tinifile.Create(Application.Location+'\AARdata.txt'); RepFile.WriteString('Initial Start', 'Actual Date ',' ' + DateTimeToStr(Now)); frstStart:= True; end else frstStart:= False; scenLoaded:= False; end; procedure ScenLoad(strHarpPath: PAnsiChar; intScenNum: SmallInt; strScenFPath: PAnsiChar; intBSNum: ShortInt; strBSFName: PAnsiChar; intSide: byte; intGameTimeIn: Long; intGameTimeLeftIn: Long; dt_scen_start_in: PHCDateTimeRec; AnnexDataIn: PHCAnnexes_disk);export;cdecl; var strFullDate: string; begin ulazguiglobals.AnnexData:= AnnexDataIn; scenLoaded:= True; intGameTime := intGameTimeIn; intGameTimeLeft := intGameTimeLeftIn; Pdt_scen_start := dt_scen_start_in; HCAnnexHelper := THCAnnexHelper.Create(AnnexDataIn, HCdisk_id_to_annex_id, uLazGUIGlobals.intVerInterface, uLazGUIGlobals.intVerSaveGame); dtNow:= HCDateTimeInc(Pdt_scen_start^, intGameTime); strFullDate:= FullDate(dtNow); RepFile:=Tinifile.Create(Application.Location+'\AARdata.txt'); RepFile.WriteString('Log', 'session start ', strFullDate); RepFile.WriteString('Log', 'Actual Date ', DateTimeToStr(Now)); RepFile.WriteString('Time Factor', strFullDate, 'Initial ' + strTimeFact); if frstStart = True then begin if intScenNum = -1 then //custom scenario RepFile.WriteString('Initial Start', 'Scenario ',strScenFPath) else RepFile.WriteString('Initial Start', 'Scenario ',strBSFName+'/Scen#'+IntToStr(intScenNum+1)); end; end; procedure TimeFactor(TimeFactor: longint);export;cdecl; var mnth, strDateTime: string; begin if scenLoaded = True then begin dtNow:= HCDateTimeInc(Pdt_scen_start^, intGameTime); strDateTime:= FullDate(dtNow); strTimeFact:= Format(' TimeFactor = 1:%d', [TimeFactor]); RepFile:=Tinifile.Create(Application.Location+'\AARdata.txt'); RepFile.WriteString('Time Factor', strDateTime, strTimeFact); end else strTimeFact:= Format(' TimeFactor = 1:%d', [TimeFactor]); end; procedure MsgLog(MsgLine: PAnsiChar);export;cdecl; begin RepFile.WriteString('log', 'Event ', MsgLine); end; procedure GameTime(GameTime: Long; GameTimeLeft: Long);export;cdecl; begin intGameTime := GameTime; intGameTimeLeft := GameTimeLeft; end; procedure DLLFree();export;cdecl; begin // Do any cleanup here, this is the end and closes library GetLastKill(); end; procedure AllDeadUnitsPtr(AllDeadUnitsPtr: PHCDeadListItem);export;cdecl; begin // get/update deadunitpointer PAllDeadUnits:= AllDeadUnitsPtr; end; procedure UnitFree(UnitID: Byte; GroupID: PAnsiChar);export;cdecl; var strFullDT, strUnitID: string; begin dtNow:= HCDateTimeInc(Pdt_scen_start^, intGameTime); strFullDT:= FullDate(dtNow); strUnitID:= format(':%2.2d',[UnitID]); RepFile.WriteString('Unit Free', strFullDT, GroupID + strUnitID); end; procedure UnitSink(UnitID: Byte; GroupID: PAnsiChar);export;cdecl; begin end; exports DLLVer, DLLVerInt, DLLDesc, DLLFree, DLLInit, AllDeadUnitsPtr, ScenLoad, TimeFactor, MsgLog, GameTime, UnitFree, UnitSink ; // begin end.