[Fix] control_rate is now applied properly.

[Fix] Targetted now renders over the pilot's below.
This commit is contained in:
Allanis 2013-02-09 16:11:53 +00:00
parent 7c435e526a
commit eac16dacdd
12 changed files with 124 additions and 102 deletions

View File

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Fleets> <Fleets>
<fleet name="Test"> <fleet name="Pirate">
<ai>test</ai> <ai>test</ai>
<faction>Independent</faction> <faction>Independent</faction>
<pilots> <pilots>
<pilot chance='100'>Test</pilot> <pilot chance='100'>Pirate</pilot>
</pilots> </pilots>
</fleet> </fleet>
<fleet name="Merchant Ship"> <fleet name="Merchant Ship">
<ai>merchant</ai> <ai>merchant</ai>
<faction>Merchant</faction> <faction>Merchant</faction>
<pilots> <pilots>
<pilot chance='100'>Ship</pilot> <pilot chance='100'>Merchant Ship</pilot>
</pilots> </pilots>
</fleet> </fleet>
<fleet name="Sml Merchant Convoy"> <fleet name="Sml Merchant Convoy">
<ai>merchant</ai> <ai>merchant</ai>
<faction>Merchant</faction> <faction>Merchant</faction>
<pilots> <pilots>
<pilot chance='80'>Ship</pilot> <pilot chance='80'>Merchant Ship</pilot>
<pilot chance='80'>Ship</pilot> <pilot chance='80'>Merchant Ship</pilot>
<pilot chance='60'>Ship</pilot> <pilot chance='60'>Merchant Ship</pilot>
<pilot chance='60'>Ship</pilot> <pilot chance='60'>Merchant Ship</pilot>
</pilots> </pilots>
</fleet> </fleet>
</Fleets> </Fleets>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Ships> <Ships>
<ship name="Ship"> <ship name="Merchant Ship">
<GFX>ship</GFX> <GFX>ship</GFX>
<class>1</class> <class>1</class>
<movement> <movement>
@ -26,7 +26,7 @@
<outfit quantity='3'>laser</outfit> <outfit quantity='3'>laser</outfit>
</outfits> </outfits>
</ship> </ship>
<ship name="Test"> <ship name="Pirate">
<GFX>ship1</GFX> <GFX>ship1</GFX>
<class>1</class> <class>1</class>
<movement> <movement>

View File

@ -14,12 +14,12 @@
<planet>KonoSphere</planet> <planet>KonoSphere</planet>
</planets> </planets>
<fleets> <fleets>
<fleet chance="100">Test</fleet> <fleet chance="100">Merchant Ship</fleet>
<fleet chance="60">Merchant Ship</fleet> <fleet chance="60">Merchant Ship</fleet>
<fleet chance="50">Merchant Ship</fleet> <fleet chance="50">Merchant Ship</fleet>
<fleet chance="40">Merchant Ship</fleet> <fleet chance="40">Merchant Ship</fleet>
<fleet chance="50">Sml Merchant Convoy</fleet> <fleet chance="50">Pirate</fleet>
<fleet chance="40">Sml Merchant Convoy</fleet> <fleet chance="40">Pirate</fleet>
</fleets> </fleets>
</ssys> </ssys>
<ssys name="KonoSys"> <ssys name="KonoSys">

View File

@ -3,13 +3,14 @@ control_rate = 2
-- Required "control" function. -- Required "control" function.
function control() function control()
if taskname() == "none" then
pushtask(0, "fly") pushtask(0, "fly")
end end
end
-- Required "attacked" function. -- Required "attacked" function.
function attacked(attacker) function attacked(attacker)
task = taskname() if taskname() ~= "runaway" then
if task ~= "runaway" then
-- Let's have some messages. -- Let's have some messages.
if attacker == player then if attacker == player then
msg = rng(0,4) msg = rng(0,4)
@ -18,6 +19,7 @@ function attacked(attacker)
elseif msg == 2 then say("LEAVE! ME! ALONE!") elseif msg == 2 then say("LEAVE! ME! ALONE!")
end end
end end
-- So bravely run away!
pushtask(0, "runaway", attacker) pushtask(0, "runaway", attacker)
end end
end end

10
scripts/ai/skeleton Normal file
View File

@ -0,0 +1,10 @@
--Required control rate.
control_rate = 2
-- Required "control" function.
function control()
end
-- Required "attacked" function
function attacked(attacker)
end

View File

