diff --git a/bin/Makefile b/bin/Makefile index e0e1851..89f047e 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -52,5 +52,5 @@ data: pack $(DATAFILES) ../src/pack.c ../utils/pack/main.c clean: @echo -e "\tRemoving data.." rm -rf $(OBJS) $(APPNAME) $(DATA) pack core - rm -rf ../lib/lua/*.o ../lib/lua/*.a + #rm -rf ../lib/lua/*.o ../lib/lua/*.a diff --git a/scripts/ai/test.lua b/scripts/ai/test.lua index 5678824..a878efe 100644 --- a/scripts/ai/test.lua +++ b/scripts/ai/test.lua @@ -3,18 +3,52 @@ control_rate = 2 -- Required "control" function. function control() - say("IMA KILL YOU!!") - pushtask(0, "attack") + pushtask(0, "fly") end +-- Required "attacked" function. +function attacked(attacker) + task = taskname() + if task ~= "attack" and task ~= "runaway" then + pushtask(0, "attack", attacker) + end +end + +-- Runs away. +function runaway() + target = gettargetid() + dir = face(target, 1) + accel() + dist = getdist(getpos(target)) + + if dist > 800 then + say("So long Biatch!!") + end +end + +-- Attack function attack() - target = 0 + target = gettargetid() dir = face(target) dist = getdist(getpos(target)) - if dir < 10 and dist > 300 then + + if parmor() < 70 then + poptask() + pushtask(0, "runaway", target) + elseif dir < 10 and dist > 300 then accel() elseif dir < 10 and dist < 300 then shoot() end end +-- Fly to the player. +function fly() + target = 0 + dir = face(target) + dist = getdist(getpos(target)) + if dir < 10 and dist > 300 then + accel() + end +end + diff --git a/src/ai.c b/src/ai.c index 6b2feea..26338d6 100644 --- a/src/ai.c +++ b/src/ai.c @@ -59,6 +59,8 @@ static int ai_accel(lua_State* L); // Accelerate. // Internal C routines. static void ai_freetask(Task* t); +// External C routines. +void ai_attacked(Pilot* attacked, const unsigned int attacker); // weapon.c // Ai routines for Lua. // Tasks. static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number) @@ -67,6 +69,10 @@ static int ai_taskname(lua_State* L); // Number taskname. // Consult values. static int ai_gettarget(lua_State* L); // Pointer gettarget() static int ai_gettargetid(lua_State* L); // Number gettargetis() +static int ai_armor(lua_State* L); // armor() +static int ai_shield(lua_State* L); // shield() +static int ai_parmor(lua_State* L); // parmor() +static int ai_pshield(lua_State* L); // pshield() static int ai_getdistance(lua_State* L); // Number getdist(Vec2) static int ai_getpos(lua_State* L); // getpos(number/pilot) static int ai_minbrakedist(lua_State* L); // Number minbrakedist() @@ -122,6 +128,10 @@ int ai_init(void) { // Consult. lua_register(L, "gettarget", ai_gettarget); lua_register(L, "gettargetid", ai_gettargetid); + lua_register(L, "armor", ai_armor); + lua_register(L, "shield", ai_shield); + lua_register(L, "parmor", ai_parmor); + lua_register(L, "pshield", ai_pshield); lua_register(L, "getdist", ai_getdistance); lua_register(L, "getpos", ai_getpos); lua_register(L, "minbrakedist", ai_minbrakedist); @@ -129,7 +139,7 @@ int ai_init(void) { 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, "isally", ai_isally); // Movement. lua_register(L, "accel", ai_accel); lua_register(L, "turn", ai_turn); @@ -189,6 +199,14 @@ void ai_think(Pilot* pilot) { if(pilot_primary) pilot_shoot(pilot, 0); // AMG, he's gunna shoot! } +// Pilot is attacked. +void ai_attacked(Pilot* attacked, const unsigned int attacker) { + cur_pilot = attacked; + lua_getglobal(L, "attacked"); + lua_pushnumber(L, attacker); + lua_pcall(L, 1, 0, 0); +} + // ===================== // INTERNAL C FUNCTIONS. // ===================== @@ -197,8 +215,8 @@ void ai_think(Pilot* pilot) { static void ai_freetask(Task* t) { if(t->next) ai_freetask(t->next); // Woot, recursive freeing! - if(t->name) free(t->name); - if(t->target) free(t->target); + if(t->name) free(t->name); + if(t->dtype == TYPE_PTR) free(t->target); free(t); } @@ -257,7 +275,7 @@ static int ai_poptask(lua_State* L) { // Grab the current tasks name. static int ai_taskname(lua_State* L) { if(cur_pilot->task) lua_pushstring(L, cur_pilot->task->name); - else lua_pushnil(L); + else lua_pushstring(L, "none"); return 1; } @@ -279,6 +297,30 @@ static int ai_gettargetid(lua_State* L) { return 0; } +// Get the pilots armor. +static int ai_armor(lua_State* L) { + lua_pushnumber(L, cur_pilot->armor); + return 1; +} + +// Get pilots shield. +static int ai_shield(lua_State* L) { + lua_pushnumber(L, cur_pilot->shield); + return 1; +} + +// 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.); + 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.); + return 1; +} + // Get the distance from the pointer. static int ai_getdistance(lua_State* L) { MIN_ARGS(1); diff --git a/src/pilot.c b/src/pilot.c index c63c46e..4a3e1f0 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -85,7 +85,7 @@ void pilot_shoot(Pilot* p, const int secondary) { // Primary weapons. if(!p->outfits) return; // No outfits. - for(i = 0; p->outfits[i].outfit; i++) // Cycle through outfits to find weapons. + for(i = 0; i < p->noutfits; i++) // Cycle through outfits to find weapons. if(outfit_isWeapon(p->outfits[i].outfit) || // Is a weapon or launch? outfit_isLauncher(p->outfits[i].outfit)) // Ready to shoot again. @@ -194,25 +194,20 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, const do pilot->outfits = NULL; ShipOutfit* so; if(ship->outfit) { - int noutfits = 0; + pilot->noutfits = 0; for(so = ship->outfit; so; so = so->next) { - pilot->outfits = realloc(pilot->outfits, (noutfits+1)*sizeof(PilotOutfit)); - pilot->outfits[noutfits].outfit = so->data; - pilot->outfits[noutfits].quantity = so->quantity; - pilot->outfits[noutfits].timer = 0; - noutfits++; + pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit)); + pilot->outfits[pilot->noutfits].outfit = so->data; + pilot->outfits[pilot->noutfits].quantity = so->quantity; + pilot->outfits[pilot->noutfits].timer = 0; + (pilot->noutfits)++; } - // Sentinal. - pilot->outfits = realloc(pilot->outfits, (noutfits+1)*sizeof(PilotOutfit)); - pilot->outfits[noutfits].outfit = NULL; - pilot->outfits[noutfits].quantity = 0; - pilot->outfits[noutfits].timer = 0; } if(flags & PILOT_PLAYER) { pilot->think = player_think; // Players don't need to thing! :P pilot->render = NULL; - pilot->properties |= PILOT_PLAYER; + pilot_setFlag(pilot, PILOT_PLAYER); // It's a player! player = pilot; } else { pilot->think = ai_think; diff --git a/src/pilot.h b/src/pilot.h index 1f5a866..d85260e 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -10,8 +10,14 @@ #define PILOT_SIZE_APROX 0.8 #define PILOT_DISABLED 0.2 // Based on armor percentage. -// Creation flags. -#define PILOT_PLAYER 1 // Pilot is a player. +// 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. typedef struct { Outfit* outfit; // Associated outfit. @@ -40,8 +46,9 @@ typedef struct Pilot { // Outfit management. PilotOutfit* outfits; + int noutfits; - unsigned int properties; // Used for AI etc. + unsigned int flags; // Used for AI etc. // AI. Task* task; // Current action. diff --git a/src/weapon.c b/src/weapon.c index 8cb34bb..ef0cc78 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -15,6 +15,9 @@ extern Pilot** pilot_stack; extern int pilots; +// Ai stuff. +extern void ai_attacked(Pilot* attacked, const unsigned int attacker); + typedef struct Weapon { Solid* solid; // Actually has its own solid. :D @@ -124,7 +127,13 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { !areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) && 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) + // Inform the ai it has been attacked. Useless if we are player. + ai_attacked(pilot_stack[i], w->parent); + // 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. weapon_destroy(w, layer); return; }