AnimatedObjectExtend = {
	autoopenState={0,3,false}; --min,max,warning lockdoor
	triggers={};	
	testString={};
	hasFlag = {CollisionFlag.VEHICLE+CollisionFlag.PLAYER,CollisionFlag.VEHICLE,CollisionFlag.PLAYER};
	flag = {CollisionFlag.VEHICLE+CollisionFlag.PLAYER,CollisionFlag.VEHICLE+CollisionFlag.PLAYER,CollisionFlag.VEHICLE+CollisionFlag.PLAYER};
	setState={};
	setExtraText = {};
};

local modDirectory = g_currentModDirectory
source(modDirectory .. "script/AnimatedObjectExtendEvent.lua")

AnimatedObjectExtend.metadata = {
	interface = "FS25 ...", --reconnect extended ls22 to ls25
	title = "AnimatedObjectExtend",
	notes = "Öffnet und Schließt bei bedarf alle Animierten Tore/Türen automatisch oder manuell, wenn man in einem Fahrzeug oder/und zu Fuss unterwegs ist.",
	author = "(by HappyLooser)",
	version = "1.0.0.0",
	build = 5,
	xmlVersion = 1,
	languageVersion = 1,
	datum = "18.04.2024", 
	update = "18.04.2025",	
	discord = "HappyLooser Modding",
	info = " Link Freigabe,Änderungen,Kopien oder Code Benutzung ist ohne meine Zustimmung nicht erlaubt"	
};

function AnimatedObjectExtend.draw()
	
	if #AnimatedObjectExtend.testString > 0 then
		setTextBold(true);		
		for a=1, #AnimatedObjectExtend.testString do
			local posY = 0.25-(a/100);
			renderText(0.5, posY, 0.010, "-S ".. tostring(a).. "- ".. tostring(AnimatedObjectExtend.testString[a]));
		end;
	end;
	if not AnimatedObjectExtend:getDetiServer() then		
		if AnimatedObjectExtend.setState == nil or AnimatedObjectExtend.setState.object == nil then return;end;
		if g_currentMission.hlUtils == nil or not g_currentMission.hlUtils.dragDrop.on then
			g_currentMission:addExtraPrintText(tostring(AnimatedObjectExtend:getAutoOpenStateText(AnimatedObjectExtend.setState.object.autoopenState, AnimatedObjectExtend.setState.object.remoteControl or false)));			
		end;
	end;
end;
BaseMission.draw = Utils.appendedFunction(BaseMission.draw, AnimatedObjectExtend.draw)

function load(self, superFunc, rootNode, xmlFile, key, xmlFilename, i3dMappings)
	local success = superFunc(self, rootNode, xmlFile, key, xmlFilename, i3dMappings);
	local autoopenState = 0;
	local remoteControl = false;
	local lockdoor = false;
	if xmlFile:hasProperty(key.. ".controls#autoopenState") then		
		autoopenState = xmlFile:getValue(key.. ".controls#autoopenState", 0);
	end;
	if xmlFile:hasProperty(key.. ".controls#lockdoor") then		
		lockdoor = xmlFile:getValue(key.. ".controls#lockdoor", false);
		if lockdoor then autoopenState = 0;end;
	end;
	if xmlFile:hasProperty(key.. ".controls#remoteControl") then		
		remoteControl = xmlFile:getValue(key.. ".controls#remoteControl", true);
	end;
    self:setAutoOpen(self, autoopenState, lockdoor, remoteControl);
	if xmlFile:hasProperty(key.. ".controls#triggerNode") then
		if self.triggerNode ~= nil and AnimatedObjectExtend.triggers[self.triggerNode] == nil then					
			AnimatedObjectExtend.triggers[self.triggerNode] = {triggerNode=self.triggerNode};			
		end;
	end;
	return success;
end;

function updateSegmentShapes(self,segment)
	local spec = self.spec_fence;
	if segment.gateIndex ~= nil then
		local autoopenState = spec.gates[segment.gateIndex].autoopenState;
		local lockdoor = spec.gates[segment.gateIndex].lockdoor;
		local remoteControl = spec.gates[segment.gateIndex].remoteControl;
		local animatedObject = segment.animatedObject;
		if animatedObject ~= nil and lockdoor ~= nil and not lockdoor then
			animatedObject:setAutoOpen(animatedObject, autoopenState, lockdoor, remoteControl);
		end;
	end;
