示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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;
	}
}
示例#4
0
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};
}
示例#5
0
int HazardType::getLifetime(GameState &state)
{
	return randBoundsInclusive(state.rng, 2 * minLifetime, 2 * maxLifetime);
}