Skip to content

Commit

Permalink
Send additionalData with choices
Browse files Browse the repository at this point in the history
Currently, this is only implemented in `TakeApproach`.
  • Loading branch information
filiph committed Feb 1, 2020
1 parent 4415627 commit 9258157
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ DESCRIPTION: $NONE
// ---
ROOM: $start_tester_build

POS: 0, 0

FIRST_DESCRIPTION:
Welcome to the test build of this game. Thank you for taking the time to make the game better.
2 changes: 2 additions & 0 deletions edgehead/lib/edgehead_lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ class EdgeheadGame extends Book {
..commandPath = ListBuilder<String>(performance.commandPath)
..helpMessage = performance.action.helpMessage
..successChance = performance.successChance.value
..actionName = performance.action.name
..additionalData = ListBuilder<int>(performance.additionalData)
..isImplicit = performance.action.isImplicit);
callbacks[choice] = () async {
await _applySelected(
Expand Down
3 changes: 3 additions & 0 deletions edgehead/lib/egamebook/commands/serializers.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions edgehead/lib/egamebook/elements/choice_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ abstract class Choice extends ElementBase

Choice._();

/// The chance of success, from `0` to `1`.
double get successChance;
/// The name of the action being used.
String get actionName;

/// Additional data, as provided by [Action.getAdditionalData].
BuiltList<int> get additionalData;

BuiltList<String> get commandPath;

Expand All @@ -27,4 +30,7 @@ abstract class Choice extends ElementBase
/// Returns [:true:] when the choice is automatic (presenter picks it
/// silently). Corresponds to `Action.isImplicit`.
bool get isImplicit;

/// The chance of success, from `0` to `1`.
double get successChance;
}
104 changes: 80 additions & 24 deletions edgehead/lib/egamebook/elements/choice_element.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions edgehead/lib/egamebook/elements/serializers.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 34 additions & 12 deletions edgehead/lib/fractal_stories/action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ abstract class Action<T> {
static const Duration defaultPlayerRecoveryDuration =
Duration(milliseconds: 750);

/// Allow [Action] subclasses to have `const` constructors.
const Action();

/// [OtherActorActionBase] should include the [target] in the result of
/// [getCommand]. To make it easier to implement, this class will
/// automatically construct the name given a [Storyline] template.
Expand All @@ -58,9 +61,6 @@ abstract class Action<T> {
/// and, if appropriate, why and when it should be used.
String get helpMessage;

/// Allow [Action] subclasses to have `const` constructors.
const Action();

/// Whether or not this action is aggressive towards its sufferer. Combat
/// moves are aggressive, healing moves aren't.
///
Expand Down Expand Up @@ -135,6 +135,17 @@ abstract class Action<T> {
'called in the first place.');
}

/// Some actions can provide additional data for a give [context] and
/// [object]. This data can be used by the presenter.
///
/// For example, a travel action can provide a path from the current
/// position ([context]) to the destination ([object]). The presenter
/// can then draw the path on a map.
List<int> getAdditionalData(ApplicabilityContext context, T object) {
// By default, there is no additional data.
return const [];
}

/// The path of sub-commands to be used for the action menu.
///
/// For example, an actions such as "kick <subject> to ground" could have
Expand Down Expand Up @@ -369,6 +380,7 @@ abstract class OtherActorActionBase extends Action<Actor> {
/// as the object. Therefore, assuming there are two different enemies
/// available for punching, the planner would create two instances
/// of `Performance`, one for each enemy.
@immutable
class Performance<T> {
/// The action to be performed on the [object]. For example, punch (if
/// the object is an enemy actor) or take (if the object is an item).
Expand All @@ -383,8 +395,20 @@ class Performance<T> {
/// The object the [action] is performed on.
final T object;

/// Additional information about the performance that can be visualized
/// by the presenter.
///
/// For example, a travel action can provide the path that is to be taken
/// by the actor to get to their destination ([object]) given their
/// current position ([context]).
///
/// This is taken from [Action.getAdditionalData] and defaults to an empty
/// list.
final List<int> additionalData;

/// Creates a performance object.
Performance(this.action, this.context, this.object, this.successChance);
const Performance(this.action, this.context, this.object, this.successChance,
this.additionalData);

/// The performer of the action.
Actor get actor => context.actor;
Expand Down Expand Up @@ -425,19 +449,17 @@ class Performance<T> {
}
}

void _addWorldRecord(ActionRecordBuilder builder, WorldStateBuilder world) {
if (_description == null) {
void _addWorldRecord(ActionRecordBuilder builder, WorldStateBuilder world,
String description) {
if (description == null) {
throw StateError("No description given when executing $action. You "
"should return it from your world-modifying function.");
}
builder.description = _description;
builder.description = description;
builder.time = world.time;
world.recordAction(builder.build());
}

/// The description of the performance.
String _description;

Storyline _applyToWorldCopy(
ActorTurn turn,
Simulation sim,
Expand All @@ -457,7 +479,7 @@ class Performance<T> {
.onBeforeAction(sim, initialWorld, outputStoryline);
final context = ActionContext(action, turn.actor, sim, initialWorld, output,
outputStoryline, successChance);
_description = applyFunction(context, object);
final description = applyFunction(context, object);

// The current situation could have been removed by [applyFunction].
// If not, let's update its time.
Expand Down Expand Up @@ -493,7 +515,7 @@ class Performance<T> {
// methods.
output.currentSituation?.onAfterTurn(context);

_addWorldRecord(builder, output);
_addWorldRecord(builder, output, description);
return outputStoryline;
}

Expand Down
Loading

0 comments on commit 9258157

Please sign in to comment.