Example #1
0
/**
 * @brief Tries to claim systems.
 *
 * Claiming systems is a way to avoid mission collisions preemptively.
 *
 * Note it does not actually claim the systems if it fails to claim. It also
 *  does not work more then once.
 *
 * @usage if not misn.claim( { system.get("Gamma Polaris") } ) then misn.finish( false ) end
 * @usage if not misn.claim( system.get("Gamma Polaris") ) then misn.finish( false ) end
 *
 *    @luaparam systems Table of systems to claim or a single system.
 *    @luareturn true if was able to claim, false otherwise.
 * @luafunc claim( systems )
 */
static int misn_claim( lua_State *L )
{
   int i, l;
   LuaSystem *ls;
   SysClaim_t *claim;
   Mission *cur_mission;

   /* Get mission. */
   cur_mission = misn_getFromLua(L);

   /* Check to see if already claimed. */
   if (cur_mission->claims != NULL) {
      NLUA_ERROR(L, "Mission trying to claim but already has.");
      return 0;
   }

   /* Create the claim. */
   claim = claim_create();

   if (lua_istable(L,1)) {
      /* Iterate over table. */
      l = lua_objlen(L,1);
      for (i=0; i<l; i++) {
         lua_pushnumber(L,i+1);
         lua_gettable(L,1);
         if (lua_issystem(L,-1)) {
            ls = lua_tosystem( L, -1 );
            claim_add( claim, ls->id );
         }
         lua_pop(L,1);
      }
   }
   else if (lua_issystem(L, 1)) {
      ls = lua_tosystem( L, 1 );
      claim_add( claim, ls->id );
   }
   else
      NLUA_INVALID_PARAMETER(L);

   /* Test claim. */
   if (claim_test( claim )) {
      claim_destroy( claim );
      lua_pushboolean(L,0);
      return 1;
   }

   /* Set the claim. */
   cur_mission->claims = claim;
   claim_activate( claim );
   lua_pushboolean(L,1);
   return 1;
}
Example #2
0
/**
 * @brief Tries to claim systems.
 *
 * Claiming systems is a way to avoid mission/event collisions preemptively.
 *
 * Note it does not actually claim the systems if it fails to claim. It also
 *  does not work more then once.
 *
 * @usage if not evt.claim( { system.get("Gamma Polaris") } ) then evt.finish( false ) end
 * @usage if not evt.claim( system.get("Gamma Polaris") ) then evt.finish( false ) end
 *
 *    @luaparam systems Table of systems to claim or a single system.
 *    @luareturn true if was able to claim, false otherwise.
 * @luafunc claim( systems )
 */
static int evt_claim( lua_State *L )
{
    LuaSystem *ls;
    SysClaim_t *claim;
    Event_t *cur_event;

    /* Get current event. */
    cur_event = event_getFromLua(L);

    /* Check to see if already claimed. */
    if (cur_event->claims != NULL) {
        NLUA_ERROR(L, "Event trying to claim but already has.");
        return 0;
    }

    /* Create the claim. */
    claim = claim_create();

    /* Handle parameters. */
    if (lua_istable(L,1)) {
        /* Iterate over table. */
        lua_pushnil(L);
        while (lua_next(L, 1) != 0) {
            if (lua_issystem(L,-1)) {
                ls = lua_tosystem( L, -1 );
                claim_add( claim, ls->id );
            }
            lua_pop(L,1);
        }
    }
    else if (lua_issystem(L, 1)) {
        ls = lua_tosystem( L, 1 );
        claim_add( claim, ls->id );
    }
    else
        NLUA_INVALID_PARAMETER(L);

    /* Test claim. */
    if (claim_test( claim )) {
        claim_destroy( claim );
        lua_pushboolean(L,0);
        return 1;
    }

    /* Set the claim. */
    cur_event->claims = claim;
    claim_activate( claim );
    lua_pushboolean(L,1);
    return 1;
}
Example #3
0
/**
 * @brief Gets jump distance from current system, or to another.
 *
 * Does different things depending on the parameter type:
 *    - nil : Gets distance from current system.
 *    - string : Gets distance from system matching name.
 *    - system : Gets distance from system
 *
 * @usage d = sys:jumpDist() -- Distance from current system.
 * @usage d = sys:jumpDist( "Draygar" ) -- Distance from system Draygar.
 * @usage d = sys:jumpDist( another_sys ) -- Distance from system another_sys.
 *
 *    @luaparam s System to get distance from.
 *    @luaparam param See description.
 *    @luaparam hidden Whether or not to consider hidden jumps.
 *    @luareturn Number of jumps to system.
 * @luafunc jumpDist( s, param, hidden )
 */
