News:

Want to praise Simutrans?
Your feedback is important for us ;D.

[DONE] Mark objects on the map.

Started by Yona-TYT, March 12, 2017, 04:28:42 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yona-TYT

I'm trying to create a function that allows me to mark and unmark objects on the map.



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, "");

Dwachs

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?
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

#2
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?

Dwachs

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'.
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

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.  ???

Dwachs

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.
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

It would be nice to choose between a green and red, but I guess it's a bit difficult to implement.  :P

An_dz

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.

Yona-TYT

#8
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: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)
}
}

Dwachs

Why not using the methods in label_x class for this purpose?
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

#10
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. ;)

Yona-TYT

It seems that the crosses (mo_crossing) are reluctant to be marked.  :o

You can try the new function here: Tutorial-testmark.zip  ;) (some problems to solve)



Yona-TYT

@Dwachs
Can you add a function for "obj-> get_flag (obj_t :: highlight)"?, I need it for the stations in the tutorial.

Yona-TYT

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.



Dwachs

there is now obj->is_marked(), which does what you wnat. r8195
Parsley, sage, rosemary, and maggikraut.

Yona-TYT

Thanks, this will make things easier for me. ;D