Jump to content

Recommended Posts

Posted

Btw i didnt read the full mod that you want to do so i undestand from the error that you got siege problem on castlezone so excuse me i will try to help you

Posted

xAdd, don't troll please, he tries to help :).

 

For others, if you have any idea of resolution, don't hesitate to PM me to give me your feelings. I can let it as a test for our "helpful developer soul" and give the resolution too if he doesn't find :).

 

ABOUT THE TEST

 

- It is mainly to show your developing skills to others, but it's a real problem I actually try to resolve.

- According how you help, people will trust you more or less, so do your best and ask the good questions :).

- I can give any parts of code you will judge necessary to resolve the problem, you just can't have the full code.

- YOU DON'T NEED TO RESOLVE THE PROBLEM YOURSELF, YOU CAN HELP GIVING ME TRACKS. Once again it's just to see "how you think" and "how far your logic can go".

- This case is possible to resolve without the whole acess to all source. I begin to have an idea why it is buggy (see "EXPERIENCES" tab).

 

DA ERROR !

 

Check my screen in first post to see the full NPE.

 

Error in line 108 of my code (I updated sources, so it's not anymore line 106, but 108), which is supposed to be

if (activeChar.getFactionId() != castleLord.getFactionId())

 

EXPERIENCES

 

- I discovered than the system worked only when the leader of castle was on (so yeah, now I have a track).

- I implemented the GameTimeController from L2Jrev, with javolution.jar update etc, without effect. Consider it's not a GameTimeController problem.

 

ABOUT THE SYSTEM

 

L2JArchid, interlude, very very old project :).

The project itself isn't to blame in my case. Don't begin a troll war about lacks in Archid.

 

My siege system is fully custom, and you need only the idea to understand it. You can't find it on any place, as I have handed-scripting all. Yeah, some people likes to develop their own ideas and not only apply patches :).

 

  • L2 got castles, they're NPCs sided at begin.
  • I have a faction server, aka 2 teams fighting each other.
  • One of the goal of my server is to adapt sieges for factions, without using any registering NPCs.
  • For that, I use the castle zone area, which is activated when a siege occurs.
  • Areas got an Enter/Exit solution which is perfect for the purpose.
  • When you enter in a castle zone, AND IF a siege occurs, a check is made about the SiegeState (RelationChanged packet).
  • According to castle lord faction and your own faction, you are put 1 (attacker) or 2 (defender).
  • If you got no clan or are a GM, you're set to 0.
  • This check is usefull only for guards aggro, doors open/kill and artefact skill cast.
     

 

----

 

About your ask, even if I know it won't be useful to resolve this case :

 

package com.l2jarchid.gameserver.model.zone.type;

import javolution.util.FastList;

import com.l2jarchid.gameserver.datatables.ClanTable;
import com.l2jarchid.gameserver.datatables.MapRegionTable;
import com.l2jarchid.gameserver.instancemanager.CastleManager;
import com.l2jarchid.gameserver.model.L2Clan;
import com.l2jarchid.gameserver.model.L2ClanMember;
import com.l2jarchid.gameserver.model.actor.L2Character;
import com.l2jarchid.gameserver.model.actor.instance.L2PcInstance;
import com.l2jarchid.gameserver.model.actor.instance.L2SiegeSummonInstance;
import com.l2jarchid.gameserver.model.entity.Castle;
import com.l2jarchid.gameserver.model.zone.L2ZoneType;
import com.l2jarchid.gameserver.network.SystemMessageId;
import com.l2jarchid.gameserver.network.serverpackets.RelationChanged;
import com.l2jarchid.gameserver.network.serverpackets.SystemMessage;
import com.l2jarchid.gameserver.network.serverpackets.UserInfo;

import java.util.logging.Logger;

