library InstaClimb; uses Classes, Interfaces, Windows, SysUtils { you can add units after this } ,uHCDefines, uHCGCI, uHCGlobals, uHCTypeDefs, uHCEventHelpers, uHCDateTime, uHCAnnexDefs, uHCAnnexHelpers, uHCUtils, uinstaclimb; const DLLVERN = 2; DLLVERINTN = 19; {*** Return DLL internal version, i.e. revision 5 of my DLL ***} 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 := 'InstaClimb DLL by Tony Eischens'; end; {*** Free DLL ***} procedure DLLFree();export;cdecl; begin // Do any cleanup here, this is the end end; {*** Checks if MessageLogLine is connected and if it is, use it ***} procedure MessageLogLine(pMessage: String); begin if (intVerInterface >= 19) then begin if (HCMessageLogLine <> nil) then begin HCMessageLogLine(PChar(pMessage)); end; end; end; {*** Init DLL ***} 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 uInstaClimb.PGEClosing:=PGEClosing; uInstaClimb.PDLLBusy:=PDLLBusy; uInstaClimb.intVerInterface:=verInterface; uInstaClimb.intVerSaveGame:=verSaveGame; // ALE 20171121 consider sending messages to the MessageLog window so we // need to capture that function // ALE 20170224 Alert the user that the GE is too old for this ExportDLL { if (verInterface < 21) then begin MessageDlg('GE too old', GetModuleName(hInstance) + ' is designed for HC2017.011+. Please ' + ' update your GE or disable this ExportDLL.', mtWarning, [mbOK], 0); end; } // ALE 20130908 List the function pointers sent over by the GE // then capture one of them for example usage HCMessageLogLine := nil; funcTmp := funcRefs; while (funcTmp <> nil) do begin if (funcTmp^.funcName = 'MessageLogLine') then begin HCMessageLogLine := THCMessageLogLine(funcTmp^.funcPtr); break; end; funcTmp := funcTmp^.Next; end; end; function ChangeAlt(pGroup: PHCGroup; pUnit: PHCUnit; pAltNew: HCALTITUDE_M): CBOOL;export;cdecl; var lGroup: PHCGroup; lUnit: PHCUnit; lAltOld: HCALTITUDE_M; begin result := CTRUE; // ALE 20170309 we are always handling the turns lGroup := pGroup; lUnit := pUnit; if ((lGroup = nil) OR (HCIsValidGroup(lGroup, uinstaclimb.PGroupStart) = CFALSE)) then begin if ((lUnit = nil) OR (HCIsValidUnit(lUnit, uinstaclimb.PUnitTop) = CFALSE)) then begin exit; end else begin // ALE 20160610 We already assigned lUnit, lUnit = Turning_unit; lGroup := lUnit^.Group; end; end else begin // ALE 20160610 We already assigned both lGroup and lUnit so we don't need to again here // ALE 20160610 But we do need to differentiate between null and bad units if (HCIsValidUnit(lUnit, uinstaclimb.PUnitTop) = CFALSE) then begin lUnit := nil; end; end; if (lUnit <> nil) then lAltOld := lUnit^.Altitude else lAltOld := lGroup^.Units^.Altitude; if (lAltOld = pAltNew) then exit; if (lUnit = nil) then begin // ALE 20160615 Whole group is changing altitude lUnit := lGroup^.Units; while (lUnit <> nil) do begin lUnit^.Altitude := pAltNew; lUnit^.AltBand := HCAltitudeToAltBand(lUnit^.Altitude); lUnit := lUnit^.next; end; if (lGroup^.side = intPlayerSide) then begin MessageLogLine('InstaClimb Group=' + lGroup^.id + ' from ' + HCAltBand2String(HCAltitudeToAltBand(lAltOld)) + ' to ' + HCAltBand2String(lGroup^.Units^.AltBand)); end; end else begin lUnit^.Altitude := pAltNew; lUnit^.AltBand := HCAltitudeToAltBand(lUnit^.Altitude); if (lUnit^.Group^.side = intPlayerSide) then begin MessageLogLine('InstaClimb Unit=' + IntToStr(lUnit^.id) + ' Group=' + lGroup^.id + ' from ' + HCAltBand2String(HCAltitudeToAltBand(lAltOld)) + ' to ' + HCAltBand2String(lUnit^.AltBand)); end; end; end; procedure UnitTop(pUnitTop: PHCUnit);export;cdecl; begin uinstaclimb.PUnitTop := pUnitTop; end; procedure StartGroup(pGroupStart: PHCGroup);export;cdecl; begin uinstaclimb.PGroupStart:=pGroupStart; 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; begin uinstaclimb.intPlayerSide := intSide; end; exports DLLVer, DLLVerInt, DLLDesc, DLLFree, DLLInit ,ChangeAlt // ALE 20170309 Allows overriding of altitude changes ,StartGroup // ALE 20170309 So we can walk the group list ,UnitTop // ALE 20170309 Tells us when Bhead.topUnit changes ,ScenLoad // ALE 20171122 Get player side so we only log for them ; end.