| 364 | static std::map<df::coord, df::building*> coord_engines; |
| 365 | |
| 366 | static EngineInfo *find_engine(df::building *bld, bool create = false) |
| 367 | { |
| 368 | auto ebld = strict_virtual_cast<df::building_siegeenginest>(bld); |
| 369 | if (!ebld) |
| 370 | return NULL; |
| 371 | |
| 372 | auto &obj = engines[bld]; |
| 373 | |
| 374 | if (obj) |
| 375 | { |
| 376 | obj->bld = ebld; |
| 377 | return obj; |
| 378 | } |
| 379 | |
| 380 | if (!create || !is_build_complete(bld)) |
| 381 | return NULL; |
| 382 | |
| 383 | obj = new EngineInfo(); |
| 384 | |
| 385 | obj->id = bld->id; |
| 386 | obj->bld = ebld; |
| 387 | obj->center = df::coord(bld->centerx, bld->centery, bld->z); |
| 388 | obj->building_rect = coord_range( |
| 389 | df::coord(bld->x1, bld->y1, bld->z), |
| 390 | df::coord(bld->x2, bld->y2, bld->z) |
| 391 | ); |
| 392 | obj->quality = average_quality(ebld); |
| 393 | obj->is_catapult = (ebld->type == siegeengine_type::Catapult); |
| 394 | obj->proj_speed = 2; |
| 395 | obj->hit_delay = obj->is_catapult ? 2 : -1; |
| 396 | obj->fire_range = get_engine_range(ebld, obj->quality); |
| 397 | |
| 398 | // Base coefficients per engine type, plus 6% exponential bonus per quality level |
| 399 | obj->sigma_coeff = (obj->is_catapult ? 30.0 : 48.0) * pow(1.06f, obj->quality); |
| 400 | |
| 401 | obj->ammo_vector_id = job_item_vector_id::BOULDER; |
| 402 | obj->ammo_item_type = item_type::BOULDER; |
| 403 | |
| 404 | obj->operator_id = obj->operator_frame = -1; |
| 405 | |
| 406 | coord_engines[obj->center] = bld; |
| 407 | return obj; |
| 408 | } |
| 409 | |
| 410 | static EngineInfo *find_engine(lua_State *L, int idx, bool create = false, bool silent = false) |
| 411 | { |
no test coverage detected