void Officer::SetWaypoint( Vector3 const &_wayPoint ) { m_wayPoint = _wayPoint; m_state = StateToWaypoint; // // If we clicked near a teleport, tell the officer to go into it m_wayPointTeleportId = -1; LList<int> *nearbyBuildings = g_app->m_location->m_obstructionGrid->GetBuildings( _wayPoint.x, _wayPoint.z ); for( int i = 0; i < nearbyBuildings->Size(); ++i ) { int buildingId = nearbyBuildings->GetData(i); Building *building = g_app->m_location->GetBuilding( buildingId ); if( building->m_type == Building::TypeRadarDish || building->m_type == Building::TypeBridge ) { float distance = ( building->m_pos - _wayPoint ).Mag(); Teleport *teleport = (Teleport *) building; if( distance < 5.0f && teleport->Connected() ) { m_wayPointTeleportId = building->m_id.GetUniqueId(); Vector3 entrancePos, entranceFront; teleport->GetEntrance( entrancePos, entranceFront ); m_wayPoint = entrancePos; break; } } } }
void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link /*= LINK_OWNER*/) { SpectatorVec list; g_game.map.getSpectators(list, getPosition(), true, true); for (Creature* spectator : list) { spectator->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR); } //add a reference to this item, it may be deleted after being added (mailbox for example) Creature* creature = thing->getCreature(); Item* item; if (creature) { creature->incrementReferenceCounter(); item = nullptr; } else { item = thing->getItem(); if (item) { item->incrementReferenceCounter(); } } if (link == LINK_OWNER) { if (hasFlag(TILESTATE_TELEPORT)) { Teleport* teleport = getTeleportItem(); if (teleport) { teleport->addThing(thing); } } else if (hasFlag(TILESTATE_TRASHHOLDER)) { TrashHolder* trashholder = getTrashHolder(); if (trashholder) { trashholder->addThing(thing); } } else if (hasFlag(TILESTATE_MAILBOX)) { Mailbox* mailbox = getMailbox(); if (mailbox) { mailbox->addThing(thing); } } //calling movement scripts Creature* creature = thing->getCreature(); if (creature) { g_moveEvents->onCreatureMove(creature, this, oldParent ? oldParent->getPosition() : getPosition(), MOVE_EVENT_STEP_IN); } else if (item) { g_moveEvents->onItemMove(item, this, true); } } //release the reference to this item onces we are finished if (creature) { g_game.ReleaseCreature(creature); } else if (item) { g_game.ReleaseItem(item); } }
void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link /*= LINK_OWNER*/) { const Position& cylinderMapPos = getPosition(); SpectatorVec list; g_game.getSpectators(list, cylinderMapPos, true, true); for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) { (*it)->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR); } //add a reference to this item, it may be deleted after being added (mailbox for example) thing->useThing2(); if (link == LINK_OWNER) { //calling movement scripts Creature* creature = thing->getCreature(); if (creature) { g_moveEvents->onCreatureMove(creature, this, true); } else { Item* item = thing->getItem(); if (item) { g_moveEvents->onItemMove(item, this, true); } } if (hasFlag(TILESTATE_TELEPORT)) { Teleport* teleport = getTeleportItem(); if (teleport) { teleport->__addThing(thing); } } else if (hasFlag(TILESTATE_TRASHHOLDER)) { TrashHolder* trashholder = getTrashHolder(); if (trashholder) { trashholder->__addThing(thing); } } else if (hasFlag(TILESTATE_MAILBOX)) { Mailbox* mailbox = getMailbox(); if (mailbox) { mailbox->__addThing(thing); } } } //release the reference to this item onces we are finished g_game.FreeThing(thing); }
void Tile::postAddNotification(Thing* thing, bool hasOwnership /*= true*/) { const Position& cylinderMapPos = getPosition(); SpectatorVec list; SpectatorVec::iterator it; g_game.getSpectators(Range(cylinderMapPos, true), list); for(it = list.begin(); it != list.end(); ++it){ if(Player* player = (*it)->getPlayer()){ player->postAddNotification(thing, false); } } //do action(s) if(Creature* creature = thing->getCreature()){ MagicEffectItem* fieldItem = getFieldItem(); if(fieldItem){ //remove magic walls/wild growth if(fieldItem->isBlocking()){ g_game.internalRemoveItem(fieldItem, 1); } const MagicEffectTargetCreatureCondition* magicTargetCondition = fieldItem->getCondition(); if(!(g_game.getWorldType() == WORLD_TYPE_NO_PVP && creature && magicTargetCondition && magicTargetCondition->getOwnerID() != 0)){ fieldItem->getDamage(creature); } if(magicTargetCondition && ((magicTargetCondition->attackType == ATTACK_FIRE) || (magicTargetCondition->attackType == ATTACK_POISON) || (magicTargetCondition->attackType == ATTACK_ENERGY))){ Creature* attacker = g_game.getCreatureByID(magicTargetCondition->getOwnerID()); g_game.creatureMakeMagic(attacker, creature->getPosition(), magicTargetCondition); } } } Teleport* teleport = getTeleportItem(); if(teleport){ teleport->__addThing(thing); } }
void IOMapBin::loadOTM(Map* map) { int op; bool end = false; while(!feof(fh) || !end) { op = fgetc(fh); switch(op) { case 0x10: // Information of the map { char name[100], author[100]; int pos; int len; // Map Name len = fgetc(fh); for (pos = 0; pos < len; pos++) name[pos] = fgetc(fh); name[pos] = '\0'; std::cout << ":: Map Name: " << name << std::endl; // Map Author len = fgetc(fh); for (pos = 0; pos < len; pos++) author[pos] = fgetc(fh); author[pos] = '\0'; std::cout << ":: Map Author: " << author << std::endl; } break; case 0x20: // Map dimensions { int width, height; width = fgetc(fh); width += fgetc(fh)<<8; height = fgetc(fh); height += fgetc(fh)<<8; map->mapwidth = width; map->mapheight = height; std::cout << ":: Map dimensions: " << width << "x" << height << std::endl; } break; case 0x30: // Global Temple Position { PositionEx templePos; templePos.x = fgetc(fh); templePos.x += fgetc(fh); // X templePos.y = fgetc(fh); templePos.y += fgetc(fh); // Y templePos.z = fgetc(fh); // Z int radius = fgetc(fh); // Radius // TODO: use the temple point and radius std::cout << ":: Global Temple Position: " << templePos.x << " " << templePos.y << " " << templePos.z << " Radius: " << radius << std::endl; } break; case 0x40: // Tiles and items { Tile *t; int x, y, z, id, total = 0; while(true) { // tile pos x = fgetc(fh); x += fgetc(fh) << 8; y = fgetc(fh); y += fgetc(fh) << 8; z = fgetc(fh); // end the loop if (x == 0xFFFF && y == 0xFFFF && z == 0xFF) break; id = fgetc(fh) + 100; id += fgetc(fh) << 8; total += 1; map->setTile(x, y, z, id); t = map->getTile(x, y, z); // check if the tile is pz if (fgetc(fh) == 1) t->setPz(); int op2; int tmpid; do { op2 = fgetc(fh); switch (op2) { case 0x10: // Action Id fgetc(fh); // len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; // t->ground->setActionId(tmpid); break; case 0x20: // Unique Id fgetc(fh); // len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; //t ->ground->setUniqueId(tmpid); break; case 0x30: // Target Id fgetc(fh); // len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; // TODO: implement target ids break; case 0xA0: // Item { int itemcount = fgetc(fh); for (int count = 0; count < itemcount; count++) { int itemid = fgetc(fh) + 100; itemid += fgetc(fh) << 8; Item *item = Item::CreateItem(itemid); int op3; do { op3 = fgetc(fh); switch (op3) { case 0x10: // Count fgetc(fh); //len item->setItemCountOrSubtype((unsigned char)fgetc(fh)); break; case 0x20: // Action Id fgetc(fh); //len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; // item->setActionId(tmpid); break; case 0x30: // Unique Id fgetc(fh); //len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; // item->setUniqueId(tmpid); break; case 0x40: // Target Id fgetc(fh); //len tmpid = fgetc(fh); tmpid += fgetc(fh) << 8; // item->setTargetId(tmpid); break; case 0x70: //Teleport { Teleport *tele = dynamic_cast<Teleport*>(item); Position toPos; fgetc(fh); //len toPos.x = fgetc(fh); toPos.x += fgetc(fh)<<8; toPos.y = fgetc(fh); toPos.y += fgetc(fh)<<8; toPos.z = fgetc(fh); if (tele) tele->setDestPos(toPos); } break; case 0x80: // Fluids fgetc(fh); if (item->isFluidContainer()) item->setItemCountOrSubtype((unsigned char)fgetc(fh)); else fgetc(fh); break; case 0xFF: // End break; default: // Unknow/New operators { printf("WARNING: Unknown operator loading items: 0x%X!\n",op3); int len = fgetc(fh); for (int i = 0; i < len; i++) fgetc(fh); } break; } } while (op3 < 0xFF); //item->pos.x = x; //item->pos.y = y; //item->pos.z = z; if (item->isAlwaysOnTop()) t->topItems.push_back(item); else t->downItems.push_back(item); } } break; case 0xFF: // End break; default: // Unknow/New operators { printf("WARNING: Unknown operator loading tiles: 0x%X!\n",op2); int len = fgetc(fh); for (int i = 0;i < len; i++) fgetc(fh); } break; } } while (op2 < 0xFF); } std::cout << ":: Total of tiles loaded is " << total << std::endl; } break; case 0x50: // Spawns { SpawnManager::initialize(&g_game); Position pos; int cx, cy, radius, total=0; long int secs; std::string cname; int num = fgetc(fh); num+=fgetc(fh)<<8; for (int i = 0; i < num; i++) { int len = fgetc(fh); int count; cname = ""; for (int j = 0;j < len; j++) cname.push_back(fgetc(fh)); // get the creature name //std::cout << cname.c_str() << std::endl; pos.x = fgetc(fh); pos.x += fgetc(fh) << 8; pos.y = fgetc(fh); pos.y += fgetc(fh) << 8; pos.z = fgetc(fh); radius = fgetc(fh) + 1; count = fgetc(fh); // number of creatures in this respawn total += count; secs = fgetc(fh); secs += fgetc(fh) << 8; Spawn *spawn = new Spawn(&g_game, pos, radius); SpawnManager::instance()->addSpawn(spawn); for (int j = 0; j < count; j++) { cx = (rand() % (radius * 2)) - radius; cy = (rand() % (radius * 2)) - radius; spawn->addMonster(cname, NORTH, cx, cy, secs * 1000); } fgetc(fh); // 1 = check for players near, 0 = dont check } std::cout << ":: Loaded spawns: " << total << std::endl; SpawnManager::instance()->startup(); } break; case 0xF0: end = true; break; } } fclose(fh); return; }
void Officer::SetOrders( Vector3 const &_orders ) { static float lastOrderSet = 0.0f; if( !g_app->m_location->IsWalkable( m_pos, _orders ) ) { g_app->m_sepulveda->Say( "officer_notwalkable" ); } else { float distanceToOrders = ( _orders - m_pos ).Mag(); if( distanceToOrders > 20.0f ) { m_orderPosition = _orders; m_orders = OrderGoto; m_absorb = false; // // If there is a teleport nearby, // assume he wants us to go in it bool foundTeleport = false; m_ordersBuildingId = -1; LList<int> *nearbyBuildings = g_app->m_location->m_obstructionGrid->GetBuildings( m_orderPosition.x, m_orderPosition.z ); for( int i = 0; i < nearbyBuildings->Size(); ++i ) { int buildingId = nearbyBuildings->GetData(i); Building *building = g_app->m_location->GetBuilding( buildingId ); if( building->m_type == Building::TypeRadarDish || building->m_type == Building::TypeBridge ) { float distance = ( building->m_pos - _orders ).Mag(); if( distance < 5.0f ) { Teleport *teleport = (Teleport *) building; m_ordersBuildingId = building->m_id.GetUniqueId(); Vector3 entrancePos, entranceFront; teleport->GetEntrance( entrancePos, entranceFront ); m_orderPosition = entrancePos; foundTeleport = true; break; } } } if( !foundTeleport ) { m_orderPosition = PushFromObstructions( m_orderPosition ); } // // Create the line using particles immediately, // so the player can see what he's just done float timeNow = GetHighResTime(); if( timeNow > lastOrderSet + 1.0f ) { lastOrderSet = timeNow; OfficerOrders orders; orders.m_pos = m_pos; orders.m_wayPoint = m_orderPosition; while( true ) { if( orders.m_arrivedTimer < 0.0f ) { g_app->m_particleSystem->CreateParticle( orders.m_pos, g_zeroVector, Particle::TypeMuzzleFlash, 50.0f ); g_app->m_particleSystem->CreateParticle( orders.m_pos, g_zeroVector, Particle::TypeMuzzleFlash, 40.0f ); } if( orders.Advance() ) break; } CancelOrderSounds(); g_app->m_soundSystem->TriggerEntityEvent( this, "SetOrderGoto" ); } } else { float timeNow = GetHighResTime(); int researchLevel = g_app->m_globalWorld->m_research->CurrentLevel( GlobalResearch::TypeOfficer ); if( timeNow > lastOrderSet + 0.3f ) { lastOrderSet = timeNow; switch( researchLevel ) { case 0 : case 1 : case 2 : m_orders = OrderNone; break; case 3 : if ( m_orders == OrderNone ) m_orders = OrderFollow; else if ( m_orders == OrderFollow ) m_orders = OrderNone; else if ( m_orders == OrderGoto ) m_orders = OrderNone; break; case 4 : if ( m_orders == OrderNone ) m_orders = OrderFollow; else if ( m_orders == OrderFollow && !m_absorb ) { m_absorb = true; m_absorbTimer = 2.0f; } else if ( m_orders == OrderFollow && m_absorb ) { m_orders = OrderNone; m_absorb = false; } else if ( m_orders == OrderGoto ) m_orders = OrderNone; break; } CancelOrderSounds(); switch( m_orders ) { case OrderNone: g_app->m_soundSystem->TriggerEntityEvent( this, "SetOrderNone" ); break; case OrderGoto: g_app->m_soundSystem->TriggerEntityEvent( this, "SetOrderGoto" ); break; case OrderFollow: if( m_absorb ) g_app->m_soundSystem->TriggerEntityEvent( this, "SetOrderAbsorb" ); else g_app->m_soundSystem->TriggerEntityEvent( this, "SetOrderFollow" ); break; } m_buildingId = -1; } } } }
bool Officer::Advance( Unit *_unit ) { if( !m_onGround ) AdvanceInAir(_unit); bool amIDead = Entity::Advance(_unit); if( m_inWater != -1.0f ) AdvanceInWater(_unit); if( m_onGround && !m_dead ) m_pos.y = g_app->m_location->m_landscape.m_heightMap->GetValue( m_pos.x, m_pos.z ); // // Advance in whatever state we are in if( !amIDead && m_onGround && m_inWater == -1.0f ) { switch( m_state ) { case StateIdle : amIDead = AdvanceIdle(); break; case StateToWaypoint : amIDead = AdvanceToWaypoint(); break; case StateGivingOrders : amIDead = AdvanceGivingOrders(); break; } } if( m_dead ) { m_vel.y -= 20.0f; m_pos.y += m_vel.y * SERVER_ADVANCE_PERIOD; } // // If we are giving orders, render them if( m_orders == OrderGoto ) { if( syncfrand() < 0.05f ) { OfficerOrders *orders = new OfficerOrders(); orders->m_pos = m_pos + Vector3(0,2,0); orders->m_wayPoint = m_orderPosition; int index = g_app->m_location->m_effects.PutData( orders ); orders->m_id.Set( m_id.GetTeamId(), UNIT_EFFECTS, index, -1 ); orders->m_id.GenerateUniqueId(); } } // // If we are absorbing, look around for Darwinians if( m_absorb ) Absorb(); // // Attack anything nearby with our "shield" if( m_shield > 0 ) { WorldObjectId id = g_app->m_location->m_entityGrid->GetBestEnemy( m_pos.x, m_pos.z, 0.0f, OFFICER_ATTACKRANGE, m_id.GetTeamId() ); if( id.IsValid() ) { Entity *entity = g_app->m_location->GetEntity( id ); entity->ChangeHealth( -10 ); m_shield --; Vector3 themToUs = m_pos - entity->m_pos; g_app->m_location->SpawnSpirit( m_pos, themToUs, 0, WorldObjectId() ); } } // // Use teleports. Remember which teleport we entered, // As there may be people following us if( m_wayPointTeleportId != -1 ) { int teleportId = EnterTeleports(m_wayPointTeleportId); if( teleportId != -1 ) { m_ordersBuildingId = teleportId; Teleport *teleport = (Teleport *) g_app->m_location->GetBuilding( teleportId ); Vector3 exitPos, exitFront; bool exitFound = teleport->GetExit( exitPos, exitFront ); if( exitFound ) m_wayPoint = exitPos + exitFront * 30.0f; if( m_orders == OrderGoto ) m_orders = OrderNone; m_wayPointTeleportId = -1; } } return amIDead || m_demoted; }