lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> I realize I haven't explained a certain aspect of what I want lua
> to do for my game.  I would like to define sequential scripted
> commands whereby I can create a file that looks like the following:
>
> function attack (target)
>     if (not infiringrange(target))
>         moveto(firingrange(target))
>   -- execution of the lua function attack "stops" here until
>   -- the attacking soldier has reached firing range
>       -- game execution (as well as lua reading other
> -- lua files) continues
>     end
> -- the soldier is now within firing range
>     openfire(target)
> end
>

Why have lua stop execution?  I have my (as you put it) "soldiers" built as
a lua class, and are maintained as a class in the game architecture.  The
lua class has an AI() function that is called every game loop from the
game's version of AI.  The lua files are all read on game-boot (actually, on
level-boot, since each level has its own set of script files, but I
digress.)  A brief example of how this works for me:

(all of my npc tables are cloned from a master npc object; this is a
bare-bones npc with an overloaded AI.  It is called via dofile() from the
master npc object file)

** a_mob.lua **

-- Create an emtpy table
my_mob = {}

-- Make it a clone of mob_main
my_mob = mob_main:clone()

-- adjust the values
my_mob.name="Foo"

-- overload the AI function
function my_mob:AI()
 -- lua_move_to(this_npc's_id, target's_id, range_to_move_to)
 lua_move_to(1, 69, self.active_weaps[0].range_medium)

 -- lua_shoot_at(this_npc's_id, target's_id, active_weapon_id)
 lua_shoot_at(1, 69, 0)
end

-- Return the new object
function LoadMob()
 -- give the fella a weapon (wpns is a global that is loaded in the
weapons-loading set of scripts.)
 my_mob.active_weaps[0] = wpns[0]:clone()
 return my_mob
end

** end a_mob.lua **

To implement, the lua_move... and lua_shoot are functions inside my
framework:

/* registered for Lua's use. */
static void lua_shoot_at(void) {
 LuaObject oid1 = Lua::getparam(1);
 LuaObject oid2 = Lua::getparam(2);
 LuaObject w = Lua::getparam(3);

 shoot_at( (int)((float)oid1), (int)((float)oid2), (int)((float)w));
}

/* registered for Lua's use */
static void lua_move_to(void) {
 LuaObject oid1 = Lua::getparam(1);
 LuaObject oid2 = Lua::getparam(2);
 LuaObject d = Lua::getparam(3);

 move_to( (int)((float)oid1), (int)((float)oid2), (float)d);
}

/* Internal function called from Lua via lua_shoot_at. */
void shoot_at(int ob_id1, int ob_id2, int w_id) {
 ZObject *obj1, *obj2;
 WeaponData *weap;
 float d;

/* get class pointers from master "living object" array */
 obj1 = App->m_Monsters->Objects[ob_id1];
 obj2 = App->m_Monsters->Objects[ob_id2];

/* if it doesn't exist.. */
 if(obj1 == NULL)
  return;

/* if it doesn't exist */
if(obj2 == NULL)
  return;

/* if no weapon */
 if (obj1->ActiveWeapons[w_id] == NULL)
  return;

/* check range...if outside of range_long, get out */
 d = geVec3d_DistanceBetween(&obj1->m_Pos, &obj2->m_Pos);
 if (d > obj1->ActiveWeapons[w_id]->range_long)
  return;

/* shoot 'em */
 obj1->ActiveWeapons[w_id]->FireWeapon(obj1, obj2);
}

Move_to works the same way, 'cept it does some actor rotation and applies
some physics to do the movement; actor stops moving when DistanceBetween is
<= what was specified via lua_move_to().


--jsm

John S. Miley
Programmer/Analyst
Public Systems Associates
mileyj@publicsystems.org
225-709-2666