· 8 years ago · Jul 07, 2018, 08:00 PM
1import("ScarUtil.scar")
2import("Fatalities/Fatalities.scar")
3
4-- Creates a temporary SGroup from a squadID
5function SGroup_FromSquad(squad)
6 local sg_temp = SGroup_CreateIfNotFound("sg_temp_from_squad");
7 SGroup_Clear(sg_temp);
8 SGroup_Add(sg_temp, squad);
9 return sg_temp;
10end
11
12-- Fetches the first vehicle entity from a squad
13function Entity_VehicleFromSquad(squad)
14
15 for i = 0, Squad_Count(squad) - 1 do
16 local e = Squad_EntityAt(squad, i);
17 if Entity_IsVehicle(e) then
18 return e;
19 end
20 end
21
22 return nil;
23
24end
25
26function WinCondition_GameOver(winningTeam, losingTeam)
27 -- Set the winning team (this will fire win/loss events for each player).
28 World_SetTeamWin(winningTeam)
29
30 local winningPlayers = Team_GetPlayers(winningTeam)
31 local losingPlayers = Team_GetPlayers(losingTeam)
32
33 Fatality_Execute(winningPlayers, losingPlayers)
34end
35
36function WinCondition_Check()
37 local results = {}
38
39 -- Check every player on each team for ownership of the "annihilation_condition" entity.
40 for i = 1, World_GetPlayerCount() do
41 local player = World_GetPlayerAt(i)
42 local team = Player_GetTeam(player)
43
44 results[team] = results[team] or { surrender_count = 0, annihilation_condition_count = 0 }
45
46 -- If any player on a team has surrendered, that team loses.
47 if (Player_IsSurrendered(player)) then
48 results[team].surrender_count = results[team].surrender_count + 1
49 end
50
51 -- If at least one player on a given team owns an "annihilation_condition" entity, then that team has not yet lost.
52 if (Player_IsAlive(player)) then
53 local entities = Player_GetEntities(player)
54 for entityCount = 1, EGroup_CountSpawned(entities) do
55 local entity = EGroup_GetSpawnedEntityAt(entities, entityCount)
56 if (Entity_IsOfType(entity, "annihilation_condition")) then
57 results[team].annihilation_condition_count = results[team].annihilation_condition_count + 1
58 break
59 end
60 end
61 end
62 end
63
64 -- Check if any team has lost.
65 for team,result in pairs(results) do
66 if (result.surrender_count > 0 or result.annihilation_condition_count == 0) then
67 Rule_RemoveAll()
68
69 local winningTeam = Team_GetEnemyTeam(team)
70 local losingTeam = team
71
72 WinCondition_GameOver(winningTeam, losingTeam)
73 end
74 end
75end
76
77local function WinCondition_Init()
78 Rule_AddInterval(WinCondition_Check, 3)
79end
80
81Scar_AddInit(WinCondition_Init)
82
83-- Fuel System:
84
85fuel_profiles = {};
86fuel_profiles["529d827de28f4899a6021f113a61bde5:dodge_wc51_ambulance_squad_mp"] = {fuel_max = 550, fuel_burn = 2.7};
87
88fuel_targets = {};
89
90-- Register a vehicle
91function Fuel_RegisterMe(...)
92
93 local entityVehicle = Entity_VehicleFromSquad(arg[1]); -- Get the vehicle entity in the squad
94
95 if entityVehicle == nil then -- Make sure the entity Vehicle is not Null/Nil
96 return; -- The target is not a vehicle, or atleast there's no entity in the squad that's marked as a vehicle
97 end
98
99 local entityID = Entity_GetGameID(entityVehicle); -- Get the entity ID of the vehicle entity
100 local squadbp = BP_GetName(Squad_GetBlueprint(arg[1])); -- Get the blueprint name of the squad
101 local player = Util_GetPlayerOwner(arg[1]); -- Get the player owner of the squad
102
103 if (fuel_targets[entityID] ~= nil) then -- Is the entity already registered in the system?
104 return; -- The target already exists in the system, no need to re-add it. Likewise we'll also avoid a bug where American vehicles can re-crew to regain lost fuel
105 end
106
107 Cmd_InstantUpgrade(SGroup_FromSquad(arg[1]), BP_GetUpgradeBlueprint("529d827de28f4899a6021f113a61bde5:fuel_capable"), 1); -- Give the squad an upgrade, marking it as fuel capable
108 -- Replace the <ModID> with your mod ID, so for example, this mod would use ID 529d827de28f4899a6021f113a61bde5
109 -- and will therefore look like this: Cmd_InstantUpgrade(SGroup_FromSquad(arg[1]), BP_GetUpgradeBlueprint("529d827de28f4899a6021f113a61bde5:fuel_capable"), 1);
110 -- The SGroup_FromSquad function is currently undefined, as it's a custom function that we'll introduce later.
111
112 -- Here we actually register the entity in the system
113 fuel_targets[entityID] = { -- Create a new entry in the table with indexing key set to the unique game ID given to the entity
114 is_aiOwned = AI_IsAIPlayer(player), -- Is the AI an owner of this vehicle?
115
116 -- The following three variables are set using the fuel_profiles table. You'll be filling in these profiles later, dont worry.
117 -- But as you can probably already see, the blueprint name is being used as a key. (if you want to challenge yourself, set up the fuel_profiles yourself without reading the tutorial)
118 maxf = fuel_profiles[squadbp].fuel_max;
119 current = fuel_profiles[squadbp].fuel_max;
120 burn = fuel_profiles[squadbp].fuel_burn;
121
122 warning50 = false; -- Variable used later, set it to false for now
123 out = false; -- Variable used to mark whether the vehicle is currently out of fuel
124 modifier = nil; -- A variable containing a speed modifier reference
125 position = Entity_GetPosition(entityVehicle); -- The current position of the vehicle
126 };
127
128 -- Should the AI ignore fuel for this vehicle? (this is handy for vehicles like the SWS where the AI could be dumb and have it use up its fuel before it gets to set up)
129 fuel_targets[entityID].ignoreifai = fuel_profiles[squadbp].ai_ignore or false; -- Make the default value false. If the ai_ignore flag is set to true, it will make the AI ignore the vehicle
130
131 if (Rule_Exists(Fuel_Update) == false) then -- Check if there's already a rule calling the Fuel_Update function (defined soon)
132 Rule_AddInterval(Fuel_Update, 1); -- Add an interval to update the fuel system every second
133 end
134
135end
136
137-- Updates the state of the fuel targets
138function Fuel_Update()
139
140 for k,v in pairs(fuel_targets) do -- Go through each element in the fuel_targets table where k = entity ID and v = entity entry
141
142 if Entity_IsValid(k) then -- Make sure the entity exists/is valid
143
144 if not (v.ignoreifai == true and v.is_aiOwned) then -- Make sure, that if the owner is an AI player, we're allowed to update it
145
146 local e = Entity_FromWorldID(k); -- Get the actual entity from the entity ID
147
148 if Entity_IsMoving(e) then -- Check if the entity is moving
149
150 local s = Entity_GetSquad(e); -- Get the squad the entity is part of
151 local sg = SGroup_FromSquad(s); -- Make a temporary SquadGroup
152
153 v.current = v.current - v.burn; -- Subtract the burn rate from the current amount of fuel
154
155 if v.current <= 0 and v.out == false then -- Check if the fuel amount is less than or equal to 0 AND the vehicle is not marked as out yet
156
157 Cmd_CriticalHit(Util_GetPlayerOwner(s), sg, BP_GetCriticalBlueprint("529d827de28f4899a6021f113a61bde5:vehicle_outfuel"), 0); -- Give a critical to the vehicle, disabling movement
158
159 if (Game_GetLocalPlayer() == Util_GetPlayerOwner(s)) then -- Is the vehicle owned by the local player?
160 EventCue_Create(CUE.VEHICLE, "$529d827de28f4899a6021f113a61bde5:1", "$529d827de28f4899a6021f113a61bde5:1", sg, "$529d827de28f4899a6021f113a61bde5:1", nil, 7, true); -- Alert the local player of the vehicle running out of fuel
161 end
162
163 v.out = true; -- Mark the vehicle as having run out of fuel
164
165 elseif v.current < (v.maxf / 3.0) and v.warning50 == false then -- Is the amount less than a third of the max fuel and the warning50 is set to false
166
167 if (v.modifier ~= nil) then -- Incase the modifier is already in place (to make sure it's not stacked)
168 Modifier_Remove(v.modifier); -- Remove the modifier
169 end
170
171 v.modifier = Modify_UnitSpeed(sg, 0.75); -- Add a speed modifier (makes the unit move 25% slower)
172 v.warning50 = true; -- Mark this as having reached it's low point
173
174 end
175 end
176 end
177
178 else -- Not valid
179
180 fuel_targets[k] = nil; -- Make it be nil, so we no longer check this vehicle
181
182 end
183
184 end
185
186end
187
188-- Allows the executer to refuel the target
189function Fuel_RefuelTarget(executer, target)
190
191 if scartype(executer) == ST_SQUAD and scartype(target) == ST_SQUAD then -- Firtsly make sure both are squads
192
193 local __InfantryGroup = SGroup_CreateIfNotFound("__InfantryGroup"); -- Crate a Sgroup for the infantry squad that is going to refuel the vehicle
194 SGroup_Add(__InfantryGroup, executer); -- Add the ability executer to the Sgroup
195
196 local entityVehicle = Entity_VehicleFromSquad(target); -- Get the vehicle from the target squad
197 local entityID = Entity_GetGameID(entityVehicle); -- Get the entityID
198
199 if fuel_targets[entityID] ~= nil then -- Make sure the entity is registered in the fuel system
200
201 fuel_targets[entityID].current = fuel_targets[entityID].maxf; -- Set the vehicles current fuel to its max fuel
202
203 UI_CreateColouredSquadKickerMessage(Game_GetLocalPlayer(), target, "$529d827de28f4899a6021f113a61bde5:2", 0, 255, 0, 0); -- Create a coloured kicker message that says 100% fuel (the last 4 numbers are RGBA numbers)
204 SGroup_RemoveUpgrade(SGroup_FromSquad(Entity_GetSquad(entityVehicle)), BP_GetUpgradeBlueprint("529d827de28f4899a6021f113a61bde5:fuel_out")); -- Remove the Fuel_Out upgrade from the entity
205
206 if Entity_HasCritical(entityVehicle, BP_GetCriticalBlueprint("529d827de28f4899a6021f113a61bde5:vehicle_outfuel")) == true then -- Make sure the target actually has this critical
207 Entity_RemoveCritical(entityVehicle, BP_GetCriticalBlueprint("529d827de28f4899a6021f113a61bde5:vehicle_outfuel")); -- Remove the critical
208 end
209
210 if (fuel_targets[entityID].modifier ~= nil) then -- Is the speed modifier valid?
211 Modifier_Remove(fuel_targets[entityID].modifier); -- Remove the speed modifier
212 end
213
214 fuel_targets[entityID].warning50 = false; -- Reset this variable
215 fuel_targets[entityID].out = false -- Reset the out variable
216
217 SGroup_RemoveUpgrade(__InfantryGroup, BP_GetUpgradeBlueprint("529d827de28f4899a6021f113a61bde5:fuel_equipped")); -- Remove the fuel_equippped upgrade from the infantry
218
219 end
220
221 SGroup_Clear(__InfantryGroup); -- Clear the infantry group
222
223 end -- You can add other combinations down here (like ST_SQUAD and ST_ENTITY)
224
225end