diff --git a/scripts/ai/merchant.lua b/scripts/ai/merchant.lua index 1459aa6..46c2403 100644 --- a/scripts/ai/merchant.lua +++ b/scripts/ai/merchant.lua @@ -3,63 +3,66 @@ control_rate = 2 -- Required "control" function. function control() - if taskname() == "none" then - planet = getrndplanet() - pushtask(0, "go", planet) + if ai.taskname() == "none" then + planet = ai.rndplanet() + ai.pushtask(0, "go", planet) end end -- Required "attacked" function. function attacked(attacker) - if taskname() ~= "runaway" then + if ai.taskname() ~= "runaway" then -- Let's have some messages. - num = rng(0,3) + num = ai.rnd(0,3) if num == 0 then msg = "Mayday! We are under attack!" elseif num == 1 then msg = "Requesting assistance! Some scoundral is attacking us!" elseif num == 2 then msg = "Merchant vessle under attack here! HALP!" end - if msg then broadcast(msg) end + if msg then ai.broadcast(msg) end -- So bravely run away! - pushtask(0, "runaway", attacker) + ai.pushtask(0, "runaway", attacker) end end -- Runs away. function runaway() - target = gettargetid() - dir = face(target, 1) - accel() + target = ai.targetid() + dir = ai.face(target, 1) + ai.accel() end -- Fly to the target. function go() - target = gettarget() - dir = face(target) - dist = getdist(target) - bdist = minbrakedist() + target = ai.target() + dir = ai.face(target) + dist = ai.dist(target) + bdist = ai.minbrakedist() if dir < 10 and dist > bdist then - accel() + ai.accel() elseif dir < 10 and dist < bdist then - poptask() - pushtask(0, "stop") + ai.poptask() + ai.pushtask(0, "stop") end end -- Backthrust. function stop() - brake() - if isstopped() then - poptask() - settimer(0, rng(8000, 15000)) - pushtask(0, "land") + ai.brake() + if ai.isstopped() then + ai.stop() + ai.poptask() + ai.settimer(0, ai.rnd(8000, 15000)) + ai.pushtask(0, "land") + else + ai.brake() end end --Waits. function land() - if timeup(0) then - pushtask(0, "runaway", player) + if ai.timeup(0) then + ai.pushtask(0, "runaway", player) end end diff --git a/scripts/ai/pirate.lua b/scripts/ai/pirate.lua index abfd37c..a13117d 100644 --- a/scripts/ai/pirate.lua +++ b/scripts/ai/pirate.lua @@ -3,112 +3,112 @@ control_rate = 2 -- Required "control" function. function control() - task = taskname() + task = ai.taskname() -- Running pilot has healed up some. if task == "runaway" then - if parmour() == 100 then + if ai.parmour() == 100 then -- "attack" should be called after "runaway". - poptask() + ai.poptask() end -- Nothing to do. elseif task ~= "attack" and task ~= "runaway" then -- If getenemy() is 0, there is no enemy around. - enemy = getenemy() - if parmour() == 100 and enemy ~= 0 then + enemy = ai.getenemy() + if ai.parmour() == 100 and enemy ~= 0 then -- Taunts. - num = rng(0,4) + num = ai.rnd(0,4) if num == 0 then msg "Prepare to be boarded!" elseif num == 1 then msg = "Whoa! Lookie what we found here!" elseif num == 2 then msg = "What's a ship like you doing in a place like this?" end - comm(enemy,msg) + ai.comm(enemy,msg) -- Make hostile to the enemy (mainly, player! YOU!). - hostile(enemy) + ai.hostile(enemy) -- Go ahead and attack. - combat() -- Set to be in combat. - pushtask(0, "attack", enemy) -- Begin the attack. + ai.combat() -- Set to be in combat. + ai.pushtask(0, "attack", enemy) -- Begin the attack. -- Nothing to attack. else - pushtask(0, "fly") + ai.pushtask(0, "fly") end end end -- Required "attacked" function function attacked(attacker) - task = taskname() + task = ai.taskname() -- Pirate isn't fighting or fleeing already. if task ~= "attack" and task ~= "runaway" then taunt(attacker) - pushtask(0, "attack", attacker) + ai.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) + if ai.targetid() ~= attacker then + ai.pushtask(0, "attack", attacker) end end end function taunt(target) - num = rng(0,4) + num = ai.rnd(0,4) if num == 0 then msg = "How dare you attack me?!" elseif num == 1 then msg = "Aha! You think you can best ME?!" elseif num == 2 then msg = "JUST! DIE!" elseif num == 3 then msg = "Ohh, You're not going to enjoy this!" end - if msg then comm(target, msg) end + if msg then ai.comm(target, msg) end end -- Run away from the target. function runaway() - target = gettargerid() + target = ai.targerid() -- Ensure target exists. - if not exists(targe) then - poptask() + if not ai.exists(target) then + ai.poptask() return end - dir = face(target, 1) - accel() + dir = ai.face(target, 1) + ai.accel() end -- Attack the target. function attack() - target = gettargetid() + target = ai.targetid() -- Ensure target exists. - if not exists(target) then - poptask() + if not ai.exists(target) then + ai.poptask() return end - dir = face(target) - dist = getdist(getpos(target)) + dir = ai.face(target) + dist = ai.dist(ai.pos(target)) -- We need to know when to run away. - if parmour() < 70 then - pushtask(0, "runaway", target) + if ai.parmour() < 70 then + ai.pushtask(0, "runaway", target) -- Try to obliterate the target. elseif dir < 10 and dist > 300 then - accel() + ai.accel() elseif dir < 10 and dist < 300 then - shoot() + ai.shoot() end end -- Fly to the player. Pointless until hyperspace is implemented. function fly() target = player - dir = face(target) - dist = getdist(getpos(target)) + dir = ai.face(target) + dist = ai.dist(ai.pos(target)) if dir < 10 and dist > 300 then - accel() + ai.accel() end end diff --git a/scripts/ai/test.lua b/scripts/ai/test.lua index c8a26f5..0e36b60 100644 --- a/scripts/ai/test.lua +++ b/scripts/ai/test.lua @@ -3,88 +3,88 @@ control_rate = 2 -- Required "control" function. function control() - if taskname() == "none" then - pushtask(0, "fly") + if ai.taskname() == "none" then + ai.pushtask(0, "fly") end end -- Required "attacked" function. function attacked(attacker) - task = taskname() + task = ai.taskname() if task ~= "attack" and task ~= "runaway" then -- Let's have some taunts. taunt(attacker) -- Now pilot fights back. - pushtask(0, "attack", attacker) + ai.pushtask(0, "attack", attacker) elseif task == "attack" then - if gettargetid() ~= attacker then - pushtask(0, "attack", attacker) + if ai.targetid() ~= attacker then + ai.pushtask(0, "attack", attacker) end end end -- Taunts. function taunt(target) - num = rng(0,4) + num = ai.rnd(0,4) if num == 0 then msg = "You will never kill me!" elseif num == 1 then msg = "DIE!" elseif num == 2 then msg = "You won't survive!" elseif num == 3 then msg = "I hate you!" end - if msg then comm(attacker, msg) end + if msg then ai.comm(attacker, msg) end end -- Runs away. function runaway() - target = gettargetid() + target = ai.targetid() -- Make sure pilot exists. - if not exists(target) then - poptask() + if not ai.exists(target) then + ai.poptask() return end - dir = face(target, 1) - accel() + dir = ai.face(target, 1) + ai.accel() end -- Attack function attack() - target = gettargetid() + target = ai.targetid() -- Make sure target exists. - if not exists(target) then - poptask() + if not ai.exists(target) then + ai.poptask() return end - dir = face(target) - dist = getdist(getpos(target)) - second = secondary() + dir = ai.face(target) + dist = ai.dist(ai.pos(target)) + second = ai.secondary() - if secondary() == "Launcher" then - settarget(target) - shoot(2) + if ai.secondary() == "Launcher" then + ai.settarget(target) + ai.shoot(2) end - if parmour() < 70 then - poptask() - pushtask(0, "runaway", target) + if ai.parmour() < 70 then + ai.poptask() + ai.pushtask(0, "runaway", target) elseif dir < 10 and dist > 300 then - accel() + ai.accel() elseif dir < 10 and dist < 300 then - shoot() + ai.shoot() end end -- Fly to the player. function fly() target = player - dir = face(target) - dist = getdist(getpos(target)) + dir = ai.face(target) + dist = ai.dist(ai.pos(target)) if dir < 10 and dist > 300 then - accel() + ai.accel() end end diff --git a/src/ai.c b/src/ai.c index 9d39d40..bed3140 100644 --- a/src/ai.c +++ b/src/ai.c @@ -46,6 +46,10 @@ // (task). // ============================================================ +// FUCK LUA!!! +#define luaL_register(L,n,l) (luaL_openlib(L, (n),(l), 0)) +// Creates a new lua table. +#define newtable(L) (lua_newtable(L), lua_gettop(L)) // Call the AI function with name f. #define AI_LCALL(f) (lua_getglobal(L, f), lua_pcall(L, 0, 0, 0)) // Register a number constant n to name s (syntax is just like lua_regfunc). @@ -117,6 +121,7 @@ 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() +static int ai_stop(lua_State* L); // stop() // Combat. static int ai_combat(lua_State* L); // combat(number) static int ai_settarget(lua_State* L); // settarget(number) @@ -128,11 +133,51 @@ static int ai_hostile(lua_State* L); // hostile(number). static int ai_settimer(lua_State* L); // settimer(number, 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) static int ai_broadcast(lua_State* L); // broadcast(string) static int ai_rng(lua_State* L); // rng(number, number) +static const luaL_Reg ai_methods[] = { + { "pushtask", ai_pushtask }, + { "poptask", ai_poptask }, + { "taskname", ai_taskname }, + { "exists", ai_exists }, + { "ismaxvel", ai_ismaxvel }, + { "isstopped", ai_isstopped }, + { "isenemy", ai_isenemy }, + { "isally", ai_isally }, + { "incombat", ai_incombat }, + { "target", ai_gettarget }, + { "targetid", ai_gettargetid }, + { "armour", ai_armour }, + { "shield", ai_shield }, + { "parmour", ai_parmour }, + { "pshield", ai_pshield }, + { "dist", ai_getdistance }, + { "pos", ai_getpos }, + { "minbrakedist", ai_minbrakedist }, + { "nearestplanet", ai_getnearestplanet }, + { "rndplanet", ai_getrndplanet }, + { "accel", ai_accel }, + { "turn", ai_turn }, + { "face", ai_face }, + { "brake", ai_brake }, + { "stop", ai_stop }, + { "hyperspace", ai_hyperspace }, + { "combat", ai_combat }, + { "settarget", ai_settarget }, + { "secondary", ai_secondary }, + { "shoot", ai_shoot }, + { "getenemy", ai_getenemy }, + { "hostile", ai_hostile }, + { "settime", ai_settimer }, + { "timeup", ai_timeup }, + { "comm", ai_comm }, + { "broadcast", ai_broadcast }, + { "rnd", ai_rng }, + { 0, 0 } // End. +}; + // Current pilot "thinking" and assorted variables. static Pilot* cur_pilot = NULL; static double pilot_acc = 0.; @@ -197,51 +242,7 @@ static int ai_loadProfile(char* filename) { lua_regnumber(L, "player", PLAYER_ID); // Player id. // Register C funstions in Lua. - // Tasks. - lua_regfunc(L, "pushtask", ai_pushtask); - lua_regfunc(L, "poptask", ai_poptask); - lua_regfunc(L, "taskname", ai_taskname); - // Consult. - lua_regfunc(L, "gettarget", ai_gettarget); - lua_regfunc(L, "gettargetid", ai_gettargetid); - lua_regfunc(L, "armour", ai_armour); - lua_regfunc(L, "shield", ai_shield); - lua_regfunc(L, "parmour", ai_parmour); - lua_regfunc(L, "pshield", ai_pshield); - lua_regfunc(L, "getdist", ai_getdistance); - lua_regfunc(L, "getpos", ai_getpos); - lua_regfunc(L, "minbrakedist", ai_minbrakedist); - // Boolean. - lua_regfunc(L, "exists", ai_exists); - lua_regfunc(L, "ismaxvel", ai_ismaxvel); - lua_regfunc(L, "isstopped", ai_isstopped); - lua_regfunc(L, "isenemy", ai_isenemy); - lua_regfunc(L, "isally", ai_isally); - lua_regfunc(L, "incombat", ai_incombat); - // Movement. - lua_regfunc(L, "accel", ai_accel); - lua_regfunc(L, "turn", ai_turn); - lua_regfunc(L, "face", ai_face); - lua_regfunc(L, "brake", ai_brake); - lua_regfunc(L, "getnearestplanet", ai_getnearestplanet); - lua_regfunc(L, "getrndplanet", ai_getrndplanet); - lua_regfunc(L, "hyperspace", ai_hyperspace); - // Combat. - lua_regfunc(L, "combat", ai_combat); - lua_regfunc(L, "settarget", ai_settarget); - lua_regfunc(L, "secondary", ai_secondary); - lua_regfunc(L, "shoot", ai_shoot); - lua_regfunc(L, "getenemy", ai_getenemy); - lua_regfunc(L, "hostile", ai_hostile); - // Timers. - lua_regfunc(L, "settimer", ai_settimer); - lua_regfunc(L, "timeup", ai_timeup); - // Misc. - lua_regfunc(L, "createvect", ai_createvect); - lua_regfunc(L, "comm", ai_comm); - lua_regfunc(L, "broadcast", ai_broadcast); - lua_regfunc(L, "rng", ai_rng); - + luaL_register(L, "ai", ai_methods); // Now load the file, since all the functions have been previously loaded. buf = pack_readfile(DATA, filename, &bufsize); @@ -676,6 +677,16 @@ static int ai_hyperspace(lua_State* L) { return 1; } +// Completely stop the pilot if it is below minimum vel error. (No instant stops.) +static int ai_stop(lua_State* L) { + (void)L; // Just avoid a gcc warning. + + if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR) + vect_pset(&cur_pilot->solid->vel, 0., 0.); + + return 0; +} + // Toggle combat flag. Default is on. static int ai_combat(lua_State* L) { int i; @@ -774,19 +785,6 @@ static int ai_timeup(lua_State* L) { return 1; } -// Create a vector. -static int ai_createvect(lua_State* L) { - MIN_ARGS(2); - Vec2* v = MALLOC_L(Vec2); - double x = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L,1) : 0.; - double y = (lua_isnumber(L, 2)) ? (double)lua_tonumber(L,2) : 0.; - - vect_cset(v, x, y); - - lua_pushlightuserdata(L, v); - return 1; -} - // Have the pilot say something to player. static int ai_comm(lua_State* L) { MIN_ARGS(2); diff --git a/src/ai.h b/src/ai.h index 0ba1fdf..1e70c68 100644 --- a/src/ai.h +++ b/src/ai.h @@ -3,7 +3,7 @@ #define MIN_DIR_ERR 1.0*M_PI/180. #define MAX_DIR_ERR 0.1*M_PI/180. -#define MIN_VEL_ERR 0.5 +#define MIN_VEL_ERR 1.0 // Max number of AI timers.