//
// scenario.script
//

{const gc_trigger_action_categoriescount = 16;
const gc_trigger_condition_categoriescount = 16;
type TScenarioEditor = class
   localetableid : String;
   actioncategories : array [0..gc_trigger_action_categoriescount-1] of Integer;
   conditioncategories : array [0..gc_trigger_condition_categoriescount-1] of Integer;
   actioncategoriestextkey : array [0..gc_trigger_action_categoriescount-1] of String;
   conditioncategoriestextkey : array [0..gc_trigger_condition_categoriescount-1] of String;
   actiontextkey : array [0..gc_trigger_action_count-1] of String;
   conditiontextkey : array [0..gc_trigger_condition_count-1] of String;
   
   //procedure Init;
   //begin
      //   localtableid := 'scenarioeditor';
      //   var ind : Integer;
      //   actioncategories[0] := gc_trigger_action_none; ind := ind+1;
      //   actioncategories[0] := gc_trigger_action_undefined; ind := ind+1;
      //   actioncategories[1] := gc_trigger_action_none; ind := ind+1;
      //   actioncategories[1] := gc_trigger_action_none; ind := ind+1;
      //   actioncategories[1] := gc_trigger_action_none; ind := ind+1;
   //end;
   //
   //constructor TScenarioEditor;
   //begin
      //   Init;
   //end;
end;}

procedure _scenario_RunConstructors(var scenario : TScenario);
begin
   scenario.Create('scenario');
   var i, j : Integer;
   for i:=0 to gc_scenario_maxtriggers-1 do
   begin
      for j:=0 to gc_trigger_maxconditions-1 do
      scenario.triggers[i].conditions[j].bactive := True;
      for j:=0 to gc_trigger_maxactions-1 do
      scenario.triggers[i].actions[j].bactive := True;
   end;
end;

_scenario_RunConstructors(gScenario);
_scenario_RunConstructors(gScenarioTmp);

procedure _scenario_WriteScenario(const ptrigger : Pointer);
begin
   var progressPlHnd : Integer = GetPlayerHandleByIndex(gc_playerind_progress);
   if (progressPlHnd<>0) then
   begin
      gpointer_register0 := ptrigger;
      //var smHnd : Integer = GetPlayerStateMachineHandle(progressPlHnd);
      //StateMachineExecuteState(smHnd, 'WriteScenario', 0);
      PlayerExecuteStateByHandle(progressPlHnd, 'WriteScenario'); // uncommented cause got net error on _record creation with smHnd exec
      gpointer_register0 := nil;
   end;
end;

procedure _scenario_CompileSignText(var text : String; sign : Integer; bwords : Boolean);
begin
   text := '';
   if (bwords) then
   case sign of
      gc_trigger_condition_sign_none : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.none');
      gc_trigger_condition_sign_equal : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.equal');
      gc_trigger_condition_sign_notequal : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.notequal');
      gc_trigger_condition_sign_more : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.more');
      gc_trigger_condition_sign_moreequal : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.moreequal');
      gc_trigger_condition_sign_less : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.less');
      gc_trigger_condition_sign_lessequal : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.lessequal');
   end
   else
   case sign of
      gc_trigger_condition_sign_none : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.sign.nonwordnone');
      gc_trigger_condition_sign_equal : text := '=';
      gc_trigger_condition_sign_notequal : text := '<>';
      gc_trigger_condition_sign_more : text := '>';
      gc_trigger_condition_sign_moreequal : text := '>=';
      gc_trigger_condition_sign_less : text := '<';
      gc_trigger_condition_sign_lessequal : text := '<=';
   end;
end;

procedure _scenario_CompileConditionTextBase(var text : String; conditionid : Integer);
begin
   case conditionid of
      gc_trigger_condition_none : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.none');
      gc_trigger_condition_undefined : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.undefined');
      gc_trigger_condition_triggerIsActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.triggerIsActive');
      gc_trigger_condition_triggerIsNotActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.triggerIsNotActive');
      gc_trigger_condition_flagActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.flagActive');
      gc_trigger_condition_flagNotActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.flagNotActive');
      gc_trigger_condition_counterValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.counterValue');
      gc_trigger_condition_timerFinished : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.timerFinished');
      gc_trigger_condition_timerNotFinished : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.timerNotFinished');
      gc_trigger_condition_difficulty : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.difficulty');
      gc_trigger_condition_playerResources : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.playerResources');
      gc_trigger_condition_units_CountOfUnitsInGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfUnitsInGroup');
      gc_trigger_condition_units_CountOfGroupUnitsInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfGroupUnitsInZone');
      gc_trigger_condition_units_CountOfPlayerUnitsInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfPlayerUnitsInZone');
      gc_trigger_condition_units_CountOfPlayersTeamUnitsInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfPlayersTeamUnitsInZone');
      gc_trigger_condition_units_CountOfUnitsInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfUnitsInZone');
      gc_trigger_condition_units_CountOfPlayerUnits : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfPlayerUnits');
      gc_trigger_condition_triggerIsActiveTime : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.triggerIsActiveTime');
      gc_trigger_condition_resultExecutedCount : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.resultExecutedCount');
      gc_trigger_condition_executeState : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.executeState');
      gc_trigger_condition_units_CountOfPlayerUnitsInGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfPlayerUnitsInGroup');
      gc_trigger_condition_units_CountOfActingUnitsInGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.units_CountOfActingUnitsInGroup');
      gc_trigger_condition_logical_OR : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.logical_OR');
      gc_trigger_condition_net_IsServer : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_IsServer');
      gc_trigger_condition_net_IsClient : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_IsClient');
      gc_trigger_condition_net_IsOnline : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_IsOnline');
      gc_trigger_condition_net_IsOffline : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_IsOffline');
      gc_trigger_condition_net_IsQueryDialogVisible : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_IsQueryDialogVisible');
      gc_trigger_condition_net_CurrentPlayer : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_CurrentPlayer');
      gc_trigger_condition_net_CurrentPlayerTeam : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_CurrentPlayerTeam');
      gc_trigger_condition_net_CurrentPlayerPosition : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_CurrentPlayerPosition');
      gc_trigger_condition_net_CountOfPlayersInTeam : text := GetLocaleTableListItemByID('editor', 'triggereditor.condition.type.net_CountOfPlayersInTeam');
      else
      text := '';
   end;
end;

procedure _scenario_CompileConditionText(var text : String; var condition : TScenarioTriggerCondition);
begin
   text := '';
   var base : String;
   _scenario_CompileConditionTextBase(base, condition.id);
   text := base;
   var textcolor : String = gc_font_color_orange;
   text := StrReplace(text, '%triggerid%', textcolor+gScenario.triggers[condition.triggerid].name+gc_font_color_default);
   text := StrReplace(text, '%flagid%', textcolor+gScenario.flags[condition.flagid].name+gc_font_color_default);
   text := StrReplace(text, '%counterid%', textcolor+gScenario.counters[condition.counterid].name+gc_font_color_default);
   text := StrReplace(text, '%timerid%', textcolor+gScenario.timers[condition.timerid].name+gc_font_color_default);
   text := StrReplace(text, '%groupid%', textcolor+gScenario.groups[condition.groupid].name+gc_font_color_default);
   text := StrReplace(text, '%zoneid%', textcolor+gScenario.zones[condition.zoneid].name+gc_font_color_default);
   text := StrReplace(text, '%resultid%', textcolor+gScenario.results[condition.resultid].name+gc_font_color_default);
   if condition.player>=0 then
   text := StrReplace(text, '%player%', textcolor+gScenario.players[condition.player].name+gc_font_color_default)
   else
   if condition.player=-1 then
   text := StrReplace(text, '%player%', textcolor+'All players'+gc_font_color_default)
   else
   if condition.player=-2 then
   text := StrReplace(text, '%player%', textcolor+'Server'+gc_font_color_default);
   text := StrReplace(text, '%difficulty%', textcolor+GetLocaleTableListItemByID('gui', 'difficulty.'+IntToStr(condition.difficulty+1))+gc_font_color_default);
   text := StrReplace(text, '%resource%', textcolor+GetLocaleTableListItemByID('gui', 'restype.'+IntToStr(condition.resource))+gc_font_color_default);
   text := StrReplace(text, '%amount%', textcolor+IntToStr(condition.amount)+gc_font_color_default);
   text := StrReplace(text, '%time%', textcolor+FloatToStr(condition.time)+gc_font_color_default);
   if (condition.bstate) then
   text := StrReplace(text, '%includebuildings%', textcolor+GetLocaleTableListItemByID('editor', 'triggereditor.flag.includebuildings')+gc_font_color_default)
   else
   text := StrReplace(text, '%includebuildings%', '');
   text := StrReplace(text, '%bstate%', textcolor+BoolToStr(condition.bstate)+gc_font_color_default);
   text := StrReplace(text, '%state%', textcolor+condition.executestate+gc_font_color_default);
   text := StrReplace(text, '%stringregister%', textcolor+condition.stringregister+gc_font_color_default);
   if (condition.counterid>-1) then
   text := StrReplace(text, '%countervalue%', textcolor+' ('+IntToStr(gScenario.counters[condition.counterid].value)+')'+gc_font_color_default);
   if (StrExists(text, '%sign%')) then
   begin
      var signtext : String;
      _scenario_CompileSignText(signtext, condition.sign, True);
      text := StrReplace(text, '%sign%', textcolor+signtext+gc_font_color_default);
   end;
end;

procedure _scenario_CompileActionTextBase(var text : String; actionid : Integer);
begin
   case actionid of
      gc_trigger_action_none : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.none');
      gc_trigger_action_undefined : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.undefined');
      gc_trigger_action_service_timerStart : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_timerStart');
      gc_trigger_action_service_timerStop : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_timerStop');
      gc_trigger_action_service_timerStartCustom : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_timerStartCustom');
      gc_trigger_action_service_flagSetActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_flagSetActive');
      gc_trigger_action_service_flagSetNotActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_flagSetNotActive');
      gc_trigger_action_service_counterAddValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_counterAddValue');
      gc_trigger_action_service_counterRemoveValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_counterRemoveValue');
      gc_trigger_action_service_counterSetValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_counterSetValue');
      gc_trigger_action_resource_resourceAdd : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.resource_resourceAdd');
      gc_trigger_action_resource_resourceRemove : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.resource_resourceRemove');
      gc_trigger_action_resource_resourceSet : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.resource_resourceSet');
      gc_trigger_action_objective_objectiveShow : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_objectiveShow');
      gc_trigger_action_objective_objectiveHide : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_objectiveHide');
      gc_trigger_action_objective_objectiveSetDone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_objectiveSetDone');
      gc_trigger_action_map_cameraMoveToZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.map_cameraMoveToZone');
      gc_trigger_action_map_revealZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.map_revealZone');
      gc_trigger_action_query_queryShow : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.query_queryShow');
      gc_trigger_action_selection_selectionAddGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.selection_selectionAddGroup');
      gc_trigger_action_selection_selectionAddUnitsInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.selection_selectionAddUnitsInZone');
      gc_trigger_action_selection_selectionClear : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.selection_selectionClear');
      gc_trigger_action_group_Clear : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_Clear');
      gc_trigger_action_group_AddUnitsOfGroupToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddUnitsOfGroupToGroup');
      gc_trigger_action_group_AddUnitsInZoneToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddUnitsInZoneToGroup');
      gc_trigger_action_group_AddUnitsOfGroupInZoneToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddUnitsOfGroupInZoneToGroup');
      gc_trigger_action_group_AddUnitsOfPlayerInZoneToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddUnitsOfPlayerInZoneToGroup');
      gc_trigger_action_group_AddUnitsOfPlayerOfGroupToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddUnitsOfPlayerOfGroupToGroup');
      gc_trigger_action_group_AddIdlePeasantsToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddIdlePeasantsToGroup');
      gc_trigger_action_group_AddIdleMinesToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddIdleMinesToGroup');
      gc_trigger_action_group_CreateSquad : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_CreateSquad');
      gc_trigger_action_player_playerSetAsEnemy : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_playerSetAsEnemy');
      gc_trigger_action_player_playerSetAsAlly : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_playerSetAsAlly');
      gc_trigger_action_player_playerSetAsNeutral : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_playerSetAsNeutral');
      gc_trigger_action_player_unitsChangePlayer : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_unitsChangePlayer');
      gc_trigger_action_units_DestroyGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.units_DestroyGroup');
      gc_trigger_action_units_KillGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.units_KillGroup');
      gc_trigger_action_order_setUnitsVisible : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_setUnitsVisible');
      gc_trigger_action_order_setUnitsUnvisible : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_setUnitsUnvisible');
      gc_trigger_action_units_CreateUnits : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.units_CreateUnits');
      gc_trigger_action_units_MakeUnplayable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.units_MakeUnplayable');
      gc_trigger_action_units_MakePlayable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.units_MakePlayable');
      gc_trigger_action_country_unitProduceEnable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.country_unitProduceEnable');
      gc_trigger_action_country_unitProduceDisable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.country_unitProduceDisable');
      gc_trigger_action_country_upgradeEnable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.country_upgradeEnable');
      gc_trigger_action_country_upgradeDisable : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.country_upgradeDisable');
      gc_trigger_action_country_makeUpgradeInstanly : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.country_makeUpgradeInstanly');
      gc_trigger_action_order_standground : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_standground');
      gc_trigger_action_order_cancelStandGround : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_cancelStandGround');
      gc_trigger_action_order_enableSearchEnemy : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_enableSearchEnemy');
      gc_trigger_action_order_disableSearchEnemy : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_disableSearchEnemy');
      gc_trigger_action_order_attackGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_attackGroup');
      gc_trigger_action_order_attackZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_attackZone');
      gc_trigger_action_order_moveToZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_moveToZone');
      gc_trigger_action_order_moveToZoneInstanly : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_moveToZoneInstanly');
      gc_trigger_action_order_setDirectionToZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_setDirectionToZone');
      gc_trigger_action_order_setDirectionToAngle : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_setDirectionToAngle');
      gc_trigger_action_order_runUpgrade : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_runUpgrade');
      gc_trigger_action_order_GroupProduceUnit : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_GroupProduceUnit');
      gc_trigger_action_order_GroupCancelProduceUnit : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_GroupCancelProduceUnit');
      gc_trigger_action_order_SetRallyPointToZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_SetRallyPointToZone');
      gc_trigger_action_order_doExtractFood : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_doExtractFood');
      gc_trigger_action_order_doExtractWood : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_doExtractWood');
      gc_trigger_action_order_doExtractStone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_doExtractStone');
      gc_trigger_action_order_goInside : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_goInside');
      gc_trigger_action_gate_gateOpen : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.gate_gateOpen');
      gc_trigger_action_gate_gateClose : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.gate_gateClose');
      gc_trigger_action_ferry_goOutside : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.ferry_goOutside');
      gc_trigger_action_endgame_win : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.endgame_win');
      gc_trigger_action_endgame_lose : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.endgame_lose');
      gc_trigger_action_advanced_ifThenElse : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_ifThenElse');
      gc_trigger_action_advanced_enableTrigger : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_enableTrigger');
      gc_trigger_action_advanced_disableTrigger : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_disableTrigger');
      gc_trigger_action_advanced_enableThisTrigger : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_enableThisTrigger');
      gc_trigger_action_service_DebugLog : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_DebugLog');
      gc_trigger_action_service_DebugMessage : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.service_DebugMessage');
      gc_trigger_action_save_save : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.save_save');
      gc_trigger_action_save_load : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.save_load');
      gc_trigger_action_advanced_executeState : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_executeState');
      gc_trigger_action_advanced_ExecuteTriggerActions  : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.advanced_ExecuteTriggerActions');
      gc_trigger_action_group_AddSpecificUnitsOfPlayerInZoneToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.group_AddSpecificUnitsOfPlayerInZoneToGroup');
      gc_trigger_action_order_findAndAttackEnemyInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_findAndAttackEnemyInZone');
      gc_trigger_action_order_dismissSquadsInGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_dismissSquadsInGroup');
      gc_trigger_action_order_ArtilleryAttackZoneCenterWithDispertion : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.order_ArtilleryAttackZoneCenterWithDispertion');
      gc_trigger_action_player_enableAI : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_enableAI');
      gc_trigger_action_player_disableAI : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.player_disableAI');
      gc_trigger_action_objective_PlaceMarkerInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_PlaceMarkerInZone');
      gc_trigger_action_objective_RemoveMarkerInZone : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_RemoveMarkerInZone');
      gc_trigger_action_objective_AddMarkerToGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_AddMarkerToGroup');
      gc_trigger_action_objective_RemoveMarkerFromGroup : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.objective_RemoveMarkerFromGroup');
      gc_trigger_action_net_SetTriggerActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_SetTriggerActive');
      gc_trigger_action_net_SetFlagState : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_SetFlagState');
      gc_trigger_action_net_SetCounterValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_SetCounterValue');
      gc_trigger_action_net_ExecuteTriggerActions : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_ExecuteTriggerActions');
      gc_trigger_action_net_SetCounterSpecialValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_SetCounterSpecialValue');
      gc_trigger_action_net_TeamSetTriggerActive : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_TeamSetTriggerActive');
      gc_trigger_action_net_TeamSetFlagState : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_TeamSetFlagState');
      gc_trigger_action_net_TeamSetCounterValue : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_TeamSetCounterValue');
      gc_trigger_action_net_TeamExecuteTriggerActions : text := GetLocaleTableListItemByID('editor', 'triggereditor.action.type.net_TeamExecuteTriggerActions');
      else
      text := '';
   end;
end;

