public void CreateAttachedBlip(TurfZone targetZone) { if (targetZone.AttachedBlip == null) { targetZone.AttachedBlip = World.CreateBlip(targetZone.zoneBlipPosition); } }
public static int CompareZonesByDistToPlayer(TurfZone x, TurfZone y) { if (x == null) { if (y == null) { return(0); } else { return(-1); } } else { if (y == null) { return(1); } else { Vector3 playerPos = MindControl.CurrentPlayerCharacter.Position; return(World.GetDistance(x.zoneBlipPosition, playerPos). CompareTo(World.GetDistance(y.zoneBlipPosition, playerPos))); } } }
public static int CompareZonesByValue(TurfZone x, TurfZone y) { if (x == null) { if (y == null) { return(0); } else { return(-1); } } else { if (y == null) { return(1); } else { return(y.value.CompareTo(x.value)); } } }
/// <summary> /// if this gang seems to be new, makes it take up to 3 neutral zones /// </summary> void DoInitialTakeover() { if (watchedGang.gangWeaponHashes.Count > 0 || ZoneManager.instance.GetZonesControlledByGang(watchedGang.name).Count > 2) { //we've been around for long enough to get weapons or get turf, abort return; } TurfZone chosenZone = ZoneManager.instance.GetRandomZone(true); if (chosenZone.ownerGangName == "none") { watchedGang.TakeZone(chosenZone, false); //we took one, now we should spread the influence around it for (int i = 0; i < 3; i++) { TurfZone nearbyZone = ZoneManager.instance.GetClosestZoneToTargetZone(chosenZone, true); if (nearbyZone.ownerGangName == "none") { watchedGang.TakeZone(nearbyZone, false); //and use this new zone as reference from now on chosenZone = nearbyZone; } } } else { //no neutral turf available, abort! return; } }
void TryExpand() { //lets attack! //pick a random zone owned by us, get the closest hostile zone and attempt to take it //..but only if the player hasn't disabled expansion if (ModOptions.instance.preventAIExpansion) { return; } if (myZones.Count > 0) { TurfZone chosenZone = RandoMath.GetRandomElementFromList(myZones); TurfZone closestZoneToChosen = ZoneManager.instance.GetClosestZoneToTargetZone(chosenZone, true); TryTakeTurf(closestZoneToChosen); } else { //we're out of turf! //get a random zone (preferably neutral, since it's cheaper for the AI) and try to take it //but only sometimes, since we're probably on a tight spot TurfZone chosenZone = ZoneManager.instance.GetRandomZone(true); TryTakeTurf(chosenZone); } }
public TurfZone GetRandomZone(bool preferablyNeutralZone = false) { if (zoneData.zoneList.Count > 0) { List <TurfZone> possibleTurfChoices = new List <TurfZone>(); possibleTurfChoices.AddRange(zoneData.zoneList); for (int i = 0; i < zoneData.zoneList.Count; i++) { if (possibleTurfChoices.Count == 0) { //we've run out of options! abort break; } TurfZone chosenZone = RandoMath.GetRandomElementFromList(possibleTurfChoices); if (!preferablyNeutralZone || chosenZone.ownerGangName == "none") { return(chosenZone); } else { possibleTurfChoices.Remove(chosenZone); } } //if we couldn't find a neutral zone, just get any zone return(zoneData.zoneList[RandoMath.CachedRandom.Next(0, zoneData.zoneList.Count)]); } else { return(null); } }
public TurfZone GetClosestZoneToTargetZone(TurfZone targetZone, bool hostileOrNeutralZonesOnly = false, bool randomBetween3Closest = true) { float smallestDistance = 0; //we start our top 3 closest zones list with only the zone we want to get the closest from and start replacing as we find better ones //the result may not be the 3 closest zones, but thats okay List <TurfZone> top3ClosestZones = new List <TurfZone> { targetZone, targetZone, targetZone }; int timesFoundBetterZone = 0; for (int i = 0; i < zoneData.zoneList.Count; i++) { float distanceToThisZone = World.GetDistance(targetZone.zoneBlipPosition, zoneData.zoneList[i].zoneBlipPosition); if (distanceToThisZone != 0 && (!hostileOrNeutralZonesOnly || targetZone.ownerGangName != zoneData.zoneList[i].ownerGangName)) { if (smallestDistance == 0 || smallestDistance > distanceToThisZone) { timesFoundBetterZone++; top3ClosestZones.Insert(0, zoneData.zoneList[i]); top3ClosestZones.RemoveAt(3); smallestDistance = distanceToThisZone; } } } if (randomBetween3Closest && timesFoundBetterZone >= 3) //only get a random from top 3 if we found 3 different zones { return(RandoMath.GetRandomElementFromList(top3ClosestZones)); } else { return(top3ClosestZones[0]); } }
public static int CalculateRewardForZone(TurfZone zone, int ownerGangTurfsCount) { float singleZoneReward = (((float)zone.value / RandoMath.Max(ModOptions.instance.maxTurfValue, 1)) * (ModOptions.instance.maxRewardPerZoneOwned - ModOptions.instance.baseRewardPerZoneOwned)) + ModOptions.instance.baseRewardPerZoneOwned; return((int)((1 + ModOptions.instance.rewardMultiplierPerZone * ownerGangTurfsCount) * singleZoneReward)); }
public void AddNewCircleBlip(Vector3 position, TurfZone targetZone) { if (targetZone != null) { Blip newCircleBlip = World.CreateBlip(position, 100); newCircleBlip.Alpha = 50; targetZone.myCircleBlips.Add(newCircleBlip); if (targetZone.zoneCircles == null) { targetZone.zoneCircles = new List <AreaBlip>(); } targetZone.zoneCircles.Add(new AreaBlip(position, 100)); } }
public void UpdateZoneData(TurfZone newTurfZone) { if (!zoneData.zoneList.Contains(newTurfZone)) { zoneData.zoneList.Add(newTurfZone); } CreateAttachedBlip(newTurfZone); newTurfZone.AttachedBlip.Position = newTurfZone.zoneBlipPosition; RefreshZoneBlips(); SaveZoneData(false); }
public void TakeZone(TurfZone takenZone, bool doNotify = true) { if (doNotify && ModOptions.instance.notificationsEnabled) { string notificationMsg = string.Concat("The ", name, " have taken ", takenZone.zoneName); if (takenZone.ownerGangName != "none") { notificationMsg = string.Concat(notificationMsg, " from the ", takenZone.ownerGangName); } notificationMsg = string.Concat(notificationMsg, "!"); UI.Notify(notificationMsg); } takenZone.value = baseTurfValue; takenZone.ownerGangName = name; ZoneManager.instance.UpdateZoneData(takenZone); }
void TryTakeTurf(TurfZone targetZone) { if (targetZone == null || targetZone.ownerGangName == watchedGang.name) { return; //whoops, there just isn't any zone available for our gang } if (targetZone.ownerGangName == "none") { //this zone is neutral, lets just take it if (watchedGang.moneyAvailable >= ModOptions.instance.baseCostToTakeTurf) { watchedGang.moneyAvailable -= ModOptions.instance.baseCostToTakeTurf; watchedGang.TakeZone(targetZone); } } else { TryStartFightForZone(targetZone); } }
public void UpdateZoneBlip(TurfZone targetZone) { if (targetZone.AttachedBlip != null) { Gang ownerGang = GangManager.instance.GetGangByName(targetZone.ownerGangName); if (ownerGang == null) { targetZone.AttachedBlip.Sprite = BlipSprite.GTAOPlayerSafehouseDead; targetZone.AttachedBlip.Color = BlipColor.White; } else { targetZone.AttachedBlip.Sprite = BlipSprite.GTAOPlayerSafehouse; Function.Call(Hash.SET_BLIP_COLOUR, targetZone.AttachedBlip, ownerGang.blipColor); if (ownerGang.isPlayerOwned) { Function.Call(Hash.SET_BLIP_SECONDARY_COLOUR, targetZone.AttachedBlip, 0f, 255, 0f); } else { Function.Call(Hash.SET_BLIP_SECONDARY_COLOUR, targetZone.AttachedBlip, 255, 0f, 0f); } targetZone.AttachedBlip.Scale = 1.0f + 0.65f / ((ModOptions.instance.maxTurfValue + 1) / (targetZone.value + 1)); } Function.Call(Hash.BEGIN_TEXT_COMMAND_SET_BLIP_NAME, "STRING"); if (ownerGang != null) { Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, string.Concat(targetZone.zoneName, " (", targetZone.ownerGangName, " turf, level ", targetZone.value.ToString(), ")")); } else { Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, string.Concat(targetZone.zoneName, " (neutral territory)")); } Function.Call(Hash.END_TEXT_COMMAND_SET_BLIP_NAME, targetZone.AttachedBlip); } }
public void OutputCurrentZoneInfo() { string zoneName = World.GetZoneName(MindControl.CurrentPlayerCharacter.Position); string zoneInfoMsg = "Current zone is " + zoneName + "."; TurfZone currentZone = GetZoneByName(zoneName); if (currentZone != null) { if (currentZone.ownerGangName != "none") { if (GangManager.instance.GetGangByName(currentZone.ownerGangName) == null) { GiveGangZonesToAnother(currentZone.ownerGangName, "none"); currentZone.ownerGangName = "none"; SaveZoneData(false); zoneInfoMsg += " It isn't owned by any gang."; } else { zoneInfoMsg += " It is owned by the " + currentZone.ownerGangName + "."; zoneInfoMsg += " Its current level is " + currentZone.value.ToString(); } } else { zoneInfoMsg += " It isn't owned by any gang."; } } else { zoneInfoMsg += " It hasn't been marked as takeable yet."; } UI.ShowSubtitle(zoneInfoMsg); }
public bool StartWar(Gang enemyGang, TurfZone warZone, WarType theWarType, AttackStrength attackStrength) { if (!isOccurring || enemyGang == GangManager.instance.PlayerGang) { this.enemyGang = enemyGang; this.warZone = warZone; this.curWarType = theWarType; curWarAtkStrength = attackStrength; playerNearWarzone = false; spawnPointsSet = false; warBlip = World.CreateBlip(warZone.zoneBlipPosition); warBlip.IsFlashing = true; warBlip.Sprite = BlipSprite.Deathmatch; warBlip.Color = BlipColor.Red; warAreaBlip = World.CreateBlip(warZone.zoneBlipPosition, ModOptions.instance.maxDistToWarBlipBeforePlayerLeavesWar); warAreaBlip.Sprite = BlipSprite.BigCircle; warAreaBlip.Color = BlipColor.Red; warAreaBlip.Alpha = 175; Function.Call(Hash.BEGIN_TEXT_COMMAND_SET_BLIP_NAME, "STRING"); Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, "Gang War (versus " + enemyGang.name + ")"); Function.Call(Hash.END_TEXT_COMMAND_SET_BLIP_NAME, warBlip); curTicksAwayFromBattle = 0; enemiesInsideCars = SpawnManager.instance.GetSpawnedMembersOfGang(enemyGang, true); if (theWarType == WarType.attackingEnemy) { alliedReinforcements = GangCalculations.CalculateAttackerReinforcements(GangManager.instance.PlayerGang, attackStrength); enemyReinforcements = GangCalculations.CalculateDefenderReinforcements(enemyGang, warZone); } else { alliedReinforcements = GangCalculations.CalculateDefenderReinforcements(GangManager.instance.PlayerGang, warZone); enemyReinforcements = GangCalculations.CalculateAttackerReinforcements(enemyGang, attackStrength); } float screenRatio = (float)Game.ScreenResolution.Width / Game.ScreenResolution.Height; int proportionalScreenWidth = (int)(1080 * screenRatio); //nativeUI UIResText works with 1080p height alliedNumText.Position = new Point((proportionalScreenWidth / 2) - 120, 10); enemyNumText.Position = new Point((proportionalScreenWidth / 2) + 120, 10); alliedNumText.Caption = alliedReinforcements.ToString(); enemyNumText.Caption = enemyReinforcements.ToString(); initialEnemyReinforcements = enemyReinforcements; reinforcementsAdvantage = alliedReinforcements / (float)enemyReinforcements; spawnedAllies = SpawnManager.instance.GetSpawnedMembersOfGang(GangManager.instance.PlayerGang).Count; spawnedEnemies = SpawnManager.instance.GetSpawnedMembersOfGang(enemyGang).Count; maxSpawnedAllies = (int)(RandoMath.Max((ModOptions.instance.spawnedMemberLimit / 2) * reinforcementsAdvantage, 5)); maxSpawnedEnemies = RandoMath.Max(ModOptions.instance.spawnedMemberLimit - maxSpawnedAllies, 5); isOccurring = true; //BANG-like sound Function.Call(Hash.PLAY_SOUND_FRONTEND, -1, "PROPERTY_PURCHASE", "HUD_AWARDS"); if (theWarType == WarType.attackingEnemy) { UI.ShowSubtitle("The " + enemyGang.name + " are coming!"); //if we are attacking, set spawns around the player! SetSpawnPoints(MindControl.CurrentPlayerCharacter.Position); } else { UI.Notify(string.Concat("The ", enemyGang.name, " are attacking ", warZone.zoneName, "! They are ", GangCalculations.CalculateAttackerReinforcements(enemyGang, attackStrength).ToString(), " against our ", GangCalculations.CalculateDefenderReinforcements(GangManager.instance.PlayerGang, warZone).ToString())); //spawns are set around the zone blip if we are defending if (World.GetDistance(MindControl.CurrentPlayerCharacter.Position, warZone.zoneBlipPosition) < 100) { SetSpawnPoints(warZone.zoneBlipPosition); } } SetHateRelationsBetweenGangs(); return(true); } else { return(false); } }
void OnTick(object sender, EventArgs e) { Wait(3000 + RandoMath.CachedRandom.Next(1000)); Logger.Log("ambient spawner tick: begin", 5); TurfZone curTurfZone = ZoneManager.instance.GetCurrentTurfZone(); if (curTurfZone != null) { // also reduce police influence if (enabled) { Game.WantedMultiplier = (1.0f / (curTurfZone.value + 1)) + ModOptions.instance.minWantedFactorWhenInGangTurf; Game.MaxWantedLevel = RandoMath.Max(CalculateMaxWantedLevelInTurf(curTurfZone.value), ModOptions.instance.maxWantedLevelInMaxedGangTurf); } if (Game.Player.WantedLevel > Game.MaxWantedLevel) { Game.Player.WantedLevel--; } if (postWarBackupsRemaining > 0 && GangWarManager.instance.playerNearWarzone) { Vector3 playerPos = MindControl.CurrentPlayerCharacter.Position, safePlayerPos = MindControl.SafePositionNearPlayer; if (SpawnManager.instance.SpawnParachutingMember(GangManager.instance.PlayerGang, playerPos + Vector3.WorldUp * 50, safePlayerPos) == null) { SpawnManager.instance.SpawnGangVehicle(GangManager.instance.PlayerGang, SpawnManager.instance.FindGoodSpawnPointForCar(safePlayerPos), safePlayerPos); } postWarBackupsRemaining--; } //if spawning is enabled, lets try to spawn the current zone's corresponding gang members! if (ModOptions.instance.ambientSpawningEnabled && enabled) { Gang curGang = GangManager.instance.GetGangByName(curTurfZone.ownerGangName); if (GangWarManager.instance.isOccurring && GangWarManager.instance.enemyGang == curGang) { return; //we want enemies of this gang to spawn only when close to the war } if (curTurfZone.ownerGangName != "none" && curGang != null) //only spawn if there really is a gang in control here { if (SpawnManager.instance.livingMembersCount < ModOptions.instance.spawnedMembersBeforeAmbientGenStops) { Vehicle playerVehicle = MindControl.CurrentPlayerCharacter.CurrentVehicle; if ((playerVehicle != null && playerVehicle.Speed < 30) || playerVehicle == null) { SpawnAmbientMember(curGang); } if (RandoMath.CachedRandom.Next(0, 5) < 3) { Wait(100 + RandoMath.CachedRandom.Next(300)); SpawnAmbientVehicle(curGang); } Wait(1 + RandoMath.CachedRandom.Next(RandoMath.Max(1, ModOptions.instance.msBaseIntervalBetweenAmbientSpawns / 2), ModOptions.instance.msBaseIntervalBetweenAmbientSpawns) / (curTurfZone.value + 1)); } } else { Game.WantedMultiplier = 1; Game.MaxWantedLevel = 6; } } } Logger.Log("ambient spawner tick: end", 5); }
public bool StartWar(Gang enemyGang, TurfZone warZone, warType theWarType, attackStrength attackStrength) { //TODO disable wars during missions if (!isOccurring || enemyGang == GangManager.instance.PlayerGang) { this.enemyGang = enemyGang; this.warZone = warZone; this.curWarType = theWarType; spawnPointsSet = false; warBlip = World.CreateBlip(warZone.zoneBlipPosition); warBlip.IsFlashing = true; warBlip.Sprite = BlipSprite.Deathmatch; warBlip.Color = BlipColor.Red; warBlip.Position += Vector3.WorldUp * 5; //an attempt to make the war blip be drawn over the zone blip Function.Call(Hash.BEGIN_TEXT_COMMAND_SET_BLIP_NAME, "STRING"); Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, "Gang War (versus " + enemyGang.name + ")"); Function.Call(Hash.END_TEXT_COMMAND_SET_BLIP_NAME, warBlip); curTicksAwayFromBattle = 0; if (theWarType == warType.attackingEnemy) { alliedReinforcements = GangManager.CalculateAttackerReinforcements(GangManager.instance.PlayerGang, attackStrength); enemyReinforcements = GangManager.CalculateDefenderReinforcements(enemyGang, warZone); } else { alliedReinforcements = GangManager.CalculateDefenderReinforcements(GangManager.instance.PlayerGang, warZone); enemyReinforcements = GangManager.CalculateAttackerReinforcements(enemyGang, attackStrength); } float screenRatio = (float)Game.ScreenResolution.Width / Game.ScreenResolution.Height; int proportionalScreenWidth = (int)(1080 * screenRatio); //nativeUI UIResText works with 1080p height alliedNumText.Position = new Point((proportionalScreenWidth / 2) - 120, 10); enemyNumText.Position = new Point((proportionalScreenWidth / 2) + 120, 10); alliedNumText.Caption = alliedReinforcements.ToString(); enemyNumText.Caption = enemyReinforcements.ToString(); initialEnemyReinforcements = enemyReinforcements; reinforcementsAdvantage = alliedReinforcements / (float)enemyReinforcements; spawnedAllies = GangManager.instance.GetSpawnedMembersOfGang(GangManager.instance.PlayerGang).Count; spawnedEnemies = GangManager.instance.GetSpawnedMembersOfGang(enemyGang).Count; maxSpawnedAllies = (int)(RandoMath.Max((ModOptions.instance.spawnedMemberLimit / 2) * reinforcementsAdvantage, 5)); maxSpawnedEnemies = RandoMath.Max(ModOptions.instance.spawnedMemberLimit - maxSpawnedAllies, 5); isOccurring = true; //try placing spawn points around the zone's blip position, which should be a good reference point if (World.GetZoneName(Game.Player.Character.Position) == warZone.zoneName || World.GetDistance(Game.Player.Character.Position, warZone.zoneBlipPosition) < 100) { SetSpawnPoints(warZone.zoneBlipPosition); } //BANG-like sound Function.Call(Hash.PLAY_SOUND_FRONTEND, -1, "PROPERTY_PURCHASE", "HUD_AWARDS"); if (theWarType == warType.attackingEnemy) { UI.ShowSubtitle("The " + enemyGang.name + " are coming!"); //if we are attacking and failed to set the initial spawn points around the war blip, //it probably means we're in a big zone, far from the zone's blip. //set spawns around the player then! if (!spawnPointsSet && theWarType == warType.attackingEnemy) { SetSpawnPoints(Game.Player.Character.Position); } } else { UI.Notify(string.Concat("The ", enemyGang.name, " are attacking ", warZone.zoneName, "! They are ", GangManager.CalculateAttackerReinforcements(enemyGang, attackStrength).ToString(), " against our ", GangManager.CalculateDefenderReinforcements(GangManager.instance.PlayerGang, warZone).ToString())); } return(true); } else { return(false); } }
/// <summary> /// if fighting is enabled and the targetzone is controlled by an enemy, attack it! ... But only if it's affordable. /// if we're desperate we do it anyway /// </summary> /// <param name="targetZone"></param> void TryStartFightForZone(TurfZone targetZone) { Gang ownerGang = GangManager.instance.GetGangByName(targetZone.ownerGangName); if (ownerGang == null) { Logger.Log("Gang with name " + targetZone.ownerGangName + " no longer exists; assigning all owned turf to 'none'", 1); ZoneManager.instance.GiveGangZonesToAnother(targetZone.ownerGangName, "none"); //this zone was controlled by a gang that no longer exists. it is neutral now if (watchedGang.moneyAvailable >= ModOptions.instance.baseCostToTakeTurf) { watchedGang.moneyAvailable -= ModOptions.instance.baseCostToTakeTurf; watchedGang.TakeZone(targetZone); } } else { if (GangWarManager.instance.isOccurring && GangWarManager.instance.warZone == targetZone) { //don't mess with this zone then, it's a warzone return; } //we check how well defended this zone is, //then figure out how large our attack should be. //if we can afford that attack, we do it int defenderStrength = GangCalculations.CalculateDefenderStrength(ownerGang, targetZone); GangWarManager.AttackStrength requiredStrength = GangCalculations.CalculateRequiredAttackStrength(watchedGang, defenderStrength); int atkCost = GangCalculations.CalculateAttackCost(watchedGang, requiredStrength); if (watchedGang.moneyAvailable < atkCost) { if (myZones.Count == 0) { //if we're out of turf and cant afford a decent attack, lets just attack anyway //we use a light attack and do it even if that means our money gets negative. //this should make gangs get back in the game or be wiped out instead of just staying away requiredStrength = GangWarManager.AttackStrength.light; atkCost = GangCalculations.CalculateAttackCost(watchedGang, requiredStrength); } else { return; //hopefully we can just find a cheaper fight } } if (targetZone.ownerGangName == GangManager.instance.PlayerGang.name) { if (ModOptions.instance.warAgainstPlayerEnabled && GangWarManager.instance.CanStartWarAgainstPlayer) { //the player may be in big trouble now watchedGang.moneyAvailable -= atkCost; GangWarManager.instance.StartWar(watchedGang, targetZone, GangWarManager.WarType.defendingFromEnemy, requiredStrength); } } else { watchedGang.moneyAvailable -= atkCost; int attackStrength = GangCalculations.CalculateAttackerStrength(watchedGang, requiredStrength); //roll dices... favor the defenders a little here if (attackStrength / RandoMath.CachedRandom.Next(1, 22) > defenderStrength / RandoMath.CachedRandom.Next(1, 15)) { watchedGang.TakeZone(targetZone); watchedGang.moneyAvailable += (int)(GangCalculations.CalculateBattleRewards(ownerGang, targetZone.value, true) * ModOptions.instance.extraProfitForAIGangsFactor); } else { ownerGang.moneyAvailable += (int)(GangCalculations.CalculateBattleRewards(watchedGang, (int)requiredStrength, false) * ModOptions.instance.extraProfitForAIGangsFactor); } } } }
/// <summary> /// gets the reinforcement count for the defenders and estimates a total power based on that number and /// the gang's fixed strength value /// </summary> /// <param name="defenderGang"></param> /// <param name="contestedZone"></param> /// <returns></returns> public static int CalculateDefenderStrength(Gang defenderGang, TurfZone contestedZone) { return(defenderGang.GetFixedStrengthValue() * CalculateDefenderReinforcements(defenderGang, contestedZone)); }
public static int CalculateDefenderReinforcements(Gang defenderGang, TurfZone targetZone) { return(ModOptions.instance.extraKillsPerTurfValue * targetZone.value + ModOptions.instance.baseNumKillsBeforeWarVictory + defenderGang.GetReinforcementsValue() / 100); }
void TryTakeTurf(TurfZone targetZone) { if (targetZone == null || targetZone.ownerGangName == watchedGang.name) { return; //whoops, there just isn't any zone available for our gang } if (targetZone.ownerGangName == "none") { //this zone is neutral, lets just take it //we make it cheaper for the AI to get neutral zones in order to not make the world a gangless place haha if (watchedGang.moneyAvailable >= ModOptions.instance.baseCostToTakeTurf / 10) { watchedGang.moneyAvailable -= ModOptions.instance.baseCostToTakeTurf / 10; watchedGang.TakeZone(targetZone); } } else { Gang ownerGang = GangManager.instance.GetGangByName(targetZone.ownerGangName); if (ownerGang == null) { ZoneManager.instance.GiveGangZonesToAnother(targetZone.ownerGangName, "none"); //this zone was controlled by a gang that no longer exists. it is neutral now if (watchedGang.moneyAvailable >= ModOptions.instance.baseCostToTakeTurf / 10) { watchedGang.moneyAvailable -= ModOptions.instance.baseCostToTakeTurf / 10; watchedGang.TakeZone(targetZone); } } else { if (GangWarManager.instance.isOccurring && GangWarManager.instance.warZone == targetZone) { //don't mess with this zone then, it's a warzone return; } //we check how well defended this zone is, //then figure out how large our attack should be. //if we can afford that attack, we do it int defenderStrength = GangManager.CalculateDefenderStrength(ownerGang, targetZone); GangWarManager.attackStrength requiredStrength = GangManager.CalculateRequiredAttackStrength(watchedGang, defenderStrength); int atkCost = GangManager.CalculateAttackCost(watchedGang, requiredStrength); if (watchedGang.moneyAvailable >= atkCost) { if (targetZone.ownerGangName == GangManager.instance.PlayerGang.name) { if (ModOptions.instance.fightingEnabled && ModOptions.instance.warAgainstPlayerEnabled && ticksSinceLastFightWithPlayer > ModOptions.instance.minGangAITicksBetweenBattlesWithSameGang) { //the player may be in big trouble now watchedGang.moneyAvailable -= atkCost; GangWarManager.instance.StartWar(watchedGang, targetZone, GangWarManager.warType.defendingFromEnemy, requiredStrength); } } else { watchedGang.moneyAvailable -= atkCost; //roll dices... favor the defenders a little here if (atkCost / ModOptions.instance.baseCostToTakeTurf * RandoMath.CachedRandom.Next(1, 20) > defenderStrength / RandoMath.CachedRandom.Next(1, 15)) { watchedGang.TakeZone(targetZone); watchedGang.moneyAvailable += (int)(GangManager.CalculateBattleRewards(ownerGang, true) * ModOptions.instance.extraProfitForAIGangsFactor); } else { ownerGang.moneyAvailable += (int)(GangManager.CalculateBattleRewards(watchedGang, false) * ModOptions.instance.extraProfitForAIGangsFactor); } } } else if (myZones.Count == 0) { //if we're out of turf and cant afford a decent attack, lets just attack anyway //we use a light attack and do it even if that means our money gets negative. //this should make gangs get back in the game or be wiped out instead of just staying away atkCost = GangManager.CalculateAttackCost(watchedGang, GangWarManager.attackStrength.light); if (targetZone.ownerGangName == GangManager.instance.PlayerGang.name) { if (ModOptions.instance.fightingEnabled && ModOptions.instance.warAgainstPlayerEnabled && ticksSinceLastFightWithPlayer > ModOptions.instance.minGangAITicksBetweenBattlesWithSameGang) { //the player may be in big trouble now watchedGang.moneyAvailable -= atkCost; GangWarManager.instance.StartWar(watchedGang, targetZone, GangWarManager.warType.defendingFromEnemy, requiredStrength); } } else { watchedGang.moneyAvailable -= atkCost; //roll dices... favor the defenders a little here if (atkCost / ModOptions.instance.baseCostToTakeTurf * RandoMath.CachedRandom.Next(1, 20) > defenderStrength / RandoMath.CachedRandom.Next(1, 15)) { watchedGang.TakeZone(targetZone); watchedGang.moneyAvailable += (int)(GangManager.CalculateBattleRewards(ownerGang, true) * ModOptions.instance.extraProfitForAIGangsFactor); } else { ownerGang.moneyAvailable += (int)(GangManager.CalculateBattleRewards(watchedGang, false) * ModOptions.instance.extraProfitForAIGangsFactor); } } } } } }
void OnTick(object sender, EventArgs e) { Wait(4000 + RandoMath.CachedRandom.Next(2000)); ZoneManager.instance.RefreshZoneBlips(); //since this runs once in a while, let's also refresh the zone blips TurfZone curTurfZone = ZoneManager.instance.GetCurrentTurfZone(); if (curTurfZone != null) { // also reduce police influence if (enabled) { Game.WantedMultiplier = (1.0f / (curTurfZone.value + 1)) + ModOptions.instance.minWantedFactorWhenInGangTurf; Game.MaxWantedLevel = RandoMath.Max(CalculateMaxWantedLevelInTurf(curTurfZone.value), ModOptions.instance.maxWantedLevelInMaxedGangTurf); } if (Game.Player.WantedLevel > Game.MaxWantedLevel) { Game.Player.WantedLevel--; } if (postWarBackupsRemaining > 0 && curTurfZone == GangWarManager.instance.warZone) { Vector3 playerPos = Game.Player.Character.Position; GangManager.instance.SpawnParachutingMember(GangManager.instance.PlayerGang, playerPos + Math.Vector3.WorldUp * 50, playerPos); GangManager.instance.SpawnGangVehicle(GangManager.instance.PlayerGang, GangManager.instance.FindGoodSpawnPointForCar(), playerPos, true, false, true); postWarBackupsRemaining--; } //if spawning is enabled, lets try to spawn the current zone's corresponding gang members! if (ModOptions.instance.ambientSpawningEnabled && enabled) { Gang curGang = GangManager.instance.GetGangByName(curTurfZone.ownerGangName); if (GangWarManager.instance.isOccurring && GangWarManager.instance.enemyGang == curGang) { return; //we want enemies of this gang to spawn only when close to the war } if (curTurfZone.ownerGangName != "none" && curGang != null) //only spawn if there really is a gang in control here { if (GangManager.instance.livingMembersCount < ModOptions.instance.spawnedMembersBeforeAmbientGenStops) { Vehicle playerVehicle = Game.Player.Character.CurrentVehicle; if ((playerVehicle != null && playerVehicle.Speed < 70) || playerVehicle == null) { Vector3 spawnPos = GangManager.instance.FindGoodSpawnPointForMember(); Ped newMember = GangManager.instance.SpawnGangMember(curGang, spawnPos); if (newMember != null) { newMember.Task.GoTo(World.GetNextPositionOnSidewalk(newMember.Position)); } } if (RandoMath.CachedRandom.Next(0, 5) < 3) { Wait(100 + RandoMath.CachedRandom.Next(300)); Vehicle spawnedVehicle = GangManager.instance.SpawnGangVehicle(curGang, GangManager.instance.FindGoodSpawnPointForCar(), Vector3.Zero, true, false, false); if (spawnedVehicle != null) { GangManager.instance.TryPlaceVehicleOnStreet(spawnedVehicle, spawnedVehicle.Position); Ped driver = spawnedVehicle.GetPedOnSeat(VehicleSeat.Driver); if (driver != null) //if, for some reason, we don't have a driver, do nothing { driver.Task.CruiseWithVehicle(spawnedVehicle, 20, (int)DrivingStyle.Rushed); } } } Wait(1000 + RandoMath.CachedRandom.Next(40000) / (curTurfZone.value * curTurfZone.value + 1)); } } else { Game.WantedMultiplier = 1; Game.MaxWantedLevel = 6; } } } }