Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/base/platform.cc')
-rw-r--r--src/game/base/platform.cc189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/game/base/platform.cc b/src/game/base/platform.cc
new file mode 100644
index 0000000..15c7576
--- /dev/null
+++ b/src/game/base/platform.cc
@@ -0,0 +1,189 @@
+/*
+ base/platform.cc
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#include "core/gameserver.h"
+#include "core/entityprojectile.h"
+
+#include "base/game.h"
+#include "base/faction.h"
+#include "base/platform.h"
+#include "base/weapon.h"
+#include "sys/sys.h"
+
+namespace game
+{
+
+Platform::Platform() : Entity()
+{
+ entity_moduletypeid = platform_enttype;
+
+ platform_cannon = 0;
+ platform_turret = 0;
+}
+
+Platform::~Platform()
+{
+
+}
+
+void Platform::set_cannon(const Weapon *cannon)
+{
+ platform_cannon = cannon;
+}
+
+void Platform::set_turret(const Weapon *turret)
+{
+ platform_turret = turret;
+}
+
+void Platform::frame(const unsigned long elapsed)
+{
+ const float weapon_range = math::max((cannon() ? cannon()->projectile_range() : 0.0f), (turret() ? turret()->projectile_range() : 0.0f));
+
+ if ((weapon_range > 0.0f) && slots() && zone()->keepalive_run()) {
+
+ // create list of potential enemies
+ std::list<Ship *> enemylist;
+
+ for (core::Zone::Content::iterator zit = zone()->content().begin(); zit != zone()->content().end(); ++zit) {
+ if ((*zit)->moduletype() == ship_enttype) {
+ Ship *ship = static_cast<Ship *>((*zit));
+
+ if ((ship->state() != Normal) && (ship->state() != ImpulseInitiate) && (ship->state() != Impulse)) {
+ continue;
+ }
+
+ const float d = math::distance(location(), ship->location());
+ const float r = radius() + ship->radius();
+
+ // too far
+ if (d > weapon_range + r) {
+ continue;
+ }
+
+ float reputation = 0.0f;
+ if (ship->owner()) {
+ // check owner reputation for the faction the NPC belongs to
+ reputation = ship->owner()->reputation(faction());
+
+ } else if (faction() && (faction()->type() == Faction::infotype())) {
+ //check my faction reputation for the other ships's faction
+ reputation = static_cast<const Faction *>(faction())->reputation(ship->faction());
+ }
+
+ // reputation threshold to get attacked
+ if (reputation > core::range::reputation_hostile) {
+ continue;
+ }
+ enemylist.push_back(ship);
+
+ }
+ }
+
+ // platforms do not need weapons in inventory to fire
+ if (enemylist.size()) {
+
+ const float modelscale = radius() / (model() ? model()->radius() : 1.0f);
+
+ for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) {
+ core::Slot *slot = (*it);
+
+ // found out if this slot is a cannon or a turret
+ const Weapon *weapon = 0;
+ if (slot->type() == model::Weapon::Cannon) {
+ weapon = cannon();
+
+ } else if (slot->type() == model::Weapon::Turret) {
+ weapon = turret();
+ }
+
+ if ((!weapon) || (weapon->projectile_interval() == 0)) {
+ continue;
+ }
+
+ if ((slot->last_fired() + weapon->projectile_interval() > core::server()->timestamp())) {
+ continue;
+ }
+
+ // location of the slot in world coordinates
+ const math::Vector3f slot_location(location() + (axis() * slot->location() * modelscale));
+
+ // find a target for this slot
+ Ship *current_enemy = 0;
+ float current_distance = 0.0f;
+
+ const float projectile_radius = core::PROJECTILE_RADIUS;
+ math::Axis projectile_axis(axis() * slot->axis());
+ const math::Vector3f projectile_location(slot_location + projectile_axis.forward() * projectile_radius);
+
+ math::Vector3f projectile_direction;
+ math::Vector3f aim_location;
+
+ // we only need half the cone angle for the cosine calculation
+ const float conecos = cosf(slot->cone() * 0.5f);
+
+ for (std::list<Ship *>::const_iterator enemy_it = enemylist.begin(); enemy_it != enemylist.end(); enemy_it++) {
+
+ const float d = math::distance((*enemy_it)->location(), projectile_location);
+
+ if (d > weapon->projectile_range() + (*enemy_it)->radius()) {
+ continue;
+ }
+ if ((current_distance > 0) && (d > current_distance)) {
+ continue;
+ }
+
+ aim_location.assign((*enemy_it)->location() + (*enemy_it)->axis().forward() * ( (*enemy_it)->radius() * 0.25f));
+ projectile_direction.assign(aim_location - projectile_location);
+ projectile_direction.normalize();
+
+ const float cosa = math::dotproduct(projectile_direction, projectile_axis.forward());
+
+ // check if the ship is in the slot's cone if fire
+ if (cosa >= conecos) {
+ current_distance = d;
+ current_enemy = (*enemy_it);
+ }
+ }
+
+ if (current_enemy) {
+ aim_location.assign(current_enemy->location() + current_enemy->axis().forward() * (current_enemy->radius() * 0.25f));
+ projectile_direction.assign(aim_location - projectile_location);
+ projectile_direction.normalize();
+
+ const float cosa = math::dotproduct(projectile_direction, projectile_axis.forward());
+
+ // point the projectile into the fire direction
+ math::Vector3f normal(math::crossproduct(projectile_direction, projectile_axis.forward()));
+ if (normal.length() > MIN_DELTA) {
+ float sina = sqrt(1.0f - cosa * cosa);
+
+ normal.normalize();
+ projectile_axis.rotate(normal, cosa, sina);
+ }
+
+ // spawn a new projectile
+ core::EntityProjectile *projectile = new core::EntityProjectile(this);
+
+ projectile->set_damage(weapon->damage());
+ projectile->set_lifespan(weapon->projectile_lifespan());
+ projectile->set_projectile_modelname(weapon->projectile_modelname());
+ projectile->set_projectile_soundname(weapon->projectile_soundname());
+
+ projectile->set_axis(projectile_axis);
+ projectile->set_location(projectile_location);
+ projectile->set_speed(weapon->projectile_speed());
+
+ projectile->reset();
+ slot->set_last_fired(core::server()->timestamp());
+ }
+ }
+
+ }
+ }
+}
+
+}