Правильная реализация заданий для игрока
Всем привет. Помогите советом или примером.
Хочу реализовать миссии(а ля сюжетка) и заказы(типа побочные задания). Миссии имеют неограниченное время выполнения а заказы в свою очередь напротив. В основном есть 4 типа заданий которые я хочу использовать и там и там. Но помимо этих основных типов заданий есть ещё другие задания которые подходят только для миссий(сюжетки) и только для заказов(побочки). Конечно же за выполнения что миссий и что заказов игроку приходит награда.
Как мне правильно реализовать? Что будет в class BaseTask? Или что то сделать через интерфейс? Какой паттерн лучше применить и нужно ли?
Помогите пойти по правильному руслу, что бы эта система task-ов была гибкая и понятная по всем канонам программирования. Потому что я понимаю, что если я сразу буду писать плохо то потом это обязательно вылезет боком.
Ответы (1 шт):
public class Task
{
ITaskCondition
TaskStatus
TaskInfo
}
В ITaskCondition условия выполнения и провала задания.
public interface ITaskCondition
{
event Action Updated;
bool CompleatConditionMet ();
bool FailConditionMet ();
void Stop();
}
Может быть условие на выполнение группы условий убей 5 Goblin за 10 минут или условие на выполнение одного из условий, например убей или договорись. По сути разные стратегии AndCondition и OrCondition, которые тоже ITaskCondition. Можно сделать обёртку для обратного условия NotCondition и комбинируя разные стратегии получать сложные условия.
убей 10 Goblin или Golin King не трогая Goblin Scout
AndCondition
OrCondition
KillCondition Goblin, 10
KillCondition GoblinKing, 1
NotCondition
KillCondition GoblinScout, 1
public class KillCondition : ITaskCondition
{
public event Action Updated;
private readonly UnitType _targetType;
private readonly int _targetCount;
private int _currentCount;
public KillCondition (UnitType type, int count)
{
_targetType = type;
_targetCount = count;
UnitManager.Killed += OnUnitKill;
}
public bool CompleatConditionMet ()
{
return _targetCount >= _currentCount;
}
public bool FailConditionMet ()
{
return false;
}
public void Stop ()
{
UnitManager.Killed -= OnUnitKill;
}
private void OnUnitKill (Unit unit)
{
if (unit.Type == _targetType)
{
_currentCount++;
Updated?.Invoke();
}
}
}
Status это просто градусник для условия.
public class TaskStatus
{
public event Action<TaskStatusType> Changed;
private ICondition _condition;
public TaskStatusType Type { get; private set; }
public Status (ICondition condition)
{
_condition = condition;
_condition.Updated += Update;
}
private void Update ()
{
if (Type != TaskStatusType.InProgress)
return;
if (_condition.CompleatConditionMet())
Change(TaskStatusType.Complicated);
else if (_condition.FailConditionMet())
Change(TaskStatusType.Failed);
}
private void Change (TaskStatusType status)
{
_condition.Stop();
Type = status;
Changed?.Invoke(Type);
}
}
Ну и всякие константы вроде Discription, Reward, иконок и прочего можно засунуть в какой-нибудь тип данных типа TaskInfo.
Наверное как-то так.