Page 1 of 1

which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 04 Nov 2016, 22:38
by luppolo
basically i want to make a quicktravel mod where you can ask some specific npcs to guide you around the zone, i'm doing this completely out of copypasting and trial&error

there's the guide here on how to add npc and kinda figured out the dialog workflow and how to call scripts for checking if you have money, have it taken if you agree to the fee etc, however i couldn't find a "correct" way to do the actual teleport, right now i'm using get_console():execute("jump_to_level map_name") which spawns you only in predefined spots (not what i want, the military and loner guide shoudn't bring you to the same spot in agroprom for example, and CoP maps are rather big so they will definitely need multiple destinations ) and is broken on some maps (going to bar with this spawns you out of map bounds)

i tried to unpack vanilla CoP files to see how it handles when you quicktravel with random squads however couldn't find anything

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 05 Nov 2016, 08:21
by Alundaio
Don't use jump_to_level it can break the game.

CoP teleports the player ontop of level changers set to silent mode which are placed into the game via the Level Editor. CoC teleports using a scripted solution, JumpToLevel in _g.script.

You can try something like this:

Code: Select all

function jump_to_smart(smart_name)
   local cvertex
   local sim,gg = alife(),game_graph()
   for id,smart in pairs(db.smart_terrain_by_id) do
      if (smart:name() == smart_name) then
         cvertex = smart and gg:vertex(smart.m_game_vertex_id)
         if (cvertex and sim:level_name(cvertex:level_id()) == new_level) then
            ChangeLevel(cvertex:level_point(),cvertex:level_vertex_id(),smart.m_game_vertex_id,vector():set(0,0,0))
            return true
         end
      end
   end
   return false
end


usage: jump_to_smart("mar_smart_terrain_base")

Then you can just use it from dialogs.script for specific smarts like:

dialogs.script:

Code: Select all

function teleport_to_csky_base(a,b)
   jump_to_smart("mar_smart_terrain_base")
end


and call it from dialog like this:
<action>dialogs.teleport_to_csky_base</action>

-----------------------------------------------------------------

Anyway, I think I might add some kind of quick travel from the PDA menu but haven't decided

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 05 Nov 2016, 11:51
by luppolo
this solution doesnt seem to work, when i select the quicktravel dialog the player just says the line but nothing happens, also no crashes so the log file is empty and the console shows nothing out of ordinary

now im going to eat, later i'll try adding some prinf around to see if everything falls apart during run or if just doesnt run at all

done that, apparently it fails to pass through this condition

Code: Select all

smart:name() == smart_name

does it mean if fails to find the smart terrain im telling him? i tried with many different ones (including the one in your example) with the names that appear in the debug pda map


the dialog has

Code: Select all

<action>dialogs.goto_test</action>


in dialogs.script i have (tried with different smart terrains in different maps)

Code: Select all

function goto_test(a, b)
   jump_to_smart("esc_smart_terrain_2_14")
end


in _g.script i added (copypasted from your post)

Code: Select all

function jump_to_smart(smart_name)
   local cvertex
   local sim,gg = alife(),game_graph()
   for id,smart in pairs(db.smart_terrain_by_id) do
      if (smart:name() == smart_name) then
         cvertex = smart and gg:vertex(smart.m_game_vertex_id)
         if (cvertex and sim:level_name(cvertex:level_id()) == new_level) then
            ChangeLevel(cvertex:level_point(),cvertex:level_vertex_id(),smart.m_game_vertex_id,vector():set(0,0,0))
            return true
         end
      end
   end
   return false
end

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 05 Nov 2016, 12:44
by Alundaio
might want to:

Code: Select all

 printf("smart=%s smart_name=%s",smart:name(),smart_name)

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 05 Nov 2016, 21:08
by luppolo
somehow the

Code: Select all

smart:name() == smart_name

check always fails, also how do i dump the console to file or just scroll it?

xrEngine 2016-11-06 01-05-02-390.jpg

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 06 Nov 2016, 00:23
by Alundaio
You can use the console command flush to flush to xray log.

Try this

Code: Select all

function jump_to_smart(smart_name)
   for id,smart in pairs(db.smart_terrain_by_id) do
      if (smart and smart:name() == smart_name) then
         ChangeLevel(smart.position,smart.m_level_vertex_id,smart.m_game_vertex_id,vector():set(0,0,0))
         return true
      end
   end
   return false
end

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 06 Nov 2016, 00:40
by luppolo
it works now, thank you

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 19 May 2017, 20:57
by luppolo
sorry to necro this but i have a question about the changelevel function

this is my script

Code: Select all

function recall()
   local m_data = alife_storage_manager.get_state()
   
   if (m_data.mr_exist) then
   
      local act = db.actor
      act.radiation = 0.99
      act.bleeding = 0.99
      
      local a = vector()
      a.x = m_data.mr_v_x
      a.y = m_data.mr_v_y
      a.z = m_data.mr_v_z
      ChangeLevel(a, m_data.mr_lvid, m_data.mr_gvid,vector():set(0,0,0))
      return true
   end
   
   return false
end


however i dont get full radiation and bleeding after changing level, if i comment the changelevel call then i get radiation sickness (no bleeding though?)

i read somewhere that changelevel skips all the rest of the code, but i assumed it meant all the code AFTER the call, in any case i should get the radiation because the code DOES execute

Code: Select all

local a = vector()
      a.x = m_data.mr_v_x
      a.y = m_data.mr_v_y
      a.z = m_data.mr_v_z
      

as when i cange level i end up in those coordinates so it's odd it does execute those lines but not the previous ones, so what's actualy going on here?

also minor unrelated question, i assume the vector():set(0,0,0) bit tells the game how the player is facing after the level change, how do i retrieve those values from db.actor so i can save them and have the player load in the same way he was facing before? in lua_help i see the only fields of actor are

Code: Select all

 property bleeding;
    property health;
    property morale;
    property power;
    property psy_health;
    property radiation;

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 19 May 2017, 21:05
by luppolo
i edited the code to

Code: Select all

local act = db.actor
      act.radiation = 1
      act.bleeding = 1
      
      local a = vector()
      a.x = m_data.mr_v_x
      a.y = m_data.mr_v_y
      a.z = m_data.mr_v_z
      if(act.radiation > 0.5) then
         ChangeLevel(a, m_data.mr_lvid, m_data.mr_gvid,vector():set(0,0,0))
      end

and the change doesnt happen, the only way i can explain this is that the script runs so fast that the changelevel call (or in this case the if check) are executed before the game "realizes" the changes to db.actor

Re: which is the correct function to teleport the player to a specific map/smart terrain?

Posted: 24 May 2017, 16:24
by Alundaio
I think it's because bleeding works differently. Some of these aren't like health, they are added per update tick and set to 0.

Here is example from change invulnerable code in 1.5:

Code: Select all

      if (bind_stalker_ext.invulnerable_time and time_global() < bind_stalker_ext.invulnerable_time) then
         if (db.actor) then
            if (db.actor.bleeding > 0) then
               db.actor.bleeding = 0.2
            end
            if (db.actor.radiation > 0) then
               db.actor.radiation = -1
            end
         end
         bind_stalker_ext.invulnerable_time = bind_stalker_ext.invulnerable_time - 500
         return false
      end


So if you want to heal bleeding might want to try changing it to something other then 1.


To change direction you use

db.actor:set_actor_direction(number)

example:

Code: Select all

local old_dir = db.actor:direction():getH()

db.actor:set_actor_direction(old_dir)

-- or to face the opposite direction
db.actor:set_actor_direction(-old_dir)