procedure _scenario_CompileActionText(var text : String; var action : TScenarioTriggerAction);
begin
   text := '';
   _scenario_CompileActionTextBase(text, action.id);
   var textcolor : String = gc_font_color_orange;
   text := StrReplace(text, '%triggerid%', textcolor+gScenario.triggers[action.triggerid].name+gc_font_color_default);
   text := StrReplace(text, '%flagid%', textcolor+gScenario.flags[action.flagid].name+gc_font_color_default);
   text := StrReplace(text, '%counterid%', textcolor+gScenario.counters[action.counterid].name+gc_font_color_default);
   text := StrReplace(text, '%timerid%', textcolor+gScenario.timers[action.timerid].name+' ('+FloatToStr(gScenario.timers[action.timerid].time)+'ms)'+gc_font_color_default);
   text := StrReplace(text, '%groupid%', textcolor+gScenario.groups[action.groupid].name+gc_font_color_default);
   text := StrReplace(text, '%groupidtrg%', textcolor+gScenario.groups[action.groupidtrg].name+gc_font_color_default);
   text := StrReplace(text, '%zoneid%', textcolor+gScenario.zones[action.zoneid].name+gc_font_color_default);
   text := StrReplace(text, '%objectiveid%', textcolor+gScenario.objectives[action.objectiveid].name+gc_font_color_default);
   text := StrReplace(text, '%queryid%', textcolor+gScenario.queries[action.queryid].name+gc_font_color_default);
   text := StrReplace(text, '%bstate%', textcolor+BoolToStr(action.bstate)+gc_font_color_default);
   text := StrReplace(text, '%player%', textcolor+gScenario.players[action.player].name+gc_font_color_default);
   text := StrReplace(text, '%playertrg%', textcolor+gScenario.players[action.playertrg].name+gc_font_color_default);
   text := StrReplace(text, '%resource%', textcolor+GetLocaleTableListItemByID('gui', 'restype.'+IntToStr(action.resource))+gc_font_color_default);
   text := StrReplace(text, '%amount%', textcolor+IntToStr(action.amount)+gc_font_color_default);
   text := StrReplace(text, '%time%', textcolor+FloatToStr(action.time)+gc_font_color_default);
   text := StrReplace(text, '%radius%', textcolor+FloatToStr(action.radius)+gc_font_color_default);
   text := StrReplace(text, '%state%', textcolor+action.executestate+gc_font_color_default);
   text := StrReplace(text, '%stringregister%', textcolor+action.stringregister+gc_font_color_default);
   text := StrReplace(text, '%marker%', textcolor+gConstScenarioMarkers[action.marker]+gc_font_color_default);
   if (action.bstate) then
   text := StrReplace(text, '%brandom%', textcolor+GetLocaleTableListItemByID('editor', 'triggereditor.flag.random')+gc_font_color_default)
   else
   text := StrReplace(text, '%brandom%', '');
   
   if (action.unitid>0) and (action.countryid>=0) then
   begin
      var unitname : String;
      _misc_GetUnitNameBySID(gObjProp[action.countryid][action.unitid].sid, unitname);
      
      var csid : String;
      _country_GetSIDByID(action.countryid, csid);
      var ttext : String = gc_loc_units+'|'+csid;
      var textCountry : String;
      _misc_StringToText(ttext, textCountry);
      _misc_GetUnitNameBySID(gObjProp[action.countryid][action.unitid].sid, unitname);
      unitname := unitname+' ('+textCountry+')';
      
      //text := StrReplace(text, '%unit%', textcolor+gObjProp[action.countryid][action.unitid].sid+gc_font_color_default);
      text := StrReplace(text, '%unit%', textcolor+unitname+gc_font_color_default);
   end;
   if (action.id=gc_trigger_action_map_revealZone) then
   begin
      var RepStr : String;
      if (action.bstate) then
      RepStr := GetLocaleTableListItemByID('editor', 'triggereditor.flag.fogofwaropen')
      else
      RepStr := GetLocaleTableListItemByID('editor', 'triggereditor.flag.fogofwarclose');
      text := StrReplace(text, '%revealstate%', textcolor+RepStr+gc_font_color_default);
   end;
   
   if (action.upgradeid>0) and (action.countryid>=0) then
   begin
      var csid : String;
      _country_GetSIDByID(action.countryid, csid);
      var ttext : String = gc_loc_units+'|'+csid;
      var textCountry : String;
      _misc_StringToText(ttext, textCountry);
      
      var upgsid : String = gCountry[action.countryid].upgrade[action.upgradeid].id;
      var upgtext : String;
      _country_GetUpgradeNameBySID(action.countryid, upgsid, upgtext);
      text := StrReplace(text, ' %countryid% ', ' ');
      text := StrReplace(text, '%upgradesid%', textcolor+upgsid+'; '+upgtext+gc_font_color_default);
   end;
   
   text := StrReplace(text, '%unitid%', textcolor+IntToStr(action.unitid)+gc_font_color_default);
   text := StrReplace(text, '%countryid%', textcolor+IntToStr(action.countryid)+gc_font_color_default);
   text := StrReplace(text, '%unitid%', textcolor+IntToStr(action.unitid)+gc_font_color_default);
   text := StrReplace(text, '%direction%', textcolor+FloatToStr(action.direction)+gc_font_color_default);
   text := StrReplace(text, '%formationsid%', textcolor+gFormation[action.formationid].sid+gc_font_color_default);
end;

function _scenario_ShowTrigger(parent : Integer; var ui : TUI; indcount, ind, count : Integer; eventstate : String; bisresulttrigger, btriggertreeopen, bupdate : Boolean) : Integer;
begin
   procedure CalcBtnWidthBasedOnScroller(parent, count : Integer; offy : Integer; var btnwidthscroll, height : Integer; var bScroller : Boolean);
   begin
      height := count*offy;
      bScroller := (height>GetGUIElementHeight(parent));
      btnwidthscroll := _misc_SwitchInt(0, -24, bScroller);
   end;
   
   var ptrigger : Pointer;
   var bactive : Boolean;
   var bpicked : Boolean;
   var bnextexists : Boolean;
   var picktrigger, pickcondition, pickaction, maxtriggers : Integer;
   var triggername : String;
   var bpickedforadd : Boolean = (gScenario.ui.pickedtriggerindex=ind);
   if (bisresulttrigger) then
   begin
      ptrigger := gScenarioTmp.resulttriggers[ind];
      pickcondition := gScenario.ui.pickedresulttriggerconditionindex;
      pickaction := gScenario.ui.pickedresulttriggeractionindex;
      bpicked := True;//(gScenarioTmp.ui.pickedresulttriggerindex=ind) and (pickcondition=-1) and (pickaction=-1);
      picktrigger := gScenario.ui.pickedresulttriggerindex;
      bnextexists := gScenarioTmp.resulttriggers[ind+1].bexists;
      maxtriggers := gc_scenario_maxresulttriggers;
   end
   else
   begin
      ptrigger := gScenario.triggers[ind];
      pickcondition := gScenario.ui.pickedconditionindex;
      pickaction := gScenario.ui.pickedactionindex;
      bpicked := (gScenario.ui.pickedtriggerindex=ind) and (pickcondition=-1) and (pickaction=-1);
      picktrigger := gScenario.ui.pickedtriggerindex;
      bnextexists := gScenario.triggers[ind+1].bexists;
      maxtriggers := gc_scenario_maxtriggers;
   end;
   bactive := TScenarioTrigger(ptrigger).bactive;
   triggername := TScenarioTrigger(ptrigger).name;
   
   const cTagEditTrigger = 201;
   const cTagDeleteTrigger = 202;
   const cTagNewCondition = 203;
   const cTagNewAction = 204;
   const cTagDeleteCondition = 205;
   const cTagDeleteAction = 206;
   const cTagEditCondition = 207;
   const cTagEditAction = 208;
   const cTagMoveUp = 209;
   const cTagMoveDown = 210;
   const cTagEnable = 211;
   const cTagDisable = 212;
   const cTagExecute = 213;
   const cTagCopyAction = 214;
   const cTagPasteAction = 215;
   const cTagCopyCondition = 216;
   const cTagPasteCondition = 217;
   const cTagEnableAction = 218;
   const cTagDisableAction = 219;
   const cTagEnableCondition = 220;
   const cTagDisableCondition = 221;
   const cTagCopyTrigger = 222;
   const cTagPasteTrigger = 223;
   
   var cTextDelete : String = GetLocaleTableListItemByID('editor', 'triggereditor.delete');
   var cTextEdit : String = GetLocaleTableListItemByID('editor', 'triggereditor.edit');
   var cTextExecute : String = GetLocaleTableListItemByID('editor', 'triggereditor.execute');
   var cTextExecuteHint : String = GetLocaleTableListItemByID('editor', 'triggereditor.execute.hint');
   var cTextNewCondition : String = GetLocaleTableListItemByID('editor', 'triggereditor.newcondition');
   var cTextNewAction : String = GetLocaleTableListItemByID('editor', 'triggereditor.newaction');
   var cTextEditTrigger : String = GetLocaleTableListItemByID('editor', 'triggereditor.edittrigger');
   var cTextDeleteTrigger : String = GetLocaleTableListItemByID('editor', 'triggereditor.deletetrigger');
   var cTextMoveUp : String = GetLocaleTableListItemByID('editor', 'triggereditor.moveup');
   var cTextMoveDown : String = GetLocaleTableListItemByID('editor', 'triggereditor.movedown');
   var cTextEnable : String = GetLocaleTableListItemByID('editor', 'triggereditor.enable');
   var cTextDisable : String = GetLocaleTableListItemByID('editor', 'triggereditor.disable');
   var cTextCopy : String = GetLocaleTableListItemByID('editor', 'triggereditor.copy');
   var cTextPaste : String = GetLocaleTableListItemByID('editor', 'triggereditor.paste');
   var cTextPasteTriggerHint : String = GetLocaleTableListItemByID('editor', 'triggereditor.pastetrigger.hint');
   var cTextPasteConditionHint : String = GetLocaleTableListItemByID('editor', 'triggereditor.pastecondition.hint');
   var cTextPasteActionHint : String = GetLocaleTableListItemByID('editor', 'triggereditor.pasteaction.hint');
   
   const bAlwaysOpenTrees = True;
   const cNonActiveAlpha = 0.5;
   const cActiveAlpha = 1;
   const cNonActiveTextColor = 0.5;
   const cActiveTextColor = 1;
   const cAddBtnMarginX = 2;
   var alpha : Float = _misc_SwitchFloat(cNonActiveAlpha, cActiveAlpha, bactive);;
   var alphatext : Float = _misc_SwitchFloat(cNonActiveTextColor, cActiveTextColor, bactive);;
   var tag32 : TInt32;
   if (ind>=256) then // to increase triggers cap from 256 to 512
   tag32.SetByte0(ind-256)
   else
   tag32.SetByte0(ind);
   tag32.SetByte1(-1);
   tag32.SetByte2(-1);
   if (ind<256) then
   tag32.SetByte3(1)
   else
   tag32.SetByte3(1+8);
   var ptag32 : Pointer = tag32;
   var tag : Integer = Integer(ptag32);
   
   //SetGUIElementUserBlend(elmLineBtn, alpha);
   var benabled : Boolean;
   var tw, th, marginw : Integer;
   var offx : Integer = 24;
   var offy : Integer = GetGUITextureHeight('line.27.normal')+2;
   var nul : String;
   var treelevel : Integer;
   
   var bScroller : Boolean;
   var btnwidthscroll, height : Integer;
   CalcBtnWidthBasedOnScroller(parent, count, offy, btnwidthscroll, height, bScroller);
   
   if (bpicked) then
   begin
      var btntext : String;
      var elmHnd : Integer;
      if (not bisresulttrigger) then
      begin
         var tmptag : Integer;
         if (TScenarioTrigger(ptrigger).bactive) then
         begin
            tmptag := cTagDisable;
            btntext := cTextDisable;
         end
         else
         begin
            tmptag := cTagEnable;
            btntext := cTextEnable;
         end;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll, indcount*offy, tw+20, 0, eventstate, nul, tmptag, bupdate);
         marginw := marginw+(tw+20+cAddBtnMarginX);
         btntext := cTextDelete;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagDeleteTrigger, bupdate);
         marginw := marginw+(tw+20+cAddBtnMarginX);
      end;
      
      btntext := cTextExecute;
      GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
      elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, cTextExecuteHint, cTagExecute, bupdate);
      marginw := marginw+(tw+20+cAddBtnMarginX);
      
      btntext := cTextEdit;
      GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
      elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagEditTrigger, bupdate);
      marginw := marginw+(tw+20+cAddBtnMarginX);
      
      if (not bisresulttrigger) then
      begin
         btntext := cTextPaste;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, cTextPasteTriggerHint, cTagPasteTrigger, bupdate);
         SetGUIElementEnabled(elmHnd, (ind<(gc_scenario_maxtriggers-1)));
         marginw := marginw+(tw+20+cAddBtnMarginX);
         
         btntext := cTextCopy;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagCopyTrigger, bupdate);
         marginw := marginw+(tw+20+cAddBtnMarginX);
      end;
      
      if (not bisresulttrigger) then
      begin
         benabled := (picktrigger<maxtriggers-1) and (bnextexists);
         btntext := cTextMoveDown;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveDown, bupdate);
         marginw := marginw+(tw+20+cAddBtnMarginX);
         SetGUIElementEnabled(elmHnd, benabled);
         
         benabled := (picktrigger>0);
         btntext := cTextMoveUp;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveUp, bupdate);
         marginw := marginw+(tw+20+cAddBtnMarginX);
         SetGUIElementEnabled(elmHnd, benabled);
      end;
   end;
   var text : String = IntToStr(ind)+' : '+triggername;
   var elmLineBtn : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(indcount), parent, 1, text, gc_halParentLeft, gc_valParentTop, 0, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx-marginw+btnwidthscroll, 0, eventstate, nul, tag, bupdate);
   SetGUIElementUseUserColor(elmLineBtn, True);
   SetGUIElementUserColor(elmLineBtn, 1, 1, 1, alpha);
   var txtHnd : Integer = GetGUIElementIndexByNameParent('t'+GetGUIElementNameByIndex(elmLineBtn), elmLineBtn);
   SetGUIElementColor(txtHnd, 1, 1, 1, alphatext);
   SetGUIElementChecked(elmLineBtn, bpicked);
   
   //var elmLineControl : Integer = _gui_CreateImageActive('control', elmLineBtn, gc_gui_material_blank, gc_halParentRightWidth, gc_valParentMiddle, 0, 0, 78, 0, 0, '', '', bupdate);
   //_gui_CreateButton('edit', elmLineControl, 'btn.rectangle.close', gc_halParentRightWidth, gc_valParentMiddle, -4, 1, 0, 0, eventstate, cTextDeleteTrigger, cTagDeleteTrigger, bupdate);
   //_gui_CreateButton('del', elmLineControl, 'btn.rectangle.settings', gc_halParentLeft, gc_valParentMiddle, 4, 1, 0, 0, eventstate, cTextEditTrigger, cTagEditTrigger, bupdate);
   //SetGUIElementVisible(elmLineControl, bpicked {and (gScenario.ui.pickedconditionindex=-1) and (gScenario.ui.pickedactionindex=-1)});
   indcount := indcount+1;
   treelevel := treelevel+1;
   if (btriggertreeopen) then
   begin
      var count : Integer;
      var j : Integer;
      for j:=0 to gc_trigger_maxconditions-1 do
      if (TScenarioTrigger(ptrigger).conditions[j].id<>gc_trigger_condition_none) then
      count := count+1;
      
      text := GetLocaleTableListItemByID('editor', 'triggereditor.conditions');
      if (count>0) and (not bAlwaysOpenTrees) {and (not gScenario.triggers[i].bconditionstreeopen)} then
      text := text+' ['+IntToStr(count)+']';
      if (ind<256) then
      tag32.SetByte3(2)
      else
      tag32.SetByte3(2+8);
      tag := Integer(ptag32);
      
      marginw := 0;
      if (bpicked) or (bpickedforadd) then
      begin
         var btntext : String = cTextNewCondition;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         var elmHnd : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagNewCondition, bupdate);
         SetGUIElementEnabled(elmHnd, (TScenarioTrigger(ptrigger).conditions[gc_trigger_maxconditions-1].id=gc_trigger_condition_none));
         marginw := (tw+20+cAddBtnMarginX);
      end;
      var elmHnd : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, text, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx+(btnwidthscroll-marginw), 0, eventstate, nul, tag, bupdate);
      SetGUIElementUserBlend(elmHnd, alpha);
      indcount := indcount+1;
      
      treelevel := treelevel+1;
      if (TScenarioTrigger(ptrigger).bconditionstreeopen) or (bAlwaysOpenTrees) then
      begin
         for j:=0 to gc_trigger_maxconditions-1 do
         begin
            if (TScenarioTrigger(ptrigger).conditions[j].id<>gc_trigger_condition_none) then
            begin
               tag32.SetByte1(j);
               tag := Integer(ptag32);
               _scenario_CompileConditionText(text, TScenarioTrigger(ptrigger).conditions[j]);
               var bpicked : Boolean = (picktrigger=ind) and (pickcondition=j);
               
               marginw := 0;
               if (bpicked) then
               begin
                  var btntext : String = cTextDelete;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll, indcount*offy, tw+20, 0, eventstate, nul, cTagDeleteCondition, bupdate);
                  marginw := (tw+20+cAddBtnMarginX);
                  
                  var tmptag : Integer;
                  if (TScenarioTrigger(ptrigger).conditions[j].bactive) then
                  begin
                     tmptag := cTagDisableCondition;
                     btntext := cTextDisable;
                  end
                  else
                  begin
                     tmptag := cTagEnableCondition;
                     btntext := cTextEnable;
                  end;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, tmptag, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextEdit;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagEditCondition, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextPaste;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, cTextPasteConditionHint, cTagPasteCondition, bupdate);
                  SetGUIElementEnabled(elmHnd, (TScenarioTrigger(ptrigger).conditions[gc_trigger_maxconditions-1].id=gc_trigger_condition_none));
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextCopy;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagCopyCondition, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  benabled := (pickcondition<gc_trigger_maxconditions-1) and (TScenarioTrigger(ptrigger).conditions[pickcondition+1].id<>gc_trigger_condition_none);
                  btntext := cTextMoveDown;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveDown, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  SetGUIElementEnabled(elmHnd, benabled);
                  
                  benabled := (pickcondition>0);
                  btntext := cTextMoveUp;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveUp, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  SetGUIElementEnabled(elmHnd, benabled);
               end;
               var alphacondition : Float;
               if (not TScenarioTrigger(ptrigger).conditions[j].bactive) then
               alphacondition := alpha*0.5
               else
               alphacondition := alpha;
               var elmLineBtn : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, text, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx-marginw+btnwidthscroll, 0, eventstate, nul, tag, bupdate);
               SetGUIElementUserBlend(elmLineBtn, alphacondition);
               SetGUIElementChecked(elmLineBtn, bpicked);
               //var elmLineControl : Integer = _gui_CreateImageActive('control', elmLineBtn, gc_gui_material_blank, gc_halParentRightWidth, gc_valParentMiddle, 0, 0, 78, 0, 0, '', '', bupdate);
               //_gui_CreateButton('del', elmLineControl, 'btn.rectangle.close', gc_halParentRightWidth, gc_valParentMiddle, -4, 1, 0, 0, eventstate, cTextDelete, cTagDeleteCondition, bupdate);
               //_gui_CreateButton('edit', elmLineControl, 'btn.rectangle.settings', gc_halParentLeft, gc_valParentMiddle, 4, 1, 0, 0, eventstate, cTextEditTrigger, cTagEditTrigger, bupdate);
               //SetGUIElementVisible(elmLineControl, bpicked);
               indcount := indcount+1;
            end;
         end;
         {var elmHnd : Integer = _ui_CreateBtn(ui, 'newcondition', elmLeft, 1, cTextNewCondition, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, 30, 0, eventstate, nul, cTagNewCondition, bupdate);
         var txtHnd : Integer = GetGUIElementIndexByNameParent('t'+GetGUIElementNameByIndex(elmHnd), elmHnd);
         SetGUIElementTextAlign(txtHnd, gUIConst.halign[gc_halMiddle], gUIConst.valign[gc_valMiddle], 0, 0);
         indcount := indcount+1;}
      end;
      treelevel := treelevel-1;
      
      count := 0;
      for j:=0 to gc_trigger_maxactions-1 do
      if (TScenarioTrigger(ptrigger).actions[j].id<>gc_trigger_action_none) then
      count := count+1;
      
      text := GetLocaleTableListItemByID('editor', 'triggereditor.actions');
      if (count>0) and (not bAlwaysOpenTrees){and (not gScenario.triggers[i].bactionstreeopen)} then
      text := text+' ['+IntToStr(count)+']';
      tag32.SetByte1(-1);
      if (ind<256) then
      tag32.SetByte3(3)
      else
      tag32.SetByte3(3+8);
      tag := Integer(ptag32);
      
      marginw := 0;
      if (bpicked) or (bpickedforadd) then
      begin
         var btntext : String = cTextNewAction;
         GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
         var elmHnd : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll, indcount*offy, tw+20, 0, eventstate, nul, cTagNewAction, bupdate);
         SetGUIElementEnabled(elmHnd, (TScenarioTrigger(ptrigger).actions[gc_trigger_maxactions-1].id=gc_trigger_action_none));
         marginw := (tw+20+cAddBtnMarginX);
      end;
      elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, text, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx-marginw+btnwidthscroll, 0, eventstate, nul, tag, bupdate);
      SetGUIElementUserBlend(elmHnd, alpha);
      indcount := indcount+1;
      {btntext := cTextNewAction;
      GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
      elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, text, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx-(tw+20+cAddBtnMarginX)+btnwidthscroll, 0, eventstate, nul, tag, bupdate);
      SetGUIElementUserBlend(elmHnd, alpha);
      
      elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll, indcount*offy, tw+20, 0, eventstate, nul, cTagNewAction, bupdate);
      SetGUIElementEnabled(elmHnd, (gScenario.triggers[i].actions[gc_trigger_maxactions-1].id=gc_trigger_action_none));
      indcount := indcount+1;}
      
      treelevel := treelevel+1;
      if (TScenarioTrigger(ptrigger).bactionstreeopen) or (bAlwaysOpenTrees) then
      begin
         for j:=0 to gc_trigger_maxactions-1 do
         begin
            if (TScenarioTrigger(ptrigger).actions[j].id<>gc_trigger_action_none) then
            begin
               tag32.SetByte2(j);
               tag := Integer(ptag32);
               _scenario_CompileActionText(text, TScenarioTrigger(ptrigger).actions[j]);
               marginw := 0;
               var bpicked : Boolean = (picktrigger=ind) and (pickaction=j);
               if (bpicked) then
               begin
                  var btntext : String = cTextDelete;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll, indcount*offy, tw+20, 0, eventstate, nul, cTagDeleteAction, bupdate);
                  marginw := (tw+20+cAddBtnMarginX);
                  
                  var tmptag : Integer;
                  if (TScenarioTrigger(ptrigger).actions[j].bactive) then
                  begin
                     tmptag := cTagDisableAction;
                     btntext := cTextDisable;
                  end
                  else
                  begin
                     tmptag := cTagEnableAction;
                     btntext := cTextEnable;
                  end;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, tmptag, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextEdit;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagEditAction, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextPaste;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, cTextPasteActionHint, cTagPasteAction, bupdate);
                  SetGUIElementEnabled(elmHnd, (TScenarioTrigger(ptrigger).actions[gc_trigger_maxactions-1].id=gc_trigger_action_none));
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  btntext := cTextCopy;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagCopyAction, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  
                  benabled := (pickaction<gc_trigger_maxactions-1) and (TScenarioTrigger(ptrigger).actions[pickaction+1].id<>gc_trigger_action_none);
                  btntext := cTextMoveDown;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveDown, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  SetGUIElementEnabled(elmHnd, benabled);
                  
                  benabled := (pickaction>0);
                  btntext := cTextMoveUp;
                  GetGUIElementFontTextFormatRect(gUIConst.font[ui.btn1.ffont], btntext, tw, th);
                  elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, btntext, gc_halParentRightWidth, gc_valParentTop, btnwidthscroll-marginw, indcount*offy, tw+20, 0, eventstate, nul, cTagMoveUp, bupdate);
                  marginw := marginw+(tw+20+cAddBtnMarginX);
                  SetGUIElementEnabled(elmHnd, benabled);
               end;
               var alphaaction : Float;
               if (not TScenarioTrigger(ptrigger).actions[j].bactive) then
               alphaaction := alpha*0.5
               else
               alphaaction := alpha;
               var elmLineBtn : Integer = _ui_CreateBtn(ui, 'line'+IntToStr(ind), parent, 1, text, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, GetGUIElementWidth(parent)-treelevel*offx-marginw+btnwidthscroll, 0, eventstate, nul, tag, bupdate);
               SetGUIElementUserBlend(elmLineBtn, alphaaction);
               SetGUIElementChecked(elmLineBtn, bpicked);
               //elmHnd := _ui_CreateBtn(ui, 'line'+IntToStr(ind), elmLeft, 1, btntext, gc_halParentRightWidth, gc_valParentTop, 0, indcount*offy, tw+20, 0, eventstate, nul, cTagDeleteAction, bupdate);
               
               //var elmLineControl : Integer = _gui_CreateImageActive('control', elmLineBtn, gc_gui_material_blank, gc_halParentRightWidth, gc_valParentMiddle, 0, 0, 78, 0, 0, '', '', bupdate);
               //_gui_CreateButton('del', elmLineControl, 'btn.rectangle.close', gc_halParentRightWidth, gc_valParentMiddle, -4, 1, 0, 0, eventstate, cTextDelete, cTagDeleteAction, bupdate);
               //_gui_CreateButton('edit', elmLineControl, 'btn.rectangle.settings', gc_halParentLeft, gc_valParentMiddle, 4, 1, 0, 0, eventstate, cTextEditTrigger, cTagEditTrigger, bupdate);
               //SetGUIElementVisible(elmLineControl, bpicked);
               indcount := indcount+1;
            end;
         end;
         {var elmHnd : Integer = _ui_CreateBtn(ui, 'newaction', elmLeft, 1, cTextNewAction, gc_halParentLeft, gc_valParentTop, treelevel*offx, indcount*offy, 30, 0, eventstate, nul, cTagNewAction, bupdate);
         var txtHnd : Integer = GetGUIElementIndexByNameParent('t'+GetGUIElementNameByIndex(elmHnd), elmHnd);
         SetGUIElementTextAlign(txtHnd, gUIConst.halign[gc_halMiddle], gUIConst.valign[gc_valMiddle], 0, 0);
         ind := ind+1;}
      end;
      treelevel := treelevel-1;
   end;
   treelevel := treelevel-1;
   
   Result := indcount;
