public override void GenerateIntoContainer(Runtime.Container container) { var runtimeRawList = new Runtime.InkList(); if (itemIdentifierList != null) { foreach (var itemIdentifier in itemIdentifierList) { var nameParts = itemIdentifier?.name.Split('.'); string listName = null; string listItemName = null; if (nameParts.Length > 1) { listName = nameParts [0]; listItemName = nameParts [1]; } else { listItemName = nameParts [0]; } var listItem = story.ResolveListItem(listName, listItemName, this); if (listItem == null) { if (listName == null) { Error("Could not find list definition that contains item '" + itemIdentifier + "'"); } else { Error("Could not find list item " + itemIdentifier); } } else { if (listName == null) { listName = ((ListDefinition)listItem.parent).identifier?.name; } var item = new Runtime.InkListItem(listName, listItem.name); if (runtimeRawList.ContainsKey(item)) { Warning("Duplicate of item '" + itemIdentifier + "' in list."); } else { runtimeRawList [item] = listItem.seriesValue; } } } } container.AddContent(new Runtime.ListValue(runtimeRawList)); }
public override Runtime.Object GenerateRuntimeObject() { var initialValues = new Runtime.InkList(); foreach (var itemDef in itemDefinitions) { if (itemDef.inInitialList) { var item = new Runtime.InkListItem(this.name, itemDef.name); initialValues [item] = itemDef.seriesValue; } } // Set origin name, so initialValues.SetInitialOriginName(name); return(new Runtime.ListValue(initialValues)); }
public override void GenerateIntoContainer(Runtime.Container container) { var foundList = story.ResolveList(name); bool usingProxyDivert = false; if (isChoiceCount) { if (arguments.Count > 0) { Error("The CHOICE_COUNT() function shouldn't take any arguments"); } container.AddContent(Runtime.ControlCommand.ChoiceCount()); } else if (isTurns) { if (arguments.Count > 0) { Error("The TURNS() function shouldn't take any arguments"); } container.AddContent(Runtime.ControlCommand.Turns()); } else if (isTurnsSince || isReadCount) { var divertTarget = arguments [0] as DivertTarget; var variableDivertTarget = arguments [0] as VariableReference; if (arguments.Count != 1 || (divertTarget == null && variableDivertTarget == null)) { Error("The " + name + "() function should take one argument: a divert target to the target knot, stitch, gather or choice you want to check. e.g. TURNS_SINCE(-> myKnot)"); return; } if (divertTarget) { _divertTargetToCount = divertTarget; AddContent(_divertTargetToCount); _divertTargetToCount.GenerateIntoContainer(container); } else { _variableReferenceToCount = variableDivertTarget; AddContent(_variableReferenceToCount); _variableReferenceToCount.GenerateIntoContainer(container); } if (isTurnsSince) { container.AddContent(Runtime.ControlCommand.TurnsSince()); } else { container.AddContent(Runtime.ControlCommand.ReadCount()); } } else if (isRandom) { if (arguments.Count != 2) { Error("RANDOM should take 2 parameters: a minimum and a maximum integer"); } // We can type check single values, but not complex expressions for (int arg = 0; arg < arguments.Count; arg++) { if (arguments [arg] is Number) { var num = arguments [arg] as Number; if (!(num.value is int)) { string paramName = arg == 0 ? "minimum" : "maximum"; Error("RANDOM's " + paramName + " parameter should be an integer"); } } arguments [arg].GenerateIntoContainer(container); } container.AddContent(Runtime.ControlCommand.Random()); } else if (isSeedRandom) { if (arguments.Count != 1) { Error("SEED_RANDOM should take 1 parameter - an integer seed"); } var num = arguments [0] as Number; if (num && !(num.value is int)) { Error("SEED_RANDOM's parameter should be an integer seed"); } arguments [0].GenerateIntoContainer(container); container.AddContent(Runtime.ControlCommand.SeedRandom()); } else if (isListRange) { if (arguments.Count != 3) { Error("LIST_RANGE should take 3 parameters - a list, a min and a max"); } for (int arg = 0; arg < arguments.Count; arg++) { arguments [arg].GenerateIntoContainer(container); } container.AddContent(Runtime.ControlCommand.ListRange()); } else if (isListRandom) { if (arguments.Count != 1) { Error("LIST_RANDOM should take 1 parameter - a list"); } arguments [0].GenerateIntoContainer(container); container.AddContent(Runtime.ControlCommand.ListRandom()); } else if (Runtime.NativeFunctionCall.CallExistsWithName(name)) { var nativeCall = Runtime.NativeFunctionCall.CallWithName(name); if (nativeCall.numberOfParameters != arguments.Count) { var msg = name + " should take " + nativeCall.numberOfParameters + " parameter"; if (nativeCall.numberOfParameters > 1) { msg += "s"; } Error(msg); } for (int arg = 0; arg < arguments.Count; arg++) { arguments [arg].GenerateIntoContainer(container); } container.AddContent(Runtime.NativeFunctionCall.CallWithName(name)); } else if (foundList != null) { if (arguments.Count > 1) { Error("Can currently only construct a list from one integer (or an empty list from a given list definition)"); } // List item from given int if (arguments.Count == 1) { container.AddContent(new Runtime.StringValue(name)); arguments [0].GenerateIntoContainer(container); container.AddContent(Runtime.ControlCommand.ListFromInt()); } // Empty list with given origin. else { var list = new Runtime.InkList(); list.SetInitialOriginName(name); container.AddContent(new Runtime.ListValue(list)); } } // Normal function call else { container.AddContent(_proxyDivert.runtimeObject); usingProxyDivert = true; } // Don't attempt to resolve as a divert if we're not doing a normal function call if (!usingProxyDivert) { content.Remove(_proxyDivert); } // Function calls that are used alone on a tilda-based line: // ~ func() // Should tidy up any returned value from the evaluation stack, // since it's unused. if (shouldPopReturnedValue) { container.AddContent(Runtime.ControlCommand.PopEvaluatedValue()); } }