NAME	 	= "Engi Bug Preventer"
VERSION		= "1.0"
TYPE		= "DISABLED"--"CONFIG"
GAME		= "CNC3TW,CNC3KW"
DESCRIPTION = "Prevent the engineer bug exploit"
AUTHOR 		= "Mjstral"
PASTEBIN	= ""

-----------------------------------------------------------------
----------------------SCRIPT SECTION-----------------------------
-----------------------------------------------------------------

-- <ScriptedEvent Name="ComingToCapture" />

-- <ModelConditionEvent Name="OnCapturingEvent">
	-- <Conditions>+CAPTURING</Conditions>
-- </ModelConditionEvent>

-- <ObjectStatusEvent Name="OnSpecialAbilityActiveEvent">
	-- <Conditions>+SPECIALABILITY_ACTIVE</Conditions>
-- </ObjectStatusEvent>

-- <EventList Name="EngineerFunctions" Inherit="BaseScriptFunctions">
	-- <EventHandler EventName="OnSpecialAbilityActiveEvent"	ScriptFunctionName="EngineerBugExploitPreventionStart" DebugSingleStep="false"/>
	-- <EventHandler EventName="OnCapturingEvent"	ScriptFunctionName="EngineerBugExploitPreventionEnd" DebugSingleStep="false"/>
-- </EventList>

-- <EventList Name="BuildingFunctions" Inherit="BaseScriptFunctions">
	-- <EventHandler EventName="ComingToCapture"	ScriptFunctionName="EngineerBugExploitPreventionEnemyBuidlingStart" DebugSingleStep="false"/>
-- </EventList>

EngineerTable = {}

function EngineerBugExploitPreventionEnemyBuidlingStart(self)
	EngineerTable[unit][self] = {}
	EngineerTable[unit][self]["unit_ref"] = self
	EngineerTable[unit][self]["start_distance"] = GetObjectDistance(self, EngineerTable[unit]["unit_ref"])
end

function EngineerBugExploitPreventionStart(self)
	EngineerTable[self] = {}
	EngineerTable[self]["unit_ref"] = self
	EngineerTable[self]["start_frame"] = GetFrame()
	ObjectBroadcastEventToEnemies(self, "ComingToCapture", 9999)
end

function EngineerBugExploitPreventionEnd(self)
	for k,v in EngineerTable[self] do
		v["end_distance"] = GetObjectDistance(self ,v["unit_ref"])
		if v["end_distance"] < 3 then 
			EngineerTable[self]["end_frame"] = GetFrame()
			local EngineerSpeed = 36
			local EngineerSpeedCalculated = (EngineerTable[self]["start_distance"] - EngineerTable[self]["end_distance"]) / (EngineerTable[self]["end_frame"] - EngineerTable[self]["start_frame"])
			if EngineerSpeedCalculated > EngineerSpeed then
				ExecuteAction("NAMED_KILL", self)
				ExecuteAction("SHOW_MILITARY_CAPTION", "Player " .. ObjectTeamName(self) .. " used the engineer bug exploit !!!\nEngineerSpeed was: " .. EngineerSpeedCalculated .. "\nNormal Speed is: 36, 8)
			end
		end
	end
end

function GetObjectDistance(object1 ,object2, start_distance)
	local CompareTable    	  = { LT=0, LE=1, EQ=2, GE=3, GT=4, NE=5, ["<"]=0, ["<="]=1, ["=="]=2, [">="]=3, [">"]=4, ["~="]=5 }
	local GetObjectStringRef = function(object)       
		if type(object) == "string" then return object
		else 
			local _, count = gsub(ObjectDescription(object),"%(","")
			if count>1 then
				return strsub(ObjectDescription(object), strfind(ObjectDescription(object),"(",1,true)+1,strfind(ObjectDescription(object),")",1,true)-1)
			else
				local StrRef = "object_" .. floor(GetRandomNumber()*99999999)
				ExecuteAction("SET_UNIT_REFERENCE", StrRef, object)
				return StrRef
			end
		end
	end
	object1 = GetObjectStringRef(object1)
	object2 = GetObjectStringRef(object2)	
	if object1==nil or object2==nil or not EvaluateCondition("NAMED_NOT_DESTROYED",object1) or not EvaluateCondition("NAMED_NOT_DESTROYED",object2) then return 0 end
	local v = {}
	v.GetDistance = function(lowerlimit,upperlimit)
		local mid=(upperlimit+lowerlimit)/2
		if upperlimit-lowerlimit<=1 then return lowerlimit
			elseif EvaluateCondition("DISTANCE_BETWEEN_OBJ", %object1, %object2, CompareTable["<"], mid) then return %v.GetDistance(lowerlimit,mid)
		else return floor(%v.GetDistance(mid,upperlimit)+0.5) end
	end
	if start_distance then return v.GetDistance(0,tonumber(start_distance)) 
	else return v.GetDistance(0,12870) end   --maxdiagsize=ceil(sqrt(2*(7500+2*800)^2)))
end

CurDrawableGetCurrentTargetDistance()