/***************************************************************************\ [*] ___ ____ ____ __ __ ____ [*] ROGUE: ROM With Attitude [*] [*] /#/ ) /#/ ) /#/ ) /#/ /#/ /#/ [*] All rights reserved [*] [*] /#/ < /#/ / /#/ _ /#/ /#/ /#/-- [*] Copyright(C) 2000-2001 [*] [*] /#/ \(#(__/ (#(__/ (#(__/#/ (#(___ [*] Kenneth Conley (Mendanbar) [*] [*] Expression of Digital Creativity.. [*] roguemud@yahoogroups.com [*] [-]---------------------------------------+-+-----------------------------[-] [*] File: space.cpp [*] [*] Usage: Space and Vehicle Module [*] \***************************************************************************/ #include <math.h> #include <stdarg.h> #include <stdlib.h> #include "merc.h" #include "space.h" LList<ShipData *> ship_list; LList<StarSystem *> starsystem_list; LList<StellarObject *> stellar_objects; // Type defs enum State { Docked, Ready, Busy, Busy2, Busy3, Refueling, Launching, Launching2, Landing, Landing2, PreHyper, Hyperspace, Flying, Destroy }; // Local Funcs void SendSystem(ShipData *ship, ShipData *ignore, const char *fmt, ...); // StarSystem stuff StarSystem::StarSystem(void) { this->Init(); } StarSystem::~StarSystem(void) { if (this->name) free(this->name); if (this->filename) free(this->filename); } void StarSystem::Init(void) { memset(this, 0, sizeof(*this)); } void StarSystem::Update(void) { ShipData *ship; START_ITER(iter, ship, ShipData *, this->ships) ship->Update(); } // StellarObject stuff StellarObject::StellarObject(StellarObjectType objectType) { this->Init(); this->clan = -1; this->zone = -1; this->type = objectType; } StellarObject::~StellarObject(void) { if (this->name) free(this->name); if (this->filename) free(this->filename); } void StellarObject::Init(void) { memset(this, 0, sizeof(*this)); } void StellarObject::Update(void) { // this would make them move about? if they are mobile? } // ShipData stuff ShipData::ShipData(void) { this->Init(); IN_ROOM(this) = NULL; this->state = Docked; } ShipData::~ShipData(void) { if (this->name) free(this->name); if (this->home) free(this->home); if (this->owner) free(this->owner); if (this->pilot) free(this->pilot); if (this->copilot) free(this->copilot); if (this->filename) free(this->filename); if (this->destination) free(this->destination); for (int i = 0; i < MAX_SHIP_ROOMS; i++) { if (this->description[i]) { free(this->description[i]); this->description[i] = NULL; } } } void ShipData::Init(void) { memset(this, 0, sizeof(*this)); } double ShipData::Distance(ShipData *target) { float x = this->vx - target->vx, y = this->vy - target->vy, z = this->vz - target->vz; return sqrt(x*x + y*y + z*z); } double ShipData::Distance(StellarObject *target) { float x = this->vx - target->x, y = this->vy - target->y, z = this->vz - target->z; return sqrt(x*x + y*y + z*z); } void ShipData::Extract(void) { if (this->Purged()) return; if (IN_ROOM(this) != NULL) this->FromRoom(); if (this->starsystem) this->FromSystem(); // ship_list.Remove(this); // purged_ships.Add(this); this->Purge(); } SInt32 ShipData::Send(const char *fmt, ...) { SInt32 size; va_list args; ROOM_INDEX_DATA *room; char sendBuffer[MAX_STRING_LENGTH]; va_start(args, fmt); size = vsprintf(sendBuffer, fmt, args); va_end(args); START_ITER(iter, room, ROOM_INDEX_DATA *, this->rooms) room->Send("%s\n\r", sendBuffer); return size; } SInt32 ShipData::SendCockpit(const char *fmt, ...) { SInt32 size; va_list args; char sendBuffer[MAX_STRING_LENGTH]; va_start(args, fmt); size = vsprintf(sendBuffer, fmt, args); va_end(args); this->pilotseat->Send("%s\n\r", sendBuffer); if (this->pilotseat != this->gunseat) this->gunseat->Send("%s\n\r", sendBuffer); if (this->pilotseat != this->viewscreen && this->viewscreen != this->gunseat) this->viewscreen->Send("%s\n\r", sendBuffer); return size; } bool ShipData::IsCloaked(void) { return false; } bool ShipData::CanSee(ShipData *target) { if (!this || !target) return false; if (target->IsCloaked()) { return false; } return true; } void ShipData::Appear(void) { /* Flags oldBits = SHIP_FLAGS(this) & (SHIP_CLOAKED); REMOVE_BIT(SHP_FLAGS(this), SHIP_CLOAKED); if (oldBits & SHIP_CLOAKED) { this->SendCockpit("`YThe ship becomes visible.`n"); SendSystem(this, 0, "Space shimmers as %s slowly appears.", this->name); } */ } void ShipData::Move(void) { StellarObject *object; if (!this->starsystem) return; if (this->speed > 0) { float nx, ny, nz; float change = sqrt(this->hx * this->hx + this->hy * this->hy + this->hz * this->hz); if (change > 0) { nx = this->hx / change; ny = this->hy / change; nz = this->hz / change; this->vx += nx * (this->speed / 5); this->vy += ny * (this->speed / 5); this->vz += nz * (this->speed / 5); } } // Insert gravity code here! Autopilot auto-adjusts for gravity pull. if (!this->AutoPilot()) { START_ITER(o_iter, object, StellarObject *, this->starsystem->objects) { if (this->vx != object->x) this->vx -= URANGE(-3, object->gravity / (this->vx - object->x) / 2, 3); if (this->vy != object->y) this->vy -= URANGE(-3, object->gravity / (this->vy - object->y) / 2, 3); if (this->vz != object->z) this->vz -= URANGE(-3, object->gravity / (this->vz - object->z) / 2, 3); if (object->type == Star && this->Distance(object) < 10) { this->SendCockpit("`R`fYou float directly into the %s.`n", object->name); SendSystem(this, 0, "`y%s floats directly into %s!`n", this->name, object->name); this->Destroy(); return; } } } if (this->speed > 0) { StellarObject *planet; START_ITER(p_iter, planet, StellarObject *, this->starsystem->objects) { if (planet->type != Star) continue; if (this->Distance(planet) < 10) { this->SendCockpit("`YYou begin orbiting %s.`n", planet->name); SendSystem(this, 0, "`y%s begins orbiting %s.`n", this->name, planet->name); this->speed = 0; return; } } } } void ShipData::Update(void) { ShipData *ship; StellarObject *object; if (this->state == Hyperspace) { this->hyperDistance -= this->hyperSpeed; if (this->hyperDistance > 0) this->pilotseat->Send("Remaining jump distance: %d.\r\n", this->hyperDistance); else { this->ToSystem(this->jumpSystem); this->jumpSystem = NULL; if (this->starsystem == NULL) this->SendCockpit("Ship lost during jump. Make new calculations.\r\n"); else { this->pilotseat->Send("Hyperjump complete.\r\n"); this->Send("The ship lurches slightly as it comes out of hyperspace."); SendSystem(this, 0, "%s enters the starsystem at %.0f %.0f %.0f.", this->name, this->vx, this->vy, this->vz); this->state = Ready; free(this->home); this->home = str_dup(this->starsystem->name); } } } switch (this->state) { case Landing: this->Land(); break; case Launching: this->Launch(); break; case Busy: this->pilotseat->Send("Manuever complete.\r\n"); this->state = Ready; break; default: break; } if (this->starsystem != NULL) { double distance, tooClose = speed + 50; if (this->speed > 0) this->pilotseat->Send("`BSpeed: `C%d `BCoords: `C%.0f %.0f %.0f`n", this->speed, this->vx, this->vy, this->vz); START_ITER(s_iter, ship, ShipData *, this->starsystem->ships) { if (this == ship) continue; if ((distance = this->Distance(ship)) < (ship->speed + tooClose)) this->SendCockpit("`RProximity alert: %s %.0f %.0f %.0f (%.0f)`n", ship->name, distance, ship->vx, ship->vy, ship->vz); } tooClose = this->speed + 100; START_ITER(o_iter, object, StellarObject *, this->starsystem->objects) { if (object->type != Star) continue; if ((distance = this->Distance(object)) < tooClose) this->SendCockpit("`RProximity alert: %s %.0f %.0f %.0f (%.0f)`n", object->name, object->x, object->y, object->z, distance); } } } bool ShipData::ToRoom(UInt32 vnum) { return false; } void ShipData::FromRoom(void) { } void ShipData::ToSystem(StarSystem *system) { } void ShipData::FromSystem(void) { } void ShipData::Land(void) { } void ShipData::Launch(void) { } void ShipData::Destroy(void) { } bool ShipData::AutoPilot(void) { return false; } // Local Functions void SendSystem(ShipData *ship, ShipData *ignore, const char *fmt, ...) { va_list args; ShipData *target; char sendBuffer[MAX_STRING_LENGTH]; if (!ship->starsystem || !fmt || !*fmt) return; va_start(args, fmt); vsprintf(sendBuffer, fmt, args); va_end(args); START_ITER(iter, target, ShipData *, ship->starsystem->ships) { if (target != ship && target != ignore && target->CanSee(ship)) target->SendCockpit(sendBuffer); } return; } void MoveShips(void) { ShipData *ship; START_ITER(siter, ship, ShipData *, ship_list) ship->Move(); } void UpdateSpace(void) { ShipData *ship; StellarObject *object; START_ITER(iter1, ship, ShipData *, ship_list) ship->Update(); START_ITER(iter2, object, StellarObject *, stellar_objects) object->Update(); } // temp func void load_space(void) { return; ShipData *ship; StarSystem *system; StellarObject *object; ship = new ShipData(); ship_list.Append(ship); ship->name = str_dup("Mendanbar's F496 StarFighter 001"); system = new StarSystem(); starsystem_list.Append(system); system->name = str_dup("Terra Prime"); object = new StellarObject(); stellar_objects.Append(object); object->name = str_dup("Planet Nevermind"); }