nic's dynamic ship definition patch. a little reworked so model .lua files don't call a define_ship function, but instead put ship info in ship_defs attribute and tag model as ship. works better with the modelviewer since it doesn't pull in a whole load of core pioneer dependencies. also similar to way extra spacestation attributes are specified

git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@570 e632f14b-6550-0410-b89e-a82653faca30
master
tompox 2010-03-30 12:44:20 +00:00
parent d8a336ae03
commit b4ce2d6713
20 changed files with 584 additions and 141 deletions

View File

@ -0,0 +1,85 @@
define_model('cobra_mk3', {
info = {
lod_pixels = { 50, 100, 200, 0 },
bounding_radius = 100,
materials = {'thrusters', 'text'},
tags = {'ship'},
ship_defs = {
{
'Cobra Mk III',
{ 2*10^7,-2*10^7,1*10^7,-1*10^7,-1*10^7,1*10^7 },
4*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,-0.5,0), v(0,0,1) },
},
{ 90, 1, 2, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
90, 100, 16000000,
1
}
}
},
static = function(lod)
load_obj('cobra3_redux.obj', Mat4x4.new(v(45,0,0),v(0,45,0),v(0,0,45)) * Mat4x4.new(v(-1,0,0),v(0,1,0),v(0,0,-1)))
set_material('thrusters', .30, .30, .30,1, .30, .30, .30, 20)
use_material('thrusters')
local vBackThruster = v(8, 0.7, 14.5) -- last number is how far back down the ship it is
local vFrontThruster = v(3.5, -1.0, -5.0)
xref_thruster(vBackThruster, v(0,0,1), 30, true)
xref_thruster(vFrontThruster, v(0,0,-1), 20, true)
local TopThrust1 = v(-9.0, 1.5, 11.0)
local TopThrust2 = v(9.0, 1.5, 11.0)
local TopThrustForward = v(0.0, 1.5, -11.0)
local BottomThrust1 = v(-9.0, -0.5, 10.0)
local BottomThrust2 = v(9.0, -0.5, 10.0)
local BottomThrustForward = v(0.0, -0.5, -10.0)
thruster(TopThrust1, v(0,1,0), 15)
thruster(TopThrust2, v(0,1,0), 15)
thruster(TopThrustForward, v(0,1,0), 15)
thruster(BottomThrust1, v(0,-1,0), 15)
thruster(BottomThrust2, v(0,-1,0), 15)
thruster(BottomThrustForward, v(0,-1,0), 15)
local LeftBackThruster = v(-18.0, 0.0, 10.0)
local LeftForwardThruster = v(-3.5, 0.0, -10.0)
local RightBackThruster = v(18.0, 0.0, 10.0)
local RightForwardThruster = v(3.5, 0.0, -10.0)
thruster(LeftBackThruster, v(-1,0,0), 15)
thruster(LeftForwardThruster, v(-1,0,0), 15)
thruster(RightBackThruster, v(1,0,0), 15)
thruster(RightForwardThruster, v(1,0,0), 15)
end,
dynamic = function(lod)
if get_arg(0) ~= 0 then
-- lights on wingtips
local lightphase = math.fmod(get_arg(1), 1)
if lightphase > .9 then
billboard('smoke.png', 10, v(1,1,1), { v(-29, 0, 14) })
elseif lightphase > .8 then
billboard('smoke.png', 10, v(1,1,1), { v(29, 0, 14) }) -- middle number is how high vertically on the ship
end
-- wheels
local v73 = v(0.0, -1.0, -5.5)
local v74 = v(-4.5, -4.5, 10.5)
local v75 = v(4.5, -4.5, 10.5)
zbias(1, v73, v(0,-1,0))
-- nose wheel
call_model('nosewheelunit', v73, v(-1,0,0), v(0,-1,0), 1.2)
zbias(1, v74, v(0,-1,0))
-- rear wheels
call_model('nosewheelunit', v74, v(-1,0,0), v(0,-1,0), .64)
call_model('nosewheelunit', v75, v(-1,0,0), v(0,-1,0), .64)
zbias(0)
end
end
})

View File

@ -0,0 +1,13 @@
# Blender3D MTL File:
# Material Count: 1
newmtl cobra3_redux_auv_cobra3_redux.png
Ns 98.039216
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd cobra3_redux.png

View File

