Goto for spacecrafts

All about writing scripts for Celestia in Lua and the .cel system
Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Goto for spacecrafts

Post #1by jan stegehuis » 20.01.2011, 17:17

This thread is in fact a continuation of "Possible bugs in Celx / Lua".

Selden:
You might consider having the script hosted by the CelestiaMotherlode.
Me
Uploaded version 1 to the motherlode last thursday but have not seen it appear in the scripts catalog yet. Uploaded the changed script just now as version 2.

I'm sorry to say, but the motherlode does not seem to be interested in the script. It has been a week now and I heard or saw absolutely nothing from them. I am not prepared to sit around any longer, waiting until they can finally bring themself to react to my upload.

So for those who are still interested in the script, I'll leave it here as a code element.

Code: Select all

-- Title: Goto for spacecrafts

-- Version:      2
-- Date:      16 jan 2011
-- Author:      Jan Stegehuis
-- Celestia:   1.6 or higher

--[[ Description
========================================================================
Extends the default Celestia "Goto", but only for spacecrafts.
   - For further information see: goto_sp.txt
=======================================================================]]


--[[ Structure: Calendar
========================================================================
   Utility (object) to print date and time in calendar format
=======================================================================]]

--[[ Table: calendar
------------------------------------------------------------------------
   holds (shorthand) names of moths
------------------------------------------------------------------------]]
calendar = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" }

         
--[[ Method: calendar:datetime()
------------------------------------------------------------------------
   return tdbTime as printable date & time
------------------------------------------------------------------------]]
function calendar:datetime(tdbTime)
   if tdbTime == -math.huge then
      return "-infinity"
   elseif tdbTime == math.huge then
      return "+infinity"
   else
      local ct = celestia:tdbtoutc(tdbTime)
      return string.format("%i %s %i  %i:%i:%i", ct.year, self[ct.month], ct.day, ct.hour, ct.minute, math.floor(ct.seconds))
   end
end


--[[ Method: calendar:date()
------------------------------------------------------------------------
   return tdbTime as printable date
------------------------------------------------------------------------]]
function calendar:date(tdbTime)
   if tdbTime == -math.huge then
      return "-infinity"
   elseif tdbTime == math.huge then
      return "+infinity"
   else
      local ct = celestia:tdbtoutc(tdbTime)
      return string.format("%i %s %i", ct.year, self[ct.month], ct.day)
   end
end


--[[ Structure: Observer
========================================================================
   Utility (object) to manipulate the observer
=======================================================================]]

--[[ Table: observer
------------------------------------------------------------------------
   holds observer parameters
------------------------------------------------------------------------]]
observer         = {
   object         = nil,
   setTime         = false,
   setDirection   = false,
   moveLocation   = false,
   distanceNow      = 0,
   defaultRadius   = 7,
   maxRadius      = 10,
   travelTime      = 7,
   timescale      = 0,
   clockText      = "",
   directionText   = ""
   }

         
--[[ Method: observer:move()
------------------------------------------------------------------------
   move observer to new object, optionally setting time and time
   direction:
      values: +1 forward clock, -1 backward clock, 0 current clock
      
   Remarks!
      F?rst prepares everything, th?n take the real action so that there
      is as little as possible (interpretation and processing) time
      between setting the timscale, setting the clock and moving the
      observer.
------------------------------------------------------------------------]]   
function observer:move(toObject, toPointInTime, clockDirection)
   if toPointInTime == nil then
      self.setTime = false
      self.setDirection = false
   else
      self.setTime = true
      if clockDirection == nil then
         self.setDirection = false
         self.clockText = ""
      else
         self.setDirection = true
      end
   end
   self.object = celestia:getobserver()
   if self.object == nill then
      celestia:print("CELESTIA ERROR: Cannot link to observer")
      return false
   else
      if self.object:getposition():distanceto(toObject:getposition(celestia:gettime())) > toObject:radius() * self.maxRadius then
         self.moveLocation = true
      else
         self.moveLocation = false
      end
      if self.setDirection == true then
         self.timescale = math.abs(celestia:gettimescale())
         if clockDirection < 0 then
            self.timescale = -self.timescale
            self.directionText = "\nClock running backward"
         elseif clockDirection > 0 then
            self.directionText = "\nClock running forward"
         else
            self.directionText = ""
         end
         celestia:settimescale(self.timescale)
      end
      if self.setTime == true then
         self.clockText = "Clock set to: " ..calendar:datetime(toPointInTime) ..self.directionText
         celestia:settime(toPointInTime)
      end
      if self.moveLocation == true then
         self.object:gotodistance(toObject, toObject:radius() * self.defaultRadius, self.travelTime)
         celestia:print("Travelling: \n" ..self.clockText,3)
      elseif self.setTime == true then
         celestia:print(self.clockText,3)
      end
      return true
   end
