Personal Project, Unity, C#, Only Developer
Twilight's Call DungeonCrawler is a DungeonCrawler based on games such as Mary Skelter and Shin Megami Tensei Strange Journey.

Combat

Twilight's Call DungeonCrawler uses a variation of the press turn system popularised by Shin Megami Tensei Nocturne. Hitting the enemys weakness will give you more turns but hitting the enemys strength will make you lose your turns. The combat moves in a much more fervent pace and was a great choice to create engaging combat.

                        
public class Attack : Skills
{



    public override void Start()
    {

        m_ElementalType = ElementalType.Null;
        m_SkillType = SkillType.Attack;
        m_Damagetype = DamageType.Strength;
        m_Damage = 110;
        m_SkillName = "Attack";
        m_SkillDescription = "Attack a single enemy";
        m_AnimationName = "t_IsAttack";
        m_SkillRange = 1;
    }

    // Update is called once per frame

    public override List UseSkill(List aVictum, Creatures aAttacker )
    {
        List AllSkillActions = new List();

        for (int i = 0; i < aVictum.Count; i++)
        {
            AllSkillActions.Add(aVictum[i].DecrementHealth(m_Damage + aAttacker.GetAllStrength() / 3, GetElementalType(),
                0.1f, 0.1f, 1));
        }

        return AllSkillActions;
    }
    
    public override IEnumerator UseSkill(Creatures aVictum, Creatures aAttacker )
    {
        return aVictum.DecrementHealth(m_Damage + aAttacker.GetAllStrength() /3, GetElementalType(),
            0.1f, 0.1f, 1);
    }
}


//Skill Execution Manager

    public void ExecuteSkill(Skills aSkill, bool aSkillRange,int aSkillPosition, Creatures aAttacker)
    {
        aAttacker.CurrentMana -= aSkillRange ? aSkill.m_MultiTargetCost : aSkill.m_SingleTargetCost;
        
        //Single Target Attack
        if (aSkill.m_SkillType == Skills.SkillType.Attack && !aSkillRange)
        {
            SingleTargetAttack(aSkill, aAttacker, aSkillPosition);
        }

        //Party Wide Attacks
        if (aSkill.m_SkillType == Skills.SkillType.Attack && aSkillRange)
        {
            PartyWideAttack(aSkill, aAttacker);
        }
        
        // Single target Heals
        if (aSkill.m_SkillType == Skills.SkillType.Heal && !aSkillRange)
        {
            SingleTargetHeal(aSkill, aAttacker, aSkillPosition);
        }
        
        // Party Wide Heals
        if (aSkill.m_SkillType == Skills.SkillType.Heal && aSkillRange)
        {
            PartyWideHeal( aSkill,  aAttacker);
        }
        
        // Single target Heals
        if (aSkill.m_SkillType == Skills.SkillType.Buff && !aSkillRange)
        {
            SingleTargetBuff(aSkill, aAttacker, aSkillPosition);
        }
        
        // Party Wide Heals
        if (aSkill.m_SkillType == Skills.SkillType.Buff && aSkillRange)
        {
            PartyWideBuff( aSkill,  aAttacker);
        }
    }
  
  
  
 //Press Turn Manager
 
    //This method will be used at the end when all is activated
    public void ProcessTurn(List aAllTurnReactions)
    {
        

        //Null Skills Consume all pressturns completely

        foreach (PressTurnReactions reaction in aAllTurnReactions)
        {
            if (reaction == PressTurnReactions.Null)
            {
                NulledPressTurn();
                return;
            }
        }
        
        
        //If Dodged Consume two pressturns if empowered only take the empowered and the next token
        
        foreach (PressTurnReactions reaction in aAllTurnReactions)
        {
            if (reaction == PressTurnReactions.Dodge ||
                reaction == PressTurnReactions.Strong )
            {
                DodgedPressTurn();
                return;
            }
        }
        
        //If weakness is hit correctly then the turn that was used will be empowered
        
        foreach (PressTurnReactions reaction in aAllTurnReactions)
        {
            if (reaction == PressTurnReactions.Weak || 
                reaction == PressTurnReactions.Pass)
            {
                WeaknessPressTurn();
                return;
            }
        }
        
        
        //Normal action Consume 1 empowered or normal pressturn
        NormalPressTurn();
        //Passing will turn a whole icon into a empowered one but will consume an empowered one if it is

    }



                        
                    
                        
	 
