public virtual bool Use(GameCore <Player> game) { var codeSpell = new CodeSpell(game.Player, SpellName, code, Mana); game.Map.AddObject(game.PlayerPosition, codeSpell); return(false); }
public MoveSpellAction(dynamic actionData, CodeSpell spell) : base(ActionType) { direction = ParseDirection((string)actionData.direction); distance = (int)actionData.distance; this.spell = spell; }
public EmitLightSpellAction(dynamic actionData, CodeSpell spell) : base(ActionType) { power = (int)actionData.power; if (power > (int)LightLevel.Blinding) { power = (int)LightLevel.Blinding; } time = (int)actionData.time; this.spell = spell; }
public LongCastSpellAction(dynamic actionData, CodeSpell spell) { var configuration = GetConfiguration(); manaCostMultiplier = configuration.ManaCostMultiplier; manaCostPower = configuration.ManaCostPower; this.spell = spell; action = ParseSpellAction(actionData.action); direction = ParseDirection((string)actionData.direction); distance = (int)actionData.distance; }
public ISpellAction GetSpellAction(dynamic actionData, CodeSpell spell) { if (string.IsNullOrEmpty(actionData.type)) { throw new SpellException("Action type cannot be empty."); } switch (actionData.type) { case MoveSpellAction.ActionType: return(new MoveSpellAction(actionData, spell)); case BuildWallSpellAction.ActionType: return(new BuildWallSpellAction(actionData)); case HeatAreaSpellAction.ActionType: return(new HeatAreaSpellAction(actionData)); case CoolAreaSpellAction.ActionType: return(new CoolAreaSpellAction(actionData)); case PushSpellAction.ActionType: return(new PushSpellAction(actionData)); case CompressSpellAction.ActionType: return(new CompressSpellAction(actionData)); case DecompressSpellAction.ActionType: return(new DecompressSpellAction(actionData)); case CreateWaterSpellAction.ActionType: return(new CreateWaterSpellAction(actionData)); case LongCastSpellAction.ActionType: return(new LongCastSpellAction(actionData, spell)); case TransformWaterSpellAction.ActionType: return(new TransformWaterSpellAction(actionData)); case ShockSpellAction.ActionType: return(new ShockSpellAction(actionData)); case EmitLightSpellAction.ActionType: return(new EmitLightSpellAction(actionData, spell)); } throw new SpellException($"Action type \"{actionData.type}\" is not supported."); }
private bool[][] ScanForWalls(Point position, int radius, CodeSpell spell) { var cost = radius * ScanForWallsManaCostMultiplier; if (spell.Mana < cost) { spell.Mana = 0; return(null); } spell.Mana -= cost; var mapSegment = CurrentGame.Map.GetMapPart(position, radius); return(mapSegment.Select(row => row.Select(cell => cell == null || cell.BlocksProjectiles).ToArray()) .ToArray()); }
private void ConfigureDynamicEngineFunctions(Point position, CodeSpell spell) { jsEngine.SetValue("getLightLevel", new Func <int>(() => GetLightLevel(position))); jsEngine.SetValue("getCaster", new Func <JsValue>(() => ConvertDestroyable(CurrentGame.Map.GetDestroyableObject(casterId)).ToJson(jsEngine))); jsEngine.SetValue("log", new Action <object>(message => LogMessage(spell, message))); jsEngine.SetValue("getMana", new Func <int>(() => spell.Mana)); jsEngine.SetValue("getPosition", new Func <JsValue>(() => ConvertPoint(position))); jsEngine.SetValue("getTemperature", new Func <int>(() => CurrentGame.Map.GetCell(position).Temperature())); jsEngine.SetValue("getIsSolidWall", new Func <string, bool>((direction) => GetIfCellIsSolid(position, direction))); jsEngine.SetValue("getObjectsUnder", new Func <JsValue[]>(() => GetObjectsUnder(position))); jsEngine.SetValue("scanForWalls", new Func <int, bool[][]>(radius => ScanForWalls(position, radius, spell))); jsEngine.SetValue("scanForObjects", new Func <int, JsValue[]>(radius => ScanForObjects(position, radius, spell))); }
public ISpellAction Execute(Point position, CodeSpell spell, int lifeTime) { var result = ExecuteCode(position, spell, lifeTime); if (result == null) { return(new EmptySpellAction()); } var action = new SpellActionsFactory().GetSpellAction(result, spell); if (action == null) { throw new SpellException("Spell returned no action."); } return(action); }
private dynamic ExecuteCode(Point position, CodeSpell spell, int lifeTime) { ConfigureDynamicEngineFunctions(position, spell); JsValue mainFunction; try { mainFunction = jsEngine.Execute(code).GetValue("main"); } catch (ParserException ex) { throw new SpellException($"Error in spell code {ex.Message}"); } catch (Exception ex) { throw new SpellException($"Unknown error during spell execution: {ex.Message}", ex); } if (mainFunction == null) { throw new SpellException("Function \"main\" not found in spell code."); } dynamic result; try { result = mainFunction.Invoke(lifeTime).ToObject() as ExpandoObject; } catch (JavaScriptException ex) { throw new SpellException($"Error in spell code: [line {ex.LineNumber}] {ex.Message}"); } catch (Exception ex) { throw new SpellException($"Unknown error during spell execution: {ex.Message}", ex); } return(result); }
private JsValue[] ScanForObjects(Point position, int radius, CodeSpell spell) { var cost = radius * ScanForObjectsManaCostMultiplier; if (spell.Mana < cost) { spell.Mana = 0; return(null); } spell.Mana -= cost; var mapSegment = CurrentGame.Map.GetMapPart(position, radius); return(mapSegment.SelectMany(row => row.Where(cell => cell != null) .SelectMany(cell => cell.Objects .OfType <IDestroyableObject>() .Select(obj => ConvertDestroyable(obj).ToJson(jsEngine)))) .ToArray()); }
private void LogMessage(CodeSpell spell, object message) { CurrentGame.Journal.Write(new SpellLogMessage(spell.Name, GetMessageString(message))); }