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;
                }
            }
        }
}
Exemplo n.º 2
0
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);
	}
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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);
	}
}
Exemplo n.º 5
0
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;
}