[phpBB Debug] PHP Warning: in file [ROOT]/phpbb/session.php on line 583: sizeof(): Parameter must be an array or an object that implements Countable
[phpBB Debug] PHP Warning: in file [ROOT]/phpbb/session.php on line 639: sizeof(): Parameter must be an array or an object that implements Countable
L2J Server • Help Fixing Swoop Cannon Skills.
Page 1 of 1

Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 2:06 am
by RogerSmith
Referring to this topic viewtopic.php?f=94&t=30429&start=105

Here are the changes I carried out in order to attempt to make the swoop cannon skills work (very crude, not elegant):

1) Added Artillery.java, which collects target list within getAffectLimit radius around a point that is getCastRange distance away from activeChar, in the direction he is facing. Primarily uses same trigonometry calculations as Warp/Blink. Appropriate ENUM - ARTILLERY is created as well.

Code: Select all

/*
 * Copyright (C) 2004-2015 L2J DataPack
 * 
 * This file is part of L2J DataPack.
 * 
 * L2J DataPack is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J DataPack is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package handlers.targethandlers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.handler.ITargetTypeHandler;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.util.Util;

/**
 * @author UnAfraid (Area) This is a directional area attack target handler - a
 *         circular area offset from the caster is affected. Intended for Swoop
 *         Cannon skills 5110 5111
 */
public class Artillery implements ITargetTypeHandler {
    @Override
    public L2Object[] getTargetList(Skill skill, L2Character activeChar,
	    boolean onlyFirst, L2Character target) {
	List<L2Character> targetList = new ArrayList<>();
	final double angle = Util.convertHeadingToDegree(activeChar
		.getHeading());
	final double radian = Math.toRadians(angle);
	final double range = skill.getCastRange();
	final int x1 = (int) (Math.cos(Math.PI + radian) * range);
	final int y1 = (int) (Math.sin(Math.PI + radian) * range);

	final boolean srcInArena = (activeChar.isInsideZone(ZoneId.PVP) && !activeChar
		.isInsideZone(ZoneId.SIEGE));

	int originx = activeChar.getX() + x1;
	int originy = activeChar.getY() + y1;
	int originz = GeoData.getInstance().getNearestZ(originx, originy,
		activeChar.getZ());

	Location origin = new Location(originz, originz, originz);
	target = activeChar; // dummy?

	int maxTargets = skill.getAffectLimit();
	final Collection<L2Character> objs = activeChar.getKnownList()
		.getKnownCharacters();
	for (L2Character obj : objs) {
	    if (!(obj.isAttackable() || obj.isPlayable())) {
		continue;
	    }

	    if (skill.getAffectRange() > Util.calculateDistance(origin,
		    obj.getLocation(), true, false)) {
		if (!Skill.checkForAreaOffensiveSkills(activeChar, obj, skill,
			srcInArena)) {
		    continue;
		}

		if ((maxTargets > 0) && (targetList.size() >= maxTargets)) {
		    break;
		}

		targetList.add(obj);
	    }
	}

	if (targetList.isEmpty()) {
	    return EMPTY_TARGET_LIST;
	}

	return targetList.toArray(new L2Character[targetList.size()]);
    }

    @Override
    public Enum<L2TargetType> getTargetType() {
	return L2TargetType.ARTILLERY;
    }
}
2) Addition to MagicSkillUse.java - another method, with slightly different arguments, to further consistent info as per linked topic (above), i.e. writeLoc(_activeChar) is same coordinates as writeLoc(_target), and writeH(_groundLocations) only sends 1 coordinate, because the array only consists of aimLoc variable and has size 1.

Code: Select all

/*
 * Copyright (C) 2004-2015 L2J Server
 * 
 * This file is part of L2J Server.
 * 
 * L2J Server is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J Server is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.gameserver.network.serverpackets;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.interfaces.IPositionable;

/**
 * MagicSkillUse server packet implementation.
 * 
 * @author UnAfraid, NosBit
 */
public final class MagicSkillUse extends L2GameServerPacket {
	private final int _skillId;
	private final int _skillLevel;
	private final int _hitTime;
	private final int _reuseDelay;
	private final L2Character _activeChar;
	private final L2Character _target;
	private final List<Integer> _unknown = Collections.emptyList();
	private final List<Location> _groundLocations;

	public MagicSkillUse(L2Character cha, L2Character target, int skillId,
			int skillLevel, int hitTime, int reuseDelay) {
		_activeChar = cha;
		_target = target;
		_skillId = skillId;
		_skillLevel = skillLevel;
		_hitTime = hitTime;
		_reuseDelay = reuseDelay;
		_groundLocations = cha.isPlayer()
				&& (cha.getActingPlayer().getCurrentSkillWorldPosition() != null) ? Arrays
				.asList(cha.getActingPlayer().getCurrentSkillWorldPosition())
				: Collections.<Location> emptyList();
	}

	// used in L2Character when skill.getTargetType() == L2TargetType.ARTILLERY
	public MagicSkillUse(L2Character cha, int skillId, int skillLevel,
			int hitTime, int reuseDelay, Location aimLoc) {
		_activeChar = cha;
		_target = cha;
		_skillId = skillId;
		_skillLevel = skillLevel;
		_hitTime = hitTime;
		_reuseDelay = reuseDelay;
		_groundLocations = Arrays.asList(aimLoc); // just one location
	}

	public MagicSkillUse(L2Character cha, int skillId, int skillLevel,
			int hitTime, int reuseDelay) {
		this(cha, cha, skillId, skillLevel, hitTime, reuseDelay);
	}

	@Override
	protected final void writeImpl() {
		writeC(0x48);
		writeD(_activeChar.getObjectId());
		writeD(_target.getObjectId());
		writeD(_skillId);
		writeD(_skillLevel);
		writeD(_hitTime);
		writeD(_reuseDelay);
		writeLoc(_activeChar);
		writeH(_unknown.size()); // TODO: Implement me!
		for (int unknown : _unknown) {
			writeH(unknown);
		}
		writeH(_groundLocations.size());
		for (IPositionable target : _groundLocations) {
			writeLoc(target);
		}
		writeLoc(_target);
	}
}
3) Changes to RequestActionUse.java to allow skill IDs 5110 and 5111 to be casted, nothing special.

Code: Select all

		case 1039: // Swoop Cannon - Cannon Fodder
			useSkill(5110, false);
			break;
		case 1040: // Swoop Cannon - Big Bang
			useSkill(5111, false);
			break;
4) Additions to L2Character.java - new function getAimPoint() for recalculation of the destination point of the skill (because I cannot pass along this Location through Artillery.java, since it returns type L2Object), as well as an addition of the new version MagicSkillUse packet IF the skillTargetType is ARTILLERY.

Code: Select all

// get the point of destination of projectile for Artillery skills. Used
    // primarily for 5110 and 5111
    public Location getAimPoint(Skill skill, L2Character activeChar) {

	final double angle = Util.convertHeadingToDegree(activeChar
		.getHeading());
	final double radian = Math.toRadians(angle);
	final double range = skill.getCastRange();
	final int x1 = (int) (Math.cos(Math.PI + radian) * range);
	final int y1 = (int) (Math.sin(Math.PI + radian) * range);

	int originx = activeChar.getX() + x1;
	int originy = activeChar.getY() + y1;
	int originz = GeoData.getInstance().getNearestZ(originx, originy,
		activeChar.getZ());
	Location aimPoint = new Location(originz, originz, originz);
	return aimPoint;
    }
AND in beginCast() of L2Character.java new MagicSkillUse

Code: Select all

// Send a Server->Client packet MagicSkillUser with target, displayId,
	// level, skillTime, reuseDelay
	// to the L2Character AND to all L2PcInstance in the _KnownPlayers of
	// the L2Character

	// If the Skill is Artillery TargetType, used different MagicSkillUse
	// that gathers the location of projectile destination.
	if (skill.getTargetType() == L2TargetType.ARTILLERY) {
	    final Location aimLoc = getAimPoint(skill, this);
	    broadcastPacket(new MagicSkillUse(this, skill.getDisplayId(),
		    skill.getDisplayLevel(), skillTime, reuseDelay, aimLoc));
	} else {
	    broadcastPacket(new MagicSkillUse(this, target,
		    skill.getDisplayId(), skill.getDisplayLevel(), skillTime,
		    reuseDelay));
	}
