From 9f1848053dabe52a2bb4083ef9420c22ee0411b6 Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:09:43 +0100 Subject: [PATCH 1/3] PrisonKindPerCreature --- config/creatrs/imp.cfg | 3 +++ src/config_crtrmodel.c | 18 +++++++++++++++ src/creature_control.h | 1 + src/creature_states_prisn.c | 46 ++++++++++++++++++++----------------- src/lvl_script_commands.c | 16 ++++++++++++- 5 files changed, 62 insertions(+), 22 deletions(-) diff --git a/config/creatrs/imp.cfg b/config/creatrs/imp.cfg index c41ca66a4e..819fe4bcd1 100644 --- a/config/creatrs/imp.cfg +++ b/config/creatrs/imp.cfg @@ -92,6 +92,9 @@ DamageToBoulder = 30 ThingSize = 240 400 ; The object the creature will create to use as a lair. Object needs to be configured correctly in objects.cfg too. LairObject = LAIR_IMP +; Defines the kind of creature it will become if it dies of starvation while imprisoned. +; Set to NULL will check if the creature has the HUMANOID_SKELETON property and will default to the room creature creation specified in terrain.cfg. +PrisonKind = NULL ; Creature properties: ; BLEEDS - the creature leaves blood when is hit, slapped, dying or being injured in any way. ; UNAFFECTED_BY_WIND - the creature isn't pushed back by Wind spell. diff --git a/src/config_crtrmodel.c b/src/config_crtrmodel.c index dad1de1735..16abaff279 100644 --- a/src/config_crtrmodel.c +++ b/src/config_crtrmodel.c @@ -85,6 +85,7 @@ const struct NamedCommand creatmodel_attributes_commands[] = { {"CORPSEVANISHEFFECT", 32}, {"FOOTSTEPPITCH", 33}, {"LAIROBJECT", 34}, + {"PRISONKIND", 35}, {NULL, 0}, }; @@ -279,6 +280,7 @@ TbBool parse_creaturemodel_attributes_blocks(long crtr_model,char *buf,long len, crstat->flying = false; crstat->can_see_invisible = false; crstat->can_go_locked_doors = false; + crstat->prison_kind = 0; crconf->namestr_idx = 0; crconf->model_flags = 0; } @@ -834,6 +836,22 @@ TbBool parse_creaturemodel_attributes_blocks(long crtr_model,char *buf,long len, COMMAND_TEXT(cmd_num), block_buf, config_textname); } break; + case 35: // PRISONKIND + if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + { + k = get_id(creature_desc, word_buf); + if (k > 0) + { + crstat->prison_kind = 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 ccr_comment: break; case ccr_endOfFile: diff --git a/src/creature_control.h b/src/creature_control.h index b5124fec11..6ffb43e5a9 100644 --- a/src/creature_control.h +++ b/src/creature_control.h @@ -532,6 +532,7 @@ struct CreatureStats { // These stats are not compatible with original DK - they unsigned short good_start_state; unsigned char natural_death_kind; unsigned char swipe_idx; + ThingModel prison_kind; struct CreaturePickedUpOffset creature_picked_up_offset; }; diff --git a/src/creature_states_prisn.c b/src/creature_states_prisn.c index 612ad53bc2..6cb5365ba5 100644 --- a/src/creature_states_prisn.c +++ b/src/creature_states_prisn.c @@ -314,9 +314,15 @@ CrStateRet creature_in_prison(struct Thing *thing) TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thing) { + struct CreatureStats* crstat = creature_stats_get_from_thing(thing); struct CreatureControl* cctrl = creature_control_get_from_thing(thing); struct Thing* crthing = INVALID_THING; - long crmodel = get_room_create_creature_model(room->kind); // That normally returns skeleton breed + ThingModel crmodel = crstat->prison_kind; + if ((crmodel > game.conf.crtr_conf.model_count) || (crmodel <= 0)) + { + // If not assigned or is unknown default to the room creature creation. + crmodel = get_room_create_creature_model(room->kind); + } if (creature_count_below_map_limit(1)) { crthing = create_creature(&thing->mappos, crmodel, room->owner); @@ -334,10 +340,10 @@ TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thin } else { - WARNLOG("Could not create creature %s to transform %s to due to creature limit", creature_code_name(crmodel),thing_model_name(thing)); + WARNLOG("Could not create creature %s to transform %s to due to creature limit", creature_code_name(crmodel), thing_model_name(thing)); } if (creature_model_bleeds(thing->model)) - create_effect_around_thing(thing, TngEff_Blood5); + create_effect_around_thing(thing, TngEff_Blood5); // TODO CONFIG: make this effect configurable? kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return !thing_is_invalid(crthing); } @@ -345,12 +351,13 @@ TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thin TbBool process_prisoner_skelification(struct Thing *thing, struct Room *room) { struct CreatureStats* crstat = creature_stats_get_from_thing(thing); - if ((thing->health >= 0) || (!crstat->humanoid_creature)) { + if ((thing->health >= 0) || ((!crstat->humanoid_creature) && ((crstat->prison_kind > game.conf.crtr_conf.model_count) || (crstat->prison_kind <= 0)))) { + return false; + } + // TODO CONFIG: (?) Allow 'skelification' only if spent specific amount of turns in prison (set it to low value). (?) + if (CREATURE_RANDOM(thing, 101) > game.conf.rules.rooms.prison_skeleton_chance) { return false; } - //TODO CONFIG Allow skeletification only if spent specific amount of turns in prison (set low value) - if (CREATURE_RANDOM(thing, 101) > game.conf.rules.rooms.prison_skeleton_chance) - return false; if (prison_convert_creature_to_skeleton(room, thing)) { if (is_my_player_number(room->owner)) @@ -358,7 +365,7 @@ TbBool process_prisoner_skelification(struct Thing *thing, struct Room *room) output_message(SMsg_PrisonMadeSkeleton, 0, true); } } - return true; //return true even if no skeleton could be created due to creature limit. Otherwise there's a confusing sound message. + return true; // Return true even if no skeleton could be created due to creature limit. Otherwise there's a confusing sound message. } void food_set_wait_to_be_eaten(struct Thing *thing) @@ -430,11 +437,7 @@ TbBool process_prison_food(struct Thing *creatng, struct Room *room) return true; } -/** - * Does a step of being imprisoned. - * Informs if the imprisoning cycle should end. - * @param thing - */ +/* Does a step of being imprisoned. * Informs if the imprisoning cycle should end. * @param thing */ CrCheckRet process_prison_function(struct Thing *creatng) { struct Room* room = get_room_creature_works_in(creatng); @@ -450,28 +453,29 @@ CrCheckRet process_prison_function(struct Thing *creatng) { return CrCkRet_Deleted; } - else if ((creatng->health < 0) && (!crstat->humanoid_creature)) - { + else if ((creatng->health < 0) && ((!crstat->humanoid_creature) && ((crstat->prison_kind > game.conf.crtr_conf.model_count) || (crstat->prison_kind <= 0)))) + { if (is_my_player_number(room->owner)) { output_message(SMsg_PrisonersStarving, MESSAGE_DELAY_STARVING, 1); } } struct CreatureControl* cctrl = creature_control_get_from_thing(creatng); - if ((cctrl->instance_id == CrInst_NULL) && process_prison_food(creatng, room) ) + if ((cctrl->instance_id == CrInst_NULL) && process_prison_food(creatng, room)) return CrCkRet_Continue; - // Breaking from jail is only possible once per some amount of turns, - // and only if creature sits in jail for long enough + // Breaking from jail is only possible once per some amount of turns, and only if creature sits in jail for long enough. if (((game.play_gameturn % game.conf.rules.rooms.time_between_prison_break) == 0) && (game.play_gameturn > cctrl->imprison.start_gameturn + game.conf.rules.rooms.time_in_prison_without_break)) { - // Check the base jail break condition - whether prison touches enemy land + // Check the base jail break condition - whether prison touches enemy land. if (jailbreak_possible(room, creatng->owner) && (CREATURE_RANDOM(creatng, 100) < game.conf.rules.rooms.prison_break_chance)) { - if (is_my_player_number(room->owner)) + if (is_my_player_number(room->owner)) { output_message(SMsg_PrisonersEscaping, 40, true); - else if (is_my_player_number(room->owner)) + } + else if (is_my_player_number(room->owner)) { output_message(SMsg_CreatrFreedPrison, 40, true); + } set_start_state(creatng); return CrCkRet_Continue; } diff --git a/src/lvl_script_commands.c b/src/lvl_script_commands.c index 3aa61276ed..eda5e79f54 100644 --- a/src/lvl_script_commands.c +++ b/src/lvl_script_commands.c @@ -2818,7 +2818,7 @@ static void set_creature_configuration_check(const struct ScriptLine* scline) } else if (creatvar == 34) // LAIROBJECT { - if (parameter_is_number(scline->tp[2])) //support name or number for lair object + if (parameter_is_number(scline->tp[2])) // Support name or number for lair object. { value1 = atoi(scline->tp[2]); } @@ -2827,6 +2827,17 @@ static void set_creature_configuration_check(const struct ScriptLine* scline) value1 = get_id(object_desc, scline->tp[2]); } } + else if (creatvar == 35) // PRISONKIND + { + if (parameter_is_number(scline->tp[2])) // Support name or number for prison kind. + { + value1 = atoi(scline->tp[2]); + } + else + { + value1 = get_id(creature_desc, scline->tp[2]); + } + } else { value1 = atoi(scline->tp[2]); @@ -3107,6 +3118,9 @@ static void set_creature_configuration_process(struct ScriptContext* context) crstat->lair_object = value; } break; + case 35: // PRISONKIND + crstat->prison_kind = value; + break; case ccr_comment: break; case ccr_endOfFile: From 147da8f96a3cd87e0ef1292bee0a159b462ed5ea Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Fri, 1 Nov 2024 10:06:57 +0100 Subject: [PATCH 2/3] TortureKindPerCreature --- config/creatrs/imp.cfg | 10 +++++----- src/config_crtrmodel.c | 18 ++++++++++++++++++ src/creature_control.h | 1 + src/creature_states_prisn.c | 5 +++-- src/creature_states_tortr.c | 18 +++++++++++++----- src/lvl_script_commands.c | 7 +++++-- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/config/creatrs/imp.cfg b/config/creatrs/imp.cfg index d86f45dc5e..cfc53bab8b 100644 --- a/config/creatrs/imp.cfg +++ b/config/creatrs/imp.cfg @@ -34,8 +34,7 @@ Armour = 5 ; Every 26 points of difference between shooter dexterity and victim defence gives ~10% to the odds. ; Also, odds can never get higher than 88% or lower than 12%. Dexterity = 60 -; Wounded fear set to 101 will make creature escape from any combat other than -; protecting heart, or a combat with single creature of the same kind. +; Wounded fear set to 101 will make creature escape from any combat other than protecting heart, or a combat with single creature of the same kind. ; This special value works the same way regardless of creature tendencies. ; Smaller value will make the creature escape if it has less than given percentage of health left. ; 0: never escape, 100: escape even if no health is lost. @@ -93,8 +92,10 @@ ThingSize = 240 400 ; The object the creature will create to use as a lair. Object needs to be configured correctly in objects.cfg too. LairObject = LAIR_IMP ; Defines the kind of creature it will become if it dies of starvation while imprisoned. -; Set to NULL will check if the creature has the HUMANOID_SKELETON property and will default to the room creature creation specified in terrain.cfg. +; Setting this to NULL will check if the creature has the 'HUMANOID_SKELETON' property and will default to the room creature creation specified in terrain.cfg. PrisonKind = NULL +; Defines the kind of creature it will become if it dies from torture. The same rule applies as above, except it does not consider the 'HUMANOID_SKELETON' property. +TortureKind = NULL ; Creature properties: ; BLEEDS - the creature leaves blood when is hit, slapped, dying or being injured in any way. ; UNAFFECTED_BY_WIND - the creature isn't pushed back by Wind spell. @@ -107,8 +108,7 @@ PrisonKind = NULL ; SPECIAL_DIGGER - creature can dig and perform other dungeon tasks. ; ARACHNID - creature is kind of spider. ; DIPTERA - creature is kind of fly. -; LORD - creature is lord of the land, usually arrives to level as final boss, and at arrival -; you can hear "beware, the lord of the land approaches". +; LORD - creature is lord of the land, usually arrives to level as final boss, and at arrival you can hear "beware, the lord of the land approaches". ; SPECTATOR - creature is just a spectator for multiplayer games. ; EVIL - creature has evil nature. ; NEVER_CHICKENS - creature isn't affected by Chicken spell. diff --git a/src/config_crtrmodel.c b/src/config_crtrmodel.c index 0e427abe11..79790ef40f 100644 --- a/src/config_crtrmodel.c +++ b/src/config_crtrmodel.c @@ -86,6 +86,7 @@ const struct NamedCommand creatmodel_attributes_commands[] = { {"FOOTSTEPPITCH", 33}, {"LAIROBJECT", 34}, {"PRISONKIND", 35}, + {"TORTUREKIND", 36}, {NULL, 0}, }; @@ -282,6 +283,7 @@ TbBool parse_creaturemodel_attributes_blocks(long crtr_model,char *buf,long len, crstat->can_see_invisible = false; crstat->can_go_locked_doors = false; crstat->prison_kind = 0; + crstat->torture_kind = 0; crconf->namestr_idx = 0; crconf->model_flags = 0; } @@ -853,6 +855,22 @@ TbBool parse_creaturemodel_attributes_blocks(long crtr_model,char *buf,long len, COMMAND_TEXT(cmd_num), block_buf, config_textname); } break; + case 36: // TORTUREKIND + if (get_conf_parameter_single(buf, &pos, len, word_buf, sizeof(word_buf)) > 0) + { + k = get_id(creature_desc, word_buf); + if (k > 0) + { + crstat->torture_kind = 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 ccr_comment: break; case ccr_endOfFile: diff --git a/src/creature_control.h b/src/creature_control.h index a4c18442a3..4acfe9ca42 100644 --- a/src/creature_control.h +++ b/src/creature_control.h @@ -534,6 +534,7 @@ struct CreatureStats { // These stats are not compatible with original DK - they unsigned char natural_death_kind; unsigned char swipe_idx; ThingModel prison_kind; + ThingModel torture_kind; struct CreaturePickedUpOffset creature_picked_up_offset; }; diff --git a/src/creature_states_prisn.c b/src/creature_states_prisn.c index 6cb5365ba5..d6d4ee91aa 100644 --- a/src/creature_states_prisn.c +++ b/src/creature_states_prisn.c @@ -320,7 +320,7 @@ TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thin ThingModel crmodel = crstat->prison_kind; if ((crmodel > game.conf.crtr_conf.model_count) || (crmodel <= 0)) { - // If not assigned or is unknown default to the room creature creation. + // If not assigned or is unknown, default to the room creature creation. crmodel = get_room_create_creature_model(room->kind); } if (creature_count_below_map_limit(1)) @@ -342,8 +342,9 @@ TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thin { WARNLOG("Could not create creature %s to transform %s to due to creature limit", creature_code_name(crmodel), thing_model_name(thing)); } - if (creature_model_bleeds(thing->model)) + if (creature_model_bleeds(thing->model)) { create_effect_around_thing(thing, TngEff_Blood5); // TODO CONFIG: make this effect configurable? + } kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return !thing_is_invalid(crthing); } diff --git a/src/creature_states_tortr.c b/src/creature_states_tortr.c index 534d004ac8..53e11c4c7e 100644 --- a/src/creature_states_tortr.c +++ b/src/creature_states_tortr.c @@ -273,14 +273,20 @@ CrCheckRet process_kinky_function(struct Thing *thing) void convert_creature_to_ghost(struct Room *room, struct Thing *thing) { - int crmodel = get_room_create_creature_model(room->kind); + struct CreatureStats* crstat = creature_stats_get_from_thing(thing); + ThingModel crmodel = crstat->torture_kind; + if ((crmodel > game.conf.crtr_conf.model_count) || (crmodel <= 0)) + { + // If not assigned or is unknown, default to the room creature creation. + crmodel = get_room_create_creature_model(room->kind); + } struct Thing* newthing = INVALID_THING; if (creature_count_below_map_limit(1)) { newthing = create_creature(&thing->mappos, crmodel, room->owner); if (thing_is_invalid(newthing)) { - ERRORLOG("Couldn't create creature %s in %s room",creature_code_name(crmodel),room_code_name(room->kind)); + ERRORLOG("Couldn't create creature %s in %s room", creature_code_name(crmodel), room_code_name(room->kind)); return; } } else @@ -290,8 +296,9 @@ void convert_creature_to_ghost(struct Room *room, struct Thing *thing) struct CreatureControl* cctrl = creature_control_get_from_thing(thing); struct CreatureControl* newcctrl = creature_control_get_from_thing(newthing); init_creature_level(newthing, cctrl->explevel); - if (creature_model_bleeds(thing->model)) - create_effect_around_thing(newthing, TngEff_Blood5); + if (creature_model_bleeds(thing->model)) { + create_effect_around_thing(newthing, TngEff_Blood5); // TODO CONFIG: make this effect configurable? + } set_start_state(newthing); strcpy(newcctrl->creature_name, cctrl->creature_name); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects|CrDed_DiedInBattle); @@ -299,8 +306,9 @@ void convert_creature_to_ghost(struct Room *room, struct Thing *thing) if (!dungeon_invalid(dungeon)) { dungeon->lvstats.ghosts_raised++; } - if (is_my_player_number(room->owner)) + if (is_my_player_number(room->owner)) { output_message(SMsg_TortureMadeGhost, 0, true); + } } void convert_tortured_creature_owner(struct Thing *creatng, PlayerNumber new_owner) diff --git a/src/lvl_script_commands.c b/src/lvl_script_commands.c index 921d4e1135..85a7844068 100644 --- a/src/lvl_script_commands.c +++ b/src/lvl_script_commands.c @@ -2827,9 +2827,9 @@ static void set_creature_configuration_check(const struct ScriptLine* scline) value1 = get_id(object_desc, scline->tp[2]); } } - else if (creatvar == 35) // PRISONKIND + else if ((creatvar == 35) || (creatvar == 36)) // PRISONKIND or TORTUREKIND { - if (parameter_is_number(scline->tp[2])) // Support name or number for prison kind. + if (parameter_is_number(scline->tp[2])) // Support name or number for prison kind or torture kind. { value1 = atoi(scline->tp[2]); } @@ -3121,6 +3121,9 @@ static void set_creature_configuration_process(struct ScriptContext* context) case 35: // PRISONKIND crstat->prison_kind = value; break; + case 36: // TORTUREKIND + crstat->torture_kind = value; + break; case ccr_comment: break; case ccr_endOfFile: From 015dc11a4fdba65e9f7491fb327299bfdb2c605f Mon Sep 17 00:00:00 2001 From: walter253 <130906143+walt253@users.noreply.github.com> Date: Fri, 1 Nov 2024 10:08:11 +0100 Subject: [PATCH 3/3] Update imp.cfg --- config/creatrs/imp.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/creatrs/imp.cfg b/config/creatrs/imp.cfg index cfc53bab8b..3109c1492e 100644 --- a/config/creatrs/imp.cfg +++ b/config/creatrs/imp.cfg @@ -94,7 +94,8 @@ LairObject = LAIR_IMP ; Defines the kind of creature it will become if it dies of starvation while imprisoned. ; Setting this to NULL will check if the creature has the 'HUMANOID_SKELETON' property and will default to the room creature creation specified in terrain.cfg. PrisonKind = NULL -; Defines the kind of creature it will become if it dies from torture. The same rule applies as above, except it does not consider the 'HUMANOID_SKELETON' property. +; Defines the kind of creature it will become if it dies from torture. +; The same rule applies as above, except it does not consider the 'HUMANOID_SKELETON' property. TortureKind = NULL ; Creature properties: ; BLEEDS - the creature leaves blood when is hit, slapped, dying or being injured in any way.