StateRef<Agent> AgentGenerator::createAgent(GameState &state, StateRef<Organisation> org, StateRef<AgentType> type) const { UString ID = Agent::generateObjectID(state); auto agent = mksp<Agent>(); agent->owner = org; agent->type = type; agent->gender = probabilityMapRandomizer(state.rng, type->gender_chance); auto firstNameList = this->first_names.find(agent->gender); if (firstNameList == this->first_names.end()) { LogError("No first name list for gender"); return nullptr; } auto firstName = listRandomiser(state.rng, firstNameList->second); auto secondName = listRandomiser(state.rng, this->second_names); agent->name = format("%s %s", firstName, secondName); agent->appearance = randBoundsExclusive(state.rng, 0, type->appearance_count); agent->portrait = randBoundsInclusive(state.rng, 0, (int)type->portraits[agent->gender].size() - 1); AgentStats s; s.health = randBoundsInclusive(state.rng, type->min_stats.health, type->max_stats.health); s.accuracy = randBoundsInclusive(state.rng, type->min_stats.accuracy, type->max_stats.accuracy); s.reactions = randBoundsInclusive(state.rng, type->min_stats.reactions, type->max_stats.reactions); s.speed = randBoundsInclusive(state.rng, type->min_stats.speed, type->max_stats.speed); s.stamina = randBoundsInclusive(state.rng, type->min_stats.stamina, type->max_stats.stamina); s.bravery = randBoundsInclusive(state.rng, type->min_stats.bravery / 10, type->max_stats.bravery / 10) * 10; s.strength = randBoundsInclusive(state.rng, type->min_stats.strength, type->max_stats.strength); s.morale = 100; s.psi_energy = randBoundsInclusive(state.rng, type->min_stats.psi_energy, type->max_stats.psi_energy); s.psi_attack = randBoundsInclusive(state.rng, type->min_stats.psi_attack, type->max_stats.psi_attack); s.psi_defence = randBoundsInclusive(state.rng, type->min_stats.psi_defence, type->max_stats.psi_defence); s.physics_skill = randBoundsInclusive(state.rng, type->min_stats.physics_skill, type->max_stats.physics_skill); s.biochem_skill = randBoundsInclusive(state.rng, type->min_stats.biochem_skill, type->max_stats.biochem_skill); s.engineering_skill = randBoundsInclusive(state.rng, type->min_stats.engineering_skill, type->max_stats.engineering_skill); agent->initial_stats = s; agent->current_stats = s; agent->modified_stats = s; // Everything worked, add agent to state (before we add his equipment) state.agents[ID] = agent; // Fill initial equipment list std::list<sp<AEquipmentType>> initialEquipment; if (type->inventory) { // Player gets no default equipment if (org == state.getPlayer()) { } // Aliens get equipment based on player score else if (org == state.getAliens()) { // FIXME: actually get player score here int playerScore = 50000; initialEquipment = EquipmentSet::getByScore(state, playerScore)->generateEquipmentList(state); } // Every human org but civilians and player gets equipment based on tech level else if (org != state.getCivilian()) { initialEquipment = EquipmentSet::getByLevel(state, org->tech_level)->generateEquipmentList(state); } } else { initialEquipment.push_back(type->built_in_weapon_right); initialEquipment.push_back(type->built_in_weapon_left); } // Add initial equipment for (auto t : initialEquipment) { if (!t) continue; if (t->type == AEquipmentType::Type::Ammo) { agent->addEquipmentByType(state, {&state, t->id}, AEquipmentSlotType::General); } else { agent->addEquipmentByType(state, {&state, t->id}); } } agent->updateSpeed(); agent->modified_stats.restoreTU(); return {&state, ID}; }