end;

function onFenceI3DLoaded(self, i3dNode, failedReason, args)
	local gate, gateXmlFile, loadingTask = unpack(args);
	if gate.animatedObject ~= nil then
		gate.animatedObject:setAutoOpen(gate.animatedObject, 0, false, true);
	end;
end;

function AnimatedObject:setAutoOpen(self, autoopenState, lockdoor, remoteControl)
	self.autoopenState = autoopenState;
	self.lockdoor = lockdoor;
	self.remoteControl = remoteControl;
	self.objectcount = 0;
	local ready = false;
	if self.triggerNode ~= nil and not lockdoor then			
		self.orgCollisionsFlag = getCollisionFilterMask(self.triggerNode);			
		local collisionsFlag = nil;
		if self.orgCollisionsFlag ~= nil and self.orgCollisionsFlag > 0 and AnimatedObjectExtend:readyFlag(self.orgCollisionsFlag) then
			ready = true;
			if autoopenState ~= 0 then
				setCollisionFilterMask(self.triggerNode, AnimatedObjectExtend.flag[autoopenState]);
			end;				
		else
			self.orgCollisionsFlag = nil;
		end;		
	end;
	if lockdoor then self.remoteControl = true;end;
	if not ready then		
		self.autoopenState = 0;
		self.lockdoor = true;
		self.remoteControl = true;
	end;
end;

function AnimatedObject:setRemoteControlState(self)
	local hasAccess, inVehicle, isOpen = AnimatedObjectExtend:hasAccess(self);
	if not hasAccess then 
		AnimatedObjectExtend:setNoPermissionText(self.autoopenState);		
		return;
	end;
	self.remoteControl = not self.remoteControl;
	local ready = false;
	if self.triggerNode ~= nil and not self.lockdoor and self.orgCollisionsFlag ~= nil and self.autoopenState > 0 then
		ready = true;
		if not AnimatedObjectExtend:getDetiServer() then
			if g_localPlayer ~= nil then
				--local text = AnimatedObjectExtend:getRemoteControlText(self.remoteControl);
				local text = tostring(AnimatedObjectExtend.metadata.title).. "-".. g_i18n:getText("shop_messageConfigurationChanged");
				if g_currentMission.hlHudSystem ~= nil then
					g_currentMission.hlHudSystem.showInfoBox( {text, 3500, g_currentMission.hlUtils.getColor("yellow", true)} );
				else
					g_currentMission.hud:addSideNotification(FSBaseMission.INGAME_NOTIFICATION_OK, text, 3500);
				end;
			end;
		end;
	end;
	if self.lockdoor or not ready then self.remoteControl = true;end;
	if ready then
		if not self.remoteControl then 
			g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);		
		else
			if not inVehicle and (self.autoopenState == 0 or self.autoopenState == 1 or self.autoopenState == 3) then		
				if isOpen then g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);end;
			elseif inVehicle and (self.autoopenState == 1 or self.autoopenState == 2) then
				if isOpen then g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);end;
			else
				g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);
			end;
		end;
		--AnimatedObjectExtend.setState = {};
		self:autoOpen(0, self.autoopenState, self.remoteControl);	
	else
		AnimatedObjectExtend.setState = {};
		AnimatedObjectExtend:setNoSupportObjectText();
	end;
end;