@ -3,13 +3,14 @@ control_rate = 2
-- Required "control" function. -- Required "control" function.
function control() function control()
if taskname() == "none" then
pushtask(0, "fly") pushtask(0, "fly")
end end
end
-- Required "attacked" function. -- Required "attacked" function.
function attacked(attacker) function attacked(attacker)
task = taskname() if taskname() ~= "attack" and task ~= "runaway" then
if task ~= "attack" and task ~= "runaway" then
-- Let's have some taunts. -- Let's have some taunts.
if attacker == player then if attacker == player then
msg = rng(0,4) msg = rng(0,4)
@ -28,7 +29,6 @@ function runaway()
target = gettargetid() target = gettargetid()
dir = face(target, 1) dir = face(target, 1)
accel() accel()
dist = getdist(getpos(target))
end end
-- Attack -- Attack

View File

@ -208,7 +208,7 @@ static int ai_loadProfile(char* filename) {
buf = pack_readfile(DATA, filename, NULL); buf = pack_readfile(DATA, filename, NULL);
if(luaL_dostring(L, buf) != 0) { if(luaL_dostring(L, buf) != 0) {
ERR("loading AI file: %s", "../scripts/ai/test.lua"); ERR("loading AI file: %s", filename);
ERR("%s", lua_tostring(L, -1)); ERR("%s", lua_tostring(L, -1));
WARN("Most likely Lua file has improper syntax, please check it."); WARN("Most likely Lua file has improper syntax, please check it.");
return -1; return -1;
@ -244,12 +244,15 @@ void ai_think(Pilot* pilot) {
// Clean up some variables. // Clean up some variables.
pilot_acc = pilot_turn = 0.; pilot_acc = pilot_turn = 0.;
//pilot_primary = 0; pilot_primary = 0;
if(cur_pilot->task == NULL) // Control function if pilot is idle or tick is up.
// Idle git! if((cur_pilot->tcontrol < SDL_GetTicks()) || (cur_pilot->task == NULL)) {
AI_LCALL("control"); AI_LCALL("control"); // Run control.
else lua_getglobal(L, "control_rate");
cur_pilot->tcontrol = SDL_GetTicks() + 1000*(int)lua_tonumber(L, -1);
}
if(cur_pilot->task != NULL)
// Pilot has a currently running task. // Pilot has a currently running task.
AI_LCALL(cur_pilot->task->name); AI_LCALL(cur_pilot->task->name);
@ -381,13 +384,13 @@ static int ai_shield(lua_State* L) {
// Get the pilot's armor in percentage. // Get the pilot's armor in percentage.
static int ai_parmor(lua_State* L) { static int ai_parmor(lua_State* L) {
lua_pushnumber(L, cur_pilot->armor / cur_pilot->ship->armor * 100.); lua_pushnumber(L, cur_pilot->armor / cur_pilot->armor_max * 100.);
return 1; return 1;
} }
// Get the pilot's shield in percentage. // Get the pilot's shield in percentage.
static int ai_pshield(lua_State* L) { static int ai_pshield(lua_State* L) {
lua_pushnumber(L, cur_pilot->shield / cur_pilot->ship->shield * 100.); lua_pushnumber(L, cur_pilot->shield / cur_pilot->shield_max * 100.);
return 1; return 1;
} }
@ -587,7 +590,7 @@ static int ai_say(lua_State* L) {
MIN_ARGS(1); MIN_ARGS(1);
if(lua_isstring(L, 1)) if(lua_isstring(L, 1))
player_message("Comm %s> \"%s\"", cur_pilot->name, lua_tostring(L, 1)); player_message("Comm: %s> \"%s\"", cur_pilot->name, lua_tostring(L, 1));
return 0; return 0;
} }

View File

@ -253,7 +253,7 @@ int main(int argc, char** argv) {
space_load(); space_load();
// Testing. // Testing.
pilot_create(ship_get("Ship"), "Player", faction_get("Player"), NULL, 0., NULL, NULL, PILOT_PLAYER); pilot_create(ship_get("Merchant Ship"), "Player", faction_get("Player"), NULL, 0., NULL, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos); gl_bindCamera(&player->solid->pos);
space_init("SaraSys"); space_init("SaraSys");

View File

@ -177,6 +177,8 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, AI_Profi
// AI. // AI.
pilot->ai = ai; pilot->ai = ai;
pilot->tcontrol = 0;
pilot->flags = 0;
// Solid. // Solid.
pilot->solid = solid_create(ship->mass, dir, pos, vel); pilot->solid = solid_create(ship->mass, dir, pos, vel);
@ -387,7 +389,7 @@ int fleet_load(void) {
free(buf); free(buf);
xmlCleanupParser(); xmlCleanupParser();
DEBUG("Loaded %d fleets", nfleets); DEBUG("Loaded %d fleets%c", nfleets, (nfleets==1)?' ':'s');
return 0; return 0;
} }

View File

@ -11,13 +11,13 @@
#define PILOT_DISABLED 0.2 // Based on armor percentage. #define PILOT_DISABLED 0.2 // Based on armor percentage.
// Flags. // Flags.
// Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player.
// Dynamic.
#define pilot_isFlag(p,f) (p->flags & f) #define pilot_isFlag(p,f) (p->flags & f)
#define pilot_setFlag(p,f) (p->flags |= f) #define pilot_setFlag(p,f) (p->flags |= f)
#define pilot_rmFlag(p,f) (p->flags ^= f) #define pilot_rmFlag(p,f) (p->flags ^= f)
#define PILOT_ATTACKED (1<<9) // Pilot is under attack. // Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player.
// Dynamic.
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
typedef struct { typedef struct {
Outfit* outfit; // Associated outfit. Outfit* outfit; // Associated outfit.
@ -52,6 +52,7 @@ typedef struct Pilot {
// AI. // AI.
AI_Profile* ai; // Ai personality profile. AI_Profile* ai; // Ai personality profile.
unsigned int tcontrol; // Timer for control tick.
Task* task; // Current action. Task* task; // Current action.
} Pilot; } Pilot;

View File

@ -48,11 +48,13 @@ typedef struct {
double r, g, b, a; double r, g, b, a;
} Color; } Color;
#define COLOR(x) glColor4d((x).r, (x).g, (x).b, (x).a) #define COLOR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
// Factions. // Standard colors.
Color cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.9, .a = 1. }; Color cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
Color cRadar_inert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. }; Color cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
Color cRadar_neut = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. }; Color cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
Color cRadar_friend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. }; Color cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
Color cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
Color cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. }; Color cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
Color cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. }; Color cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
// Bars. // Bars.
@ -107,7 +109,11 @@ typedef struct {
} Msg; } Msg;
static Msg* msg_stack; static Msg* msg_stack;
// External.
extern void pilot_render(Pilot* pilot); // Extern is in Pilot.* extern void pilot_render(Pilot* pilot); // Extern is in Pilot.*
// Internal.
void gui_renderPilot(Pilot* p);
void gui_renderBar(Color* c, Vec2* p, Rect* r, double w);
void player_message(const char* fmt, ...) { void player_message(const char* fmt, ...) {
va_list ap; va_list ap;
@ -129,8 +135,7 @@ void player_message(const char* fmt, ...) {
// Render the player. // Render the player.
void player_render(void) { void player_render(void) {
int i; int i, j;
double x, y, sx, sy;
Pilot* p; Pilot* p;
Vec2 v; Vec2 v;
@ -164,7 +169,7 @@ void player_render(void) {
switch(gui.radar.shape) { switch(gui.radar.shape) {
case RADAR_RECT: case RADAR_RECT:
// Planets. // Planets.
COLOR(cRadar_friend); COLOR(cFriend);
planets_minimap(gui.radar.res, gui.radar.w, gui.radar.h); planets_minimap(gui.radar.res, gui.radar.w, gui.radar.h);
// Weapons. // Weapons.
@ -172,36 +177,20 @@ void player_render(void) {
COLOR(cRadar_weap); COLOR(cRadar_weap);
weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h); weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h);
glEnd(); // Put end to those points. glEnd(); // Put end to those points.
for(i = 1; i < pilots; i++) { for(j = 0, i = 1; i < pilots; i++) {
p = pilot_stack[i]; // Skip the player.
x = (p->solid->pos.x - player->solid->pos.x) / gui.radar.res; if(pilot_stack[i]->id == player_target) j = i;
y = (p->solid->pos.y - player->solid->pos.y) / gui.radar.res; else gui_renderPilot(pilot_stack[i]);
sx = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sw / gui.radar.res;
sy = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sh / gui.radar.res;
if(sx < 1.) sx = 1.;
if(sy < 1.) sy = 1.;
if((ABS(x) > gui.radar.w / 2+sx) || (ABS(y) > gui.radar.h / 2. + sy))
continue; // Pilot isn't in range.
glBegin(GL_QUADS);
// Colors.
if(p->id == player_target) COLOR(cRadar_targ);
else COLOR(cRadar_neut);
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MIN(y+sx, gui.radar.w/2.)); // top left.
glVertex2d(MIN(x+sx, gui.radar.w/2.), MIN(y+sy, gui.radar.h/2.)); // Top right.
glVertex2d(MIN(x+sx, gui.radar.w/2.), MAX(y-sy, -gui.radar.h/2.)); // Bottom right.
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MAX(y-sy, -gui.radar.h/2.)); // Bottom left.
glEnd(); // The Quads.
} }
// Render the targetted pilot.
if(j != 0) gui_renderPilot(pilot_stack[j]);
glBegin(GL_POINTS); // For ze player. glBegin(GL_POINTS); // For ze player.
break; break;
case RADAR_CIRCLE: case RADAR_CIRCLE:
glBegin(GL_POINTS); glBegin(GL_POINTS);
for(i = 1; i < pilots; i++) { for(i = 1; i < pilots; i++) {
p = pilot_stack[i]; p = pilot_stack[i];
COLOR(cRadar_neut); COLOR(cNeutral);
glVertex2d((p->solid->pos.x - player->solid->pos.x) / gui.radar.res, glVertex2d((p->solid->pos.x - player->solid->pos.x) / gui.radar.res,
(p->solid->pos.y - player->solid->pos.y) / gui.radar.res); (p->solid->pos.y - player->solid->pos.y) / gui.radar.res);
} }
@ -224,41 +213,9 @@ void player_render(void) {
glPopMatrix(); // GL_PROJECTION. glPopMatrix(); // GL_PROJECTION.
// Health. // Health.
glBegin(GL_QUADS); // Shield. gui_renderBar(&cShield, &gui.pos_shield, &gui.shield, player->shield / player->shield_max);
COLOR(cShield); gui_renderBar(&cArmor, &gui.pos_armor, &gui.armor, player->armor / player->armor_max);
x = VX(gui.pos_shield) - gl_screen.w/2.; gui_renderBar(&cEnergy, &gui.pos_energy, &gui.energy, player->energy / player->energy_max);
y = VY(gui.pos_shield) - gl_screen.h/2.;
sx = player->shield / player->shield_max * gui.shield.w;
sy = gui.shield.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
glBegin(GL_QUADS); // Armor.
COLOR(cArmor);
x = VX(gui.pos_armor) - gl_screen.w/2.;
y = VY(gui.pos_armor) - gl_screen.h/2.;
sx = player->armor / player->armor_max * gui.armor.w;
sy = gui.armor.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
glBegin(GL_QUADS); // Energy.
COLOR(cEnergy);
x = VX(gui.pos_energy) - gl_screen.w/2.;
y = VY(gui.pos_energy) - gl_screen.h/2.;
sx = player->energy / player->energy_max * gui.energy.w;
sy = gui.energy.h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
// Target. // Target.
if(player_target) { if(player_target) {
@ -288,6 +245,51 @@ void player_render(void) {
} }
} }
// Renders a pilot.
void gui_renderPilot(Pilot* p) {
int x, y, sx, sy;
x = (p->solid->pos.x - player->solid->pos.x) / gui.radar.res;
y = (p->solid->pos.y - player->solid->pos.y) / gui.radar.res;
sx = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sw / gui.radar.res;
sy = PILOT_SIZE_APROX/2. * p->ship->gfx_space->sh / gui.radar.res;
if(sx < 1.) sx = 1.;
if(sy < 1.) sy = 1.;
if((ABS(x) > gui.radar.w/2+sx) || (ABS(y) > gui.radar.h/2.+sy))
return; // Pilot isn't in range.
glBegin(GL_QUADS);
// Colors.
if(p->id == player_target) COLOR(cRadar_targ);
else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOR(cHostile);
else COLOR(cNeutral);
// Image.
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MIN(y+sy, gui.radar.h/2)); // Top left.
glVertex2d(MIN(x+sx, gui.radar.w/2.), MIN(y+sy, gui.radar.h/2)); // Top right.
glVertex2d(MIN(x+sx, gui.radar.w/2.), MAX(y-sy, -gui.radar.h/2)); // Bottom right.
glVertex2d(MAX(x-sx, -gui.radar.w/2.), MAX(y-sy, -gui.radar.h/2)); // Bottom left.
glEnd();
}
// Render a bar.
void gui_renderBar(Color* c, Vec2* p, Rect* r, double w) {
int x, y, sx, sy;
glBegin(GL_QUADS);
COLOR(*c);
x = VX(*p) - gl_screen.w/2.;
y = VY(*p) - gl_screen.h/2.;
sx = w * r->w;
sy = r->h;
glVertex2d(x, y);
glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy);
glEnd();
}
// Init GUI. // Init GUI.
int gui_init(void) { int gui_init(void) {
// -- Targeting. // -- Targeting.

View File

@ -128,9 +128,11 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
CollideSprite(w->outfit->gfx_space, wsx, wsy, &w->solid->pos, CollideSprite(w->outfit->gfx_space, wsx, wsy, &w->solid->pos,
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) { pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
if(i != 0) if(i != 0) {
// Inform the ai it has been attacked. Useless if we are player. // Inform the ai it has been attacked. Useless if we are player.
ai_attacked(pilot_stack[i], w->parent); ai_attacked(pilot_stack[i], w->parent);
pilot_setFlag(pilot_stack[i], PILOT_HOSTILE);
}
// Inform the ship that it should take some damage. // Inform the ship that it should take some damage.
pilot_hit(pilot_stack[i], w->outfit->damage_shield, w->outfit->damage_armor); pilot_hit(pilot_stack[i], w->outfit->damage_shield, w->outfit->damage_armor);
// No need for the weapon particle anymore. // No need for the weapon particle anymore.