DefenderWeapon and SidearmWeapon

This commit is contained in:
2016-03-01 22:37:19 +01:00
parent afd0e69a8a
commit 13546aa3fc
14 changed files with 340 additions and 65 deletions
+45 -7
View File
@@ -390,14 +390,52 @@ bool EditorGUI::drawComponentField_Vector(ComponentWrapper &c, const ComponentIn
// Limit scale values to a minimum of 0
return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits<float>::max());
} else if (field.Name == "Orientation") {
// Make orentations have a period of 2*Pi
glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi<float>()));
if (ImGui::SliderFloat3("", glm::value_ptr(tempVal), 0.f, glm::two_pi<float>())) {
val = tempVal;
return true;
} else {
return false;
//glm::vec3 tempVal = val;
glm::vec3 originalVal = val;
ImVec2 cursorPos = ImGui::GetCursorScreenPos();
glm::tvec3<bool> isSnapping(false, false, false);
bool changed = ImGui::DragFloat3("", glm::value_ptr(val), 0.066666f);
if (changed) {
// Make orentations have a period of 2*Pi
val = glm::fmod(val, glm::vec3(glm::two_pi<float>()));
for (int i = 0; i < 3; i++) {
if (val[i] < 0) {
val[i] += glm::two_pi<float>();
}
}
}
// Snap to angle
//float snapRange = glm::pi<float>() / 15.f;
//float snapAngle = glm::quarter_pi<float>();
//glm::vec3 snap = glm::fmod(val, glm::vec3(snapAngle));
//for (int i = 0; i < 3; i++) {
// isSnapping[i] = glm::abs(snap[i] - (snapRange / 2.f)) < snapRange;
//}
//if (changed && ImGui::IsMouseDown(0)) {
// glm::vec3 change = val - originalVal;
// for (int i = 0; i < 3; i++) {
// if (isSnapping[i] && glm::abs(change[i]) < snapRange) {
// val[i] -= snap[i] - snapRange;
// }
// }
//}
// Draw snapping outline
float width = ImGui::CalcItemWidth() / 3.f;;
float spacing = GImGui->Style.ItemInnerSpacing.x;
for (int i = 0; i < 3; i++) {
if (isSnapping[i]) {
ImVec2 pos = cursorPos + ImVec2(i * (width + spacing), 0.f);
ImRect bb(pos - ImVec2(1, 1), pos + ImVec2(width, 17));
auto window = ImGui::GetCurrentWindow();
const ImU32 col = window->Color(ImGuiCol_HeaderActive);
window->DrawList->AddRect(bb.Min, bb.Max, col, 3.f);
}
}
return changed;
} else {
return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
}
@@ -2,33 +2,73 @@
void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt)
{
(double&)cWeapon["TimeSinceLastFire"] += dt;
double& fireCooldown = cWeapon["FireCooldown"];
fireCooldown = glm::max(0.0, fireCooldown - dt);
WeaponBehaviour::UpdateComponent(entity, cWeapon, dt);
}
void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
{
bool isFiring = cWeapon["IsFiring"];
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
if (isFiring && cooldownPassed && isNotShielding) {
double& reloadTimer = cWeapon["ReloadTimer"];
reloadTimer = glm::max(0.0, reloadTimer - dt);
double reloadTime = cWeapon["ReloadTime"];
bool& isReloading = cWeapon["IsReloading"];
if (isReloading && reloadTimer <= 0.0) {
int& magAmmo = cWeapon["MagazineAmmo"];
int& magSize = cWeapon["MagazineSize"];
int& ammo = cWeapon["Ammo"];
if (magAmmo < magSize && ammo > 0) {
ammo -= 1;
magAmmo += 1;
reloadTimer = reloadTime;
} else {
isReloading = false;
}
}
if (canFire(cWeapon, wi)) {
fireShell(cWeapon, wi);
}
}
void DefenderWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["IsFiring"] = true;
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
if (cooldownPassed && isNotShielding) {
cWeapon["TriggerHeld"] = true;
if (canFire(cWeapon, wi)) {
fireShell(cWeapon, wi);
}
}
void DefenderWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["IsFiring"] = false;
cWeapon["TriggerHeld"] = false;
}
void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
{
bool& isReloading = cWeapon["IsReloading"];
if (isReloading) {
return;
}
int& magAmmo = cWeapon["MagazineAmmo"];
int& magSize = cWeapon["MagazineSize"];
if (magAmmo >= magSize) {
return;
}
int& ammo = cWeapon["Ammo"];
if (ammo <= 0) {
return;
}
double reloadTime = cWeapon["ReloadTime"];
double& reloadTimer = cWeapon["ReloadTimer"];
// Start reload
isReloading = true;
reloadTimer = reloadTime;
}
bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e)
@@ -47,15 +87,23 @@ bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInf
return false;
}
bool DefenderWeaponBehaviour::OnSetCamera(const Events::SetCamera& e)
{
m_CurrentCamera = e.CameraEntity;
return true;
}
void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["TimeSinceLastFire"] = 0.0;
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
// Stop reloading
bool& isReloading = cWeapon["IsReloading"];
isReloading = false;
// Ammo
int& magAmmo = cWeapon["MagazineAmmo"];
if (magAmmo <= 0) {
OnReload(cWeapon, wi);
return;
} else {
magAmmo -= 1;
}
int numPellets = cWeapon["NumPellets"];
float spreadAngle = cWeapon["SpreadAngle"];
std::uniform_real_distribution<float> randomSpreadAngle(-spreadAngle, spreadAngle);
@@ -92,7 +140,6 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi
dealDamage(cWeapon, wi, direction, pelletDamage);
}
}
}
void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage)
@@ -154,16 +201,13 @@ void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& w
LOG_DEBUG("Damage: %f", damage);
}
float DefenderWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction)
bool DefenderWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi)
{
float distance;
glm::vec3 pos;
auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos);
if (entity) {
return distance;
} else {
return 100.f;
}
bool triggerHeld = cWeapon["TriggerHeld"];
bool cooldownPassed = (double)cWeapon["FireCooldown"] <= 0.0;
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
// TODO: Ammo checks
return triggerHeld && cooldownPassed && isNotShielding;
}
Camera DefenderWeaponBehaviour::cameraFromEntity(EntityWrapper camera)
@@ -14,7 +14,7 @@ void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWra
void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
{
if (canFire(cWeapon)) {
if ((bool)cWeapon["Automatic"] && canFire(cWeapon)) {
fireBullet(cWeapon, wi);
}
}
@@ -32,6 +32,11 @@ void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, Weapon
cWeapon["TriggerHeld"] = false;
}
void SidearmWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"];
}
void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
{
// Make sure the trigger is released if weapon is holstered while firing
@@ -46,7 +51,23 @@ void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi)
{
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
// Get weapon model based on current person
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
if (!weaponModelEntity.Valid()) {
return;
}
// Tracer
EntityWrapper tracerSpawner = weaponModelEntity.FirstChildByName("WeaponMuzzle");
if (tracerSpawner.Valid()) {
glm::vec3 origin = Transform::AbsolutePosition(tracerSpawner);
glm::vec3 direction = Transform::AbsoluteOrientation(tracerSpawner) * glm::vec3(0, 0, -1);
float distance = traceRayDistance(origin, direction);
EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner);
((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f);
}
}
bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon)