[Fix] control_rate is now applied properly.
[Fix] Targetted now renders over the pilot's below.
This commit is contained in:
parent
7c435e526a
commit
eac16dacdd
@ -1,27 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Fleets>
|
||||
<fleet name="Test">
|
||||
<fleet name="Pirate">
|
||||
<ai>test</ai>
|
||||
<faction>Independent</faction>
|
||||
<pilots>
|
||||
<pilot chance='100'>Test</pilot>
|
||||
<pilot chance='100'>Pirate</pilot>
|
||||
</pilots>
|
||||
</fleet>
|
||||
<fleet name="Merchant Ship">
|
||||
<ai>merchant</ai>
|
||||
<faction>Merchant</faction>
|
||||
<pilots>
|
||||
<pilot chance='100'>Ship</pilot>
|
||||
<pilot chance='100'>Merchant Ship</pilot>
|
||||
</pilots>
|
||||
</fleet>
|
||||
<fleet name="Sml Merchant Convoy">
|
||||
<ai>merchant</ai>
|
||||
<faction>Merchant</faction>
|
||||
<pilots>
|
||||
<pilot chance='80'>Ship</pilot>
|
||||
<pilot chance='80'>Ship</pilot>
|
||||
<pilot chance='60'>Ship</pilot>
|
||||
<pilot chance='60'>Ship</pilot>
|
||||
<pilot chance='80'>Merchant Ship</pilot>
|
||||
<pilot chance='80'>Merchant Ship</pilot>
|
||||
<pilot chance='60'>Merchant Ship</pilot>
|
||||
<pilot chance='60'>Merchant Ship</pilot>
|
||||
</pilots>
|
||||
</fleet>
|
||||
</Fleets>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Ships>
|
||||
<ship name="Ship">
|
||||
<ship name="Merchant Ship">
|
||||
<GFX>ship</GFX>
|
||||
<class>1</class>
|
||||
<movement>
|
||||
@ -26,7 +26,7 @@
|
||||
<outfit quantity='3'>laser</outfit>
|
||||
</outfits>
|
||||
</ship>
|
||||
<ship name="Test">
|
||||
<ship name="Pirate">
|
||||
<GFX>ship1</GFX>
|
||||
<class>1</class>
|
||||
<movement>
|
||||
|
@ -14,12 +14,12 @@
|
||||
<planet>KonoSphere</planet>
|
||||
</planets>
|
||||
<fleets>
|
||||
<fleet chance="100">Test</fleet>
|
||||
<fleet chance="100">Merchant Ship</fleet>
|
||||
<fleet chance="60">Merchant Ship</fleet>
|
||||
<fleet chance="50">Merchant Ship</fleet>
|
||||
<fleet chance="40">Merchant Ship</fleet>
|
||||
<fleet chance="50">Sml Merchant Convoy</fleet>
|
||||
<fleet chance="40">Sml Merchant Convoy</fleet>
|
||||
<fleet chance="50">Pirate</fleet>
|
||||
<fleet chance="40">Pirate</fleet>
|
||||
</fleets>
|
||||
</ssys>
|
||||
<ssys name="KonoSys">
|
||||
|
@ -3,13 +3,14 @@ control_rate = 2
|
||||
|
||||
-- Required "control" function.
|
||||
function control()
|
||||
if taskname() == "none" then
|
||||
pushtask(0, "fly")
|
||||
end
|
||||
end
|
||||
|
||||
-- Required "attacked" function.
|
||||
function attacked(attacker)
|
||||
task = taskname()
|
||||
if task ~= "runaway" then
|
||||
if taskname() ~= "runaway" then
|
||||
-- Let's have some messages.
|
||||
if attacker == player then
|
||||
msg = rng(0,4)
|
||||
@ -18,6 +19,7 @@ function attacked(attacker)
|
||||
elseif msg == 2 then say("LEAVE! ME! ALONE!")
|
||||
end
|
||||
end
|
||||
-- So bravely run away!
|
||||
pushtask(0, "runaway", attacker)
|
||||
end
|
||||
end
|
||||
|
10
scripts/ai/skeleton
Normal file
10
scripts/ai/skeleton
Normal file
@ -0,0 +1,10 @@
|
||||
--Required control rate.
|
||||
control_rate = 2
|
||||
|
||||
-- Required "control" function.
|
||||
function control()
|
||||
end
|
||||
|
||||
-- Required "attacked" function
|
||||
function attacked(attacker)
|
||||
end
|
@ -3,13 +3,14 @@ control_rate = 2
|
||||
|
||||
-- Required "control" function.
|
||||
function control()
|
||||
if taskname() == "none" then
|
||||
pushtask(0, "fly")
|
||||
end
|
||||
end
|
||||
|
||||
-- Required "attacked" function.
|
||||
function attacked(attacker)
|
||||
task = taskname()
|
||||
if task ~= "attack" and task ~= "runaway" then
|
||||
if taskname() ~= "attack" and task ~= "runaway" then
|
||||
-- Let's have some taunts.
|
||||
if attacker == player then
|
||||
msg = rng(0,4)
|
||||
@ -28,7 +29,6 @@ function runaway()
|
||||
target = gettargetid()
|
||||
dir = face(target, 1)
|
||||
accel()
|
||||
dist = getdist(getpos(target))
|
||||
end
|
||||
|
||||
-- Attack
|
||||
|
21
src/ai.c
21
src/ai.c
@ -208,7 +208,7 @@ static int ai_loadProfile(char* filename) {
|
||||
buf = pack_readfile(DATA, filename, NULL);
|
||||
|
||||
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));
|
||||
WARN("Most likely Lua file has improper syntax, please check it.");
|
||||
return -1;
|
||||
@ -244,12 +244,15 @@ void ai_think(Pilot* pilot) {
|
||||
|
||||
// Clean up some variables.
|
||||
pilot_acc = pilot_turn = 0.;
|
||||
//pilot_primary = 0;
|
||||
pilot_primary = 0;
|
||||
|
||||
if(cur_pilot->task == NULL)
|
||||
// Idle git!
|
||||
AI_LCALL("control");
|
||||
else
|
||||
// Control function if pilot is idle or tick is up.
|
||||
if((cur_pilot->tcontrol < SDL_GetTicks()) || (cur_pilot->task == NULL)) {
|
||||
AI_LCALL("control"); // Run control.
|
||||
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.
|
||||
AI_LCALL(cur_pilot->task->name);
|
||||
|
||||
@ -381,13 +384,13 @@ static int ai_shield(lua_State* L) {
|
||||
|
||||
// Get the pilot's armor in percentage.
|
||||
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;
|
||||
}
|
||||
|
||||
// Get the pilot's shield in percentage.
|
||||
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;
|
||||
}
|
||||
|
||||
@ -587,7 +590,7 @@ static int ai_say(lua_State* L) {
|
||||
MIN_ARGS(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;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ int main(int argc, char** argv) {
|
||||
space_load();
|
||||
|
||||
// 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);
|
||||
space_init("SaraSys");
|
||||
|
||||
|
@ -177,6 +177,8 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, AI_Profi
|
||||
|
||||
// AI.
|
||||
pilot->ai = ai;
|
||||
pilot->tcontrol = 0;
|
||||
pilot->flags = 0;
|
||||
|
||||
// Solid.
|
||||
pilot->solid = solid_create(ship->mass, dir, pos, vel);
|
||||
@ -387,7 +389,7 @@ int fleet_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d fleets", nfleets);
|
||||
DEBUG("Loaded %d fleets%c", nfleets, (nfleets==1)?' ':'s');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,13 +11,13 @@
|
||||
#define PILOT_DISABLED 0.2 // Based on armor percentage.
|
||||
|
||||
// Flags.
|
||||
// Creation.
|
||||
#define PILOT_PLAYER (1<<0) // Pilot is a player.
|
||||
// Dynamic.
|
||||
#define pilot_isFlag(p,f) (p->flags & f)
|
||||
#define pilot_setFlag(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 {
|
||||
Outfit* outfit; // Associated outfit.
|
||||
@ -52,6 +52,7 @@ typedef struct Pilot {
|
||||
|
||||
// AI.
|
||||
AI_Profile* ai; // Ai personality profile.
|
||||
unsigned int tcontrol; // Timer for control tick.
|
||||
Task* task; // Current action.
|
||||
} Pilot;
|
||||
|
||||
|
134
src/player.c
134
src/player.c
@ -48,11 +48,13 @@ typedef struct {
|
||||
double r, g, b, a;
|
||||
} Color;
|
||||
#define COLOR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
||||
// Factions.
|
||||
Color cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.9, .a = 1. };
|
||||
Color cRadar_inert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||
Color cRadar_neut = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||
Color cRadar_friend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
||||
// Standard colors.
|
||||
Color cInert = { .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 cFriend = { .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_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
// Bars.
|
||||
@ -107,7 +109,11 @@ typedef struct {
|
||||
} Msg;
|
||||
static Msg* msg_stack;
|
||||
|
||||
// External.
|
||||
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, ...) {
|
||||
va_list ap;
|
||||
@ -129,8 +135,7 @@ void player_message(const char* fmt, ...) {
|
||||
|
||||
// Render the player.
|
||||
void player_render(void) {
|
||||
int i;
|
||||
double x, y, sx, sy;
|
||||
int i, j;
|
||||
Pilot* p;
|
||||
Vec2 v;
|
||||
|
||||
@ -164,7 +169,7 @@ void player_render(void) {
|
||||
switch(gui.radar.shape) {
|
||||
case RADAR_RECT:
|
||||
// Planets.
|
||||
COLOR(cRadar_friend);
|
||||
COLOR(cFriend);
|
||||
planets_minimap(gui.radar.res, gui.radar.w, gui.radar.h);
|
||||
|
||||
// Weapons.
|
||||
@ -172,36 +177,20 @@ void player_render(void) {
|
||||
COLOR(cRadar_weap);
|
||||
weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h);
|
||||
glEnd(); // Put end to those points.
|
||||
for(i = 1; i < pilots; i++) {
|
||||
p = pilot_stack[i];
|
||||
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))
|
||||
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.
|
||||
for(j = 0, i = 1; i < pilots; i++) {
|
||||
// Skip the player.
|
||||
if(pilot_stack[i]->id == player_target) j = i;
|
||||
else gui_renderPilot(pilot_stack[i]);
|
||||
}
|
||||
// Render the targetted pilot.
|
||||
if(j != 0) gui_renderPilot(pilot_stack[j]);
|
||||
glBegin(GL_POINTS); // For ze player.
|
||||
break;
|
||||
case RADAR_CIRCLE:
|
||||
glBegin(GL_POINTS);
|
||||
for(i = 1; i < pilots; i++) {
|
||||
p = pilot_stack[i];
|
||||
COLOR(cRadar_neut);
|
||||
COLOR(cNeutral);
|
||||
glVertex2d((p->solid->pos.x - player->solid->pos.x) / 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.
|
||||
|
||||
// Health.
|
||||
glBegin(GL_QUADS); // Shield.
|
||||
COLOR(cShield);
|
||||
x = VX(gui.pos_shield) - gl_screen.w/2.;
|
||||
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();
|
||||
gui_renderBar(&cShield, &gui.pos_shield, &gui.shield, player->shield / player->shield_max);
|
||||
gui_renderBar(&cArmor, &gui.pos_armor, &gui.armor, player->armor / player->armor_max);
|
||||
gui_renderBar(&cEnergy, &gui.pos_energy, &gui.energy, player->energy / player->energy_max);
|
||||
|
||||
// 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.
|
||||
int gui_init(void) {
|
||||
// -- Targeting.
|
||||
|
@ -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,
|
||||
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.
|
||||
ai_attacked(pilot_stack[i], w->parent);
|
||||
pilot_setFlag(pilot_stack[i], PILOT_HOSTILE);
|
||||
}
|
||||
// Inform the ship that it should take some damage.
|
||||
pilot_hit(pilot_stack[i], w->outfit->damage_shield, w->outfit->damage_armor);
|
||||
// No need for the weapon particle anymore.
|
||||
|
Loading…
Reference in New Issue
Block a user