function AnimatedObject:setAutoOpenState(self, autoopenState)
	local oldState = self.autoopenState;
	local hasAccess, inVehicle, isOpen = AnimatedObjectExtend:hasAccess(self);
	if not hasAccess then 
		AnimatedObjectExtend:setNoPermissionText();
		return;
	end;
	self.autoopenState = autoopenState;	
	local ready = false;
	if self.triggerNode ~= nil and not self.lockdoor and self.orgCollisionsFlag ~= nil then
		if autoopenState ~= 0 then setCollisionFilterMask(self.triggerNode, AnimatedObjectExtend.flag[autoopenState]);else setCollisionFilterMask(self.triggerNode, self.orgCollisionsFlag);end;
		ready = true;
		if not AnimatedObjectExtend:getDetiServer() then
			if g_localPlayer ~= nil then
				--local text = tostring(AnimatedObjectExtend.metadata.title).. "-".. tostring(AnimatedObjectExtend:getAutoOpenStateText(autoopenState, self.remoteControl or false))
				local text = tostring(AnimatedObjectExtend.metadata.title).. "-".. g_i18n:getText("shop_messageConfigurationChanged");
				if g_currentMission.hlHudSystem ~= nil then
					local color = "yellow";
					if autoopenState == 0 then color = "orangeRed";end;
					g_currentMission.hlHudSystem.showInfoBox( {text, 3500, g_currentMission.hlUtils.getColor(color, true)} );
				else
					g_currentMission.hud:addSideNotification(FSBaseMission.INGAME_NOTIFICATION_OK, text, 3500);
				end;
			end;
		end;
	end;
	if self.lockdoor or not ready then self.autoopenState = 0;self.lockdoor = true;end;
	if ready then		
		if not self.remoteControl then 
			g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);
		else
			if not inVehicle and (self.autoopenState == 0 or self.autoopenState == 1 or self.autoopenState == 3) then		
				if self.remoteControl and isOpen then g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);end;
			elseif inVehicle and (self.autoopenState == 1 or self.autoopenState == 2) then
				if self.remoteControl and isOpen then g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);end;
			else
				g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);
			end;
		end;
		--AnimatedObjectExtend.setState = {};
		self:autoOpen(0, self.autoopenState, self.remoteControl);
	else
		AnimatedObjectExtend.setState = {};
		AnimatedObjectExtend:setNoSupportObjectText();
	end;
end;

function AnimatedObjectExtend:hasAccess(animatedObject)
	local inVehicle = g_localPlayer ~= nil and g_localPlayer.getCurrentVehicle ~= nil and g_localPlayer:getCurrentVehicle() ~= nil;
	local access = animatedObject.ownerFarmId == nil or animatedObject.ownerFarmId == AccessHandler.EVERYONE or g_currentMission.accessHandler:canFarmAccessOtherId(g_currentMission:getFarmId(), animatedObject.ownerFarmId) or (inVehicle and g_currentMission.accessHandler:canFarmAccessOtherId(g_localPlayer:getCurrentVehicle():getActiveFarm(), animatedObject.ownerFarmId));
	local isOpen = animatedObject.openingHours == nil or (animatedObject.openingHours ~= nil and self.openingHours.isOpen);	
	return access, inVehicle, isOpen;
end;

function onLoad(self, superFunc, savegame)
	local success = superFunc(self, savegame);
	local spec = self.spec_fence;
	local xmlFile = self.xmlFile;
	xmlFile:iterate("placeable.fence.gate", function (_, key)
		for _, gates in ipairs(spec.gates) do
			gates.autoopenState = xmlFile:getValue(key.. "#autoopenState", 0);
			gates.lockdoor = xmlFile:getValue(key.. "#lockdoor", false);
			gates.remoteControl = xmlFile:getValue(key.. "#remoteControl", true);
		end
	end)
	return success;
end;

function AnimatedObject:autoOpen(objectcount, autoopenState, remoteControl, noEventSend)
	self.objectcount = objectcount;
	self.autoopenState = autoopenState;		
	self.remoteControl = remoteControl;
	if self.isServer then		
		if not self.lockdoor then
			if (self.objectcount > 0 ) then
				if self.animation.time ~= 1 then
					self.animation.direction = 1;
				end;
			else
				if self.animation.time ~= 0 then
					self.animation.direction = -1;
				end;
			end;
		end;		
        self:raiseActive();
	end;	
	if noEventSend then		
	elseif g_server ~= nil then
		g_server:broadcastEvent(AnimatedObjectExtendEvent.new(self, self.objectcount, self.autoopenState, self.remoteControl), nil, nil, self);
	else
		g_client:getServerConnection():sendEvent(AnimatedObjectExtendEvent.new(self, self.objectcount, self.autoopenState, self.remoteControl));
	end;
end;

