// Add a named sprite object to symbol table and object list internal int AddObject(string name, Pair <float, float> pivot, float scale, int width, IList <int> grid, int textcolour, string text) { _symbols[name] = new ObjectSymbol { Name = name, Kind = SymbolKind.Real, ObjectIds = new List <int> { _gamedef.PuzzleObjects.Count + 1 }, }; _gamedef.PuzzleObjects.Add(new PuzzleObject { Name = name, Layer = 0, // set later Pivot = pivot, Scale = scale, Width = width, Sprite = grid, TextColour = textcolour, Text = text, }); DebugLog("Sprite Object {0}: '{1}' {2}x{3} {4} {5} '{6}'", _gamedef.PuzzleObjects.Count, name, width, grid.Count / width, scale, pivot, text); Logger.WriteLine(4, "{0}", grid.Select(c => String.Format("{0:X}", c)).Join()); return(_gamedef.PuzzleObjects.Count); }
// expand an OR symbol throughout a rule // error if more than one in pattern IList <AtomicRule> ExpandSymbolMulti(AtomicRule oldrule, ObjectSymbol oldsym) { var pcells = oldrule.Patterns.SelectMany(p => p.Cells .SelectMany(c => c.Where(a => a.Symbol == oldsym && !a.IsNegated))); if (pcells.Count() != 1) { return(null); } // expand one rule per object id var newrules = new List <AtomicRule>(); foreach (var newobj in oldsym.ObjectIds) { var newrule = oldrule.Clone(); for (var riter = new RuleIterator { Rule = oldrule }; !riter.Done; riter.Step()) { newrule.Patterns[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceObject(riter.PatternAtoms, oldsym, newobj); newrule.Actions[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceObject(riter.ActionAtoms, oldsym, newobj); } newrules.AddRange(ExpandRule(newrule)); } return(newrules); }
// Clone an atom but change the symbol internal RuleAtom Clone(ObjectSymbol symbol) { var rm = this.MemberwiseClone() as RuleAtom; rm.Symbol = symbol; return(rm); }
void EmitDestroy(ObjectSymbol objsym) { if (!objsym.IsObject || objsym.ObjectIds.Count() == 0) { throw Error.Assert(objsym.Name); } _gen.Emit(Opcodes.DestroyO); _gen.Emit(objsym); }
static internal CommandCall Create(CommandName command, string text, ScriptFunctionCall call, ObjectSymbol symbol = null) { return(new CommandCall { commandId = command, text = text, funcCall = call, symbol = symbol, }); }
void EmitCreateByRef(ObjectSymbol objsym, Direction direction) { if (objsym.ObjectIds.Count() != 1) { throw Error.Assert(objsym.Name); } _gen.Emit(Opcodes.CreateO); _gen.Emit(~objsym.ObjectIds.First()); // special to trigger variable lookup _gen.Emit(direction); }
void EmitCreate(ObjectSymbol objsym, Direction direction = Direction.None) { if (!objsym.IsObject || objsym.ObjectIds.Count() == 0) { throw Error.Assert(objsym.Name); } _gen.Emit(Opcodes.CreateO); _gen.Emit(objsym); _gen.Emit(direction); }
internal static RuleAtom Create(bool isnegated, Direction direction, ObjectSymbol objects, ObjectSymbol variable, ScriptFunctionCall call) { return(new RuleAtom { IsNegated = isnegated, Direction = direction, Symbol = objects, Variable = variable, Call = call, }); }
// define or return a variable, null if cannot internal ObjectSymbol ParseVariable(string name) { var sym = _symbols.SafeLookup(name); if (sym == null) { _symbols[name] = sym = new ObjectSymbol { Name = name, Kind = SymbolKind.RefObject, ObjectIds = new List <int>(), // must get added later }; } return(sym.Kind == SymbolKind.RefObject ? sym : null); }
internal void Emit(ObjectSymbol symbol) { if (symbol.Kind == SymbolKind.RefObject) { Emit(~symbol.ObjectIds.First()); } else if (symbol.Kind == SymbolKind.Script) { Emit(-99); } else { Emit(symbol.ObjectIds); } }
IList <RuleAtom> ReplaceObject(IList <RuleAtom> cell, ObjectSymbol oldsym, int newobj) { IList <RuleAtom> newcell = null; for (var i = 0; i < cell.Count; i++) { if (cell[i].Symbol == oldsym && !cell[i].IsNegated) { if (newcell == null) { newcell = new List <RuleAtom>(cell); // BUG: could lose atoms } newcell[i] = cell[i].Clone(_parser.GetSymbol(newobj)); } } return(newcell ?? cell); }
void EmitCommand(CommandName command, string argument, ObjectSymbol objsym, ScriptFunctionCall call) { if (call != null) { call.Emit(_gen); } if (objsym != null) { _gen.Emit(Opcodes.CommandCSO); _gen.Emit((int)command); if (call == null) { _gen.Emit(argument); } else { _gen.Emit(-99); } _gen.Emit(objsym); } else if (argument != null) { _gen.Emit(Opcodes.CommandCS); _gen.Emit((int)command); if (call == null) { _gen.Emit(argument); } else { _gen.Emit(-99); } } else { _gen.Emit(Opcodes.CommandC); _gen.Emit((int)command); } }
// true if references the same objects in the same way // CHECK: same ids in different sequence will fail internal bool Matches(ObjectSymbol other) { return(ObjectIds.SequenceEqual(other.ObjectIds)); }
void EmitSetMove(ObjectSymbol objsym, Direction direction) { _gen.Emit(Opcodes.MoveOM); _gen.Emit(objsym); _gen.Emit(direction); }