5)All the accomodating XML changes to skill - removal of TEMP HACK fixes to target types and locations, commented out some requirements (itemID use, etc) and changed targetype to ARTILLERY. Pretty basic. I only use 5110 (Cannon Fodder) for testing.

Code: Select all

<skill id="5110" levels="1" name="Cannon Fodder">
		<!-- Confirmed CT2.5 -->
		<!-- Swoop Cannon Skill -->
		<set name="affectRange" val="200" />
		<set name="castRange" val="1600" />
		<set name="effectPoint" val="-100" />
		<set name="effectRange" val="1600" />
		<set name="hitTime" val="15000" />
		<!-- <set name="itemConsumeCount" val="4" /> -->
		<!-- <set name="itemConsumeId" val="8872" /> -->
		<set name="magicLvl" val="70" />
		<set name="operateType" val="A1" />
		<set name="power" val="68" />
		<set name="reuseDelay" val="10500" />
		<set name="rideState" val="NONE" />
		<set name="targetType" val="ARTILLERY" />
		<cond msgId="113" addName="1">
			<not>
				<player insideZoneId="51101, 51102, 51103, 51104, 51105, 51106, 51108, 51108, 51109" />
			</not>
		</cond>
		<for>
			<effect name="PhysicalAttack" />
		</for>
	</skill>


So, whats the result?
I've had no compile issues or problems, so that must count for something :lol: .
Problem is, when I try to use the abilities ingame, chatlog gives the typical "Target cannot be found" or something message.
Is this because Artillery.java has a clause

Code: Select all

 if (targetList.isEmpty()) {
	    return EMPTY_TARGET_LIST;
???
What else did I miss?
Did I use the packet correctly?[/b]

Re: Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 2:03 pm
by RogerSmith
I guess one obvious issue to explore is whether or not the target pulled is still coming from owner,
since 5110 and 5111 are casted by a servitor, so then the owner/master targets will be used.

Re: Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 3:12 pm
by RogerSmith
Ok further tests:

I added the skills to my char instead of summon, incase the targets were being used by master, not direction of summon heading.

When targeting castle gate - invalid target message (as expected)
When selecting self or summon - "your target cannot be found"
When selecting mobs or attackables - "Target type of skill is not currently handled"
I checked cmd .bat output, and it says 33 target handlers loaded, which is exactly the amount of handlers there are if excluding the new Artillery.

Re: Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 5:05 pm
by RogerSmith
Ok, so I was pretty dumb - added ENUM but forgot to register in masterhandler. Did that, now console says it loaded 34 targethandlers, as expected.

But when I use the skill I still get the same errors. At least now I get some output from console.
Image

EDIT: More stupid stuff... Have no geodata loaded.
ARE YOU NOT ENTERTAINED? :kappa:

Re: Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 7:55 pm
by RogerSmith
MORE PROGRESS
I removed the Geodata Z, put temp activeChar Z.

And it works! Problem is, can't be cast on oneself without forced attack, and when targeting mobs it behaves weird, I guess because of AI of char.
Sometimes it deals damage in a different area. So, if you run, it will deal damage in direction you run, but cast in direction target is (mob), i guess this is where the AI changes char heading on skillCast.

Sometimes it randomly moves char... to get in range or something, very weird.

Also doesn't detonate the animation fireball, just disappear when reach the Z coordinate.

Also doesn't work when Swoop Cannon casts it :( Keeps saying "target not found"

Re: Help Fixing Swoop Cannon Skills.

Posted: Wed Nov 04, 2015 10:39 pm
by RogerSmith
MORE PROGRESS

I've managed to make it work when summon casts it. I still have to select target, but it works if I use self or summon as target and used force attack (ctrl), which then causes it to fire in the facing direction.
Still some problems:
1) Even if the target is owner or servitor, it won't cast skill unless there are valid Attackable targets in the effect area. Need some sort of exclusion for EMPTY_TARGET_LIST to force cast even if no attackable targets?
2) AI forces either player char or servitor to change heading in the direction of the attackable target when cast and also approach to get in range. Typically closest attackable.
L2Character had a setHeading and broadcast packet ExRotation in beginCast() if the target was an attackable. I don't know why this persists when I have already changed the target to be caster or activeChar.
I added

