private bool GetNextCollision(IReadOnlyList <Manifold> collisions, int counter, out Manifold collision) { // The *4 is completely arbitrary if (counter > collisions.Count * 4) { collision = default; return(false); } var indexes = new List <int>(); for (int i = 0; i < collisions.Count; i++) { indexes.Add(i); } _random.Shuffle(indexes); foreach (var index in indexes) { if (collisions[index].Unresolved) { collision = collisions[index]; return(true); } } collision = default; return(false); }
public void SelectRandomMap() { var maps = CurrentlyEligibleMaps().ToList(); _random.Shuffle(maps); _currentMap = maps[0]; _currentMapForced = false; }
/// <summary> /// Finds 2-5 random, alive entities that can host diseases /// and gives them a randomly selected disease. /// They all get the same disease. /// </summary> public override void Startup() { base.Startup(); HashSet <EntityUid> stationsToNotify = new(); List <DiseaseCarrierComponent> aliveList = new(); foreach (var(carrier, mobState) in _entityManager.EntityQuery <DiseaseCarrierComponent, MobStateComponent>()) { if (!mobState.IsDead()) { aliveList.Add(carrier); } } _random.Shuffle(aliveList); /// We're going to filter the above out to only alive mobs. Might change after future mobstate rework var toInfect = _random.Next(2, 5); var diseaseName = _random.Pick(NotTooSeriousDiseases); if (!_prototypeManager.TryIndex(diseaseName, out DiseasePrototype? disease)) { return; } var diseaseSystem = EntitySystem.Get <DiseaseSystem>(); var entSysMgr = IoCManager.Resolve <IEntitySystemManager>(); var stationSystem = entSysMgr.GetEntitySystem <StationSystem>(); var chatSystem = entSysMgr.GetEntitySystem <ChatSystem>(); // Now we give it to people in the list of living disease carriers earlier foreach (var target in aliveList) { if (toInfect-- == 0) { break; } diseaseSystem.TryAddDisease(target.Owner, disease, target); var station = stationSystem.GetOwningStation(target.Owner); if (station == null) { continue; } stationsToNotify.Add((EntityUid)station); } if (!AnnounceEvent) { return; } foreach (var station in stationsToNotify) { chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"), playDefaultSound: false, colorOverride: Color.YellowGreen); } }
private void OnSpawnPlayer(PlayerSpawningEvent args) { // TODO: Cache all this if it ends up important. var points = EntityQuery <SpawnPointComponent>().ToList(); _random.Shuffle(points); foreach (var spawnPoint in points) { var xform = Transform(spawnPoint.Owner); if (args.Station != null && _stationSystem.GetOwningStation(spawnPoint.Owner, xform) != args.Station) { continue; } if (_gameTicker.RunLevel == GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.LateJoin) { args.SpawnResult = _stationSpawning.SpawnPlayerMob( xform.Coordinates, args.Job, args.HumanoidCharacterProfile, args.Station); return; } else if (_gameTicker.RunLevel != GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.Job && (args.Job == null || spawnPoint.Job?.ID == args.Job.Prototype.ID)) { args.SpawnResult = _stationSpawning.SpawnPlayerMob( xform.Coordinates, args.Job, args.HumanoidCharacterProfile, args.Station); return; } } // Ok we've still not returned, but we need to put them /somewhere/. // TODO: Refactor gameticker spawning code so we don't have to do this! foreach (var spawnPoint in points) { var xform = Transform(spawnPoint.Owner); args.SpawnResult = _stationSpawning.SpawnPlayerMob( xform.Coordinates, args.Job, args.HumanoidCharacterProfile, args.Station); return; } Logger.ErrorS("spawning", "No spawn points were available!"); }
/// <summary> /// Finds 1-3 random, dead entities accross the station /// and turns them into zombies. /// </summary> public override void Startup() { base.Startup(); HashSet <EntityUid> stationsToNotify = new(); List <MobStateComponent> deadList = new(); foreach (var mobState in _entityManager.EntityQuery <MobStateComponent>()) { if (mobState.IsDead() || mobState.IsCritical()) { deadList.Add(mobState); } } _random.Shuffle(deadList); var toInfect = _random.Next(1, 3); var zombifysys = _entityManager.EntitySysManager.GetEntitySystem <ZombifyOnDeathSystem>(); // Now we give it to people in the list of dead entities earlier. var entSysMgr = IoCManager.Resolve <IEntitySystemManager>(); var stationSystem = entSysMgr.GetEntitySystem <StationSystem>(); var chatSystem = entSysMgr.GetEntitySystem <ChatSystem>(); foreach (var target in deadList) { if (toInfect-- == 0) { break; } zombifysys.ZombifyEntity(target.Owner); var station = stationSystem.GetOwningStation(target.Owner); if (station == null) { continue; } stationsToNotify.Add((EntityUid)station); } if (!AnnounceEvent) { return; } foreach (var station in stationsToNotify) { chatSystem.DispatchStationAnnouncement((EntityUid)station, Loc.GetString("station-event-zombie-outbreak-announcement"), playDefaultSound: false, colorOverride: Color.DarkMagenta); } }
public ObjectivePrototype?GetRandomObjective(Mind mind) { var objectives = GetAllPossibleObjectives(mind).ToList(); _random.Shuffle(objectives); //to prevent endless loops foreach (var objective in objectives) { if (!_random.Prob(objective.Probability)) { continue; } return(objective); } return(null); }
public override void Startup() { base.Startup(); var targetList = _entityManager.EntityQuery <SentienceTargetComponent>().ToList(); _random.Shuffle(targetList); var toMakeSentient = _random.Next(2, 5); var groups = new HashSet <string>(); foreach (var target in targetList) { if (toMakeSentient-- == 0) { break; } MakeSentientCommand.MakeSentient(target.Owner, _entityManager); _entityManager.RemoveComponent <SentienceTargetComponent>(target.Owner); var comp = _entityManager.AddComponent <GhostTakeoverAvailableComponent>(target.Owner); comp.RoleName = _entityManager.GetComponent <MetaDataComponent>(target.Owner).EntityName; comp.RoleDescription = Loc.GetString("station-event-random-sentience-role-description", ("name", comp.RoleName)); groups.Add(target.FlavorKind); } if (groups.Count == 0) { return; } var groupList = groups.ToList(); var kind1 = groupList.Count > 0 ? groupList[0] : "???"; var kind2 = groupList.Count > 1 ? groupList[1] : "???"; var kind3 = groupList.Count > 2 ? groupList[2] : "???"; _chatManager.DispatchStationAnnouncement( Loc.GetString("station-event-random-sentience-announcement", ("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count), ("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")), ("strength", Loc.GetString($"random-sentience-event-strength-{_random.Next(1, 8)}"))) ); }
public override void Startup() { base.Startup(); var apcSys = EntitySystem.Get <ApcSystem>(); var allApcs = _entityManager.EntityQuery <ApcComponent>().ToList(); var toDisable = Math.Min(_random.Next(3, 7), allApcs.Count); if (toDisable == 0) { return; } _random.Shuffle(allApcs); for (var i = 0; i < toDisable; i++) { apcSys.ApcToggleBreaker(allApcs[i].Owner, allApcs[i]); } }
public override void Startup() { base.Startup(); var spawnLocations = _entityManager.EntityQuery <VentCritterSpawnLocationComponent, TransformComponent>().ToList(); _random.Shuffle(spawnLocations); var spawnAmount = _random.Next(7, 15); // A small colony of critters. for (int i = 0; i < spawnAmount && i < spawnLocations.Count - 1; i++) { var spawnChoice = _random.Pick(SpawnedPrototypeChoices); if (_random.Prob(0.01f) || i == 0) //small chance for multiple, but always at least 1 { spawnChoice = "MobRatKing"; } _entityManager.SpawnEntity(spawnChoice, spawnLocations[i].Item2.Coordinates); } }
public override void Startup() { base.Startup(); var spawnChoice = _random.Pick(SpawnedPrototypeChoices); var spawnLocations = _entityManager.EntityQuery <VentCritterSpawnLocationComponent>().ToList(); _random.Shuffle(spawnLocations); var spawnAmount = _random.Next(4, 12); // A small colony of critters. foreach (var location in spawnLocations) { if (spawnAmount-- == 0) { break; } var coords = _entityManager.GetComponent <TransformComponent>(location.Owner); _entityManager.SpawnEntity(spawnChoice, coords.Coordinates); } }
public ObjectivePrototype[] GetRandomObjectives(Mind mind, float maxDifficulty = 3) { var objectives = GetAllPossibleObjectives(mind); //to prevent endless loops if (objectives.Length == 0 || objectives.Sum(o => o.Difficulty) == 0f) { return(objectives); } var result = new List <ObjectivePrototype>(); var currentDifficulty = 0f; _random.Shuffle(objectives); while (currentDifficulty < maxDifficulty) { foreach (var objective in objectives) { if (!_random.Prob(objective.Probability)) { continue; } result.Add(objective); currentDifficulty += objective.Difficulty; if (currentDifficulty >= maxDifficulty) { break; } } } if (currentDifficulty > maxDifficulty) //will almost always happen { result.Pop(); } return(result.ToArray()); }
/// <summary> /// Finds 2-5 random, alive entities that can host diseases /// and gives them a randomly selected disease. /// They all get the same disease. /// </summary> public override void Startup() { base.Startup(); List <DiseaseCarrierComponent> aliveList = new(); foreach (var(carrier, mobState) in _entityManager.EntityQuery <DiseaseCarrierComponent, MobStateComponent>()) { if (!mobState.IsDead()) { aliveList.Add(carrier); } } _random.Shuffle(aliveList); /// We're going to filter the above out to only alive mobs. Might change after future mobstate rework var toInfect = _random.Next(2, 5); var diseaseName = _random.Pick(NotTooSeriousDiseases); if (!_prototypeManager.TryIndex(diseaseName, out DiseasePrototype? disease)) { return; } var diseaseSystem = EntitySystem.Get <DiseaseSystem>(); /// Now we give it to people in the list of living disease carriers earlier foreach (var target in aliveList) { if (toInfect-- == 0) { break; } diseaseSystem.TryAddDisease(target.Owner, disease, target); } _chatManager.DispatchStationAnnouncement(Loc.GetString("station-event-disease-outbreak-announcement")); }
public void Initialize() { _configurationManager.OnValueChanged(CCVars.GameMap, value => { if (TryLookupMap(value, out var map)) { _currentMap = map; } else { throw new ArgumentException($"Unknown map prototype {value} was selected!"); } }, true); _configurationManager.OnValueChanged(CCVars.GameMapForced, value => _currentMapForced = value, true); _configurationManager.OnValueChanged(CCVars.GameMapRotation, value => _mapRotationEnabled = value, true); _configurationManager.OnValueChanged(CCVars.GameMapMemoryDepth, value => { _mapQueueDepth = value; // Drain excess. while (_previousMaps.Count > _mapQueueDepth) { _previousMaps.Dequeue(); } }, true); var maps = AllVotableMaps().ToArray(); _random.Shuffle(maps); foreach (var map in maps) { if (_previousMaps.Count >= _mapQueueDepth) { break; } _previousMaps.Enqueue(map.ID); } }
public override void Startup() { base.Startup(); HashSet <EntityUid> stationsToNotify = new(); var targetList = _entityManager.EntityQuery <SentienceTargetComponent>().ToList(); _random.Shuffle(targetList); var toMakeSentient = _random.Next(2, 5); var groups = new HashSet <string>(); foreach (var target in targetList) { if (toMakeSentient-- == 0) { break; } MakeSentientCommand.MakeSentient(target.Owner, _entityManager); _entityManager.RemoveComponent <SentienceTargetComponent>(target.Owner); var comp = _entityManager.AddComponent <GhostTakeoverAvailableComponent>(target.Owner); comp.RoleName = _entityManager.GetComponent <MetaDataComponent>(target.Owner).EntityName; comp.RoleDescription = Loc.GetString("station-event-random-sentience-role-description", ("name", comp.RoleName)); groups.Add(target.FlavorKind); } if (groups.Count == 0) { return; } var groupList = groups.ToList(); var kind1 = groupList.Count > 0 ? groupList[0] : "???"; var kind2 = groupList.Count > 1 ? groupList[1] : "???"; var kind3 = groupList.Count > 2 ? groupList[2] : "???"; var entSysMgr = IoCManager.Resolve <IEntitySystemManager>(); var stationSystem = entSysMgr.GetEntitySystem <StationSystem>(); var chatSystem = entSysMgr.GetEntitySystem <ChatSystem>(); foreach (var target in targetList) { var station = stationSystem.GetOwningStation(target.Owner); if (station == null) { continue; } stationsToNotify.Add((EntityUid)station); } foreach (var station in stationsToNotify) { chatSystem.DispatchStationAnnouncement( (EntityUid)station, Loc.GetString("station-event-random-sentience-announcement", ("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count), ("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")), ("strength", Loc.GetString($"random-sentience-event-strength-{_random.Next(1, 8)}"))), playDefaultSound: false, colorOverride: Color.Gold ); } }
private void TryMetabolize(EntityUid uid, MetabolizerComponent?meta = null, MechanismComponent?mech = null) { if (!Resolve(uid, ref meta)) { return; } Resolve(uid, ref mech, false); // First step is get the solution we actually care about Solution? solution = null; EntityUid?solutionEntityUid = null; EntityUid?bodyEntityUid = mech?.Body?.Owner; SolutionContainerManagerComponent?manager = null; if (meta.SolutionOnBody) { if (mech != null) { var body = mech.Body; if (body != null) { if (!Resolve((body).Owner, ref manager, false)) { return; } _solutionContainerSystem.TryGetSolution((body).Owner, meta.SolutionName, out solution, manager); solutionEntityUid = body.Owner; } } } else { if (!Resolve(uid, ref manager, false)) { return; } _solutionContainerSystem.TryGetSolution(uid, meta.SolutionName, out solution, manager); solutionEntityUid = uid; } if (solutionEntityUid == null || solution == null) { return; } // randomize the reagent list so we don't have any weird quirks // like alphabetical order or insertion order mattering for processing var list = solution.Contents.ToArray(); _random.Shuffle(list); int reagents = 0; foreach (var reagent in list) { if (!_prototypeManager.TryIndex <ReagentPrototype>(reagent.ReagentId, out var proto)) { continue; } FixedPoint2 mostToRemove = FixedPoint2.Zero; if (proto.Metabolisms == null) { if (meta.RemoveEmpty) { _solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId, FixedPoint2.New(1)); } continue; } // we're done here entirely if this is true if (reagents >= meta.MaxReagentsProcessable) { return; } reagents += 1; // loop over all our groups and see which ones apply if (meta.MetabolismGroups == null) { continue; } foreach (var group in meta.MetabolismGroups) { if (!proto.Metabolisms.Keys.Contains(group.Id)) { continue; } var entry = proto.Metabolisms[group.Id]; // we don't remove reagent for every group, just whichever had the biggest rate if (entry.MetabolismRate > mostToRemove) { mostToRemove = entry.MetabolismRate; } mostToRemove *= group.MetabolismRateModifier; mostToRemove = FixedPoint2.Clamp(mostToRemove, 0, reagent.Quantity); // if it's possible for them to be dead, and they are, // then we shouldn't process any effects, but should probably // still remove reagents if (EntityManager.TryGetComponent <MobStateComponent>(solutionEntityUid.Value, out var state)) { if (state.IsDead()) { continue; } } var actualEntity = bodyEntityUid != null ? bodyEntityUid.Value : solutionEntityUid.Value; var args = new ReagentEffectArgs(actualEntity, (meta).Owner, solution, proto, mostToRemove, EntityManager, null); // do all effects, if conditions apply foreach (var effect in entry.Effects) { if (!effect.ShouldApply(args, _random)) { continue; } if (effect.ShouldLog) { _adminLogger.Add(LogType.ReagentEffect, effect.LogImpact, $"Metabolism effect {effect.GetType().Name:effect} of reagent {args.Reagent.LocalizedName:reagent} applied on entity {actualEntity:entity} at {Transform(actualEntity).Coordinates:coordinates}"); } effect.Effect(args); } } // remove a certain amount of reagent if (mostToRemove > FixedPoint2.Zero) { _solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId, mostToRemove); } } }