end;

// _scenario_CheckSignCondition
//
function _scenario_CheckSignCondition(val1 : Float; sign : Integer; val2 : Float) : Boolean;
begin
   Result := False;
   case sign of
      //gc_trigger_condition_sign_none : ErrorLog('_scenario_CheckSignCondition sign=none');
      gc_trigger_condition_sign_equal : Result := (val1=val2);
      gc_trigger_condition_sign_notequal : Result := (val1<>val2);
      gc_trigger_condition_sign_more : Result := (val1>val2);
      gc_trigger_condition_sign_moreequal : Result := (val1>=val2);
      gc_trigger_condition_sign_less : Result := (val1<val2);
      gc_trigger_condition_sign_lessequal : Result := (val1<=val2);
   end;
end;

// _scenario_ShowQuery
//
procedure _scenario_ShowQuery(var queryID : String);
begin
   StringRegister0 := queryID;
   GUIExecuteState('RequestQueryWindow');
end;

// _scenario_UpdateQueries
//
procedure _scenario_UpdateQueries(var scenario : TScenario);
begin
   var queriesHnd : Integer = QueryMachineGetQueriesHandle;
   var i : Integer;
   for i:=QueryMachineQueriesCount(queriesHnd)-1 downto 0 do
   QueryMachineQueriesDelete(queriesHnd, i);
   for i:=0 to gc_scenario_maxqueries-1 do
   begin
      var pquery : Pointer = scenario.queries[i];
      var bresults : Boolean;
      var j : Integer;
      for j:=0 to gc_scenario_maxqueryresults-1 do
      begin
         var resid : Integer = TScenarioQuery(pquery).results[j];
         if (resid>=0) then
         begin
            bresults := True;
            break;
         end;
      end;
      if (bresults) then
      begin
         var name : String = TScenarioQuery(pquery).name;
         if (name<>'') then
         begin
            var queryHnd : Integer = QueryMachineQueriesGetOrAddByID(queriesHnd, name);
            var resultsHnd : Integer = QueryMachineQueryGetResults(queryHnd);
            var k : Integer;
            for k:=QueryMachineResultsCount(queryHnd)-1 downto 0 do
            QueryMachineResultsDelete(resultsHnd, k);
            var langtable : String = TScenarioQuery(pquery).langtable;
            var langkey : String = TScenarioQuery(pquery).langkey;
            var imageid : Integer = TScenarioQuery(pquery).imageid;
            var imagematerial : String;
            if (imageid>=0) then
            imagematerial := scenario.images[imageid].material;
            QueryMachineQuerySetTable(queryHnd, langtable);
            QueryMachineQuerySetKey(queryHnd, langkey);
            QueryMachineQuerySetIcon(queryHnd, imagematerial);
            for j:=0 to gc_scenario_maxqueryresults-1 do
            begin
               var rid : Integer = TScenarioQuery(pquery).results[j];
               if (rid>=0) then
               begin
                  var presult : Pointer = scenario.results[rid];
                  var rname : String = TScenarioResult(presult).name;
                  if (rname<>'') then
                  begin
                     var resultHnd : Integer = QueryMachineResultsGetOrAddByID(resultsHnd, rname);
                     var langtable : String = TScenarioResult(presult).langtable;
                     var langkey : String = TScenarioResult(presult).langkey;
                     var nextqueryid : Integer = TScenarioResult(presult).nextqueryid;
                     var nextquery : String;
                     if (nextqueryid>=0) then
                     nextquery := scenario.queries[nextqueryid].name;
                     var resulttriggerid : Integer = TScenarioResult(presult).resulttriggerid;
                     QueryMachineResultSetTable(resultHnd, langtable);
                     QueryMachineResultSetKey(resultHnd, langkey);
                     QueryMachineResultSetNextQuery(resultHnd, nextquery);
                     QueryMachineResultSetTagInteger(resultHnd, resulttriggerid);
                     QueryMachineResultSetTagFloat(resultHnd, round(rid));
                  end;
               end;
            end;
         end;
      end;
   end;
end;

procedure _scenario_UpdateUnitsGroupsID(var scenario : TScenario);
begin
   var i, j : Integer;
   for i:=gc_MaxPlayerCount-1 downto 0 do
   begin
      var plhnd : Integer = GetPlayerHandleByIndex(i);
      for j:=0 to GetPlayerGameObjectsCountByHandle(plhnd)-1 do
      begin
         var goHnd : Integer = GetGameObjectHandleByIndex(j, plhnd);
         if (_misc_GetBaseObjID(goHnd)=gc_baseid_obj) then
         begin
            var pobj : Pointer = _unit_GetTObj(goHnd);
            if (pobj<>nil) and (TObj(pobj).scenariogroupid>-1) then
            TObj(pobj).scenariogroupid := -1;
         end;
      end;
   end;
   for i:=0 to gc_scenario_maxgroups-1 do
   begin
      for j:=0 to scenario.groups[i].unitslist.GetCount-1 do
      begin
         var goHnd : Integer = scenario.groups[i].unitslist.Get(j);
         if (_misc_GetBaseObjID(goHnd)=gc_baseid_obj) then
         begin
            var pobj : Pointer = _unit_GetTObj(goHnd);
            if (pobj<>nil) then
            TObj(pobj).scenariogroupid := i;
         end;
      end;
   end;
end;

procedure _scenario_AIRegionOnInclude(const aireghnd, gohnd : Integer);
begin
   var plind : Integer = GetPlayerIndexByHandle(GetGameObjectPlayerHandleByHandle(gohnd));
   if (plind<gc_MaxPlayerCount) and (_misc_GetBaseObjID(goHnd)=gc_baseid_obj) then
   begin
      var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
      var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
      if (zoneid>=0) and (zoneid<gc_scenario_maxzones) then
      begin
         var pobj : Pointer = _unit_GetTObj(gohnd);
         if (pobj<>nil) then
         begin
            if (not TObj(pobj).bdead) then
            begin
               var bOk : Boolean = True;
               if (gScenario.zones[zoneid].bonlyungroup) and (TObj(pobj).scenariogroupid>-1) then
               bOk := False
               else
               if (gScenario.zones[zoneid].player>=0) and (TObj(pobj).pl<>gScenario.zones[zoneid].player) then
               bOk := False
               else
               if (gScenario.zones[zoneid].group>=0) and (TObj(pobj).scenariogroupid<>gScenario.zones[zoneid].group) then
               bOk := False
               else
               if (GetGameObjectVisibleByHandle(goHnd)) and ((GetGameObjectStatesTagByHandle(goHnd) and gc_statetag_essential_none)<>0) then
               begin
                  var index : Integer = gScenario.zones[zoneid].unitslist.IndexOf(gohnd);
                  if (index=-1) then
                  gScenario.zones[zoneid].unitslist.Add(gohnd);
                  if (gScenario.ui.bshowui) then
                  begin
                     index := gScenarioTmp.zones[zoneid].unitslist.IndexOf(gohnd);
                     if (index=-1) then
                     gScenarioTmp.zones[zoneid].unitslist.Add(gohnd);
                  end;
                  //Log('OnInclude : gohnd = '+IntToStr(gohnd));
               end;
            end
            else
            ErrorLog('OnInclude : gohnd = '+IntToStr(gohnd)+' bdead=true');
         end
         else
         ErrorLog('OnInclude : gohnd = '+IntToStr(gohnd)+' pobj=nil');
      end
      else
      ErrorLog('airegion out of range');
   end;
end;

procedure _scenario_AIRegionOnDeclude(const aireghnd, gohnd : Integer);
begin
   var plind : Integer = GetPlayerIndexByHandle(GetGameObjectPlayerHandleByHandle(gohnd));
   if (plind<gc_MaxPlayerCount) and (_misc_GetBaseObjID(goHnd)=gc_baseid_obj) then
   begin
      var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
      var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
      if (zoneid>=0) and (zoneid<gc_scenario_maxzones) then
      begin
         var pobj : Pointer = _unit_GetTObj(gohnd);
         if (pobj<>nil) then
         begin
            var index : Integer = gScenario.zones[zoneid].unitslist.IndexOf(gohnd);
            if (index>-1) then
            gScenario.zones[zoneid].unitslist.Delete(index);
            if (gScenario.ui.bshowui) then
            begin
               index := gScenarioTmp.zones[zoneid].unitslist.IndexOf(gohnd);
               if (index>-1) then
               gScenarioTmp.zones[zoneid].unitslist.Delete(index);
            end;
            //Log('OnDeclude : gohnd = '+IntToStr(gohnd));
         end
         else
         ErrorLog('OnDeclude : gohnd = '+IntToStr(gohnd)+' pobj=nil');
      end
      else
      ErrorLog('airegion out of range');
   end;
end;

procedure _scenario_UpdateGetAIRegionsFlags(var scenario : TScenario);
begin
   var i : Integer;
   var count : Integer = CountOfAIRegions;
   for i:=0 to count-1 do
   begin
      var aireghnd : Integer = GetAIRegionHandleByIndex(i);
      //var aireghnd : Integer = GetAIRegionHandleByName('zone'+IntToStr(i));
      if (aireghnd<>0) then
      begin
         //if (aireghnd<>tmpaireghnd) then
         //ErrorLog('_scenario_UpdateGetAIRegionsFlags : (aireghnd<>tmpaireghnd)');
         var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
         var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
         if (not StrExists(GetAIRegionNameByHandle(aireghnd), 'zone')) then
         ErrorLog('_scenario_UpdateGetAIRegionsFlags bad airegion name zoneid = '+IntToStr(zoneid));
         if (zoneid>=0) and (zoneid<(count-1)) then
         begin
            var bEnabled : Boolean = GetAIRegionEnabledByHandle(aireghnd);
            scenario.zones[zoneid].bactive := bEnabled;
         end;
      end;
   end;
end;

procedure _scenario_AIRegionForceRescan();
begin
   var i, j : Integer;
   for i:=0 to CountOfAIRegions-1 do
   begin
      var aireghnd : Integer = GetAIRegionHandleByIndex(i);
      //var aireghnd : Integer = GetAIRegionHandleByName('zone'+IntToStr(i));
      if (aireghnd<>0) then
      begin
         //if (aireghnd<>tmpaireghnd) then
         //ErrorLog('_scenario_AIRegionForceRescan : (aireghnd<>tmpaireghnd)');
         var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
         var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
         if (not StrExists(GetAIRegionNameByHandle(aireghnd), 'zone')) then
         ErrorLog('_scenario_AIRegionForceRescan bad airegion name zoneid = '+IntToStr(zoneid));
         gScenario.zones[zoneid].unitslist.Clear;
         AIRegionDoClearObjectsByHandle(aireghnd); // added to fix crash on scenario start :( sad but true
         AIRegionDoScanObjectsExtByHandle(aireghnd, False, False);
         for j:=GetAIRegionCountOfGameObjectsByHandle(aireghnd)-1 downto 0 do
         begin
            var goHnd : Integer = GetAIRegionGOHandleByGOIndexByHandle(aireghnd, j);
            _scenario_AIRegionOnInclude(aireghnd, goHnd);
         end;
      end;
   end;
end;

procedure _scenario_UpdateSetAIRegionsFlags(var scenario : TScenario);
begin
   var count : Integer = gc_scenario_maxzones;
   var i : Integer;
   for i:=0 to count-1 do
   begin
      var aireghnd : Integer = GetAIRegionHandleByIndex(i);
      //var aireghnd : Integer = GetAIRegionHandleByName('zone'+IntToStr(i));
      if (aireghnd<>0) then
      begin
         //if (aireghnd<>tmpaireghnd) then
         //ErrorLog('_scenario_UpdateSetAIRegionsFlags : (aireghnd<>tmpaireghnd)');
         var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
         var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
         if (not StrExists(GetAIRegionNameByHandle(aireghnd), 'zone')) then
         ErrorLog('_scenario_UpdateSetAIRegionsFlags bad airegion name zoneid = '+IntToStr(zoneid));
         if (zoneid>=0) and (zoneid<(count-1)) then
         begin
            if ((scenario.zones[zoneid].w>0) and (scenario.zones[zoneid].h>0)) or
            ((scenario.zones[zoneid].blinkgroup) and (scenario.groups[scenario.zones[zoneid].linkgroup].unitslist.GetCount>0)) then
            begin
               var bAiRegionPrevState : Boolean = GetAIRegionEnabledByHandle(aireghnd);
               if (bAiRegionPrevState) and (not scenario.zones[zoneid].bactive) then
               begin
                  var j : Integer;
                  for j:=GetAIRegionCountOfGameObjectsByHandle(aireghnd)-1 downto 0 do
                  begin
                     var goHnd : Integer = GetAIRegionGOHandleByGOIndexByHandle(aireghnd, j);
                     _scenario_AIRegionOnDeclude(aireghnd, goHnd);
                  end;
                  AIRegionDoClearObjectsByHandle(aireghnd);
                  scenario.zones[zoneid].unitslist.Clear;
                  SetAIRegionEnabledByHandle(aireghnd, False);
               end
               else
               if (not bAiRegionPrevState) and (scenario.zones[zoneid].bactive) then
               begin
                  SetAIRegionEnabledByHandle(aireghnd, True);
                  scenario.zones[zoneid].unitslist.Clear;
                  AIRegionDoClearObjectsByHandle(aireghnd); // added to fix crash on scenario start :( sad but true
                  AIRegionDoScanObjectsExtByHandle(aireghnd, False, False);
                  var j : Integer;
                  for j:=GetAIRegionCountOfGameObjectsByHandle(aireghnd)-1 downto 0 do
                  begin
                     var goHnd : Integer = GetAIRegionGOHandleByGOIndexByHandle(aireghnd, j);
                     _scenario_AIRegionOnInclude(aireghnd, goHnd);
                  end;
               end;
            end;
         end;
      end;
   end;
end;

