BattleHazard::BattleHazard(GameState &state, StateRef<DamageType> damageType) : damageType(damageType), hazardType(damageType->hazardType) { frame = randBoundsExclusive(state.rng, 0, HAZARD_FRAME_COUNT); ticksUntilVisible = std::max((unsigned)0, (hazardType->doodadType->lifetime - 4) * TICKS_MULTIPLIER); ticksUntilNextEffect = TICKS_PER_HAZARD_EFFECT; ticksUntilNextFrameChange = randBoundsInclusive(state.rng, (unsigned)0, TICKS_PER_HAZARD_EFFECT); }
BattleHazard::BattleHazard(GameState &state, StateRef<DamageType> damageType, bool delayVisibility) : damageType(damageType), hazardType(damageType->hazardType) { frame = randBoundsExclusive(state.rng, 0, HAZARD_FRAME_COUNT); if (delayVisibility) { ticksUntilVisible = std::max((unsigned)0, (hazardType->doodadType->lifetime - 4) * TICKS_MULTIPLIER); } frameChangeTicksAccumulated = randBoundsInclusive(state.rng, (unsigned)0, TICKS_PER_HAZARD_UPDATE); }
void BattleItem::hopTo(GameState &state, Vec3<float> targetPosition) { if (falling) { return; } // It was observed that boomeroids hop 1 to 4 tiles away (never overshooting) int distance = std::min(16.0f, BattleUnitTileHelper::getDistanceStatic(position, targetPosition)) / 4.0f; distance = randBoundsInclusive(state.rng, 1, distance); auto targetVector = targetPosition - position; float velXY = 0.0f; float velZ = 0.0f; while (distance > 1) { // Try to hop this distance towards target velXY = 0.0f; velZ = 0.0f; Vec3<float> target = position + glm::normalize(targetVector) * (float)distance; if (item->getVelocityForThrow(tileObject->map, 100, position, target, velXY, velZ)) { break; } else { distance--; } } if (distance > 1) { falling = true; velocity = (glm::normalize(Vec3<float>{targetVector.x, targetVector.y, 0.0f}) * velXY + Vec3<float>{0.0f, 0.0f, velZ}) * VELOCITY_SCALE_BATTLE; // Enough to leave our home cell collisionIgnoredTicks = (int)ceilf(36.0f / glm::length(velocity / VELOCITY_SCALE_BATTLE)) + 1; } }
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}; }
int HazardType::getLifetime(GameState &state) { return randBoundsInclusive(state.rng, 2 * minLifetime, 2 * maxLifetime); }