@ -0,0 +1,73 @@
# Blender3D v249 OBJ File:
# www.blender3d.org
mtllib cobra3_redux.mtl
v 0.000000 0.150000 -0.000000
v -0.160000 -0.005000 0.325000
v 0.160000 -0.005000 0.325000
v -0.160000 -0.150000 -0.325000
v 0.160000 -0.150000 -0.325000
v 0.440000 0.100000 -0.325000
v 0.600000 -0.030000 -0.130000
v 0.650000 -0.030000 -0.325000
v -0.440000 0.100000 -0.325000
v -0.600000 -0.030000 -0.130000
v -0.650000 -0.030000 -0.325000
v 0.000000 0.150000 -0.325000
vt 0.597272 0.596730
vt 0.807101 0.498491
vt 0.989045 0.764906
vt 0.597150 0.400215
vt 0.187142 0.597479
vt 0.320941 0.872075
vt 0.187173 0.400220
vt 0.201678 0.090000
vt 0.320416 0.125481
vt 0.989458 0.231931
vt 0.857320 0.125973
vt 0.970709 0.085571
vt 0.997979 0.498564
vt 0.031880 0.770370
vt 0.001961 0.498344
vt 0.033533 0.227184
vt 0.114031 0.097948
vt 0.111804 0.900773
vt 0.857040 0.870578
vt 0.970035 0.910844
vt 0.202224 0.907788
vn -0.310344 0.908324 0.280416
vn 0.000000 0.902604 0.430472
vn -0.167301 -0.962254 0.214657
vn 0.000000 -0.976010 0.217725
vn 0.237428 -0.969496 0.060879
vn 0.310344 0.908324 0.280416
vn 0.357445 0.885448 0.297010
vn 0.167301 -0.962254 0.214657
vn 0.521625 0.842625 0.133750
vn -0.112910 0.993605 -0.000000
vn 0.000000 0.000000 -1.000000
vn -0.357445 0.885448 0.297010
vn -0.521625 0.842625 0.133750
vn -0.237428 -0.969496 0.060879
vn 0.112910 0.993605 -0.000000
usemtl cobra3_redux_auv_cobra3_redux.png
s off
f 2/1/1 1/2/1 9/3/1
f 3/4/2 1/2/2 2/1/2
f 4/5/3 2/1/3 10/6/3
f 5/7/4 3/4/4 2/1/4
f 5/7/4 2/1/4 4/5/4
f 5/7/5 8/8/5 7/9/5
f 6/10/6 1/2/6 3/4/6
f 6/10/7 3/4/7 7/11/7
f 7/9/8 3/4/8 5/7/8
f 8/12/9 6/10/9 7/11/9
f 9/3/10 1/2/10 12/13/10
f 9/14/11 12/15/11 6/16/11
f 9/14/11 6/16/11 8/17/11
f 9/14/11 8/17/11 5/7/11
f 9/14/11 5/7/11 4/5/11
f 9/14/11 4/5/11 11/18/11
f 10/19/12 2/1/12 9/3/12
f 10/19/13 9/3/13 11/20/13
f 10/6/14 11/21/14 4/5/14
f 12/13/15 1/2/15 6/10/15

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

View File