function _scenario_GetAIRegionHandleByZoneID(var scenario : TScenario; const zoneid : Integer) : Integer;
begin
   Result := 0;
   var i : Integer;
   for i:=0 to gc_scenario_maxzones-1 do
   begin
      var zonename : String = 'zone'+IntToStr(i);
      var aireghnd : Integer = GetAIRegionHandleByName(zonename);
      var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
      var tmpzoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
      if (zoneid=tmpzoneid) then
      begin
         Result := aireghnd;
         break;
      end;
   end;
end;

procedure _scenario_SetAIRegionPosition(const aireghnd : Integer; const posx, posy : Float);
begin
   var minx, maxx, miny, maxy : Float;
   GetAIRegionExtendsByHandle(aireghnd, minx, miny, maxx, maxy);
   var hw : Float = Abs(maxx-minx)/2;
   var hh : Float = Abs(maxy-miny)/2;
   if (minx<>(posx-hw)) or (miny<>(posy-hh)) or (maxx<>(posx+hw)) or (maxy<>(posy+hh)) then
   SetAIRegionExtendsByHandle(aireghnd, posx-hw, posy-hh, posx+hw, posy+hh);
end;

procedure _scenario_SetAIRegionPositionRect(const aireghnd : Integer; const posx, posy, width, height : Float);
begin
   var hw, hh : Float;
   var minx, maxx, miny, maxy : Float;
   if (width=0) or (height=0) then
   GetAIRegionExtendsByHandle(aireghnd, minx, miny, maxx, maxy);
   if (width=0) then
   hw := Abs(maxx-minx)/2
   else
   hw := width/2;
   if (height=0) then
   hh := Abs(maxy-miny)/2
   else
   hh := height/2;
   if (minx<>(posx-hw)) or (miny<>(posy-hh)) or (maxx<>(posx+hw)) or (maxy<>(posy+hh)) then
   SetAIRegionExtendsByHandle(aireghnd, posx-hw, posy-hh, posx+hw, posy+hh);
end;

procedure _scenario_ModifyAIRegionPositionRect(var scenario : TScenario; const zoneid : Integer; const posx, posy, width, height : Float);
begin
   var zonename : String = 'zone'+IntToStr(zoneid);
   var tmpzoneid : Integer = -1;
   var aireghnd : Integer = GetAIRegionHandleByName(zonename);
   if (aireghnd<>0) then
   begin
      var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
      tmpzoneid := StateMachineGetIntValueByIndex(smhnd, 0);
   end;
   if (zoneid=tmpzoneid) then
   _scenario_SetAIRegionPositionRect(aireghnd, posx, posy, width, height)
   else
   begin
      aireghnd := _scenario_GetAIRegionHandleByZoneID(scenario, zoneid);
      if (aireghnd<>0) then
      _scenario_SetAIRegionPositionRect(aireghnd, posx, posy, width, height);
   end;
end;

procedure _scenario_SetAIRegionRectToUnitsList(var list : TIntegerList; zoneid : Integer; addmargin : Float; bUpdateIfChanged, bUseAverageRect : Boolean);
begin
   // bUseAverageRect - for single squad
   // not bUseAverageRect - for army, that contains more then 1 squad;
   var aireghnd : Integer = _scenario_GetAIRegionHandleByZoneID(gScenario, zoneid);
   if (aireghnd<>0) and (list.GetCount>0) then
   begin
      var cpx, cpz : Float;
      _misc_GetUnitsListCentralPos(list, cpx, cpz);
      
      var lx, rx, tx, bx : Float;
      var ly, ry, ty, by : Float;
      var minx, maxx : Float = cpx;
      var miny, maxy : Float = cpz;
      var lc, rc, tc, bc : Integer;
      
      var i : Integer;
      for i:=list.GetCount-1 downto 0 do
      begin
         var bright, bleft, btop, bbottom : Boolean;
         var goHnd : Integer = list.Get(i);
         var goX : Float = GetGameObjectPositionXByHandle(goHnd);
         var goZ : Float = GetGameObjectPositionZByHandle(goHnd);
         if (goX<minx) then minx := goX;
         if (goX>maxx) then maxx := goX;
         if (goZ<miny) then miny := goZ;
         if (goZ>maxy) then maxy := goZ;
         if (goX>=cpx) then bright := True
         else
         bleft := True;
         if (goZ>=cpz) then bbottom := True
         else
         btop := True;
         if (bLeft) then
         begin
            lx := lx+goX;
            lc := lc+1;
         end
         else
         if (bRight) then
         begin
            rx := rx+goX;
            rc := rc+1;
         end;
         if (bTop) then
         begin
            ty := ty+goZ;
            tc := tc+1;
         end
         else
         if (bBottom) then
         begin
            by := by+goZ;
            bc := bc+1;
         end;
      end;
      const cBaseMargin = 3;
      var newminx, newminy, newmaxx, newmaxy : Float;
      var summargin : Float;
      if (bUseAverageRect) then
      begin
         summargin := cBaseMargin+addmargin;
         if (lc>0) then lx := lx/lc else lx := cpx;
         if (rc>0) then rx := rx/rc else rx := cpx;
         if (tc>0) then ty := ty/tc else ty := cpz;
         if (bc>0) then by := by/bc else by := cpz;
         newminx := lx-summargin;
         newminy := ty-summargin;
         newmaxx := rx+summargin;
         newmaxy := by+summargin;
      end
      else
      begin
         summargin := addmargin;
         newminx := minx-summargin;
         newminy := miny-summargin;
         newmaxx := maxx+summargin;
         newmaxy := maxy+summargin;
      end;
      var bUpdated : Boolean;
      if (bUpdateIfChanged) then
      begin
         var curminx, curmaxx, curminy, curmaxy : Float;
         GetAIRegionExtendsByHandle(aireghnd, curminx, curminy, curmaxx, curmaxy);
         if (curminx<>newminx) or (curminy<>newminy) or (curmaxx<>newmaxx) or (curmaxy<>newmaxy) then
         bUpdated := True;
      end
      else
      bUpdated := True;
      
      if (bUpdated) then
      begin
         SetAIRegionExtendsByHandle(aireghnd, newminx, newminy, newmaxx, newmaxy);
         gScenario.zones[zoneid].x := (newminx+newmaxx)/2;
         gScenario.zones[zoneid].y := (newminy+newmaxy)/2;
         gScenario.zones[zoneid].w := Abs(newminx-newmaxx);
         gScenario.zones[zoneid].h := Abs(newminy-newmaxy);
      end;
   end;
end;

procedure _scenario_UpdateAIRegions(var scenario : TScenario);
begin
   var i : Integer;
   for i:=0 to gc_scenario_maxzones-1 do
   begin
      var zoneid : Integer = i;
      if ((scenario.zones[zoneid].w>0) and (scenario.zones[zoneid].h>0)) or
      ((scenario.zones[zoneid].blinkgroup) {and (scenario.groups[scenario.zones[zoneid].linkgroup].unitslist.GetCount>0)}) then
      begin
         var zonename : String = 'zone'+IntToStr(zoneid);
         var aireghnd : Integer = GetAIRegionHandleByName(zonename);
         if (aireghnd=0) then
         begin
            aireghnd := CreateAIRegion(zonename);
            SetAIRegionScanModeByHandle(aireghnd, 0);
            SetAIRegionOnIncludeByHandle(aireghnd, '_scenario_AIRegionOnInclude');
            SetAIRegionOnDecludeByHandle(aireghnd, '_scenario_AIRegionOnDeclude');
            SetAIRegionExecuteAsFuncByHandle(aireghnd, True);
         end;
         if (scenario.zones[zoneid].blinkgroup) and (scenario.zones[zoneid].unitslist.GetCount>0) then
         _scenario_SetAIRegionRectToUnitsList(scenario.groups[scenario.zones[zoneid].linkgroup].unitslist, zoneid, scenario.zones[zoneid].addradius, False, scenario.zones[zoneid].buseaverage)
         else
         begin
            var minx, maxx, miny, maxy : Float;
            GetAIRegionExtendsByHandle(aireghnd, minx, miny, maxx, maxy);
            if (minx<>(scenario.zones[zoneid].x-scenario.zones[zoneid].w/2)) or (miny<>(scenario.zones[zoneid].y-scenario.zones[zoneid].h/2)) or (maxx<>(scenario.zones[zoneid].x+scenario.zones[zoneid].w/2)) or (maxy<>(scenario.zones[zoneid].y+scenario.zones[zoneid].h/2)) then
            SetAIRegionExtendsByHandle(aireghnd, scenario.zones[zoneid].x-scenario.zones[zoneid].w/2, scenario.zones[zoneid].y-scenario.zones[zoneid].h/2, scenario.zones[zoneid].x+scenario.zones[zoneid].w/2, scenario.zones[zoneid].y+scenario.zones[zoneid].h/2);
         end;
         var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
         StateMachineLoadFromFile(smhnd, '.\data\scripts\misc\airegion.aix');
         StateMachineSetIntValueByName(smhnd, 'id', zoneid);
      end;
   end;
   _scenario_UpdateSetAIRegionsFlags(scenario);
end;

procedure _scenario_UpdateAIRegionsActiveStateToTriggers(var scenario : TScenario);
begin
   // turn ai regions that exists in active triggers conditions
   if (scenario.bactive) then
   begin
      var i, j, k : Integer;
      for i:=0 to CountOfAIRegions-1 do
      begin
         var aireghnd : Integer = GetAIRegionHandleByIndex(i);
         //var aireghnd : Integer = GetAIRegionHandleByName('zone'+IntToStr(i));
         if (aireghnd<>0) then
         begin
            //if (aireghnd<>tmpaireghnd) then
            //ErrorLog('_scenario_UpdateAIRegionsActiveStateToTriggers : (aireghnd<>tmpaireghnd)');
            var smhnd : Integer = GetAIRegionStateMachineHandle(aireghnd);
            var zoneid : Integer = StateMachineGetIntValueByIndex(smhnd, 0);
            if (not StrExists(GetAIRegionNameByHandle(aireghnd), 'zone')) then
            ErrorLog('_scenario_UpdateAIRegionsActiveStateToTriggers bad airegion name zoneid = '+IntToStr(zoneid));
            var bexists : Boolean;
            if (zoneid>=0) and (zoneid<(gc_scenario_maxzones-1)) then
            begin
               if (scenario.zones[zoneid].blinkgroup) and (scenario.groups[scenario.zones[zoneid].linkgroup].unitslist.GetCount>0) then
               bexists := True
               else
               for [MAIN]j:=0 to gc_scenario_maxtriggers-1 do
               begin
                  if (scenario.triggers[j].bactive) then
                  begin
                     for k:=0 to gc_trigger_maxconditions-1 do
                     begin
                        var conditionid : Integer = scenario.triggers[j].conditions[k].id;
                        if (zoneid=scenario.triggers[j].conditions[k].zoneid) and ((conditionid=gc_trigger_condition_units_CountOfGroupUnitsInZone) or (conditionid=gc_trigger_condition_units_CountOfPlayerUnitsInZone) or (conditionid=gc_trigger_condition_units_CountOfPlayersTeamUnitsInZone) or (conditionid=gc_trigger_condition_units_CountOfUnitsInZone)) then
                        begin
                           bexists := True;
                           break(MAIN);
                        end;
                     end;
                     for k:=0 to  gc_trigger_maxactions-1 do
                     begin
                        var actionid : Integer = scenario.triggers[j].actions[k].id;
                        if (zoneid=scenario.triggers[j].actions[k].zoneid) and
                        ((actionid=gc_trigger_action_group_AddUnitsInZoneToGroup) or
                        (actionid=gc_trigger_action_group_AddUnitsOfGroupInZoneToGroup) or
                        (actionid=gc_trigger_action_group_AddUnitsOfPlayerInZoneToGroup) or
                        (actionid=gc_trigger_action_group_AddSpecificUnitsOfPlayerInZoneToGroup) or
                        (actionid=gc_trigger_action_order_findAndAttackEnemyInZone) or
                        (actionid=gc_trigger_action_order_ArtilleryAttackZoneCenterWithDispertion)) then
                        begin
                           bexists := True;
                           break(MAIN);
                        end;
                     end;
                  end;
               end;
               scenario.zones[zoneid].bactive := bexists;
            end;
         end;
      end;
      _scenario_UpdateSetAIRegionsFlags(scenario);
   end;
end;

