diff --git a/bin/conf.example b/bin/conf.example index e936dca..80631c5 100644 --- a/bin/conf.example +++ b/bin/conf.example @@ -16,11 +16,12 @@ joystick = "Precision" -- If left is an axis, it will automatically set right to the same axis. -- setting both to the same axis (key). -- You can use reverse = 1 option to reverse them. -accel = { type = "jbutton", key = 0 } -left = { type = "jaxis", key = 0 } -right = { type = "jaxis", key = 0 } -primary = { type = "jbutton", key = 1 } -target = { type = "jbutton", key = 4 } -mapzoomin = { type = "jbutton", key = 7 } -mapzoomout = { type = "jbuton", key = 6 } +accel = { type = "jbutton", key = 0 } +left = { type = "jaxis", key = 0 } +right = { type = "jaxis", key = 0 } +primary = { type = "jbutton", key = 1 } +target = { type = "jbutton", key = 4 } +target_nearest = { type = "jbutton", key = 3 } +mapzoomin = { type = "jbutton", key = 7 } +mapzoomout = { type = "jbuton", key = 6 } diff --git a/scripts/ai/API b/scripts/ai/API index 04e8fe5..a2a7a55 100644 --- a/scripts/ai/API +++ b/scripts/ai/API @@ -71,6 +71,11 @@ pshield() // BOOLEAN! // ================ +exists(number id) + -- Check to see if pilot id is valid. + -- id -- Pilot to check. + -- return true if the pilot is valid. + ismaxval() -- Check if velocity is maximum. -- return true if velocity is max, false otherwise. @@ -89,6 +94,11 @@ isally(Pilot p) -- p - Pilot to check if ally. -- return true if p is ally. +incombat([number id]) + -- Queries whether a pilot is in combat or not. + -- id - Pilot to check if is in combat. -- Defaults to self. + -- return if pilos is in combat or not. + // ================ // MOVEMENT! // ================ @@ -125,6 +135,11 @@ getrndplanet() // COMBAT! // ================ +combat([number b]) + -- Set pilot as either in combat or out (for comm etc.) + -- b - if 0 set the pilot to be in combat, if 1 or ommitted sets it to be in combat. + -- return nil + shoot([number weapon]) -- Make the pilot shoot weapons. -- weapon to shoot, 1 if primary, 2 if secondary, 3 if both. Defaults to 1. diff --git a/scripts/ai/pirate.lua b/scripts/ai/pirate.lua index a8cc666..99299cd 100644 --- a/scripts/ai/pirate.lua +++ b/scripts/ai/pirate.lua @@ -4,10 +4,19 @@ control_rate = 2 -- Required "control" function. function control() task = taskname() - if task ~= "attack" and task ~= "runaway" then + + -- Running pilot has healed up some. + if task == "runaway" then + if parmor() == 100 then + -- "attack" should be called after "runaway". + poptask() + end + + -- Nothing to do. + elseif task ~= "attack" and task ~= "runaway" then -- If getenemy() is 0, there is no enemy around. enemy = getenemy() - if enemy ~= 0 then + if parmor() == 100 and enemy ~= 0 then -- Taunts. num = rng(0,4) if num == 0 then msg "Prepare to be boarded!" @@ -20,7 +29,9 @@ function control() hostile(enemy) -- Go ahead and attack. - pushtask(0, "attack", enemy) + combat() -- Set to be in combat. + pushtask(0, "attack", enemy) -- Begin the attack. + -- Nothing to attack. else pushtask(0, "fly") end @@ -30,9 +41,12 @@ end -- Required "attacked" function function attacked(attacker) task = taskname() + + -- Pirate isn't fighting or fleeing already. if task ~= "attack" and task ~= "runaway" then taunt() pushtask(0, "attack", attacker) + -- Pirate is fighting bit switches to new target (doesn't forget the old on though). elseif task == "attack" then if gettargetid() ~= attacker then pushtask(0, "attack", attacker) @@ -53,6 +67,13 @@ end -- Run away from the target. function runaway() target = gettargerid() + + -- Ensure target exists. + if not exists(targe) then + poptask() + return + end + dir = face(target, 1) accel() end @@ -60,12 +81,18 @@ end -- Attack the target. function attack() target = gettargetid() + + -- Ensure target exists. + if not exists(target) then + poptask() + return + end + dir = face(target) dist = getdist(getpos(target)) -- We need to know when to run away. if parmor() < 70 then - poptask() pushtask(0, "runaway", target) -- Try to obliterate the target. elseif dir < 10 and dist > 300 then diff --git a/scripts/ai/test.lua b/scripts/ai/test.lua index f09b92a..dd6f971 100644 --- a/scripts/ai/test.lua +++ b/scripts/ai/test.lua @@ -28,6 +28,13 @@ end -- Runs away. function runaway() target = gettargetid() + + -- Make sure pilot exists. + if not exists(target) then + poptask() + return + end + dir = face(target, 1) accel() end @@ -35,6 +42,13 @@ end -- Attack function attack() target = gettargetid() + + -- Make sure target exists. + if not exists(target) then + poptask() + return + end + dir = face(target) dist = getdist(getpos(target)) diff --git a/src/ai.c b/src/ai.c index bf9fd2f..751c834 100644 --- a/src/ai.c +++ b/src/ai.c @@ -98,10 +98,12 @@ static int ai_getdistance(lua_State* L); // Number getdist(Vec2) static int ai_getpos(lua_State* L); // getpos(number) static int ai_minbrakedist(lua_State* L); // Number minbrakedist() // Boolean expressions. +static int ai_exists(lua_State* L); // boolean exists static int ai_ismaxvel(lua_State* L); // Boolean ismaxvel() static int ai_isstopped(lua_State* L); // Boolean isstopped() -static int ai_isenemy(lua_State* L); // bool isenemy(number). -static int ai_isally(lua_State* L); // bool isally(number). +static int ai_isenemy(lua_State* L); // boolean isenemy(number). +static int ai_isally(lua_State* L); // boolean isally(number). +static int ai_incombat(lua_State* L); // boolean incombat([number]) // Movement. static int ai_accel(lua_State* L); // accel(number); nuimber <= 1. static int ai_turn(lua_State* L); // turn(number); abs(number) <= 1. @@ -109,13 +111,15 @@ static int ai_face(lua_State* L); // face(number/pointer) static int ai_brake(lua_State* L); // Brake() static int ai_getnearestplanet(lua_State* L); // pointer getnearestplanet() static int ai_getrndplanet(lua_State* L); // pointer getrndplanet() +static int ai_hyperspace(lua_State* L); // [number] hyperspace() // Combat. +static int ai_combat(lua_State* L); // combat(number) static int ai_shoot(lua_State* L); // shoot(number) number = 1,2,3. static int ai_getenemy(lua_State* L); // number getenemy(). static int ai_hostile(lua_State* L); // hostile(number). // Timers. static int ai_settimer(lua_State* L); // settimer(number, number) -static int ai_timeup(lua_State* L); // bool timeup(number) +static int ai_timeup(lua_State* L); // boolean timeup(number) // Misc. static int ai_createvect(lua_State* L); // createvect(number, number) static int ai_comm(lua_State* L); // comm(string) @@ -200,10 +204,12 @@ static int ai_loadProfile(char* filename) { lua_register(L, "getpos", ai_getpos); lua_register(L, "minbrakedist", ai_minbrakedist); // Boolean. + lua_register(L, "exists", ai_exists); lua_register(L, "ismaxvel", ai_ismaxvel); lua_register(L, "isstopped", ai_isstopped); lua_register(L, "isenemy", ai_isenemy); lua_register(L, "isally", ai_isally); + lua_register(L, "incombat", ai_incombat); // Movement. lua_register(L, "accel", ai_accel); lua_register(L, "turn", ai_turn); @@ -211,7 +217,9 @@ static int ai_loadProfile(char* filename) { lua_register(L, "brake", ai_brake); lua_register(L, "getnearestplanet", ai_getnearestplanet); lua_register(L, "getrndplanet", ai_getrndplanet); + lua_register(L, "hyperspace", ai_hyperspace); // Combat. + lua_register(L, "combat", ai_combat); lua_register(L, "shoot", ai_shoot); lua_register(L, "getenemy", ai_getenemy); lua_register(L, "hostile", ai_hostile); @@ -459,7 +467,10 @@ static int ai_getdistance(lua_State* L) { // Get the pilots position. static int ai_getpos(lua_State* L) { Pilot* p; - if(lua_isnumber(L, 1)) p = pilot_get((int)lua_tonumber(L,1)); // Pilot ID. + if(lua_isnumber(L, 1)) { + p = pilot_get((int)lua_tonumber(L,1)); // Pilot ID. + if(p == NULL) return 0; + } else p = cur_pilot; // Default to ones self. lua_pushlightuserdata(L, &p->solid->pos); @@ -487,6 +498,16 @@ static int ai_minbrakedist(lua_State* L) { return 1; } +static int ai_exists(lua_State* L) { + MIN_ARGS(1); + + if(lua_isnumber(L,1)) { + lua_pushboolean(L, (int)pilot_get((unsigned int)lua_tonumber(L,1))); + return 1; + } + return 0; +} + // Are we at max velocity? static int ai_ismaxvel(lua_State* L) { lua_pushboolean(L, VMOD(cur_pilot->solid->vel) == cur_pilot->ship->speed); @@ -512,6 +533,17 @@ static int ai_isally(lua_State* L) { return 1; } +// Check to see if the pilot is in combat. Defaults to self. +static int ai_incombat(lua_State* L) { + Pilot* p; + + if(lua_isnumber(L, 1)) p = pilot_get((unsigned int)lua_tonumber(L,1)); + else p = cur_pilot; + + lua_pushboolean(L,pilot_isFlag(p, PILOT_COMBAT)); + return 1; +} + // Accelerate the pilot based on a param. static int ai_accel(lua_State* L) { pilot_acc = (lua_gettop(L) > 1 && lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.; @@ -529,7 +561,13 @@ static int ai_turn(lua_State* L) { static int ai_face(lua_State* L) { MIN_ARGS(1); Vec2* v; // Grab the position to face. - if(lua_isnumber(L,1)) v = &pilot_get((unsigned int)lua_tonumber(L,1))->solid->pos; + Pilot* p; + + if(lua_isnumber(L,1)) { + p = pilot_get((unsigned int)lua_tonumber(L,1)); + if(p == NULL) return 0; // Make sure pilot is valid. + v = &p->solid->pos; + } else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1); double mod = -10; @@ -614,6 +652,30 @@ static int ai_getrndplanet(lua_State* L) { return 1; } +// Attempt to enter the pilot hyperspace. Return the distance if too far away. +static int ai_hyperspace(lua_State* L) { + int dist; + + dist = space_hyperspace(cur_pilot); + if(dist == 0) return 0; + + lua_pushnumber(L,dist); + return 1; +} + +// Toggle combat flag. Default is on. +static int ai_combat(lua_State* L) { + int i; + + if(lua_isnumber(L, 1)) { + i = (int)lua_tonumber(L,1); + if(i == 1) pilot_setFlag(cur_pilot, PILOT_COMBAT); + else if(i == 0) pilot_rmFlag(cur_pilot, PILOT_COMBAT); + } else pilot_setFlag(cur_pilot, PILOT_COMBAT); + + return 0; +} + // Pew pew.. Says the pilot. static int ai_shoot(lua_State* L) { int n = 1; diff --git a/src/pilot.h b/src/pilot.h index 532b2d9..f0b9ee6 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -17,9 +17,11 @@ #define pilot_setFlag(p,f) (p->flags |= f) #define pilot_rmFlag(p,f) (p->flags ^= f) // Creation. -#define PILOT_PLAYER (1<<0) // Pilot is a player. +#define PILOT_PLAYER (1<<0) // Pilot is a player. // Dynamic. -#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player. +#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player. +#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat. +#define PILOT_HYPERSPACE (1<<3) // Pilot is in hyperspace. // Just makes life simpler. #define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER) diff --git a/src/space.c b/src/space.c index 7d65eeb..c560c3d 100644 --- a/src/space.c +++ b/src/space.c @@ -34,6 +34,10 @@ static StarSystem* systems = NULL; static int nsystems = 0; StarSystem* cur_system = NULL; // Current star system. +// Current stardate in nice format. +char* stardate = "Stardate"; +unsigned int date = 0; // time since epoch. + #define STAR_BUF 100 // Area to leave around screen, more = less repitition. typedef struct { double x, y; // Position. It is simpler ligher to use two doubles than the physics. @@ -43,9 +47,12 @@ typedef struct { static Star* stars = NULL; // Star array. static int nstars = 0; // Total stars. +// Intern static Planet* planet_get(const char* name); static StarSystem* system_parse(const xmlNodePtr parent); static PlanetClass planetclass_get(const char a); +// Extern. +extern void player_message(const char* fmt, ...); // Draw the planet. Used in planet.c // Matrix mode is already displaced to center of the minimap. @@ -135,6 +142,25 @@ static PlanetClass planetclass_get(const char a) { }; } +// Hyperspaces, return 0 if entering hyperspace, or distance otherwise. +int space_hyperspace(Pilot* p) { + int i; + double d; + for(i = 0; i < cur_system->nplanets; i++) { + d = vect_dist(&p->solid->pos, &cur_system->planets[i].pos); + if(d < MIN_HYPERSPACE_DIST) + return (int)(MIN_HYPERSPACE_DIST - d); + } + // TODO: All hyperspace worky work. + if(p == player) { + // Player crap. + } else { + + } + + return 0; +} + // Init the system. void space_init(const char* sysname) { int i, j; @@ -146,6 +172,8 @@ void space_init(const char* sysname) { if(i == nsystems) ERR("System %s not found in stack", sysname); cur_system = systems+i; + player_message("Entering System %s on %s", sysname, stardate); + // Set up stars. nstars = (cur_system->stars*gl_screen.w*gl_screen.h+STAR_BUF*STAR_BUF)/(800*640); stars = realloc(stars, sizeof(Star)*nstars); // Should realloc this, not malloc. diff --git a/src/space.h b/src/space.h index f5c4014..86fd2c1 100644 --- a/src/space.h +++ b/src/space.h @@ -72,3 +72,7 @@ void space_exit(void); void space_render(double dt); void planets_render(void); +// Misc. +int space_hyperspace(Pilot* p); +extern char* stardate; +