Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 24 additions & 59 deletions src/engine/core/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,15 @@ void CheckLight(CharData *ch, int was_equip, int was_single, int was_holylight,
}

void DecreaseFeatTimer(CharData *ch, EFeat feat_id) {
for (auto *skj = ch->timed_feat; skj; skj = skj->next) {
if (skj->feat == feat_id) {
if (skj->time >= 1) {
--(skj->time);
} else {
ExpireTimedFeat(ch, skj);
}
return;
auto it = ch->timed_feat.find(feat_id);
if (it != ch->timed_feat.end()) {
if (it->second >= 1) {
--(it->second);
} else {
ch->timed_feat.erase(it);
}
}
};
}

template <class TalentId>
int GetTalentTimerMod(CharData *ch, TalentId id) {
Expand All @@ -151,82 +149,49 @@ int GetTalentTimerMod(CharData *ch, TalentId id) {
}

void ImposeTimedFeat(CharData *ch, TimedFeat *timed) {
timed->time = std::max(1, timed->time + GetTalentTimerMod(ch, timed->feat));

struct TimedFeat *timed_alloc, *skj;
for (skj = ch->timed_feat; skj; skj = skj->next) {
if (skj->feat == timed->feat) {
skj->time = timed->time;
return;
}
}

CREATE(timed_alloc, 1);

*timed_alloc = *timed;
timed_alloc->next = ch->timed_feat;
ch->timed_feat = timed_alloc;
ch->timed_feat[timed->feat] = std::max(1, timed->time + GetTalentTimerMod(ch, timed->feat));
}

void ExpireTimedFeat(CharData *ch, TimedFeat *timed) {
if (ch->timed_feat == nullptr) {
void ExpireTimedFeat(CharData *ch, EFeat feat) {
if (ch->timed_feat.empty()) {
log("SYSERR: timed_feat_from_char(%s) when no timed...", GET_NAME(ch));
return;
}

REMOVE_FROM_LIST(timed, ch->timed_feat);
free(timed);
ch->timed_feat.erase(feat);
}

int IsTimedByFeat(CharData *ch, EFeat feat) {
struct TimedFeat *hjp;

for (hjp = ch->timed_feat; hjp; hjp = hjp->next)
if (hjp->feat == feat)
return (hjp->time);

auto it = ch->timed_feat.find(feat);
if (it != ch->timed_feat.end()) {
return it->second;
}
return (0);
}

/**
* Insert an TimedSkill in a char_data structure
*/
void ImposeTimedSkill(CharData *ch, struct TimedSkill *timed) {
timed->time = std::max(1, timed->time + GetTalentTimerMod(ch, timed->skill));

struct TimedSkill *timed_alloc, *skj;
for (skj = ch->timed; skj; skj = skj->next) {
if (skj->skill == timed->skill) {
skj->time = timed->time;
return;
}
}

CREATE(timed_alloc, 1);

*timed_alloc = *timed;
timed_alloc->next = ch->timed;
ch->timed = timed_alloc;
ch->timed_skill[timed->skill] = std::max(1, timed->time + GetTalentTimerMod(ch, timed->skill));
}

void ExpireTimedSkill(CharData *ch, struct TimedSkill *timed) {
if (ch->timed == nullptr) {
void ExpireTimedSkill(CharData *ch, ESkill skill) {
if (ch->timed_skill.empty()) {
log("SYSERR: ExpireTimedSkill(%s) when no timed...", GET_NAME(ch));
// core_dump();
return;
}

REMOVE_FROM_LIST(timed, ch->timed);
free(timed);
ch->timed_skill.erase(skill);
}

int IsTimedBySkill(CharData *ch, ESkill id) {
struct TimedSkill *hjp;

for (hjp = ch->timed; hjp; hjp = hjp->next)
if (hjp->skill == id)
return (hjp->time);


auto it = ch->timed_skill.find(id);
if (it != ch->timed_skill.end()) {
return it->second;
}
return (0);
}

Expand Down
6 changes: 3 additions & 3 deletions src/engine/core/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ void CheckLight(CharData *ch, int was_equip, int was_single, int was_holylight,

// handling the affected-structures //
void ImposeTimedFeat(CharData *ch, TimedFeat *timed);
void ExpireTimedFeat(CharData *ch, TimedFeat *timed);
void ExpireTimedFeat(CharData *ch, EFeat feat);
int IsTimedByFeat(CharData *ch, EFeat feat);
void ImposeTimedSkill(CharData *ch, struct TimedSkill *timed);
void ExpireTimedSkill(CharData *ch, struct TimedSkill *timed);
void ImposeTimedSkill(CharData *ch, TimedSkill *timed);
void ExpireTimedSkill(CharData *ch, ESkill skill);
int IsTimedBySkill(CharData *ch, ESkill id);
void DecreaseFeatTimer(CharData *ch, EFeat feat_id);

Expand Down
6 changes: 3 additions & 3 deletions src/engine/core/iosystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1163,10 +1163,10 @@ std::string MakePrompt(DescriptorData *d) {
}

if (ch->IsFlagged(EPrf::kDispTimed)) {
for (auto timed = ch->timed; timed; timed = timed->next) {
if (timed->skill != ESkill::kWarcry && timed->skill != ESkill::kTurnUndead) {
for (auto timed : ch->timed_skill) {
if (timed.first != ESkill::kWarcry && timed.first != ESkill::kTurnUndead) {
fmt::format_to(std::back_inserter(out), "{}:{} ",
MUD::Skill(timed->skill).GetAbbr(), +timed->time);
MUD::Skill(timed.first).GetAbbr(), +timed.second);
}
}
if (ch->GetSkill(ESkill::kWarcry)) {
Expand Down
7 changes: 1 addition & 6 deletions src/engine/entities/char_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,6 @@ void CharData::zero_init() {
punctual_wait = 0;
last_comm.clear();
player_specials = nullptr;
timed = nullptr;
timed_feat = nullptr;
carrying = nullptr;
desc = nullptr;
followers = nullptr;
Expand Down Expand Up @@ -430,10 +428,7 @@ void CharData::purge() {
free(this->mob_specials.Questor);
}
this->affected.clear();
while (this->timed) {
ExpireTimedSkill(this, this->timed);
}

this->timed_skill.clear();
celebrates::RemoveFromMobLists(this->get_uid());

const bool keep_player_specials = player_specials == player_special_data::s_for_mobiles ? true : false;
Expand Down
4 changes: 2 additions & 2 deletions src/engine/entities/char_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,8 +775,8 @@ class CharData : public ProtectedCharData {
int GetCarryingQuantity() const { return char_specials.carry_items; };

char_affects_list_t affected; // affected by what spells
struct TimedSkill *timed; // use which timed skill/spells
struct TimedFeat *timed_feat; // use which timed feats
std::unordered_map<ESkill, ubyte> timed_skill; // use which timed skill/spells
std::unordered_map<EFeat, ubyte> timed_feat; // use which timed feats
ObjData *equipment[EEquipPos::kNumEquipPos]; // Equipment array

ObjData *carrying; // Head of list
Expand Down
14 changes: 5 additions & 9 deletions src/engine/entities/char_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,6 @@ void Player::save_char() {
int i;
time_t li;
ObjData *char_eq[EEquipPos::kNumEquipPos];
struct TimedSkill *skj;

int tmp = time(0) - this->player_data.time.logon;

Expand Down Expand Up @@ -539,8 +538,8 @@ void Player::save_char() {

if (GetRealLevel(this) < kLvlImmortal) {
fprintf(saved, "FtTm:\n");
for (auto tf = this->timed_feat; tf; tf = tf->next) {
fprintf(saved, "%d %d %s\n", to_underlying(tf->feat), tf->time, MUD::Feat(tf->feat).GetCName());
for (auto tf : this->timed_feat) {
fprintf(saved, "%d %d %s\n", to_underlying(tf.first), tf.second, MUD::Feat(tf.first).GetCName());
}
fprintf(saved, "0 0\n");
}
Expand All @@ -566,8 +565,8 @@ void Player::save_char() {
// Задержки на скилы
if (GetRealLevel(this) < kLvlImmortal) {
fprintf(saved, "SkTm:\n");
for (skj = this->timed; skj; skj = skj->next) {
fprintf(saved, "%d %d\n", to_underlying(skj->skill), skj->time);
for (auto skj : this->timed_skill) {
fprintf(saved, "%d %d %s\n", to_underlying(skj.first), skj.second, MUD::Skill(skj.first).GetName());
}
fprintf(saved, "0 0\n");
}
Expand Down Expand Up @@ -956,7 +955,6 @@ int Player::load_char_ascii(const char *name, const int load_flags) {
char filename[40];
char line[kMaxStringLength], tag[6];
char line1[kMaxStringLength];
TimedSkill timed;
TimedFeat timed_feat;
*filename = '\0';
log("Load ascii char %s", name);
Expand Down Expand Up @@ -1769,9 +1767,7 @@ int Player::load_char_ascii(const char *name, const int load_flags) {
fbgetline(fl, line);
sscanf(line, "%d %d", &num, &num2);
if (num != 0) {
timed.skill = static_cast<ESkill>(num);
timed.time = num2;
ImposeTimedSkill(this, &timed);
this->timed_skill[static_cast<ESkill>(num)] = num2;
}
} while (num != 0);
} else if (!strcmp(tag, "Spel")) {
Expand Down
9 changes: 2 additions & 7 deletions src/engine/ui/cmd/do_remort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,8 @@ void DoRemort(CharData *ch, char *argument, int/* cmd*/, int subcmd) {
}
}

while (ch->timed) {
ExpireTimedSkill(ch, ch->timed);
}

while (ch->timed_feat) {
ExpireTimedFeat(ch, ch->timed_feat);
}
ch->timed_skill.clear();
ch->timed_feat.clear();
for (const auto &feat : MUD::Feats()) {
ch->UnsetFeat(feat.GetId());
}
Expand Down
12 changes: 2 additions & 10 deletions src/engine/ui/cmd_god/do_arena_restore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ void DoArenaRestore(CharData *ch, char *argument, int/* cmd*/, int/* subcmd*/) {
} else {
vict->mem_queue.stored = vict->mem_queue.total;
}
if (vict->GetSkill(ESkill::kWarcry) > 0) {
struct TimedSkill wctimed;
wctimed.skill = ESkill::kWarcry;
wctimed.time = 0;
ImposeTimedSkill(vict, &wctimed);
}
if (IS_GRGOD(ch) && IS_IMMORTAL(vict)) {
vict->set_str(25);
vict->set_int(25);
Expand All @@ -46,10 +40,8 @@ void DoArenaRestore(CharData *ch, char *argument, int/* cmd*/, int/* subcmd*/) {
RemoveAffectFromChar(vict, ESpell::kAbstinent);

//сброс таймеров скиллов и фитов
while (vict->timed)
ExpireTimedSkill(vict, vict->timed);
while (vict->timed_feat)
ExpireTimedFeat(vict, vict->timed_feat);
ch->timed_skill.clear();
ch->timed_feat.clear();
reset_affects(vict);
for (int i = 0; i < EEquipPos::kNumEquipPos; i++) {
if (GET_EQ(vict, i)) {
Expand Down
13 changes: 2 additions & 11 deletions src/engine/ui/cmd_god/do_restore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ void DoRestore(CharData *ch, char *argument, int/* cmd*/, int subcmd) {
} else {
vict->mem_queue.stored = vict->mem_queue.total;
}
if (vict->GetSkill(ESkill::kWarcry) > 0) {
struct TimedSkill wctimed;
wctimed.skill = ESkill::kWarcry;
wctimed.time = 0;
ImposeTimedSkill(vict, &wctimed);
}
if (IS_GRGOD(ch) && IS_IMMORTAL(vict)) {
vict->set_str(25);
vict->set_int(25);
Expand All @@ -56,11 +50,8 @@ void DoRestore(CharData *ch, char *argument, int/* cmd*/, int subcmd) {
RemoveAffectFromChar(vict, ESpell::kAbstinent);

//сброс таймеров скиллов и фитов
while (vict->timed)
ExpireTimedSkill(vict, vict->timed);
while (vict->timed_feat)
ExpireTimedFeat(vict, vict->timed_feat);

ch->timed_skill.clear();
ch->timed_feat.clear();
if (subcmd == kScmdRestoreGod) {
SendMsgToChar(OK, ch);
act("Вы были полностью восстановлены $N4!",
Expand Down
1 change: 0 additions & 1 deletion src/gameplay/abilities/feats.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
struct TimedFeat {
EFeat feat{EFeat::kUndefined}; // Used feature //
ubyte time{0}; // Time for next using //
struct TimedFeat *next{nullptr};
};

int CalcMaxFeatSlotPerLvl(const CharData *ch);
Expand Down
47 changes: 21 additions & 26 deletions src/gameplay/affects/affect_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,25 +191,22 @@ void player_timed_update() {
for (auto d = descriptor_list; d; d = d->next) {
if (d->state != EConState::kPlaying)
continue;
const auto i = d->get_character();
auto ch = i.get();
const auto ch = d->get_character().get();

decltype(ch->timed) timed_skill;
for (auto timed = ch->timed; timed; timed = timed_skill) {
timed_skill = timed->next;
if (timed->time >= 1) {
timed->time--;
for (auto timed = ch->timed_skill.begin(); timed != ch->timed_skill.end();) {
if (timed->second >= 1) {
timed->second--;
++timed;
} else {
ExpireTimedSkill(ch, timed);
timed = ch->timed_skill.erase(timed);
}
}
decltype(ch->timed_feat) timed_feat;
for (auto timed = ch->timed_feat; timed; timed = timed_feat) {
timed_feat = timed->next;
if (timed->time >= 1) {
timed->time--;
for (auto timed = ch->timed_feat.begin(); timed != ch->timed_feat.end();) {
if (timed->second >= 1) {
timed->second--;
++timed;
} else {
ExpireTimedFeat(ch, timed);
timed = ch->timed_feat.erase(timed);
}
}
}
Expand Down Expand Up @@ -448,22 +445,20 @@ void mobile_affect_update() {
if (need_recalc) {
affect_total(ch);
}
decltype(ch->timed) timed_skill;
for (auto timed = ch->timed; timed; timed = timed_skill) {
timed_skill = timed->next;
if (timed->time >= 1) {
timed->time--;
for (auto timed = ch->timed_skill.begin(); timed != ch->timed_skill.end();) {
if (timed->second >= 1) {
timed->second--;
++timed;
} else {
ExpireTimedSkill(ch, timed);
timed = ch->timed_skill.erase(timed);
}
}
decltype(ch->timed_feat) timed_feat;
for (auto timed = ch->timed_feat; timed; timed = timed_feat) {
timed_feat = timed->next;
if (timed->time >= 1) {
timed->time--;
for (auto timed = ch->timed_feat.begin(); timed != ch->timed_feat.end();) {
if (timed->second >= 1) {
timed->second--;
++timed;
} else {
ExpireTimedFeat(ch, timed);
timed = ch->timed_feat.erase(timed);
}
}
if (deathtrap::check_death_trap(ch)) {
Expand Down
Loading