Code: Select all

if ((target != this)
		&& (skill.getTargetType() != L2TargetType.ARTILLERY)) {
	    setHeading(Util.calculateHeadingFrom(this, target));
	    broadcastPacket(new ExRotation(getObjectId(), getHeading()));
	}
to see if it helps, not noticed any difference.
3) Animation still doesn't show explosion. Bad MSU send I guess? SaveGame's packet info mentioned "~~~end of loop~~~", I assume this causes the animation to run final frames?

Overall, somewhat happy. Slowly making it work :D

EDIT: HERE ARE SOME SCREENSHOTS

http://i.imgur.com/Zq7Y9oU.jpg
http://i.imgur.com/vCyYTl0.jpg
http://i.imgur.com/nKDkLR5.jpg

Re: Help Fixing Swoop Cannon Skills.

Posted: Thu Nov 05, 2015 11:38 am
by Pandragon
I would recommend to make a diff patch and share it on git.
It would make easier for people to test or maybe help you on this.

Re: Help Fixing Swoop Cannon Skills.

Posted: Thu Nov 05, 2015 1:02 pm
by RogerSmith
Pandragon wrote:I would recommend to make a diff patch and share it on git.
It would make easier for people to test or maybe help you on this.
Yeah I haven't exactly kept my source up-to date, and I'm not familiar with how to make patches.
My formatting got screwed up by eclipse, and some line numbers to match up.

Re: Help Fixing Swoop Cannon Skills.

Posted: Sun Nov 08, 2015 4:43 pm
by RogerSmith
Pandragon wrote:I would recommend to make a diff patch and share it on git.
It would make easier for people to test or maybe help you on this.
viewtopic.php?f=69&p=190598#p190598
I put the patches here.

Re: Help Fixing Swoop Cannon Skills.

Posted: Mon Jul 11, 2016 5:20 am
by soviet2007
RogerSmith wrote: 3) Animation still doesn't show explosion. Bad MSU send I guess? SaveGame's packet info mentioned "~~~end of loop~~~", I assume this causes the animation to run final frames?
The explosion impact effect is visible, but you look when the Swoop Cannon cast the fireball: the Explosion impact effect is visible/show in the Swoop Cannon (Summon) when shoot the fireball.

These effect must be where in "aimLoc" point (target), not in activeChar as it is happening now.

I hope I've helped. Sorry for my bad english.

Re: Help Fixing Swoop Cannon Skills.

Posted: Tue Jul 12, 2016 5:07 am
by maneco2
RogerSmith wrote:

Code: Select all

<set name="hitTime" val="15000" />
retail hitTime is 10 sec Swoop Cannon Skill 5110

Re: Help Fixing Swoop Cannon Skills.

Posted: Mon Jul 25, 2016 8:22 am
by RogerSmith
soviet2007 wrote:
RogerSmith wrote: 3) Animation still doesn't show explosion. Bad MSU send I guess? SaveGame's packet info mentioned "~~~end of loop~~~", I assume this causes the animation to run final frames?
The explosion impact effect is visible, but you look when the Swoop Cannon cast the fireball: the Explosion impact effect is visible/show in the Swoop Cannon (Summon) when shoot the fireball.

These effect must be where in "aimLoc" point (target), not in activeChar as it is happening now.

I hope I've helped. Sorry for my bad english.
THere are 2 explosion effects on this skill, the smoke that covers the summon and then the detonation when it lands.
I am sure the correct MSU construction is was sent, as advised by SaveGame (i think).

I believe the animation fault is due to the global bug with animations here https://bitbucket.org/l2jserver/l2j_ser ... ion-skills
maneco2 wrote:
RogerSmith wrote:

Code: Select all

<set name="hitTime" val="15000" />
retail hitTime is 10 sec Swoop Cannon Skill 5110
I know. That's beyond the point.