Пример #1
0
//----------------------------------------------------------------------------
IDestination * CBuildingTest::getRandomDestination()
{
	CBuildingManager * bm = CBuildingManager::getInstance();
	nlassert( bm );

	IDestination * dest = NULL;
	do
	{
		sint32 randomNumber = RandomGenerator.rand( (uint16)bm->_Triggers.size()-1 );
		CHashMap<sint,CBuildingManager::CTrigger>::iterator itTrigger = bm->_Triggers.begin();
		for (sint32 i = 0; i < randomNumber; i++)
		{
			++itTrigger;
			if (itTrigger == bm->_Triggers.end())
				itTrigger = bm->_Triggers.begin();
		}

		const sint triggerId = (*itTrigger).first;
		CBuildingManager::CTrigger & trigger = (*itTrigger).second;
		if (trigger.Destinations.empty())
		{
			nlwarning("*** BuildingUnitTest *** trigger %u has no destination.", triggerId);
			continue;
		}

		randomNumber = RandomGenerator.rand( (uint16)trigger.Destinations.size()-1 );
		dest = trigger.Destinations[randomNumber];
	} while ( !dest );

	return dest;
}
Пример #2
0
//-----------------------------------------------
bool CTimedAction::testCancelOnHit( sint32 attackSkillValue, CEntityBase * attacker, CEntityBase * defender)
{
	// get defender defense skill
	sint32 defenderValue;
	if ( defender->getId().getType() == RYZOMID::player )
	{
		CCharacter *pC = dynamic_cast<CCharacter*> (defender);
		if (!pC)
		{
			nlwarning("Entity %s type is player but dynamic_cast in CCharacter * returns NULL ?!", defender->getId().toString().c_str());
			return false;
		}
		defenderValue = pC->getSkillValue(pC->getBestSkill());
	}
	else
	{
		const CStaticCreatures * form = defender->getForm();
		if ( !form )
		{
			nlwarning( "<MAGIC>invalid creature form %s in entity %s", defender->getType().toString().c_str(), defender->getId().toString().c_str() );
			return false;
		}	
		defenderValue = form->getAttackLevel();
	}
	
	//test if the spell is broken
	const uint8 chances = CStaticSuccessTable::getSuccessChance( SUCCESS_TABLE_TYPE::BreakCastResist, defenderValue - attackSkillValue);
	const uint8 roll = (uint8) RandomGenerator.rand(99);
	
	if ( roll >= chances )
		return true;
	else
		return false;
}
Пример #3
0
//----------------------------------------------------------------------------
void CBuildingTest::moveCharacter(uint charIndex)
{
	nlassert( charIndex < TestCharacters.size() );

	if ( !TestCharacters[charIndex].InBuilding )
	{
		enterBuilding( charIndex );
	}
	else
	{
		const bool leave = (RandomGenerator.rand(99) & 1);
		if (leave)
			leaveBuilding( charIndex );
		else
			changeRoom( charIndex );
	}
}
Пример #4
0
//----------------------------------------------------------------------------
void CBuildingTest::timerCallback(CTimer * timer)
{
	H_AUTO(BuildingTestTimerEvent);

	if (Verbose)
	{
		nlinfo("*** BuildingUnitTest *** callback count %u", _Count);
	}

	const uint randomNumber = (uint) RandomGenerator.rand( (uint16)TestCharacters.size()-1 );
	for (uint i = 0; i < _Simultaneous; i++)
	{
		checkIntegrity();
		const uint charIndex = (randomNumber + i) % TestCharacters.size();
		moveCharacter( charIndex );
	}
	checkIntegrity();

	setNextEvent( timer );
}
Пример #5
0
//--------------------------------------------------------------
//		CBounceEffect::getTargetForBounce()
//--------------------------------------------------------------
CEntityBase *CBounceEffect::getTargetForBounce(CEntityBase *actor) const
{
    // get entities around
    if (!_AffectedEntity)
        _AffectedEntity = CEntityBaseManager::getEntityBasePtr(_TargetRowId);

    if (!_AffectedEntity)
        return NULL;

    // get entities in surrouding area
    // range of the effect in meters = _Value
    CRangeSelector entitiesSelector;
    entitiesSelector.buildDisc( CEntityBaseManager::getEntityBasePtr(getCreatorRowId()), _AffectedEntity->getX(), _AffectedEntity->getY(), (float) _Value, EntityMatrix, true );

    // select valid entities
    const vector<CEntityBase*> &entities = entitiesSelector.getEntities();
    const uint size = (uint)entities.size();

    vector<CEntityBase*> selectedEntities;
    selectedEntities.reserve(size);

    for (uint i = 0; i < entities.size() ; ++i)
    {
        if ( entities[i] && ( entities[i] != (CEntityBase*)(_AffectedEntity) ) && isEntityValidTarget(entities[i], actor) )
        {
            selectedEntities.push_back(entities[i]);
        }
    }

    if (selectedEntities.empty())
        return NULL;

    uint32 num = RandomGenerator.rand((uint16)selectedEntities.size()-1);

    return selectedEntities[num];

} // getTargetForBounce //
Пример #6
0
// mark a bnp file without corrupting its datas (this force the patch to be applied the next time the client is launched, thus delaying the trouble maker)
static void markBNPFile(std::string &path)
{
	CRandom rnd;
	rnd.srand((sint32) CTime::getLocalTime());

	uint32 nFileSize=CFile::getFileSize(path);
	if (!nFileSize) return;
	FILE *f = fopen(path.c_str(), "rb+");
	if (!f) return;
// Result
	if (nlfseek64 (f, nFileSize-4, SEEK_SET) != 0)
	{
		fclose (f);
		return;
	}

	uint32 nOffsetFromBeginning;
	if (fread (&nOffsetFromBeginning, sizeof(uint32), 1, f) != 1)
	{
		fclose (f);
		return;
	}

#ifdef NL_BIG_ENDIAN
	NLMISC_BSWAP32(nOffsetFromBeginning);
#endif

	if (nlfseek64 (f, nOffsetFromBeginning, SEEK_SET) != 0)
	{
		fclose (f);
		return;
	}

	// Read the file count
	uint32 nNbFile;
	if (fread (&nNbFile, sizeof(uint32), 1, f) != 1)
	{
		fclose (f);
		return;
	}

#ifdef NL_BIG_ENDIAN
	NLMISC_BSWAP32(nNbFile);
#endif

	for (uint32 i = 0; i < nNbFile; ++i)
	{
		char FileName[MAX_PATH];
		uint8 nStringSize;
		if (fread (&nStringSize, 1, 1, f) != 1)
		{
			fclose(f);
			return;
		}

		sint64 currPos = nlftell64(f);
		if (currPos < 0)
		{
			fclose(f);
			return;
		}
		if (fread (FileName, 1, nStringSize, f) != nStringSize)
		{
			fclose (f);
			return;
		}

		FileName[nStringSize] = 0;

		for(uint k = 0; k < nStringSize; ++k)
		{
			if (rnd.rand() & 1) FileName[k] = toupper(FileName[k]);
			else FileName[k] = tolower(FileName[k]);
		}


		if (nlfseek64 (f, currPos, SEEK_SET) != 0)
		{
			fclose (f);
			return;
		}


		// write shuffled version
		if (fwrite(FileName, 1, nStringSize, f) != nStringSize)
		{
			fclose(f);
			return;
		}
		fflush(f);

		uint32 nFileSize2;
		if (fread (&nFileSize2, sizeof(uint32), 1, f) != 1)
		{
			fclose (f);
			return;
		}

#ifdef NL_BIG_ENDIAN
		NLMISC_BSWAP32(nFileSize2);
#endif

		uint32 nFilePos;
		if (fread (&nFilePos, sizeof(uint32), 1, f) != 1)
		{
			fclose (f);
			return;
		}

#ifdef NL_BIG_ENDIAN
		NLMISC_BSWAP32(nFilePos);
#endif
	}

	fclose (f);
}
//-----------------------------------------------
// CSLinkEffectOffensive updateOffensive
//-----------------------------------------------
bool CSLinkEffectOffensive::updateOffensive(CTimerEvent * event, bool sendReportForXP)
{
	if ( CSLinkEffect::update(event,true) )
		return true;

	CEntityBase * target = CEntityBaseManager::getEntityBasePtr( _TargetRowId );
	if ( !target )
	{
		nlwarning("<CSLinkEffectDot update> Invalid target %u",_TargetRowId.getIndex() );
		_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
		return true;
	}

	// if target is now protected, cancel the effect
	CSEffect *effect = target->lookForActiveEffect(EFFECT_FAMILIES::PowerAntiMagicShield);
	if (effect)
	{
		_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
		return true;
	}

	// test target is still valid for a link (can happen in PVP or duel)
	string errorCode;
	if ( !PHRASE_UTILITIES::validateSpellTarget(_CreatorRowId, _TargetRowId, ACTNATURE::OFFENSIVE_MAGIC, errorCode, true ) )
	{
		_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
		return true;
	}

	if (_LinkExists)
	{
		CEntityBase * caster = CEntityBaseManager::getEntityBasePtr( _CreatorRowId );
		if ( !caster )
		{
			nlwarning("<CSLinkEffectDot update> Invalid caster %u",_CreatorRowId.getIndex() );
			_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
			return true;
		}
	
		// test resistance
		if ( !_FirstResist && !EntitiesNoResist)
		{
			uint32 resistValue = 0;
			if (_Family == EFFECT_FAMILIES::Dot)
			{
				CSLinkEffectDot *dot = dynamic_cast<CSLinkEffectDot*> (this);
				if (dot)
				{
					resistValue = target->getMagicResistance(dot->getDamageType());
				}
			}
			else
			{
				resistValue = target->getMagicResistance(_Family);
			}

			sint skillValue = 0;
			if ( caster->getId().getType() == RYZOMID::player )
			{
				CCharacter * pC = (CCharacter *) caster;
				skillValue = pC->getSkillValue( _Skill );
			}
			else
			{
				const CStaticCreatures * form = caster->getForm();
				if ( !form )
				{
					nlwarning( "<MAGIC>invalid creature form %s in entity %s", caster->getType().toString().c_str(), caster->getId().toString().c_str() );
					_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
					return true;
				}	
				skillValue = form->getAttackLevel();
			}

			const CSEffect* debuff = caster->lookForActiveEffect( EFFECT_FAMILIES::DebuffSkillMagic );
			if ( debuff )
				skillValue -= debuff->getParamValue();
			const CSEffect * outPostBuff = caster->lookForActiveEffect( EFFECT_FAMILIES::OutpostMagic );
			if ( outPostBuff )
				skillValue += outPostBuff->getParamValue();

			// cap skill values with brick power
			if ( (sint32)_Power < skillValue )
				skillValue = (sint32)_Power;
			
			if ( caster->getId().getType() == RYZOMID::player )
			{
				CCharacter * pC = dynamic_cast<CCharacter *>( caster );
				if( pC )
				{
					// boost magic skill for low level chars
					sint sb = (sint)MagicSkillStartValue.get();
					skillValue = max( sb, skillValue );

					// add magic boost from consumable
					skillValue += pC->magicSuccessModifier();
				}
			}

			// test resistance
			const uint8 roll = (uint8)RandomGenerator.rand( 99 );
			_ResistFactor = CStaticSuccessTable::getSuccessFactor(SUCCESS_TABLE_TYPE::MagicResistLink, skillValue - resistValue, roll);

			// increase target resistance
			if (_ResistFactor > 0.0f)
			{
				if (_Family == EFFECT_FAMILIES::Dot)
				{
					CSLinkEffectDot *dot = dynamic_cast<CSLinkEffectDot*> (this);
					if (dot)
					{
						target->incResistModifier(dot->getDamageType(), _ResistFactor);
					}
				}
				else
				{
					target->incResistModifier(_Family,_ResistFactor);
				}
			}

			// delta level for XP gain 
			// opponent must be a creature or an npc to gain xp
			_Report.DeltaLvl = skillValue - resistValue;
			if (target->getId().getType() != RYZOMID::player && caster->getId().getType() == RYZOMID::player)
			{
				CCreature *creature = dynamic_cast<CCreature*> (target);
				if (!creature)
				{
					nlwarning("Entity %s type is creature but dynamic_cast in CCreature * returns NULL ?!", target->getId().toString().c_str());
					_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
					return true;
				}
				CCharacter * pC = dynamic_cast<CCharacter*> (caster);
				if (!pC)
				{
					nlwarning("Entity %s type is player but dynamic_cast in CCharacter * returns NULL ?!", caster->getId().toString().c_str());
					_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
					return true;
				}

				const CStaticCreatures* form = creature->getForm();
				if (form)
					_Report.DeltaLvl =  pC->getSkillValue(_Skill) - form->getXPLevel();
				else
					sendReportForXP = false;
			}
			else
				sendReportForXP = false;
		}
		else
		{
			_FirstResist = false;
			_ResistFactor = 1.0f;
		}
		
		bool end = true;
		// resist if factor <= 0
		if ( _ResistFactor > 0.0f  )
		{
			end = false;
			if ( _ResistFactor > 1.0f )
			{
				_ResistFactor = 1.0f;
			}

			// send report for XP			
			_Report.factor = _ResistFactor;

			if (sendReportForXP)
			{
				PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->actionReport( _Report );
				PROGRESSIONPVP::CCharacterProgressionPVP::getInstance()->reportAction(_Report);
			}
		}
		else
		{
			PHRASE_UTILITIES::sendSpellResistMessages( _CreatorRowId, _TargetRowId);
		}

		//////////////////////////////////////////////////////////////////////////
		// TEMPORARY : SEND AGGRO MESSAGE FOR EVERY UPDATE OF OFFENSIVE LINKS
		//////////////////////////////////////////////////////////////////////////	
		CAiEventReport report;
		report.Originator = _CreatorRowId;
		report.Target = _TargetRowId;
		report.Type = ACTNATURE::OFFENSIVE_MAGIC;		
		report.AggroAdd = -0.01f;
		CPhraseManager::getInstance().addAiEventReport(report);
		//////////////////////////////////////////////////////////////////////////
				
		if (end)
		{
			_EndTimer.setRemaining(1, new CEndEffectTimerEvent(this));
			return true;
		}
	}
	else
	{
		// no link -> no possible resist ?
	}

	return false;
} // CSLinkEffectOffensive::updateOffensive //
Пример #8
0
//----------------------------------------------------------------------------
bool CBuildingTest::changeRoom(uint charIndex)
{
	nlassert( charIndex < TestCharacters.size() );
	nlassert( TestCharacters[charIndex].InBuilding );

	CEntityId id = TestCharacters[charIndex].EId;

	CCharacter * c = PlayerManager.getChar( id );
	nlassert( c );

	sint32 cellId = TestCharacters[charIndex].CellId;
	const IRoomInstance * room = CBuildingManager::getInstance()->getRoomInstanceFromCell( cellId );
	if ( !room )
	{
		nlwarning("*** BuildingUnitTest *** cannot get room instance for character %u at cell %d.", charIndex, cellId);
		return false;
	}

	IBuildingPhysical * buildingInst = room->getBuilding();
	nlassert( buildingInst );

	const uint16 roomIndex = room->getRoomIndex();

	vector<IBuildingPhysical::CRoomPhysical> & rooms = buildingInst->_Rooms;
	nlassert( !rooms.empty() );

	if ( rooms.size() == 1 )
		return true;

	// find another room
	uint16 newRoomIndex;
	const uint maxLoops = 1000;
	uint nbLoops = 0;
	while (1)
	{
		nlassert(++nbLoops <= maxLoops);

		newRoomIndex = (uint16) RandomGenerator.rand( (uint16)rooms.size()-1 );
		if (newRoomIndex >= rooms.size())
			newRoomIndex = 0;

		if (newRoomIndex != roomIndex)
			break;
	}

	nlassert( !rooms[newRoomIndex].Cells.empty() );
	const sint32 newCellId = rooms[newRoomIndex].Cells[0];
	const IRoomInstance * newRoom = CBuildingManager::getInstance()->getRoomInstanceFromCell( newCellId );
	if ( !newRoom )
	{
		nlwarning("*** BuildingUnitTest *** cannot get room instance for character %u at cell %d.", charIndex, newCellId);
		return false;
	}

	IBuildingPhysical * newBuildingInst = newRoom->getBuilding();
	nlassert( newBuildingInst );
	nlassert( newBuildingInst == buildingInst );

	// cannot change room if we are in a guild/player building
	if ( !dynamic_cast<const CRoomInstanceCommon *>( newRoom ) )
		return true;

	if ( !newBuildingInst->addUser( c, newRoomIndex, 0, cellId ) )
	{
		nlwarning("*** BuildingUnitTest *** character %u cannot go from room %hu to room %hu in building %s.",
			charIndex, roomIndex, newRoomIndex, TestCharacters[charIndex].BuildingName.c_str()
			);
		CBuildingManager::getInstance()->removePlayerFromRoom( c );
		return false;
	}

	if (Verbose)
	{
		nlinfo("*** BuildingUnitTest *** character %u goes from room %hu (cell = %d) to room %hu (cell = %d) in building %s.",
			charIndex, roomIndex, TestCharacters[charIndex].CellId, newRoomIndex, cellId, TestCharacters[charIndex].BuildingName.c_str()
			);
	}

	// fake teleport
	CBuildingManager::getInstance()->removePlayerFromRoom( c );
	CMirrorPropValue<TYPE_CELL> mirrorCell( TheDataset, c->getEntityRowId(), DSPropertyCELL );
	mirrorCell = cellId;

	// update character data
	TestCharacters[charIndex].CellId		= cellId;
	TestCharacters[charIndex].RoomIndex		= newRoomIndex;

	return true;
}