Skip to content

Commit

Permalink
Prison & Torture Kind per creature, 2 new fields on the creature conf…
Browse files Browse the repository at this point in the history
…ig file (#3613)
  • Loading branch information
walt253 authored Nov 2, 2024
1 parent 929e7af commit cdb6f86
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 30 deletions.
9 changes: 7 additions & 2 deletions config/creatrs/imp.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -92,6 +91,12 @@ 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.
; 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.
Expand Down
36 changes: 36 additions & 0 deletions src/config_crtrmodel.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ const struct NamedCommand creatmodel_attributes_commands[] = {
{"CORPSEVANISHEFFECT", 32},
{"FOOTSTEPPITCH", 33},
{"LAIROBJECT", 34},
{"PRISONKIND", 35},
{"TORTUREKIND", 36},
{NULL, 0},
};

Expand Down Expand Up @@ -281,6 +283,8 @@ 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;
crstat->torture_kind = 0;
crconf->namestr_idx = 0;
crconf->model_flags = 0;
}
Expand Down Expand Up @@ -840,6 +844,38 @@ 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 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:
Expand Down
2 changes: 2 additions & 0 deletions src/creature_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ 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;
ThingModel torture_kind;
struct CreaturePickedUpOffset creature_picked_up_offset;
};

Expand Down
49 changes: 27 additions & 22 deletions src/creature_states_prisn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -334,31 +340,33 @@ 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); // TODO CONFIG: make this effect configurable?
}
if (creature_model_bleeds(thing->model))
create_effect_around_thing(thing, TngEff_Blood5);
kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects);
return !thing_is_invalid(crthing);
}

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))
{
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)
Expand Down Expand Up @@ -430,11 +438,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);
Expand All @@ -450,28 +454,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;
}
Expand Down
18 changes: 13 additions & 5 deletions src/creature_states_tortr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -290,17 +296,19 @@ 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);
struct Dungeon* dungeon = get_dungeon(room->owner);
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)
Expand Down
19 changes: 18 additions & 1 deletion src/lvl_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
Expand All @@ -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) || (creatvar == 36)) // PRISONKIND or TORTUREKIND
{
if (parameter_is_number(scline->tp[2])) // Support name or number for prison kind or torture kind.
{
value1 = atoi(scline->tp[2]);
}
else
{
value1 = get_id(creature_desc, scline->tp[2]);
}
}
else
{
value1 = atoi(scline->tp[2]);
Expand Down Expand Up @@ -3107,6 +3118,12 @@ static void set_creature_configuration_process(struct ScriptContext* context)
crstat->lair_object = value;
}
break;
case 35: // PRISONKIND
crstat->prison_kind = value;
break;
case 36: // TORTUREKIND
crstat->torture_kind = value;
break;
case ccr_comment:
break;
case ccr_endOfFile:
Expand Down

0 comments on commit cdb6f86

Please sign in to comment.