function triggerCallback(self, superFunc, triggerId, otherId, onEnter, onLeave, onStay, anotherId)   
	if g_currentMission.missionInfo:isa(FSCareerMissionInfo) then		
		
		if self.autoopenState == nil or self.lockdoor == nil or (self.lockdoor and (onEnter or onLeave or onStay)) then 
			if self.lockdoor ~= nil then AnimatedObjectExtend.autoopenState[3] = true;end;
			AnimatedObjectExtend.setState = {};
			return superFunc(self, triggerId, otherId, onEnter, onLeave, onStay, anotherId);
		else 
			AnimatedObjectExtend.autoopenState[3] = false;
		end;			
		local vehicle = g_currentMission.nodeToObject[otherId];		
		local isVehicle = false;
		local vehicleCanAccess = false;		
		local controlledVehicle = false;
		if vehicle ~= nil then			
			if vehicle.type ~= nil then				
				if g_localPlayer ~= nil and g_localPlayer.getCurrentVehicle ~= nil and vehicle == g_localPlayer:getCurrentVehicle() then controlledVehicle = true;end;
				isVehicle = true;
				if vehicle.getActiveFarm ~= nil then
					vehicleCanAccess = g_currentMission.accessHandler:canFarmAccessOtherId(vehicle:getActiveFarm(), self.ownerFarmId);
				else
					vehicleCanAccess = false;
				end;				
			end;
		end;
		local oldobjectcount = self.objectcount;
		local useauto = false;
		if self.autoopenState > 0 then
			if self.openingHours ~= nil then
				if self.openingHours.isOpen then
					useauto = true;
				else
					useauto = false;
				end;
			else
				useauto = true;
			end;			
		end;
		local manually = useauto and self.remoteControl;
		local onFoot = self.autoopenState == 0;
		local onVehicle = self.autoopenState == 1 or self.autoopenState == 2;
		isVehicle = isVehicle and onVehicle;
		if onEnter or onLeave then			
			if g_localPlayer ~= nil and otherId == g_localPlayer.rootNode then
				if self.autoopenState == 2 then 
					if onEnter then AnimatedObjectExtend.setState = {object=self};else AnimatedObjectExtend.setState = {};end;
					return;
				end;
				if onEnter then
					if self.ownerFarmId == nil or self.ownerFarmId == AccessHandler.EVERYONE or g_currentMission.accessHandler:canFarmAccessOtherId(g_currentMission:getFarmId(), self.ownerFarmId) then						
						AnimatedObjectExtend.setState = {object=self};
						if onFoot or not useauto or manually then						
							g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);
						else
							if useauto then								
								self.objectcount = self.objectcount + 1;								
							end;
						end;
					end;
				else 	
					AnimatedObjectExtend.setState = {};
					if onFoot or not useauto or manually then
						g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);
					else
						if useauto then							
							self.objectcount = math.max(self.objectcount - 1, 0);							
						end;
					end;
				end;				
				if onFoot or not useauto then self:raiseActive();end;	
			else
				if self.autoopenState == 3 then 
					if onEnter and g_localPlayer ~= nil then AnimatedObjectExtend.setState = {object=self};else AnimatedObjectExtend.setState = {};end; --on start game
					return;
				end;
				if isVehicle and controlledVehicle and not self.lockdoor then				
					if self.ownerFarmId == nil or self.ownerFarmId == AccessHandler.EVERYONE or vehicleCanAccess then						
						if onEnter then
							--local canTriggered = self.activatable:getIsActivatable();
							AnimatedObjectExtend.setState = {object=self};
							if useauto then
								if manually then
									g_currentMission.activatableObjectsSystem:addActivatable(self.activatable);
								else
									self.objectcount = self.objectcount + 1;
								end;
							end;
						else 
							--local canTriggered = self.activatable:getIsActivatable();
							AnimatedObjectExtend.setState = {};
							if useauto then
								if manually then
									g_currentMission.activatableObjectsSystem:removeActivatable(self.activatable);
								else
									self.objectcount = math.max(self.objectcount - 1, 0);
								end;
							end;
						end;	
					end;				
				end;
			end;
			if useauto and oldobjectcount ~= self.objectcount and not self.lockdoor then				
				self:autoOpen(self.objectcount, self.autoopenState, self.remoteControl);				
			end;
		--elseif onStay then
		--	AnimatedObjectExtend.setState = {object=self};
		else
			AnimatedObjectExtend.setState = {};
		end;		
	end;
