SRPG游戏开发(五十七)第十一章 地图动作与地图事件 - 六 地图事件的条件(Condition of Map Event)

版权声明:本文为博主原创文章,未经允许不得转载。 https://blog.csdn.net/darkrabbit/article/details/87918385

返回总目录

第十一章 地图动作与地图事件(Map Action and Map Event)

我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制。

我们这一章来完成地图上的操作,地图的操作将全部由MapAction控制。



六 地图事件的条件(Condition of Map Event)

地图事件是我们地图中所发生的事情,包括:

  • 触发条件;

  • 触发结果。

它也比较常见,例如:

条件 结果 FE4中实例
地图开始 创建各种地图对象 战斗开始时的剧情,然后创建地图对象
角色到达某个地点 获取物品 第一章时斧骑士到达海边获取二回攻击斧
某回合开始 创建各种地图对象 某些剧情需要
对应角色对话 获取物品、提升属性等 某些章节对话

等等诸如此类的事件。

这一节,我们挑选一些典型的事件来说明。


1 条件类(Class Condition)

每一个事件,大多需要一些条件才能触发,这就需要我们知道这些条件是什么。

且每个事件需要的条件可能是多种,但都需要一个进入的条件(主条件),其它为子条件。

首先,我们先来归类一下条件类型:

创建一个枚举MapEventConditionType来表示条件类型(它们不是必须的,按需来):

using System;

namespace DR.Book.SRPG_Dev.ScriptManagement
{
    [Serializable]
    public enum MapEventConditionType
    {
        NoneCondition = 0,

        /// <summary>
        /// 回合
        /// </summary>
        TurnCondition,

        /// <summary>
        /// 位置
        /// </summary>
        PositionCondition,

        /// <summary>
        /// 角色id
        /// </summary>
        RoleCondition,

        /// <summary>
        /// 属性
        /// </summary>
        PropertyCondition,

        /// <summary>
        /// 角色死亡
        /// </summary>
        RoleDeadCondition,

        /// <summary>
        /// 对话
        /// </summary>
        RoleTalkCondition,

        /// <summary>
        /// 战斗对话
        /// </summary>
        RoleCombatTalkCondition,

        /// <summary>
        /// 物品
        /// </summary>
        ItemCondition
    }
}

这些条件并不都是进入条件,我们规定:

  • NoneCondition:没有条件,进入地图时触发;

  • TurnCondition:回合条件,当回合开始时触发;

  • PositionCondition:位置条件,当角色到达此坐标时触发,常与RoleCondition连用;

  • RoleCondition:角色条件,不是主条件,常做为其它条件的子条件使用;

  • PropertyCondition:属性条件,不是主条件,常做为其它条件的子条件使用;

  • RoleDeadCondition:死亡条件,角色死亡时触发;

  • RoleTalkCondition:对话条件,两个角色有对话时触发,常与TurnCondition连用(在某些回合范围内可对话);

  • RoleCombatTalkCondition:战斗对话条件,两个角色发生战斗时触发;

  • ItemCondition:物品条件,不是主条件,常做为其它条件的子条件使用(例如(不)持有某些物品时)。

这以上只是一些常见条件,都是按需。它们有些只能触发一次,而有些可以触发多次(例如《FE4》中的教会)。

我在这里依然选择了xml作为保存它们的文件类型。

而这些条件需要返回一个布尔类型,来表示条件是否满足。

创建类:

        [Serializable]
        public class Condition
        {
            [XmlIgnore]
            public virtual MapEventConditionType type
            {
                get { return MapEventConditionType.NoneCondition; }
            }

            public virtual bool GetResult(MapAction action)
            {
                return true;
            }
        }

2 回合条件(Turn Condition)

在回合条件中,我们在只有在此回合内才能触发,所以它需要:

  • 最小回合;

  • 最大回合;

  • 回合内的阵营。

只有在阵营对应且在当前回合比最小回合大,比最大回合小时才会触发。

        [Serializable]
        public class TurnCondition : Condition
        {
            [XmlAttribute]
            public int minTurn;
            [XmlAttribute]
            public int maxTurn;
            [XmlAttribute]
            public bool allAttitudeTowards;
            [XmlAttribute]
            public AttitudeTowards attitudeTowards;

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.TurnCondition; }
            }

            public sealed override bool GetResult(MapAction action)
            {
                if (!allAttitudeTowards && action.turn != attitudeTowards)
                {
                    return false;
                }

                int turn = action.turnToken;
                // 如果最大回合数小于0,则只取最小回合
                if (maxTurn < 0)
                {
                    return turn >= minTurn;
                }

                return turn >= minTurn && turn <= maxTurn;
            }
        }

