@@ -125,12 +125,12 @@ static bool is_in_range(const coord_range &target, df::coord pos)
125125 target.first .z <= pos.z && pos.z <= target.second .z ;
126126}
127127
128- static std::pair<int , int > get_engine_range (df::building_siegeenginest *bld)
128+ static std::pair<int , int > get_engine_range (df::building_siegeenginest *bld, float quality )
129129{
130130 if (bld->type == siegeengine_type::Ballista)
131- return std::make_pair (1 , 200 );
131+ return std::make_pair (1 , 200 + int ( 10 * quality) );
132132 else
133- return std::make_pair (30 , 100 );
133+ return std::make_pair (30 - int (quality) , 100 + int ( 5 * quality) );
134134}
135135
136136static void orient_engine (df::building_siegeenginest *bld, df::coord target)
@@ -148,6 +148,27 @@ static void orient_engine(df::building_siegeenginest *bld, df::coord target)
148148 df::building_siegeenginest::Up;
149149}
150150
151+ static bool is_build_complete (df::building *bld)
152+ {
153+ return bld->getBuildStage () >= bld->getMaxBuildStage ();
154+ }
155+
156+ static float average_quality (df::building_actual *bld)
157+ {
158+ float quality = 0 ;
159+ int count = 0 ;
160+
161+ for (size_t i = 0 ; i < bld->contained_items .size (); i++)
162+ {
163+ if (bld->contained_items [i]->use_mode != 2 )
164+ continue ;
165+ count++;
166+ quality += bld->contained_items [i]->item ->getQuality ();
167+ }
168+
169+ return count > 0 ? quality/count : 0 ;
170+ }
171+
151172static int point_distance (df::coord speed)
152173{
153174 return std::max (abs (speed.x ), std::max (abs (speed.y ), abs (speed.z )));
@@ -239,6 +260,7 @@ struct EngineInfo {
239260 df::coord center;
240261 coord_range building_rect;
241262
263+ float quality;
242264 bool is_catapult;
243265 int proj_speed, hit_delay;
244266 std::pair<int , int > fire_range;
@@ -280,7 +302,7 @@ static EngineInfo *find_engine(df::building *bld, bool create = false)
280302 return obj;
281303 }
282304
283- if (!create)
305+ if (!create || ! is_build_complete (bld) )
284306 return NULL ;
285307
286308 obj = new EngineInfo ();
@@ -292,10 +314,11 @@ static EngineInfo *find_engine(df::building *bld, bool create = false)
292314 df::coord (bld->x1 , bld->y1 , bld->z ),
293315 df::coord (bld->x2 , bld->y2 , bld->z )
294316 );
317+ obj->quality = average_quality (ebld);
295318 obj->is_catapult = (ebld->type == siegeengine_type::Catapult);
296319 obj->proj_speed = 2 ;
297320 obj->hit_delay = obj->is_catapult ? 2 : -1 ;
298- obj->fire_range = get_engine_range (ebld);
321+ obj->fire_range = get_engine_range (ebld, obj-> quality );
299322
300323 obj->ammo_vector_id = job_item_vector_id::BOULDER ;
301324 obj->ammo_item_type = item_type::BOULDER ;
@@ -444,6 +467,7 @@ static bool setTargetArea(df::building_siegeenginest *bld, df::coord target_min,
444467{
445468 CHECK_NULL_POINTER (bld);
446469 CHECK_INVALID_ARGUMENT (target_min.isValid () && target_max.isValid ());
470+ CHECK_INVALID_ARGUMENT (is_build_complete (bld));
447471
448472 if (!enable_plugin ())
449473 return false ;
@@ -577,6 +601,7 @@ static bool addStockpileLink(df::building_siegeenginest *bld, df::building_stock
577601{
578602 CHECK_NULL_POINTER (bld);
579603 CHECK_NULL_POINTER (pile);
604+ CHECK_INVALID_ARGUMENT (is_build_complete (bld));
580605
581606 if (!enable_plugin ())
582607 return false ;
@@ -612,6 +637,7 @@ static bool removeStockpileLink(df::building_siegeenginest *bld, df::building_st
612637static df::workshop_profile *saveWorkshopProfile (df::building_siegeenginest *bld)
613638{
614639 CHECK_NULL_POINTER (bld);
640+ CHECK_INVALID_ARGUMENT (is_build_complete (bld));
615641
616642 if (!enable_plugin ())
617643 return NULL ;
0 commit comments