/**
* A castle zone
*
* @author  durgus
*/
public class L2CastleZone extends L2ZoneType
{
private static Logger _log = Logger.getLogger(L2CastleZone.class.getName());

private int _castleId;
private Castle _castle;
private int[] _spawnLoc;

public L2CastleZone()
{
	super();
	_spawnLoc = new int[3];
}

@Override
public void setParameter(String name, String value)
{
	if (name.equals("castleId"))
	{
		_castleId = Integer.parseInt(value);

		// Register self to the correct castle
		_castle = CastleManager.getInstance().getCastleById(_castleId);
		_castle.setZone(this);
	}
	else if (name.equals("spawnX"))
		_spawnLoc[0] = Integer.parseInt(value);
	else if (name.equals("spawnY"))
		_spawnLoc[1] = Integer.parseInt(value);
	else if (name.equals("spawnZ"))
		_spawnLoc[2] = Integer.parseInt(value);
	else 
		super.setParameter(name, value);
}

@Override
protected void onEnter(L2Character character)
{
	if (_castle.getSiege().getIsInProgress())
	{
		character.setInsideZone(L2Character.ZONE_PVP, true);
		character.setInsideZone(L2Character.ZONE_SIEGE, true);

		if (character instanceof L2PcInstance)
		{
			L2PcInstance activeChar = (L2PcInstance) character;

			activeChar.sendPacket(new SystemMessage(SystemMessageId.ENTERED_COMBAT_ZONE));

			// Mise a jour de la relation (excepte pour GMs et joueurs sans clan)
			if (!activeChar.isGM() && activeChar.getClan() != null)
			{
				//si le possesseur du chateau est different de rien
				if (_castle.getOwnerId() > 0)
				{
					//recherche du clan possesseur, et ensuite du clan leader
					L2Clan clanOwner = ClanTable.getInstance().getClan(_castle.getOwnerId());

					if (clanOwner != null)
					{
						L2PcInstance castleLord = clanOwner.getLeader().getPlayerInstance();

						// si le joueur est d'une faction differente du clan possesseur, 
						// il est affiche en ennemi - sinon il est affiche en defenseur
						if (activeChar.getFactionId() != castleLord.getFactionId())
							activeChar.setSiegeState((byte) 1);
						else
							activeChar.setSiegeState((byte) 2);
					}
				}
				//sinon tout le monde est considere comme ennemi.
				else
					activeChar.setSiegeState((byte) 1);

				//renvoit les infos du joueur au joueur
				activeChar.sendPacket(new UserInfo(activeChar));

				//puis aux joueurs autour de lui
				for (L2PcInstance player : activeChar.getKnownList().getKnownPlayers().values())
					player.sendPacket(new RelationChanged(activeChar, activeChar.getRelation(player), activeChar.isAutoAttackable(player)));
			}
		}
	}
}

@Override
protected void onExit(L2Character character)
{
	if (_castle.getSiege().getIsInProgress())
	{
		character.setInsideZone(L2Character.ZONE_PVP, false);
		character.setInsideZone(L2Character.ZONE_SIEGE, false);

		if (character instanceof L2PcInstance)
		{
			L2PcInstance activeChar = (L2PcInstance) character;

			activeChar.sendPacket(new SystemMessage(SystemMessageId.LEFT_COMBAT_ZONE));

			//reset le state
			activeChar.setSiegeState((byte) 0);

			//renvoit les infos du joueur au joueur
			activeChar.sendPacket(new UserInfo(activeChar));

			//puis aux joueurs autour de lui
			for (L2PcInstance player : activeChar.getKnownList().getKnownPlayers().values())
				player.sendPacket(new RelationChanged(activeChar, activeChar.getRelation(player), activeChar.isAutoAttackable(player)));
		}
	}

	// les siege summons sont desummones s'ils quittent la zone
	if (character instanceof L2SiegeSummonInstance)
		((L2SiegeSummonInstance)character).unSummon(((L2SiegeSummonInstance)character).getOwner());
}

@Override
protected void onDieInside(L2Character character) {}

@Override
protected void onReviveInside(L2Character character) {}

public void updateZoneStatusForCharactersInside()
{
	if (_castle.getSiege().getIsInProgress())
	{
		for (L2Character character : _characterList.values())
		{
			try
			{
				onEnter(character);
			}
			catch (NullPointerException e) {}
		}
	}
	else
	{
		for (L2Character character : _characterList.values())
		{
			try
			{
				character.setInsideZone(L2Character.ZONE_PVP, false);
				character.setInsideZone(L2Character.ZONE_SIEGE, false);

				if (character instanceof L2PcInstance)
					((L2PcInstance)character).sendPacket(new SystemMessage(SystemMessageId.LEFT_COMBAT_ZONE));

				if (character instanceof L2SiegeSummonInstance)
					((L2SiegeSummonInstance)character).unSummon(((L2SiegeSummonInstance)character).getOwner());
			}
			catch (NullPointerException e) {}
		}
	}
}

/**
 * Removes all foreigners from the castle
 * @param owningClanId
 */
public void banishForeigners(int owningClanId)
{
	for (L2Character temp : _characterList.values())
	{
		if(!(temp instanceof L2PcInstance)) 
			continue;

		if (((L2PcInstance)temp).getClanId() == owningClanId) 
			continue;

		((L2PcInstance)temp).teleToLocation(MapRegionTable.TeleportWhereType.Faction);
	}
}

/**
 * Sends a message to all players in this zone
 * @param message
 */
public void announceToPlayers(String message)
{
	for (L2Character temp : _characterList.values())
	{
		if (temp instanceof L2PcInstance)
			((L2PcInstance)temp).sendMessage(message);
	}
}

/**
 * Returns all players within this zone
 * @return
 */
public FastList<L2PcInstance> getAllPlayers()
{
	FastList<L2PcInstance> players = new FastList<L2PcInstance>();

	for (L2Character temp : _characterList.values())
	{
		if (temp instanceof L2PcInstance)
			players.add((L2PcInstance)temp);
	}

	return players;
}

/**
 * Get the castles defender spawn
 * @return
 */
public int[] getSpawn()
{
	return _spawnLoc;
}
}

 