3 位置条件(Position Condition)

只有当角色到达这一位置时才会触发。

        [Serializable]
        public class PositionCondition : Condition
        {
            [XmlAttribute]
            public int x;
            [XmlAttribute]
            public int y;

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.PositionCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                if (action.selectedUnit == null)
                {
                    return false;
                }
                Vector3Int position = action.selectedUnit.cellPosition;
                return position.x == x && position.y == y;
            }
        }

4 角色条件与角色死亡条件(Role (Dead) Condition)

只有是这个角色时,才会触发。

        [Serializable]
        public class RoleCondition : Condition
        {
            [XmlAttribute]
            public int characterId;

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.RoleCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                if (action.selectedUnit == null)
                {
                    return false;
                }

                Role role = action.selectedUnit.role;
                if (role.roleType == RoleType.Following)
                {
                    return false;
                }

                return role.characterId == characterId;
            }
        }

而角色死亡条件是只有当角色死亡时触发。

        [Serializable]
        public class RoleDeadCondition : RoleCondition
        {
            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.RoleDeadCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                // 必须先存在此角色
                RoleModel model = ModelManager.models.Get<RoleModel>();
                if (!model.ContainsKey(this.characterId))
                {
                    return false;
                }

                return model.GetOrCreateRole(this.characterId, RoleType.Unique).isDead;
            }
        }

5 对话条件与战斗对话条件(Role (Combat) Talk Condition)

对话条件,在角色条件的基础上,增加了目标角色,只有双方都对应才能有对话。

        [Serializable]
        public class RoleTalkCondition : RoleCondition
        {
            [XmlAttribute]
            public int targetId;

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.RoleTalkCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                if (action.selectedUnit == null 
                    || action.targetUnit == null
                    || action.selectedUnit.role.roleType != RoleType.Unique
                    || action.targetUnit.role.roleType != RoleType.Unique)
                {
                    return false;
                }

                if (action.selectedUnit.role.characterId != characterId
                    || action.targetUnit.role.characterId != targetId)
                {
                    return false;
                }

                return true;
            }
        }

而战斗对话,只要是双方的角色就会触发。

        [Serializable]
        public class RoleCombatTalkCondition : RoleTalkCondition
        {
            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.RoleCombatTalkCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                if (action.selectedUnit == null
                    || action.targetUnit == null
                    || action.selectedUnit.role.roleType != RoleType.Unique
                    || action.targetUnit.role.roleType != RoleType.Unique)
                {
                    return false;
                }

                if ((action.selectedUnit.role.characterId == characterId
                    && action.targetUnit.role.characterId == targetId)
                    || (action.selectedUnit.role.characterId == targetId
                    && action.targetUnit.role.characterId == characterId))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

6 属性条件(Property Condition)

我们选择的角色中,某些属性在范围内就触发。

        [Serializable]
        public class PropertyCondition : Condition
        {
            [XmlAttribute]
            public FightPropertyType propertyType;
            [XmlAttribute]
            public int minValue;
            [XmlAttribute]
            public int maxValue;

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.PropertyCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                if (action.selectedUnit == null)
                {
                    return false;
                }

                Role role = action.selectedUnit.role;
                FightProperties fightProperties = role.fightProperties;
                return fightProperties[propertyType] >= minValue 
                    && fightProperties[propertyType] <= maxValue;
            }
        }

7 物品条件(Item Condition)

我们角色持有或者不持有某物品触发。

        [Serializable]
        public class ItemCondition : Condition
        {
            [XmlAttribute]
            public int characterId = -1;
            [XmlAttribute]
            public int itemId;
            [XmlAttribute]
            public bool hold; // 是否持有

            [XmlIgnore]
            public override MapEventConditionType type
            {
                get { return MapEventConditionType.ItemCondition; }
            }

            public override bool GetResult(MapAction action)
            {
                Role role;
                if (characterId < 0)
                {
                    if (action.selectedUnit == null)
                    {
                        return false;
                    }
                    role = action.selectedUnit.role;
                    if (role.roleType == RoleType.Following)
                    {
                        return false;
                    }
                }
                else
                {
                    RoleModel model = ModelManager.models.Get<RoleModel>();
                    if (!model.ContainsKey(characterId))
                    {
                        return false;
                    }
                    role = model.GetOrCreateRole(characterId, RoleType.Unique);
                }

                Item[] items = role.items;
                bool hasItem = items.Any(item => item != null && item.itemId == itemId);

                return hasItem == hold;
            }
        }

猜你喜欢

转载自blog.csdn.net/darkrabbit/article/details/87918385