void HandleTurnStarted(object sender, EventArgs args) { TurnStartedEvent e = args as TurnStartedEvent; BUnit bUnit = GetBUnit(e.unit); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void HandleRoundSetup(object sender, EventProxyArgs args) { RoundSetupEvent e = args as RoundSetupEvent; bInitativeList.UpdateList(e.sortedList); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
public void Execute() { // assume we have only 2 teams on the field int aliveTeamA = 0; int aliveTeamB = 0; // count number of units alive on each team foreach (Unit unit in model.units) { switch (unit.team) { case Unit.Team.PLAYER: if (unit.Alive) { aliveTeamA++; } break; case Unit.Team.AI: if (unit.Alive) { aliveTeamB++; } break; } } // if all units on one team are that the game is over bool playerDefeated = false; bool aiDefeated = false; if (aliveTeamA == 0) { playerDefeated = true; } if (aliveTeamB == 0) { aiDefeated = true; } if (playerDefeated || aiDefeated) { if (aiDefeated) // player has won // get current level ID { int lastLevel = int.Parse(Application.loadedLevelName.Substring(6)); // check highest level int highestLevel = PlayerPrefs.GetInt("HighestLevel"); if (highestLevel < lastLevel) { highestLevel = lastLevel; } // update player prefs PlayerPrefs.SetInt("LastLevel", lastLevel); PlayerPrefs.SetInt("HighestLevel", highestLevel); } model.matchRunning = false; EventProxyManager.FireEvent(this, new GameoverEvent(playerDefeated, aiDefeated)); } }
/// <summary> /// This routine does the movement animation. /// </summary> /// <returns>Nothing; IEnumerator is just for coroutines</returns> /// <param name="path">The path we want to move along</param> /// <param name="bCombatMenu">This combat Menu will be hide during animation</param> public IEnumerator MoveRoutine(BMapTile[] path, BCombatMenu bCombatMenu) { bCombatMenu.Hide(); for (int i = 1; i < path.Length; i++) { Vector3 nextWp = path[i].transform.position; Vector3 lookPoint = nextWp; lookPoint.y = 0; meshContainer.transform.LookAt(lookPoint); do { Vector3 translation = nextWp - transform.position; float distance = translation.magnitude; translation = translation.normalized * Time.deltaTime * movementSpeed; if (distance < translation.magnitude) { transform.position = nextWp; break; } else { transform.Translate(transform.InverseTransformDirection(translation)); } yield return(0); } while(transform.position != nextWp); } bCombatMenu.OpenForBUnit(parent); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
/// <summary> /// Routine to perfome a attack animation /// </summary> /// <returns>IEnumerator is needed for co-routines.<</returns> /// <param name="target">The BUnit whom is the attack target.</param> /// <param name="attack">The attack which will be performed.</param> /// <param name="efficeny">0 = not effectiv, 1 = normal efficeny, 2 = very effectiv</param> /// <param name="damage">The amount of damage dealt by this attack.</param> public IEnumerator AttackRoutine(UnitAttackedEvent e, BMapTile target, BUnit[] victims, BCombatMenu bCombatMenu) { meshContainer.transform.LookAt(target.transform.position); bCombatMenu.Hide(); // sound effect attackSound.Play(); // animation animator.SetTrigger("AttackTrigger"); // wait some time before starting the attack effect yield return(new WaitForSeconds(e.attack.effectDelay)); // caluclate the direction of the attack and project it on one of the 4 vectors: (0,1),(1,0),(0,-1),(-1,0) Vector direction = new Vector(Mathf.FloorToInt(target.transform.position.x - this.transform.position.x), Mathf.FloorToInt(target.transform.position.z - this.transform.position.z)); direction.NormalizeTo4Direction(); BParticleManager.PlayEffect(e.attack.attackName, target.transform.position, new Vector3(direction.x, 0, direction.y)); // wait some time before trigger the hit animtion/effect yield return(new WaitForSeconds(e.attack.hitDelay)); for (int i = 0; i < victims.Length; i++) { victims[i].PlayHitAnimation(e.efficiency, e.damage[i]); victims[i].unitUI.ShowDamage(e.damage[i]); } // wait the rest of the time for the animation before contuine with next event yield return(new WaitForSeconds(e.attack.fullAnimationTime - e.attack.effectDelay - e.attack.hitDelay)); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void HandleUnitSpawned(object sender, EventArgs args) { UnitSpawnedEvent e = args as UnitSpawnedEvent; SpawnBUnit(e.unit); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
public void Execute() { // stop if start and destination are the same if ((unit.mapTile == path.Last) // or if target is to far away for unit move || (path.Cost > unit.MovePoints)) { path = new Path(new MapTile[] { path.Last }); EventProxyManager.FireEvent(this, new UnitMovedEvent(unit, path)); } else { // we are now sure, that unit is allowed to move and target is in range // now performce actual move model.MoveUnit(unit, path.Last); EventProxyManager.FireEvent(this, new UnitMovedEvent(unit, path)); // trigger OnStayEffect on each topping on the path for (int i = 0; i < path.Length; i++) { if (path[i].topping != null) { path[i].topping.OnStayEffect(unit); } } // clear units move resource, since only one move per turn is permitted unit.MovePoints = 0; model.combat.CheckForDeadUnits(); } }
void HandleToppingDestroyed(object sender, EventArgs args) { ToppingDestroyedEvent e = args as ToppingDestroyedEvent; BMapTile bMapTile = GetBMapTile(e.target.mapTile); bMapTile.DestroyTopping(); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void HandleUnitLoseHealth(object sender, EventProxyArgs eventArgs) { UnitLoseHealthEvent e = eventArgs as UnitLoseHealthEvent; BUnit bUnit = GetBUnit(e.unit); bUnit.unitUI.UpdateLifebar(e.damage); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void HandleBUnitTapped(object sender, EventArgs args) { // use tapped unit as attack target for active unit // if active unit is not ready to attack, nothing will happen // BUnitTappedEvent e = args as BUnitTappedEvent; // if(GetBMapTile(e.bUnit.unit.mapTile).Clickable) // activeBUnit.SetAttackTarget(e.bUnit); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
public IEnumerator DeathRoutine(BUnitUI unitUI) { yield return(new WaitForSeconds(1f)); deathSound.Play(); animator.SetTrigger("DeathTrigger"); yield return(new WaitForSeconds(2f)); meshContainer.SetActive(false); unitUI.gameObject.SetActive(false); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void OnTap() { // we clicked with mouse or tapped on the touchscreen // cast an ray from the screen point Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition); // create layer mask to ignore layer "Ignore Raycast" and hit all others int mask = 1 << LayerMask.NameToLayer("Ignore Raycast"); mask = ~mask; BMapTile bMapTile = null; RaycastHit[] hits = Physics.RaycastAll(cursorRay, Mathf.Infinity, mask); // this does not work since buttons will be Deactivate just as we cast the ray // so we don't hit them anymore :( if (CheckUIHit()) { return; } // check all objects hit on raycast foreach (RaycastHit hit in hits) { // let's see what we hit with the raycast switch (hit.collider.gameObject.layer) { case UI_LAYER: // we hit an ui element first // stop looking for map and stuff and just return Debug.LogWarning("Hit UI! Stop here"); return; case UNIT_LAYER: // find the quad the unit is standing on BUnit bUnit = hit.collider.GetComponent <BUnit>(); // fire event for the tapped bUnit tapFieldSound.Play(); EventProxyManager.FireEvent(this, new BUnitTappedEvent(bUnit)); break; case GRID_LAYER: // we hit an quad of the map bMapTile = hit.collider.GetComponent <BMapTile>(); // fire event for the tapped mapTile tapFieldSound.Play(); EventProxyManager.FireEvent(this, new BMapTileTappedEvent(bMapTile)); break; } } }
void HandleEvent(object sender, EventProxyArgs args) { if (args.name == EventName.TurnStarted) { TurnStartedEvent e = (TurnStartedEvent)args; Debug.Log("Round: " + e.round + " Turn: " + e.turn); } eventQueue.Enqueue(args); if (!performingEvent) { EventProxyManager.FireEvent(this, new EventDoneEvent()); } }
/// <summary> /// Plaies the hit animation. /// </summary> /// <param name="efficeny">0 = not effectiv, 1 = normal efficeny, 2 = very effectiv</param> public void PlayHitAnimation(byte efficeny, int damage) { if (damage > 0) { //unitUI.UpdateLifebar(damage); StartCoroutine(bUnitAnimator.DamageFlashRoutine()); StartCoroutine(bUnitAnimator.ShakeRoutine(0.25f * efficeny, 0.1f * efficeny)); } else { EventProxyManager.FireEvent(this, new EventDoneEvent()); } }
IEnumerator NotifyRoutine(BUnit bUnit) { if (bUnit.unit.team == Unit.Team.PLAYER) { bNotification.Display("Dein " + bUnit.unit.UnitName + " ist am Zug"); } else { bNotification.Display("Gegnerische " + bUnit.unit.UnitName + " ist am Zug"); } yield return(new WaitForSeconds(2f)); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
public void SetupRound() { currentRound.Clear(); foreach (Unit unit in activeUnits) { unit.ResetTurn(); currentRound.Enqueue(unit); } // count rounds round++; turn = 0; EventProxyManager.FireEvent(this, new RoundSetupEvent(currentRound.ToList <Unit>())); }
public void SpawnUnit(MapTile mapTile, Unit.Team team, string name) { // IMPORTANT! Keep refence synced Unit unit = new Unit(); unit.mapTile = mapTile; mapTile.unit = unit; unit.Init(); unit.team = team; if (Unit.Team.AI == team) { unit.ai = new AIHunter(this, controller, unit); } // add unit to list units.Add(unit); // unit is spawned EventProxyManager.FireEvent(this, new UnitSpawnedEvent(unit)); }
void Init(MapTile[][] mapTiles, Unit[] units) { // load database //GameData.LoadFromFile(); // register for logic important events EventProxyManager.RegisterForEvent(EventName.RoundSetup, HandleRoundSetup); EventProxyManager.RegisterForEvent(EventName.UnitDied, HandleUnitDied); EventProxyManager.RegisterForEvent(EventName.TurnStarted, HandleTurnStarted); // init model model = new Model(this); model.InitMap(mapTiles); model.InitUnits(units); // init pathFinder object pathFinder = new PathFinder(model.grid); pathFinder.Diagonals = false; pathFinder.PunishChangeDirection = false; pathFinder.SearchLimit = 9000; pathFinder.DebugFoundPath = true; pathFinder.DebugProgress = true; }
public void InitMap(MapTile[][] mapTiles) { // init 1st dimension this.mapTiles = mapTiles; // instantiate maptile from mapData // for (int i = 0; i < mapData.width; i++) { // // init 2nd dimension // mapTiles[i] = new MapTile[mapData.height]; // // for (int j = 0; j < mapData.height; j++) { // mapTiles[i][j] = new MapTile(i,j); // mapTiles[i][j].Penalty = mapData.penalties[i][j]; // } // } grid = new byte[mapTiles.Length, mapTiles[0].Length]; UseMoveGrid(); // map is now initiliazed EventProxyManager.FireEvent(this, new MapInitializedEvent(mapTiles)); }
/// <summary> /// Checks every unit's hp and calls the death event if necessary. /// </summary> public void CheckForDeadUnits() { List <Unit> deadUnits = new List <Unit>(); foreach (Unit unit in activeUnits) { if (!unit.Alive) { // add to deceased units deadUnits.Add(unit); // remove target from map unit.mapTile.unit = null; // fire event EventProxyManager.FireEvent(this, new UnitDiedEvent(unit)); } } foreach (Unit deceased in deadUnits) { activeUnits.Remove(deceased); } }
public void Execute() { // get next unit from queue Unit unit = model.combat.GetNextUnit(); // increase turn counter model.combat.turn++; // immedialty end turn if unit is already dead if (!unit.Alive) { controller.EndTurn(); return; } // execute field effect for all unit foreach (Unit u in model.units) { if (u.mapTile.topping != null) { u.mapTile.topping.OnStayEffect(u); } } model.combat.CheckForDeadUnits(); // check again if this unit is dead (might have died from field effects) if (!unit.Alive) { controller.EndTurn(); return; } // activate next unit model.ActivateUnit(unit); EventProxyManager.FireEvent(this, new TurnStartedEvent(unit, model.combat.round, model.combat.turn)); }
public void LoseHealth(int damage) { currentHealth -= damage; EventProxyManager.FireEvent(EventName.UnitLoseHealth, new UnitLoseHealthEvent(this, damage)); }
public void Execute() { // auto set attack target for range 0 attack // helps AI to perfome rang 0 attacks if (attack.range == 0) { target = source.mapTile; } // quite early if source unit is not allowed to attack or target is out of range if (!source.CanAttack || AttackDistance(source.mapTile, target) > attack.range) { return; } // lower attack resource on source unit // so it can't attack again this turn source.AttackPoints = 0; float hit = (float)new Random().NextDouble(); int damageUnit = 0; byte efficency = 1; float typeModifier = 1; // check hit chance if (attack.hitChance < hit) { return; } // attack is succesfull // apply damage to all unit in attack area // don't trigger the toppings right away, otherwise breaking oil vases would ignite right away in most cases List <KeyValuePair <MapTile, Topping> > affectedToppings = new List <KeyValuePair <MapTile, Topping> >(); // to be secure we make a list of already checked mapTiles, so the recusion will not be endless List <Vector> checkedMapTiles = new List <Vector>(); int x = 0; int y = 0; List <Unit> victims = new List <Unit>(); List <int> damage = new List <int>(); Vector rotDir = new Vector(target.x - source.mapTile.x, target.y - source.mapTile.y); // make sure the direction for the attack is one of the four standart direcitons rotDir.NormalizeTo4Direction(); int[,] rot = Vector.RotateToMatrix(rotDir); // perform attack for eacht field in the attack area foreach (Vector pt in attack.area) { // apply rotation to field Vector rotPt = pt.Clone(); if (rotDir != Vector.zero) { rotPt.ApplyMatrix(rot); } x = target.x + rotPt.x; y = target.y + rotPt.y; // check if field is inside grid if (model.IsPointOnGrid(new Vector(x, y))) { // do attack effect on mapTile if (model.mapTiles[x][y].topping != null) { //recursivly check all neighbour fields if they are of the same topping type RecursivlyEffectToppings(model.mapTiles[x][y], attack, ref checkedMapTiles, ref affectedToppings); } // check field for units if (model.mapTiles[x][y].unit != null) { Unit unit = model.mapTiles[x][y].unit; // calculate and apply damage to unit typeModifier = CalcTypeModifier(attack, unit); efficency = (byte)((typeModifier > 1f) ? 2 : (typeModifier == 1f) ? 1 : 0); damageUnit = CalcDamage(source.Attack, attack.damage, typeModifier); // add to list of hit units victims.Add(unit); damage.Add(damageUnit); } } } // apply the attack effect to all hit toppings foreach (KeyValuePair <MapTile, Topping> pair in affectedToppings) { // check that the topping still exists and wasn't destroyed by a neighbouring topping if (pair.Key.topping == pair.Value) { pair.Value.OnAttackEffect(attack, model); } } EventProxyManager.FireEvent(this, new UnitAttackedEvent(attack, source, target, victims, efficency, damage)); for (int i = 0; i < victims.Count; i++) { victims[i].LoseHealth(damage[i]); } // when target died fire event AFTER attack was performed this.model.combat.CheckForDeadUnits(); }
public void ActivateUnit(Unit unit) { activeUnit = unit; EventProxyManager.FireEvent(this, new UnitActivatedEvent(unit)); }
void HandleBMapTileTapped(object sender, EventArgs args) { // forward maptile to active unit BMapTileTappedEvent e = args as BMapTileTappedEvent; // handle taps while moveing if (activeBUnit.CurrentAction == BUnit.Action.MOVE || activeBUnit.CurrentAction == BUnit.Action.CONFIRMMOVE) { if (e.bMapTile.colorState == BMapTile.ColorState.PATH) { if (e.bMapTile == activeBUnit.Target) { activeBUnit.SetMoveTarget(new Path(new MapTile[] { e.bMapTile.mapTile })); } EventProxyManager.FireEvent(this, new EventDoneEvent()); return; } if (e.bMapTile.Clickable) { // ignore the active unit on the grid, since it is the one who will move byte[,] grid = controller.model.grid; grid[activeBUnit.unit.mapTile.x, activeBUnit.unit.mapTile.y] = 1; // calculate path with new grid Path path = controller.GetPath(activeBUnit.path.Last, e.bMapTile.mapTile, grid); activeBUnit.SetMoveTarget(path); } else { activeBUnit.CancleTargetSelection(); } } else { if (e.bMapTile.Clickable) { activeBUnit.SetAttackTarget(e.bMapTile); } } // check unit on the field for beeing the active unit if (e.bMapTile.mapTile.unit != null) { BUnit bUnit = GetBUnit(e.bMapTile.mapTile.unit); if (bUnit == activeBUnit && bUnit.CurrentAction != BUnit.Action.CONFIRMATTACK) { bUnit.PopupCombatMenu(); } } else { // while beeing in move-mode; close menu on mapTile click if (activeBUnit.CurrentAction != BUnit.Action.ATTACK) { Debug.Log("dont hide back button"); } //bCombatMenu.Hide(); } EventProxyManager.FireEvent(this, new EventDoneEvent()); }
void Init() { performingEvent = true; // register event EventProxyManager.RegisterForEvent(EventName.Initialized, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitSpawned, HandleEvent); EventProxyManager.RegisterForEvent(EventName.RoundSetup, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitActivated, HandleEvent); EventProxyManager.RegisterForEvent(EventName.TurnStarted, HandleEvent); EventProxyManager.RegisterForEvent(EventName.BMapTileTapped, HandleEvent); EventProxyManager.RegisterForEvent(EventName.BUnitTapped, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitMoved, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitAttacked, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitLoseHealth, HandleEvent); EventProxyManager.RegisterForEvent(EventName.UnitDied, HandleEvent); EventProxyManager.RegisterForEvent(EventName.ToppingSpawned, HandleEvent); EventProxyManager.RegisterForEvent(EventName.ToppingDestroyed, HandleEvent); EventProxyManager.RegisterForEvent(EventName.Gameover, HandleEvent); EventProxyManager.RegisterForEvent(EventName.EventDone, HandleEventDone); EventProxyManager.RegisterForEvent(EventName.DebugLog, HandleDebugLog); // find scene references bCombatMenu = GameObject.FindObjectOfType <BCombatMenu>(); bInputManager = GameObject.FindObjectOfType <BInputManager>(); bCameraMover = GameObject.FindObjectOfType <BCameraMover>(); // instatiate marker unitMarker = (GameObject)Instantiate(bActiveMarkerPrefab); MapTile[][] mapTiles = new MapTile[bMap.lengthX][]; for (int i = 0; i < bMap.lengthX; i++) { mapTiles[i] = new MapTile[bMap.lengthY]; for (int j = 0; j < bMap.lengthY; j++) { bMap[i, j].UpdateTopping(); // this is required to tranfer the topping data to the mapTile mapTiles[i][j] = bMap[i, j].mapTile; } } BUnit[] startBUnits = GameObject.FindObjectsOfType <BUnit>(); bUnits = new List <BUnit>(); Unit[] units = new Unit[startBUnits.Length]; for (int i = 0; i < units.Length; i++) { // add units from scene to an array units[i] = startBUnits[i].unit; // set maptile reference by scene position int x = Mathf.FloorToInt(startBUnits[i].transform.position.x); int y = Mathf.FloorToInt(startBUnits[i].transform.position.z); units[i].mapTile = mapTiles[x][y]; mapTiles[x][y].unit = units[i]; // add bUnit to list startBUnits[i].Init(this, bCombatMenu); bUnits.Add(startBUnits[i]); } // start the game controller = new Controller(this, mapTiles, units); EventProxyManager.FireEvent(this, new EventDoneEvent()); }
/// <summary> /// Remove this Topping from the game. /// </summary> public void Destroy() { this.mapTile.topping = null; EventProxyManager.FireEvent(this, new ToppingDestroyedEvent(this)); }
public void OnDestroy() { // unregister from all Events EventProxyManager.Clear(); }
/// <summary> /// Place this instance on a MapTile. /// </summary> /// <param name="mapTile">The parent MapTile where to spawn</param> public void Spawn(MapTile mapTile) { this.mapTile = mapTile; EventProxyManager.FireEvent(this, new ToppingSpawnEvent(this)); }
void HandleInitialized(object sender, EventArgs args) { InstatiateMap((args as MapInitializedEvent).mapTiles); EventProxyManager.FireEvent(this, new EventDoneEvent()); }