static int systemL_jumpdistance( lua_State *L )
{
   StarSystem *sys, *sysp;
   StarSystem **s;
   int jumps;
   const char *start, *goal;
   int h;

   sys = luaL_validsystem(L,1);
   start = sys->name;
   h   = lua_toboolean(L,3);

   if (lua_gettop(L) > 1) {
      if (lua_isstring(L,2))
         goal = lua_tostring(L,2);
      else if (lua_issystem(L,2)) {
         sysp = luaL_validsystem(L,2);
         goal = sysp->name;
      }
      else NLUA_INVALID_PARAMETER(L);
   }
   else
      goal = cur_system->name;

   s = map_getJumpPath( &jumps, start, goal, 1, h, NULL );
   free(s);

   lua_pushnumber(L,jumps);
   return 1;
}
Example #4
0
/**
 * @brief Gets system at index raising an error if type doesn't match.
 *
 *    @param L Lua state to get system from.
 *    @param ind Index position of system.
 *    @return The LuaSystem at ind.
 */
LuaSystem* luaL_checksystem( lua_State *L, int ind )
{
   if (lua_issystem(L,ind))
      return lua_tosystem(L,ind);
   luaL_typerror(L, ind, SYSTEM_METATABLE);
   return NULL;
}
Example #5
0
/**
 * @brief Gets jump path from current system, or to another.
 *
 * Does different things depending on the parameter type:
 *    - nil : Gets path from current system.
 *    - string : Gets path from system matching name.
 *    - system : Gets path from system
 *
 * @usage jumps = sys:jumpPath() -- Path to current system.
 * @usage jumps = sys:jumpPath( "Draygar" ) -- Path from current sys to Draygar.
 * @usage jumps = system.jumpPath( "Draygar", another_sys ) -- Path from Draygar to another_sys.
 *
 *    @luatparam System s System to get path from.
 *    @luatparam nil|string|System param See description.
 *    @luatparam[opt=false] boolean hidden Whether or not to consider hidden jumps.
 *    @luatreturn {Jump,...} Table of jumps.
 * @luafunc jumpPath( s, param, hidden )
 */
static int systemL_jumpPath( lua_State *L )
{
   LuaJump lj;
   StarSystem *sys, *sysp;
   StarSystem **s;
   int i, sid, jumps, pushed, h;
   const char *start, *goal;

   h   = lua_toboolean(L,3);

   /* Foo to Bar */
   if (lua_gettop(L) > 1) {
      sys   = luaL_validsystem(L,1);
      start = sys->name;
      sid   = sys->id;

      if (lua_isstring(L,2))
         goal = lua_tostring(L,2);
      else if (lua_issystem(L,2)) {
         sysp = luaL_validsystem(L,2);
         goal = sysp->name;
      }
      else NLUA_INVALID_PARAMETER(L);
   }
   /* Current to Foo */
   else {
      start = cur_system->name;
      sid   = cur_system->id;
      sys   = luaL_validsystem(L,1);
      goal  = sys->name;
   }

   s = map_getJumpPath( &jumps, start, goal, 1, h, NULL );
   if (s == NULL)
      return 0;

   /* Create the jump table. */
   lua_newtable(L);
   pushed = 0;

   /* Map path doesn't contain the start system, push it manually. */
   lj.srcid  = sid;
   lj.destid = s[0]->id;

   lua_pushnumber(L, ++pushed); /* key. */
   lua_pushjump(L, lj);         /* value. */
   lua_rawset(L, -3);

   for (i=0; i<(jumps - 1); i++) {
      lj.srcid  = s[i]->id;
      lj.destid = s[i+1]->id;

      lua_pushnumber(L, ++pushed); /* key. */
      lua_pushjump(L, lj);         /* value. */
      lua_rawset(L, -3);
   }
   free(s);

   return 1;
}
Example #6
0
/**
 * @brief Back-end for luaL_validjump.
 *
 *    @param L Lua state to get jump from.
 *    @param ind Index to check.
 *    @param[out] offset How many Lua arguments were passed.
 *    @param[out] sys System the jump exists in.
 *    @return Jump found at the index in the state.
 *
 * @sa luaL_validjump
 */