@ -3,9 +3,41 @@ print("REMEMBER TO PORT ship6model!!!");
define_model('missile', {
info = {
bounding_radius = 4,
materials={'body'}
bounding_radius = 4,
materials={ 'body' },
tags = { 'ship' },
ship_defs = {
{
'MISSILE_UNGUIDED',
{ 0, -4*10^5, 0, 0, 0, 0 },
0,
{},
{ 0, 0, 1, 0 },
90, 100, 16000000
}, {
'MISSILE_GUIDED',
{ 1*10^5, -2*10^5, 0, 0, 0, 0 },
2*10^4,
{},
{ 0, 0, 1, 0 },
10, 1, 100
}, {
'MISSILE_SMART',
{ 1.5*10^5, -3*10^5, 0, 0, 0, 0 },
2*10^4,
{},
{ 0, 0, 1, 0 },
10, 1, 100
}, {
'MISSILE_NAVAL',
{ 2.0*10^5, -4*10^5, 0, 0, 0, 0 },
2*10^4,
{},
{ 0, 0, 1, 0 },
10, 1, 100
}
},
},
static = function(lod)
set_material('body', 1,1,1,1)
use_material('body')
@ -14,6 +46,8 @@ define_model('missile', {
end
})
define_model('nosewheel', {
info = {
lod_pixels={5,50,0},
@ -134,7 +168,33 @@ define_model('ladybird', {
lod_pixels = {50,100,200,0},
bounding_radius = 35,
materials={'white','engines','matvar0', 'matvar2',
'engine_inside'}
'engine_inside'},
tags = {'ship'},
ship_defs = {
{
'Ladybird Starfighter',
{ 2*10^6,-2*10^6,1*10^6,-1*10^6,-1*10^6,2*10^6 },
1*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,0,0), v(0,0,1) },
},
{ 60, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
60, 60, 8700000,
2
}, {
'Taipan',
{ 4*10^6,-4*10^6,1*10^6,-1*10^6,-1*10^6,1*10^6 },
1*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,0,0), v(0,0,1) },
},
{ 240, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
240, 200, 56000000,
4
}
},
},
static = function(lod)
local v06 = v(-4.0, -5.0, -20.0);
@ -247,6 +307,7 @@ define_model('ladybird', {
end
})
define_model('__walruswing', {
info = {
lod_pixels = { 20, 50, 0 },
@ -281,7 +342,22 @@ define_model('walrus', {
info = {
scale = 1.0,
bounding_radius = 70,
materials = {'matvar0', 'text'}
materials = {'matvar0', 'text'},
tags = { 'ship' },
ship_defs = {
{
'Walrus',
{ 12*10^6,-12*10^6,4*10^6,-4*10^6,-4*10^6,4*10^6 },
1*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,0,0), v(0,0,1) },
},
{ 320, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
320, 300, 35000000,
5
}
}
},
static = function()
local v06 = v(-5.0, 10.0, -30.0)
@ -421,7 +497,22 @@ define_model('flowerfairy_heavy_trader', {
scale=2.0,
lod_pixels = {25,50,0},
bounding_radius = 100,
materials = {'matvar0','gray','text','engine_inside'}
materials = {'matvar0','gray','text','engine_inside'},
tags = {'ship'},
ship_defs = {
{
'Flowerfairy Heavy Trader',
{ 1*10^5,-1*10^5,1*10^5,-1*10^5,-1*10^5,1*10^5 },
1*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,0,0), v(0,0,1) },
},
{ 500, 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
500, 500, 55000000,
6
}
}
},
static = function(lod)
-- // 6, nose vertices
@ -551,7 +642,22 @@ define_model('interdictor', {
info = {
lod_pixels = { 50, 100, 200, 0 },
bounding_radius = 100,
materials = {'matvar0', 'matvar2', 'engine', 'engine_inside', 'cockpit', 'text'}
materials = {'matvar0', 'matvar2', 'engine', 'engine_inside', 'cockpit', 'text'},
tags = {'ship'},
ship_defs = {
{
'Sirius Interdictor',
{ 2*10^7,-2*10^7,1*10^7,-1*10^7,-1*10^7,1*10^7 },
4*10^7,
{
{ v(0,-0.5,0), v(0,0,-1) },
{ v(0,-0.5,0), v(0,0,1) },
},
{ 90, 1, 2, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
90, 100, 16000000,
1
}
}
},
static = function(lod)
local nose_tip = v(0.0, 0.0, -35.0)
@ -875,3 +981,4 @@ define_model('interdictor', {
end
})
load_lua('data/models/mods')

View File

@ -5,6 +5,14 @@
#include "collider/collider.h"
#include "perlin.h"
#include "Render.h"
#ifdef _WIN32
#include <../msvc/win32-dirent.h>
#else
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#define MODEL "Model"
struct RenderState {
@ -793,7 +801,7 @@ int LmrModel::GetIntAttribute(const char *attr_name) const
return result;
}
void LmrModel::PushAttributeToStack(const char *attr_name) const
void LmrModel::PushAttributeToLuaStack(const char *attr_name) const
{
char buf[256];
snprintf(buf, sizeof(buf), "%s_info", m_name.c_str());
@ -2027,10 +2035,15 @@ namespace ObjLoader {
*end = 0;
}
static std::map<std::string, std::string> load_mtl_file(const char* mtl_file) {
static std::map<std::string, std::string> load_mtl_file(lua_State *L, const char* mtl_file) {
std::map<std::string, std::string> mtl_map;
char buf[1024], name[1024] = "", file[1024];
snprintf(buf, sizeof(buf), "data/models/%s", mtl_file);
lua_getglobal(L, "CurrentDirectory");
std::string curdir = luaL_checkstring(L, -1);
lua_pop(L, 1);
snprintf(buf, sizeof(buf), "%s/%s", curdir.c_str(), mtl_file);
FILE *f = fopen(buf, "r");
if (!f) {
printf("Could not open %s\n", buf);
@ -2058,9 +2071,13 @@ namespace ObjLoader {
if (numArgs > 1) {
transform = MyLuaMatrix::checkMat4x4(L, 2);
}
lua_getglobal(L, "CurrentDirectory");
std::string curdir = luaL_checkstring(L, -1);
lua_pop(L, 1);
char buf[1024];
snprintf(buf, sizeof(buf), "data/models/%s", obj_name);
snprintf(buf, sizeof(buf), "%s/%s", curdir.c_str(), obj_name);
FILE *f = fopen(buf, "r");
if (!f) {
printf("Could not open %s\n", buf);
@ -2170,7 +2187,7 @@ namespace ObjLoader {
else if (strncmp("mtllib ", buf, 7) == 0) {
char lib_name[128];
if (1 == sscanf(buf, "mtllib %s", lib_name)) {
mtl_map = load_mtl_file(lib_name);
mtl_map = load_mtl_file(L, lib_name);
}
}
else if (strncmp("usemtl ", buf, 7) == 0) {
@ -2179,7 +2196,7 @@ namespace ObjLoader {
if ( mtl_map.find(mat_name) != mtl_map.end() ) {
try {
char texfile[256];
snprintf(texfile, sizeof(texfile), "data/models/%s", mtl_map[mat_name].c_str());
snprintf(texfile, sizeof(texfile), "%s/%s", curdir.c_str(), mtl_map[mat_name].c_str());
texture = util_load_tex_rgba(texfile);
} catch (LmrUnknownMaterial) {
printf("Warning: Missing material %s (%s) in %s\n", mtl_map[mat_name], mat_name, obj_name);
@ -2209,6 +2226,56 @@ namespace UtilFuncs {
lua_pushnumber(L, noise(v));
return 1;
}
void lua_traverse(lua_State *L, const char *fn) {
DIR *dir;
struct dirent *entry;
int count;
char path[1024];
struct stat info;
lua_getglobal(L, "CurrentDirectory");
std::string save_dir = luaL_checkstring(L, -1);
lua_pop(L, 1);
lua_pushstring(L, fn);
lua_setglobal(L, "CurrentDirectory");
if ((dir = opendir(fn)) == NULL)
perror("opendir() error");
else {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] != '.') {
strcpy(path, fn);
strcat(path, "/");
strcat(path, entry->d_name);
if (stat(path, &info) != 0)
fprintf(stderr, "stat() error on %s: %s\n", path, strerror(errno));
else {
if (S_ISDIR(info.st_mode))
lua_traverse(L, path);
else {
if ( strlen(entry->d_name) >= strlen(".lua") && strcasecmp(entry->d_name+strlen(entry->d_name)-4, ".lua") == 0)
if (luaL_dofile(L, path)) {
printf("%s\n", lua_tostring(L, -1));
break;
}
}
}
}
}
closedir(dir);
}
lua_pushstring(L, save_dir.c_str());
lua_setglobal(L, "CurrentDirectory");
}
int load_lua(lua_State *L) {
const char *fn = luaL_checkstring(L, 1);
lua_traverse(L, fn);
return 0;
}
} /* UtilFuncs */
static int define_model(lua_State *L)
@ -2313,8 +2380,11 @@ void LmrModelCompilerInit()
lua_register(L, "call_model", ModelFuncs::call_model);
lua_register(L, "noise", UtilFuncs::noise);
lua_register(L, "load_obj", ObjLoader::load_obj_file);
lua_register(L, "load_lua", UtilFuncs::load_lua);
s_buildDynamic = false;
lua_pushstring(L, "data/models");
lua_setglobal(L, "CurrentDirectory");
if (luaL_dofile(L, "data/models/models.lua")) {
printf("%s\n", lua_tostring(L, -1));
}

View File

@ -47,7 +47,7 @@ public:
float GetBoundingRadius() const { return m_boundingRadius; }
float GetFloatAttribute(const char *attr_name) const;
int GetIntAttribute(const char *attr_name) const;
void PushAttributeToStack(const char *attr_name) const;
void PushAttributeToLuaStack(const char *attr_name) const;
const char *GetName() const { return m_name.c_str(); }
private:
void Build(int lod, const LmrObjParams *params);

View File

@ -6,13 +6,11 @@
Missile::Missile(ShipType::Type type, Body *owner, Body *target): Ship(type)
{
switch (type) {
case ShipType::MISSILE_GUIDED: m_power = 1; break;
case ShipType::MISSILE_SMART: m_power = 2; break;
case ShipType::MISSILE_NAVAL: m_power = 3; break;
default:
case ShipType::MISSILE_UNGUIDED: m_power = 0; break;
};
m_power = 0;
if (type == ShipType::MISSILE_GUIDED) m_power = 1;
if (type == ShipType::MISSILE_SMART) m_power = 2;
if (type == ShipType::MISSILE_NAVAL) m_power = 3;
m_owner = owner;
m_target = target;
m_distToTarget = FLT_MAX;

View File

@ -27,4 +27,31 @@ namespace MyLuaMatrix {
int Mat4x4_register (lua_State *L);
}; /* namespace MyLuaMatrix */
// i'll just throw them in here...
static inline const char *luaPi_gettable_checkstring(lua_State *L, int table, int idx)
{
lua_pushinteger(L, idx);
lua_gettable(L, (table<0 ? table-1 : table));
const char *r = luaL_checkstring(L, -1);
lua_pop(L, 1);
return r;
}
static inline double luaPi_gettable_checknumber(lua_State *L, int table, int idx)
{
lua_pushinteger(L, idx);
lua_gettable(L, (table<0 ? table-1 : table));
double num = luaL_checknumber(L, -1);
lua_pop(L, 1);
return num;
}
static inline int luaPi_gettable_checkinteger(lua_State *L, int table, int idx)
{
lua_pushinteger(L, idx);
lua_gettable(L, (table<0 ? table-1 : table));
int num = luaL_checkinteger(L, -1);
lua_pop(L, 1);
return num;
}
#endif /* _MYLUAMATHTYPES_H */

View File

@ -8,6 +8,7 @@
#include "Star.h"
#include "Frame.h"
#include "ShipCpanel.h"
#include "ShipType.h"
#include "SectorView.h"
#include "SystemView.h"
#include "SystemInfoView.h"
@ -161,6 +162,7 @@ void Pi::Init(IniConfig &config)
GLFTInit();
LmrModelCompilerInit();
ShipType::Init();
GeoSphere::Init();
Space::Init();
Polit::Init();

View File

@ -23,6 +23,7 @@ class SpaceStation;
class GalacticView;
struct SBodyPath;
class GameMenuView;
struct lua_State;
class IniConfig: private std::map<std::string, std::string> {
public:
@ -116,6 +117,7 @@ public:
static ShipCpanel *cpan;
static GLUquadric *gluQuadric;
static StarSystem *currentSystem;
static lua_State *luaPersistent;
static int CombatRating(int kills);
static const char * const combatRating[];

View File

@ -121,7 +121,7 @@ void Ship::Load()
void Ship::Init()
{
const ShipType &stype = GetShipType();
SetModel(stype.sbreModelName);
SetModel(stype.lmrModelName.c_str());
SetMassDistributionFromModel();
UpdateMass();
m_stats.hull_mass_left = (float)stype.hullMass;

View File

@ -10,7 +10,8 @@ static const LmrMaterial s_white = { { 1.0f, 1.0f, 1.0f, 1.0f } };
ShipFlavour::ShipFlavour()
{
memset(this, 0, sizeof(ShipFlavour));
regid[0] = 0;
price = 0;
}
void ShipFlavour::MakeRandomColor(LmrMaterial &m)
@ -52,7 +53,7 @@ ShipFlavour::ShipFlavour(ShipType::Type type)
void ShipFlavour::MakeTrulyRandom(ShipFlavour &v)
{
v = ShipFlavour(static_cast<ShipType::Type>(Pi::rng.Int32(ShipType::END)));
v = ShipFlavour(ShipType::GetRandomType());
}
void ShipFlavour::ApplyTo(LmrObjParams *p) const
@ -88,7 +89,7 @@ void ShipFlavour::LoadLmrMaterial(LmrMaterial *m)
void ShipFlavour::Save()
{
using namespace Serializer::Write;
wr_int((int)type);
wr_string(type);
wr_int(price);
wr_string(regid);
SaveLmrMaterial(&primaryColor);
@ -98,7 +99,7 @@ void ShipFlavour::Save()
void ShipFlavour::Load()
{
using namespace Serializer::Read;
type = static_cast<ShipType::Type>(rd_int());
type = rd_string();
price = rd_int();
rd_cstring2(regid, sizeof(regid));
LoadLmrMaterial(&primaryColor);

View File

@ -1,115 +1,152 @@
#include "ShipType.h"
#include "LmrModel.h"
#include "Serializer.h"
#include "MyLuaMathTypes.h"
#include "Pi.h"
#include "utils.h"
const char *ShipType::gunmountNames[GUNMOUNT_MAX] = {
"Front", "Rear" };
const ShipType ShipType::types[] = {
{
"Swordfish Starfighter",
"66",
{ 2e6,-2e6,1e6,-1e6,-1e6,1e6 },
1e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,0,0), vector3f(0,0,1) }
},
{ 20, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
20, 20, 4000000,
Equip::DRIVE_CLASS1,
}, {
// besides running a wicked corporatist regime in the
// sirius system, Sirius corporation make a range of
// lovely starships
"Sirius Interdictor", "interdictor",
{ 2e7,-2e7,1e7,-1e7,-1e7,1e7 },
4e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,-0.5,0), vector3f(0,0,1) }
},
{ 90, 1, 2, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
90, 100, 16000000,
Equip::DRIVE_CLASS3,
}, {
// john - you should pick names yourself or this happens
"Ladybird Starfighter",
"ladybird",
{ 2e6,-2e6,1e6,-1e6,-1e6,1e6 },
1e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,0,0), vector3f(0,0,1) }
},
{ 60, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
60, 60, 8700000,
Equip::DRIVE_CLASS2,
}, {
"Taipan",
"ladybird",
{ 4e6,-4e6,1e6,-1e6,-1e6,1e6 },
1e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,0,0), vector3f(0,0,1) }
},
{ 240, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
240, 200, 56000000,
Equip::DRIVE_CLASS4,
}, {
"Walrus",
"walrus",
{ 12e6,-12e6,4e6,-4e6,-4e6,4e6 },
1e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,0,0), vector3f(0,0,1) }
},
{ 320, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
320, 300, 35000000,
Equip::DRIVE_CLASS5,
}, {
"Flowerfairy Heavy Trader",
"flowerfairy_heavy_trader",
{ 1e5,-1e5,1e5,-1e5,-1e5,1e5 },
1e7,
{
{ vector3f(0,-0.5,0), vector3f(0,0,-1) },
{ vector3f(0,0,0), vector3f(0,0,1) }
},
{ 500, 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
500, 500, 55000000,
Equip::DRIVE_CLASS6,
}, {
0,
"missile",
{ 0, -4e5, 0, 0, 0, 0 },
0, {},
{ 0, 0, 1, 0 },
10, 1, 100
}, {
0,
"missile",
{ 1e5, -2e5, 0, 0, 0, 0 },
2e4, {},
{ 0, 0, 1, 0 },
10, 1, 100
}, {
0,
"missile",
{ 1.5e5, -3e5, 0, 0, 0, 0 },
2e4, {},
{ 0, 0, 1, 0 },
10, 1, 100
}, {
0,
"missile",
{ 2.0e5, -4e5, 0, 0, 0, 0 },
2e4, {},
{ 0, 0, 1, 0 },
10, 1, 100
std::map<ShipType::Type, ShipType> ShipType::types;
std::string ShipType::LADYBIRD = "Ladybird Starfighter";
std::string ShipType::SIRIUS_INTERDICTOR = "Sirius Interdictor";
std::string ShipType::MISSILE_GUIDED = "MISSILE_GUIDED";
std::string ShipType::MISSILE_NAVAL = "MISSILE_NAVAL";
std::string ShipType::MISSILE_SMART = "MISSILE_SMART";
std::string ShipType::MISSILE_UNGUIDED = "MISSILE_UNGUIDED";
int ShipType::define_ship(lua_State *L, const char *model_name)
{
ShipType s;
printf("%s\n", model_name);
s.name = luaPi_gettable_checkstring(L, -1, 1);
printf("%s!\n", s.name.c_str());
s.lmrModelName = model_name;
lua_rawgeti(L, -1, 2);
bool malformed = false;
if (lua_istable(L, -1)) {
for (int i=0; i<THRUSTER_MAX; i++) {
lua_pushinteger(L, i+1);
lua_gettable(L, -2);
if (lua_isnumber(L, -1)) {
s.linThrust[i] = lua_tonumber(L, -1);
lua_pop(L, 1);
} else {
malformed = true;
lua_pop(L, 1);
break;
}
}
} else {
malformed = true;
}
};
lua_pop(L, 1);
if (malformed) Error("Expected thruster values in ship_defs of %s\n", model_name);
s.angThrust = (float)luaPi_gettable_checknumber(L, -1, 3);
lua_rawgeti(L, -1, 4);
if (lua_istable(L, -1)) {
for (unsigned int i=0; i<lua_objlen(L,-1); i++) {
lua_pushinteger(L, i+1);
lua_gettable(L, -2);
if (lua_istable(L, -1) && lua_objlen(L,-2) == 2) {
lua_pushinteger(L, 1);
lua_gettable(L, -2);
s.gunMount[i].pos = *MyLuaVec::checkVec(L, -1);
lua_pop(L, 1);
lua_pushinteger(L, 2);
lua_gettable(L, -2);
s.gunMount[i].dir = *MyLuaVec::checkVec(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 1);
}
}
lua_pop(L, 1);
for (int i=0; i<Equip::SLOT_MAX; i++) s.equipSlotCapacity[i] = 0;
lua_rawgeti(L, -1, 5);
if (lua_istable(L, -1)) {
for (unsigned int i=0; (i<lua_objlen(L,-1)) && (i<Equip::SLOT_MAX); i++) {
lua_pushinteger(L, i+1);
lua_gettable(L, -2);
s.equipSlotCapacity[i] = luaL_checkinteger(L, -1);
lua_pop(L, 1);
}
}
lua_pop(L, 1);
s.capacity = luaPi_gettable_checkinteger(L, -1, 6);
s.hullMass = luaPi_gettable_checkinteger(L, -1, 7);
s.baseprice = luaPi_gettable_checkinteger(L, -1, 8);
lua_rawgeti(L, -1, 9);
if(!lua_isnoneornil(L, -1)) {
s.hyperdrive = (Equip::Type)((int)Equip::DRIVE_CLASS1+luaL_checkinteger(L, -1)-1);
} else {
s.hyperdrive = Equip::NONE;
}
lua_pop(L, 1);
printf("%d,%d,%d, h %d\n", s.capacity, s.hullMass, s.baseprice, s.hyperdrive);
types[s.name] = s;
return 0;
}
void ShipType::Init()
{
static bool isInitted = false;
if (isInitted) return;
isInitted = true;
std::vector<LmrModel*> ship_models;
LmrGetModelsWithTag("ship", ship_models);
lua_State *L = LmrGetLuaState();
int num = 0;
for (std::vector<LmrModel*>::iterator i = ship_models.begin();
i != ship_models.end(); ++i) {
LmrModel *model = *i;
model->PushAttributeToLuaStack("ship_defs");
if (lua_isnil(L, -1)) {
fprintf(stderr, "Warning: model %s is tagged as ship but has no ship_defs.\n",
model->GetName());
} else if (lua_istable(L, -1)) {
// multiple ship-defs for 1 model
for (unsigned int i=0; i<lua_objlen(L,-1); i++) {
lua_pushinteger(L, i+1);
lua_gettable(L, -2);
define_ship(L, model->GetName());
num++;
lua_pop(L, 1);
}
} else {
Error("Model %s: ships_def is malformed", model->GetName());
}
lua_pop(L, 1);
}
printf("%d ship types.\n", num);
}
ShipType::Type ShipType::GetRandomType() {
ShipType::Type type = "";
while (true) {
std::map<ShipType::Type, ShipType>::iterator iter = types.begin();
int idx = Pi::rng.Int32(types.size());
for (int i=0; i<=idx; i++) {
type = iter->first;
iter++;
}
// Don't include missiles
if (type.find("MISSILE")!=0)
break;
}
return type;
}
void EquipSet::Save()
{

View File

@ -5,16 +5,18 @@
#include "vector3.h"
#include "EquipType.h"
#include <vector>
#include <map>
struct lua_State;
struct ShipType {
enum Thruster { THRUSTER_FRONT, THRUSTER_REAR, THRUSTER_TOP, THRUSTER_BOTTOM, THRUSTER_LEFT, THRUSTER_RIGHT, THRUSTER_MAX };
enum Type { SWORDFISH, SIRIUS_INTERDICTOR, LADYBIRD, TAIPAN, WALRUS, FLOWERFAIRY,
MISSILE_UNGUIDED, MISSILE_GUIDED, MISSILE_SMART, MISSILE_NAVAL, END=MISSILE_UNGUIDED };
enum { GUN_FRONT, GUN_REAR, GUNMOUNT_MAX = 2 };
typedef std::string Type;
////////
const char *name;
const char *sbreModelName;
std::string name;
std::string lmrModelName;
float linThrust[THRUSTER_MAX];
float angThrust;
struct GunMount {
@ -28,8 +30,19 @@ struct ShipType {
Equip::Type hyperdrive;
///////
static const ShipType types[];
static std::string LADYBIRD;
static std::string SIRIUS_INTERDICTOR;
static std::string MISSILE_GUIDED;
static std::string MISSILE_NAVAL;
static std::string MISSILE_SMART;
static std::string MISSILE_UNGUIDED;
static Type GetRandomType();
static std::map<Type, ShipType> types;
static const char *gunmountNames[GUNMOUNT_MAX];
static void Init();
private:
static int define_ship(lua_State *L, const char *model_name);
};
class EquipSet {

View File

@ -37,7 +37,7 @@ struct SpaceStationType {
void _ReadStageDurations(const char *key, int *outNumStages, float **durationArray) {
lua_State *L = LmrGetLuaState();
model->PushAttributeToStack(key);
model->PushAttributeToLuaStack(key);
assert(lua_istable(L, -1));
int num = lua_objlen(L, -1);
@ -75,7 +75,7 @@ struct SpaceStationType {
if ((stage > 0) && (stage > numDockingStages)) return false;
lua_State *L = LmrGetLuaState();
// It's a function of form function(stage, t, from)
model->PushAttributeToStack("ship_dock_anim");
model->PushAttributeToLuaStack("ship_dock_anim");
if (!lua_isfunction(L, -1)) {
fprintf(stderr, "Error: Spacestation model %s needs ship_dock_anim method\n", model->GetName());
Pi::Quit();

View File

@ -279,7 +279,7 @@ public:
SpaceStation *station = Pi::player->GetDockedWith();
m_flavourIdx = flavour_idx;
m_flavour = station->GetShipsOnSale()[flavour_idx];
m_lmrModel = LmrLookupModelByName(ShipType::types[m_flavour.type].sbreModelName);
m_lmrModel = LmrLookupModelByName(ShipType::types[m_flavour.type].lmrModelName.c_str());
m_ondraw3dcon = Pi::spaceStationView->onDraw3D.connect(
sigc::mem_fun(this, &StationViewShipView::Draw3D));
}

View File

@ -18,6 +18,7 @@
#include <malloc.h>
#define alloca _alloca
#define strncasecmp strnicmp
#define strcasecmp stricmp
#else
#include <alloca.h>
#endif

View File

@ -132,6 +132,17 @@ std::string join_path(const char *firstbit, ...)
return out;
}
void Error(const char *format, ...)
{
fputs("Error: ", stderr);
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fputs("\n", stderr);
abort();
}
void strip_cr_lf(char *string)
{
char *s = string;

View File

@ -23,6 +23,12 @@
#define glError()
#endif
#ifndef __GNUC__
#define __attribute(x)
#endif /* __GNUC__ */
void Error(const char *format, ...) __attribute((format(printf,1,2)));
struct MissingFileException {};
// joinpath("data","models","some.def") = "data/models/some.def"
@ -39,9 +45,6 @@ GLuint util_load_tex_rgba(const char *filename);
FILE *fopen_or_die(const char *filename, const char *mode);
#ifndef __GNUC__
#define __attribute(x)
#endif /* __GNUC__ */
static inline std::string stringf(int maxlen, const char *format, ...)
__attribute((format(printf,2,3)));