This is sort of a package to easily add an automated control to your gates. This is especially for mappers who have very basic SCAR knowledge.
Looking at the gate automation problem I thought it would be useful to have a single line instruction that can allow the gate automation.
Truth is I just hate having to duplicate functions because I am always making a lot of mistakes.
The basic code is not mine. This is derived from Incarnate and Fuggles code. What I did was encapsulate it in order to have a single line call.
What it does for each gate:
- gate is closed if no player owns all the control points associated to the gate
- if some player owns all control points associated to a gate then gate opens if friendly unit come in the area of an "opening marker". This marker can be placed anywhere you want on the map.
- when opened, the gate will close if some ennemy units come in the area of a "closing marker". This marker will most probably be centered on the gate but it is not a requirement.
- if both open and close conditions are met then the gate will open (or stay opened).
Notes:
- you can put a gatehouse_01 over the gate. It is not a problem for the code.
- code is load/save capable when playing signleplayer skirmish.
- code is multiplayer capable.
- code could be extended to change ownership of the door in order to allow enemies to attack/destroy the gate. I can do it if someone asks
- it would be better to avoid using several control points for one gate when players are teamed. If two allied player own each a portion of one gate's points then they won't be able to open the gate. They will have to wait for the ennemy to capture the points because you can't capture an allied point. I have a workaround to avoid this. Ask me if you need it.
How to setup the automation:
What you need is :
- a map with one or more gate doors. They need to be "gatehouse_door_01". In Mission Editor, it can be found in the folder environment/single_player/ms07. World needs to be the owner of the gate.
- at least one capturable point (strategic point, relic, strategic objective) to control the gate(s).
Steps to get automated control of the gates:
1/ Open the map in the Mission Editor
2/ Create an Entity Group for each gate door and assign the door object to it. I'd recommend naming the groups "eg_Gate1", "eg_Gate2", and so on.
3/ Create an Entity Group for each gate door which includes the associated control points. They can be objective points, strategic points or relics. There can be several points. I'd recommend naming the groups "eg_CtrlGate1", "eg_CtrlGate2", and so on.
4/ Create a basic marker for each gate to open it. Use radius to set the zone size. I'd recommend naming the markers "mkr_OpenGate1", "mkr_OpenGate2", and so on.
5/ Create a basic marker for each gate to close it. Use radius to set the zone size. I'd recommend naming the groups "mkr_CloseGate1", "mkr_CloseGate2", and so on.
6/ Save and close Mission Editor
7/ Create a text file in the same folder as your map with the same name but with extension "scar". For example: tmp.sgb => tmp.scar.
8/ Open the scar file with an editor (notepad is enough)
9/ Copy and Paste the following code in the file
10/ The pasted code is for 3 gates. Now edit the lines 15-17 which are in bold characters to remove gates or add some more. To do it, just delete or copy/paste the lines and set the group names. Be careful :Code:import("ScarUtil.scar") import("WXPScarUtil.scar") function OnInit() -- add gate(s) to gate manager using. -- GatesMgr.Add(String egGateName, String egCtrlName, String mkrOpenGateName, String mkrCloseGateName) -- where -- egGateName : name of Egroup that contains the door -- egCtrlName : name of egroup that contains points that need to be controlled to open the gate -- mkrOpenGateName : name of the marker to cross to open the gate (owner + allies) -- mkrCloseGateName : name of the marker to cross to close the gate (ennemy of owner) GatesMgr.Add("eg_Gate1", "eg_CtrlGate1", "mkr_OpenGate1", "mkr_CloseGate1") GatesMgr.Add("eg_Gate2", "eg_CtrlGate2", "mkr_OpenGate2", "mkr_CloseGate2") GatesMgr.Add("eg_Gate3", "eg_CtrlGate3", "mkr_OpenGate3", "mkr_CloseGate3") -- start gate rule Rule_AddInterval(GatesRule,1) end Scar_AddInit(OnInit) -- -- Start of Gate manager -- -- Do not edit if you don't know what you're doing ;) -- Gate rule, to be runned each second function GatesRule() for GateIndex,GateData in ipairs(GatesMgr.List) do GatesMgr.PlayGate(GateData) end end -- Initialize GateMgr table if this is a new game (otherwise game is reloading) if GatesMgr==nil then GatesMgr={ List={} } end -- GatesMgr.Add(String egGateName, String egCtrlName, String mkrOpenGateName, String mkrCloseGateName) -- Add a gate to the GateMGr -- egGateName : name of Egroup that contains the door -- egCtrlName : name of egroup that contains points that need to be controlled to open the gate -- mkrOpenGateName : name of the marker to cross to open the gate (owner + allies) -- mkrCloseGateName : name of the marker to cross to close the gate (ennemy of owner) function GatesMgr.Add(egGateName, egCtrlName, mkrOpenGateName, mkrCloseGateName) -- store gate's data in a table local Gate={ egGateName=egGateName, egCtrlName=egCtrlName, mkrOpenGateName=mkrOpenGateName, mkrCloseGateName=mkrCloseGateName, IsClosed=true } -- save local table table.insert(GatesMgr.List,Gate) end function GatesMgr.OpenGate(GateData) print("open gate " .. GateData.egGateName) Anim_PlayEGroupAnim( EGroup_FromName( GateData.egGateName), "die") GateData.IsClosed=false GateData.EndMove=World_GetGameTime()+7 end function GatesMgr.CloseGate(GateData) print("close gate " .. GateData.egGateName) EGroup_ReSpawn(GateData.egGateName) Anim_PlayEGroupAnim( EGroup_FromName( GateData.egGateName), "door_raise") GateData.IsClosed=true GateData.EndMove=World_GetGameTime()+7 end function GatesMgr.PlayGate(GateData) -- Gate is moving => nothing to be done if GateData.EndMove~=nil then if World_GetGameTime()>=GateData.EndMove then GateData.EndMove=nil if GateData.IsClosed==false then EGroup_DeSpawn(GateData.egGateName) end end return end --check gate owner local NewGateOwner for i=0,World_GetPlayerCount()-1 do if EGroup_IsCapturedByPlayer(GateData.egCtrlName, World_GetPlayerAt(i), true) then NewGateOwner=i break end end -- if no owner or owner changed then close gate if it is open and exit if (NewGateOwner~=GateData.GateOwner) or (NewGateOwner==nil) then GateData.GateOwner=NewGateOwner if GateData.IsClosed==false then GatesMgr.CloseGate(GateData) end return end -- if gate is closed => open if friendly troops are near local GateOwnerID=World_GetPlayerAt( GateData.GateOwner ) if GateData.IsClosed==true then for i=0,World_GetPlayerCount()-1 do if Player_GetRelationship( World_GetPlayerAt( GateData.GateOwner), World_GetPlayerAt(i))==R_ALLY then if Player_AreSquadsNearMarker( World_GetPlayerAt(i), GateData.mkrOpenGateName ) then GatesMgr.OpenGate(GateData) return end end end -- gate is open, close if ennemies are near, leave it open in case both friends and ennemies are near else local close=false for i=0,World_GetPlayerCount()-1 do local Relation=Player_GetRelationship( World_GetPlayerAt( GateData.GateOwner), World_GetPlayerAt(i)) if Relation==R_ALLY then if Player_AreSquadsNearMarker( World_GetPlayerAt(i), GateData.mkrOpenGateName ) then return end elseif Relation==R_ENEMY then if Player_AreSquadsNearMarker( World_GetPlayerAt(i), GateData.mkrCloseGateName ) then close=true end end end if close then GatesMgr.CloseGate(GateData) end end end -- -- End of Gate manager --
- change only the names between " ".
- code is case sensitive: "eg_Ctrl_Gate1" is not the same thing as "eg_ctrl_gate1". If you want to be sure, you can copy and paste names from the Mission Editor.
11/ Save and close notepad. You can now play and see your gates opening or closing.
There are some comments in the code to explain how it is working.
Feel free to ask any question in this thread and I will try to answer as I can.