static JumpPoint* luaL_validjumpSystem( lua_State *L, int ind, int *offset, StarSystem **outsys )
{
   LuaJump *lj;
   JumpPoint *jp;
   StarSystem *a, *b;

   /* Defaults. */
   jp = NULL;
   a = NULL;
   b = NULL;

   if (lua_isjump(L, ind)) {
      lj = luaL_checkjump(L, ind);
      a = system_getIndex( lj->srcid );
      b = system_getIndex( lj->destid );
      if (offset != NULL)
         *offset = 1;
   }
   else if (lua_gettop(L) > 1) {
      if (lua_isstring(L, ind))
         a = system_get( lua_tostring( L, ind ));
      else if (lua_issystem(L, ind))
         a = system_getIndex( lua_tosystem(L, ind) );

      if (lua_isstring(L, ind+1))
         b = system_get( lua_tostring( L, ind+1 ));
      else if (lua_issystem(L, ind+1))
         b = system_getIndex( lua_tosystem(L, ind+1) );

      if (offset != NULL)
         *offset = 2;
   }
   else {
      luaL_typerror(L, ind, JUMP_METATABLE);
      return NULL;
   }

   if (b != NULL && a != NULL)
         jp = jump_getTarget( b, a );

   if (jp == NULL)
      NLUA_ERROR(L, "Jump is invalid");

   if (outsys != NULL)
      *outsys = a;
   return jp;
}
Example #7
0
/**
 * @brief Gets a jump.
 *
 * Possible values of params: <br/>
 *    - string : Gets the jump by system name. <br/>
 *    - system : Gets the jump by system. <br/>
 *
 * @usage j,r  = jump.get( "Ogat", "Goddard" ) -- Returns the Ogat to Goddard and Goddard to Ogat jumps.
 *    @luaparam param See description.
 *    @luareturn Returns the jump and the inverse (where it exits).
 * @luafunc get( param )
 */
static int jumpL_get( lua_State *L )
{
   LuaJump lj;
   StarSystem *a, *b;

   /* Defaults. */
   a = NULL;
   b = NULL;

   if (lua_gettop(L) > 1) {
      if (lua_isstring(L, 1))
         a = system_get( lua_tostring(L, 1));
      else if (lua_issystem(L, 1))
         a = system_getIndex( lua_tosystem(L, 1) );

      if (lua_isstring(L, 2))
         b = system_get( lua_tostring(L, 2));
      else if (lua_issystem(L, 2))
         b = system_getIndex( lua_tosystem(L, 2) );

      if ((a == NULL) || (b == NULL)) {
         NLUA_ERROR(L, "No matching jump points found.");
         return 0;
      }

      if (jump_getTarget(b, a) != NULL) {
         lj.srcid  = a->id;
         lj.destid = b->id;
         lua_pushjump(L, lj);

         /* The inverse. If it doesn't exist, there are bigger problems. */
         lj.srcid  = b->id;
         lj.destid = a->id;
         lua_pushjump(L, lj);
         return 2;
      }
   }
   else
      NLUA_INVALID_PARAMETER(L);

   return 0;
}
Example #8
0
/**
 * @brief Gets system (or system name) at index raising an error if type doesn't match.
 *
 *    @param L Lua state to get system from.
 *    @param ind Index position of system.
 *    @return The System at ind.
 */
