Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Enemy AI #2381

Merged
merged 5 commits into from
Oct 25, 2020
Merged
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ add_library(${PROJECT_NAME} STATIC
src/dynrpg.h
src/dynrpg_easyrpg.cpp
src/dynrpg_easyrpg.h
src/enemyai.cpp
src/enemyai.h
src/exe_reader.cpp
src/exe_reader.h
src/exfont.h
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ libeasyrpg_player_a_SOURCES = \
src/dynrpg.h \
src/dynrpg_easyrpg.cpp \
src/dynrpg_easyrpg.h \
src/enemyai.cpp \
src/enemyai.h \
src/exe_reader.cpp \
src/exe_reader.h \
src/exfont.h \
Expand Down
13 changes: 9 additions & 4 deletions resources/easyrpg-player.6.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,21 @@ directory!
*--seed* 'SEED'::
Seeds the random number generator.

*--start-map-id* 'ID'::
Overwrite the map used for new games and use Map__ID__.lmu instead ('ID' is
padded to four digits).

*--autobattle-algo* 'ALGO'::
Which AutoBattle algorithm to use. Possible options:
- 'RPG_RT' - The default RPG_RT compatible algo, including RPG_RT bugs
- 'RPG_RT+' - The default RPG_RT compatible algo, with bug fixes
- 'ATTACK' - RPG_RT+ but only physical attacks, no skills

*--enemyai-algo* 'ALGO'::
Which EnemyAI algorithm to use. Possible options:
- 'RPG_RT' - The default RPG_RT compatible algo, including RPG_RT bugs
- 'RPG_RT+' - The default RPG_RT compatible algo, with bug fixes

*--start-map-id* 'ID'::
Overwrite the map used for new games and use Map__ID__.lmu instead ('ID' is
padded to four digits).

NOTE: Incompatible with *--load-game-id*.

*--start-position* 'X' 'Y'::
Expand Down
10 changes: 8 additions & 2 deletions resources/unix/bash-completion/easyrpg-player
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ _easyrpg-player ()

# all possible options
ouropts='--autobattle-algo --battle-test --disable-audio --disable-rtp --enable-mouse --enable-touch \
--encoding --engine --fps-limit --fps-render-window --fullscreen -h --help \
--encoding --enemyai-algo --engine --fps-limit --fps-render-window --fullscreen -h --help \
--hide-title --load-game-id --new-game --no-vsync --project-path --record-input \
--replay-input --save-path --seed --show-fps --start-map-id --start-party \
--start-position --test-play --window -v --version'
rpgrtopts='BattleTest battletest HideTitle hidetitle TestPlay testplay Window window'
engines='rpg2k rpg2kv150 rpg2ke rpg2k3 rpg2k3v105 rpg2k3e'
autobattle_algos='RPG_RT RPG_RT+ ATTACK'
enemyai_algos='RPG_RT RPG_RT+'

# first list all special cases
case $prev in
Expand All @@ -36,10 +37,15 @@ _easyrpg-player ()
return
;;
# Select autobattle algorithm
--autobattle-algos)
--autobattle-algo)
COMPREPLY=($(compgen -W "$autobattle_algos" -- $cur))
return
;;
# Select enemyai algorithm
--enemyai-algo)
COMPREPLY=($(compgen -W "$enemyai_algos" -- $cur))
return
;;
# load save files
--load-game-id)
# broken, disabled for now
Expand Down
10 changes: 3 additions & 7 deletions src/algo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ int CalcSkillToHit(const Game_Battler& source, const Game_Battler& target, const

// RPG_RT BUG: rm2k3 editor doesn't let you set the failure message for skills, and so you can't make them physical type anymore.
// Despite that, RPG_RT still checks the flag and run the below code?
if (skill.failure_message != 3
|| (skill.scope != lcf::rpg::Skill::Scope_enemy && skill.scope != lcf::rpg::Skill::Scope_enemies)) {
if (skill.failure_message != 3 || SkillTargetsAllies(skill)) {
return to_hit;
}

Expand Down Expand Up @@ -225,9 +224,7 @@ int CalcSkillEffect(const Game_Battler& source,
effect += skill.physical_rate * source.GetAtk() / 20;
effect += skill.magical_rate * source.GetSpi() / 40;

if ((skill.scope == lcf::rpg::Skill::Scope_enemy
|| skill.scope == lcf::rpg::Skill::Scope_enemies)
&& !skill.ignore_defense) {
if (SkillTargetsEnemies(skill) && !skill.ignore_defense) {
effect -= skill.physical_rate * target.GetDef() / 40;
effect -= skill.magical_rate * target.GetSpi() / 80;
}
Expand Down Expand Up @@ -285,8 +282,7 @@ bool IsSkillUsable(const lcf::rpg::Skill& skill,
return true;
}

if (skill.scope == lcf::rpg::Skill::Scope_enemy
|| skill.scope == lcf::rpg::Skill::Scope_enemies) {
if (SkillTargetsEnemies(skill)) {
return false;
}

Expand Down
21 changes: 21 additions & 0 deletions src/algo.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@ inline bool IsNormalOrSubskill(const lcf::rpg::Skill& skill) {
|| skill.type >= lcf::rpg::Skill::Type_subskill;
}

/**
* Checks if the skill targets the opposing party.
*
* @param skill the skill to check
* @return true if targets opposing party
*/
inline bool SkillTargetsEnemies(const lcf::rpg::Skill& skill) {
return skill.scope == lcf::rpg::Skill::Scope_enemy
|| skill.scope == lcf::rpg::Skill::Scope_enemies;
}

/**
* Checks if the skill targets the allied party.
*
* @param skill the skill to check
* @return true if targets allied party
*/
inline bool SkillTargetsAllies(const lcf::rpg::Skill& skill) {
return !SkillTargetsEnemies(skill);
}

} // namespace Algo


Expand Down
10 changes: 5 additions & 5 deletions src/autobattle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ static int CalcSkillCostAutoBattle(const Game_Actor& source, const lcf::rpg::Ski
}

double CalcSkillHealAutoBattleTargetRank(const Game_Actor& source, const Game_Battler& target, const lcf::rpg::Skill& skill, bool apply_variance, bool emulate_bugs) {
assert(skill.type == lcf::rpg::Skill::Type_normal || skill.type >= lcf::rpg::Skill::Type_subskill);
assert(skill.scope == lcf::rpg::Skill::Scope_self || skill.scope == lcf::rpg::Skill::Scope_ally || skill.scope == lcf::rpg::Skill::Scope_party);
assert(Algo::IsNormalOrSubskill(skill));
assert(Algo::SkillTargetsAllies(skill));

const double src_max_sp = source.GetMaxSp();
const double tgt_max_hp = target.GetMaxHp();
Expand Down Expand Up @@ -124,8 +124,8 @@ double CalcSkillHealAutoBattleTargetRank(const Game_Actor& source, const Game_Ba
}

double CalcSkillDmgAutoBattleTargetRank(const Game_Actor& source, const Game_Battler& target, const lcf::rpg::Skill& skill, bool apply_variance, bool emulate_bugs) {
assert(skill.type == lcf::rpg::Skill::Type_normal || skill.type >= lcf::rpg::Skill::Type_subskill);
assert(skill.scope == lcf::rpg::Skill::Scope_enemy || skill.scope == lcf::rpg::Skill::Scope_enemies);
assert(Algo::IsNormalOrSubskill(skill));
assert(Algo::SkillTargetsEnemies(skill));
(void)emulate_bugs;

if (!(skill.affect_hp && target.Exists())) {
Expand Down Expand Up @@ -164,7 +164,7 @@ double CalcSkillAutoBattleRank(const Game_Actor& source, const lcf::rpg::Skill&
if (!source.IsSkillUsable(skill.ID)) {
return 0.0;
}
if (skill.type != lcf::rpg::Skill::Type_normal && skill.type < lcf::rpg::Skill::Type_subskill) {
if (!Algo::IsNormalOrSubskill(skill)) {
return 0.0;
}

Expand Down
Loading