#include "antifaShip.h" #include "game.h" #include "settings.h" #include "bullets.h" #include "assets.h" void initAntifaShip(Entity * entity, Game * game) { entity->model = &game->assets.models[ANTIFA_SHIP_ASSET]; entity->collisionModel = entityCreateCollisionModel(*entity->model); entity->transformedCollisionModel = entityCreateCollisionModel(*entity->model); setEntityRadius(entity); // Acceleration stuff. entity->useAcceleration = true; entity->acceleration = (EntityAcceleration){ .speedUp = 30.0, .speedDown = 15, .rotation = (Vector3){2000000.0, 2000000.0, 2000000.0} }; // Set Data pointer. entity->data = KF_MALLOC(sizeof(AntifaShip)); if (entity->data == NULL) { ALLOCATION_ERROR; return; } AntifaShip * data = (AntifaShip*)entity->data; data->lastMouse = GetMousePosition(); data->forwardSpeed = 0.0; data->shouldInitMousePosition = true; data->timeSinceLastBullet = GetTime(); data->doAutoTarget = false; data->targetedEntityId = ENTITY_NONE; data->isOnTarget = false; } // Go back to burger king you elon musking loving mother fucker! void closeAntifaShip(Entity * entity) { if (entity->data != NULL) KF_FREE(entity->data); entityFreeCollisionModel(entity->collisionModel); entityFreeCollisionModel(entity->transformedCollisionModel); } float getAntifaShipAimDistance(Entity * ship, Entity * targetEntity) { Vector3 directionAiming = Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, ship->rotation); Vector3 directionToTarget = Vector3Normalize(Vector3Subtract(targetEntity->position, ship->position)); return Vector3Distance(directionAiming, directionToTarget); } // Returns closest entity to ship and in range or none. EntityId getShipInRangeAntifaShip(Game * game, Entity * entity) { int i; // Needs at least two entities to work correctly. if (game->world.entitiesCount < 2) return ENTITY_NONE; // Start out with entity 1 as closest. Entity * currentEntity = &game->world.entities[1]; EntityId closestId = ENTITY_NONE; float closestDistance = (float)INT_MAX; float distance; // This entity will only ever be at id 0 so skip it. for (i = 1; i < game->world.entitiesCount; ++i) { // Get entity and distance. currentEntity = &game->world.entities[i]; distance = Vector3Distance(currentEntity->position, entity->position); // Is closest and in range. if (distance < closestDistance && getAntifaShipAimDistance(entity, currentEntity) <= ANTIFA_START_AUTO_TARGET_MAX) { closestDistance = distance; closestId = currentEntity->id; } } return closestId; } void updateAntifaShipTarget(Game * game, Entity * entity) { float t = GetFrameTime(); AntifaShip * data = (AntifaShip*)entity->data; if (data->doAutoTarget) { Entity * targetEntity = getEntityFromWorld(game->world, data->targetedEntityId); // Lost target. if (targetEntity == NULL) { data->doAutoTarget = false; return; } else if (targetEntity->fingerprint != data->targetedEntityFingerprint) { data->doAutoTarget = false; return; } // If to far from target. float aimDistance = getAntifaShipAimDistance(entity, targetEntity); if (aimDistance > ANTIFA_START_AUTO_TARGET_MAX) { data->doAutoTarget = false; return; } Vector3 directionToTarget = Vector3Normalize(Vector3Subtract(targetEntity->position, entity->position)); // Update target. float speed = ANTIFA_TARGETING_SPEED / aimDistance; data->gunTarget = Vector3Lerp(data->gunTarget, directionToTarget, speed * t); //printf("%f\n", speed); // Is on target. data->isOnTarget = traceRayToEntity(*targetEntity, (Ray){entity->position, data->gunTarget}).hit; } else { data->isOnTarget = false; data->gunTarget = Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, entity->rotation); } } void toggleAntifaShipAutoTarget(Game * game, Entity * entity) { AntifaShip * data = (AntifaShip*)entity->data; // Turn off auto target. if (data->doAutoTarget) { data->doAutoTarget = false; return; } EntityId closestId = getShipInRangeAntifaShip(game, entity); if (closestId == ENTITY_NONE) return; data->targetedEntityId = closestId; Entity * closestEntity = getEntityFromWorld(game->world, closestId); data->targetedEntityFingerprint = closestEntity->fingerprint; data->doAutoTarget = true; } // This fucker will fire a bullet!!! void fireBulletAntifa(Game * game, Entity * entity) { double t = GetTime(); AntifaShip * data = (AntifaShip*)entity->data; // Let it cool down. if (t - data->timeSinceLastBullet < ANTIFA_BULLET_COOLDOWN) return; Bullet bullet = createBulletFromDirection(*entity, data->gunTarget, ANTIFA_BULLET_DAMAGE); BulletHitInfo info = shootBullet(&game->world, bullet); data->lastBulletShot = bullet; if (info.hit) { Entity * hitEntity = getEntityFromWorld(game->world, info.hitId); // We were the fucker that killed this low iq fascist! if (hitEntity->health <= 0.0) hitEntity->killedByPlayer = true; } data->timeSinceLastBullet = t; } void controlAntifaShipJoystick(Game * game, Entity * entity) { Settings settings = game->settings; int gamePadNum = settings.gamePadNum; // Get joystick values. float pitchStick = GetGamepadAxisMovement(gamePadNum, settings.pitchStick); float yawStick = GetGamepadAxisMovement(gamePadNum, settings.yawStick); float rollStick = GetGamepadAxisMovement(gamePadNum, settings.rollStick); float speedStick = GetGamepadAxisMovement(gamePadNum, settings.speedStick); // Shoot button. if (IsGamepadButtonPressed(gamePadNum, 8)) fireBulletAntifa(game, entity); Vector3 stick = (Vector3){ pitchStick, -yawStick, rollStick }; stick = Vector3Scale(stick, settings.joystickSensitivity); float speed = fabs(speedStick * ANTIFA_SHIP_MAX_SPEED); entityJoystickControl(entity, stick, speed); } void controlAntifaShipKeyboardAndMouse(Game * game, Entity * entity) { AntifaShip * data = (AntifaShip*)entity->data; // Resets mouse on init. if (data->shouldInitMousePosition) { data->shouldInitMousePosition = false; SetMousePosition(0, 0); data->lastMouse = Vector2Zero(); } #ifdef DEBUG_KEYS // Kill me. if (IsKeyPressed(KEY_K)) entity->health = 0.0; // Kill everyone else. if (IsKeyPressed(KEY_L)) for (int i = 1; i < game->world.entitiesCount; ++i) game->world.entities[i].health = 0.0; #endif // Shoot bullet. if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) toggleAntifaShipAutoTarget(game, entity); if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) fireBulletAntifa(game, entity); // Get mouse values. Vector2 mouse = GetMousePosition(); float speed = GetMouseWheelMove(); // Speed mod. float speedMod = 1.0; if (IsKeyDown(KEY_LEFT_SHIFT)) speedMod = 1.0 / game->settings.speedMod; else if (IsKeyDown(KEY_LEFT_CONTROL)) speedMod = game->settings.speedMod; //printf("%f\n", speedMod); data->forwardSpeed += (speed * game->settings.scrollBarSpeed * speedMod); if (data->forwardSpeed < 0.) data->forwardSpeed = 0.0; else if (data->forwardSpeed > ANTIFA_SHIP_MAX_SPEED) data->forwardSpeed = ANTIFA_SHIP_MAX_SPEED; Vector2 v = Vector2Subtract(mouse, data->lastMouse); v = Vector2Scale(v, 1.0 / GetFrameTime()); data->lastMouse = mouse; // Using mouse as a joystick. Vector3 mouseStick = (Vector3){v.y, -v.x, 0.0}; mouseStick = Vector3Scale(mouseStick, game->settings.mouseSensitivity); mouseStick = Vector3Scale(mouseStick, speedMod); // Swap axis for more movement with mouse. if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)) { mouseStick.z = -mouseStick.y; mouseStick.y = 0.0; } entityJoystickControl(entity, mouseStick, data->forwardSpeed); } void updateAntifaShip(Game * game, Entity * entity) { entityUpdateLastValues(entity); updateAntifaShipTarget(game, entity); switch (game->settings.controlMode) { case JOYSTICK_CONTROL: controlAntifaShipJoystick(game, entity); break; case KEYBOARD_AND_MOUSE_CONTROL: controlAntifaShipKeyboardAndMouse(game, entity); break; default: break; } //printf("%f\n", entity->health); entityCheckTransformedCollisionModel(entity); } void drawAntifaShip(Game * game, Entity * entity) { entityDraw(entity); // Draw bullet. AntifaShip * data = (AntifaShip*)entity->data; // Auto target line. if (data->doAutoTarget) { Entity * targetedEntity = getEntityFromWorld(game->world, data->targetedEntityId); if (targetedEntity != NULL) DrawLine3D( entity->position, targetedEntity->position, data->isOnTarget ? RED : BLUE ); } // Draw bullet being shot. if (GetTime() - data->timeSinceLastBullet <= ANTIFA_DRAW_BULLET_FOR) DrawRay(data->lastBulletShot.ray, RED); }