in rts/engine/rule_actor.cc [224:330]
bool RuleActor::act_per_unit(const GameEnv &env, const Unit *u, const int *state, RegionHist *region_hist, string *state_string, AssignedCmds *assigned_cmds) {
UnitType ut = u->GetUnitType();
const CmdDurative *curr_cmd = _receiver->GetUnitDurativeCmd(u->GetId());
bool idle = (curr_cmd == nullptr);
CmdType cmdtype = idle ? INVALID_CMD : curr_cmd->type();
if (ut == BASE && state[STATE_BUILD_WORKER] && idle) {
if (_preload.BuildIfAffordable(WORKER)) {
*state_string = "Build worker..Success";
store_cmd(u, _B(WORKER), assigned_cmds);
}
}
// Ask workers to gather.
if (ut == WORKER) {
// Gather!
if (idle) store_cmd(u, _preload.GetGatherCmd(), assigned_cmds);
// If resource permit, build barracks.
if (cmdtype == GATHER && state[STATE_BUILD_BARRACK] && ! region_hist->has_built_barracks) {
if (_preload.Affordable(BARRACKS)) {
*state_string = "Build barracks..Success";
CmdBPtr cmd = _preload.GetBuildBarracksCmd(env);
if (cmd != nullptr) {
store_cmd(u, std::move(cmd), assigned_cmds);
region_hist->has_built_barracks = true;
_preload.Build(BARRACKS);
}
}
}
}
if (ut == BARRACKS && idle) {
if (state[STATE_BUILD_MELEE_TROOP] && ! region_hist->has_built_melee) {
if (_preload.BuildIfAffordable(MELEE_ATTACKER)) {
*state_string = "Build Melee Troop..Success";
store_cmd(u, _B(MELEE_ATTACKER), assigned_cmds);
region_hist->has_built_melee = true;
}
}
if (state[STATE_BUILD_RANGE_TROOP] && ! region_hist->has_built_range) {
if (_preload.BuildIfAffordable(RANGE_ATTACKER)) {
*state_string = "Build Range Troop..Success";
store_cmd(u, _B(RANGE_ATTACKER), assigned_cmds);
region_hist->has_built_range = true;
}
}
}
if (state[STATE_ATTACK] && (ut == MELEE_ATTACKER || ut == RANGE_ATTACKER)) {
if (idle) store_cmd(u, _preload.GetAttackEnemyBaseCmd(), assigned_cmds);
}
if (state[STATE_HIT_AND_RUN]) {
// cout << "Enter hit and run procedure" << endl << flush;
auto enemy_troops = _preload.EnemyTroops();
*state_string = "Hit and run";
if (ut == RANGE_ATTACKER) {
// cout << "Enemy only have worker" << endl << flush;
if (enemy_troops[MELEE_ATTACKER].empty() && enemy_troops[RANGE_ATTACKER].empty() && ! enemy_troops[WORKER].empty()) {
hit_and_run(env, u, enemy_troops[WORKER], assigned_cmds);
}
if (! enemy_troops[MELEE_ATTACKER].empty()) {
hit_and_run(env, u, enemy_troops[MELEE_ATTACKER], assigned_cmds);
}
}
if (ut == RANGE_ATTACKER || ut == MELEE_ATTACKER) {
if (! enemy_troops[RANGE_ATTACKER].empty() && idle) {
store_cmd(u, _A(enemy_troops[RANGE_ATTACKER][0]->GetId()), assigned_cmds);
}
}
}
const auto& enemy_troops_in_range = _preload.EnemyTroopsInRange();
const auto& enemy_attacking_economy = _preload.EnemyAttackingEconomy();
if ((ut == RANGE_ATTACKER || ut == MELEE_ATTACKER)
&& idle && state[STATE_ATTACK_IN_RANGE] && ! enemy_troops_in_range.empty()) {
*state_string = "Attack enemy in range..Success";
auto cmd = _A(enemy_troops_in_range[0]->GetId());
store_cmd(u, std::move(cmd), assigned_cmds);
}
if (state[STATE_DEFEND]) {
// Group Retaliation. All troops attack.
*state_string = "Defend enemy attack..NOOP";
const Unit *enemy_at_resource = _preload.EnemyAtResource();
if (enemy_at_resource != nullptr) {
*state_string = "Defend enemy attack..Success";
store_cmd(u, _A(enemy_at_resource->GetId()), assigned_cmds);
}
const Unit *enemy_at_base = _preload.EnemyAtBase();
if (enemy_at_base != nullptr) {
*state_string = "Defend enemy attack..Success";
store_cmd(u, _A(enemy_at_base->GetId()), assigned_cmds);
}
if (! enemy_attacking_economy.empty()) {
*state_string = "Defend enemy attack..Success";
auto it = enemy_attacking_economy.begin();
store_cmd(u, _A((*it)->GetId()), assigned_cmds);
}
}
return true;
}