Skip to content

Commit d7249cc

Browse files
committed
Reveal Closest Resource Areas and Refactor of Resource Mod
- Adds new feature that will reveal the closest resource point to each team's spawn location to ensure the team can see at least one resource when the round begins. This can be configured with two new preferences: -- Resources_Aliens_RevealClosestAreaOnStart (default: false) -- Resources_Humans_RevealClosestAreaOnStart (default: true) - Refactor of code for Resource mod to remove hard-coded team index values - Adds a new setting to allow adjusting starting resources for each faction separately, by default these are now all equal -- Resources_Centauri_StartingAmount (default: 8000) -- Resources_Sol_StartingAmount (default: 8000) -- Resources_Aliens_StartingAmount (default: 8000)
1 parent c51cbff commit d7249cc

File tree

1 file changed

+150
-42
lines changed

1 file changed

+150
-42
lines changed

Si_Resources/Si_Resources.cs

Lines changed: 150 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ You should have received a copy of the GNU General Public License
3232
using System;
3333
using System.Linq;
3434

35-
[assembly: MelonInfo(typeof(ResourceConfig), "Resource Configuration", "1.1.1", "databomb")]
35+
[assembly: MelonInfo(typeof(ResourceConfig), "Resource Configuration", "1.2.0", "databomb")]
3636
[assembly: MelonGame("Bohemia Interactive", "Silica")]
3737
[assembly: MelonOptionalDependencies("Admin Mod")]
3838

@@ -41,16 +41,21 @@ namespace Si_Resources
4141
public class ResourceConfig : MelonMod
4242
{
4343
static MelonPreferences_Category _modCategory = null!;
44-
static MelonPreferences_Entry<int> Pref_Resources_Humans_StartingAmount = null!;
44+
static MelonPreferences_Entry<int> Pref_Resources_Centauri_StartingAmount = null!;
45+
static MelonPreferences_Entry<int> Pref_Resources_Sol_StartingAmount = null!;
4546
static MelonPreferences_Entry<int> Pref_Resources_Aliens_StartingAmount = null!;
47+
static MelonPreferences_Entry<bool> Pref_Resources_Aliens_RevealClosestArea = null!;
48+
static MelonPreferences_Entry<bool> Pref_Resources_Humans_RevealClosestArea = null!;
4649

4750
public override void OnInitializeMelon()
4851
{
4952
_modCategory ??= MelonPreferences.CreateCategory("Silica");
50-
Pref_Resources_Humans_StartingAmount ??= _modCategory.CreateEntry<int>("Resources_Humans_StartingAmount", 11000);
51-
Pref_Resources_Aliens_StartingAmount ??= _modCategory.CreateEntry<int>("Resources_Aliens_StartingAmount", 9000);
53+
Pref_Resources_Centauri_StartingAmount ??= _modCategory.CreateEntry<int>("Resources_Centauri_StartingAmount", 8000);
54+
Pref_Resources_Sol_StartingAmount ??= _modCategory.CreateEntry<int>("Resources_Sol_StartingAmount", 8000);
55+
Pref_Resources_Aliens_StartingAmount ??= _modCategory.CreateEntry<int>("Resources_Aliens_StartingAmount", 8000);
56+
Pref_Resources_Aliens_RevealClosestArea ??= _modCategory.CreateEntry<bool>("Resources_Aliens_RevealClosestAreaOnStart", false);
57+
Pref_Resources_Humans_RevealClosestArea ??= _modCategory.CreateEntry<bool>("Resources_Humans_RevealClosestAreaOnStart", true);
5258
}
53-
5459

5560
public override void OnLateInitializeMelon()
5661
{
@@ -66,10 +71,12 @@ public override void OnLateInitializeMelon()
6671

6772
QList.Options.RegisterMod(this);
6873

69-
QList.OptionTypes.IntOption humanStartingRes = new(Pref_Resources_Humans_StartingAmount, true, Pref_Resources_Humans_StartingAmount.Value, 3500, 50000, 500);
70-
QList.OptionTypes.IntOption alienStartingRes = new(Pref_Resources_Aliens_StartingAmount, true, Pref_Resources_Aliens_StartingAmount.Value, 3500, 50000, 500);
74+
QList.OptionTypes.IntOption centauriStartingRes = new(Pref_Resources_Centauri_StartingAmount, true, Pref_Resources_Centauri_StartingAmount.Value, 8000, 50000, 500);
75+
QList.OptionTypes.IntOption solStartingRes = new(Pref_Resources_Sol_StartingAmount, true, Pref_Resources_Sol_StartingAmount.Value, 8000, 50000, 500);
76+
QList.OptionTypes.IntOption alienStartingRes = new(Pref_Resources_Aliens_StartingAmount, true, Pref_Resources_Aliens_StartingAmount.Value, 8000, 50000, 500);
7177

72-
QList.Options.AddOption(humanStartingRes);
78+
QList.Options.AddOption(centauriStartingRes);
79+
QList.Options.AddOption(solStartingRes);
7380
QList.Options.AddOption(alienStartingRes);
7481
#endif
7582
}
@@ -113,8 +120,7 @@ public static void Command_Resources(Player? callerPlayer, String args)
113120
}
114121

