diff --git a/sources/AcediaLauncherMut.uc b/sources/AcediaLauncherMut.uc index 70519ab..82ee6ca 100644 --- a/sources/AcediaLauncherMut.uc +++ b/sources/AcediaLauncherMut.uc @@ -34,6 +34,7 @@ simulated function PreBeginPlay() { local StartUp startUpActor; + _ = class'Global'.static.GetInstance(); if (level.netMode == NM_DedicatedServer) { foreach AllActors(class'StartUp', startUpActor) @@ -47,9 +48,7 @@ simulated function PreBeginPlay() } SetupMutatorSignals(); } - else - { - _ = class'Global'.static.GetInstance(); + else { class'ClientLevelCore'.static.CreateLevelCore(self); } } diff --git a/sources/GameModes/BaseGameMode.uc b/sources/GameModes/BaseGameMode.uc index f3accb2..3b7a017 100644 --- a/sources/GameModes/BaseGameMode.uc +++ b/sources/GameModes/BaseGameMode.uc @@ -322,69 +322,84 @@ private function ValidateFeatureArray( public function UpdateFeatureArray( out array featuresToEnable) { - local int i; - local Text newConfigName; - local string nextFeatureClassName; - - for (i = 0; i < featuresToEnable.length; i += 1) + local int i; + local HashTable includedFeaturesMap; + local Text nextKey, nextConfig; + local string nextFeatureClassName; + local CollectionIterator iter; + local Packages.FeatureConfigPair newPair; + + // Exclude features we're told to exclude + while (i < featuresToEnable.length) { nextFeatureClassName = string(featuresToEnable[i].featureClass); - // `excludeFeature` - if (FeatureExcluded(nextFeatureClassName)) + if (IsFeatureExcluded(nextFeatureClassName)) { _.memory.Free(featuresToEnable[i].configName); - featuresToEnable[i].configName = none; - continue; + featuresToEnable.Remove(i, 1); } - // `includeFeatureAs` - newConfigName = TryReplacingFeatureConfig(nextFeatureClassName); - if (newConfigName != none) - { - _.memory.Free(featuresToEnable[i].configName); - featuresToEnable[i].configName = newConfigName; + else { + i += 1; } - // `includeFeature` - if ( featuresToEnable[i].configName == none - && FeatureInIncludedArray(nextFeatureClassName)) + } + // Rewrite auto-enabled configs if different config was specified + includedFeaturesMap = BuildIncludedFeaturesMap(); + for (i = 0; i < featuresToEnable.length; i += 1) + { + nextKey = + _.text.FromString(Locs(string(featuresToEnable[i].featureClass))); + nextConfig = Text(includedFeaturesMap.TakeItem(nextKey)); + if (nextConfig != none) { - featuresToEnable[i].configName = P("default").Copy(); + _.memory.Free(featuresToEnable[i].configName); + featuresToEnable[i].configName = nextConfig; } + nextKey.FreeSelf(); } -} - -private function bool FeatureExcluded(string featureClassName) -{ - local int i; - - for (i = 0; i < excludeFeature.length; i += 1) + // Add features that are included, but weren't auto-enabled in + // the first place + for (iter = includedFeaturesMap.Iterate(); !iter.HasFinished(); iter.Next()) { - if (excludeFeature[i] ~= featureClassName) { - return true; - } + nextKey = Text(iter.GetKey()); + newPair.featureClass = class(_.memory.LoadClass(nextKey)); + newPair.configName = Text(iter.Get()); + nextKey.FreeSelf(); + featuresToEnable[featuresToEnable.length] = newPair; } - return false; + includedFeaturesMap.FreeSelf(); } -private function Text TryReplacingFeatureConfig(string featureClassName) +private function HashTable BuildIncludedFeaturesMap() { - local int i; + local int i; + local Text nextKey; + local HashTable result; + result = _.collections.EmptyHashTable(); + // First fill `HashTable` with non-specified conmfigs from `includeFeature` + for (i = 0; i < includeFeature.length; i += 1) + { + nextKey = _.text.FromString(Locs(includeFeature[i])); + result.SetItem(nextKey, none); + nextKey.FreeSelf(); + } + // Then add/rewrite configs from `includeFeatureAs` for (i = 0; i < includeFeatureAs.length; i += 1) { - if (includeFeatureAs[i].feature ~= featureClassName) { - return _.text.FromString(includeFeatureAs[i].config); - } + nextKey = _.text.FromString(Locs(includeFeatureAs[i].feature)); + result.SetString(nextKey, Locs(includeFeatureAs[i].config)); + nextKey.FreeSelf(); } - return none; + return result; } -private function bool FeatureInIncludedArray(string featureClassName) +private function bool IsFeatureExcluded(string featureClassName) { local int i; - for (i = 0; i < includeFeature.length; i += 1) + for (i = 0; i < excludeFeature.length; i += 1) { - if (includeFeature[i] ~= featureClassName) { + if (excludeFeature[i] ~= featureClassName) { return true; } } diff --git a/sources/StartUp.uc b/sources/StartUp.uc index 5fdd78d..b0cc070 100644 --- a/sources/StartUp.uc +++ b/sources/StartUp.uc @@ -79,6 +79,7 @@ private function InitializeServer() availableFeatures = GetAutoConfigurationInfo(); if (class'Packages'.default.useGameModes) { + class'GameMode'.static.Initialize(); votingAdapter = VotingHandlerAdapter( _.memory.Allocate(class'VotingHandlerAdapter')); currentGameMode = votingAdapter.SetupGameModeAfterTravel(); @@ -127,6 +128,7 @@ private function CheckForGarbage() public function array GetAutoConfigurationInfo() { local int i; + local Text autoConfig; local array< class > availableFeatures; local Packages.FeatureConfigPair nextPair; local array result; @@ -134,27 +136,43 @@ public function array GetAutoConfigurationInfo() availableFeatures = _.environment.GetAvailableFeatures(); for (i = 0; i < availableFeatures.length; i += 1) { - nextPair.featureClass = availableFeatures[i]; - nextPair.configName = availableFeatures[i].static - .GetAutoEnabledConfig(); - result[result.length] = nextPair; + autoConfig = availableFeatures[i].static.GetAutoEnabledConfig(); + if (autoConfig != none) + { + nextPair.featureClass = availableFeatures[i]; + nextPair.configName = autoConfig; + result[result.length] = nextPair; + } } return result; } private function EnableFeatures(array features) { - local int i; + local int i; + local Text defaultConfigName; + local Text nextConfigName; + defaultConfigName = _.text.FromString("default"); for (i = 0; i < features.length; i += 1) { - if (features[i].featureClass == none) continue; - if (features[i].configName == none) continue; - features[i].featureClass.static.EnableMe(features[i].configName); + if (features[i].featureClass == none) { + continue; + } + // `configName` being `none` here means that config name was not + // specified through config and we should fallback to "default" + if (features[i].configName == none) { + nextConfigName = defaultConfigName.Copy(); + } + else { + nextConfigName = features[i].configName.Copy(); + } + features[i].featureClass.static.EnableMe(nextConfigName); _.logger.Auto(infoFeatureEnabled) .Arg(_.text.FromString(string(features[i].featureClass))) - .Arg(features[i].configName); // consumes `configName` + .Arg(nextConfigName); // consumes `nextConfigName` } + defaultConfigName.FreeSelf(); } private final function RunStartUpTests() diff --git a/sources/VotingHandlerAdapter.uc b/sources/VotingHandlerAdapter.uc index f734c32..d0538d1 100644 --- a/sources/VotingHandlerAdapter.uc +++ b/sources/VotingHandlerAdapter.uc @@ -120,7 +120,6 @@ public final function InjectIntoVotingHandler() return; } votingHandlerReference = _server.unreal.ActorRef(votingHandler); - class'GameMode'.static.Initialize(); availableGameModes = class'GameMode'.static.AvailableConfigs(); for (i = 0; i < availableGameModes.length; i += 1) {