StarSystem* luaL_validsystem( lua_State *L, int ind )
{
   LuaSystem *ls;
   StarSystem *s;

   if (lua_issystem(L, ind)) {
      ls = luaL_checksystem(L, ind);
      s = system_getIndex( ls->id );
   }
   else if (lua_isstring(L, ind))
      s = system_get( lua_tostring(L, ind) );
   else {
      luaL_typerror(L, ind, FACTION_METATABLE);
      return NULL;
   }

   if (s == NULL)
      NLUA_ERROR(L, "System is invalid");

   return s;
}
Example #9
0
/**
 * @brief Teleports the player to a new system (only if not landed).
 *
 * Does not change the position nor velocity of the player.p, which will probably be wrong in the new system.
 *
 * @usage player.teleport( system.get("Arcanis") ) -- Teleports the player to arcanis.
 * @usage player.teleport( "Arcanis" ) -- Teleports the player to arcanis.
 *
 *    @luaparam sys System or name of a system to teleport the player to.
 * @luafunc teleport( sys )
 */
static int playerL_teleport( lua_State *L )
{
   LuaSystem *sys;
   const char *name;

   /* Must not be landed. */
   if (landed)
      NLUA_ERROR(L,"Can not teleport the player while landed!");
   if (comm_isOpen())
      NLUA_ERROR(L,"Can not teleport the player while the comm is open!");
   if (player_isBoarded())
      NLUA_ERROR(L,"Can not teleport the player while he is boarded!");

   /* Get a system. */
   if (lua_issystem(L,1)) {
      sys   = lua_tosystem(L,1);
      name  = system_getIndex(sys->id)->name;
   }
   else if (lua_isstring(L,1))
      name = lua_tostring(L,1);
   else
      NLUA_INVALID_PARAMETER(L);

   /* Check if system exists. */
   if (!system_exists( name )) {
      NLUA_ERROR( L, "System '%s' does not exist.", name );
      return 0;
   }

   /* Jump out hook is run first. */
   hooks_run( "jumpout" );

   /* Just in case remove hyperspace flags. */
   pilot_rmFlag( player.p, PILOT_HYPERSPACE );
   pilot_rmFlag( player.p, PILOT_HYP_BEGIN );
   pilot_rmFlag( player.p, PILOT_HYP_BRAKE );
   pilot_rmFlag( player.p, PILOT_HYP_PREP );

   /* Free graphics. */
   space_gfxUnload( cur_system );

   /* Go to the new system. */
   space_init( name );

   /* Map gets deformed when jumping this way. */
   map_clear();

   /* Add the escorts. */
   player_addEscorts();

   /* Run hooks - order is important. */
   hooks_run( "jumpin" );
   hooks_run( "enter" );
   events_trigger( EVENT_TRIGGER_ENTER );

   /* Reset targets when teleporting */
   player_targetPlanetSet( -1 );
   player_targetHyperspaceSet( -1 );
   gui_setNav();
   return 0;
}
Example #10
0
/**
 * @brief Teleports the player to a new planet or system (only if not landed).
 *
 * If the destination is a system, the coordinates of the player will not change.
 * If the destination is a planet, the player will be placed over that planet.
 *
 * @usage player.teleport( system.get("Arcanis") ) -- Teleports the player to Arcanis.
 * @usage player.teleport( "Arcanis" ) -- Teleports the player to Arcanis.
 * @usage player.teleport( "Dvaer Prime" ) -- Teleports the player to Dvaer, and relocates him to Dvaer Prime.
 *
 *    @luaparam dest System or name of a system or planet or name of a planet to teleport the player to.
 * @luafunc teleport( dest )
 */
