The International Simutrans Forum

Development => Scripting Scenarios and AI => Topic started by: Yona-TYT on March 12, 2017, 04:28:42 AM

Title: [DONE] Mark objects on the map.
Post by: Yona-TYT on March 12, 2017, 04:28:42 AM
I'm trying to create a function that allows me to mark and unmark objects on the map.

(https://www.mediafire.com/convkey/2fd1/ha92ikdy561c9446g.jpg)

This is what I have achieved so far:

// Mark and unmark objects on the map.
SQInteger world_marking_obj(HSQUIRRELVM vm)
{
   
    koord k = param<koord>::get(vm, 2);
    grund_t *gr = welt->lookup_kartenboden( k );
    obj_t *obj = gr->obj_bei(0);
    if (!obj->get_flag( obj_t::highlight )){
        obj->set_flag( obj_t::highlight );
        return SQ_OK;
    }
    else{
        obj->clear_flag( obj_t::highlight );
        return SQ_OK;
    }
}

//Indicates whether the object is marked or not.
SQInteger world_get_marking(HSQUIRRELVM vm)
{
    koord k = param<koord>::get(vm, 2);
    grund_t *gr = welt->lookup_kartenboden( k );
    obj_t *obj = gr->obj_bei(0);
    int marking = obj->get_flag( obj_t::highlight );
    return push_ribi(vm, marking);
   
}


    /**
     * Mark map obj.
     */
    STATIC register_function(vm, world_marking_obj, "marking_obj", 2, "");

    /**
     * Get mark obj.
     */
    STATIC register_function(vm, world_get_marking, "get_marking", 2, "");
Title: Re: Mark objects on the map.
Post by: Dwachs on March 12, 2017, 06:24:35 PM
This code will crash if there is nothing on the tile, i.e., obj==NULL.

One can certainly think about such functionality (maybe restricted to scenarios). What about adding such functions as member functions to map_object_x?
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 12, 2017, 10:34:02 PM
Quote from: Dwachs on March 12, 2017, 06:24:35 PM
This code will crash if there is nothing on the tile, i.e., obj==NULL.
That is why it closed simutrans.

Quote from: Dwachs on March 12, 2017, 06:24:35 PM
One can certainly think about such functionality (maybe restricted to scenarios). What about adding such functions as member functions to map_object_x?
I'll try.




Edit.

I do not know if this is an error, but the selection tool does not work with cruses, tunnels and high ways. Does this make sense?

I would like to mark the entrance of a tunnel so that the player notices that the road is badly connected.  8)



Edit.
Another detail is that the image is not updated instantly, it is always necessary to place the cursor on the marked object so that it is marked / unmarked. Is it possible to solve this?
Title: Re: Mark objects on the map.
Post by: Dwachs on March 13, 2017, 10:22:49 AM
Quote
I do not know if this is an error, but the selection tool does not work with cruses, tunnels and high ways. Does this make sense?
I do not know whether I understand it right: You could change k to koord3d and call welt->lookup(k). Then it should be possible to mark things on bridges and in tunnels.

Quote from: Yona-TYT on March 12, 2017, 10:34:02 PM
Another detail is that the image is not updated instantly, it is always necessary to place the cursor on the marked object so that it is marked / unmarked. Is it possible to solve this?
you should call obj->set_flag( obj_t::dirty);


Another comment: it is easier to implement methods and register them with 'register_method'  (I could not come up with a better naming convention). Just check any API method that is exported via calls to 'register_method'.
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 13, 2017, 04:14:26 PM
Quote from: Dwachs on March 13, 2017, 10:22:49 AM
I do not know whether I understand it right: You could change k to koord3d and call welt->lookup(k). Then it should be possible to mark things on bridges and in tunnels.
I just want to mark the tunnel entrance, but it does not work.

Quote from: Dwachs on March 13, 2017, 10:22:49 AM
you should call obj->set_flag( obj_t::dirty);
I think this does not work, no object is marked.  ???
Title: Re: Mark objects on the map.
Post by: Dwachs on March 13, 2017, 06:25:11 PM
I added mark and unmark to the map objects class:

http://dwachs.github.io/simutrans-sqapi-doc/classmap__object__x.html

Example - it works with tunnels:

local t = tile_x(26,37,4)
local o = t.find_object(mo_tunnel)
if (o) {
o.mark()
}

