@@ -938,6 +938,47 @@ df::plant *Maps::getPlantAtTile(int32_t x, int32_t y, int32_t z)
938938 return NULL ;
939939}
940940
941+ bool Maps::isPlantInBox (df::plant *plant, const cuboid &bounds)
942+ {
943+ if (!bounds.isValid ())
944+ return false ;
945+ else if (bounds.containsPos (plant->pos ))
946+ return true ;
947+ else if (!plant->tree_info )
948+ return false ;
949+
950+ auto &pos = plant->pos ;
951+ auto &t = *(plant->tree_info );
952+ // Northwest x/y pos of tree bounds
953+ int x_NW = pos.x - (t.dim_x >> 1 );
954+ int y_NW = pos.y - (t.dim_y >> 1 );
955+
956+ if (!cuboid (max (0 , x_NW), max (0 , y_NW), max (0 , pos.z - t.roots_depth ),
957+ x_NW + t.dim_x , y_NW + t.dim_y , pos.z + t.body_height - 1 ).clamp (bounds).isValid ())
958+ { // No intersection of tree bounds with cuboid
959+ return false ;
960+ }
961+
962+ int xy_size = t.dim_x * t.dim_y ;
963+ // Iterate tree body
964+ for (int z_idx = 0 ; z_idx < t.body_height ; z_idx++)
965+ for (int xy_idx = 0 ; xy_idx < xy_size; xy_idx++)
966+ if ((t.body [z_idx][xy_idx].whole & 0x7F ) != 0 && // Any non-blocked
967+ bounds.containsPos (x_NW + xy_idx % t.dim_x , y_NW + xy_idx / t.dim_x , pos.z + z_idx))
968+ {
969+ return true ;
970+ }
971+ // Iterate tree roots
972+ for (int z_idx = 0 ; z_idx < t.roots_depth ; z_idx++)
973+ for (int xy_idx = 0 ; xy_idx < xy_size; xy_idx++)
974+ if ((t.roots [z_idx][xy_idx].whole & 0x7F ) != 0 && // Any non-blocked
975+ bounds.containsPos (x_NW + xy_idx % t.dim_x , y_NW + xy_idx / t.dim_x , pos.z - z_idx - 1 ))
976+ {
977+ return true ;
978+ }
979+ return false ;
980+ }
981+
941982/*
942983* Biomes
943984*/
0 commit comments