static int playerL_teleport( lua_State *L )
{
    Planet *pnt;
    StarSystem *sys;
    const char *name, *pntname;

    /* Must not be landed. */
    if (landed)
        NLUA_ERROR(L,"Can not teleport the player while landed!");
    if (comm_isOpen())
        NLUA_ERROR(L,"Can not teleport the player while the comm is open!");
    if (player_isBoarded())
        NLUA_ERROR(L,"Can not teleport the player while he is boarded!");

    pnt = NULL;

    /* Get a system. */
    if (lua_issystem(L,1)) {
        sys   = luaL_validsystem(L,1);
        name  = system_getIndex(sys->id)->name;
    }
    /* Get a planet. */
    else if (lua_isplanet(L,1)) {
        pnt   = luaL_validplanet(L,1);
        name  = planet_getSystem( pnt->name );
        if (name == NULL) {
            NLUA_ERROR( L, "Planet '%s' does not belong to a system..", pnt->name );
            return 0;
        }
    }
    /* Get destination from string. */
    else if (lua_isstring(L,1)) {
        name = lua_tostring(L,1);
        if (!system_exists( name )) {
            if (!planet_exists( name )) {
                NLUA_ERROR( L, "'%s' is not a valid teleportation target.", name );
                return 0;
            }

            /* No system found, assume destination string is the name of a planet. */
            pntname = name;
            name = planet_getSystem( name );
            pnt  = planet_get( pntname );
            if (name == NULL) {
                NLUA_ERROR( L, "Planet '%s' does not belong to a system..", pntname );
                return 0;
            }
        }
    }
    else
        NLUA_INVALID_PARAMETER(L);

    /* Check if system exists. */
    if (!system_exists( name )) {
        NLUA_ERROR( L, "System '%s' does not exist.", name );
        return 0;
    }

    /* Jump out hook is run first. */
    hooks_run( "jumpout" );

    /* Just in case remove hyperspace flags. */
    pilot_rmFlag( player.p, PILOT_HYPERSPACE );
    pilot_rmFlag( player.p, PILOT_HYP_BEGIN );
    pilot_rmFlag( player.p, PILOT_HYP_BRAKE );
    pilot_rmFlag( player.p, PILOT_HYP_PREP );

    /* Free graphics. */
    space_gfxUnload( cur_system );

    /* Go to the new system. */
    space_init( name );

    /* Map gets deformed when jumping this way. */
    map_clear();

    /* Add the escorts. */
    player_addEscorts();

    /* Run hooks - order is important. */
    hooks_run( "jumpin" );
    hooks_run( "enter" );
    events_trigger( EVENT_TRIGGER_ENTER );
    missions_run( MIS_AVAIL_SPACE, -1, NULL, NULL );

    /* Reset targets when teleporting */
    player_targetPlanetSet( -1 );
    player_targetHyperspaceSet( -1 );
    gui_setNav();

    /* Move to planet. */
    if (pnt != NULL)
        vectcpy( &player.p->solid->pos, &pnt->pos );

    return 0;
}
Example #11
0
/**
 * @brief Persists the node on the top of the stack and pops it.
 *
 *    @param L Lua state with node to persist on top of the stack.
 *    @param writer XML Writer to use.
 *    @param Are we parsing a node in a table?  Avoids checking for extra __save.
 *    @return 0 on success.
 */
