#include "precompile.h" #include #include #include "collision.h" #include "creature.h" #include "obstacle.h" #include "roomobstacle.h" #include "room.h" #include "mt/Map.h" #include "mt/MapThing.h" bool Collision::CheckBullet(IBullet* bullet, Creature* c) { glm::vec3 bullet_real_pos = bullet->GetPos().ToGlmVec3() - bullet->GetDir() * bullet->GetHitRadius(); float bullet_hit_radius = bullet->GetHitRadius(); if (c->room->IsNewBieRoom()) { bullet_hit_radius += 3; } bool ret = a8::IntersectCylinderCylinder ( bullet_real_pos, bullet_hit_radius * 1.0, 10, c->GetPos().ToGlmVec3(), c->GetHitRadius(), 10 ); if (!ret) { bullet_real_pos = bullet->GetPos().ToGlmVec3() - bullet->GetDir() * (bullet->GetHitRadius() - 2); ret = a8::IntersectCylinderCylinder ( bullet_real_pos, bullet_hit_radius * 1.0, 10, c->GetPos().ToGlmVec3(), c->GetHitRadius(), 10 ); } return ret; } bool Collision::CheckBullet(IBullet* bullet, Entity* e) { glm::vec3 bullet_real_pos = bullet->GetPos().ToGlmVec3() - bullet->GetDir() * bullet->GetHitRadius(); if (e->IsEntityType(ET_Obstacle) && ((Obstacle*)e)->IsRoomObstacle()) { RoomObstacle* ob = (RoomObstacle*)e; float distance = std::fabs(bullet->GetPos().GetX() - e->GetPos().GetX()) + std::fabs(bullet->GetPos().GetZ() - e->GetPos().GetZ()); if (distance > 300) { return false; } if (ob->init_args) { auto wobj = ob->init_args->Get>(0); return a8::IntersectCylinderCylinder ( bullet_real_pos, bullet->GetHitRadius() * 1.0, 10, e->GetPos().ToGlmVec3(), std::max(wobj->size.x/2.0f, wobj->size.z/2.0f), 10 ); } else { return a8::IntersectCylinderCylinder ( bullet_real_pos, bullet->GetHitRadius() * 1.0, 10, e->GetPos().ToGlmVec3(), ob->meta->width(), 10 ); } } return false; } bool Collision::CheckCC(Creature* a, Creature* b) { return false; } bool Collision::CheckCC(Creature* a, float a_radius, Creature* b, float b_radius) { return a8::IntersectCylinderCylinder ( a->GetPos().ToGlmVec3(), a_radius, 10, b->GetPos().ToGlmVec3(), b_radius, 10 ); } bool Collision::CheckCB(Creature* c, Obstacle* b) { return false; } bool Collision::CheckCB(Creature* c, float c_radius, Obstacle* b, float b_radius) { return a8::IntersectCylinderCylinder ( c->GetPos().ToGlmVec3(), c_radius, 10, b->GetPos().ToGlmVec3(), b_radius, 10 ); } static float TwoDistance(float x1, float y1, float x2, float y2) { return pow(pow((x1 - x2), 2.0f) + pow((y1 - y2), 2.0f), 0.5); } static float rot(float x1, float y1, float x2, float y2) { float value = (y1 - y2) / (x1 - x2); return atan(value) * 180 / A8_PI; } static void GetNewRxRy(float x1, float y1, float x2, float y2, float dro, float& new_rx, float& new_ry) { float distance = TwoDistance(x1, y1, x2, y2); float new_rot = rot(x1, y1, x2, y2) - dro; new_rx = cos(new_rot / 180 * A8_PI) * distance; new_ry = sin(new_rot / 180 * A8_PI) * distance; } bool Collision::Check2dRotationRectangle(float rx, float ry, float r, float dx, float dy, float dw, float dh, float dro) { float new_rx = 0.0f; float new_ry = 0.0f; GetNewRxRy(rx, ry, dx, dy, dro, new_rx, new_ry); float tmp_dx = std::min(new_rx, dw * 0.5f); float tmp_dx1 = std::max(tmp_dx, -dw * 0.5f); float tmp_dy = std::min(new_ry, dh * 0.5f); float tmp_dy1 = std::max(tmp_dy, -dh * 0.5f); #ifdef DEBUG1 a8::XPrintf("new_rx:%f new_ry:%f dx1:%f dy1:%f dro:%f v1:%f v2:%f r:%f,%f d:%f,%f\n", { new_rx, new_ry, tmp_dx1, tmp_dy1, dro, (tmp_dx1 - new_rx) * (tmp_dx1 - new_rx) + (tmp_dy1 - new_ry) * (tmp_dy1 - new_ry) , r*r, rx,ry, dx,dy }); #endif return (tmp_dx1 - new_rx) * (tmp_dx1 - new_rx) + (tmp_dy1 - new_ry) * (tmp_dy1 - new_ry) <= r * r; }