Lua Boat Script

From Blue Mars Developer Guidebook

Jump to: navigation, search

Hi folks, I have been working on this script based on Tim's Ride-able turtle script. Please enjoy. No warranty, contact me via PM or email if you need some help installing or customizing. Here is the Lua:

--------------------------------------------------------------------------
--------------------------------------------------------------------------
--This script is based on the rideableturtle script that was:
--Created by Tim Webb
--tim@avatar-reality.com
--Property of Avatar Reality Inc.
--This is a sample of how to create an animated vehicle for BlueMars
--This code is valid and pertinent only to BlueMars City developers
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--Further modified by Corey Evans from Gridrock City on Blue Mars to include physics for impluses and turn. 
--I have removed the animated entity sections for simplicity.
--General overview of how to use this script: (It assumes you have some knowledge of Lua entities in Blue Mars, 
--if you need help installing it please contact whyroc@in2orbit.net)
--1.You need to create an entity .ent file and rename script references where needed
--2.You will have to add or edit a default action map configuration for the level
--3.A suitable geometry must be made with proxies and shaped in a boat like way 
--4.Post any modifications or improvements for all to benefit
--------------------------------------------------------------------------
--------------------------------------------------------------------------

GRC_vehicle = {
   Properties = {
      bDisableSeeThrough = 1,
      },
   States = {"Idle","Moving"},--some states so we can go dormant when we are not being ridden
   speed = 40, --maximum impulse value
   actionCallbackId = nil,--we'll use this to make sure we don't register ourself for more than one action callback
   rideroffset = {x=0,y=0,z=0.1},--where the rider will be when they get on the turtle
   dismountoffset = {x=2,y=0,z=0},--where the rider will be when they get off the turtle
   motorposition = {x=0,y=0,z=0},
   rider = nil,
   walking = false,--moving
   speedfwd = 0,
   stopheight = 32,--a cut off should be just above you wave highest level.  This will stop the boat from flying into the air off a big wave.
   turnforce = 0,
   --variables for turning off the default actions maps
   actionCallbackID = 0,
   bAMapWasEnabled_Player = false,
   bAMapWasEnabled_Default = false,
   bAMapWasEnabled_Debug = false,
}
--from New_co city example functions to enable / disable action maps
function GRC_vehicle:DisableActionMaps()
  if (ActionMapManager.IsActionMapEnabled("player")) then
    ActionMapManager.EnableActionMap("player",false);
    self.bAMapWasEnabled_Player = true; System.Log("Disabled PLAYER ACTION MAP");
  end
  if (ActionMapManager.IsActionMapEnabled("default")) then
    ActionMapManager.EnableActionMap("default",false);
    self.bAMapWasEnabled_Default = true;  System.Log("Disabled DEFAULT ACTION MAP");
  end
  if (ActionMapManager.IsActionMapEnabled("debug")) then
    ActionMapManager.EnableActionMap("debug",false);
    self.bAMapWasEnabled_Debug = true;  System.Log("Disabled DEBUG ACTION MAP");
  end
end

function GRC_vehicle:ReenableActionMaps()
  if (self.bAMapWasEnabled_Player) then
    ActionMapManager.EnableActionMap("player",true);
    System.Log("Enabled PLAYER ACTION MAP ")
  end
  if (self.bAMapWasEnabled_Default) then
    ActionMapManager.EnableActionMap("default",true);
    System.Log("Enabled DEFAULT ACTION MAP ")
  end
  if (self.bAMapWasEnabled_Debug) then
    ActionMapManager.EnableActionMap("debug",true);
    System.Log("Enabled DEBUG ACTION MAP ");
  end
end




--OnInit() runs when we are in the client
function GRC_vehicle:OnInit()
   --This way we'll call OnReset() when we load in the client so our results should be the same in editor and client.
   self:OnReset();
end

--OnReset() runs when we are in the editor
function GRC_vehicle:OnReset()
   self:LoadObject(0,"Levels/I2O/Common/Objects/Vehicles/boat6.cgf");--your BOAT MODEL here
   self:Physicalize(0,PE_RIGID,{mass=10,density=0});--Set a starting mass
   --set physics here, mass should be from 10-30 , experiment with buoancy settings. The shape of your boat (its proxy) 
   --will have a big effect on the responsiveness.
   self:SetPhysicParams( PHYSICPARAM_SIMULATION, {mass= 20, sleep_speed = 0.04,damping = 10,max_logged_collisions = 1,max_time_step = 0.04,min_energy = 0.0016, });
   self:SetPhysicParams( PHYSICPARAM_BUOYANCY, {water_density = 8, water_damping = 20, water_resistance = 10 });
   --now go to an idle state
   self:GotoState("Idle");
end

--OnSelect will allow something to happen when we click on the turtle
function GRC_vehicle:OnSelect( avatarEntity, dist, destPos, destNormal )
   --Move player to rideroffset and parent them to the turtle
   self.rider = avatarEntity;--let's remember who is on us so we can take them off later
   self.rider:SetPos(SumVectors(self:GetPos(),self.rideroffset));--let's move the rider to the riding spot
   self:AttachChild(self.rider.id,ATTACHMENT_KEEP_TRANSFORMATION);--and attach the rider to move with us.