static int nxml_persistDataNode( lua_State *L, xmlTextWriterPtr writer, int intable )
{
   int ret, b;
   LuaPlanet *p;
   LuaSystem *s;
   LuaFaction *f;
   LuaShip *sh;
   LuaTime *lt;
   Planet *pnt;
   StarSystem *ss;
   char buf[PATH_MAX];
   const char *name, *str;
   int keynum;

   /* Default values. */
   ret   = 0;

   /* key, value */
   /* Handle different types of keys. */
   switch (lua_type(L, -2)) {
      case LUA_TSTRING:
         /* Can just tostring directly. */
         name     = lua_tostring(L,-2);
         /* Isn't a number key. */
         keynum   = 0;
         break;
      case LUA_TNUMBER:
         /* Can't tostring directly. */
         lua_pushvalue(L,-2);
         name     = lua_tostring(L,-1);
         lua_pop(L,1);
         /* Is a number key. */
         keynum   = 1;
         break;

      /* We only handle string or number keys, so ignore the rest. */
      default:
         lua_pop(L,1);
         /* key */
         return 0;
   }
   /* key, value */

   /* Now handle the value. */
   switch (lua_type(L, -1)) {
      /* Recursive for tables. */
      case LUA_TTABLE:
         /* Check if should save -- only if not in table.. */
         if (!intable) {
            lua_getfield(L, -1, "__save");
            b = lua_toboolean(L,-1);
            lua_pop(L,1);
            if (!b) /* No need to save. */
               break;
         }
         /* Start the table. */
         xmlw_startElem(writer,"data");
         xmlw_attr(writer,"type","table");
         xmlw_attr(writer,"name","%s",name);
         if (keynum)
            xmlw_attr(writer,"keynum","1");
         lua_pushnil(L); /* key, value, nil */
         /* key, value, nil */
         while (lua_next(L, -2) != 0) {
            /* key, value, key, value */
            ret = nxml_persistDataNode( L, writer, 1 );
            /* key, value, key */
         }
         /* key, value */
         xmlw_endElem(writer); /* "table" */
         break;

      /* Normal number. */
      case LUA_TNUMBER:
         nxml_saveData( writer, "number",
               name, lua_tostring(L,-1), keynum );
         /* key, value */
         break;

      /* Boolean is either 1 or 0. */
      case LUA_TBOOLEAN:
         /* lua_tostring doesn't work on booleans. */
         if (lua_toboolean(L,-1)) buf[0] = '1';
         else buf[0] = '0';
         buf[1] = '\0';
         nxml_saveData( writer, "bool",
               name, buf, keynum );
         /* key, value */
         break;

      /* String is saved normally. */
      case LUA_TSTRING:
         nxml_saveData( writer, "string",
               name, lua_tostring(L,-1), keynum );
         /* key, value */
         break;

      /* User data must be handled here. */
      case LUA_TUSERDATA:
         if (lua_isplanet(L,-1)) {
            p = lua_toplanet(L,-1);
            pnt = planet_getIndex( p->id );
            if (pnt != NULL)
               nxml_saveData( writer, "planet",
                     name, pnt->name, keynum );
            else
               WARN("Failed to save invalid planet.");
            /* key, value */
            break;
         }
         else if (lua_issystem(L,-1)) {
            s  = lua_tosystem(L,-1);
            ss = system_getIndex( s->id );
            if (ss != NULL)
               nxml_saveData( writer, "system",
                     name, ss->name, keynum );
            else
               WARN("Failed to save invalid system.");
            /* key, value */
            break;
         }
         else if (lua_isfaction(L,-1)) {
            f = lua_tofaction(L,-1);
            str = faction_name( f->f );
            if (str == NULL)
               break;
            nxml_saveData( writer, "faction",
                  name, str, keynum );
            /* key, value */
            break;
         }
         else if (lua_isship(L,-1)) {
            sh = lua_toship(L,-1);
            str = sh->ship->name;
            if (str == NULL)
               break;
            nxml_saveData( writer, "ship",
                  name, str, keynum );
            /* key, value */
            break;
         }
         else if (lua_istime(L,-1)) {
            lt = lua_totime(L,-1);
            snprintf( buf, sizeof(buf), "%"PRId64, lt->t );
            nxml_saveData( writer, "time",
                  name, buf, keynum );
            break;
         }

      /* Rest gets ignored, like functions, etc... */
      default:
         /* key, value */
         break;
   }
   lua_pop(L,1);
   /* key */

   return ret;
}