bool CItemMulti::Ship_SetMoveDir( DIR_TYPE dir ) { // Set the direction we will move next time we get a tick. int iSpeed = 1; if ( m_itShip.m_DirMove == dir && m_itShip.m_fSail ) { if ( m_itShip.m_DirFace == m_itShip.m_DirMove && m_itShip.m_fSail == 1 ) { iSpeed = 2; } else return( false ); } if ( ! IsAttr(ATTR_MAGIC )) // make sound. { if ( ! Calc_GetRandVal(10)) { Sound( Calc_GetRandVal(2)?0x12:0x13 ); } } m_itShip.m_DirMove = dir; m_itShip.m_fSail = iSpeed; GetTopSector()->SetSectorWakeStatus(); // may get here b4 my client does. SetTimeout(( m_itShip.m_fSail == 1 ) ? 1*TICK_PER_SEC : (TICK_PER_SEC/5)); return( true ); }
void CItemCommCrystal::OnMoveFrom() { ADDTOCALLSTACK("CItemCommCrystal::OnMoveFrom"); // Being removed from the top level. CSector *pSector = GetTopSector(); if ( pSector ) pSector->RemoveListenItem(); }
void CItemSpawn::GenerateChar(CResourceDef *pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); if ( !IsTopLevel() ) return; RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef *pSpawnGroup = static_cast<const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); size_t i = pSpawnGroup->GetRandMemberIndex(); if ( i != pSpawnGroup->BadMemberIndex() ) rid = pSpawnGroup->GetMemberID(i); } if ( (rid.GetResType() != RES_CHARDEF) && (rid.GetResType() != RES_UNKNOWN) ) return; CChar *pChar = CChar::CreateBasic(static_cast<CREID_TYPE>(rid.GetResIndex())); if ( !pChar ) return; CPointMap pt = GetTopPoint(); pChar->NPC_LoadScript(true); pChar->StatFlag_Set(STATF_Spawned); pChar->MoveTo(pt); // Check if the NPC can spawn in this region CRegionBase *pRegion = GetTopPoint().GetRegion(REGION_TYPE_AREA); if ( !pRegion || (pRegion->IsGuarded() && pChar->Noto_IsEvil()) ) { pChar->Delete(); return; } AddObj(pChar->GetUID()); pChar->NPC_CreateTrigger(); // removed from NPC_LoadScript() and triggered after char placement and attachment to the spawnitem pChar->Update(); size_t iCount = GetTopSector()->GetCharComplexity(); if ( iCount > g_Cfg.m_iMaxCharComplexity ) g_Log.Event(LOGL_WARN, "%d chars at %s. Sector too complex!\n", iCount, GetTopSector()->GetBasePoint().WriteUsed()); }
void CItem::Spawn_GenerateChar( CResourceDef * pDef ) { if ( ! IsTopLevel()) return; // creatures can only be top level. if ( m_itSpawnChar.m_current >= GetAmount()) return; int iComplexity = GetTopSector()->GetCharComplexity(); if ( iComplexity > g_Cfg.m_iMaxCharComplexity ) { DEBUG_MSG(( "Spawn uid=0%lx too complex (%d>%d)\n", GetUID(), iComplexity, g_Cfg.m_iMaxCharComplexity )); return; } int iDistMax = m_itSpawnChar.m_DistMax; RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef * pSpawnGroup = STATIC_CAST <const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); int i = pSpawnGroup->GetRandMemberIndex(); if ( i >= 0 ) { rid = pSpawnGroup->GetMemberID(i); } } CREID_TYPE id; if ( rid.GetResType() == RES_CHARDEF || rid.GetResType() == RES_UNKNOWN ) { id = (CREID_TYPE) rid.GetResIndex(); } else { return; } CChar * pChar = CChar::CreateNPC( id ); if ( pChar == NULL ) return; ASSERT(pChar->m_pNPC); m_itSpawnChar.m_current ++; pChar->Memory_AddObjTypes( this, MEMORY_ISPAWNED ); // Move to spot "near" the spawn item. pChar->MoveNearObj( this, iDistMax ); if ( iDistMax ) { pChar->m_ptHome = GetTopPoint(); pChar->m_pNPC->m_Home_Dist_Wander = iDistMax; } pChar->Update(); }
void CItemSpawn::GenerateChar(CResourceDef *pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef *pSpawnGroup = static_cast<const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); size_t i = pSpawnGroup->GetRandMemberIndex(); if ( i != pSpawnGroup->BadMemberIndex() ) rid = pSpawnGroup->GetMemberID(i); } if ( (rid.GetResType() != RES_CHARDEF) && (rid.GetResType() != RES_UNKNOWN) ) return; CPointMap pt = GetTopPoint(); CRegionBase *pRegion = pt.GetRegion(REGION_TYPE_AREA); if ( !pRegion ) return; CChar *pChar = CChar::CreateBasic(static_cast<CREID_TYPE>(rid.GetResIndex())); if ( !pChar ) return; pChar->NPC_LoadScript(true); pChar->StatFlag_Set(STATF_Spawned); // Try placing the char near the spawn if ( !pChar->MoveNearObj(this, m_itSpawnChar.m_DistMax) || !pChar->CanSeeLOS(pt) ) { // If this fails, try placing the char over the spawn if ( !pChar->MoveTo(pt) ) { DEBUG_ERR(("Spawn UID:0%lx is unable to place a character inside the world.\n", static_cast<DWORD>(GetUID()))); pChar->Delete(); return; } } AddObj(pChar->GetUID()); pChar->NPC_CreateTrigger(); // removed from NPC_LoadScript() and triggered after char placement and attachment to the spawnitem pChar->Update(); size_t iCount = GetTopSector()->GetCharComplexity(); if ( iCount > g_Cfg.m_iMaxCharComplexity ) g_Log.Event(LOGL_WARN, "%" FMTSIZE_T " chars at %s. Sector too complex!\n", iCount, GetTopSector()->GetBasePoint().WriteUsed()); }
bool CItemMulti::Ship_Move( DIR_TYPE dir ) { if ( dir >= DIR_QTY ) return( false ); if ( m_pRegion == NULL ) { DEBUG_ERR(( "Ship bad region\n" )); return false; } CPointMap ptDelta; ptDelta.ZeroPoint(); ptDelta.Move( dir ); CPointMap ptForePrv = m_pRegion->GetRegionCorner(dir); CPointMap ptFore = ptForePrv; ptFore.Move( dir ); ptFore.m_z = GetTopZ(); if ( ! ptFore.IsValidPoint() || ( ptForePrv.m_x < UO_SIZE_X_REAL && ptFore.m_x >= UO_SIZE_X_REAL && ( ptFore.m_map <= 1 ))) { // Circle the globe // Fall off edge of world ? CItem * pTiller = Multi_GetSign(); ASSERT(pTiller); pTiller->Speak( "Turbulent waters Cap'n", 0, TALKMODE_SAY, FONT_NORMAL ); // Compute the new safe place to go. (where we will not overlap) int iMaxDist = Multi_GetMaxDist(); /* if ( ptFore.m_x <= 0 ) { } else if ( ptFore.m_x >= UO_SIZE_X_REAL ) { } else if ( ptFore.m_y <= 0 ) { } else if ( ptFore.m_y >= UO_SIZE_Y ) { } */ return false; } // We should check all relevant corners. if ( ! Ship_CanMoveTo( ptFore )) { cantmove: CItem * pTiller = Multi_GetSign(); ASSERT(pTiller); pTiller->Speak( "We've stopped Cap'n", 0, TALKMODE_SAY, FONT_NORMAL ); return false; } // left side CPointMap ptTmp = m_pRegion->GetRegionCorner(GetDirTurn(dir,-1)); ptTmp.Move( dir ); ptTmp.m_z = GetTopZ(); if ( ! Ship_CanMoveTo( ptTmp )) goto cantmove; // right side. ptTmp = m_pRegion->GetRegionCorner(GetDirTurn(dir,+1)); ptTmp.Move( dir ); ptTmp.m_z = GetTopZ(); if ( ! Ship_CanMoveTo( ptTmp )) goto cantmove; Ship_MoveDelta( ptDelta ); // Move again GetTopSector()->SetSectorWakeStatus(); // may get here b4 my client does. return true; }
void CItemSpawn::GenerateChar(CResourceDef * pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); if ( !IsTopLevel() || ( m_itSpawnChar.m_current >= GetAmount() ) || ( GetTopSector()->GetCharComplexity() > g_Cfg.m_iMaxCharComplexity )) return; int iDistMax = m_itSpawnChar.m_DistMax; RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef * pSpawnGroup = STATIC_CAST <const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); size_t i = pSpawnGroup->GetRandMemberIndex(); if ( i != pSpawnGroup->BadMemberIndex() ) { rid = pSpawnGroup->GetMemberID(i); } } if (( rid.GetResType() != RES_CHARDEF ) && ( rid.GetResType() != RES_UNKNOWN )) return; CREID_TYPE id = static_cast<CREID_TYPE>(rid.GetResIndex()); bool isBadPlaceToSpawn = false; CChar * pChar = CChar::CreateBasic(id); if( pChar == NULL ) { return; } pChar->NPC_LoadScript(true); AddObj(pChar->GetUID()); pChar->m_uidSpawnItem = GetUID(); // SpawnItem for this char pChar->StatFlag_Set( STATF_Spawned ); pChar->MoveTo(GetTopPoint()); pChar->NPC_CreateTrigger(); //Removed from NPC_LoadScript() and triggered after char placement if( pChar->GetRegion() == NULL ) { isBadPlaceToSpawn = true; } else if( pChar->GetRegion()->IsGuarded() && pChar->Noto_IsEvil() ) { isBadPlaceToSpawn = true; } // Deny definitely known a bad place to spawn (like red NPCs in guarded areas) // Usually caused by wide range near the edge of the towns if( isBadPlaceToSpawn ) { pChar->Delete(); //m_itSpawnChar.m_current--; return; } ASSERT(pChar->m_pNPC); if ( iDistMax ) { pChar->m_ptHome = GetTopPoint(); pChar->m_pNPC->m_Home_Dist_Wander = static_cast<WORD>(iDistMax); } pChar->Update(); }