// _scenario_CheckTriggerConditions
//
function _scenario_CheckTriggerConditions(ptrigger : Pointer) : Boolean;
begin
   Result := False;
   var bConditionsOK, bPrevIsConditionOK : Boolean = True;
   var j : Integer;
   for j:=0 to gc_trigger_maxconditions-1 do
   begin
      var bPrevIsOR, bNextIsOR : Boolean;
      if (j>0) and (TScenarioTrigger(ptrigger).conditions[j-1].id=gc_trigger_condition_logical_OR) then
      bPrevIsOR := True;
      if (j<(gc_trigger_maxconditions-1)) and (TScenarioTrigger(ptrigger).conditions[j+1].id=gc_trigger_condition_logical_OR) then
      bNextIsOR := True;
      if (bNextIsOR) or (TScenarioTrigger(ptrigger).conditions[j].id=gc_trigger_condition_logical_OR) then
      bNextIsOR := True;
      if (TScenarioTrigger(ptrigger).conditions[j].id=gc_trigger_condition_logical_OR) then
      begin
         bPrevIsOR := True;
         bNextIsOR := True;
      end;
      if (bNextIsOR) then
      bPrevIsConditionOK := bConditionsOK;
      if (TScenarioTrigger(ptrigger).conditions[j].id<>gc_trigger_condition_none) and (TScenarioTrigger(ptrigger).conditions[j].id<>gc_trigger_condition_undefined) and (TScenarioTrigger(ptrigger).conditions[j].bactive) then
      begin
         var ptriggercondition : Pointer = TScenarioTrigger(ptrigger).conditions[j];
         // update amount and time corresponding to counter value if this condition use conterasamount
         if (TScenarioTriggerCondition(ptriggercondition).busecounterasamount) then
         case TScenarioTriggerCondition(ptriggercondition).id of
            gc_trigger_condition_counterValue, gc_trigger_condition_playerResources, gc_trigger_condition_units_CountOfUnitsInGroup, gc_trigger_condition_units_CountOfGroupUnitsInZone, gc_trigger_condition_units_CountOfPlayerUnitsInZone, gc_trigger_condition_units_CountOfUnitsInZone, gc_trigger_condition_units_CountOfPlayerUnits, {gc_trigger_condition_executeState, gc_trigger_condition_resultExecutedCount,} gc_trigger_condition_units_CountOfPlayerUnitsInGroup, gc_trigger_condition_units_CountOfPlayersTeamUnitsInZone, gc_trigger_condition_units_CountOfActingUnitsInGroup,
            gc_trigger_condition_net_CurrentPlayer, gc_trigger_condition_net_CurrentPlayerTeam, gc_trigger_condition_net_CurrentPlayerPosition : begin
               TScenarioTriggerCondition(ptriggercondition).amount := gScenario.counters[TScenarioTriggerCondition(ptriggercondition).usecounterid].value;
            end;
         end;
         // update amount and time corresponding to counter value if this condition use conterastime
         if (TScenarioTriggerCondition(ptriggercondition).busecounterasamount) then
         case TScenarioTriggerCondition(ptriggercondition).id of
            gc_trigger_condition_triggerIsActiveTime : begin
               if (TScenarioTriggerCondition(ptriggercondition).busecounterastime) then
               TScenarioTriggerCondition(ptriggercondition).time := gScenario.counters[TScenarioTriggerCondition(ptriggercondition).usecounterid].value;
            end;
         end;
         case TScenarioTriggerCondition(ptriggercondition).id of
            gc_trigger_condition_triggerIsActive : bConditionsOK := gScenario.triggers[TScenarioTriggerCondition(ptriggercondition).triggerid].bactive;
            gc_trigger_condition_triggerIsNotActive : bConditionsOK := (not gScenario.triggers[TScenarioTriggerCondition(ptriggercondition).triggerid].bactive);
            gc_trigger_condition_flagActive : bConditionsOK := (gScenario.flags[TScenarioTriggerCondition(ptriggercondition).flagid].bactive);
            gc_trigger_condition_flagNotActive : bConditionsOK := (not gScenario.flags[TScenarioTriggerCondition(ptriggercondition).flagid].bactive);
            gc_trigger_condition_counterValue : begin
               bConditionsOK := (gScenario.flags[TScenarioTriggerCondition(ptriggercondition).flagid].bactive);
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               bConditionsOK := _scenario_CheckSignCondition(gScenario.counters[TScenarioTriggerCondition(ptriggercondition).counterid].value, sign, amount)
            end;
            gc_trigger_condition_timerFinished : bConditionsOK := (gScenario.timers[TScenarioTriggerCondition(ptriggercondition).timerid].bfinished);
            gc_trigger_condition_timerNotFinished : bConditionsOK := (not gScenario.timers[TScenarioTriggerCondition(ptriggercondition).timerid].bfinished);
            gc_trigger_condition_difficulty : bConditionsOK := (gScenario.difficulty=TScenarioTriggerCondition(ptriggercondition).difficulty);
            gc_trigger_condition_playerResources : begin
               var pl : Integer = TScenarioTriggerCondition(ptriggercondition).player;
               var res : Integer = TScenarioTriggerCondition(ptriggercondition).resource;
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               if (res>gc_resource_type_none) then
               bConditionsOK := _scenario_CheckSignCondition(gPlayer[pl].res[res], sign, amount)
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_units_CountOfUnitsInGroup : begin
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               var groupid : Integer = TScenarioTriggerCondition(ptriggercondition).groupid;
               bConditionsOK := _scenario_CheckSignCondition(gScenario.groups[groupid].unitslist.GetCount, sign, amount);
            end;
            gc_trigger_condition_units_CountOfGroupUnitsInZone : begin
               var zoneid : Integer = TScenarioTriggerCondition(ptriggercondition).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  var groupid : Integer = TScenarioTriggerCondition(ptriggercondition).groupid;
                  var x : Float = gScenario.zones[zoneid].x;
                  var y : Float = gScenario.zones[zoneid].y;
                  var w : Float = gScenario.zones[zoneid].w;
                  var h : Float = gScenario.zones[zoneid].h;
                  var count : Integer;
                  var k : Integer;
                  for k:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var hnd : Integer = gScenario.zones[zoneid].unitslist.Get(k);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(hnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(hnd);
                        if (pobj<>nil) then
                        begin
                           if (groupid=TObj(pobj).scenariogroupid) then
                           count := count+1;
                           if (count>amount) then
                           break;
                        end;
                     end
                     else
                     ErrorLog('gc_trigger_condition_units_CountOfGroupUnitsInZone : invalid uid. hnd='+IntToStr(hnd)+' zone='+IntToStr(zoneid)+' k='+IntToStr(k)+' count='+IntToStr(gScenario.zones[zoneid].unitslist.GetCount));
                  end;
                  bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
               end
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_units_CountOfPlayerUnitsInZone : begin
               var zoneid : Integer = TScenarioTriggerCondition(ptriggercondition).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var pl : Integer = TScenarioTriggerCondition(ptriggercondition).player;
                  var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  var bIncludeBuildings : Boolean = TScenarioTriggerCondition(ptriggercondition).bstate;
                  var x : Float = gScenario.zones[zoneid].x;
                  var y : Float = gScenario.zones[zoneid].y;
                  var w : Float = gScenario.zones[zoneid].w;
                  var h : Float = gScenario.zones[zoneid].h;
                  var count : Integer;
                  var k : Integer;
                  for k:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var hnd : Integer = gScenario.zones[zoneid].unitslist.Get(k);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(hnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(hnd);
                        if (pobj<>nil) then
                        begin
                           if (pl=TObj(pobj).pl) and ((bIncludeBuildings) or (not gObjProp[TObj(pObj).cid][TObj(pObj).id].bbuilding)) then
                           count := count+1;
                           if (count>amount) then
                           break;
                        end;
                     end
                     else
                     ErrorLog('gc_trigger_condition_units_CountOfPlayerUnitsInZone : invalid uid. hnd='+IntToStr(hnd)+' zone='+IntToStr(zoneid)+' k='+IntToStr(k)+' count='+IntToStr(gScenario.zones[zoneid].unitslist.GetCount));
                  end;
                  bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
               end
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_units_CountOfPlayersTeamUnitsInZone : begin
               var zoneid : Integer = TScenarioTriggerCondition(ptriggercondition).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var pl : Integer = TScenarioTriggerCondition(ptriggercondition).player;
                  var team : Integer = gPlayer[pl].team;
                  var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  var bIncludeBuildings : Boolean = TScenarioTriggerCondition(ptriggercondition).bstate;
                  var x : Float = gScenario.zones[zoneid].x;
                  var y : Float = gScenario.zones[zoneid].y;
                  var w : Float = gScenario.zones[zoneid].w;
                  var h : Float = gScenario.zones[zoneid].h;
                  var count : Integer;
                  var k : Integer;
                  for k:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var hnd : Integer = gScenario.zones[zoneid].unitslist.Get(k);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(hnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(hnd);
                        if (pobj<>nil) then
                        begin
                           if (team=gPlayer[TObj(pobj).pl].team) and ((bIncludeBuildings) or (not gObjProp[TObj(pObj).cid][TObj(pObj).id].bbuilding)) then
                           count := count+1;
                           if (count>amount) then
                           break;
                        end;
                     end
                     else
                     ErrorLog('gc_trigger_condition_units_CountOfPlayersTeamUnitsInZone : invalid uid. hnd='+IntToStr(hnd)+' zone='+IntToStr(zoneid)+' k='+IntToStr(k)+' count='+IntToStr(gScenario.zones[zoneid].unitslist.GetCount));
                  end;
                  bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
               end
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_units_CountOfUnitsInZone : begin
               var zoneid : Integer = TScenarioTriggerCondition(ptriggercondition).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  var bIncludeBuildings : Boolean = TScenarioTriggerCondition(ptriggercondition).bstate;
                  var x : Float = gScenario.zones[zoneid].x;
                  var y : Float = gScenario.zones[zoneid].y;
                  var w : Float = gScenario.zones[zoneid].w;
                  var h : Float = gScenario.zones[zoneid].h;
                  var count : Integer;
                  var k : Integer;
                  for k:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var hnd : Integer = gScenario.zones[zoneid].unitslist.Get(k);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(hnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(hnd);
                        if (pobj<>nil) then
                        begin
                           if ((bIncludeBuildings) or (not gObjProp[TObj(pObj).cid][TObj(pObj).id].bbuilding)) then
                           count := count+1;
                           if (count>amount) then
                           break;
                        end;
                     end
                     else
                     ErrorLog('gc_trigger_condition_units_CountOfUnitsInZone : invalid uid. hnd='+IntToStr(hnd)+' zone='+IntToStr(zoneid)+' k='+IntToStr(k)+' count='+IntToStr(gScenario.zones[zoneid].unitslist.GetCount));
                  end;
                  bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
               end
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_units_CountOfPlayerUnits : begin
               var pl : Integer = TScenarioTriggerCondition(ptriggercondition).player;
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               var bIncludeBuildings : Boolean = TScenarioTriggerCondition(ptriggercondition).bstate;
               var count : Integer;
               if (bIncludeBuildings) then
               count := gPlayer[pl].counter.total
               else
               count := gPlayer[pl].counter.farmused;
               bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
            end;
            gc_trigger_condition_units_CountOfPlayerUnitsInGroup : begin
               var pl : Integer = TScenarioTriggerCondition(ptriggercondition).player;
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               var groupid : Integer = TScenarioTriggerCondition(ptriggercondition).groupid;
               var count : Integer;
               var k : Integer;
               for k:=gScenario.groups[groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var hnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  var uid : Integer = GetGameObjectUniqueIdByHandle(hnd); // debug issue
                  if (uid<>0) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(hnd);
                     if (pobj<>nil) then
                     begin
                        if (groupid=TObj(pobj).scenariogroupid) and (pl=TObj(pobj).pl) then
                        count := count+1;
                        if (count>amount) then
                        break;
                     end;
                  end
                  else
                  ErrorLog('gc_trigger_condition_units_CountOfPlayerUnitsInGroup : invalid uid');
               end;
               bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
            end;
            gc_trigger_condition_units_CountOfActingUnitsInGroup : begin
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               var groupid : Integer = TScenarioTriggerCondition(ptriggercondition).groupid;
               var count : Integer;
               var k : Integer;
               for k:=gScenario.groups[groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var hnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  var statetag : Integer = GetGameObjectStatesTagByHandle(hnd);
                  if ((statetag and gc_statetag_move_walk)<>0) or ((statetag and gc_statetag_action_none)=0) then
                  count := count+1;
               end;
               bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
            end;
            gc_trigger_condition_triggerIsActiveTime : begin
               if (TScenarioTrigger(ptrigger).activetime>0) then
               begin
                  var delta : Float = (GetGameTime-gScenario.triggers[TScenarioTriggerCondition(ptriggercondition).triggerid].activetime)*1000;
                  if (delta<TScenarioTriggerCondition(ptriggercondition).time) then
                  bConditionsOK := False;
               end
               else
               bConditionsOK := False;
            end;
            gc_trigger_condition_resultExecutedCount : begin
               var resultid : Integer = TScenarioTriggerCondition(ptriggercondition).resultid;
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               bConditionsOK := _scenario_CheckSignCondition(gScenario.results[resultid].executecount, sign, amount);
            end;
            gc_trigger_condition_executeState : begin
               var smHnd : Integer = GetTriggerManagerStateMachineHandle('trigger0');
               if (smHnd<>0) then
               begin
                  var statename : String = TScenarioTriggerCondition(ptriggercondition).executestate;
                  IntRegister0 := gScenario.counters[TScenarioTriggerCondition(ptriggercondition).counterid].value;
                  StringRegister0 := TScenarioTriggerCondition(ptriggercondition).stringregister;
                  StateMachineExecuteState(smHnd, statename, 0);
                  var result : Integer = IntRegister0;
                  var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  bConditionsOK := _scenario_CheckSignCondition(result, sign, amount);
               end;
            end;
            gc_trigger_condition_net_IsServer : begin
               bConditionsOK := _net_IsServer;
            end;
            gc_trigger_condition_net_IsClient : begin
               bConditionsOK := _net_IsClient;
            end;
            gc_trigger_condition_net_IsOnline : begin
               bConditionsOK := _net_IsOnline;
            end;
            gc_trigger_condition_net_IsOffline : begin
               var myplind : Integer = GetPlayerIndexInterfaceIO;
               bConditionsOK := (_net_IsOffline) and (gInterface.gamemode=gc_gamemode_game) and (gPlayer[myplind].victorystate=gc_player_victorystate_none);
            end;
            gc_trigger_condition_net_IsQueryDialogVisible : begin
               var bstate : Boolean = TScenarioTriggerCondition(ptriggercondition).bstate;
               bConditionsOK := (gbool_gui_querywindow=bstate);
            end;
            gc_trigger_condition_net_CurrentPlayer : begin
               var myplind : Integer = GetPlayerIndexInterfaceIO;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               bConditionsOK := (myplind=amount);
            end;
            gc_trigger_condition_net_CurrentPlayerTeam : begin
               var myplind : Integer = GetPlayerIndexInterfaceIO;
               if (myplind>=0) and (myplind<gc_MaxPlayerCount) then
               begin
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  bConditionsOK := (gMap.players[myplind].team=amount);
               end;
            end;
            gc_trigger_condition_net_CurrentPlayerPosition : begin
               var myplind : Integer = GetPlayerIndexInterfaceIO;
               if (myplind>=0) and (myplind<gc_MaxPlayerCount) then
               begin
                  var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
                  bConditionsOK := (gMap.players[myplind].cid=amount);
               end;
            end;
            gc_trigger_condition_net_CountOfPlayersInTeam : begin
               var sign : Integer = TScenarioTriggerCondition(ptriggercondition).sign;
               var amount : Integer = TScenarioTriggerCondition(ptriggercondition).amount;
               var count : Integer;
               var i : Integer;
               for i:=0 to gc_MaxPlayerCount-1 do
               if (gMap.players[i].bexists) and (gMap.players[i].team=gScenario.counters[TScenarioTriggerCondition(ptriggercondition).counterid].value) then
               count := count+1;
               bConditionsOK := _scenario_CheckSignCondition(count, sign, amount);
            end;
         end;
      end;
      if (not bConditionsOK) and (bPrevIsOR) and (bPrevIsConditionOK) then
      bConditionsOK := bPrevIsConditionOK;
      if (not bConditionsOK) and (not bPrevIsOR) and (not bPrevIsConditionOK) then
      break;
      if (not bConditionsOK) and (not bNextIsOR) then
      break;
   end;
   Result := bConditionsOK;
end;

// _scenario_EvaluateTriggerActions
//
procedure _scenario_EvaluateTriggerActions(ptrigger : Pointer);
begin
   var bupdateally: Boolean;
   var j : Integer;
   var myplind : Integer = GetPlayerIndexInterfaceIO;
   if (_net_IsOnline) then
   begin
      var bnetexists : Boolean;
      for j:=0 to gc_trigger_maxactions-1 do
      begin
         if (TScenarioTrigger(ptrigger).actions[j].id<>gc_trigger_action_none) and (TScenarioTrigger(ptrigger).actions[j].bactive) then
         begin
            var ptriggeraction : Pointer = TScenarioTrigger(ptrigger).actions[j];
            case TScenarioTriggerAction(ptriggeraction).id of
               gc_trigger_action_net_SetTriggerActive, gc_trigger_action_net_SetFlagState, gc_trigger_action_net_SetCounterValue, gc_trigger_action_net_ExecuteTriggerActions : begin
                  if (TScenarioTrigger(ptrigger).actions[j].player<>myplind) then
                  begin
                     bnetexists := True;
                     break;
                  end;
               end;
               gc_trigger_action_net_TeamSetTriggerActive, gc_trigger_action_net_TeamSetFlagState, gc_trigger_action_net_TeamSetCounterValue, gc_trigger_action_net_TeamExecuteTriggerActions : begin
                  bnetexists := True;
                  break;
               end;
            end;
         end;
      end;
      if (bnetexists) then
      _scenario_WriteScenario(ptrigger);
   end;
   for j:=0 to gc_trigger_maxactions-1 do
   begin
      if (TScenarioTrigger(ptrigger).actions[j].id<>gc_trigger_action_none) and (TScenarioTrigger(ptrigger).actions[j].bactive) then
      begin
         var ptriggeraction : Pointer = TScenarioTrigger(ptrigger).actions[j];
         case TScenarioTriggerAction(ptriggeraction).id of
            gc_trigger_action_none : begin
            end;
            gc_trigger_action_service_timerStartCustom : begin
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bstarted := True;
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bfinished := False;
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].starttime := GetGameTime;
               if (TScenarioTriggerAction(ptriggeraction).busecounterastime) then
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time := TScenarioTriggerAction(ptriggeraction).time;
            end;
            gc_trigger_action_service_timerStart : begin
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bstarted := True;
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bfinished := False;
               gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].starttime := GetGameTime;
            end;
            gc_trigger_action_service_timerStop : begin
               if (gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bstarted) then
               begin
                  gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bstarted := False;
                  gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].bfinished := False;
                  gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time := (1000*(gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].starttime-GetGameTime)+gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time);
                  if (gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time<0) then
                  gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].time := 0;
                  gScenario.timers[TScenarioTriggerAction(ptriggeraction).timerid].starttime := GetGameTime;
               end;
            end;
            gc_trigger_action_service_flagSetActive : gScenario.flags[TScenarioTriggerAction(ptriggeraction).flagid].bactive := True;
            gc_trigger_action_service_flagSetNotActive : gScenario.flags[TScenarioTriggerAction(ptriggeraction).flagid].bactive := False;
            gc_trigger_action_service_counterAddValue, gc_trigger_action_service_counterRemoveValue, gc_trigger_action_service_counterSetValue : begin
               var amount : Integer;
               if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
               amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               amount := TScenarioTriggerAction(ptriggeraction).amount;
               if (TScenarioTriggerAction(ptriggeraction).bstate) then
               amount := floor(Random*(amount+1));
               case TScenarioTriggerAction(ptriggeraction).id of
                  gc_trigger_action_service_counterAddValue : gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value := gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value+amount;
                  gc_trigger_action_service_counterRemoveValue : gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value := gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value-amount;
                  gc_trigger_action_service_counterSetValue : gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value := amount;
               end;
            end;
            gc_trigger_action_resource_resourceAdd, gc_trigger_action_resource_resourceRemove, gc_trigger_action_resource_resourceSet : begin
               var amount : Integer;
               if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
               amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               amount := TScenarioTriggerAction(ptriggeraction).amount;
               case TScenarioTriggerAction(ptriggeraction).id of
                  gc_trigger_action_resource_resourceAdd : _res_AddResToPlayerByIndex(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).resource, amount);
                  gc_trigger_action_resource_resourceRemove : _res_AddResToPlayerByIndex(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).resource, -amount);
                  gc_trigger_action_resource_resourceSet : _res_SetResToPlayerByIndex(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).resource, amount);
               end;
            end;
            gc_trigger_action_objective_objectiveShow : begin
               gScenario.objectives[TScenarioTriggerAction(ptriggeraction).objectiveid].gametime := GetGameTime;
               gScenario.objectives[TScenarioTriggerAction(ptriggeraction).objectiveid].bvisible := True;
               gInterface.showobjectivestimer := GetCurrentTime;
               gInterface.bupdateobjectivestext := True;
            end;
            gc_trigger_action_objective_objectiveHide : begin
               gScenario.objectives[TScenarioTriggerAction(ptriggeraction).objectiveid].bvisible := False;
               gInterface.showobjectivestimer := GetCurrentTime;
               gInterface.bupdateobjectivestext := True;
            end;
            gc_trigger_action_objective_objectiveSetDone : begin
               gScenario.objectives[TScenarioTriggerAction(ptriggeraction).objectiveid].bdone := True;
               gInterface.showobjectivestimer := GetCurrentTime;
               gInterface.bupdateobjectivestext := True;
            end;
            gc_trigger_action_map_cameraMoveToZone : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               _control_MoveCameraToPosition(gScenario.zones[zoneid].x, gScenario.zones[zoneid].y, 0, True);
            end;
            gc_trigger_action_map_revealZone : begin
               var bstate : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               var radius : Float = TScenarioTriggerAction(ptriggeraction).radius;
               var x : Float = gScenario.zones[zoneid].x;
               var z : Float = gScenario.zones[zoneid].y;
               if (bstate) then
               _misc_GetOrCreateFogReveal(x, z, radius)
               else
               _misc_RemoveFogReveal(x, z);
               if (GetFOWEnable) then
               FOWBuildFull;
               log('Scenario : TODO : gc_trigger_action_map_revealZone zoneid='+IntToStr(zoneid)+' radius='+FloatToStr(radius));
            end;
            gc_trigger_action_query_queryShow : begin
               var queryid : Integer = TScenarioTriggerAction(ptriggeraction).queryid;
               _scenario_ShowQuery(gScenario.queries[queryid].name);
            end;
            gc_trigger_action_selection_selectionAddGroup : log('Scenario : TODO : gc_trigger_action_selection_selectionAddGroup');
            gc_trigger_action_selection_selectionAddUnitsInZone : log('Scenario : TODO : gc_trigger_action_selection_selectionAddUnitsInZone');
            gc_trigger_action_selection_selectionClear : log('Scenario : TODO : gc_trigger_action_selection_selectionClear');
            gc_trigger_action_group_Clear : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) and (TObj(pobj).scenariogroupid>-1) then
                  begin
                     gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                     if (gScenario.ui.bshowui) then
                     gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                     TObj(pobj).scenariogroupid := -1;
                     AIRegionDoUpdateObject(0, goHnd, True);
                  end;
               end;
               //_scenario_UpdateAIRegions(gScenario);
            end;
            gc_trigger_action_group_AddUnitsOfGroupToGroup : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  if (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     if (pobj<>nil) and (TObj(pobj).scenariogroupid>-1) then
                     begin
                        gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                        if (gScenario.ui.bshowui) then
                        gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                     end;
                     gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                     if (gScenario.ui.bshowui) then
                     gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                     TObj(pobj).scenariogroupid := groupidtrg;
                     AIRegionDoUpdateObject(0, goHnd, True);
                  end;
               end;
               //_scenario_UpdateAIRegions(gScenario);
            end;
            gc_trigger_action_group_AddUnitsInZoneToGroup : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
                  var i : Integer;
                  for i:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.zones[zoneid].unitslist.Get(i);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(goHnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(goHnd);
                        if (pobj<>nil) then
                        begin
                           if (TObj(pobj).scenariogroupid<>groupidtrg) and (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                           begin
                              if (TObj(pobj).scenariogroupid>-1) then
                              begin
                                 gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                                 if (gScenario.ui.bshowui) then
                                 gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                              end;
                              gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                              if (gScenario.ui.bshowui) then
                              gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                              TObj(pobj).scenariogroupid := groupidtrg;
                              AIRegionDoUpdateObject(0, goHnd, True);
                           end;
                        end;
                     end;
                  end;
                  //_scenario_UpdateAIRegions(gScenario);
               end;
            end;
            gc_trigger_action_group_AddUnitsOfGroupInZoneToGroup : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
                  var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
                  var i : Integer;
                  for i:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.zones[zoneid].unitslist.Get(i);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(goHnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(goHnd);
                        if (pobj<>nil) then
                        begin
                           if (TObj(pobj).scenariogroupid=groupid) and (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                           begin
                              if (TObj(pobj).scenariogroupid>-1) then
                              begin
                                 gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                                 if (gScenario.ui.bshowui) then
                                 gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                              end;
                              gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                              if (gScenario.ui.bshowui) then
                              gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                              TObj(pobj).scenariogroupid := groupidtrg;
                              AIRegionDoUpdateObject(0, goHnd, True);
                           end;
                        end;
                     end;
                  end;
                  //_scenario_UpdateAIRegions(gScenario);
               end;
            end;
            gc_trigger_action_group_AddUnitsOfPlayerInZoneToGroup : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
                  var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
                  var i : Integer;
                  for i:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.zones[zoneid].unitslist.Get(i);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(goHnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(goHnd);
                        if (pobj<>nil) then
                        begin
                           if (TObj(pobj).pl=player) and (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                           begin
                              if (TObj(pobj).scenariogroupid>-1) then
                              begin
                                 gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                                 if (gScenario.ui.bshowui) then
                                 gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                              end;
                              gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                              if (gScenario.ui.bshowui) then
                              gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                              TObj(pobj).scenariogroupid := groupidtrg;
                              AIRegionDoUpdateObject(0, goHnd, True);
                           end;
                        end;
                     end;
                  end;
                  //_scenario_UpdateAIRegions(gScenario);
               end;
            end;
            gc_trigger_action_group_AddSpecificUnitsOfPlayerInZoneToGroup : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               if (gScenario.zones[zoneid].bactive) then
               begin
                  var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
                  var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
                  var unitcid : Integer = TScenarioTriggerAction(ptriggeraction).countryid;
                  var unitid : Integer = TScenarioTriggerAction(ptriggeraction).unitid;
                  var i : Integer;
                  for i:=gScenario.zones[zoneid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.zones[zoneid].unitslist.Get(i);
                     var uid : Integer = GetGameObjectUniqueIdByHandle(goHnd); // debug issue
                     if (uid<>0) then
                     begin
                        var pobj : Pointer = _unit_GetTObj(goHnd);
                        if (pobj<>nil) then
                        begin
                           if (TObj(pobj).pl=player) and (TObj(pobj).cid=unitcid) and (TObj(pobj).id=unitid) and (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                           begin
                              if (TObj(pobj).scenariogroupid>-1) then
                              begin
                                 gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                                 if (gScenario.ui.bshowui) then
                                 gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                              end;
                              gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                              if (gScenario.ui.bshowui) then
                              gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                              TObj(pobj).scenariogroupid := groupidtrg;
                              AIRegionDoUpdateObject(0, goHnd, True);
                           end;
                        end;
                     end;
                  end;
                  //_scenario_UpdateAIRegions(gScenario);
               end;
            end;
            gc_trigger_action_group_AddUnitsOfPlayerOfGroupToGroup : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
               var i : Integer;
               for i:=gScenario.groups[groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  var uid : Integer = GetGameObjectUniqueIdByHandle(goHnd); // debug issue
                  if (uid<>0) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     if (pobj<>nil) then
                     begin
                        if (TObj(pobj).scenariogroupid=groupid) and (TObj(pobj).pl=player) and (gScenario.groups[groupidtrg].unitslist.IndexOf(goHnd)<0) then
                        begin
                           gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                           gScenario.groups[groupidtrg].unitslist.Add(goHnd);
                           if (gScenario.ui.bshowui) then
                           begin
                              gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                              gScenarioTmp.groups[groupidtrg].unitslist.Add(goHnd);
                           end;
                           TObj(pobj).scenariogroupid := groupidtrg;
                           AIRegionDoUpdateObject(0, goHnd, True);
                        end;
                     end;
                  end;
               end;
               //_scenario_UpdateAIRegions(gScenario);
            end;
            gc_trigger_action_group_AddIdlePeasantsToGroup : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var plHnd : Integer = GetPlayerHandleByIndex(player);
               var i : Integer;
               for i:=GetPlayerGameObjectsCountByHandle(plHnd)-1 downto 0 do
               begin
                  var goHnd : Integer = GetGameObjectHandleByIndex(i, plHnd);
                  if (GetGameObjectPlayableObjectByHandle(goHnd)) and (GetGameObjectVisibleByHandle(goHnd)) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     if (gObjProp[TObj(pobj).cid][TObj(pobj).id].usage=gc_obj_usage_peasant) and (TObj(pobj).orders[0].itype=gc_obj_order_type_none) then
                     begin
                        if (TObj(pobj).scenariogroupid>-1) then
                        begin
                           gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                           if (gScenario.ui.bshowui) then
                           gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                        end;
                        gScenario.groups[groupid].unitslist.Add(goHnd);
                        if (gScenario.ui.bshowui) then
                        gScenarioTmp.groups[groupid].unitslist.Add(goHnd);
                        TObj(pobj).scenariogroupid := groupid;
                        AIRegionDoUpdateObject(0, goHnd, True);
                     end;
                  end;
               end;
               //_scenario_UpdateAIRegions(gScenario);
            end;
            gc_trigger_action_group_AddIdleMinesToGroup : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var plHnd : Integer = GetPlayerHandleByIndex(player);
               var i : Integer;
               for i:=GetPlayerGameObjectsCountByHandle(plHnd)-1 downto 0 do
               begin
                  var goHnd : Integer = GetGameObjectHandleByIndex(i, plHnd);
                  if (GetGameObjectPlayableObjectByHandle(goHnd)) and (GetGameObjectVisibleByHandle(goHnd)) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     var usage : Integer = gObjProp[TObj(pobj).cid][TObj(pobj).id].usage;
                     var peasantabsorber : Integer = gObjProp[TObj(pobj).cid][TObj(pobj).id].peasantabsorber;
                     
                     var pObjInside : Pointer = _misc_GetObjectArgData(goHnd, gc_argunit_inside);
                     var inCount : Integer;
                     if pObjInside <> nil then
                     inCount := TIntegerList(pObjInside).GetCount;
                     
                     if (usage=gc_obj_usage_mine) and ((inCount{+TObj(pobj).insidereserved})<(peasantabsorber+TObj(pobj).individual.addpeasantabsorber)) then
                     begin
                        if (TObj(pobj).scenariogroupid>-1) then
                        begin
                           gScenario.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                           if (gScenario.ui.bshowui) then
                           gScenarioTmp.groups[TObj(pobj).scenariogroupid].unitslist.Remove(goHnd);
                        end;
                        gScenario.groups[groupid].unitslist.Add(goHnd);
                        if (gScenario.ui.bshowui) then
                        gScenarioTmp.groups[groupid].unitslist.Add(goHnd);
                        TObj(pobj).scenariogroupid := groupid;
                        AIRegionDoUpdateObject(0, goHnd, True);
                     end;
                  end;
               end;
               //_scenario_UpdateAIRegions(gScenario);
            end;
            gc_trigger_action_group_CreateSquad : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(0);
               var pobj : Pointer = _unit_GetTObj(goHnd);
               if (pobj<>nil) then
               begin
                  var plHnd : Integer = GetPlayerHandleByIndex(TObj(pobj).pl);
                  var i : Integer;
                  for i:=gScenario.groups[groupid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                     pobj := _unit_GetTObj(goHnd);
                     if (pobj<>nil) and (TObj(pObj).squad>-1) then
                     _misc_DisbandSquad(GetPlayerHandleByIndex(TObj(pObj).pl), TObj(pObj).squad, true);
                  end;
                  _player_WriteSquadNew(plHnd, -1, 0, 0, gScenario.groups[groupid].unitslist, false, false);
               end;
            end;
            gc_trigger_action_player_playerSetAsEnemy : begin
               //_player_MakeEnemy(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).playertrg);
               var plind : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var trgplind : Integer = TScenarioTriggerAction(ptriggeraction).playertrg;
               //_player_MakeEnemy(plind, trgplind);
               if (plind=0) or (trgplind=0) then
               begin
                  gPlayer[plind].bneutral := False;
                  gPlayer[trgplind].bneutral := False;
               end;
               gPlayer[plind].enemyplmask := gPlayer[plind].enemyplmask or (1 shl trgplind);
               gPlayer[trgplind].enemyplmask := gPlayer[trgplind].enemyplmask or (1 shl plind);
               if GetIsFriendPlayersByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind)) then
               DeletePlayerFriendPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               if GetIsFriendPlayersByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind)) then
               DeletePlayerFriendPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               AddPlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               AddPlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               
               var plIO : Integer = GetPlayerIndexByHandle(GetPlayerHandleInterfaceIO);
               if (plind=plIO) or (trgplind=plIO) then
               bupdateally := True;
            end;
            gc_trigger_action_player_playerSetAsAlly : begin
               //_player_MakeAlly(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).playertrg);
               var plind : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var trgplind : Integer = TScenarioTriggerAction(ptriggeraction).playertrg;
               _player_MakeAlly(plind, trgplind);
               if (plind=0) or (trgplind=0) then
               begin
                  gPlayer[plind].bneutral := False;
                  gPlayer[trgplind].bneutral := False;
               end;
               
               if (gPlayer[plind].enemyplmask and (1 shl trgplind)<>0) then
               gPlayer[plind].enemyplmask := gPlayer[plind].enemyplmask-(1 shl trgplind);
               if (gPlayer[trgplind].enemyplmask and (1 shl plind)<>0) then
               gPlayer[trgplind].enemyplmask := gPlayer[trgplind].enemyplmask-(1 shl plind);
               
               if GetIsEnemyPlayersByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind)) then
               DeletePlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               if GetIsEnemyPlayersByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind)) then
               DeletePlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               AddPlayerFriendPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               AddPlayerFriendPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               
               var plIO : Integer = GetPlayerIndexByHandle(GetPlayerHandleInterfaceIO);
               if (plind=plIO) or (trgplind=plIO) then
               bupdateally := True;
            end;
            gc_trigger_action_player_playerSetAsNeutral : begin
               //_player_MakeAlly(TScenarioTriggerAction(ptriggeraction).player, TScenarioTriggerAction(ptriggeraction).playertrg);
               var plind : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var trgplind : Integer = TScenarioTriggerAction(ptriggeraction).playertrg;
               if (gPlayer[plind].enemyplmask and (1 shl trgplind)<>0) then
               gPlayer[plind].enemyplmask := gPlayer[plind].enemyplmask-(1 shl trgplind);
               if (gPlayer[trgplind].enemyplmask and (1 shl plind)<>0) then
               gPlayer[trgplind].enemyplmask := gPlayer[trgplind].enemyplmask-(1 shl plind);
               if (plind=0) or (trgplind=0) then
               begin
                  if (plind<>0) then
                  gPlayer[plind].bneutral := True;
                  if (trgplind<>0) then
                  gPlayer[trgplind].bneutral := True;
               end;
               if GetIsEnemyPlayersByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind)) then
               DeletePlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               if GetIsEnemyPlayersByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind)) then
               DeletePlayerEnemyPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               AddPlayerFriendPlayerByHandle(GetPlayerHandleByIndex(plind), GetPlayerHandleByIndex(trgplind));
               AddPlayerFriendPlayerByHandle(GetPlayerHandleByIndex(trgplind), GetPlayerHandleByIndex(plind));
               var plIO : Integer = GetPlayerIndexByHandle(GetPlayerHandleInterfaceIO);
               if (plind=plIO) or (trgplind=plIO) then
               bupdateally := True;
            end;
            gc_trigger_action_player_unitsChangePlayer : begin
               var plHnd : Integer = GetPlayerHandleByIndex(TScenarioTriggerAction(ptriggeraction).player);
               var lastsquad : Integer = -1;
               var lastplayer : Integer = -1;
               var aloneUnitsList : TIntegerList;
               var squadsIndexList : TIntegerList;
               var squadsPlayerIndexList : TIntegerList;
               var i, j : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     if (TObj(pobj).squad<0) then
                     aloneUnitsList.Add(goHnd)
                     else
                     if (TObj(pobj).squad<>lastsquad) or (TObj(pobj).pl<>lastplayer) then
                     begin
                        lastsquad := TObj(pobj).squad;
                        lastplayer := TObj(pobj).pl;
                        var indof : Integer = squadsIndexList.IndexOf(TObj(pobj).squad);
                        if (indof=-1) or (squadsPlayerIndexList.Get(indof)<>TObj(pobj).pl) then
                        begin
                           squadsIndexList.Add(TObj(pobj).squad);
                           squadsPlayerIndexList.Add(TObj(pobj).pl);
                        end;
                     end;
                  end;
               end;
               if (squadsIndexList.GetCount>0) or (squadsPlayerIndexList.GetCount>0) then
               _misc_SortIntegerLists2D(squadsIndexList, squadsPlayerIndexList, False);
               for i:=squadsIndexList.GetCount-1 downto 0 do
               begin
                  var plInd : Integer = squadsPlayerIndexList.Get(i);
                  var sqInd : Integer = squadsIndexList.Get(i);
                  for j:=gPlayer[plInd].squads.GetCount-1 downto 0 do
                  begin
                     var psquad : Pointer = gPlayer[plInd].squads.Get(j);
                     if (psquad<>nil) and (TSquad(psquad).fIndex=sqInd) then
                     begin
                        var pNewSquad : Pointer = _misc_SquadChangePlayer(psquad, TScenarioTriggerAction(ptriggeraction).player);
                        if (pNewSquad<>nil) then
                        begin
                           var posx, posz, dirx, dirz : Float;
                           _squad_GetCentralPosAndDir(pNewSquad, posx, posz, dirx, dirz);
                           var sqind : Integer = TSquad(pNewSquad).fIndex;
                           _player_SetSquadPosition(plHnd, sqind, posx, posz, dirx, dirz, False, True, gc_obj_order_move_mode_default, True);
                           _player_StopSquad(TScenarioTriggerAction(ptriggeraction).player, sqind);
                        end;
                        break;
                     end;
                  end;
               end;
               for i:=0 to aloneUnitsList.GetCount-1 do
               begin
                  var goHnd : Integer = aloneUnitsList.Get(i);
                  _misc_ChangePlayer(goHnd, plHnd, False, True, True);
               end;
            end;
            gc_trigger_action_player_enableAI : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var bNeedUpdate : Boolean = (not gPlayer[player].bai);
               gPlayer[player].bai := True;
               gPlayer[player].bexists := True;
               gScenario.players[player].bai := gPlayer[player].bai;
               gScenarioTmp.players[player].bai := gPlayer[player].bai;
               if (bNeedUpdate) then
               _player_UpdateAIData(player, bNeedUpdate);
            end;
            gc_trigger_action_player_disableAI : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               gPlayer[player].bai := False;
               gScenario.players[player].bai := gPlayer[player].bai;
               gScenarioTmp.players[player].bai := gPlayer[player].bai;
            end;
            gc_trigger_action_units_DestroyGroup : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Remove(goHnd);
                  if (gScenario.ui.bshowui) then
                  gScenarioTmp.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Remove(goHnd);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  TObj(pobj).scenariogroupid := -1;
                  _unit_SetTagStates(goHnd, gc_statetag_essential_death);
                  SetGameObjectVisibleByHandle(goHnd, False);
               end;
            end;
            gc_trigger_action_units_KillGroup : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Remove(goHnd);
                  if (gScenario.ui.bshowui) then
                  gScenarioTmp.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Remove(goHnd);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  TObj(pobj).scenariogroupid := -1;
                  _unit_SetTagStates(goHnd, gc_statetag_essential_death);
               end;
            end;
            gc_trigger_action_order_setUnitsVisible : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  _unit_SetSTO(goHnd, 0);
                  if (not _unit_IsWaterUnit(goHnd)) then
                  _unit_SetTagStates(goHnd, gc_statetag_visual_none or gc_statetag_essential_none);
                  SetGameObjectVisibleByHandle(goHnd, True);
                  SetGameObjectCollisionDetectionByHandle(goHnd, True);
                  SetGameObjectPlayableObjectByHandle(goHnd, True);
                  _unit_ScanGridProgress(goHnd);
               end;
            end;
            gc_trigger_action_order_setUnitsUnvisible : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  _unit_SetSTO(goHnd, 0);
                  if (not _unit_IsWaterUnit(goHnd)) then
                  _unit_SetTagStates(goHnd, gc_statetag_visual_hide or gc_statetag_essential_birth)
                  else
                  SetGameObjectVisibleByHandle(goHnd, False);
                  SetGameObjectPlayableObjectByHandle(goHnd, False);
                  _unit_ScanGridRemoveUnit(goHnd);
                  var behHnd : Integer = GetBehaviourByKey(goHnd, 'prim');
                  if (behHnd<>0) then
                  BehaviourDestroy(behHnd);
               end;
            end;
            gc_trigger_action_units_CreateUnits : begin
               var dir : Float = TScenarioTriggerAction(ptriggeraction).direction;
               var amount : Integer;
               if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
               amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               amount := TScenarioTriggerAction(ptriggeraction).amount;
               var formationid : Integer = TScenarioTriggerAction(ptriggeraction).formationid;
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               
               var ind : Integer;
               var i, j, k : Integer;
               var minx : Integer = 100;
               var miny : Integer = 100;
               var maxx : Integer;
               var maxy : Integer;
               for j:=0 to gc_formation_maskmaxheight-1 do
               for k:=0 to gc_formation_maskmaxwidth-1 do
               begin
                  if (gFormation[formationid].mask[j][k]) then
                  begin
                     if (j<miny) then miny := j;
                     if (j>maxy) then maxy := j;
                     if (k<minx) then minx := k;
                     if (k>maxx) then maxx := k;
                  end;
               end;
               var width : Integer = maxx-minx;
               var height : Integer = maxy-miny;
               const cUnitRadius = 0.515;
               var midx : Float = -(width div 2)*cUnitRadius;
               var midy : Float;
               var midz : Float = -(height div 2)*cUnitRadius;
               VectorRotateY(midx, midy, midz, dir);
               var test : Integer;
               while ind<amount do
               begin
                  for [MAIN]j:=miny to maxy do
                  for k:=minx to maxx do
                  begin
                     test := test+1;
                     if (ind>=amount) then
                     break(MAIN);
                     if (gFormation[formationid].mask[j][k]) then
                     begin
                        ind := ind+1;
                        var plInd : Integer = TScenarioTriggerAction(ptriggeraction).player;
                        var plHnd : Integer = GetPlayerHandleByIndex(plInd);
                        var goHnd : Integer;
                        var dirx : Float = k*cUnitRadius;
                        var diry : Float;
                        var dirz : Float = j*cUnitRadius;
                        VectorRotateY(dirx, diry, dirz, dir);
                        var x : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x+midx+dirx;
                        var z : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y+midz+dirz;
                        var cid : Integer = TScenarioTriggerAction(ptriggeraction).countryid;
                        var unitid : Integer = TScenarioTriggerAction(ptriggeraction).unitid;
                        var pobj : Pointer = nil;
                        if (not gObjProp[cid][unitid].bbuilding) then begin
                           var parg: Pointer = StateMachineGetArgDataByInd(GetPlayerStateMachineHandle(plHnd), gc_argplayer_plr);
                           TPlayerArgs(parg).fposx:=x;
                           TPlayerArgs(parg).fposz:=z;
                           TPlayerArgs(parg).fracename:=gc_racename_units;
                           TPlayerArgs(parg).fbasename:=gObjProp[cid][unitid].sid;
                           TPlayerArgs(parg).fcid:=-cid;
                           PlayerExecuteStateByHandle(plHnd, 'WriteNew');
                           goHnd:=TPlayerArgs(parg).fresult;
                           GameObjectRollByHandle(goHnd, dir);
                           if (goHnd<>0) then
                           pobj := _unit_GetTObj(goHnd);
                           {if (goHnd<>0) then
                           begin
                              pobj := _unit_GetTObj(goHnd);
                              if _unit_IsWaterUnit(goHnd) then
                              begin
                                 TPlayerArgs(parg).fid := GetPlayerIndexByHandle(plHnd);
                                 TPlayerArgs(parg).fsid := gObjProp[cid][unitid].sid;
                                 TPlayerArgs(parg).find := -1;
                                 TPlayerArgs(parg).fofficer := goHnd;
                                 TPlayerArgs(parg).fposition := True;
                                 TPlayerArgs(parg).fbstate := False;
                                 TPlayerArgs(parg).fintlst := nil;
                                 PlayerExecuteStateByHandle(plHnd, 'WriteSquadNew');
                              end;
                           end;}
                        end
                        else
                        begin
                           x := floor(x*2)/2+0.25;
                           z := floor(z*2)/2+0.25;
                           var parg: Pointer = StateMachineGetArgDataByInd(GetPlayerStateMachineHandle(plHnd), gc_argplayer_plr);
                           TPlayerArgs(parg).fposx:=x;
                           TPlayerArgs(parg).fposz:=z;
                           TPlayerArgs(parg).fracename:=gc_racename_buildings;
                           TPlayerArgs(parg).fbasename:=gObjProp[cid][unitid].sid;
                           TPlayerArgs(parg).fcid:=-cid;
                           PlayerExecuteStateByHandle(plHnd, 'WriteNew');
                           goHnd:=TPlayerArgs(parg).fresult;
                           if goHnd<>0 then begin
                              pobj := _unit_GetTObj(goHnd);
                              if (pobj<>nil) then
                              begin
                                 TObj(pobj).bbuilt := False;
                                 TObj(pobj).buildprogress := 0;
                                 TObj(pobj).hp := gPlayer[TObj(pobj).pl].objbase[TObj(pobj).cid][TObj(pobj).id].maxhp;
                              end;
                           end;
                        end;
                        if (goHnd<>0) and (groupid>-1) and (pobj<>nil) then
                        begin
                           gScenario.groups[groupid].unitslist.Add(goHnd);
                           if (gScenario.ui.bshowui) then
                           gScenarioTmp.groups[groupid].unitslist.Add(goHnd);
                           TObj(pobj).scenariogroupid := groupid;
                           AIRegionDoUpdateObject(0, goHnd, True);
                        end;
                     end;
                  end;
                  if (test>10000) then
                  begin
                     ErrorLog('Scenario : perpetum cycle');
                     break;
                  end;
               end;
            end;
            gc_trigger_action_units_MakeUnplayable : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  SetGameObjectPlayableObjectByHandle(goHnd, False);
                  _unit_ScanGridRemoveUnit(goHnd);
               end;
            end;
            gc_trigger_action_units_MakePlayable : begin
               var i : Integer;
               for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                  SetGameObjectPlayableObjectByHandle(goHnd, True);
                  _unit_ScanGridAddUnit(goHnd);
               end;
            end;
            gc_trigger_action_country_unitProduceEnable : gPlayer[TScenarioTriggerAction(ptriggeraction).player].objbase[TScenarioTriggerAction(ptriggeraction).countryid][TScenarioTriggerAction(ptriggeraction).unitid].bproduceenabled := True;
            gc_trigger_action_country_unitProduceDisable : gPlayer[TScenarioTriggerAction(ptriggeraction).player].objbase[TScenarioTriggerAction(ptriggeraction).countryid][TScenarioTriggerAction(ptriggeraction).unitid].bproduceenabled := False;
            gc_trigger_action_country_upgradeEnable : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var plHnd : Integer = GetPlayerHandleByIndex(player);
               gPlayer[player].upgstate[TScenarioTriggerAction(ptriggeraction).countryid][TScenarioTriggerAction(ptriggeraction).upgradeid].bscenariodisabled := False;
               if (GetPlayerHandleInterfaceIO=plHnd) then
               gbool_gui_update_unitcontrol := True;
            end;
            gc_trigger_action_country_upgradeDisable : begin
               var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
               var plHnd : Integer = GetPlayerHandleByIndex(player);
               gPlayer[player].upgstate[TScenarioTriggerAction(ptriggeraction).countryid][TScenarioTriggerAction(ptriggeraction).upgradeid].bscenariodisabled := True;
               if (GetPlayerHandleInterfaceIO=plHnd) then
               gbool_gui_update_unitcontrol := True;
            end;
            gc_trigger_action_country_makeUpgradeInstanly : begin
               _player_ApplyUpgrade(GetPlayerHandleByIndex(TScenarioTriggerAction(ptriggeraction).player), 0, TScenarioTriggerAction(ptriggeraction).countryid, TScenarioTriggerAction(ptriggeraction).upgradeid, True);
            end;
            gc_trigger_action_order_GroupProduceUnit : begin
               var amount : Integer;
               if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
               amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               amount := TScenarioTriggerAction(ptriggeraction).amount;
               var cid : Integer = TScenarioTriggerAction(ptriggeraction).countryid;
               var unitid : Integer = TScenarioTriggerAction(ptriggeraction).unitid;
               var binfinite : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
               if (binfinite) then
               amount := gc_obj_order_produce_infinite;
               var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0);
               if (goHnd<>0) then
               begin
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     var plHnd : Integer = GetPlayerHandleByIndex(TObj(pobj).pl);
                     _unit_ProduceUnit(plHnd, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, cid, unitid, amount, True, True, True);
                  end;
               end;
            end;
            gc_trigger_action_order_GroupCancelProduceUnit : begin
               var amount : Integer;
               if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
               amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
               else
               amount := TScenarioTriggerAction(ptriggeraction).amount;
               var cid : Integer = TScenarioTriggerAction(ptriggeraction).countryid;
               var unitid : Integer = TScenarioTriggerAction(ptriggeraction).unitid;
               var binfinite : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
               if (binfinite) then
               amount := gc_obj_order_produce_infinite;
               var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0);
               if (goHnd<>0) then
               begin
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     var plHnd : Integer = GetPlayerHandleByIndex(TObj(pobj).pl);
                     _unit_ProduceUnit(plHnd, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, cid, unitid, amount, False, True, True);
                  end;
               end;
            end;
            gc_trigger_action_order_SetRallyPointToZone : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               var x : Float = gScenario.zones[zoneid].x;
               var z : Float = gScenario.zones[zoneid].y;
               var i : Integer;
               for i:=gScenario.groups[groupid].unitslist.GetCount-1 downto 0 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  _unit_SetRallyPoint(goHnd, x, z, true, false);
               end;
            end;
            gc_trigger_action_order_standground : _misc_SetUnitsListUnitState(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, True, False, True, False);
            gc_trigger_action_order_cancelStandGround : _misc_SetUnitsListUnitState(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, True, False, False, False);
            gc_trigger_action_order_enableSearchEnemy : _misc_SetUnitsListUnitState(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, False, True, False, True);
            gc_trigger_action_order_disableSearchEnemy : _misc_SetUnitsListUnitState(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, False, True, False, False);
            gc_trigger_action_order_moveToZone : begin
               var btransport : Boolean;
               if (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount=1) then
               begin
                  var trgx : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x;
                  var trgz : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y;
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     var pObjProp : Pointer = _unit_GetObjProp(goHnd);
                     if (pObj <> nil) and (pObjProp <> nil) and (TObjProp(pObjProp).transport > 0) then
                     begin
                        var plInd : Integer = TObj(pobj).pl;
                        var pArmy : Pointer = gPlayer[plInd].aiData.armyList.AddSetup(plInd);
                        if (pArmy<>nil) then
                        begin
                           var squad : Integer = TObj(pobj).squad;
                           var psquad : Pointer = gPlayer[plInd].squads.Get(squad);
                           if psquad<>nil then
                           begin
                              var grHnd : Integer = _squad_GetGroupHandle(pSquad);
                              _group_AddUnitsFromSquad(grHnd, pSquad);
                              _group_Initialize(grHnd, pSquad);
                              
                              TArmy(pArmy).fSpec := _ai_GetUnitArmySpec(goHnd);
                              TArmy(pArmy).Add(pSquad);
                              _ai_FindMoorPosition(pArmy, trgx, trgz);
                              btransport := True;
                           end;
                        end;
                     end;
                  end;
               end;
               
               if (not btransport) and (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount>0) then
               begin
                  var posx, posz : Float;
                  _misc_GetUnitsListCentralPosExt(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, gc_statetag_essential_none);
                  var trgx : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x;
                  var trgz : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y;
                  var angle : Float = _misc_GetAngleToXVector(posx, posz, trgx, trgz);
                  var dirx : Float = 1;
                  var diry, dirz : Float;
                  VectorRotateY(dirx, diry, dirz, angle);
                  var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                  if (pobj<>nil) then
                  _player_SetUnitsPosition(TObj(pobj).pl, gc_obj_order_move_mode_default, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, trgx, trgz, dirx, dirz);
               end;
            end;
            gc_trigger_action_order_moveToZoneInstanly : begin
               if (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount>0) then
               begin
                  var trgx : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x;
                  var trgz : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y;
                  var angle : Float = TScenarioTriggerAction(ptriggeraction).direction;
                  var dirx : Float = 1;
                  var diry, dirz : Float;
                  VectorRotateY(dirx, diry, dirz, -angle);
                  var lastsquad : Integer = -1;
                  var aloneUnitsList : TIntegerList;
                  var plHnd : Integer;
                  var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                  if (pobj<>nil) then
                  plHnd := GetPlayerHandleByIndex(TObj(pobj).pl);
                  var i : Integer;
                  for i:=gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 downto 0 do
                  begin
                     var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(i);
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     if (pobj<>nil) then
                     begin
                        if (TObj(pobj).squad<0) then
                        aloneUnitsList.Add(goHnd)
                        else
                        if (TObj(pobj).squad<>lastsquad) then
                        begin
                           lastsquad := TObj(pobj).squad;
                           var psquad : Pointer = gPlayer[TObj(pobj).pl].squads.Get(TObj(pobj).squad);
                           if (psquad<>nil) then
                           _player_StandSquadToPosition(plHnd, psquad, trgx, trgz, dirx, dirz);
                        end;
                     end;
                  end;
                  _player_StandUnitsToPosition(plHnd, aloneUnitsList, trgx, trgz, dirx, dirz);
               end;
            end;
            gc_trigger_action_order_attackGroup : begin
               var groupcount : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount;
               var enemycount : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupidtrg].unitslist.GetCount;
               if (groupcount>0) and (enemycount>0) then
               begin
                  var trgHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupidtrg].unitslist.Get(0);
                  if (trgHnd<>0) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                     var pobjtrg : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupidtrg].unitslist.Get(0));
                     if (pobj<>nil) and (pobjtrg<>nil) then
                     begin
                        var posx, posz, trgx, trgz : Float;
                        _misc_GetUnitsListCentralPosExt(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, gc_statetag_essential_none);
                        _misc_GetUnitsListCentralPosExt(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupidtrg].unitslist, trgx, trgz, gc_statetag_essential_none);
                        var angle : Float = VectorAngle(posx, 0, posz, trgx, 0, trgz);
                        var dirx : Float = 1;
                        var diry, dirz : Float;
                        VectorRotateY(dirx, diry, dirz, angle);
                        
                        _player_SetUnitsPosition(TObj(pobj).pl, gc_obj_order_move_mode_attack, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, trgx, trgz, dirx, dirz);
                        var bbuilding : Boolean = gObjProp[TObj(pobjtrg).cid][TObj(pobjtrg).id].bbuilding;
                        var bwall : Boolean = gObjProp[TObj(pobjtrg).cid][TObj(pobjtrg).id].bwall;
                        if (bwall) or (bbuilding) then
                        if ((gPlayer[TObj(pobj).pl].myplmask and gPlayer[TObj(pobjtrg).pl].enemyplmask)<>0) and (_unit_SelectedUnitsCanAttack(TObj(pobj).pl, trgHnd, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist)) then
                        begin
                           gPtrList.Clear;
                           var i, j : Integer;
                           for i:=0 to enemycount-1 do
                           begin
                              gIntegerList.Clear;
                              var minInd : Integer = i*(groupcount div enemycount);
                              var maxInd : Integer = (i+1)*(groupcount div enemycount);
                              if (i>=enemycount-1) or (maxInd>=groupcount) then
                              maxInd := groupcount-1;
                              for j:=minInd to maxInd do
                              gIntegerList.Add(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(j));
                              var wallHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupidtrg].unitslist.Get(i);
                              if (wallHnd<>0) and (_misc_GetBaseObjID(wallHnd)=gc_baseid_obj) then
                              _player_OrderUnitsToAttack(TObj(pobj).pl, wallHnd, gIntegerList, gPtrList, True, True);
                           end;
                        end;
                     end;
                  end;
               end;
            end;
            gc_trigger_action_order_attackZone : begin
               if (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount>0) then
               begin
                  var posx, posz : Float;
                  _misc_GetUnitsListCentralPosExt(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, gc_statetag_essential_none);
                  var trgx : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x;
                  var trgz : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y;
                  var angle : Float = _misc_GetAngleToXVector(posx, posz, trgx, trgz);
                  var dirx : Float = 1;
                  var diry, dirz : Float;
                  VectorRotateY(dirx, diry, dirz, angle);
                  var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                  if (pobj<>nil) then
                  _player_SetUnitsPosition(TObj(pobj).pl, gc_obj_order_move_mode_attack, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, trgx, trgz, dirx, dirz);
               end;
            end;
            gc_trigger_action_order_setDirectionToZone : begin
               if (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount>0) then
               begin
                  var posx, posz : Float;
                  _misc_GetUnitsListEndPointCentralPos(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz);
                  var movemode : Integer = _misc_GetUnitsListMoveMode(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist);
                  var trgx : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].x;
                  var trgz : Float = gScenario.zones[TScenarioTriggerAction(ptriggeraction).zoneid].y;
                  var angle : Float = _misc_GetAngleToXVector(posx, posz, trgx, trgz);
                  var dirx : Float = 1;
                  var diry, dirz : Float;
                  VectorRotateY(dirx, diry, dirz, angle);
                  var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                  if (pobj<>nil) then
                  _player_SetUnitsPosition(TObj(pobj).pl, movemode, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, dirx, dirz);
               end;
            end;
            gc_trigger_action_order_setDirectionToAngle : begin
               if (gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount>0) then
               begin
                  var angle : Float = TScenarioTriggerAction(ptriggeraction).direction;
                  var posx, posz : Float;
                  _misc_GetUnitsListEndPointCentralPos(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz);
                  var movemode : Integer = _misc_GetUnitsListMoveMode(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist);
                  var dirx : Float = 1;
                  var diry, dirz : Float;
                  VectorRotateY(dirx, diry, dirz, -angle);
                  var pobj : Pointer = _unit_GetTObj(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(0));
                  if (pobj<>nil) then
                  _player_SetUnitsPosition(TObj(pobj).pl, movemode, gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, dirx, dirz);
               end;
            end;
            gc_trigger_action_order_runUpgrade : begin
               gIntegerList.Clear;
               var k : Integer;
               for k:=0 to gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist.Get(k);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     if (TObj(pobj).cid=TScenarioTriggerAction(ptriggeraction).countryid) then
                     gIntegerList.Add(goHnd);
                  end;
               end;
               if (gIntegerList.GetCount>0) then
               begin
                  var plHnd : Integer = GetGameObjectPlayerHandleByHandle(gIntegerList.Get(0));
                  _unit_MakeUpgrade(plHnd, gIntegerList, TScenarioTriggerAction(ptriggeraction).upgradeid, True, True);
               end;
            end;
            gc_trigger_action_order_doExtractFood, gc_trigger_action_order_doExtractWood, gc_trigger_action_order_doExtractStone : begin
               var restype : Integer;
               case TScenarioTriggerAction(ptriggeraction).id of
                  gc_trigger_action_order_doExtractFood : restype := gc_resource_type_food;
                  gc_trigger_action_order_doExtractWood : restype := gc_resource_type_wood;
                  gc_trigger_action_order_doExtractStone : restype := gc_resource_type_stone;
               end;
               var posx, posz : Float;
               if (_misc_GetUnitsListCentralPosExt(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, gc_statetag_essential_none)) then
               begin
                  _player_OrderUnitsListToGainRes(gScenario.groups[TScenarioTriggerAction(ptriggeraction).groupid].unitslist, posx, posz, restype, True)
               end;
            end;
            gc_trigger_action_order_findAndAttackEnemyInZone : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               if (gScenario.groups[groupid].unitslist.GetCount>0) then
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(0);
                  if (goHnd<>0) then
                  begin
                     var groupx, groupy : Float;
                     _misc_GetUnitsListCentralPosExt(gScenario.groups[groupid].unitslist, groupx, groupy, gc_statetag_essential_none);
                     
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     var enemyplmask : Integer = gPlayer[TObj(pobj).pl].enemyplmask;
                     var killmask : Integer = gObjProp[TObj(pobj).cid][TObj(pobj).id].kmask;
                     var cellx, celly, cellxmax, cellymax : Integer;
                     
                     var left, top : Integer;
                     // -2 +2 fix bug when find and attack cant find enemy when he came in zone, cause of floor/roundup of - values fault
                     _misc_PosToScanGridIndices(gScenario.zones[zoneid].x-_misc_RoundUp(gScenario.zones[zoneid].w/2)-2, gScenario.zones[zoneid].y-_misc_RoundUp(gScenario.zones[zoneid].h/2)-2, left, top);
                     var right : Integer = left+_misc_RoundUp((gScenario.zones[zoneid].w+2+gc_scangrid_size)/gc_scangrid_size);
                     var bottom : Integer = top+_misc_RoundUp((gScenario.zones[zoneid].h+2+gc_scangrid_size)/gc_scangrid_size);
                     if (left<0) then left := 0
                     else if (left>=gc_scangrid_countx) then left := gc_scangrid_countx-1;
                     if (right<0) then right := 0
                     else if (right>=gc_scangrid_countx) then right := gc_scangrid_countx-1;
                     if (top<0) then top := 0
                     else if (top>=gc_scangrid_county) then top := gc_scangrid_county-1;
                     if (bottom<0) then bottom := 0
                     else if (bottom>=gc_scangrid_county) then bottom := gc_scangrid_county-1;
                     
                     var mindst : Float = -1;
                     var bestx, besty : Float;
                     var ix, iy : Integer;
                     for ix:=left to right do
                     for iy:=top to bottom do
                     begin
                        var plmask : Integer = gScanGrid[ix,iy].fPlMask;
                        var bisenemy : Boolean = (enemyplmask and plmask<>0);
                        if (bisenemy) then
                        begin
                           var count : Integer;
                           var pl : Integer;
                           for pl:=0 to gc_MaxPlayerCount-1 do
                           begin
                              if ((enemyplmask and (1 shl pl))<>0) then
                              count := count+gScanGrid[ix,iy].fPlCount[pl];
                           end;
                           if (count>0) then
                           begin
                              var cellrx, cellry : Float;
                              _misc_ScanGridIndicesToPos(ix, iy, cellrx, cellry);
                              var length : Float = VectorDistance(groupx, 0, groupy, cellrx, 0, cellry);
                              var dst : Float = length/(count/10);
                              if (dst<mindst) or (mindst<0) then
                              begin
                                 mindst := dst;
                                 bestx := cellrx;
                                 besty := cellry;
                              end;
                           end;
                        end;
                     end;
                     if (mindst>0) then
                     begin
                        var angle : Float = _misc_GetAngleToXVector(groupx, groupy, bestx, besty);
                        var dirx : Float = 1;
                        var diry, dirz : Float;
                        VectorRotateY(dirx, diry, dirz, angle);
                        _player_SetUnitsPosition(TObj(pobj).pl, gc_obj_order_move_mode_attack, gScenario.groups[groupid].unitslist, bestx, besty, dirx, dirz);
                     end;
                  end;
               end;
            end;
            gc_trigger_action_order_dismissSquadsInGroup : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var k : Integer;
               for k:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) then
                  begin
                     if (TObj(pObj).squad>=0) then
                     begin
                        var plHnd : Integer = GetPlayerHandleByIndex(TObj(pObj).pl);
                        _misc_DisbandSquad(plHnd, TObj(pObj).squad, true);
                     end;
                  end;
               end;
            end;
            gc_trigger_action_order_ArtilleryAttackZoneCenterWithDispertion : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               var radius : Float = TScenarioTriggerAction(ptriggeraction).radius;
               var k : Integer;
               for k:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  var pobj : Pointer = _unit_GetTObj(goHnd);
                  if (pobj<>nil) and (_misc_GetUnitType(goHnd)=gc_result_unittype_art) then
                  begin
                     var dx, dy, dz : Float;
                     _weapon_CalcShotDispertion(goHnd, radius, gScenario.zones[zoneid].x, 0, gScenario.zones[zoneid].y, dx, dy, dz);
                     _unit_OrderAttackPoint(goHnd, dx, dz, False, True);
                  end;
               end;
            end;
            gc_trigger_action_order_goInside : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var groupidtrg : Integer = TScenarioTriggerAction(ptriggeraction).groupidtrg;
               if (gScenario.groups[groupidtrg].unitslist.GetCount>0) and (gScenario.groups[groupid].unitslist.GetCount>0) then
               begin
                  var plHnd : Integer = GetGameObjectPlayerHandleByHandle(gScenario.groups[groupid].unitslist.Get(0));
                  var plInd : Integer = GetPlayerIndexByHandle(plHnd);
                  var trgHnd : Integer;
                  trgHnd := gScenario.groups[groupidtrg].unitslist.Get(0);
                  
                  gPtrList.Clear;
                  if (trgHnd<>0) and (_unit_UnitsCanGoInside(trgHnd, gScenario.groups[groupid].unitslist, gPtrList)) then
                  _player_OrderUnitsToGoInside(plInd, gScenario.groups[groupid].unitslist, gPtrList, trgHnd, True, true);
               end;
            end;
            gc_trigger_action_gate_gateOpen : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var k : Integer;
               for k:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  _unit_SetTagStates(goHnd, gc_statetag_visual_stage_0);
               end;
            end;
            gc_trigger_action_gate_gateClose : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var k : Integer;
               for k:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  _unit_SetTagStates(goHnd, gc_statetag_visual_none);
               end;
            end;
            gc_trigger_action_ferry_goOutside : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var bPicked : Boolean;
               gIntegerList.Clear;
               var k : Integer;
               for k:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(k);
                  var pObjInside : Pointer = _misc_GetObjectArgData(goHnd, gc_argunit_inside);
                  if (pObjInside<>nil) then
                  begin
                     var pobj : Pointer = _unit_GetTObj(goHnd);
                     var pObjProp : Pointer = _unit_GetObjProp(goHnd);
                     if (pObj<>nil) and (pObjProp<>nil) and ((TObjProp(pObjProp).transport=0) or (TObj(pobj).brally)) then
                     begin
                        bPicked := bPicked or GetGameObjectPickedByHandle(goHnd);
                        var m : Integer;
                        for m:=TIntegerList(pobjinside).GetCount-1 downto 0 do
                        begin
                           var unitHnd : Integer = TIntegerList(pobjinside).Get(m);
                           var pobjunit : Pointer = _unit_GetTObj(unitHnd);
                           if (not TObj(pobjunit).bLeaveRequested) then
                           gIntegerList.Add(unitHnd);
                        end;
                     end;
                  end;
               end;
               if (gIntegerList.GetCount>0) then
               begin
                  _unit_DoUnitsGoOutside(gIntegerList, false, true);
                  if (bPicked) then
                  gbool_gui_update_unitcontrol := True;
               end;
            end;
            gc_trigger_action_endgame_win : begin
               gPlayer[myplind].victorystate := gc_player_victorystate_win;
               if (gPlayer[myplind].victorystategametime=0) then
               gPlayer[myplind].victorystategametime := GetGameTime;

               //if (gMap.bbattle) and (_net_IsOnline) then
               //gInterface.gamemode := gc_gamemode_spectator;
               var p : Pointer = _misc_GetOrCreateCampaignMissionProgressPointer(gScenario.campname, gScenario.missname);
               if (p<>nil) then
               begin
                  if (TCampaignProgress(p).started=0) then
                  TCampaignProgress(p).started := 1;
                  TCampaignProgress(p).finished := Min(TCampaignProgress(p).finished+1, TCampaignProgress(p).started);
                  TCampaignProgress(p).maxfinishdifficulty := Max(TCampaignProgress(p).maxfinishdifficulty, gScenario.difficulty);
                  
                  var sind : String = SubStr(gScenario.missname, StrLength(gScenario.missname), 1);
                  var misind : Integer = StrToInt(sind);
                  case gScenario.campname of
                     'auscam' : begin
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalaus].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalaus].cur or (1 shl misind);
                        if (TCampaignProgress(p).maxfinishdifficulty=gc_player_difficulty_veryhard) then
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalaus_impossible].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalaus_impossible].cur or (1 shl misind);
                     end;
                     'engcam' : begin
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finaleng].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finaleng].cur or (1 shl misind);
                        if (TCampaignProgress(p).maxfinishdifficulty=gc_player_difficulty_veryhard) then
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finaleng_impossible].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finaleng_impossible].cur or (1 shl misind);
                     end;
                     'fracam' : begin
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalfra].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalfra].cur or (1 shl misind);
                        if (TCampaignProgress(p).maxfinishdifficulty=gc_player_difficulty_veryhard) then
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalfra_impossible].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalfra_impossible].cur or (1 shl misind);
                     end;
                     'ukrcam' : begin
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalukr].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalukr].cur or (1 shl misind);
                        if (TCampaignProgress(p).maxfinishdifficulty=gc_player_difficulty_veryhard) then
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalukr_impossible].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalukr_impossible].cur or (1 shl misind);
                     end;
                     'ruscam' : begin
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalrus].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalrus].cur or (1 shl misind);
                        if (TCampaignProgress(p).maxfinishdifficulty=gc_player_difficulty_veryhard) then
                        gProfileUserStruct.achs.ach[gc_ach_campaign_finalrus_impossible].cur := gProfileUserStruct.achs.ach[gc_ach_campaign_finalrus_impossible].cur or (1 shl misind);
                     end;
                     'tutcam' : begin
                        if (misind=1) then
                        gProfileUserStruct.achs.ach[gc_ach_camp_tutmis1_fin].cur := gProfileUserStruct.achs.ach[gc_ach_camp_tutmis1_fin].cur+1
                        else
                        if (misind=2) then
                        gProfileUserStruct.achs.ach[gc_ach_camp_tutmis2_fin].cur := gProfileUserStruct.achs.ach[gc_ach_camp_tutmis2_fin].cur+1;
                     end;
                  end;
                  _profile_SaveStructToUserProfileParser('gProfileUserStruct');
               end;
            end;
            gc_trigger_action_endgame_lose : begin
               gPlayer[myplind].victorystate := gc_player_victorystate_lose;
               if (gPlayer[myplind].victorystategametime=0) then
               gPlayer[myplind].victorystategametime := GetGameTime;

               //if (gMap.bbattle) and (_net_IsOnline) then
               //gInterface.gamemode := gc_gamemode_spectator;
               var p : Pointer = _misc_GetOrCreateCampaignMissionProgressPointer(gScenario.campname, gScenario.missname);
               if (p<>nil) then
               begin
                  if (TCampaignProgress(p).started=0) then
                  TCampaignProgress(p).started := 1;
                  TCampaignProgress(p).lose := Min(TCampaignProgress(p).lose+1, TCampaignProgress(p).started);
                  TCampaignProgress(p).maxfinishdifficulty := Max(TCampaignProgress(p).maxfinishdifficulty, gScenario.difficulty);
                  _profile_SaveStructToUserProfileParser('gProfileUserStruct');
               end;
            end;
            gc_trigger_action_advanced_ifThenElse : begin
               log('todo : gc_trigger_action_advanced_ifThenElse');
            end;
            gc_trigger_action_advanced_enableTrigger : begin
               if (not gScenario.triggers[TScenarioTriggerAction(ptriggeraction).triggerid].bactive) then
               begin
                  gScenario.triggers[TScenarioTriggerAction(ptriggeraction).triggerid].bactive := True;
                  //_scenario_UpdateAIRegionsActiveStateToTriggers(gScenario); // done after progress
               end;
            end;
            gc_trigger_action_advanced_disableTrigger : begin
               if (gScenario.triggers[TScenarioTriggerAction(ptriggeraction).triggerid].bactive) then
               begin
                  gScenario.triggers[TScenarioTriggerAction(ptriggeraction).triggerid].bactive := False;
                  //_scenario_UpdateAIRegionsActiveStateToTriggers(gScenario); // done after progress
               end;
            end;
            gc_trigger_action_advanced_enableThisTrigger : begin
               TScenarioTrigger(ptrigger).bactive := True;
            end;
            gc_trigger_action_service_DebugLog : Log('trigger action debug log : name='+TScenarioTrigger(ptrigger).name);
            gc_trigger_action_service_DebugMessage : Log('trigger action debug message : name='+TScenarioTrigger(ptrigger).name);
            gc_trigger_action_save_save : begin
               var name : String;
               if (gMap.name<>'') then
               name := gMap.name
               else
               name := 'camp';
               var filename : String = name+'.map';
               //_misc_SaveMap(filename, True);
               if GetGUIDelayExecuteState='' then begin
                  gbool_gui_quicksave := false;
                  gstring_gui_saving := filename;
                  GUIDelayExecuteState('DoAutoSave', 3);
               end;
            end;
            gc_trigger_action_save_load : begin
               var name : String;
               if (gMap.name<>'') then
               name := gMap.name
               else
               name := 'camp';
               var filename : String = name+'.autosave.1.map';
               _misc_LoadMap(filename);
            end;
            gc_trigger_action_advanced_executeState : begin
               var smHnd : Integer = GetTriggerManagerStateMachineHandle('trigger0');
               if (smHnd<>0) then
               begin
                  var statename : String = TScenarioTriggerAction(ptriggeraction).executestate;
                  IntRegister0 := gScenario.counters[TScenarioTriggerAction(ptriggeraction).counterid].value;
                  StringRegister0 := TScenarioTriggerAction(ptriggeraction).stringregister;
                  StateMachineExecuteState(smHnd, statename, 0);
               end;
            end;
            gc_trigger_action_advanced_ExecuteTriggerActions : begin
               var ptriggerTrg : Pointer = gScenario.triggers[TScenarioTriggerAction(ptriggeraction).triggerid];
               _scenario_EvaluateTriggerActions(ptriggerTrg);
            end;
            gc_trigger_action_objective_PlaceMarkerInZone : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               var x : Float = gScenario.zones[zoneid].x;
               var z : Float = gScenario.zones[zoneid].y;
               var miscplhnd : Integer = GetPlayerHandleByIndex(gc_playerind_misc);
               var markerbasename : String = gConstScenarioMarkers[TScenarioTriggerAction(ptriggeraction).marker];
               var hnd : Integer = CreatePlayerGameObjectHandleByHandle(miscplhnd, gc_racename_misc, markerbasename, x, 0, z);
               //_misc_ApplyKeyColorRecursiveChild(hnd, gMap.players[pl].color); // apply some color in future
            end;
            gc_trigger_action_objective_RemoveMarkerInZone : begin
               var zoneid : Integer = TScenarioTriggerAction(ptriggeraction).zoneid;
               var x : Float = gScenario.zones[zoneid].x;
               var z : Float = gScenario.zones[zoneid].y;
               var miscplhnd : Integer = GetPlayerHandleByIndex(gc_playerind_misc);
               GetGameObjectsInRadius(x, z, gc_epsilon, false, false, miscplhnd, -1, 0, false, false, false, false, false, false);
               var i, j : Integer;
               for i:=GetGameObjectListCount-1 downto 0 do
               begin
                  var goHnd : Integer = GetGameObjectListByIndex(i);
                  var basename : String = GetGameObjectBaseNameByHandle(goHnd);
                  for j:=0 to gc_scenario_marker_count-1 do
                  begin
                     if (gConstScenarioMarkers[j]=basename) then
                     GameObjectRequestToDestroyByHandle(goHnd);
                     //GameObjectDestroyByHandle(goHnd);
                  end;
               end;
            end;
            gc_trigger_action_objective_AddMarkerToGroup : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var miscplhnd : Integer = GetPlayerHandleByIndex(gc_playerind_misc);
               var markerbasename : String = gConstScenarioMarkers[TScenarioTriggerAction(ptriggeraction).marker];
               var i : Integer;
               for i:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  var hnd : Integer = CreatePlayerGameObjectHandleByHandle(miscplhnd, gc_racename_misc, markerbasename, GetGameObjectPositionXByHandle(goHnd), 0, GetGameObjectPositionZByHandle(goHnd));
                  GameObjectParentToChildAbsolute(hnd, goHnd);
                  //_misc_ApplyKeyColorRecursiveChild(hnd, gMap.players[pl].color); // apply some color in future
               end;
            end;
            gc_trigger_action_objective_RemoveMarkerFromGroup : begin
               var groupid : Integer = TScenarioTriggerAction(ptriggeraction).groupid;
               var miscplhnd : Integer = GetPlayerHandleByIndex(gc_playerind_misc);
               var i, j, k : Integer;
               for i:=0 to gScenario.groups[groupid].unitslist.GetCount-1 do
               begin
                  var goHnd : Integer = gScenario.groups[groupid].unitslist.Get(i);
                  for j:=GetGameObjectCountChildByHandle(goHnd)-1 downto 0 do
                  begin
                     var hnd : Integer = GetGameObjectGOHandleChildByHandle(goHnd, j);
                     if (GetGameObjectRaceTag(hnd)=gc_racetag_misc) then
                     begin
                        var basename : String = GetGameObjectBaseNameByHandle(hnd);
                        for k:=0 to gc_scenario_marker_count-1 do
                        begin
                           if (gConstScenarioMarkers[k]=basename) then
                           begin
                              var bHnd : Integer = GetBehaviourByClassName(goHnd, 'TXTLFAnimationBehaviour');
                              if (bHnd<>0) then
                              SetBehaviourIntProperty(bHnd, 'RemoveAndDestroyObject', hnd)
                              else
                              GameObjectRequestToDestroyByHandle(hnd);
                           end;
                           //GameObjectDestroyByHandle(hnd);
                        end;
                     end;
                  end;
               end;
            end;
            gc_trigger_action_net_SetTriggerActive : begin
               if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var triggerid : Integer = TScenarioTriggerAction(ptriggeraction).triggerid;
                  var bstate : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
                  gScenario.triggers[triggerid].bactive := bstate;
               end;
            end;
            gc_trigger_action_net_SetFlagState : begin
               if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var flagid : Integer = TScenarioTriggerAction(ptriggeraction).flagid;
                  var bstate : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
                  gScenario.flags[flagid].bactive := bstate;
               end;
            end;
            gc_trigger_action_net_SetCounterValue : begin
               if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var counterid : Integer = TScenarioTriggerAction(ptriggeraction).counterid;
                  var amount : Integer;
                  if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
                  amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
                  else
                  amount := TScenarioTriggerAction(ptriggeraction).amount;
                  gScenario.counters[counterid].value := amount;
               end;
            end;
            gc_trigger_action_net_ExecuteTriggerActions : begin
               if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var triggerid : Integer = TScenarioTriggerAction(ptriggeraction).triggerid;
                  var ptrigger : Pointer = gScenario.triggers[triggerid];
                  _scenario_EvaluateTriggerActions(ptrigger);
               end;
            end;
            gc_trigger_action_net_TeamSetTriggerActive : begin
               if (gMap.players[TScenarioTriggerAction(ptriggeraction).player].team=gMap.players[myplind].team) then
               //if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var triggerid : Integer = TScenarioTriggerAction(ptriggeraction).triggerid;
                  var bstate : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
                  gScenario.triggers[triggerid].bactive := bstate;
               end;
            end;
            gc_trigger_action_net_TeamSetFlagState : begin
               if (gMap.players[TScenarioTriggerAction(ptriggeraction).player].team=gMap.players[myplind].team) then
               //if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var flagid : Integer = TScenarioTriggerAction(ptriggeraction).flagid;
                  var bstate : Boolean = TScenarioTriggerAction(ptriggeraction).bstate;
                  gScenario.flags[flagid].bactive := bstate;
               end;
            end;
            gc_trigger_action_net_TeamSetCounterValue : begin
               if (gMap.players[TScenarioTriggerAction(ptriggeraction).player].team=gMap.players[myplind].team) then
               //if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var counterid : Integer = TScenarioTriggerAction(ptriggeraction).counterid;
                  var amount : Integer;
                  if (TScenarioTriggerAction(ptriggeraction).busecounterasamount) then
                  amount := gScenario.counters[TScenarioTriggerAction(ptriggeraction).usecounterid].value
                  else
                  amount := TScenarioTriggerAction(ptriggeraction).amount;
                  gScenario.counters[counterid].value := amount;
               end;
            end;
            gc_trigger_action_net_TeamExecuteTriggerActions : begin
               if (gMap.players[TScenarioTriggerAction(ptriggeraction).player].team=gMap.players[myplind].team) then
               //if (TScenarioTriggerAction(ptriggeraction).player=myplind) then
               begin
                  var triggerid : Integer = TScenarioTriggerAction(ptriggeraction).triggerid;
                  var ptrigger : Pointer = gScenario.triggers[triggerid];
                  _scenario_EvaluateTriggerActions(ptrigger);
               end;
            end;
            gc_trigger_action_net_SetCounterSpecialValue : begin
               if (myplind>=0) and (myplind<gc_MaxPlayerCount) then
               begin
                  //var player : Integer = TScenarioTriggerAction(ptriggeraction).player;
                  var counterid : Integer = TScenarioTriggerAction(ptriggeraction).counterid;
                  var amount : Integer = TScenarioTriggerAction(ptriggeraction).amount;
                  case amount of
                     0 : gScenario.counters[counterid].value := myplind;
                     1 : gScenario.counters[counterid].value := gMap.players[myplind].team;
                     2 : gScenario.counters[counterid].value := gMap.players[myplind].cid;
                     3 : begin
                        var count : Integer;
                        var i : Integer;
                        for i:=0 to gc_MaxPlayerCount-1 do
                        if (gMap.players[i].team=1) then
                        count := count+1;
                        gScenario.counters[counterid].value := count;
                     end;
                     4 : begin
                        var count : Integer;
                        var i : Integer;
                        for i:=0 to gc_MaxPlayerCount-1 do
                        count := count+1;
                        gScenario.counters[counterid].value := count;
                     end;
                  end;
               end;
            end;
         end;
      end;
   end;
   if (bupdateally) then
   begin
      var plIO : Integer = GetPlayerIndexByHandle(GetPlayerHandleInterfaceIO);
      _player_UpdateFOW(plIO);
      _misc_UpdateMiniMapPrimitives(False);
   end;
end;

function _scenario_GetSelectedGroupIndex() : Integer;
begin
   var selind : Integer = -1;
   var i, j : Integer;
   for i:=0 to gc_scenario_maxgroups-1 do
   begin
      for j:=gScenario.groups[i].unitslist.GetCount-1 downto 0 do
      begin
         var goHnd : Integer = gScenario.groups[i].unitslist.Get(j);
         if (GetGameObjectPickedByHandle(goHnd)) then
         begin
            if (selind<>-2) then
            begin
               if (selind<>-1) and (selind<>i) then
               selind := -2
               else
               selind := i;
            end;
         end;
      end;
   end;
   Result := selind;
end;
{procedure _scenario_RunConstructors;
begin
   var i : Integer;
   for i:=0 to gc_scenario_maxgroups-1 do
   begin
      gScenario.groups[i].unitslist.Create(SizeOf(Integer));
      gScenarioTmp.groups[i].unitslist.Create(SizeOf(Integer));
   end;
   for i:=0 to gc_scenario_maxzones-1 do
   begin
      gScenario.zones[i].unitslist.Create(SizeOf(Integer));
      gScenarioTmp.zones[i].unitslist.Create(SizeOf(Integer));
   end;
end;}