TO COMPLETE

 

Sry for french comments, but if you're smart, you can understand it easily.

Good luck :D.

 

Posted

Author requested for lock, but as we can see there is cool "test" so lets leave it opened for a while.

 

Anyway its not thread about iplay etc, so stop useless spam or -karma will be "reward".

Posted

Author requested for lock, but as we can see there is cool "test" so lets leave it opened for a while.

 

Anyway its not thread about iplay etc, so stop useless spam or -karma will be "reward".

 

Yep really those tests are so cool ;d

 

Anyway i'm intersting about your tests, maybe with those tests we can "upgrade our skills". ( i don't speak about all)

 

Btw, i think this "Akken" is pathetic if he requested for lock, maybe he can't do it, i can't see another reason. (only my opinion, maybe he [(~"know"`)] more than all devs from here - i think i exaggerated =]])

Posted

Yup, when I began to expose my case yesterday I thought about a section which could show examples of real/fake problems, with solutions if found/possible.

 

But it would need a complete section, one topic for one case. Currently, it should be the HELP section but... Lol :).

 

----

 

Akken wanted to lock the topic because of the flames (and your post doesn't help :P), he is willing to help people who ask. I ask, so he helps ^^. The fact I do that in public can show all internal problems you can find developing a server, and more, to develop accurate ideas of NEW gameplay (stop your fockin DM / KOTH / Newbie faction) :D.

 

Stop to blame the bear, and check your own developer penis :P. If my contribution can help Akken to show his skills, or better, to see his handle-all-problems level, I'm glad.

 

Stop the hate, and think about my problem :). If he finds it and you no, guess what ? It's you who will be in fault. Akken didn't affirm he was the c00lest dev in the world, he just give a try on your problem. Please understand it that way and stop the war :).

 

And if that can help people to improve their knowledge, or give ideas of mods, "Tout est pour le mieux dans le meilleur des mondes possibles", dixit Voltaire.

 

Back to topic please :). Dunno how it will end, but that's the funny part.

Posted

Yup, when I began to expose my case yesterday I thought about a section which could show examples of real/fake problems, with solutions if found/possible.

 

But it would need a complete section, one topic for one case. Currently, it should be the HELP section but... Lol :).

 

----

 

Akken wanted to lock the topic because of the flames (and your post doesn't help :P), he is willing to help people who ask. I ask, so he helps ^^. The fact I do that in public can show all internal problems you can find developing a server, and more, accurate ideas of gameplay.

 

Stop to blame the bear, and check your own developer penis :P. If my contribution can help Akken to show his skills, or better, to see his handle-all-problems level, I'm glad.

 

Stop the hate, and think about my problem :). If he finds it and you no, guess what ? It's you who will be in fault. Akken didn't affirm he was the c00lest dev in the world, he just give a try on your problem. Please understand it that way and stop the war :).

 

And if that can help people to improve their knowledge, or give ideas of mods, "Tout est pour le mieux dans le meilleur des mondes possibles", dixit Voltaire.

 

Back to topic please :). Dunno how it will end, but that's the funny part.

 

Honest, I admire you anyway i can't say same thing about Akken, 'he tried to show us something false'.

 

I think mod can lock it if i'm right. He (Akken) said on P.M ".. just for the people that want help give a pm".

 

If he said help on P.M i think he wanted post here to say "LOL gj, gratz for your time".

Posted

I will help only the people that aprecciate ok i can say some things i am not able to do them but surely i can help this error of tryskell even if i ask some help from my dev team

Posted

Akken will PM me with solution, if found :).

 

Others can still continue searching why it bugs, and how to fix (via PM to keep it clear and save the test :D).

 

----

 

Personally, I found WHY it bugs, now I have to search HOW to correct it.

 

It's 75% problem / 25% test now ^^.

 

I will give the reason it does the NPE today far evening, like that you could search how to fix the problem tomorrow.

 

All informations about the reason is write in my big post, top of page 2. You don't miss any infos.

 

----

 

Okay, we're in end of afternoon, so here is the trick :

 

The Timer error is related to nothing. This is a false positive. The real problem is of course the line 108, which do a NPE. But why a NPE occurs sometimes ?

 

I said in EXPERIENCES with tests the leader of the castle had to be online for the system works.

 

Let's analyze my code (the onEnter one, not another part as xAdd was right to cry about :D) :

 

@Override
protected void onEnter(L2Character character)
{
	if (_castle.getSiege().getIsInProgress())
	{
		character.setInsideZone(L2Character.ZONE_PVP, true);
		character.setInsideZone(L2Character.ZONE_SIEGE, true);

		if (character instanceof L2PcInstance)
		{
			L2PcInstance activeChar = (L2PcInstance) character;

			activeChar.sendPacket(new SystemMessage(SystemMessageId.ENTERED_COMBAT_ZONE));

Until that part of code, nothing is custom. When you enter in the area, and if a castle siege is in progress in this area, it decides to put you on a pvp zone and a siege zone at the same time. Then it verifies if you're a L2PcInstance (aka a player) and send you a message "You entered in in a combat zone".

			// Mise a jour de la relation (excepte pour GMs et joueurs sans clan)
			if (!activeChar.isGM() && activeChar.getClan() != null)
			{

				//si le possesseur du chateau est different de rien
				if (_castle.getOwnerId() > 0)
				{

This part of code says following orders will be skipped for clanless people and GMs. It adds a check to see if the castle is NPC or players sided. Nothing wrong too.

 

----

 

Now, here is the funny part and where I have problem. To remember you, the purpose of this "custom" area is to make a check on the castle owning faction. The "easiest" way is to find the faction of the leader of the clan which owns the castle where we are. Many infos needed, aren't they ? Let's process :

					//recherche du clan possesseur, et ensuite du clan leader
					L2Clan clanOwner = ClanTable.getInstance().getClan(_castle.getOwnerId());

					if (clanOwner != null)
					{

Will look the clan owner, according to the castleId. Just with that we made the "the clan which owns the castle where we are" part. It returns (from what I rem) the Id of the clanOwner. If the clan owner doesn't exists (case of bugged clans), it will skip the check.

 

This is the part where I got my problem, and the line 108.

						L2PcInstance castleLord = clanOwner.getLeader().getPlayerInstance();

						// si le joueur est d'une faction differente du clan possesseur, 
						// il est affiche en ennemi - sinon il est affiche en defenseur
						if (activeChar.getFactionId() != castleLord.getFactionId())
							activeChar.setSiegeState((byte) 1);
						else
							activeChar.setSiegeState((byte) 2);

This part is the crucial point of course :). It tries to pickup the castle lord from the given clanId. After that, it uses the getPlayerInstance to reach the player's data (in this exemple, getFactionId, which is normally linked to L2PcInstance).

 

So now, the explanation : getPlayerInstance() can't be null. If you check this method (in any chronicle) you will see a check saying if it's null, it should return. In others words, in the actual state, from the moment this player (the leader) isn't online, the check can't be made correctly, as this instance of this player isn't existing right now. So it fock up the whole system :).

 

----

 

Now you understood the problem, how to fix it ? Adding a null check is useless, as it means if the leader is offline, there won't never have siegeState checks. It would resolve the NPE, but not the problem.

 

I think you get it, we have to recreate the check in another format :). The question now is :

 

How to call one L2PcInstance stat (any : faction, but could be class, level, total experience, pvpkills) from a clanId, as it's the only real reliable information we got.

 

The show must go on :)

 

o_o

Posted

Hey i was looking the code again and again i asked hanwik if he see any error and it isnt from l2castlezone so give us the file that the line 108 is  in l2castlezone cant create npe hanwik dont see errors..

Posted

Well I bump the topic with the solution, found the 25th, but I wanted to wait for any other solution which could be lighter.

 

Ofc the NPE was related of my last post. That means I had to change the complete way of thinking, as the code won't offer me a "click & play" solution.

 

I decided to change the question to : make a test on the faction of the clan. Which obviously don't exist before I implement it.

 

I added a new variable in datatable "clan_data", factionId, which is written at the creation of the clan taking the leader.getFactionId().

 

So in "Datatables.ClanTable" I add in the createClan method

clan.setFactionId(player.getFactionId());

 

After that, I just put 2 methods getFactionId and setFactionId on L2Clan.java + variable initialization at top.

    public int getFactionId()
   {
   	return _factionId;
   }

   public void setFactionId(int faction)
   {
   	_factionId = faction;
   }

 

Then, in my L2CastleZone, I modified my check for this new type, as my clan got now a factionId :

if (activeChar.getFactionId() != clanOwner.getFactionId())
      activeChar.setSiegeState((byte) 1);
else
      activeChar.setSiegeState((byte) 2);

 

And finally it works :).

  • 3 weeks later...
Posted

i need some help on a l2j freya server :) pls contact me who wanna help me :D tks alot !!

add me on msn or pm me with yours sniffsniff@hotmail.gr

Guest
This topic is now closed to further replies.

×
×
  • Create New...