private void nextStep() {

    boolean stop = false;

    ArrayList<Action> actions = getActions();

    while (ip < actions.size() && !stop) {
      Action a = actions.get(ip);

      if (EngineLogger.debugMode())
        EngineLogger.debug(
            "RunVerbAction: " + verb + "(" + ip + ") " + a.getClass().getSimpleName());

      try {
        if (a.run(this)) stop = true;
        else ip++;
      } catch (Exception e) {
        EngineLogger.error("EXCEPTION EXECUTING ACTION: " + a.getClass().getSimpleName(), e);
      }
    }

    if (getWait() && !stop) {
      super.resume();
    }
  }
  public TextureRegion getBgIcon(String atlas, String region) {

    // check here for dispose instead in project loading because the opengl context lost in new
    // project thread
    if (disposeBgCache) {
      dispose();
      disposeBgCache = false;
    }

    String s = atlas + "#" + region;
    TextureRegion icon = bgIconCache.get(s);

    if (icon == null) {
      try {
        Batch batch = getStage().getBatch();
        batch.end();
        bgIconCache.put(s, createBgIcon(atlas, region));
        batch.begin();
      } catch (Exception e) {
        EngineLogger.error("Error creating Background icon");
        return null;
      }

      icon = bgIconCache.get(s);
    }

    return icon;
  }
  public static Action create(String name, HashMap<String, String> params) {
    String className = actions.get(name);

    if (className == null) {
      EngineLogger.error("Action with name '" + name + "' not found.");

      return null;
    }

    return ActionFactory.createByClass(className, params);
  }
  public void nextStep() {

    boolean stop = false;

    while (!isFinished() && !stop) {
      Action a = actions.get(ip);

      if (EngineLogger.debugMode()) EngineLogger.debug(ip + ". " + a.getClass().getSimpleName());

      try {
        if (a.run(this)) stop = true;
        else ip++;
      } catch (Exception e) {
        EngineLogger.error("EXCEPTION EXECUTING ACTION: " + a.getClass().getSimpleName(), e);
        ip++;
      }
    }

    if (EngineLogger.debugMode() && isFinished()) EngineLogger.debug(">>> Verb FINISHED: " + id);
  }
  public static Action createByClass(String className, HashMap<String, String> params) {

    Action a = null;

    try {
      Class<?> c = ClassReflection.forName(className);
      a = (Action) ClassReflection.newInstance(c);

      if (params != null) {
        //				a.setParams(params);

        for (String key : params.keySet()) {
          String value = params.get(key);

          try {
            ActionUtils.setParam(a, key, value);
          } catch (NoSuchFieldException
              | SecurityException
              | IllegalArgumentException
              | IllegalAccessException e) {
            EngineLogger.error(
                "Error Setting Action Param - Action:"
                    + className
                    + " Param: "
                    + key
                    + " Value: "
                    + value
                    + " Msg: NOT FOUND "
                    + e.getMessage());
          }
        }
      }
    } catch (ReflectionException e) {
      EngineLogger.error(e.getMessage());
    }

    return a;
  }
  @Override
  public ArrayList<Action> getActions() {
    Verb v = getVerb(verb, target, state);

    if (v == null) {
      EngineLogger.error(
          MessageFormat.format(
              "Verb ''{0}'' not found for actor ''{1}({3})'' and target ''{2}''",
              verb,
              actorId,
              target,
              World.getInstance().getCurrentScene().getActor(actorId, true).getState()));

      return new ArrayList<Action>(0);
    }

    return v.getActions();
  }
  private Verb getVerb(String verb, String target, String state) {
    Verb v = null;

    if (actorId != null) {
      BaseActor a = World.getInstance().getCurrentScene().getActor(actorId, true);

      v = a.getVerbManager().getVerb(verb, state, target);
    }

    if (v == null) {
      v = World.getInstance().getCurrentScene().getVerb(verb);
    }

    if (v == null) {
      v = VerbManager.getWorldVerbs().get(verb);
    }

    if (v == null) EngineLogger.error("Cannot find VERB: " + verb + " for ACTOR: " + actorId);

    return v;
  }
  public void removeActor(BaseActor a) {

    if (player != null && a.getId().equals(player)) {
      player = null;
    }

    BaseActor r = actors.remove(a.getId());

    if (r == null) {
      EngineLogger.error("Removing actor from scene: Actor not found");
      return;
    }

    SceneLayer layer = getLayer(a.getLayer());
    layer.getActors().remove(a);

    if (a instanceof ObstacleActor && polygonalNavGraph != null)
      polygonalNavGraph.removeDinamicObstacle(a.getBBox());

    a.setScene(null);
  }
  public void drawBBoxLines(ShapeRenderer renderer) {
    // renderer.begin(ShapeType.Rectangle);
    renderer.begin(ShapeType.Line);

    for (BaseActor a : actors.values()) {
      Polygon p = a.getBBox();

      if (p == null) {
        EngineLogger.error("ERROR DRAWING BBOX FOR: " + a.getId());
      }

      if (a instanceof ObstacleActor) renderer.setColor(OBSTACLE_COLOR);
      else renderer.setColor(ACTOR_BBOX_COLOR);

      renderer.polygon(p.getTransformedVertices());

      // Rectangle r = a.getBBox().getBoundingRectangle();
      // renderer.rect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
    }

    if (polygonalNavGraph != null) {
      renderer.setColor(WALKZONE_COLOR);
      renderer.polygon(polygonalNavGraph.getWalkZone().getTransformedVertices());

      // DRAW LINEs OF SIGHT
      renderer.setColor(Color.WHITE);
      ArrayList<NavNodePolygonal> nodes = polygonalNavGraph.getGraphNodes();
      for (NavNodePolygonal n : nodes) {
        for (NavNode n2 : n.neighbors) {
          renderer.line(n.x, n.y, ((NavNodePolygonal) n2).x, ((NavNodePolygonal) n2).y);
        }
      }
    }

    renderer.end();
  }
  public void run() {
    if (EngineLogger.debugMode()) EngineLogger.debug(">>> Running verb: " + id);

    ip = 0;
    nextStep();
  }