end;

function readStream(self, streamId, connection)
    if connection:getIsServer() then
		self.objectcount = streamReadUInt8(streamId);		
		self.autoopenState = streamReadUInt8(streamId);
		self.remoteControl = streamReadBool(streamId);			
    end;
end;

function writeStream(self, streamId, connection)
    if not connection:getIsServer() then
		streamWriteUInt8(streamId, self.objectcount);		
		streamWriteUInt8(streamId, self.autoopenState);
		streamWriteBool(streamId, self.remoteControl);		
    end;
end;

function registerSavegameXMLPaths(schema, basePath)
    schema:register(XMLValueType.INT, basePath.. "#autoopenState", "Auto open marker state, 0=off, 1=onVehicle+onFoot, 2=onVehicle, 3=onFoot (default 0)");
	schema:register(XMLValueType.BOOL, basePath.. "#lockdoor", "Animated object lock auto open (modder or) (default false)");
	schema:register(XMLValueType.BOOL, basePath.. "#remoteControl", "Animated object auto open (false) or manually (true) (default true)");
end;

function loadFromXMLFile(self, xmlFile, key)    
	local autoopenState = xmlFile:getValue(key.. "#autoopenState");
	local lockdoor = xmlFile:getValue(key.. "#lockdoor");	
	local remoteControl = xmlFile:getValue(key.. "#remoteControl");
	if lockdoor ~= nil then self.lockdoor = lockdoor;if lockdoor then autoopenState = 0;remoteControl = true;end;end;
	if autoopenState ~= nil then self.autoopenState = autoopenState;end;
	if remoteControl ~= nil then self.remoteControl = remoteControl;end;
	return true;
end;

function saveToXMLFile(self, xmlFile, key, usedModNames)
	xmlFile:setValue(key.. "#autoopenState", self.autoopenState or 0);	
	xmlFile:setValue(key.. "#lockdoor", self.lockdoor or false);
	xmlFile:setValue(key.. "#remoteControl", self.remoteControl or true);	
end;

function registerXMLPathsAnimated(schema, basePath)
	schema:setXMLSharedRegistration("AnimatedObject", basePath);
	basePath = basePath.. ".animatedObject(?)";
   	schema:register(XMLValueType.INT, basePath.. ".controls#autoopenState", "Auto open marker state, 0=off, 1=onVehicle+onFoot, 2=onVehicle, 3=onFoot (default 0)");
	schema:register(XMLValueType.BOOL, basePath.. ".controls#lockdoor", "Animated object lock auto open (modder or) (default false)");
	schema:register(XMLValueType.BOOL, basePath.. ".controls#remoteControl", "Animated object auto open (false) or manually (true) (default true)");
	schema:setXMLSharedRegistration();
end;

function registerXMLPathsFence(schema, basePath)
	schema:setXMLSpecializationType("Fence");
    schema:register(XMLValueType.INT, basePath.. ".fence.gate(?)#autoopenState", "Auto open marker state, 0=off, 1=onVehicle+onFoot, 2=onVehicle, 3=onFoot (default 0)");
	schema:register(XMLValueType.BOOL, basePath.. ".fence.gate(?)#lockdoor", "Animated object lock auto open (modder or) (default false)");
	schema:register(XMLValueType.BOOL, basePath.. ".fence.gate(?)#remoteControl", "Animated object auto open (false) or manually (true) (default true)");
	schema:setXMLSharedRegistration();
end;

