// todo: potentially, method can hang - for example when 2x2 heroes / enemies are in the corner and the starting position is there as well // workaround: make radius scale public Vector2i FindValidPosition(Vector2i sPos, HashSet <LevelData.GemEffectType> validTypes, int excludeColor) { Vector2i gridPos = sPos; int i = 0; while (true) { if (Grid.Valid(gridPos)) { LevelData.GemTypeInfo gti = GameManager.Instance.LevelData.GetGemTypeInfo(Get(gridPos).GetGemType()); if (validTypes.Contains(gti._effectType) && (!gti._colored || gti._effectData != excludeColor)) { return(gridPos); } } int span = 1, mod = 3; if (i > 9) { span = 2; mod = 5; } gridPos.x = sPos.x - span + i % mod; gridPos.y = sPos.y - span + i / mod; i++; } }
public List <Vector2i> DetectMatchedGems(bool[,] matched, LevelData.GemEffectType effectType) { List <Vector2i> list = null; Vector2i gridPos; for (gridPos.x = 0; gridPos.x < Constants.FIELD_SIZE_X; gridPos.x++) { for (gridPos.y = 0; gridPos.y < Constants.FIELD_SIZE_Y; gridPos.y++) { if (matched[gridPos.x, gridPos.y]) { Gem gem = _grid[gridPos.x, gridPos.y]._script; LevelData.GemTypeInfo ti = _levelData.GetGemTypeInfo(gem.GetGemType()); if (ti._effectType == effectType) { if (list == null) { list = new List <Vector2i>(); } list.Add(gridPos); } } } } return(list); }
static void ApplyCross(List <Vector2i> crossList, bool[,] matched, Vector2i pos) { Gem gem = GameManager.Instance.Grid.Get(pos); LevelData.GemTypeInfo ti = GameManager.Instance.LevelData.GetGemTypeInfo(gem.GetGemType()); if (ti._effectType == LevelData.GemEffectType.ET_ENEMY) { if (!gem.IsDead()) { Figure figure = GameManager.Instance.EnemyManager.GetEnemyAtIndex(gem.GetData()); figure.ActionPoints -= GameManager.Instance.LevelData.GetCrossDamage(); if (figure.GetGemScript().IsDead()) { matched[pos.x, pos.y] = true; } StartCoroutine(Effects.Sparkle(GameManager.Instance.Definitions.CrossEnemyTime, GameManager.Instance.Definitions.ParticleCrossEnemy, figure.transform.position)); } } else if (ti._effectType != LevelData.GemEffectType.ET_HERO) { if (ti._effectType == LevelData.GemEffectType.ET_GEM_CROSS && !crossList.Contains(pos)) { crossList.Add(pos); } matched[pos.x, pos.y] = true; } }
private bool CheckMatch(int type1, int type2) { LevelData.GemTypeInfo ti1 = _levelData.GetGemTypeInfo(type1); LevelData.GemTypeInfo ti2 = _levelData.GetGemTypeInfo(type2); if (ti1._colored && ti2._colored && ti1._effectData == ti2._effectData) { return(true); } if (ti1._effectType == LevelData.GemEffectType.ET_GEM_HEALTH && ti2._effectType == LevelData.GemEffectType.ET_GEM_HEALTH) { return(true); } if (ti1._effectType == LevelData.GemEffectType.ET_GEM_COIN && ti2._effectType == LevelData.GemEffectType.ET_GEM_COIN) { return(true); } return(false); }
public void Log() { if (Application.isEditor) { string str = ""; for (int y = 0; y < Constants.FIELD_SIZE_Y; y++) { for (int x = 0; x < Constants.FIELD_SIZE_X; x++) { LevelData.GemTypeInfo gi = GameManager.Instance.LevelData.GetGemTypeInfo(_grid[x, y]._script.GetGemType()); int data = gi._effectData; if (data > 9) { data = 0; } str += effectStr[(int)gi._effectType] + data.ToString() + " "; } str += "\n"; } Debug.Log(str); } }
static void CreateSpecialGems(ref bool[,] matched, Directions dir, Vector2i?lastPos) { int[,] matchMap = new int[Constants.FIELD_SIZE_X, Constants.FIELD_SIZE_Y]; int[,] specialGems = new int[Constants.FIELD_SIZE_X, Constants.FIELD_SIZE_Y]; Vector2i mapPos; int mapData; for (mapPos.x = 0; mapPos.x < Constants.FIELD_SIZE_X; mapPos.x++) { for (mapPos.y = 0; mapPos.y < Constants.FIELD_SIZE_Y; mapPos.y++) { if (matched[mapPos.x, mapPos.y]) { LevelData.GemTypeInfo gti = GameManager.Instance.LevelData.GetGemTypeInfo(GameManager.Instance.Grid.Get(mapPos).GetGemType()); mapData = gti._colored ? gti._effectData : -1; } else { mapData = -1; } matchMap[mapPos.x, mapPos.y] = mapData; specialGems[mapPos.x, mapPos.y] = -1; } } if (lastPos != null) { Vector2i pos = lastPos.Value; CreateSpecialGem(ref matchMap, ref matched, pos); pos = lastPos.Value + directionVectors[(int)dir]; DebugUtils.Assert(Grid.Valid(pos)); CreateSpecialGem(ref matchMap, ref matched, pos); } int start = -1, startType = -1, best = -1, bestGem = -1; for (mapPos.x = 0; mapPos.x < Constants.FIELD_SIZE_X; mapPos.x++) { for (mapPos.y = 0; mapPos.y < Constants.FIELD_SIZE_Y; mapPos.y++) { if (start == -1) { if (matchMap[mapPos.x, mapPos.y] != -1) { start = mapPos.y; startType = matchMap[mapPos.x, mapPos.y]; bestGem = -1; best = mapPos.y; } } if (start != -1) { if (matchMap[mapPos.x, mapPos.y] == startType) { int gem = DetectSpecialGem(ref matchMap, mapPos, false); if (gem > bestGem) { bestGem = gem; best = mapPos.y; } } else { start = -1; specialGems[mapPos.x, best] = bestGem; mapPos.y--; } } } if (start != -1) { specialGems[mapPos.x, best] = bestGem; start = -1; } } for (mapPos.y = 0; mapPos.y < Constants.FIELD_SIZE_Y; mapPos.y++) { for (mapPos.x = 0; mapPos.x < Constants.FIELD_SIZE_X; mapPos.x++) { if (start == -1) { if (matchMap[mapPos.x, mapPos.y] != -1) { start = mapPos.x; startType = matchMap[mapPos.x, mapPos.y]; bestGem = -1; } } if (start != -1) { if (matchMap[mapPos.x, mapPos.y] == startType) { int gem = specialGems[mapPos.x, mapPos.y]; if (gem > bestGem) { bestGem = gem; best = mapPos.x; } } else { start = -1; CreateSpecialGem(ref matchMap, ref matched, new Vector2i(best, mapPos.y)); mapPos.x--; } } } if (start != -1) { CreateSpecialGem(ref matchMap, ref matched, new Vector2i(best, mapPos.y)); start = -1; } } }
public IEnumerator PowerAttack() { float pulseTime = GameManager.Instance.Definitions.PulseTime; ResetPowerCharge(); yield return(StartCoroutine(Scale(pulseTime))); switch (_power._type) { case LevelData.Power.Types.DAMAGE: StartCoroutine(Effects.Pulse(GameManager.Instance.Definitions.PulseFlyTime, GameManager.Instance.Definitions.PulseFlyWaitTime, GameManager.Instance.Definitions.PulseHitTime, null, GameManager.Instance.Definitions.ParticlePowerDamageFly, GameManager.Instance.Definitions.ParticlePowerDamage, transform.position, GameManager.Instance.HUD.Health.GetBarCenter(), true)); yield return(new WaitForSeconds(GameManager.Instance.Definitions.PulseFlyWaitTime)); GameManager.Instance.HUD.Health.Add(-((int)(ActionPoints * _power._f + 0.5f) + _power._i)); yield return(new WaitForSeconds(GameManager.Instance.Definitions.PulseHitTime)); break; case LevelData.Power.Types.DAMAGE_FIGURES_SELF: case LevelData.Power.Types.DAMAGE_FIGURES_TARGET: { bool anyDead = false; int count = _hero ? GameManager.Instance.EnemyManager.GetEnemiesCount():GameManager.Instance.HeroManager.GetHeroesCount(); for (int i = 0; i < count; i++) { Figure figure = _hero ? GameManager.Instance.EnemyManager.GetEnemyAtIndex(i) : GameManager.Instance.HeroManager.GetHeroAtIndex(i); if (figure && !figure.GetGemScript().IsDead()) { yield return(StartCoroutine(Effects.Pulse(GameManager.Instance.Definitions.PulseFlyTime, GameManager.Instance.Definitions.PulseFlyWaitTime, GameManager.Instance.Definitions.PulseHitTime, null, GameManager.Instance.Definitions.ParticlePowerDamageFigureFly, GameManager.Instance.Definitions.ParticlePowerDamageFigure, transform.position, figure.transform.position, true))); int points = _power._type == LevelData.Power.Types.DAMAGE_FIGURES_SELF ? ActionPoints : figure.ActionPoints; figure.ActionPoints -= (int)(points * _power._f + 0.5f) + _power._i; anyDead |= figure.GetGemScript().IsDead(); } } if (anyDead) { yield return(StartCoroutine(Puzzle.CollapseField(Directions.Down, null))); } break; } case LevelData.Power.Types.ABSORB_GEMS: { bool any = false; for (int i = 0; i < _power._i; i++) { Vector2i gemPos = GameManager.Instance.Grid.FindNearest(_gem.GetGridPosition(), _power._et); if (gemPos.x == -1) { break; } StartCoroutine(Effects.Pulse(GameManager.Instance.Definitions.PulseFlyTime, GameManager.Instance.Definitions.PulseFlyWaitTime, GameManager.Instance.Definitions.PulseHitTime, GameManager.Instance.Definitions.ParticlePowerAbsorbHealthGem, GameManager.Instance.Definitions.ParticlePowerAbsorbHealthFly, GameManager.Instance.Definitions.ParticlePowerAbsorbHealth, GameManager.Instance.Grid.Get(gemPos).transform.position, transform.position, true)); yield return(new WaitForSeconds(pulseTime)); Gem gem = GameManager.Instance.Grid.Get(gemPos); gem.SetupFadeOut(pulseTime); yield return(StartCoroutine(Scale(pulseTime))); ActionPoints += _power._i2; gem.SetGemType(GameManager.Instance.LevelData.GetEmptyGemType()); gem.TweenColor(0, new Color(0, 0, 0, 0), Tweener.Method.EaseIn); gem.Die(); any = true; } if (any) { yield return(StartCoroutine(Puzzle.CollapseField(Directions.Down, null))); } break; } case LevelData.Power.Types.COLLECT_GEMS: { Vector2i gridPos; for (int j = 0; j < 4; j++) { for (int i = 1; i <= _power._i; i++) { gridPos = _gem.GetGridPosition() + Vector2i.Directions[j] * i; if (Grid.Valid(gridPos)) { Gem gem = GameManager.Instance.Grid.Get(gridPos); LevelData.GemEffectType et = GameManager.Instance.LevelData.GetGemTypeInfo(gem.GetGemType())._effectType; if (_hero && et == LevelData.GemEffectType.ET_ENEMY || !_hero && et == LevelData.GemEffectType.ET_HERO) { Figure figure = _hero ? GameManager.Instance.EnemyManager.GetAtPosition(gridPos) : GameManager.Instance.HeroManager.GetAtPosition(gridPos); figure.ActionPoints -= (int)((float)ActionPoints * _power._f) + _power._i2; StartCoroutine(Effects.Sparkle(pulseTime, GameManager.Instance.Definitions.ParticlePowerCollectGemEnemy, gem.transform.position)); } else if (et != LevelData.GemEffectType.ET_HERO) { gem.Die(); StartCoroutine(Effects.Sparkle(pulseTime, GameManager.Instance.Definitions.ParticlePowerCollectGem, gem.transform.position)); } } } } yield return(new WaitForSeconds(pulseTime)); yield return(StartCoroutine(Puzzle.CollapseField(Directions.Down, null))); break; } case LevelData.Power.Types.TRANSFORM_RANDOM_GEMS: { Vector2i pos; Coroutine c = null; LevelData.GemTypeInfo gti = GameManager.Instance.LevelData.GetGemTypeInfo(_power._i2); int excludeColor = gti._colored ? gti._effectData : -1; for (int j = 0; j < _power._i; j++) { pos = GameManager.Instance.Grid.FindValidPosition(Grid.RandomGridPosition(), LevelData.GetBasicGemTypes(), excludeColor); c = StartCoroutine(GameManager.Instance.Grid.Get(pos).ChangeGemType(_power._i2, GameManager.Instance.Definitions.ParticlePowerTransformGem)); yield return(new WaitForSeconds(GameManager.Instance.Definitions.TransformGemWaitTime)); } yield return(c); yield return(StartCoroutine(Puzzle.CollapseField(Directions.Down, null))); break; } } }