To mark bridge heads mark the way object on such a tile instead. Do not mark moving stuff. It may be hard to unmark it.
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 13, 2017, 10:51:46 PM
It would be nice to choose between a green and red, but I guess it's a bit difficult to implement.  :P
Title: Re: Mark objects on the map.
Post by: An_dz on March 14, 2017, 02:07:22 AM
Quote from: Yona-TYT on March 13, 2017, 10:51:46 PM
It would be nice to choose between a green and red, but I guess it's a bit difficult to implement.  :P
It would require some changes in other parts of the code so not as easy as 'just' adding a script api. And I guess Dwachs would want me to commit the 16bit patch first, which I'll do as soon as I can connect with the SVN.
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 14, 2017, 03:07:45 AM
I have modified the code to be able to place texts, I would like to add this too. ;D // mark objects
void_t mark_object(grund_t *gr,  const char* text)
{
obj_t *obj = gr->obj_bei(0);
gr->set_text(text);
obj->set_flag(obj_t::highlight);
obj->set_flag(obj_t::dirty);
return void_t();
}

void_t unmark_object(grund_t *gr, const char* text)
{
obj_t *obj = gr->obj_bei(0);
text=NULL;
gr->set_text(text);
obj->clear_flag(obj_t::highlight);
obj->set_flag(obj_t::dirty);
return void_t();
}
Look at this example:(https://scontent-bog1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/17212055_1270587153018433_4407925574843471994_o.jpg?efg=eyJpIjoiYiJ9&oh=d09b7943a242ab0a94ae5a3e331e9899&oe=596F9D05)for(local j=0;j<siz;j++){
local ribi=0
local t

c_z = square_x(c_x,c_y+j).get_ground_tile().z
c_way = coord3d(c_x,c_y+j,c_z)
mark = world.get_marking(square_x(c_way.x,c_way.y))

t = tile_x(c_way.x, c_way.y, c_way.z)

if (sw_way==0 && tile_x(c_way.x, c_way.y, c_way.z).find_object(mo_tunnel)) continue
if (sw_way==0 && tile_x(c_way.x, c_way.y, c_way.z).find_object(mo_bridge)) continue
if (tile_x(c_way.x, c_way.y, c_way.z).find_object(mo_way)){
sw_way=1
ribi = way_x(c_way.x, c_way.y, c_way.z).get_dirs()
if ((ribi==1) || (ribi==2) || (ribi==4)||(ribi==8)){
if (j!=0 && j!=siz-1){
foreach(obj in t.get_objects()){
tile_x(c_way.x, c_way.y, c_way.z).find_object(obj.get_type()).mark("Connect way here!!")
}
return c_way
}
}
if(j>=siz-1 && ribi!=0) return 0

}
else {
if(ribi==0) continue
foreach(obj in t.get_objects()){
tile_x(c_way.x, c_way.y, c_way.z).find_object(obj.get_type()).mark("Connect way here!!")
}
return c_way
}
foreach(obj in t.get_objects()){
tile_x(c_way.x, c_way.y, c_way.z).find_object(obj.get_type()).unmark(null)
}
}
Title: Re: Mark objects on the map.
Post by: Dwachs on March 14, 2017, 07:14:25 AM
Why not using the methods in label_x class for this purpose?
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 14, 2017, 09:04:46 AM
Quote from: Dwachs on March 14, 2017, 07:14:25 AM
Why not using the methods in label_x class for this purpose?
With this it is possible to select any object (regardless of its owner) and it does so at no cost. ;)
Edt.Additionally, a "null" value can be used to not create texts. ;)
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 16, 2017, 12:04:44 AM
It seems that the crosses (mo_crossing) are reluctant to be marked.  :o

You can try the new function here: Tutorial-testmark.zip  ;)  (http://www.mediafire.com/file/1zpnn8g3vf95gg3/Tutorial-testmark.zip) (some problems to solve)

(https://www.mediafire.com/convkey/f93e/og9cujfgwd6ctv46g.jpg)
Title: Re: Mark objects on the map.
Post by: Yona-TYT on March 31, 2017, 06:28:05 AM
@Dwachs
Can you add a function for "obj-> get_flag (obj_t :: highlight)"?, I need it for the stations in the tutorial.
Title: Re: Mark objects on the map.
Post by: Yona-TYT on April 02, 2017, 06:34:51 PM
Quote from: Yona-TYT on March 31, 2017, 06:28:05 AM
@Dwachs
Can you add a function for "obj-> get_flag (obj_t :: highlight)"?, I need it for the stations in the tutorial.

The problem is that "is_schedule_allowed (pl, schedule)" only works when there is more than one station, therefore there is no way to know if the station was selected. I can solve using the "Marked Tile" to determine if the stop was selected.

(https://www.mediafire.com/convkey/3b42/ydil4tmfx508f7t6g.jpg)
Title: Re: Mark objects on the map.
Post by: Dwachs on April 07, 2017, 07:10:04 PM
there is now obj->is_marked(), which does what you wnat. r8195
Title: Re: Mark objects on the map.
Post by: Yona-TYT on April 07, 2017, 11:39:45 PM
Thanks, this will make things easier for me. ;D