end


--[[ Spacecraft Structure
=======================================================================
   a structure/object that holds all the data and logic (functions
   and methods) to perform the 'spacecraft goto' functionality
=======================================================================]]

--[[ Table: spacecraft
------------------------------------------------------------------------
   holds the spacecraft's details
   also holds the tables:
   - menuKeys,
   - text and
   - state
   see below
------------------------------------------------------------------------]]
spacecraft          = {
   object          = nil,
   phase         = 0,
   phases          = {},
   }


--[[ Table: Spacecraft.menuKeys
------------------------------------------------------------------------
   holds keyboard keys used for menu choices
------------------------------------------------------------------------]]
spacecraft.menuKeys   = { keyBegin = "B", keyMiddle = "M", keyNow = "N", keyEnd = "E", keyPhase = "P", keyBlank = "**"  }


--[[ Table: Spacecraft.text
------------------------------------------------------------------------
   holds (parts of) display texts
------------------------------------------------------------------------]]
spacecraft.text      = {
   name          = "Spacecraft: %s",
   outside         = "\nSimulation time is outside of object lifetime"
                  .."\nTo adjust simulation clock and go press:",
   lifeBegin      = "\n%s - for begin of object lifetime: = %s",
   lifeMiddle      = "\n%s - for middle of object lifetime: = %s",
   lifeEnd         = "\n%s - for end of object lifetime:   = %s",
   lifeNow         = "\n%s - for system time:   = %s",
   timePhase      = "\n%s - to select 1 out of %i phases",
   phase          = "\n%i - phase %i: from %s till %s",
   phaseBegin      = "\n%s - for begin of phase timespan: = %s",
   phaseMiddle      = "\n%s - for middle of phase timespan: = %s",
   phaseEnd      = "\n%s - for end of phase timespan:   = %s"
   }

   
--[[ Table: spacecraft.state
------------------------------------------------------------------------
   Holds user-interface state information.
   Serves as a basis for the user-interface state machine.
   This is only part of the state structure and it's table;
   the table is completed towards the end of the script. This, in
   order to let lua correctly resolve the adresses of the various
   state machine functions.
------------------------------------------------------------------------]]
spacecraft.state   = {
   current         = nil,
   digits         = "123456789",                  -- is used to fill selectPhaseMenu.commandKey
   goto          = {   commandKey       = "GBMNEP"},
   gotoMenu      = {   commandKey      = ""},         -- is defined by method
   selectPhaseMenu   = { commandKey       = ""},         -- is defined by method
   gotoPhaseMenu   = {   commandKey       = ""}         -- is defined by method
   }


--[[ Method: spacecraft.state:reset()
------------------------------------------------------------------------
   reset state machine to the default state
   !! self == spacecraft.state
------------------------------------------------------------------------]]
function spacecraft.state:reset()
   if spacecraft.object == nil and self.current == self.goto then
      return
   else
      spacecraft.object    = nil
      spacecraft.phase   = 0
      spacecraft.phases    = {}
      self.current      = self.goto
      return
   end
end


--[[ Spacecraft structure:
=======================================================================
   spacecraft methods
=======================================================================]]


