All pastes #20239 Raw Edit

Something

public text v1 · immutable
#20239 ·published 2005-08-17 08:38 UTC
rendered paste body
	private void levelSoulCrystals(L2Character attacker)
	{
		boolean success = true;
		int thisMobId = getNpcId();
		L2PcInstance killer = (L2PcInstance)attacker;
		
		// Only L2PcInstance can absorb a soul
		if (!(attacker instanceof L2PcInstance))
			success = false;
		
		// Fail if this L2Attackable isn't absorbed or there's no one in its _absorbersList
		if (!isAbsorbed() || _absorbersList == null)
			success = false;

		// Fail if the killer isn't in the _absorbersList of this L2Attackable
		AbsorberInfo ai = _absorbersList.get(killer);
		if (ai == null || ai.absorber.getObjectId() != killer.getObjectId())
			success = false;
		
		// Check if the soul crystal was used when HP of this L2Attackable wasn't higher than half of it
		if (ai.absorbedHP > (getMaxHp()/2))
			success = false;
		
		// If failed, clears the _absorbersList and just return
		if (!success) {
			_absorbed = false;
			_absorbersList = null;
			return;
		}
		
		// Check if this L2Attackable isn't within any of the groups of mobs that can be absorbed
		success = false;
		int maxCrystalLevel = 0;
		for (int mobId : _absorbingMOBS_level4) {
			if (thisMobId == mobId) {
				maxCrystalLevel = 4;
				success = true;
				break;
			}
		}
		if (!success) {
			for (int mobId : _absorbingMOBS_level8) {
				if (thisMobId == mobId) {
					maxCrystalLevel = 8;
					success = true;
					break;
				}
			}
		}
		if (!success) {
			for (int mobId : _absorbingMOBS_level10) {
				if (thisMobId == mobId) {
					maxCrystalLevel = 10;
					success = true;
					break;
				}
			}
		}
		
		// If failed, clears the _absorbersList and just return
		if (!success) {
			_absorbed = false;
			_absorbersList = null;
			return;
		}
		
		// Init some info
		Random _rnd = new Random();
		int dice = _rnd.nextInt(100);
		int crystalId = ai.crystalId;
		int oldCrystalId = 0;
		int newCrystalId = 0;
		int crystalOffset = 0;
		int crystalsCount = 0;
		SystemMessage sms = new SystemMessage(SystemMessage.EARNED_ITEM);
		SystemMessage sm = new SystemMessage(614);
		success = true;
		
		final L2ItemInstance[] inv = killer.getInventory().getItems();
		for (int index = 0; index < inv.length; index++) 
		{
			final L2ItemInstance item = inv[index];
			/** We must improve this */
			if ( ((item.getItemId() >= _REDCRYSTAL_OFFSET) || (item.getItemId() >= _GREENCRYSTAL_OFFSET) || (item.getItemId() >= _BLUECRYSTAL_OFFSET)) &&
				 ((item.getItemId() <= _REDCRYSTAL_OFFSET+10) || (item.getItemId() <= _GREENCRYSTAL_OFFSET+10) || (item.getItemId() <= _BLUECRYSTAL_OFFSET+10)) )
			{
				crystalsCount++;
			}
			if (crystalsCount > 1) {
				success = false;
				break;
			}
		}
		
		// The attacker has no crystals at all, let's just quit
		if (crystalsCount < 1)
		{
			_absorbed = false;
			_absorbersList = null;
			return;
		}
		
		// The attacker has more than one soul crystal with him, the crystal just will resonate
		if (!success) {
			sm.addString("The soul crystal resonated.");
			killer.sendPacket(new PlaySound("ItemSound2.broken_key"));
			killer.sendPacket(sm);
			_absorbed = false;
			_absorbersList = null;
			return;
		}

		// Now we got four choices:
		// 1- The Monster level is too low for the crystal. Nothing happens.
		// 2- Everything is correct, but it failed. Nothing happens. (50%)
		// 3- Everything is correct, but it failed. The crystal scatters. A sound event is played. (10%)
		// 4- Everything is correct, the crystal level up. A sound event is played. (40%)
		success = false;
		for (int crystalLevel = 0; crystalLevel < _MAX_CRYSTALS_LEVEL; crystalLevel++)
		{
			// Get a crystal offset to calculate the new crystal ID
			if (crystalId == (_REDCRYSTAL_OFFSET + crystalLevel)) crystalOffset = _REDCRYSTAL_OFFSET;
			if (crystalId == (_GREENCRYSTAL_OFFSET + crystalLevel)) crystalOffset = _GREENCRYSTAL_OFFSET;  
			if (crystalId == (_BLUECRYSTAL_OFFSET + crystalLevel)) crystalOffset = _BLUECRYSTAL_OFFSET;
			if (crystalLevel > 9) {
				if (crystalId == (_REDCRYSTAL_OFFSET+10)) crystalOffset = _REDCRYSTAL_LVL11 - 11;
				if (crystalId == (_GREENCRYSTAL_OFFSET+10)) crystalOffset = _GREENCRYSTAL_LVL11 - 11;
				if (crystalId == (_BLUECRYSTAL_OFFSET+10)) crystalOffset = _BLUECRYSTAL_LVL11 - 11;
				if (crystalId == (_REDCRYSTAL_LVL11)) crystalOffset = _REDCRYSTAL_LVL12 - 12;
				if (crystalId == (_GREENCRYSTAL_LVL11)) crystalOffset = _GREENCRYSTAL_LVL12 - 12;
				if (crystalId == (_BLUECRYSTAL_LVL11)) crystalOffset = _BLUECRYSTAL_LVL12 - 12;
			}
			
			// If we have a valid offset, make the checks
			if (crystalOffset > 0)
			{
				// If the crystal level is way too high for this mob, then quit
				if (crystalLevel >= maxCrystalLevel) {
					sm.addString("The soul crystal has refused to absorb the soul.");
					break;
				}
				
				oldCrystalId = crystalId;
				newCrystalId = (crystalOffset + crystalLevel) + 1;
				L2ItemInstance newCrystal = ItemTable.getInstance().createItem(newCrystalId);
				
				// Crystals with level > 10 always succeed in leveling
				if (crystalLevel > 10)
				{
					// Manage the item exchange from killer inventory;
					killer.getInventory().destroyItemByItemId(oldCrystalId, 1);
					killer.getInventory().addItem(newCrystal);
					killer.sendPacket(new PlaySound("ItemSound.quest_middle"));
					sms.addItemName(newCrystalId);
					break;
				}

				// If the killer get a critical failure, break the crystal
				if (dice < _BREAK_CHANCE)
				{
					// Manage the item deletion from killer inventory;
					killer.getInventory().destroyItemByItemId(oldCrystalId, 1);
					killer.sendPacket(new PlaySound("ItemSound3.sys_enchant_failed"));
					sm.addString("The soul crystal scattered itself.");
					break;
				}
				
				// If the killer succeeds, level up the crystal
				if (dice < _LEVEL_CHANCE)
				{
					// Manage the item exchange from killer inventory;
					killer.getInventory().destroyItemByItemId(oldCrystalId, 1);
					killer.getInventory().addItem(newCrystal);
					// Update all the shortcuts to the new crystal
					L2ShortCut[] allShortCuts = killer.getAllShortCuts();
					for (L2ShortCut sc : allShortCuts) {
						if (sc.id == oldCrystalId && sc.type == L2ShortCut.TYPE_ITEM)
						{
							L2ShortCut newsc = new L2ShortCut(sc.slot, sc.page, sc.type, newCrystalId, sc.level, sc.unk);
							killer.sendPacket(new ShortCutRegister(newsc));
							killer.registerShortCut(newsc);
						}
					}
					// Send a sound event and text message to the player
					killer.sendPacket(new PlaySound("ItemSound.quest_itemget"));
					sms.addItemName(newCrystalId);
					success = true;
					break;
				}

				// Anything else, just fails...
				sm.addString("The soul crystal has failed to absorb the soul.");
				break;
			}
		}
		
		// Send Server->Client packets to notify the killer and update his Inventory
		if (success)
			killer.sendPacket(sms);
		else
			killer.sendPacket(sm);
		ItemList il = new ItemList(killer, false);
		killer.sendPacket(il);

	}