115122
string amountText = args.Split(' ')[1];
116-
int amount = 0;
117-
if (!int.TryParse(amountText, out amount))
123+
if (!int.TryParse(amountText, out int amount))
118124
{
119125
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, commandName, ": Invalid amount specified");
120126
return;
@@ -151,52 +157,53 @@ public static void Command_Resources(Player? callerPlayer, String args)
151157
[HarmonyPatch(typeof(MP_Strategy), nameof(MP_Strategy.SetTeamVersusMode))]
152158
private static class Resources_Patch_MPStrategy_SetTeamVersusMode
153159
{
154-
public static void Postfix(MP_Strategy __instance, MP_Strategy.ETeamsVersus __0)
160+
public static void Postfix(MP_Strategy __instance, GameModeExt.ETeamsVersus __0)
155161
{
156162
try
157163
{
158-
switch (__0)
164+
foreach (StrategyTeamSetup strategyTeamSetup in __instance.TeamSetups)
159165
{
160-
case MP_Strategy.ETeamsVersus.HUMANS_VS_HUMANS:
166+
if (!__instance.GetTeamSetupActive(strategyTeamSetup))
161167
{
162-
// Sol
163-
Team.Teams[2].StartingResources = Pref_Resources_Humans_StartingAmount.Value;
164-
// Centauri
165-
Team.Teams[1].StartingResources = Pref_Resources_Humans_StartingAmount.Value;
168+
continue;
169+
}
166170

167-
MelonLogger.Msg("Set starting resources. Humans: " + Pref_Resources_Humans_StartingAmount.Value.ToString());
168-
break;
171+
// re-adjust starting resources immediately after the game sets it
172+
strategyTeamSetup.Team.StartingResources = GetTeamStartingResources(strategyTeamSetup.Team);
173+
MelonLogger.Msg("Set starting resources for Team (" + strategyTeamSetup.Team.TeamShortName + ") to " + strategyTeamSetup.Team.StartingResources);
174+
175+
// check if we should make the first biotics/balterium resource area visible to the team
176+
if (!MakeClosestResearchAreaVisible(strategyTeamSetup.Team))
177+
{
178+
continue;
169179
}
170-
case MP_Strategy.ETeamsVersus.HUMANS_VS_ALIENS:
180+
181+
Resource? resourceType = GetTeamResourceType(strategyTeamSetup.Team);
182+
if (resourceType == null)
171183
{
172-
// Alien
173-
Team.Teams[0].StartingResources = Pref_Resources_Aliens_StartingAmount.Value;
174-
// Sol
175-
Team.Teams[2].StartingResources = Pref_Resources_Humans_StartingAmount.Value;
184+
MelonLogger.Warning("Could not find default resource type for team: " + strategyTeamSetup.Team.TeamShortName);
185+
continue;
186+
}
176187

177-
MelonLogger.Msg("Set starting resources. Aliens: " + Pref_Resources_Aliens_StartingAmount.Value.ToString() + " Humans: " + Pref_Resources_Humans_StartingAmount.Value.ToString());
178-
break;
188+
if (ResourceArea.GetNumKnownResourcesAreas(strategyTeamSetup.Team, resourceType) > 0)
189+
{
190+
MelonLogger.Msg("Already a visible resource type for team: " + strategyTeamSetup.Team.TeamShortName);
191+
continue;
179192
}
180-
case MP_Strategy.ETeamsVersus.HUMANS_VS_HUMANS_VS_ALIENS:
193+
194+
ResourceArea? closestStartingResourceArea = GetTeamClosestResourceArea(strategyTeamSetup.Team, resourceType);
195+
if (closestStartingResourceArea == null)
181196
{
182-
// Alien
183-
Team.Teams[0].StartingResources = Pref_Resources_Aliens_StartingAmount.Value;
184-
// Sol
185-
Team.Teams[1].StartingResources = Pref_Resources_Humans_StartingAmount.Value;
186-
// Centauri
187-
Team.Teams[2].StartingResources = Pref_Resources_Humans_StartingAmount.Value;
188-
189-
MelonLogger.Msg("Set starting resources. Aliens: " + Pref_Resources_Aliens_StartingAmount.Value.ToString() + " Humans: " + Pref_Resources_Humans_StartingAmount.Value.ToString());
190-
break;
197+
MelonLogger.Warning("Could not find closest resource area for team: " + strategyTeamSetup.Team.TeamShortName);
198+
continue;
191199
}
192-
}
193200

194-
if (__0 != MP_Strategy.ETeamsVersus.NONE)
195-
{
196-
// set how many resources are in each resource area
201+
UnityEngine.Vector3 unitSpawnPosition = closestStartingResourceArea.transform.position;
202+
unitSpawnPosition[1] += 7f;
197203

198-
// hook? ResourceArea.DistributeAllResources
199-
// iterate and set ResourceArea.ResourceAmountMax = ?
204+
// make this visible by spawning a starting unit
205+
string prefabName = (strategyTeamSetup.Team.Index == (int)SiConstants.ETeam.Alien ? "Crab" : "Soldier_Scout");
206+
HelperMethods.SpawnAtLocation(prefabName, unitSpawnPosition, UnityEngine.Quaternion.identity, strategyTeamSetup.Team.Index);
200207
}
201208
}
202209
catch (Exception error)
@@ -205,5 +212,106 @@ public static void Postfix(MP_Strategy __instance, MP_Strategy.ETeamsVersus __0)
205212
}
206213
}
207214
}
215+
216+
static bool MakeClosestResearchAreaVisible(Team team)
217+
{
218+
if (team.Index == (int)SiConstants.ETeam.Alien)
219+
{
220+
return Pref_Resources_Aliens_RevealClosestArea.Value;
221+
}
222+
else if (team.Index == (int)SiConstants.ETeam.Sol || team.Index == (int)SiConstants.ETeam.Centauri)
223+
{
224+
return Pref_Resources_Humans_RevealClosestArea.Value;
225+
}
226+
227+
return false;
228+
}
229+
230+
static ResourceArea? GetTeamClosestResourceArea(Team team, Resource type)
231+
{
232+
UnityEngine.Vector3 position = GetTeamStartingPosition(team);
233+
234+
GameListCache.QueryResourceAreas.Clear();
235+
foreach (ResourceArea resourceArea in ResourceArea.ResourceAreas)
236+
{
237+
if (resourceArea.ResourceType != type)
238+
{
239+
continue;
240+
}
241+
242+
if (resourceArea.ResourceAmountCurrent <= 0)
243+
{
244+
continue;
245+
}
246+
247+
GameListCache.QueryResourceAreas.Add(resourceArea);
248+
}
249+
250+
ResourceArea? closestArea = null;
251+
float closestDistance = float.MaxValue;
252+
foreach (ResourceArea resourceArea in GameListCache.QueryResourceAreas)
253+
{
254+
float sqrMagnitude = (resourceArea.SignalCenter - position).sqrMagnitude;
255+
if (sqrMagnitude < closestDistance)
256+
{
257+
closestArea = resourceArea;
258+
closestDistance = sqrMagnitude;
259+
}
260+
}
261+
262+
return closestArea;
263+
}
264+
265+
static UnityEngine.Vector3 GetTeamStartingPosition(Team team)
266+
{
267+
if (team.Structures.Count <= 0)
268+
{
269+
MelonLogger.Warning("Could not determine starting position for team: " + team.TeamShortName);
270+
return UnityEngine.Vector3.zero;
271+
}
272+
273+
return team.Structures[0].transform.position;
274+
}
275+
276+
static Resource? GetTeamResourceType(Team team)
277+
{
278+
switch (team.Index)
279+
{
280+
case (int)SiConstants.ETeam.Alien:
281+
// "Biotics"
282+
#if NET6_0
283+
return Resource.Resources[1];
284+
#else
285+
return Resource.Resources.Find(r => r.ResourceName.StartsWith("Bi"));
286+
#endif
287+
case (int)SiConstants.ETeam.Sol:
288+
case (int)SiConstants.ETeam.Centauri:
289+
// "Balterium"
290+
#if NET6_0
291+
return Resource.Resources[0];
292+
#else
293+
return Resource.Resources.Find(r => r.ResourceName.StartsWith("Ba"));
294+
#endif
295+
default:
296+
MelonLogger.Warning("Could not determine default resource type for team: " + team.TeamShortName);
297+
return null;
298+
}
299+
}
300+
301+
static int GetTeamStartingResources(Team team)
302+
{
303+
switch (team.Index)
304+
{
305+
case (int)SiConstants.ETeam.Alien:
306+
return Pref_Resources_Aliens_StartingAmount.Value;
307+
case (int)SiConstants.ETeam.Centauri:
308+
return Pref_Resources_Centauri_StartingAmount.Value;
309+
case (int)SiConstants.ETeam.Sol:
310+
return Pref_Resources_Sol_StartingAmount.Value;
311+
default:
312+
MelonLogger.Warning("Could not determine starting resources for team: " + team.TeamShortName);
313+
return 8000;
314+
}
315+
}
208316
}
209317
}

0 commit comments

Comments
 (0)