diff --git a/config/fxdata/terrain.cfg b/config/fxdata/terrain.cfg index 25de5e0b84..a66b2f7056 100644 --- a/config/fxdata/terrain.cfg +++ b/config/fxdata/terrain.cfg @@ -1086,11 +1086,22 @@ Messages = 0 0 0 ; Sound sample playing in a loop when hovering over it on screen. AmbientSndSample = 0 ; Algorithm used to compute room capacity: -; slabs_all_only, slabs_all_wth_effcncy, slabs_div2_wth_effcncy, gold_slabs_wth_effcncy, gold_slabs_full, none. +; slabs_all_only - One capacity per slab. +; slabs_all_wth_effcncy - Capacity is reduced when the room is less effecient. +; slabs_no_min_wth_effcncy - Same as above, but without a minimum capacity of 1. +; slabs_div2_wth_effcncy - Capacity is reduced by room effeciency, then divided by two. +; slabs_div2_nomin_effcncy - Same as above, but without a minimum capacity of 1. +; slabs_mul2_wth_effcncy - Capacity is reduced by room effeciency, then multiplied by two. +; slabs_pow2_wth_effcncy - Capacity is reduced by the square of room effeciency, ie 50% efficient means 25% capacity. +; gold_slabs_wth_effcncy - Capacity is reduced by room effeciency, then multiplied by gold hoard types (5). +; gold_slabs_full - One capacity per slab, then multiplied by gold hoard types. +; none - No capacity. TotalCapacity = none ; Algorithm used to used storage space and used worker space: ; count_gold_hoardes_in_room, count_books_in_room, count_workers_in_room, count_crates_in_room, count_bodies_in_room, count_food_in_room, count_lair_occupants, none. UsedCapacity = none none +; Slab that it also receives full efficiency bonus from. +SlabSynergy = none ; Height in cubes at which storage is created. Negative values for any. StorageHeight = 0 ; Sprite icon of the room, large size and medium size. @@ -1113,6 +1124,7 @@ Messages = 0 0 0 AmbientSndSample = 0 TotalCapacity = slabs_all_only UsedCapacity = none none +SlabSynergy = none StorageHeight = 0 SymbolSprites = 0 0 PointerSprites = 0 @@ -1131,6 +1143,7 @@ Messages = 39 24 35 AmbientSndSample = 0 TotalCapacity = gold_slabs_wth_effcncy UsedCapacity = gold_hoardes_in_room none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 29 57 PointerSprites = 25 @@ -1149,6 +1162,7 @@ Messages = 0 25 0 AmbientSndSample = 0 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = books_in_room workers_in_room +SlabSynergy = none StorageHeight = 1 SymbolSprites = 33 61 PointerSprites = 27 @@ -1168,6 +1182,7 @@ Messages = 0 26 0 AmbientSndSample = 0 TotalCapacity = slabs_all_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 37 65 PointerSprites = 29 @@ -1187,6 +1202,7 @@ Messages = 0 27 0 AmbientSndSample = 0 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 35 63 PointerSprites = 28 @@ -1205,6 +1221,7 @@ Messages = 0 28 0 AmbientSndSample = 85 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 39 67 PointerSprites = 30 @@ -1222,6 +1239,7 @@ Properties = CANNOT_BE_CLAIMED CANNOT_BE_SOLD CANNOT_VANDALIZE HAS_NO_ENSIGN AmbientSndSample = 0 TotalCapacity = none UsedCapacity = none none +SlabSynergy = none StorageHeight = 2 SymbolSprites = 0 0 PointerSprites = 0 @@ -1240,6 +1258,7 @@ Messages = 0 29 0 AmbientSndSample = 86 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = crates_in_room workers_in_room +SlabSynergy = none StorageHeight = 1 SymbolSprites = 47 75 PointerSprites = 34 @@ -1258,6 +1277,7 @@ Messages = 0 30 0 AmbientSndSample = 156 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 49 77 PointerSprites = 35 @@ -1276,6 +1296,7 @@ Messages = 0 31 0 AmbientSndSample = 155 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 2 SymbolSprites = 45 73 PointerSprites = 33 @@ -1295,6 +1316,7 @@ Messages = 0 32 0 AmbientSndSample = 45 TotalCapacity = slabs_all_only UsedCapacity = bodies_in_room none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 43 71 PointerSprites = 32 @@ -1313,6 +1335,7 @@ Messages = 0 33 0 AmbientSndSample = 0 TotalCapacity = slabs_div2_wth_effcncy UsedCapacity = none none +SlabSynergy = none StorageHeight = 2 SymbolSprites = 41 69 PointerSprites = 31 @@ -1331,6 +1354,7 @@ Messages = 41 22 34 AmbientSndSample = 0 TotalCapacity = slabs_all_wth_effcncy UsedCapacity = food_in_room none +SlabSynergy = none StorageHeight = 0 SymbolSprites = 31 59 PointerSprites = 26 @@ -1349,6 +1373,7 @@ Messages = 40 23 36 AmbientSndSample = 0 TotalCapacity = slabs_all_wth_effcncy UsedCapacity = lair_occupants none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 51 79 PointerSprites = 36 @@ -1367,6 +1392,7 @@ Messages = 0 0 0 AmbientSndSample = 0 TotalCapacity = none UsedCapacity = none none +SlabSynergy = none StorageHeight = 1 SymbolSprites = 53 81 PointerSprites = 37 @@ -1385,6 +1411,7 @@ Messages = 0 0 0 AmbientSndSample = 0 TotalCapacity = slabs_all_only UsedCapacity = none none +SlabSynergy = none StorageHeight = 2 SymbolSprites = 55 83 PointerSprites = 38 diff --git a/keeperfx_vs2010.vcxproj b/keeperfx_vs2010.vcxproj index 20ccca5ff7..5f8b340e85 100644 --- a/keeperfx_vs2010.vcxproj +++ b/keeperfx_vs2010.vcxproj @@ -226,6 +226,7 @@ + diff --git a/keeperfx_vs2010.vcxproj.filters b/keeperfx_vs2010.vcxproj.filters index 55574e890b..54560434d6 100644 --- a/keeperfx_vs2010.vcxproj.filters +++ b/keeperfx_vs2010.vcxproj.filters @@ -735,6 +735,9 @@ Source Files + + Source Files + diff --git a/src/config_terrain.c b/src/config_terrain.c index bac86d19a8..c41dd1a30d 100644 --- a/src/config_terrain.c +++ b/src/config_terrain.c @@ -80,9 +80,10 @@ const struct NamedCommand terrain_room_commands[] = { {"PANELTABINDEX", 12}, {"TOTALCAPACITY", 13}, {"USEDCAPACITY", 14}, - {"AMBIENTSNDSAMPLE", 15}, - {"ROLES", 16}, - {"STORAGEHEIGHT", 17}, + {"SLABSYNERGY", 15}, + {"AMBIENTSNDSAMPLE", 16}, + {"ROLES", 17}, + {"STORAGEHEIGHT", 18}, {NULL, 0}, }; @@ -129,17 +130,25 @@ const struct NamedCommand room_roles_desc[] = { extern void count_slabs_all_only(struct Room *room); extern void count_slabs_all_wth_effcncy(struct Room *room); +extern void count_slabs_no_min_wth_effcncy(struct Room *room); extern void count_slabs_div2_wth_effcncy(struct Room *room); +extern void count_slabs_div2_nomin_effcncy(struct Room *room); +extern void count_slabs_mul2_wth_effcncy(struct Room *room); +extern void count_slabs_pow2_wth_effcncy(struct Room *room); extern void count_gold_slabs_wth_effcncy(struct Room *room); extern void count_gold_slabs_full(struct Room *room); const struct NamedCommand terrain_room_total_capacity_func_type[] = { {"slabs_all_only", 1}, {"slabs_all_wth_effcncy", 2}, - {"slabs_div2_wth_effcncy", 3}, - {"gold_slabs_wth_effcncy", 4}, - {"gold_slabs_full", 5}, - {"none", 6}, + {"slabs_no_min_wth_effcncy",3}, + {"slabs_div2_wth_effcncy", 4}, + {"slabs_div2_nomin_effcncy",5}, + {"slabs_mul2_wth_effcncy", 6}, + {"slabs_pow2_wth_effcncy", 7}, + {"gold_slabs_wth_effcncy", 8}, + {"gold_slabs_full", 9}, + {"none", 10}, {NULL, 0}, }; @@ -147,7 +156,11 @@ Room_Update_Func terrain_room_total_capacity_func_list[] = { NULL, count_slabs_all_only, count_slabs_all_wth_effcncy, + count_slabs_no_min_wth_effcncy, count_slabs_div2_wth_effcncy, + count_slabs_div2_nomin_effcncy, + count_slabs_mul2_wth_effcncy, + count_slabs_pow2_wth_effcncy, count_gold_slabs_wth_effcncy, count_gold_slabs_full, NULL, @@ -1083,7 +1096,27 @@ TbBool parse_terrain_room_blocks(char *buf, long len, const char *config_textnam COMMAND_TEXT(cmd_num),block_buf,config_textname); } break; - case 15: // AMBIENTSNDSAMPLE + case 15: // SLABSYNERGY + if (get_conf_parameter_single(buf,&pos,len,word_buf,sizeof(word_buf)) > 0) + { + if ((strcasecmp(word_buf, "none") == 0)) { + roomst->synergy_slab = -2; + n++; + } + k = get_id(slab_desc, word_buf); + if (k >= 0) + { + roomst->synergy_slab = k; + n++; + } + } + if (n < 1) + { + CONFWRNLOG("Incorrect value of \"%s\" parameter in [%s] block of %s file.", + COMMAND_TEXT(cmd_num),block_buf,config_textname); + } + break; + case 16: // AMBIENTSNDSAMPLE if (get_conf_parameter_single(buf,&pos,len,word_buf,sizeof(word_buf)) > 0) { k = atoi(word_buf); @@ -1095,11 +1128,12 @@ TbBool parse_terrain_room_blocks(char *buf, long len, const char *config_textnam } if (n < 1) { + roomst->synergy_slab = -3; CONFWRNLOG("Incorrect value of \"%s\" parameter in [%s] block of %s file.", COMMAND_TEXT(cmd_num),block_buf,config_textname); } break; - case 16: // ROLES + case 17: // ROLES roomst->roles = RoRoF_None; while (get_conf_parameter_single(buf,&pos,len,word_buf,sizeof(word_buf)) > 0) { @@ -1113,7 +1147,7 @@ TbBool parse_terrain_room_blocks(char *buf, long len, const char *config_textnam } } break; - case 17: // STORAGEHEIGHT + case 18: // STORAGEHEIGHT if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) { k = atoi(word_buf); diff --git a/src/config_terrain.h b/src/config_terrain.h index b57e5d0206..56af55cd5c 100644 --- a/src/config_terrain.h +++ b/src/config_terrain.h @@ -140,6 +140,7 @@ struct RoomConfigStats { TextStringId tooltip_stridx; long creature_creation_model; SlabKind assigned_slab; + SlabKind synergy_slab; char storage_height; unsigned long flags; RoomRole roles; @@ -177,7 +178,7 @@ extern const struct NamedCommand terrain_room_properties_commands[]; extern const struct NamedCommand room_roles_desc[]; extern const struct NamedCommand terrain_room_total_capacity_func_type[]; extern const struct NamedCommand terrain_room_used_capacity_func_type[]; -extern Room_Update_Func terrain_room_total_capacity_func_list[8]; +extern Room_Update_Func terrain_room_total_capacity_func_list[12]; extern Room_Update_Func terrain_room_used_capacity_func_list[10]; /******************************************************************************/ diff --git a/src/lvl_script_commands.c b/src/lvl_script_commands.c index f92ce76e6a..879ee6324a 100644 --- a/src/lvl_script_commands.c +++ b/src/lvl_script_commands.c @@ -286,7 +286,8 @@ const struct NamedCommand room_config_desc[] = { {"Roles", 13}, {"TotalCapacity", 14}, {"UsedCapacity", 15}, - {"StorageHeight", 16}, + {"SlabSynergy", 16}, + {"StorageHeight", 17}, {NULL, 0}, }; @@ -1217,7 +1218,7 @@ static void set_room_configuration_check(const struct ScriptLine* scline) } value->shorts[2] = newvalue; } - else if (roomvar == 10) // SlabAssign + else if ((roomvar == 10) || (roomvar == 16)) // SlabAssign & SlabSynergy { newvalue = get_id(slab_desc, valuestring); if (newvalue == -1) @@ -2030,7 +2031,11 @@ static void set_room_configuration_process(struct ScriptContext *context) roomst->update_workers_in_room = terrain_room_used_capacity_func_list[value2]; reinitialise_rooms_of_kind(room_type); break; - case 16: // StorageHeight + case 16: // SlabSynergy + roomst->synergy_slab = value; + recalculate_effeciency_for_rooms_of_kind(room_type); + break; + case 17: // StorageHeight roomst->storage_height = value; break; default: diff --git a/src/room_data.c b/src/room_data.c index 3e55ccc5b5..8394e8f1ca 100644 --- a/src/room_data.c +++ b/src/room_data.c @@ -63,7 +63,11 @@ extern "C" { /******************************************************************************/ void count_slabs_all_only(struct Room *room); void count_slabs_all_wth_effcncy(struct Room *room); +void count_slabs_no_min_wth_effcncy(struct Room *room); void count_slabs_div2_wth_effcncy(struct Room *room); +void count_slabs_div2_nomin_effcncy(struct Room *room); +void count_slabs_mul2_wth_effcncy(struct Room *room); +void count_slabs_pow2_wth_effcncy(struct Room *room); void count_workers_in_room(struct Room *room); long find_random_valid_position_for_item_in_different_room_avoiding_object(struct Thing* thing, struct Room* skip_room, struct Coord3d* pos); /******************************************************************************/ @@ -465,7 +469,16 @@ void count_slabs_all_wth_effcncy(struct Room *room) unsigned long count = room->slabs_count * ((long)room->efficiency); count = (count/ROOM_EFFICIENCY_MAX); if (count <= 1) - count = 1; + count = 1; + room->total_capacity = count; +} + +void count_slabs_no_min_wth_effcncy(struct Room *room) +{ + unsigned long count = room->slabs_count * ((long)room->efficiency); + count = (count/ROOM_EFFICIENCY_MAX); + if (count < 1) + count = 0; room->total_capacity = count; } @@ -478,6 +491,33 @@ void count_slabs_div2_wth_effcncy(struct Room *room) room->total_capacity = count; } +void count_slabs_div2_nomin_effcncy(struct Room *room) +{ + unsigned long count = room->slabs_count * ((long)room->efficiency); + count = ((count/ROOM_EFFICIENCY_MAX) >> 1); + if (count < 1) + count = 0; + room->total_capacity = count; +} + +void count_slabs_mul2_wth_effcncy(struct Room *room) +{ + unsigned long count = room->slabs_count * ((long)room->efficiency); + count = ((count/ROOM_EFFICIENCY_MAX) << 1); + if (count <= 1) + count = 1; + room->total_capacity = count; +} + +void count_slabs_pow2_wth_effcncy(struct Room *room) +{ + unsigned long count = room->slabs_count * ((long)room->efficiency) * ((long)room->efficiency); + count = (count/ROOM_EFFICIENCY_MAX/ROOM_EFFICIENCY_MAX); + if (count <= 1) + count = 1; + room->total_capacity = count; +} + void delete_room_structure(struct Room *room) { if (room_is_invalid(room)) @@ -1012,6 +1052,42 @@ unsigned short i_can_allocate_free_room_structure(void) } + +/** + * Recalculates all players rooms of specific kind. + * @param rkind + * @return Total amount of rooms which were reinitialized. + */ +long recalculate_effeciency_for_rooms_of_kind(RoomKind rkind) +{ + unsigned int k = 0; + for (unsigned int n = 0; n < DUNGEONS_COUNT; n++) + { + struct Dungeon* dungeon = get_dungeon(n); + unsigned int i = dungeon->room_kind[rkind]; + while (i != 0) + { + struct Room* room = room_get(i); + if (room_is_invalid(room)) + { + ERRORLOG("Jump to invalid room detected"); + break; + } + i = room->next_of_owner; + // Per-room code starts + set_room_efficiency(room); + // Per-room code ends + k++; + if (k > ROOMS_COUNT) + { + ERRORLOG("Infinite loop detected when sweeping rooms list"); + break; + } + } + } + return k; +} + /** * Re-initializes all players rooms of specific kind. * @param rkind @@ -1127,7 +1203,7 @@ long calculate_cummulative_room_slabs_effeciency(const struct Room *room) while (i != 0) { // Per room tile code - score += calculate_effeciency_score_for_room_slab(i, room->owner); + score += calculate_effeciency_score_for_room_slab(i, room->owner, get_room_kind_stats(room->kind)->synergy_slab); // Per room tile code ends i = get_next_slab_number_in_room(i); // It would be better to have this before per-tile block, but we need old value k++; diff --git a/src/room_data.h b/src/room_data.h index b8f129a6c1..ffc3d45747 100644 --- a/src/room_data.h +++ b/src/room_data.h @@ -239,6 +239,7 @@ void destroy_dungeon_heart_room(PlayerNumber plyr_idx, const struct Thing *heart void update_room_total_capacity(struct Room *room); long reinitialise_rooms_of_kind(RoomKind rkind); +long recalculate_effeciency_for_rooms_of_kind(RoomKind rkind); TbBool find_random_valid_position_for_thing_in_room_avoiding_object_excluding_room_slab(struct Thing *thing, struct Room *room, struct Coord3d *pos, long slbnum); diff --git a/src/slab_data.c b/src/slab_data.c index a79e74cb5f..dc4202af38 100644 --- a/src/slab_data.c +++ b/src/slab_data.c @@ -462,7 +462,7 @@ SlabKind find_core_slab_type(MapSlabCoord slb_x, MapSlabCoord slb_y) return corekind; } -long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNumber plyr_idx) +long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNumber plyr_idx, SlabKind synergy_slab_num) { TbBool is_room_inside = true; long eff_score = 0; @@ -478,6 +478,9 @@ long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNu MapSlabCoord slb_y = slb_num_decode_y(round_slab_num); // Per slab code if ((slabmap_owner(round_slb) == slabmap_owner(slb)) && (round_slb->kind == slb->kind)) + { + eff_score += 2; + } else if(((slabmap_owner(round_slb) == slabmap_owner(slb)) || !(get_slab_kind_attrs(synergy_slab_num)->is_ownable)) && (round_slb->kind == synergy_slab_num)) { eff_score += 2; } else diff --git a/src/slab_data.h b/src/slab_data.h index 7bb57afe12..4b4529dd05 100644 --- a/src/slab_data.h +++ b/src/slab_data.h @@ -152,7 +152,7 @@ PlayerNumber get_slab_owner_thing_is_on(const struct Thing *thing); unsigned long slabmap_wlb(struct SlabMap *slb); void slabmap_set_wlb(struct SlabMap *slb, unsigned long wlb_type); SlabCodedCoords get_next_slab_number_in_room(SlabCodedCoords slab_num); -long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNumber plyr_idx); +long calculate_effeciency_score_for_room_slab(SlabCodedCoords slab_num, PlayerNumber plyr_idx, SlabKind synergy_slab_num); TbBool slab_is_safe_land(PlayerNumber plyr_idx, MapSlabCoord slb_x, MapSlabCoord slb_y); TbBool slab_is_door(MapSlabCoord slb_x, MapSlabCoord slb_y);