// This is the array that contains the floor, each number represents an avaliable direction

     short tableinit[] =
        {
            0, 10, 15,  9, 10, 15,  9,  0,  2,  0,  0,  0,  0,  0,  0,  4, 11, 15,  3,  0, //1
            4,  5,  5, 13, 14,  5,  5, 15,  5,  9, 11, 11, 11, 11, 11, 15,  9, 14, 11,  3, //2
            0,  8,  5, 13,  8, 12,  7,  8,  5,  7,  0,  0,  0,  0,  0,  8, 13,  6,  0,  0, //3
            10, 11, 7,  6,  0,  0,  0,  0,  6,  0,  0,  0,  0, 10, 15,  9,  6, 14, 15,  9, //4
            6, 10, 15, 13,  0, 10,  9, 10,  5,  9, 10,  9,  0, 14,  5, 13,  6,  8,  5,  7, //5
            6, 14, 12, 13,  2, 14,  5,  5,  5,  5,  5, 13,  0,  8,  5,  7,  6, 10,  5,  9, //6
            6,  6,  0,  6,  6,  8,  7, 14,  5, 13,  8,  7,  0,  0, 14, 15, 13, 14,  5, 13, //7
            6,  6,  0,  6,  6, 10,  9, 14,  5, 13, 10,  9,  0,  0,  8, 12, 13,  6,  6,  6, //8
            6,  6,  0,  6,  6, 14,  5,  5,  5,  5,  5, 13,  0,  2, 10,  9,  8,  7,  6,  6, //9
            6,  6,  0,  6,  6,  8,  7, 14,  5, 13,  8,  7,  0, 14,  5,  5, 11, 11,  7,  6, //10
            6,  6,  0,  6,  6, 10,  9, 14,  5, 13, 10,  9,  0,  6,  8,  7, 10, 15,  9,  6, //11
            6, 14, 15,  5, 13, 14,  5,  5,  5,  5,  5, 13,  0,  6, 10,  9,  6,  8,  7,  6, //12
            6,  8, 12,  7,  1,  8,  7,  8,  5,  7,  8,  7,  0,  6,  8,  7,  5, 11,  9,  6, //13
            8, 11, 15,  9,  0,  0,  4, 15,  5, 15,  3,  0,  0,  8,  9,  4, 13, 10, 13,  6, //14
            10, 9, 14, 13,  0,  0,  0,  8,  5,  7,  0,  0,  0,  0, 14,  9,  6,  8,  7,  6, //15
            8, 12, 12, 12, 11, 11, 11, 11, 12, 11, 11, 11, 15,  3, 14,  7,  8, 11, 11,  7, //16
            0,  0,  0,  0,  0, 10,  9,  0,  0,  0,  0, 10,  5,  9,  8, 11, 11,  9,  0,  0, //17
            0,  0,  0,  0,  0, 14,  5, 11, 15, 11, 11, 12,  5,  7,  0,  2,  0,  6,  0,  2, //18
            0,  0,  0,  0,  0,  8,  7, 10,  5,  9, 10, 15, 13,  0,  0, 14, 11, 12, 11,  7, //19
            0,  0,  0,  0,  0,  0,  0,  8, 12,  7,  8,  7,  1,  0,  0,  1,  0,  0,  0,  0  //20
        //  1   2   3   4   5   6   7   8   9  10  11   12  13  14  15  16  17  18  19  20
        }; 
		
// Floor Generator

    public void SetLevelNodes(short[] aLevelBlueprint)
    {
        for (int x = 0; x < m_FloorCore.GridDimensionX; x++)
        {
            for (int y = 0; y < m_FloorCore.GridDimensionY; y++)
            {
                int LevelIndex = m_FloorCore.GetIndex(x, y);
                //If there is no node then continue
                if (aLevelBlueprint[LevelIndex] == (short) Floor.LevelCreationDirections.Empty)
                {
                    continue;
                }

                SpawnNode(x , y,LevelIndex );
                
                m_FloorNodes[LevelIndex].Initialize(aLevelBlueprint[LevelIndex]);
            }
        }
    
    }
	
	
	public void SpawnNode(int aRow, int aColumn,int aIndex)
    {

        FloorNode tempFloorNode = Instantiate(m_FloorNodePrefab);
         
        m_FloorNodes[aIndex] =  tempFloorNode;

        m_FloorNodes[aIndex].m_PositionInGrid = new Vector2Int(aRow,aColumn);
        m_FloorNodes[aIndex].gameObject.transform.parent = transform;
        m_FloorNodes[aIndex].gameObject.name  = aRow + " " + aColumn;
        m_FloorNodes[aIndex].transform.position = new Vector3(4 * aRow, 0.5f, 4 * aColumn);
        m_FloorNodes[aIndex].m_NodeFloorManager = this;

        //  m_GridPathArray[x, y].m_Grid = m_Grid;
    }
	
	
//This function was shortened for the sake of it being an example	
	public void SetWalkableDirections(short aWalkabledirections)
	{
	switch (aWalkabledirections)
	{
		case  CardinalNodeDirections::Up:
			m_WalkableDirections.Add( CardinalNodeDirections::Up);
		break;

		case CardinalNodeDirections::Down:
			m_WalkableDirections.Add( CardinalNodeDirections::Down);
		break;

		case  CardinalNodeDirections::Left:
			m_WalkableDirections.Add( CardinalNodeDirections::Left);
		break;

		case  CardinalNodeDirections::Right:
			m_WalkableDirections.Add( CardinalNodeDirections::Right);
		break;

		case  CardinalNodeDirections::AllSidesOpen:
            m_WalkableDirections.Add( CardinalNodeDirections::Up);
            m_WalkableDirections.Add( CardinalNodeDirections::Down);
            m_WalkableDirections.Add( CardinalNodeDirections::Right);
            m_WalkableDirections.Add( CardinalNodeDirections::Left);
        break;
	}
	
	SetLevelNode(m_WalkableDirections);
	}
	
                        
                    

Level Editor

Each level is created with multiple Floors. Each floor is created using tools I have setup to make the entire system modular. Levels are generated in a grid and each number represents the amount of directions avaliable for the node. This is done to modularly set up the player so it knows what directions is it can go to.

Gallery