示例#1
0
//--------------------------------------------------------------------------
void C2DMap::BuildMapTables(void)
{
	mapalephs.RemoveAll();
	SMapAleph *pmapaleph;
	if (igcmap == NULL) return;
	POSITION pos = igcmap->cl_alephs.GetHeadPosition();
	for (int i=0;i < igcmap->cl_alephs.GetCount();i++)
	{
		CIGCAleph *paleph;
		paleph = &(igcmap->cl_alephs.GetNext(pos));
		if (!KnownAleph(paleph))
		{
			pmapaleph = new SMapAleph;
			pmapaleph->aleph1 = paleph;
			pmapaleph->sect1 = FindSector(paleph);
			pmapaleph->aleph2 = FindConnectingAleph(paleph);
			pmapaleph->sect2 = FindSector(pmapaleph->aleph2);
			mapalephs.AddTail(*pmapaleph);
		}
	}
	Rescale();
}
示例#2
0
EID EntityManager::CreateNPC(psCharacter *chardata, bool updateProxList, bool alwaysWatching)
{
    csVector3 pos;
    float yrot;
    psSectorInfo *sectorinfo;
    iSector *sector;
    InstanceID instance;

    chardata->GetLocationInWorld(instance, sectorinfo,pos.x,pos.y,pos.z,yrot);
    sector = FindSector(sectorinfo->name);

    if (sector == NULL)
    {
        Error3("Could not resolve sector >%s< for NPC %s.", sectorinfo->name.GetData(), ShowID(chardata->GetPID()));
        delete chardata;
        return false;
    }

    return CreateNPC(chardata, instance, pos, sector, yrot, updateProxList, alwaysWatching);
}
示例#3
0
bool EntityManager::CreateActionLocation(psActionLocation *al, bool transient = false)
{
    const csVector3 pos = al->GetPosition();
    iSector *sector = FindSector(al->GetSectorName());
    if (!sector)
    {
        CPrintf(CON_ERROR, "Action Location ID %u : Sector not found!\n", al->id);
        return false;
    }

    gemActionLocation *obj = new gemActionLocation(al, sector, 0);
    
    // Add action location to all nearby clients
    obj->UpdateProxList( true );

    // Add action location to all Super Clients
    psserver->npcmanager->AddEntity(obj);

    //Debug3(LOG_STARTUP ,0, "Action Location ID %u : Created successfully(EID: %u)!", instance->id,obj->GetEID());
    return true;
}
示例#4
0
gemItem* EntityManager::CreateItem(psItem *& iteminstance, bool transient)
{
    psSectorInfo *sectorinfo;
    csVector3 newpos;
    float xrot;
    float yrot;
    float zrot;
    iSector *isec;
    InstanceID instance;

    iteminstance->GetLocationInWorld(instance, &sectorinfo,newpos.x,newpos.y,newpos.z,yrot);
    iteminstance->GetXZRotationInWorld(xrot,zrot);
    if (sectorinfo==NULL)
        return NULL;
    isec = FindSector(sectorinfo->name);
    if (isec==NULL)
        return NULL;

    /* Apparently merchants like to arrange similar items on tables without
     * them auto-stacking and thus averaging qualities.  Similarly, people
     * like to arrange food on tables, etc.  Disabling at the request of Bovek.
    // Try to stack this first
    csArray<gemObject*> nearlist = gem->FindNearbyEntities( isec, newpos, RANGE_TO_STACK );
    size_t count = nearlist.GetSize();
    for (size_t i=0; i<count; i++)
    {
        gemObject *nearobj = nearlist[i];
        if (!nearobj)
            continue;

        psItem *nearitem = nearobj->GetItem();
        if ( nearitem && nearitem->CheckStackableWith(iteminstance, false) )
        {
            // Put new item(s) into old stack
            nearitem->CombineStack(iteminstance);
            nearitem->Save(false);
            return nearitem->GetGemObject(); // Done
        }
    }
    */

    // Cannot stack, so make a new one
    // Get the mesh for this object
    const char *meshname = iteminstance->GetMeshName();
    gemItem *obj;
    if (iteminstance->GetIsContainer())
    {
        obj = new gemContainer(iteminstance,meshname,instance,isec,newpos,xrot,yrot,zrot,0);
    }
    else
    {
        obj = new gemItem(iteminstance,meshname,instance,isec,newpos,xrot,yrot,zrot,0);
    }

    // Won't create item if gemItem entity was not created
    //CS_ASSERT(obj->GetEntity() != NULL);
    
    if (transient && !sectorinfo->GetIsNonTransient())
    {
        // don't create removal events for items in e.g guildhalls
        iteminstance->ScheduleRemoval();
    }
        
    obj->Move(newpos,yrot,isec);

    // Add object to all nearby clients
    obj->UpdateProxList( true );

    // Add object to all Super Clients
    psserver->npcmanager->AddEntity(obj);

    return obj;
}
示例#5
0
bool EntityManager::CreatePlayer (Client* client)
{
    psCharacter *chardata=psServer::CharacterLoader.LoadCharacterData(client->GetPID(),true);
    if (chardata==NULL)
    {
        CPrintf(CON_ERROR, "Couldn't load character for %s!\n", ShowID(client->GetPID()));
        psserver->RemovePlayer (client->GetClientNum(),"Your character data could not be loaded from the database.  Please contact tech support about this.");
        return false;
    }

    // FIXME: This should really be an assert in LoadCharacterData or such
    psRaceInfo *raceinfo=chardata->GetRaceInfo();
    if (raceinfo==NULL)
    {
        CPrintf(CON_ERROR, "Character load returned with NULL raceinfo pointer for %s!\n", ShowID(client->GetPID()));
        psserver->RemovePlayer (client->GetClientNum(),"Your character race could not be loaded from the database.  Please contact tech support about this.");
        delete chardata;
        return false;
    }

    csVector3 pos;
    float yrot;
    psSectorInfo *sectorinfo;
    iSector *sector;
    InstanceID instance;
    chardata->GetLocationInWorld(instance,sectorinfo,pos.x,pos.y,pos.z,yrot);
    sector=FindSector(sectorinfo->name);
    if (sector==NULL)
    {
        Error3("Could not resolve sector >%s< for %s.", sectorinfo->name.GetData(), ShowID(client->GetPID()));
        psserver->RemovePlayer (client->GetClientNum(),"The server could not create your character entity. (Sector not found)  Please contact tech support about this.");
        delete chardata;
        return false;
    }

    gemActor *actor = new gemActor(chardata,raceinfo->mesh_name,
                                   instance,sector,pos,yrot,
                                   client->GetClientNum());

    client->SetActor(actor);

    if (!actor || !actor->IsValid() )
    {
        Error2("Error while creating gemActor for Character '%s'\n", chardata->GetCharName());
        psserver->RemovePlayer (client->GetClientNum(),"The server could not create your character entity. (new gemActor() failed)  Please contact tech support about this.");
        return false;
    }
  
    chardata->LoadActiveSpells();

    // These are commented out now because they are handled by psConnectEvent published
    // Check for buddy list members
    // usermanager->NotifyBuddies(client, UserManager::LOGGED_ON);
    
    // Check for Guild members to notify
    // usermanager->NotifyGuildBuddies(client, UserManager::LOGGED_ON);

    // Set default state
    actor->SetMode(PSCHARACTER_MODE_PEACE);

    // Add Player to all Super Clients
    psserver->npcmanager->AddEntity(actor);

    psSaveCharEvent *saver = new psSaveCharEvent(actor);
    saver->QueueEvent();    
    
    return true;
}
示例#6
0
BYTE CDrive::In (WORD wPort_)
{
    BYTE bRet = 0x00;

    // Continue command execution if we're busy but not transferring data
    if ((m_sRegs.bStatus & (BUSY|DRQ)) == BUSY)
        ExecuteNext();

    // Register to read from is the bottom 3 bits of the port
    switch (wPort_ & 0x03)
    {
        case regStatus:
        {
            // Return value is the status byte
            bRet = m_sRegs.bStatus;

            // Type 1 command mode uses more status bits
            if ((m_sRegs.bCommand & FDC_COMMAND_MASK) <= STEP_OUT_UPD)
            {
                // Set the track 0 bit state
                if (!m_bHeadCyl)
                {
                    bRet |= TRACK00;
                    m_sRegs.bTrack = 0;         // this is updated even in non-update mode!
                }

                // The following only apply if there's a disk in the drive
                if (m_pDisk)
                {
                    // Set the write protect bit if the disk is read-only
                    if (m_pDisk->IsReadOnly())
                        bRet |= WRITE_PROTECT;

                    // If spin-up wasn't disabled, flag it complete
                    if (!(m_sRegs.bCommand & CMD_FLAG_SPINUP))
                        bRet |= SPIN_UP;

                    // Toggle the index pulse status bit periodically to show the disk is spinning
                    static int n = 0;
                    if (IsMotorOn() && !(++n % 1024))   // FIXME: use an event for the correct index timing
                        bRet |= INDEX_PULSE;
                }
            }

            // SAM DICE relies on a strange error condition, which requires special handling
            else if ((m_sRegs.bCommand & FDC_COMMAND_MASK) == READ_ADDRESS)
            {
                static int nBusyTimeout = 0;

                // Clear busy after 16 polls of the status port
                if (!(bRet & BUSY))
                    nBusyTimeout = 0;
                else if (!(++nBusyTimeout & 0x0f))
                {
                    ModifyStatus(0, BUSY);
                    m_bSectorIndex = 0;
                }
            }

            break;
        }

        case regTrack:
            // Return the current track register value (may not match the current physical head position)
            bRet = m_sRegs.bTrack;
            TRACE("Disk track: returning %#02x\n", bRet);
            break;

        case regSector:
            // Return the current sector register value
            bRet = m_sRegs.bSector;
//          TRACE("Disk sector: returning %#02x\n", byte);
            break;

        case regData:
        {
            // Data available?
            if (m_uBuffer)
            {
                // Read the next byte into the data register
                m_sRegs.bData = *m_pbBuffer++;
                m_uBuffer--;

                // Has all the data been read?
                if (!m_uBuffer)
                {
                    // Reset BUSY and DRQ to show we're done
                    ModifyStatus(0, BUSY|DRQ);

                    // Some commands require additional handling
                    switch (m_sRegs.bCommand & FDC_COMMAND_MASK)
                    {
                        case READ_ADDRESS:
                            break;

                        case READ_TRACK:
                            // No more data available
                            ModifyStatus(RECORD_NOT_FOUND, 0);
                            break;

                        case READ_1SECTOR:
                            // Set the data read status to include data CRC errors
                            ModifyStatus(m_bDataStatus, 0);
                            break;

                        case READ_MSECTOR:
                            // Set the data read status to include data CRC errors, and only continue if ok
                            ModifyStatus(m_bDataStatus, 0);
                            if (!m_bDataStatus)
                            {
                                IDFIELD id;

                                // Advance the sector number
                                m_sRegs.bSector++;

                                // Are there any more sectors to return?
                                if (FindSector(&id))
                                {
                                    TRACE("FDC: Multiple-sector read moving to sector %d\n", id.bSector);

                                    // Read the data, reporting anything but CRC errors now
                                    m_bDataStatus = ReadSector(m_pbBuffer = m_abBuffer, &m_uBuffer);
                                    ModifyReadStatus();
                                }
                            }
                            break;

                        default:
                            TRACE("Data requested for unknown command (%d)!\n", m_sRegs.bCommand);
                    }
                }
            }

            // Return the data register value
            bRet = m_sRegs.bData;
        }
    }

    return bRet;
}
示例#7
0
void CDrive::ExecuteNext ()
{
    BYTE bStatus = m_sRegs.bStatus;

    // Nothing to do if there's no disk in the drive
    if (!m_pDisk)
        return;

    // Continue processing the background
    if (m_pDisk->IsBusy(&bStatus))
    {
        // Keep the drive motor on as we're busy
        ModifyStatus(MOTOR_ON, 0);
        return;
    }

    // Some commands require additional handling
    switch (m_sRegs.bCommand & FDC_COMMAND_MASK)
    {
        case READ_1SECTOR:
        case READ_MSECTOR:
        {
            IDFIELD id;

            if (!FindSector(&id))
                ModifyStatus(RECORD_NOT_FOUND, BUSY);
            else
            {
                // Read the data, reporting anything but CRC errors now, as we can't check the CRC until we reach it at the end of the data on the disk
                m_bDataStatus = ReadSector(m_pbBuffer = m_abBuffer, &m_uBuffer);
                ModifyReadStatus();

                // Just for fun ;-)
                if (m_sRegs.bTrack == 4 && m_sRegs.bSector == 1 && m_abBuffer[0x016] == 0xC3 && CrcBlock(m_abBuffer, m_uBuffer) == 0x6c54)
                    m_abBuffer[0x016] -= 0x37;
            }
            break;
        }

        case WRITE_1SECTOR:
        case WRITE_MSECTOR:
        {
            if (m_nState == 0)
            {
                IDFIELD id;

                // Locate the sector, reset busy and signal record not found if we couldn't find it
                if (!FindSector(&id))
                    ModifyStatus(RECORD_NOT_FOUND, BUSY);
                else if (m_pDisk->IsReadOnly())
                    ModifyStatus(WRITE_PROTECT, BUSY);
                else
                {
                    // Prepare data pointer to receive data, and the amount we're expecting
                    m_pbBuffer = m_abBuffer;
                    m_uBuffer = 128U << (id.bSize & 3);

                    // Signal that data is now requested for writing
                    ModifyStatus(DRQ, 0);
                    m_nState++;
                }
            }
            else
            {
                // Write complete, so set its status and clear busy
                ModifyStatus(bStatus, BUSY);
            }

            break;
        }

        case READ_ADDRESS:
        {
            // Read an ID field into our general buffer
            IDFIELD* pId = reinterpret_cast<IDFIELD*>(m_pbBuffer = m_abBuffer);
            BYTE bReadStatus = ReadAddress(pId);

            // If successful set up the number of bytes available to read
            if (!(bReadStatus & TYPE23_ERROR_MASK))
            {
                m_sRegs.bSector = pId->bTrack;

                m_uBuffer = sizeof(IDFIELD);
                ModifyStatus(bStatus|DRQ, 0);   // Don't clear BUSY yet!
            }

            // Set the error status, resetting BUSY so the client sees the error
            else
            {
                ModifyStatus(bStatus, BUSY);
                m_uBuffer = 0;
            }

            break;
        }

        case READ_TRACK:
        {
            // Prepare a semi-convincing raw track
            ReadTrack(m_pbBuffer = m_abBuffer, m_uBuffer = sizeof(m_abBuffer));
            ModifyStatus(DRQ, 0);
            break;
        }

        case WRITE_TRACK:
        {
            ModifyStatus(bStatus, BUSY);
            break;
        }
    }
}