--this is where there is a problem in the client, the avatar does not stay stuck as well, at low acceleration is useable. 
--problem is known by AR staff.
   ActionMapManager.EnableActionMap("seavehicle",true);
    System.Log("Enabled seavehicle ACTION MAP ");
   self:DisableActionMaps();
   self:GotoState("Moving");
end


GRC_vehicle.Idle =
{
   OnBeginState = function(self)
      --Make sure we are not on the active entities list and not getting Updates.
      --This doesn't mean your script will go away, you can still call OnSelect to ride again.
      self:Activate(0);
   end,

   OnUpdate = function(self, time )
   end,

   OnEndState = function(self)
   end,
}

GRC_vehicle.Moving =
{
   OnBeginState = function(self)
      --since we need to have OnUpdate called for movement
      self:Activate(1);
      --This next call will make the system let us know when a key has been pressed so we can move the turtle
      if(not self.actionCallbackId)then --we don't want to register more than once
         self.actionCallbackId = HUD.RegisterActionCallback(self.Moving.OnAction, self);
      end
   end,
   --here are the events, wasd + space bar to dismount 
   OnAction = function(self, action, activationMode)
      if(action ~= "") then
         local currentdir = self:GetDirectionVector();
         if(action == "v_moveforward") then
            if(self.speedfwd <= self.speed) then
            self.speedfwd = self.speedfwd + 5;
            System.Log(tostring(self.speedfwd));
            end
            self.walking = true;
         end
         
         if(action == "v_brake")then
            self:GotoState("Idle");
         end

         if(action=="v_moveback")then
            if(self.speedfwd >= -self.speed) then
            self.speedfwd = self.speedfwd - 5;
            System.Log(tostring(self.speedfwd));
            end
         end
         
         if(action == "v_turnleft") then
         self.turnforce = self.turnforce - 1;
         System.Log(tostring(self.turnforce));
         end

         if(action == "v_turnright") then
         self.turnforce = self.turnforce + 1;
         System.Log(tostring(self.turnforce));
         end
      end
   end,
--here are the important bits, we are pushing the boat in its forward direction as well as rolling it and turning it
   OnUpdate = function(self, time )
      if(self.walking == true)then
      local currentdir = self:GetDirectionVector();
      local height = self:GetPos();
         if (height.z < self.stopheight)then
         self:AddImpulse(-1, self.motorposition,currentdir, self.speedfwd,0,{x=0,y=0,z=-1},self.turnforce);--fwd and turn
         self:AddImpulse(-1, self.motorposition,currentdir, 0,0,SumVectors(currentdir,{x=0,y=1,z=0}),self.turnforce * 0.1);--roll
         else
         self.speedfwd = 0;
         turnforce = 0;
         self.walking = false;
         end
      end
   end,

   OnEndState = function(self)
      self.walking = false;
      self.speedfwd = 0;
      self.turnforce = 0;
      --Get off the tutrle
      --First detach the rider so they don't move with us anymore
      self:DetachAll(ATTACHMENT_KEEP_TRANSFORMATION);
      --alternatively if you had more than one passenger you could call self.rider:DetachThis(0) on whichever rider you wanted off.
      --then move them to a safe spot
      self.rider:SetPos(SumVectors(self:GetWorldPos(),self.dismountoffset));
      --self.rider:EnableGroundAlignment( 0, true );
      self:ReenableActionMaps();
      ActionMapManager.EnableActionMap("vehicle",false);
      --We don't need to be getting keyboard input right now
      --HUD.UnregisterActionCallback(self.actionCallbackId);
      self.actionCallbackId = nil;
   end,
}

You will need to create a default action map 'defaultprofile.xml' in Blue Mars City Developer Tools\Game\Levels\I2O\Common\Libs\Config, see New co city example for details.

<ActionMaps>
  <actionmap name="NEWCOExample" version="21">
    <action name="newco_mouseclick" onPress="1">
      <key name="mouse1" />
    </action>   
    <action name="newco_arrowup" onPress="1">
      <key name="up" />
      <key name="np_8" />
    </action>
    <action name="newco_arrowdown" onPress="1">
      <key name="down" />
      <key name="np_2" />
    </action>
  </actionmap>



  <actionmap name="seavehicle" version="21">
    <action name="v_boost" onPress="1" onRelease="1" onHold="1" retriggerable="1">
      <key name="lshift" />
      <key name="xi_shoulderl" />
    </action>
    <action name="v_brake" onPress="1" onRelease="1">
      <key name="space" />
      <key name="xi_a" />
    </action>
    <action name="v_moveforward" onPress="1" onRelease="1" retriggerable="1">
      <key name="w" />
    </action>
    <action name="v_moveback" onPress="1" onRelease="1" retriggerable="1">
      <key name="s" />
    </action>
    <action name="v_turnleft" onPress="1" onRelease="1" retriggerable="1" onHold="0">
      <key name="a" />
    </action>
    <action name="v_turnright" onPress="1" onRelease="1" retriggerable="1" onHold="0">
      <key name="d" />
    </action>
  </actionmap>
  
  

</ActionMaps>

Problems with this wiki page? Contact us either by: Support Email or Support Ticket System

Blue Mars Guidebook Privacy Policy
Blue Mars Guidebook Community Guidelines

Personal tools