diff --git a/Character.cpp b/Character.cpp index c94b1e5..c33971c 100644 --- a/Character.cpp +++ b/Character.cpp @@ -434,6 +434,17 @@ bool Character::CanAct() const { return true; } +bool Character::IsInvulnerable() const { + for (const StatusEffect& status : statuses) + if (GetStatusEffectInfo(status.type).invulnerable) + return true; + return false; +} + +bool Character::HasHyperArmor() const { + return body && body->combat.HasHyperArmor(); +} + bool Character::DodgesHits() const { for (const StatusEffect& status : statuses) if (GetStatusEffectInfo(status.type).dodgesHits) diff --git a/Character.h b/Character.h index b0e524f..f4b62f9 100644 --- a/Character.h +++ b/Character.h @@ -220,6 +220,8 @@ public: bool IsKnockedDown() const { return HasStatus(StatusEffect::Type::Knockdown); } bool CanAct() const; // not stunned or held by a status effect bool DodgesHits() const; // a status effect keeps ordinary hits off it + bool IsInvulnerable() const; // has iframes: a status effect keeps every hit off it + bool HasHyperArmor() const; // in a move that takes hits without flinching, being stunned or pushed about const std::vector& GetStatuses() const { return statuses; } // Recoils from a hit: whatever swing it was in is cut off and its flinch plays over everything, if it has one. diff --git a/Combat.cpp b/Combat.cpp index 670068f..5135e8e 100644 --- a/Combat.cpp +++ b/Combat.cpp @@ -96,6 +96,14 @@ bool CharacterCombat::IsAbilityPivoting() const { return move.pivots && (move.pivotEndFrame <= 0.0f || abilityTime < AbilityFrameTime(move, move.pivotEndFrame)); } +bool CharacterCombat::HasHyperArmor() const { + if (ability < 0) + return false; + const Ability& move = abilities[ability]; + return move.hyperArmor && abilityTime >= AbilityFrameTime(move, move.hyperArmorStartFrame) + && (move.hyperArmorEndFrame <= 0.0f || abilityTime < AbilityFrameTime(move, move.hyperArmorEndFrame)); +} + void CharacterCombat::StartAbility(CharacterBody& body, int index) { // It takes over the action layer, so a swing in its recovery is over and the combo starts again after current = -1; diff --git a/Combat.h b/Combat.h index 8bf4bb9..29ace2f 100644 --- a/Combat.h +++ b/Combat.h @@ -53,6 +53,10 @@ struct Ability { float moveSpeedMultiplier = 0.5f; // of walking speed while it's going bool pivots = false; // keeps turning to face where the player looks while it's going, so it can be aimed float pivotEndFrame = 0.0f; // stops pivoting here, 0 pivots all the way through + // Hyper armor: hits still hurt, but don't flinch, stun, knock back or knock down the user, so the move carries on + bool hyperArmor = false; + float hyperArmorStartFrame = 0.0f; + float hyperArmorEndFrame = 0.0f; // 0 keeps it to the end std::string sound; // played where it goes off, as it does. Empty plays nothing. float screenshake = 0.0f; // how hard the camera shakes as it goes off, when it's the player's @@ -142,6 +146,9 @@ public: // Whether the ability it's in turns it to face where it's aimed right now bool IsAbilityPivoting() const; + // Whether the ability it's in has hyper armor right now + bool HasHyperArmor() const; + // Whether abilities[index] can be used now, and how much of its cooldown is left, 1 just used to 0 ready bool IsAbilityReady(int index) const; float GetCooldownFraction(int index) const; diff --git a/Engine.cpp b/Engine.cpp index 23ea7b3..f4e8f1f 100644 --- a/Engine.cpp +++ b/Engine.cpp @@ -226,7 +226,7 @@ void Engine::Initiate() shoot.knockback = 1.5f; shoot.stun = 0.8f; shoot.sound = "assets/gunshot.mp3"; - shoot.screenshake = 0.45f; // a punch landing is 0.3, the combo finisher 0.6 + shoot.screenshake = 0.65f; // a punch landing is 0.3, the combo finisher 0.6 if (std::filesystem::exists("assets/rifleexecutionhit.glb")) // whoever it kills goes down like this, filmed by its Camera bone shoot.killAnimation = charactermanager->LoadAnimation("rifleexecutionhit", "assets/rifleexecutionhit.glb", "humanoid"); shoot.killSounds = { { 40.0f, "assets/dramaticwoosh.mp3" }, { 60.0f, "assets/glassbreak.mp3" } }; @@ -238,7 +238,7 @@ void Engine::Initiate() // 2: a switchblade out of nowhere into whoever's in front. It stays in them a while, bleeding them. Ability stab; stab.name = "Stab"; - stab.description = "Pull a switchblade and stab whoever is right in front of you. The knife stays in them, making them bleed. Stuns what it hits."; + stab.description = "Pull a switchblade and stab whoever is right in front of you. The knife stays in them, making them bleed. Stuns what it hits. Hyper armor: hits don't stop it."; stab.effect = Ability::Effect::Stab; stab.animation = charactermanager->LoadAnimation("riflestab", "assets/riflestab.glb", "humanoid"); // brings the Knife bone stab.lastFrame = 60.0f; // 1 s at 60 fps, played at its own speed @@ -246,6 +246,7 @@ void Engine::Initiate() stab.hitExitFrame = 50.0f; // landing it, it's over 10 frames early stab.cooldown = 3.0f; stab.moveSpeedMultiplier = 0.0f; + stab.hyperArmor = true; // trades hits rather than being knocked out of it stab.lungeDistance = 1.5f; // steps in over the first 15 frames stab.lungeStartFrame = 0.0f; stab.lungeEndFrame = 15.0f; @@ -481,7 +482,14 @@ void Engine::Initiate() // The camera shakes by shake when it was the player's. auto LandHit = [&](const Character* attacker, Character& target, float damage, const glm::vec3& shove, float shake, float stun) { + // Hyper armor takes the damage and nothing else + const bool armored = target.HasHyperArmor(); Hurt(target, damage); + if (armored && !target.IsDead()) { + if (attacker == controlled) + camera->AddScreenshake(shake); + return; + } target.Flinch(); // nothing if that was the hit that put them down target.Stun(stun); if (target.ragdoll) { @@ -968,7 +976,8 @@ void Engine::Initiate() float life = 0.0f; // real seconds left, 0 when it's free }; std::vector tracers; - const float tracerTime = 0.06f; + const float tracerTime = 0.16f; // real seconds, thinning out to nothing over it + const float tracerThickness = 0.07f; auto ShowTracer = [&](const glm::vec3& from, const glm::vec3& direction, float length) { Tracer* tracer = nullptr; @@ -979,12 +988,12 @@ void Engine::Initiate() tracer = &tracers.back(); tracer->mesh = CreateCubeMesh(); tracer->mesh->name = "tracer"; - tracer->mesh->colorOverride = glm::vec4(1.0f, 0.86f, 0.55f, 1.0f); + tracer->mesh->colorOverride = glm::vec4(1.0f, 0.82f, 0.45f, 1.0f); tracer->mesh->emissive = 1.0f; tracer->mesh->castshadow = false; } // A thin box from end to end, its length along its own z - tracer->mesh->t.ScaleTo({ 0.025f, 0.025f, length }); + tracer->mesh->t.ScaleTo({ tracerThickness, tracerThickness, length }); tracer->mesh->t.RotateToQuaternion(LookAt(direction)); tracer->mesh->t.TranslateTo(from + direction * (length * 0.5f)); if (tracer->life <= 0.0f) @@ -1004,10 +1013,66 @@ void Engine::Initiate() muzzleSparks->emitangle = glm::vec3(0.7f, 0.7f, 0.0f); // radians of spread muzzleSparks->facecamera = true; muzzleSparks->BindToRenderSystem(); - const int sparksPerShot = 14; + const int sparksPerShot = 32; + + // The flash itself: a few big bright blobs right on the muzzle for a frame or two + ParticleEmitter* muzzleFlash = new ParticleEmitter(); + muzzleFlash->name = "muzzle flash"; + muzzleFlash->surface = SurfaceTexture::Stretched(blanktex); + muzzleFlash->opaque = false; + muzzleFlash->color = glm::vec4(3.0f, 2.2f, 1.0f, 1.0f); + muzzleFlash->size = glm::vec3(0.32f); + muzzleFlash->speed = 2.5f; + muzzleFlash->lifespan = 0.05f; + muzzleFlash->emitangle = glm::vec3(0.5f, 0.5f, 0.0f); + muzzleFlash->facecamera = true; + muzzleFlash->BindToRenderSystem(); + const int flashesPerShot = 6; + + // Smoke hanging about the barrel afterwards, drifting up + ParticleEmitter* muzzleSmoke = new ParticleEmitter(); + muzzleSmoke->name = "muzzle smoke"; + muzzleSmoke->surface = SurfaceTexture::Stretched(blanktex); + muzzleSmoke->opaque = false; + muzzleSmoke->color = glm::vec4(0.55f, 0.55f, 0.55f, 0.35f); + muzzleSmoke->size = glm::vec3(0.22f); + muzzleSmoke->speed = 1.2f; + muzzleSmoke->lifespan = 0.7f; + muzzleSmoke->emitangle = glm::vec3(1.2f, 1.2f, 0.0f); + muzzleSmoke->gravity = glm::vec3(0.0f, 1.5f, 0.0f); + muzzleSmoke->facecamera = true; + muzzleSmoke->BindToRenderSystem(); + const int smokePerShot = 8; + + // Sparks off whoever it hits, back toward the shooter + ParticleEmitter* impactSparks = new ParticleEmitter(); + impactSparks->name = "impact sparks"; + impactSparks->surface = SurfaceTexture::Stretched(blanktex); + impactSparks->opaque = false; + impactSparks->color = glm::vec4(2.0f, 1.4f, 0.6f, 1.0f); + impactSparks->size = glm::vec3(0.05f); + impactSparks->speed = 6.0f; + impactSparks->lifespan = 0.2f; + impactSparks->emitangle = glm::vec3(1.6f, 1.6f, 0.0f); + impactSparks->gravity = glm::vec3(0.0f, -12.0f, 0.0f); + impactSparks->facecamera = true; + impactSparks->BindToRenderSystem(); + const int impactSparksPerHit = 24; + + // Lights up everything around the gun for a moment + PointLight* muzzleLight = rendersystem->lighting->AddPointLight(glm::vec3(0.0f), glm::vec3(1.0f, 0.7f, 0.35f), 0.0f, 8.0f); + muzzleLight->castShadow = false; // too quick to be worth six shadow renders a frame + const float muzzleLightIntensity = 160.0f; + const float muzzleLightTime = 0.08f; // real seconds + float muzzleLightLeft = 0.0f; auto UpdateTracers = [&](float dt) { muzzleSparks->Step(dt); + muzzleFlash->Step(dt); + muzzleSmoke->Step(dt); + impactSparks->Step(dt); + muzzleLightLeft = std::max(muzzleLightLeft - dt, 0.0f); + muzzleLight->intensity = muzzleLightIntensity * (muzzleLightLeft / muzzleLightTime); for (Tracer& tracer : tracers) { if (tracer.life <= 0.0f) continue; @@ -1015,7 +1080,11 @@ void Engine::Initiate() if (tracer.life <= 0.0f) { tracer.life = 0.0f; rendersystem->RemoveRenderable(tracer.mesh); + continue; } + const float thickness = tracerThickness * (tracer.life / tracerTime); + const glm::vec3 scale = tracer.mesh->t.GetScale(); + tracer.mesh->t.ScaleTo({ thickness, thickness, scale.z }); } }; @@ -1042,6 +1111,13 @@ void Engine::Initiate() shot.stun = ability.stun; shot.killAnimation = ability.killAnimation; shot.killAbility = &ability; + shot.onHit = [&, direction](Character& target) { + const glm::vec3 at = target.body->t.GetTranslation() + glm::vec3(0.0f, target.body->t.GetScale().y * 0.2f, 0.0f); + impactSparks->t.TranslateTo(at); + impactSparks->t.RotateToQuaternion(LookAt(-direction)); + for (int i = 0; i < impactSparksPerHit; i++) + impactSparks->Emit(); + }; hitboxsystem->Add(shot); ShowTracer(origin, direction, ability.range); @@ -1052,6 +1128,16 @@ void Engine::Initiate() muzzleSparks->t.RotateToQuaternion(LookAt(direction)); for (int i = 0; i < sparksPerShot; i++) muzzleSparks->Emit(); + muzzleFlash->t.TranslateTo(origin + direction * 0.15f); + muzzleFlash->t.RotateToQuaternion(LookAt(direction)); + for (int i = 0; i < flashesPerShot; i++) + muzzleFlash->Emit(); + muzzleSmoke->t.TranslateTo(origin); + muzzleSmoke->t.RotateToQuaternion(LookAt(direction)); + for (int i = 0; i < smokePerShot; i++) + muzzleSmoke->Emit(); + muzzleLight->position = origin + direction * 0.3f; + muzzleLightLeft = muzzleLightTime; // Its own channel every time, so quick shots overlap rather than cutting each other off if (!ability.sound.empty()) @@ -1179,7 +1265,7 @@ void Engine::Initiate() auto ApplyAbilityStatus = [&](Character& user, const Ability& ability) { const unsigned int use = user.body->combat.GetAbilityUse(); for (const AbilityHit& hit : abilityHits) - if (hit.user == &user && hit.use == use && !hit.target->IsDead()) + if (hit.user == &user && hit.use == use && !hit.target->IsDead() && !hit.target->IsInvulnerable()) hit.target->AddStatus(ability.status, ability.statusTime); }; @@ -1490,6 +1576,7 @@ void Engine::Initiate() // ------------------------------------------------------------------------ struct Execution { Character* victim = nullptr; + Character* killer = nullptr; // has iframes until it's over, so the cutscene can't be cut short Animation* animation = nullptr; float timeLeft = 0.0f; // real seconds float time = 0.0f; // real seconds since it started @@ -1526,6 +1613,9 @@ void Engine::Initiate() const float ticksPerSecond = animation->GetTicksPerSecond() > 0.0f ? animation->GetTicksPerSecond() : 25.0f; execution.timeLeft = animation->GetDuration() / ticksPerSecond; execution.filmed = (&victim == controlled || killer == controlled) && !IsFilming(); + execution.killer = const_cast(killer); + if (execution.killer && execution.killer != &victim) + execution.killer->AddStatus(StatusEffect::Type::Invulnerable); if (ability && execution.filmed) execution.sounds = ability->killSounds; executions.push_back(execution); @@ -1560,6 +1650,13 @@ void Engine::Initiate() // Over: up again somewhere else, or for those that heal on death, right where they are victim.RemoveStatus(StatusEffect::Type::Executed); + if (Character* killer = execution.killer) { + // Unless it's in another one of its own + const bool stillExecuting = std::any_of(executions.begin(), executions.end(), [&](const Execution& other) { + return &other != &execution && other.killer == killer; }); + if (!stillExecuting) + killer->RemoveStatus(StatusEffect::Type::Invulnerable); + } if (Animator* action = victim.body->actionAnimator; action && action->m_CurrentAnimation == execution.animation) { action->holdsAtEnd = false; action->StopAnimation(); @@ -1865,7 +1962,7 @@ void Engine::Initiate() StartExecution(target, attacker, hitbox.killAnimation, hitbox.killAbility); return; } - if (hitbox.knockdown > 0.0f) + if (hitbox.knockdown > 0.0f && !target.HasHyperArmor()) target.Knockdown(hitbox.knockdown); if (hitbox.onHit) hitbox.onHit(target); diff --git a/Hitbox.cpp b/Hitbox.cpp index c6fd7cd..ddd9808 100644 --- a/Hitbox.cpp +++ b/Hitbox.cpp @@ -36,7 +36,7 @@ void HitboxSystem::Resolve(const std::vector& characters, const HitH for (Character* target : characters) { if (target == hitbox.owner || target->IsDead() || target->ragdoll || !target->body) continue; - if (target->DodgesHits() && !hitbox.hitsKnockedDown) + if (target->IsInvulnerable() || (target->DodgesHits() && !hitbox.hitsKnockedDown)) continue; if (hitbox.swing != 0) { const std::vector& already = hitBySwing[hitbox.swing]; diff --git a/StatusEffect.h b/StatusEffect.h index 698f1d5..d64c61f 100644 --- a/StatusEffect.h +++ b/StatusEffect.h @@ -8,7 +8,8 @@ struct StatusEffect { enum class Type { HeavyGravity, // pulled down harder: slower, can't jump, and falls faster Knockdown, // on the floor: can't do anything, and only attacks that hit the knocked down can hit it - Executed // playing out how it was killed: can't do anything or be hit until it's over + Executed, // playing out how it was killed: can't do anything or be hit until it's over + Invulnerable // iframes: nothing at all can hit it, not even what hits the knocked down }; Type type = Type::HeavyGravity; @@ -23,13 +24,17 @@ struct StatusEffectInfo { bool preventsJumping = false; bool preventsActing = false; // can't move, turn, attack or anything else, like a stun bool dodgesHits = false; // only hitboxes that hit the knocked down can touch it + bool invulnerable = false; // no hitbox can touch it }; inline const StatusEffectInfo& GetStatusEffectInfo(StatusEffect::Type type) { static const StatusEffectInfo heavyGravity = { "HEAVY", 0.5f, 3.0f, true }; static const StatusEffectInfo knockdown = { "KNOCKED DOWN", 0.0f, 1.0f, true, true, true }; - static const StatusEffectInfo executed = { "", 0.0f, 1.0f, true, true, true }; + static const StatusEffectInfo executed = { "", 0.0f, 1.0f, true, true, true, true }; + static const StatusEffectInfo invulnerable = { "", 1.0f, 1.0f, false, false, false, true }; switch (type) { + case StatusEffect::Type::Invulnerable: + return invulnerable; case StatusEffect::Type::Executed: return executed; case StatusEffect::Type::Knockdown: diff --git a/emmd/x64/Debug/Character.obj b/emmd/x64/Debug/Character.obj index 4bba9cc..8c03b6a 100644 Binary files a/emmd/x64/Debug/Character.obj and b/emmd/x64/Debug/Character.obj differ diff --git a/emmd/x64/Debug/CharacterManager.obj b/emmd/x64/Debug/CharacterManager.obj index 630db76..e8467f5 100644 Binary files a/emmd/x64/Debug/CharacterManager.obj and b/emmd/x64/Debug/CharacterManager.obj differ diff --git a/emmd/x64/Debug/CharacterMind.obj b/emmd/x64/Debug/CharacterMind.obj index a85306f..a57d4c8 100644 Binary files a/emmd/x64/Debug/CharacterMind.obj and b/emmd/x64/Debug/CharacterMind.obj differ diff --git a/emmd/x64/Debug/CollisionMesh.obj b/emmd/x64/Debug/CollisionMesh.obj index 48126c2..027f74d 100644 Binary files a/emmd/x64/Debug/CollisionMesh.obj and b/emmd/x64/Debug/CollisionMesh.obj differ diff --git a/emmd/x64/Debug/Combat.obj b/emmd/x64/Debug/Combat.obj index 64d9f57..45384c5 100644 Binary files a/emmd/x64/Debug/Combat.obj and b/emmd/x64/Debug/Combat.obj differ diff --git a/emmd/x64/Debug/Console.obj b/emmd/x64/Debug/Console.obj index 3a06c8c..7fe9ee8 100644 Binary files a/emmd/x64/Debug/Console.obj and b/emmd/x64/Debug/Console.obj differ diff --git a/emmd/x64/Debug/Cubemap.obj b/emmd/x64/Debug/Cubemap.obj index e5379c7..27a5565 100644 Binary files a/emmd/x64/Debug/Cubemap.obj and b/emmd/x64/Debug/Cubemap.obj differ diff --git a/emmd/x64/Debug/EBO.obj b/emmd/x64/Debug/EBO.obj index 894a529..853187c 100644 Binary files a/emmd/x64/Debug/EBO.obj and b/emmd/x64/Debug/EBO.obj differ diff --git a/emmd/x64/Debug/Engine.obj b/emmd/x64/Debug/Engine.obj index 0730769..e525a68 100644 Binary files a/emmd/x64/Debug/Engine.obj and b/emmd/x64/Debug/Engine.obj differ diff --git a/emmd/x64/Debug/Hitbox.obj b/emmd/x64/Debug/Hitbox.obj index 89c9cc4..a1c12b2 100644 Binary files a/emmd/x64/Debug/Hitbox.obj and b/emmd/x64/Debug/Hitbox.obj differ diff --git a/emmd/x64/Debug/Hud.obj b/emmd/x64/Debug/Hud.obj index d646a1d..484f63a 100644 Binary files a/emmd/x64/Debug/Hud.obj and b/emmd/x64/Debug/Hud.obj differ diff --git a/emmd/x64/Debug/Mouse.obj b/emmd/x64/Debug/Mouse.obj index 54de62f..c758f60 100644 Binary files a/emmd/x64/Debug/Mouse.obj and b/emmd/x64/Debug/Mouse.obj differ diff --git a/emmd/x64/Debug/Physics.obj b/emmd/x64/Debug/Physics.obj index 3e8bab1..8d5f883 100644 Binary files a/emmd/x64/Debug/Physics.obj and b/emmd/x64/Debug/Physics.obj differ diff --git a/emmd/x64/Debug/Ragdoll.obj b/emmd/x64/Debug/Ragdoll.obj index 45d7d5c..14289e2 100644 Binary files a/emmd/x64/Debug/Ragdoll.obj and b/emmd/x64/Debug/Ragdoll.obj differ diff --git a/emmd/x64/Debug/RenderSystem.obj b/emmd/x64/Debug/RenderSystem.obj index 0a92d23..9c0a1c4 100644 Binary files a/emmd/x64/Debug/RenderSystem.obj and b/emmd/x64/Debug/RenderSystem.obj differ diff --git a/emmd/x64/Debug/ResourceManager.obj b/emmd/x64/Debug/ResourceManager.obj index bab000b..39da2f5 100644 Binary files a/emmd/x64/Debug/ResourceManager.obj and b/emmd/x64/Debug/ResourceManager.obj differ diff --git a/emmd/x64/Debug/Sound.obj b/emmd/x64/Debug/Sound.obj index b3224fc..adf8723 100644 Binary files a/emmd/x64/Debug/Sound.obj and b/emmd/x64/Debug/Sound.obj differ diff --git a/emmd/x64/Debug/SoundSystem.obj b/emmd/x64/Debug/SoundSystem.obj index fa6516d..adf6303 100644 Binary files a/emmd/x64/Debug/SoundSystem.obj and b/emmd/x64/Debug/SoundSystem.obj differ diff --git a/emmd/x64/Debug/StatBar.obj b/emmd/x64/Debug/StatBar.obj index ea68857..7686c70 100644 Binary files a/emmd/x64/Debug/StatBar.obj and b/emmd/x64/Debug/StatBar.obj differ diff --git a/emmd/x64/Debug/VAO.obj b/emmd/x64/Debug/VAO.obj index f497c74..9081bea 100644 Binary files a/emmd/x64/Debug/VAO.obj and b/emmd/x64/Debug/VAO.obj differ diff --git a/emmd/x64/Debug/VBO.obj b/emmd/x64/Debug/VBO.obj index 871c01a..a683069 100644 Binary files a/emmd/x64/Debug/VBO.obj and b/emmd/x64/Debug/VBO.obj differ diff --git a/emmd/x64/Debug/emmd.ilk b/emmd/x64/Debug/emmd.ilk index 5930b0f..c336205 100644 Binary files a/emmd/x64/Debug/emmd.ilk and b/emmd/x64/Debug/emmd.ilk differ diff --git a/emmd/x64/Debug/emmd.tlog/link.read.1.tlog b/emmd/x64/Debug/emmd.tlog/link.read.1.tlog index 7603e86..ba82a3b 100644 Binary files a/emmd/x64/Debug/emmd.tlog/link.read.1.tlog and b/emmd/x64/Debug/emmd.tlog/link.read.1.tlog differ diff --git a/emmd/x64/Debug/glad.obj b/emmd/x64/Debug/glad.obj index 441b904..2181da5 100644 Binary files a/emmd/x64/Debug/glad.obj and b/emmd/x64/Debug/glad.obj differ diff --git a/emmd/x64/Debug/main.obj b/emmd/x64/Debug/main.obj index ffcc484..fd558a3 100644 Binary files a/emmd/x64/Debug/main.obj and b/emmd/x64/Debug/main.obj differ diff --git a/emmd/x64/Debug/shaderClass.obj b/emmd/x64/Debug/shaderClass.obj index a12f9a7..de24692 100644 Binary files a/emmd/x64/Debug/shaderClass.obj and b/emmd/x64/Debug/shaderClass.obj differ diff --git a/emmd/x64/Debug/tFunctions.obj b/emmd/x64/Debug/tFunctions.obj index 4dcad84..1d372de 100644 Binary files a/emmd/x64/Debug/tFunctions.obj and b/emmd/x64/Debug/tFunctions.obj differ diff --git a/emmd/x64/Debug/texture.obj b/emmd/x64/Debug/texture.obj index a5955d2..1316e1e 100644 Binary files a/emmd/x64/Debug/texture.obj and b/emmd/x64/Debug/texture.obj differ diff --git a/emmd/x64/Debug/vc143.idb b/emmd/x64/Debug/vc143.idb index ad31119..30b7b09 100644 Binary files a/emmd/x64/Debug/vc143.idb and b/emmd/x64/Debug/vc143.idb differ diff --git a/emmd/x64/Debug/vc143.pdb b/emmd/x64/Debug/vc143.pdb index 7cd9775..e4aa1fc 100644 Binary files a/emmd/x64/Debug/vc143.pdb and b/emmd/x64/Debug/vc143.pdb differ