function AnimatedObjectExtend:registerActionEvent()
	PlayerInputComponent.registerGlobalPlayerActionEvents = Utils.appendedFunction(
		PlayerInputComponent.registerGlobalPlayerActionEvents,
		function(self, controlling)
			if controlling ~= "VEHICLE" then
				local inputAction = InputAction.AUTOOPENSTATE;
				local callbackTarget = self;
				local callbackFunc = self.animatedObjectExtendKeyMouse;
				local triggerUp = false;
				local triggerDown = true;
				local triggerAlways = false;
				local startActive = true;

				local _, eventId = g_inputBinding:registerActionEvent(inputAction, callbackTarget, callbackFunc, triggerUp, triggerDown, triggerAlways, startActive);
				g_inputBinding:setActionEventTextVisibility(eventId, false);
				
				inputAction = InputAction.REMOTECONTROL;
				_, eventId = g_inputBinding:registerActionEvent(inputAction, callbackTarget, callbackFunc, triggerUp, triggerDown, triggerAlways, startActive);
				g_inputBinding:setActionEventTextVisibility(eventId, false);
			end
	end)
	function PlayerInputComponent:animatedObjectExtendKeyMouse(actionName, inputValue, callbackState, isAnalog, isMouse, deviceCategory)
		if g_currentMission.hlUtils == nil or not g_currentMission.hlUtils.dragDrop.on then
			if (actionName == "REMOTECONTROL" or actionName == "AUTOOPENSTATE") and AnimatedObjectExtend.autoopenState[3] then
				local text = AnimatedObjectExtend:getLockdoorText();
				if g_currentMission.hlHudSystem ~= nil then
					g_currentMission.hlHudSystem.showInfoBox( {text, 3500, g_currentMission.hlUtils.getColor("orangeRed", true)} );
				else
					g_currentMission:showBlinkingWarning(text, 3500);
				end;
				AnimatedObjectExtend.autoopenState[3] = false;
				return;
			end;
			if AnimatedObjectExtend.setState == nil or AnimatedObjectExtend.setState.object == nil then return;end;
			if (actionName == "REMOTECONTROL" or actionName == "AUTOOPENSTATE") and AnimatedObjectExtend.setState.object.lockdoor then
				local text = AnimatedObjectExtend:getLockdoorText();
				if g_currentMission.hlHudSystem ~= nil then
					g_currentMission.hlHudSystem.showInfoBox( {text, 3500, g_currentMission.hlUtils.getColor("orangeRed", true)} );
				else
					g_currentMission:showBlinkingWarning(text, 3500);
				end;
				AnimatedObjectExtend.autoopenState[3] = false;
			elseif actionName == "REMOTECONTROL" then
				AnimatedObject:setRemoteControlState(AnimatedObjectExtend.setState.object);
			elseif actionName == "AUTOOPENSTATE" then				
				local autoopenState = AnimatedObjectExtend.setState.object.autoopenState;
				if autoopenState+1 > AnimatedObjectExtend.autoopenState[2] then autoopenState = AnimatedObjectExtend.autoopenState[1];else autoopenState = autoopenState+1;end;
				AnimatedObject:setAutoOpenState(AnimatedObjectExtend.setState.object, autoopenState);						
			end;
		end;
	end;
end;

function onDraw(self)
	if self.animatedObject.autoopenState ~= nil then
		--g_currentMission:addExtraPrintText(tostring(AnimatedObjectExtend:getAutoOpenStateText(self.animatedObject.autoopenState, self.animatedObject.remoteControl or false)));	
	end;
end;

function onUpdate(self, dt)
	if self.animatedObject ~= nil and self.animatedObject.autoopenState ~= nil then
		--g_currentMission:addExtraPrintText(tostring(AnimatedObjectExtend:getAutoOpenStateText(self.animatedObject.autoopenState, self.animatedObject.remoteControl or false)));	
	end;
end;


function AnimatedObjectExtend:readyFlag(flag)
	for f=1, 3 do
		if AnimatedObjectExtend.hasFlag[f] == flag then return true;end;
	end;
	return false;
end;

function AnimatedObjectExtend:getAutoOpenStateText(autoopenState, remoteControl)
	if autoopenState == 0 then return g_i18n:getText("autoopenState").. " ".. g_i18n:getText("configuration_valueDefault").. " (" .. g_i18n:getText("autoopenState".. tostring(autoopenState)).. ")";end;
	return g_i18n:getText("autoopenState").. " ".. g_i18n:getText("autoopenState".. tostring(autoopenState)).. " (".. g_i18n:getText("remoteControl".. tostring(remoteControl)).. ")";	
end;

function AnimatedObjectExtend:getLockdoorText()
	local text = string.format(g_i18n:getText("warning_objectStorageObjectNotSupported"), AnimatedObjectExtend.metadata.title);
	return g_i18n:getText("ui_modUnavailable").. " (XML "..  g_i18n:getText("ui_missionStatusTitle").. ": ".. g_i18n:getText("setting_disasterDestructionState_disabled").. ")\n".. text;
end;

function AnimatedObjectExtend:getRemoteControlText(remoteControl)
	return g_i18n:getText("input_REMOTECONTROL").. " ".. g_i18n:getText("remoteControl".. tostring(remoteControl));	
end;

function AnimatedObjectExtend:getNoPermissionText(autoopenState)
	if autoopenState ~= nil and autoopenState == 0 then
		return g_i18n:getText("ui_construction_couldNotLoadItem").. " (".. g_i18n:getText("autoopenState").. " ".. g_i18n:getText("autoopenState0").. ")";
	end;
	return g_i18n:getText("shop_messageNoPermissionGeneral");
end;

function AnimatedObjectExtend:setNoPermissionText(autoopenState)
	local text = AnimatedObjectExtend:getNoPermissionText(autoopenState);
	if g_currentMission.hlHudSystem ~= nil then
		g_currentMission.hlHudSystem.showInfoBox( {text, 3500, g_currentMission.hlUtils.getColor("orangeRed", true)} );
	else
		g_currentMission:showBlinkingWarning(text, 3500);
	end;
end;

function AnimatedObjectExtend:setNoSupportObjectText()
	local text = string.format(g_i18n:getText("warning_objectStorageObjectNotSupported"), AnimatedObjectExtend.metadata.title);
	if g_currentMission.hlHudSystem ~= nil then
		g_currentMission.hlHudSystem.showInfoBox( {text, 4500, g_currentMission.hlUtils.getColor("orangeRed", true)} );
	else
		g_currentMission:showBlinkingWarning(text, 4500);
	end;
end;		

function AnimatedObjectExtend:getDetiServer()
	return g_server ~= nil and g_client ~= nil and g_dedicatedServer ~= nil;	
end;

function init()
	AnimatedObject.load = Utils.overwrittenFunction(AnimatedObject.load, load);
	AnimatedObject.readStream = Utils.appendedFunction(AnimatedObject.readStream, readStream);
	AnimatedObject.registerSavegameXMLPaths = Utils.appendedFunction(AnimatedObject.registerSavegameXMLPaths, registerSavegameXMLPaths);
	AnimatedObject.loadFromXMLFile = Utils.appendedFunction(AnimatedObject.loadFromXMLFile, loadFromXMLFile);
	AnimatedObject.saveToXMLFile = Utils.appendedFunction(AnimatedObject.saveToXMLFile, saveToXMLFile);
	AnimatedObject.registerXMLPaths = Utils.appendedFunction(AnimatedObject.registerXMLPaths, registerXMLPathsAnimated);
	PlaceableFence.registerXMLPaths = Utils.appendedFunction(PlaceableFence.registerXMLPaths, registerXMLPathsFence);
	AnimatedObject.writeStream = Utils.appendedFunction(AnimatedObject.writeStream, writeStream);
	PlaceableFence.updateSegmentShapes = Utils.appendedFunction(PlaceableFence.updateSegmentShapes, updateSegmentShapes);
	PlaceableFence.onLoad = Utils.overwrittenFunction(PlaceableFence.onLoad, onLoad);
	AnimatedObject.triggerCallback = Utils.overwrittenFunction(AnimatedObject.triggerCallback, triggerCallback);
	--AnimatedObjectActivatable.draw = Utils.appendedFunction(AnimatedObjectActivatable.draw, onDraw)
	--AnimatedObject.update = Utils.appendedFunction(AnimatedObject.update, onUpdate)
	if not AnimatedObjectExtend:getDetiServer() then AnimatedObjectExtend:registerActionEvent();end;
end;
print("---loading ".. tostring(AnimatedObjectExtend.metadata.title).. " ".. tostring(AnimatedObjectExtend.metadata.version).. "(#".. tostring(AnimatedObjectExtend.metadata.build).. ") ".. tostring(AnimatedObjectExtend.metadata.author).. "---")
init();