public TowerAI(ICanyonShooterGame game, EnemyDescription desc) : base(game, "Enemy-TankAI") { this.game = game; id = createdTanks++; // Set the tank model SetModel(desc.Model); LocalScale = new Vector3(4f, 4f, 4f); LocalPosition = desc.RelativeSpawnLocation; dir = new Vector3(0, 0, -1); // Physics Config ConnectedToXpa = true; this.Static = true; ContactGroup = ContactGroup.Enemies; LocalPosition = desc.RelativeSpawnLocation; // Initialize AI-States of TowerAI AIStates = new AIStateMachine(game, this); AIStates.AddState(new TowerAIObserving(game.World.Players[0])); AIStates.AddState(new TowerAIAttackPlayer(game.World.Players[0])); AIStates.DebugAI = false; }
/// <param name="desc">The description data (i.e. healthpoints, strength).</param> public KamidroneAI(ICanyonShooterGame game, EnemyDescription desc) : base(game, "Enemy-KamidroneAI") { EnemyNr = EnemiesCreated++; this.game = game; // Physics Config ConnectedToXpa = true; ContactGroup = ContactGroup.Enemies; InfluencedByGravity = false; InfoMessage(string.Format("Created at: {0}", desc.RelativeSpawnLocation)); currentHitpoints = desc.MaxHitpoints; LocalPosition = desc.RelativeSpawnLocation; // System typeDesc = game.Content.Load <EnemyTypeDescription>("Content\\Enemies\\" + desc.Type); SetModel(typeDesc.Model); // Initiate AI-System: AI = new AIStateMachine(game, this); AI.DebugAI = false; // Add States to Machine: AI.AddState(new Patrol()); // Init-State AI.AddState(new FlyToWaypoint(desc.SegmentId)); AI.AddState(new FlyToPlayer()); // SquadronFormations if (desc.SquadronCount > 1) //Enemy-Squadron erzeugen. { // Create EnemyFormation and join it EnemyFormation formation = new EnemyFormation(game, LocalPosition, desc.SegmentId, desc.Speed, typeDesc.Formation); JoinFormation(formation); desc.SquadronCount = 1; int count = typeDesc.Formation.Count - 1; // dieser enemy hat sich bereits selbst hinzugefügt. for (int i = 0; i < count; i++) { // Versezte den nächsten Enemy in Richtung des Canyons Vector3 canyonDirection = game.World.Level.Cache[desc.SegmentId].ADir; canyonDirection.Normalize(); desc.RelativeSpawnLocation = desc.RelativeSpawnLocation + canyonDirection * 100; // Nächsten Enemy im Squadron erzeugen: KamidroneAI enemyForFormation = new KamidroneAI(game, desc); //enemyFollowing.FollowEnemy(this); // follow ME! enemyForFormation.JoinFormation(formation); game.World.AddObject(enemyForFormation); } } }
public WaveSimulatorDamageStats SimulateDamageToEnemies( EnemyDescription enemy, WaveSolution solution, float HandMissileFreqency, float HandMissileDamantPctAverage, int enemyCount, bool invincible) { DamageStats = new WaveSimulatorDamageStats(); InvincibleEnemies = invincible; float waveTime = 0.0F; float timeDelta = 1.0F / 72.0F; float previousHandMissileTime = 0.0f; EnemyWave waveDesc = new EnemyWave(); waveDesc.Count = enemyCount; waveDesc.Enemy = enemy.Name; waveDesc.DifficultyMultiplier = 1.0F; ResetLevelDescState(LevelDesc); TurretManager turrets = new TurretManager(LevelDesc); ProjectileManager projectiles = new ProjectileManager(LevelDesc, LevelManager.LookupProjectile); WaveInstance wave = new WaveInstance(LevelDesc, waveDesc, enemy, 0.0F, SimulatorDamageCallback); for (int i = 0; i < solution.Turrets.Count; i++) { turrets.AddTurret(LevelManager.LookupTurret(solution.Turrets[i].Name), solution.Turrets[i].pos, projectiles); } Debug.Log("----------------------------------------"); Debug.Log(" Wave of " + enemyCount + " " + enemy.Name + "s"); Debug.Log("----------------------------------------"); do { wave.Advance(waveTime); projectiles.AdvanceAll(waveTime); turrets.Fire(waveTime); float timeSinceLastHandMissile = waveTime - previousHandMissileTime; if (timeSinceLastHandMissile >= HandMissileFreqency) { // Real projectiles have to incur flight time but we'll simulate // the damage as instanntaneous to keep it simple. Also real projectiles // have blast radius that should hit multiple enemies. We'll just hit one. } waveTime += timeDelta; } while (!wave.IsCompleted); DamageStats.DamagePerEnemy = DamageStats.DamageDealt / enemyCount; return(DamageStats); }
public void Spawn(EnemyDescription enemyDescription) { GameObject enemy = EnemyFactory.Instance.GetEnemy(); // TODO // enemyDescription.PrefabPath not used, cause in EnemyFactory have only one type of enemy enemy.GetComponent <Transform>().position = enemyDescription.EnemySpawnPosition; enemy.SetActive(true); }
/// <summary> /// Sets whenever the elite enemy benefits from generic elite bonuses. /// <para> If true, elites will gain HP scaling based on player count, more money drops, will grant more EXP, etc. </para> /// <remarks> An example of enemies with no elite "bonus" are empowered Season Knights and Season Mages. </remarks> /// </summary> public static void SetEliteBonuses(this EnemyDescription xDesc, bool bGrantBonuses) { if (!xDesc.enType.IsModEnemy()) { throw new ArgumentException("Provided enType is not a mod enemy."); } ModLibrary.EnemyDetails[xDesc.enType].bGrantEliteBonuses = bGrantBonuses; }
/// <summary> /// Sets the delegate used to scale stats for enemy instances when they're turned into Elites. /// This delegate is usually called when a new enemy is created as Elite. It's also called whenever an existing enemy is promoted to Elite status (Skeleton Mages, Bishop in Arcade, etc.) /// <para> /// The delegate is where you should modify the enemy's stats so that Elite enemies are more dangerous. /// You can also modify the Elite enemy's Animations to be faster or whatever, like what SoG does for some enemies. /// </para> /// <para> Unlike the other two delegates, you can choose to skip this one if you wish. Doing so will cause the enemy to have no elite variant. </para> /// </summary> public static void SetEliteBuilder(this EnemyDescription xDesc, EnemyBuilderPrototype xProto) { if (!xDesc.enType.IsModEnemy()) { throw new ArgumentException("Provided enType is not a mod enemy."); } ModLibrary.EnemyDetails[xDesc.enType].EliteBuilder = xProto; }
public static float CalculateDPSforWave(EnemyDescription enemy) { float DPS = 0.0F; float hitPointsPerEnemy = enemy.HitPoints; float spawnRate = enemy.SpawnRate; DPS = hitPointsPerEnemy * (1.0F / spawnRate); return(DPS); }
public WaveInstance(LevelDescription levelDesc, EnemyWave waveDescription, EnemyDescription enemyDesc, float gameTime, SimulatorDamageCallback damageCallback = null) { EnemyType = enemyDesc; LevelDesc = levelDesc; Desc = waveDescription; Enemies = new List <EnemyInstance>(); RoadSegments = levelDesc.Road.Count; WaveStartTime = gameTime; LastSpawnTime = WaveStartTime; CoinEarnedToReport = 0; LivesLostToReport = 0; DamageCallback = damageCallback; }
public IEnumerator LoadCurrentLevel(LevelDescription myLevel) { for (int i = 0; i < myLevel.Enemies.Length; i++) { EnemyDescription enemy = myLevel.Enemies[i]; while (enemy.SpawnDate > Time.time - timeStart) { yield return(new WaitForSeconds(0.5f)); } mySpawn.FonctionSpawn(enemy.SpawnPosition, enemy.PrefabPath); nbWave = enemy.Wave; } NextLevel(); }
public void AddEnemy() { EnemyDescription enemy = new EnemyDescription(); enemy.Name = "New Enemy"; enemy.Asset = ""; enemy.HitPoints = 1; enemy.MovementSpeed = 1.0F; enemy.SpawnRate = 1.0F; Enemies.Add(enemy); WriteChanges(); TreeRefreshNeeded?.Invoke(); }
IEnumerator SpawnEnemy(EnemyDescription description) { GameObject enemyType = description.enemyType; float delay = description.unitDelay; int enemiesToSpawn = description.waveSpawnCount; for (int i = 0; i < enemiesToSpawn; ++i) { GameObject newEnemy = Instantiate(enemyType, (Vector2)transform.position + new Vector2(Random.Range(-halfWidth, halfWidth), Random.Range(-halfHeight, halfHeight)), Quaternion.identity); newEnemy.GetComponent <AgentScript>().goal = endGoal; newEnemy.GetComponent <AgentScript>().aStar = AStar; aliveEnemies++; // Add one to our alive enemies counter yield return(new WaitForSeconds(delay)); } }
IEnumerator SpawnWave() { while (wave < waveDescriptions.Length) { WaveDescription currentWave = waveDescriptions[wave]; for (int i = 0; i < currentWave.enemyDescriptions.Length; i++) // For every enemy Type { EnemyDescription currentEnemy = currentWave.enemyDescriptions[i]; StartCoroutine(SpawnEnemy(currentEnemy)); // spawn that enemy type yield return(new WaitForSeconds(currentEnemy.waveDelay)); } ++wave; yield return(new WaitForSeconds(currentWave.delay)); } }
public static EnemyDescription LookupEnemy(string name) { EnemyDescription enemy = null; List <EnemyDescription> Enemies = GetEnemies(); for (int i = 0; i < Enemies.Count; i++) { if (Enemies[i].Name == name) { enemy = Enemies[i]; } } return(enemy); }
public static EnemyDescription LinqToXml(string enemyName, string fileName) { string path = System.Environment.CurrentDirectory + "\\Files\\enemies\\" + fileName; XElement rootNode = XElement.Load(path); IEnumerable <XElement> enemies = rootNode.Elements(); XElement node = null; foreach (XElement theNode in enemies) { //Debug.Log(node.Element("name")); if (theNode.Element("name").Value.Equals(enemyName)) { node = theNode; break; } } if (node == null) { Debug.Log("Enemy with name " + enemyName + " does not exist in the file " + fileName + "."); return(null); } EnemyDescription ans = new EnemyDescription(); ans.info = new EnemyInfo(); ans.info.name = node.Element("name").Value; ans.info.hp = Int32.Parse(node.Element("health").Value); ans.info.damage = Int32.Parse(node.Element("dmg").Value); ans.info.money = Int32.Parse(node.Element("money").Value); ans.info.speed = Int32.Parse(node.Element("speed").Value); ans.info.weight = Int32.Parse(node.Element("weight").Value); ans.info.enemyType = EnemyDescription.GetEnemyType(node.Element("type").Value); ans.info.sizeType = EnemyDescription.GetSizeType(node.Element("size").Value); ans.info.resistance = new Dictionary <ResisType, double>(); ans.info.resistance.Add(ResisType.bullet, Double.Parse(node.Element("resis_bullet").Value)); ans.info.resistance.Add(ResisType.explosive, Double.Parse(node.Element("resis_explo").Value)); ans.info.resistance.Add(ResisType.tesla, Double.Parse(node.Element("resis_tesla").Value)); ans.info.resistance.Add(ResisType.flame, Double.Parse(node.Element("resis_flame").Value)); ans.info.resistance.Add(ResisType.toxic, Double.Parse(node.Element("resis_toxic").Value)); ans.info.resistance.Add(ResisType.nuclear, Double.Parse(node.Element("resis_nuclear").Value)); return(ans); }
// Static setup methods /// <summary> Creates a new EnemyDescription that can be used by the game. </summary> public static EnemyDescription CreateEnemyDescription(string sName, int iLevel, int iBaseHealth) { string sBaseEntryName = sName.Replace(" ", ""); EnemyDescription xDesc = new EnemyDescription(ModLibrary.EnemyTypesNext, sBaseEntryName + "_Name", iLevel, iBaseHealth) { sOnDeathSound = "", sOnHitSound = "", sFullName = sName }; EnemyCodex.denxDescriptionDict[xDesc.enType] = xDesc; ModLibrary.EnemyDetails.Add(xDesc.enType, new ModEnemyData(xDesc.enType)); Ui.AddMiscText("Enemies", sBaseEntryName + "_Name", sName); return(xDesc); }
public EnemyInstance(EnemyDescription desc, float spawnTime) { Desc = desc; LastMoveTime = spawnTime; HealthRemaining = desc.HitPoints; LinearProgress = 0.0F; Position = new Vector3(); ReachedFinishLine = false; ActiveEffects = new List <EffectInstance>(); MapPosition = null; go = GameObjectFactory.InstantiateObject(Desc.Asset); GameObject healthIndicatorGo = GameObjectFactory.InstantiateObject("EnemyHealthIndicator"); #if LEVEL_EDITOR == false go.tag = "Enemy"; healthIndicatorGo.transform.parent = go.transform; healthIndicatorGo.transform.forward = Vector3.back; #endif }
public TankAI(ICanyonShooterGame game, EnemyDescription desc) : base(game, "Enemy-TankAI") { this.game = game; id = createdTanks++; // Set the tank model SetModel(desc.Model); LocalScale = new Vector3(8f, 8f, 8f); LocalPosition = desc.RelativeSpawnLocation; dir = new Vector3(0, 0, -1); // Physics Config ConnectedToXpa = true; ContactGroup = ContactGroup.Enemies; InfluencedByGravity = false; LocalPosition = desc.RelativeSpawnLocation; }
//</data> //<methods> //<create> public static void ReadFromXml(EnemyDescription[] ei, string filename) { XmlDocument enemyDocument = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; XmlReader enemyReader = XmlReader.Create(System.Environment.CurrentDirectory + "\\Files\\towers\\" + filename); enemyDocument.Load(enemyReader); XmlNode enemyRootNode = enemyDocument.SelectSingleNode("enemies"); XmlNodeList enemyList = enemyRootNode.ChildNodes; ei = new EnemyDescription[enemyList.Count]; int enemyCount = 0; foreach (XmlNode enemy in enemyList) { XmlElement enemyElement = (XmlElement)enemy; XmlNodeList enemyProperties = enemyElement.ChildNodes; ei[enemyCount].info.name = enemyProperties.Item(0).InnerText; ei[enemyCount].info.description = enemyProperties.Item(1).InnerText; ei[enemyCount].info.hp = Int32.Parse(enemyProperties.Item(2).InnerText); ei[enemyCount].info.damage = Int32.Parse(enemyProperties.Item(3).InnerText); ei[enemyCount].info.speed = Int32.Parse(enemyProperties.Item(4).InnerText); ei[enemyCount].info.money = Int32.Parse(enemyProperties.Item(5).InnerText); XmlElement enemyResistance = (XmlElement)enemyProperties.Item(6); XmlNodeList enemyResisList = enemyResistance.ChildNodes; foreach (XmlNode r in enemyList) { ei[enemyCount].info.resistance.Add(ResisType.bullet, Double.Parse(enemyResisList.Item(0).InnerText)); ei[enemyCount].info.resistance.Add(ResisType.explosive, Double.Parse(enemyResisList.Item(1).InnerText)); ei[enemyCount].info.resistance.Add(ResisType.tesla, Double.Parse(enemyResisList.Item(2).InnerText)); ei[enemyCount].info.resistance.Add(ResisType.flame, Double.Parse(enemyResisList.Item(3).InnerText)); ei[enemyCount].info.resistance.Add(ResisType.toxic, Double.Parse(enemyResisList.Item(4).InnerText)); ei[enemyCount].info.resistance.Add(ResisType.nuclear, Double.Parse(enemyResisList.Item(5).InnerText)); } enemyCount++; } }
public void Execute() { levelTimer = Time.time - this.startTime; for (int index = 0; index < this.enemiesToSpawn.Count; index++) { EnemyDescription enemyDescription = this.description.Enemies[index]; if (this.enemyStateArray[index] == EnemyState.Spawned) { continue; } if (levelTimer < enemyDescription.SpawnDate) { continue; } // Spawn EnemyFactory.Instance.GetEnemy(enemyDescription.Type, enemyDescription.SpawnPosition); this.enemyStateArray[index] = EnemyState.Spawned; } }
private void CalculateStatsForWaves(List <TurretStats> Turrets) { WaveStatList = new List <WaveStats>(); float maxDPSOverall = 0.0F; int coinNeeded = 0; for (int j = 0; j < Turrets.Count; j++) { maxDPSOverall += Turrets[j].MaxDPSOverall; coinNeeded += Turrets[j].t.Cost; } int maxCoinEarned = LevelDesc.StartingCoins; for (int i = 0; i < LevelDesc.Waves.Count; i++) { EnemyWave wave = LevelDesc.Waves[i]; EnemyDescription enemyDesc = LevelManager.LookupEnemy(wave.Enemy); WaveSolution solution = GenerateWaveSolution(); WaveStats stats = new WaveStats(); WaveSimulatorDamageStats singleEnemyStats = SimulateWave(enemyDesc, solution, 1, true); WaveSimulatorDamageStats fullWaveStats = SimulateWave(enemyDesc, solution, wave.Count, false); EnemyDescription enemy = LevelManager.LookupEnemy(wave.Enemy); stats.MaxDmgDealtSingleEnemy = singleEnemyStats.DamageDealt; stats.MaxDPSOverall = maxDPSOverall; stats.MaxHPPSProducted = EnemyEditLayout.CalculateDPSforWave(enemy); stats.FullSimulation = fullWaveStats; stats.CoinNeeded = coinNeeded; stats.CoinAvail = maxCoinEarned; maxCoinEarned += (enemy.Coins * wave.Count); WaveStatList.Add(stats); } }
public void Execute() { if (!this.IsLevelStarted) { return; } float timePassedSinceBeginning = Time.time - this.currentLevelStartDate; if (this.description == null) { return; } if (this.description.Enemies == null) { return; } for (int index = 0; index < this.description.Enemies.Length; index++) { EnemyDescription enemyDescription = this.description.Enemies[index]; if (this.isEnemySpawned[index] == EnemyState.Spawned) { continue; } if (timePassedSinceBeginning < enemyDescription.SpawnDate) { continue; } // Spawn ! EnemyFactory.GetEnemy(enemyDescription.SpawnPosition, Quaternion.Euler(0f, 0f, 0f), enemyDescription.PrefabPath); this.isEnemySpawned[index] = EnemyState.Spawned; } }
// // Harmony Library Patches // /// <summary> Patches GetEnemyInstance so that SoG can create modded enemy instances. </summary> private static bool GetEnemyInstance_PrefixPatch(ref Enemy __result, EnemyCodex.EnemyTypes enType, Level.WorldRegion enOverrideContent) { if (!enType.IsModEnemy()) { return(true); // Executes original method } EnemyDescription xDesc = EnemyCodex.denxDescriptionDict[enType]; __result = new Enemy() { xEnemyDescription = xDesc, enType = enType }; __result.xRenderComponent.xOwnerObject = __result; ModEnemyData xModData = ModLibrary.EnemyDetails[enType]; xModData.InstanceBuilder?.Invoke(__result); __result.xBaseStats.iLevel = __result.xEnemyDescription.iLevel; __result.xBaseStats.iHP = (__result.xBaseStats.iBaseMaxHP = __result.xEnemyDescription.iMaxHealth); if (__result.xEnemyDescription.enCategory == EnemyDescription.Category.Regular) { __result.rcRegularHPRenderComponent = new RegularEnemyHPRenderComponent(__result); } __result.xRenderComponent.bReSortHeight = true; __result.xRenderComponent.GetCurrentAnimation().Reset(); foreach (DropChance xDrop in __result.xEnemyDescription.lxLootTable) { __result.lxLootTable.Add(new DropChance(xDrop.iChance, xDrop.enItemToDrop, xDrop.iRolls)); ItemCodex.GetItemDescription(xDrop.enItemToDrop); } return(false); // Skips original method }
/// <param name="desc">The description data (i.e. healthpoints, strength).</param> public EnemyAI2(ICanyonShooterGame game, EnemyDescription desc) : base(game, "Enemy-AI2") { this.game = game; // Physics Config ConnectedToXpa = true; ContactGroup = ContactGroup.Enemies; InfluencedByGravity = false; LocalPosition = desc.RelativeSpawnLocation; typeDesc = game.Content.Load <EnemyTypeDescription>("Content\\Enemies\\" + desc.Type); currentHitpoints = typeDesc.MaxHitpoints; SetModel(typeDesc.Model); LocalScale = new Vector3(1.5f, 1.5f, 1.5f); itemChance = desc.ItemChance; itemList = desc.ItemList; if (game.Graphics.ShadowMappingSupported) { game.World.Sky.Sunlight.ShadowMapLow.Scene.AddDrawable(this); game.World.Sky.Sunlight.ShadowMapHigh.Scene.AddDrawable(this); } #region Init WeaponManager and add Weapons if (weapons == null) { weapons = new WeaponManager(game, Model, WeaponHolderType.Enemy); foreach (string weapon in typeDesc.Weapons) { weapons.AddWeapon((WeaponType)Enum.Parse(typeof(WeaponType), weapon, true)); } } #endregion }
public EnemyAI1(ICanyonShooterGame game, EnemyDescription desc) : base(game, "Enemy-AI1") { // hier Konstruktor }
/// <summary> Sets the sound cues for hitting and killing an enemy. </summary> public static void SetCommonSounds(this EnemyDescription xDesc, string sOnHitSound, string sOnDeathSound) { xDesc.sOnHitSound = sOnHitSound; xDesc.sOnDeathSound = sOnDeathSound; }
/// <summary> Spawns an enemy at the target location. </summary> public static Enemy SpawnEnemy(this EnemyDescription xDesc, Vector2 v2Pos, float fVirtualHeight, int iColliderLayer) { return(Utils.GetTheGame()._EntityMaster_AddEnemy(xDesc.enType, v2Pos, iColliderLayer, fVirtualHeight)); }
// EnemyDescription extensions /// <summary> Spawns an enemy at the target player's position. </summary> /// <remarks> Use this for testing purposes; spawning enemies next to players isn't a great idea.</remarks> public static Enemy SpawnEnemy(this EnemyDescription xDesc, PlayerView xTarget) { PlayerEntity xEntity = xTarget.xEntity; return(Utils.GetTheGame()._EntityMaster_AddEnemy(xDesc.enType, xEntity.xTransform.v2Pos, xEntity.xCollisionComponent.ibitCurrentColliderLayer, xEntity.xRenderComponent.fVirtualHeight)); }
private WaveSimulatorDamageStats SimulateWave(EnemyDescription enemy, WaveSolution solution, int enemyCount, bool invincible) { WaveSimulator sim = new WaveSimulator(LevelDesc); return(sim.SimulateDamageToEnemies(enemy, solution, HandMissileFreqency, HandMissileDamantPctAverage, enemyCount, invincible)); }
/// <summary> Adds an item that can be dropped when the enemy is killed. </summary> /// <remarks> This method can be called multiple times to have multiple item drops of the same type, but with different drop chance or roll count. </remarks> /// <param name="fDropChance"> Chance for an item to drop. 100.0f translates to 100% chance, and 0f to 0% respectively. </param> /// <param name="iRolls"> Number of items to roll for. Setting this to 4 would mean up to 4 enType items can drop, each with fDropChance chance. </param> public static void AddLoot(this EnemyDescription xDesc, ItemCodex.ItemTypes enType, float fDropChance = 100.0f, int iRolls = 1) { xDesc.lxLootTable.Add(new DropChance((int)(fDropChance * 1000.0f), enType, iRolls)); }
/// <summary> /// Sets the size of an enemy, and approximately where the enemy's "center" is. /// These are used by some game objects (such as Guardian Shields). /// </summary> public static void SetSizeAndOffset(this EnemyDescription xDesc, Vector2 v2Size, Vector2 v2OffsetToMid) { xDesc.v2ApproximateOffsetToMid = v2OffsetToMid; xDesc.v2ApproximateSize = v2Size; }