--[[ Method: spacecraft:getTimeLine()
------------------------------------------------------------------------
   get the spacraft's timeline from celestia and store the timespan
   for each phase in spacecraft.phases{}
------------------------------------------------------------------------]]
function spacecraft:getTimeLine()
   count = 0
   for phase in self.object:phases() do
      count = count + 1
      self.phases[count] = {phase:timespan()}
   end
   if  count < 1 then
      celestia:print("Object has no timeline")
      return false
   elseif count > 9 then
      celestia:print("Object has too many phases (max = 9)")
      return false
   elseif count == 1 and self.phases[1][1] <= -math.huge and self.phases[1][2] >= -math.huge then
      celestia:print("Object has infinite timeline")
      return false
   else
      return true
   end
end


--[[ Method: spacecraft:gotoMenu()
------------------------------------------------------------------------
   display the 'G'oto menu and adjust the state
   disable choice(es) that denote infinity
------------------------------------------------------------------------]]
function spacecraft:gotoMenu()
   local observationTime = celestia:getobserver():gettime()
   if observationTime <= self.phases[#self.phases][2] and observationTime >= self.phases[1][1] then
      return false
   else
      -- construct the menu
      local menuKey = ""
      local allowedMenuKeys = ""
      local message = string.format(self.text.name .. self.text.outside, self.object:name())
      -- goto begin
      if self.phases[1][1] <= -math.huge then
         -- negative infinity; can't go to begin
         menuKey = self.menuKeys.keyBlank
      else
         menuKey = self.menuKeys.keyBegin
         allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyBegin
      end
      message = message ..string.format(self.text.lifeBegin, menuKey, calendar:datetime(self.phases[1][1]))
      -- goto middle
      if self.phases[1][1] > -math.huge and self.phases[#self.phases][2] < math.huge then
         -- can't go to middle if either date is infinity
         middle = self.phases[1][1] + ((self.phases[#self.phases][2] - self.phases[1][1]) / 2)
         menuKey = self.menuKeys.keyMiddle
         allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyMiddle
         message = message ..string.format(self.text.lifeMiddle, menuKey, calendar:datetime(middle))
      end
      -- goto now
      if self.phases[1][1] <= celestia:getsystemtime() and celestia:getsystemtime() <= self.phases[#self.phases][2] then
         menuKey = self.menuKeys.keyNow
         allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyNow
         message = message ..string.format(self.text.lifeNow, menuKey, calendar:datetime(celestia:getsystemtime()))
      end
      -- goto end
      if self.phases[#self.phases][2] >= math.huge then
         -- positive infinity; can't go to end
         menuKey = self.menuKeys.keyBlank
      else
         menuKey = self.menuKeys.keyEnd
         allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyEnd
      end
      message = message ..string.format(self.text.lifeEnd, menuKey, calendar:datetime(self.phases[#self.phases][2]))
      -- select [phase
      if #self.phases > 1 then
         -- add "select phase" to menu
         allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyPhase
         message = message ..string.format(self.text.timePhase, self.menuKeys.keyPhase, #self.phases)
      end
      -- set state machine
      self.state.gotoMenu.commandKey = allowedMenuKeys
      self.state.current = self.state.gotoMenu
      -- print the menu
      celestia:print(message, 15, -1, 0, 5, 0)
      return true
   end
end


--[[ Method: spacecraft:gotoLifeBegin()
------------------------------------------------------------------------
   set the clock to the beginning of the object's lifetime
   and have it run forward
------------------------------------------------------------------------]]
function spacecraft:gotoLifeBegin()
   if self.phases[1][1] <= -math.huge then      -- for when gotoMenu got bypassed
      celestia:print("Can not set clock to -infinity", 3)
   else
      observer:move(self.object, self.phases[1][1], 1)
   end
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:gotoLifeMiddle()
------------------------------------------------------------------------
   set the clock to the middle of the object's lifetime
------------------------------------------------------------------------]]
function spacecraft:gotoLifeMiddle()
   if self.phases[1][1] <= -math.huge or self.phases[#self.phases][2] >= math.huge then      -- for when gotoMenu got bypassed
      celestia:print("Can not set clock to middle when infinity", 3)
   else
      middle = self.phases[1][1] + ((self.phases[#self.phases][2] - self.phases[1][1]) / 2)
      observer:move(self.object, middle, 0)
   end
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:gotoLifeNow()
------------------------------------------------------------------------
   set the clock to system time
------------------------------------------------------------------------]]
function spacecraft:gotoLifeNow()
   if self.phases[1][1] > celestia:getsystemtime() or celestia:getsystemtime() > self.phases[#self.phases][2] then      -- for when gotoMenu got bypassed
      celestia:print("Can not set clock outside of object lifetime", 3)
   else
      observer:move(self.object, celestia:getsystemtime(), 0)
   end
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:gotoLifeEnd()
------------------------------------------------------------------------
   set the clock to the end of the object's lifetime
   and have it run backward
------------------------------------------------------------------------]]
function spacecraft:gotoLifeEnd()
   if self.phases[#self.phases][2] >= math.huge then      -- for when gotoMenu got bypassed
      celestia:print("Can not set clock to +infinity", 3)
   else
      observer:move(self.object, self.phases[#self.phases][2], -1)
   end
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:selectPhaseMenu()
------------------------------------------------------------------------
   display the "select phase" submenu and adjust the state
------------------------------------------------------------------------]]
function spacecraft:selectPhaseMenu()
   if #self.phases <= 1 then      -- for when gotoMenu got bypassed
      return false
   else
      -- construct the menu
      local message = string.format(self.text.name, self.object:name())
      -- add the phases
      for i=1, #self.phases do
         message = message ..string.format(self.text.phase, i, i, calendar:date(self.phases[i][1]), calendar:date(self.phases[i][2]))
      end
      -- set state machine
      self.state.selectPhaseMenu.commandKey = string.sub(self.state.digits, 1, #self.phases)
      self.state.current = self.state.selectPhaseMenu
      -- print the menu
      celestia:print(message, 10, -1, 0, 5, 0)
      return true
   end
end


--[[ Method: spacecraft:gotoPhaseMenu()
------------------------------------------------------------------------
   display the "goto (begin or end of) phase" menu and adjust the state
   disable choice(es) that denote infinity
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseMenu()
   -- construct the menu
   local menuKey = ""
   local allowedMenuKeys = ""
   local message = string.format(self.text.name  ..": Phase %i", self.object:name(), self.phase)
   -- goto begin
   if self.phases[self.phase][1] <= -math.huge then
      -- negative infinity; can't go there
      menuKey = self.menuKeys.keyBlank
   else
      menuKey = self.menuKeys.keyBegin
      allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyBegin
   end
   message = message ..string.format(self.text.phaseBegin, menuKey, calendar:datetime(self.phases[self.phase][1]))
   -- goto middle
   if self.phases[self.phase][1] > -math.huge and self.phases[self.phase][2] < math.huge then
      -- can't go to middle if either date is infinity
      middle = self.phases[self.phase][1] + ((self.phases[self.phase][2] - self.phases[self.phase][1]) / 2)
      menuKey = self.menuKeys.keyMiddle
      allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyMiddle
      message = message ..string.format(self.text.lifeMiddle, menuKey, calendar:datetime(middle))
   end
   -- goto end
   if self.phases[self.phase][2] >= math.huge then
      -- positive infinity; can't go there
      menuKey = self.menuKeys.keyBlank
   else
      menuKey = self.menuKeys.keyEnd
      allowedMenuKeys = allowedMenuKeys ..self.menuKeys.keyEnd
   end
   message = message ..string.format(self.text.phaseEnd, menuKey, calendar:datetime(self.phases[self.phase][2]))
   -- set state machine
   self.state.gotoPhaseMenu.commandKey = allowedMenuKeys
   self.state.current = self.state.gotoPhaseMenu
   -- print the menu
   celestia:print(message, 10, -1, 0, 5, 0)
   return true
end


--[[ Method: spacecraft:gotoPhaseBegin()
------------------------------------------------------------------------
   set the clock to the begin of the selected phase
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseBegin(eventInfo)
   if self.phase == 1 then
      -- is beginning of first phase; set clock forward
      observer:move(self.object, self.phases[self.phase][1], 1)
   else
      -- leave clock as is
      observer:move(self.object, self.phases[self.phase][1], 0)
   end
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:gotoPhaseMiddle()
------------------------------------------------------------------------
   set the clock to the middle of the selected phase
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseMiddle(eventInfo)
   middle = self.phases[self.phase][1] + ((self.phases[self.phase][2] - self.phases[self.phase][1]) / 2)
   observer:move(self.object, middle, 0)
   self.state:reset()
   return true   
end


--[[ Method: spacecraft:gotoPhaseEnd()
------------------------------------------------------------------------
   set the clock to the end of the selected phase
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseEnd()
   if self.phase == #self.phases then
      -- is end of last phase; set clock backward
      observer:move(self.object, self.phases[self.phase][2], -1)
   else
      -- leave clock as is
      observer:move(self.object, self.phases[self.phase][2], 0)
   end
   self.state:reset()
   return true   
end


--[[ Spacecraft structure:
=======================================================================
   spacecraft state methods
=======================================================================]]


--[[ State method: spacecraft:gotoWantKey()
------------------------------------------------------------------------
   current state == goto; if key has correct value, accept key as input
------------------------------------------------------------------------]]
function spacecraft:gotoWantKey(eventInfo)
   if string.find(self.state.goto.commandKey, eventInfo.char) == nil then
      return false
   else
      selectedObject = celestia:getselection()
      if selectedObject:type() ~= "spacecraft" then
         return false
      else
         self.state:reset()
         self.object = selectedObject
         return true
      end
   end
end


--[[ State method: spacecraft:gotoProcessKey()
------------------------------------------------------------------------
   current state == goto; process the key entered by the user
------------------------------------------------------------------------]]
function spacecraft:gotoProcessKey(eventInfo)
   if self.object == nil then
      return false
   elseif not self:getTimeLine() then
      return false
   else
      return self.state.goto.key[string.upper(eventInfo.char)](self)
   -- ".key[](self)" is needed here; Lua will n?t resolve: ":key[]()" correctly
   end
end


--[[ State method: spacecraft:gotoMenuWantKey()
------------------------------------------------------------------------
   current state == gotoMenu; if key has correct value, accept key as input
------------------------------------------------------------------------]]
function spacecraft:gotoMenuWantKey(eventInfo)
   if string.find(self.state.gotoMenu.commandKey, string.upper(eventInfo.char)) == nil then
      self.state:reset()
      return false
   else
      return true
   end
end


--[[ State method: spacecraft:gotoMenuProcessKey()
------------------------------------------------------------------------
   current state == gotoMenu; process the key entered by the user
------------------------------------------------------------------------]]
function spacecraft:gotoMenuProcessKey(eventInfo)
   return self.state.gotoMenu.key[string.lower(eventInfo.char)](self)
   -- ".key[](self)" is needed here; Lua will n?t resolve: ":key[]()" correctly
end


--[[ State method: spacecraft:selectPhaseMenuWantKey()
------------------------------------------------------------------------
   current state == selectPhaseMenu; if key has correct value, accept key as input
------------------------------------------------------------------------]]
function spacecraft:selectPhaseMenuWantKey(eventInfo)
   if string.find(self.state.selectPhaseMenu.commandKey, eventInfo.char) == nil then
      self.state:reset()
      return false
   else
      return true
   end
end


--[[ State method: spacecraft:selectPhaseMenuProcessKey()
------------------------------------------------------------------------
   current state == selectPhaseMenu; process the key entered by the user
------------------------------------------------------------------------]]
function spacecraft:selectPhaseMenuProcessKey(eventInfo)
   self.phase = tonumber(eventInfo.char)
   return self.state.selectPhaseMenu.key(self)
   -- ".key(self)" is needed here; Lua will n?t resolve: ":key()" correctly
end


--[[ State method: spacecraft:gotoPhaseMenuWantKey()
------------------------------------------------------------------------
   current state == gotoPhaseMenu; if key has correct value, accept key as input
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseMenuWantKey(eventInfo)
   if string.find(self.state.gotoPhaseMenu.commandKey, string.upper(eventInfo.char)) == nil then
      self.state:reset()
      return false
   else
      return true
   end
end


--[[ State method: spacecraft:gotoPhaseMenuProcessKey()
------------------------------------------------------------------------
   current state == gotoPhaseMenu; process the key entered by the user
------------------------------------------------------------------------]]
function spacecraft:gotoPhaseMenuProcessKey(eventInfo)
   return self.state.gotoPhaseMenu.key[string.lower(eventInfo.char)](self)
end


--[[ Table spacecraft.state      part two
------------------------------------------------------------------------
-- complete spacecraft.state table
-- has to be done here, after all state methods are specified
-- otherwise Lua can't resolve function adresses correctly
-- links methods to user-input, dependent on the current state
------------------------------------------------------------------------]]
spacecraft.state.goto.wantKey               = spacecraft.gotoWantKey
spacecraft.state.goto.processKey            = spacecraft.gotoProcessKey
spacecraft.state.goto.key                  = {   G = spacecraft.gotoMenu,
                                       B = spacecraft.gotoLifeBegin,
                                       M = spacecraft.gotoLifeMiddle,
                                       N = spacecraft.gotoLifeNow,
                                       E = spacecraft.gotoLifeEnd,
                                       P = spacecraft.selectPhaseMenu}
spacecraft.state.gotoMenu.wantKey            = spacecraft.gotoMenuWantKey
spacecraft.state.gotoMenu.processKey         = spacecraft.gotoMenuProcessKey
spacecraft.state.gotoMenu.key               = {   b = spacecraft.gotoLifeBegin,
                                       m = spacecraft.gotoLifeMiddle,
                                       n = spacecraft.gotoLifeNow,
                                       e = spacecraft.gotoLifeEnd,
                                       p = spacecraft.selectPhaseMenu}
spacecraft.state.selectPhaseMenu.wantKey      = spacecraft.selectPhaseMenuWantKey
spacecraft.state.selectPhaseMenu.processKey      = spacecraft.selectPhaseMenuProcessKey
spacecraft.state.selectPhaseMenu.key         = spacecraft.gotoPhaseMenu
spacecraft.state.gotoPhaseMenu.wantKey         = spacecraft.gotoPhaseMenuWantKey
spacecraft.state.gotoPhaseMenu.processKey      = spacecraft.gotoPhaseMenuProcessKey
spacecraft.state.gotoPhaseMenu.key            = {   b = spacecraft.gotoPhaseBegin,
                                       m = spacecraft.gotoPhaseMiddle,
                                       e = spacecraft.gotoPhaseEnd}

                                       
--[[ Method: spacecraft:wantKey()
------------------------------------------------------------------------
   check if spacecraft wants to process the key the user pressed
------------------------------------------------------------------------]]
function spacecraft:wantKey(eventInfo)
   celestia:print("")
   if self.state.current == nil then
      return false
   else
      return self.state.current.wantKey(self, eventInfo)
      -- ".wantKey(self," is needed here; Lua will n?t resolve: ":wantKey(" correctly
   end
end


--[[ Method: spacecraft:processKey()
------------------------------------------------------------------------
   allow spacecraft to process the key the user pressed
------------------------------------------------------------------------]]
function spacecraft:processKey(eventInfo)
   if self.state.current == nil then
      return false
   else
      return self.state.current.processKey(self, eventInfo)
      -- ".processKey(self," is needed here; Lua will n?t resolve: ":processKey(" correctly
   end
end


--[[ Script Main:
=======================================================================
   The main functions
=======================================================================]]


--[[ Function: keyEvent()
------------------------------------------------------------------------
   the keyboard event handler
------------------------------------------------------------------------]]
function keyEvent(eventInfo)
   if spacecraft:wantKey(eventInfo) then
      return spacecraft:processKey(eventInfo)
   -- elseif otherObject:wantKey(eventInfo) then
      -- return otherObject:processKey(eventInfo)
   else
      return false
   end
end


--[[ Function: Main()
------------------------------------------------------------------------
   the function Main
------------------------------------------------------------------------]]
function Main()
   spacecraft.state:reset()
   celestia:registereventhandler("key", keyEvent)
   celestia:print("Spacecraft Goto is active", 3)
end


--[[ Script
------------------------------------------------------------------------
   start
------------------------------------------------------------------------]]
Main()


I had also uploaded a small description; I'll leave that here also.

Code: Select all

-- Name: Goto for spacecrafts

-- Version:      2
-- Date:      16 jan 2011
-- Author:      Jan Stegehuis
-- Celestia:   1.6 or higher



--[[ Description
========================================================================
Extends the default Celestia "Goto", but only for spacecrafts.
Reacts to [Shift] + [G]; shows a message and a menu ?f the currently
selected object is a spacecraft and ?f the current simulation time is
outside the spacecrafts lifetime. The menu allows to:

   B - set the clock to the beginning of the crafts lifetime
      - and set the direction of the clock to forward
   M - set the clock in the middle of the crafts lifetime
      - do not change the direction of the clock
   E - set the clock to the end of the crafts lifetime
      - and set the direction of the clock to backward
   N - set the clock to "now" (is the current system time)
      - only when "now" is within the craft's lifetime
      - do not change the direction of the clock
   P - show a menu to select a specific phase
      - a submenu then allows to set the clock to the
        beginning, middle or end of the chosen phase
      - only if a craft has more than 1 phase specified
      - allows max 9 phases per object to keep the state machine
        from becomming too complex for a script

If the selected object is not a spacecraft or the current simulation
time is within the lifetime of the currently selected craft, the script
reverts to Celestia's default Goto function. The same happens when the
object has no lifetime specified; i.e. both begin- and endtime are
reported by celestia as -infinity and +infinity respectively (like for
the spacecrafts: Integral and Chandra X-Ray Observatory).

Pressing any other key then B, M, etc. will set the menu state machine
back to it's default state. This excludes keys like "escape", F1 => F12,
Up, Down, etc. These keys do not seem to be reported to the script by
celestia's keyeventhandler().

Also reacts to: [Shift] + [B], [Shift] + [M], [Shift] + [N], [Shift] + [E]
and [Shift] + [P]. These act as a shortcuts into the Goto menu for a
currently selected spacecraft, but they also work when the simulation clock
is within the spacecraft's lifetime.

Remarks:
   - if a begin- or end time is +infinity or -infinity,
      the menu option in question is disabled as is the "middle" option.
   - only travels (uses the goto function) when the target object's centre
      is further away from the observer then 10* the target object's radius
   - except for the Begin and End options, only those options are shown
      that are applicable
=======================================================================]]



--[[ Installation and use:
========================================================================

Installation:
-------------
1. Unzip and copy "goto_sp.celx" to your Celestia\scripts folder.


Use:
-------------
1. Start Celestia and choose "File/Scripts/Goto for spacecrafts" from the
   menubar. Or choose "File/Open Script...", navigate to your scripts
   folder, select "goto_sp.celx" and choose "Open".
   The script will confirm it's running status by printing "Spacecraft
   goto is active" onscreen.
2. Select a spacecraft like the MIR that doesn't exist anymore, press
   [Shift] + [G] and follow the onscreen messages.

3. Once a spacecraft is selected, you can also use [Shift] + [B], etc.
   as a shortcut into the menu.
   
Remarks:
-   Celestia can only run 1 script at a time. When you execute a second
   script, you will have to 'restart' goto for spacecrafts again.
=======================================================================]]



--[[ History
========================================================================

version 2            16 jan 2011
-----------------------------------
- Added:
   Menuoptions:
   M = Middle of lifetime or timespan
   N = Now (systemtime)

- Changed:
   - Replaced the use of celestia:goto() by celestia:gotodistance(). Goes
   to a distance of 7 times the object's radius from the objects centre,
   whereas the goto() seems to default to 5 times the radius.
   
   - Now only travels (uses gotodistance()) when at the start the observer
   is further away from the object's centre then 10* it's radius. Otherwise
   it confines to (re)setting the simulation clock.
   
   - added some ui reportings, like for infinite lifetimes
   
   - Corrected error with phases and infinity


version 2            13 jan 2011
-----------------------------------
Initial version

=======================================================================]]


Jan
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".

Avatar
Adirondack M
Posts: 528
Joined: 01.03.2004
With us: 20 years 8 months

Re: Goto for spacecrafts

Post #2by Adirondack » 21.01.2011, 18:05

As Selden already wrote: It depends on how busy the people managing it are.

We will proceed it within the next days. Please be patien. Thanks.

Adirondack
We all live under the same sky, but we do not have the same horizon. (K. Adenauer)
The horizon of some people is a circle with the radius zero - and they call it their point of view. (A. Einstein)

Avatar
Adirondack M
Posts: 528
Joined: 01.03.2004
With us: 20 years 8 months

Re: Goto for spacecrafts

Post #3by Adirondack » 22.01.2011, 14:11

FYI:
jan stegehuis wrote:So do me a favour, forget that I ever uploaded the script and don't put it on the lode!
Adirondack
We all live under the same sky, but we do not have the same horizon. (K. Adenauer)

The horizon of some people is a circle with the radius zero - and they call it their point of view. (A. Einstein)

Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Re: Goto for spacecrafts

Post #4by jan stegehuis » 30.01.2011, 19:20

The script can now also be downloaded here:

https://sites.google.com/site/jansceles ... spacecraft

Jan
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".

Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Re: Goto for spacecrafts

Post #5by jan stegehuis » 25.02.2011, 20:17

Version 2 of the script has been available for a number of weeks now and since no one has reported a problem with it, it probably is stable enough to upload it to the Motherlode. I did that a few minutes ago.
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".

Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Re: Goto for spacecrafts

Post #6by jan stegehuis » 02.03.2011, 15:33

The script is available for download on the motherlode: http://www.celestiamotherlode.net/catalog/show_addon_details.php?addon_id=1539.
It has already been so since yesterday actually. That's realy quick so after earlier critics it now suits me to hand the guys from the motherlode a big compliment.

Thanks guys.
Jan
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".

Avatar
Marco Klunder
Posts: 181
Joined: 20.02.2008
Age: 62
With us: 16 years 9 months
Location: The Netherlands

Re: Goto for spacecrafts

Post #7by Marco Klunder » 15.04.2011, 17:18

Jan,

First of all, I'm still enjoying the use of this Goto for Spacecraft tool.
I have however a remark on a mall issue.
Although technically working correct :!: , I think the layout of the time display may be improved :idea:

GotoSP.png

In the example above, I refer to the 1-digit h:m:s presentation of the time versus the 2-digit hh:mm:ss presentation.
Of course the 1-digit presentation only occurs when the first digit is zero, but looking at it, the first impression is that the time is wrong. This is especially the case for the mm and ss parts in the time fields.

When I see the time: 9:26:7, my first impression is - What's wrong?
but displaying it as 9:26:07 or 09:26:07 eliminates that feeling.
The same for 17:0:53 :arrow: 17:00:53 in the example for the minutes.

As said, I think it's a small issue and you may or may not agree on it :wink:
But I thought it's worth reporting it. :mrgreen:

Marco
Marco Klunder
email: marco.klunder@xs4all.nl
Windows10 PD 3.0 GHz, 2 GB of RAM, Nvidia GeForce 6700 XL
Celestia161 / SVN + Lua Edu Tools v1.2 Beta9, Celestia160-ED and Celestia1621

Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Re: Goto for spacecrafts (2.1)

Post #8by jan stegehuis » 17.04.2011, 13:30

Marco,

You are quite right. I have been unhappy with the layout - in general - from the start, but there is not that much that one can do within 1 celestia:print() statement.
I had in mind to give it an overhaul at some point after also looking into lua hooks; I agree however that your "request"/"correction" would be an improvement and since it is easy to implement, it is now available as version 2.1 in it's normal download location:

Since I was at it, I also changed a few other things to improve the menu print.

Jan
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".

Topic author
jan stegehuis
Posts: 27
Joined: 13.12.2010
Age: 70
With us: 13 years 11 months
Location: Hoogmade, The Netherlands

Re: Goto for spacecrafts (2.1)

Post #9by jan stegehuis » 25.04.2011, 18:40

Version 2.1 is now also available on the motherlode.

With thanks to the guys there.
jan.stegehuis at google mail
win 7 hp 64bit, intel I5, 2.53 GHz, 4GB , ATI MR HD 5470
celestia 1.6.0

Not smoking still "sucks".


Return to “Scripting”