Jump to content

Recommended Posts

Posted (edited)

hello all, tonight I decided to share l2 supermonster code adapted acis, 100% tested !

 

so let's start.

 

package net.sf.l2j;

 

config.java

/** Events */  public static final String SMALLEVENTS_FILE = "./config/Events/SmallEvents.properties";
  public static final String OLYMPIAD_FILE = "./config/Events/Olympiad.properties";
  public static final String STRIDER_FILE = "./config/Events/Strider.properties";
  public static final String RANDOMFIGHT_FILE = "./config/Events/RandomFight.properties";
+public static final String SUPERMONSTER_FILE = "./config/Events/SuperMonster.properties";

at line 2599 

aCis_gameserver/java/net/sf/l2j/Config.java

// Super Monster
ExProperties SuperMonster = load(SUPERMONSTER_FILE);
ENABLE_SUPER_MONSTER = SuperMonster.getProperty("EnableSuperMonster", false);
SUPER_MONSTERS = SuperMonster.getProperty("SuperMonsters");


SUPER_MONSTERS_IDS = new ArrayList<>();
String[] arrayOfString1 = SUPER_MONSTERS.split(",");
int i = arrayOfString1.length;
int str1;
for (str1 = 0; str1 < i; str1++)
{
String id = arrayOfString1[str1];
SUPER_MONSTERS_IDS.add(Integer.valueOf(Integer.parseInt(id)));
}
SM_REWARD_PARTY = SuperMonster.getProperty("RewardParty", false);
SM_REWARD_PARTY_NOBLE = SuperMonster.getProperty("GiveNoblesseFullParty", false);
SM_REWARD_PARTY_HERO = SuperMonster.getProperty("GiveHeroFullParty", false);
SM_GIVE_NOBLE = SuperMonster.getProperty("GiveNoblesse", false);
SM_GIVE_HERO = SuperMonster.getProperty("GiveHero", false);
SM_GIVE_ITEM = SuperMonster.getProperty("GiveItemReward", false);


String[] smReward = SuperMonster.getProperty("ItemRewards", "57,100000").split(";");
SM_ITEM_REWARD = new ArrayList<>();
String[] arrayOfString2 = smReward;
str1 = arrayOfString2.length;
for (int id = 0; id < str1; id++)
{
String reward = arrayOfString2[id];


String[] rewardSplit = reward.split(",");
if (rewardSplit.length != 2)
{
_log.warning(StringUtil.concat(new String[]
{
"[Config.load()]: invalid config property -> ItemRewards \"",
reward,
"\""
}));
}
else
{
try
{
SM_ITEM_REWARD.add(new int[]
{


Integer.parseInt(rewardSplit[0]),
Integer.parseInt(rewardSplit[1])
});
}
catch (NumberFormatException nfe)
{
if (!reward.isEmpty())
{
_log.warning(StringUtil.concat(new String[]
{
"[Config.load()]: invalid config property -> ItemRewards \"",
reward,
"\""
}));
}
}
}
}
config file:
 
#=============================================================
# Super Monster
#=============================================================
# This are special monsters that are having special reward features when get killed.
# The list can contain L2Monster, L2Raid, L2GrandBoss instances!
# The script can be edited from data/scripts/events/SuperMonster/SuperMonster.java
# Enable The Super Monster ?
EnableSuperMonster = False

# Monsters ids.
# WARNING all the features will be available for the configured monsters!
# Format monsterId,monsterId,monsterId
SuperMonsters = 0

# Give reward for the full party?
RewardParty = False

# Give noblesse to the full party?
GiveNoblesseFullParty = False

# Give hero status to the full party? (Untill logout)
GiveHeroFullParty = False

# Give noblesse status for the killer?
GiveNoblesse = False

# Give hero status to the killer? (Untill logout)
GiveHero = False

# Give item reward?
# This is for both full party (if enabled) and killer.
GiveItemReward = False

# Items for reward
# Format itemId,amount;itemId,amount;itemId,amount
ItemRewards = 57,100000

script.cfg import:

events/SuperMonster/SuperMonster.java

datapack:

aCis_datapack/data/scripts/events/SuperMonster/SuperMonster.java

package events.SuperMonster;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.datatables.ItemTable;
import net.sf.l2j.gameserver.model.actor.L2Npc;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.itemcontainer.PcInventory;
import net.sf.l2j.gameserver.model.quest.Quest;
import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate;

public class SuperMonster extends Quest
{
	public SuperMonster()
	{
		super(-1, "SuperMonster", "custom");
		
		if (Config.ENABLE_SUPER_MONSTER)
		{
			for (int mobs : Config.SUPER_MONSTERS_IDS)
				addKillId(mobs);
		}
	}
	
	@Override
	public String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
	{
		if (Config.SM_REWARD_PARTY && player.getParty() != null)
		{
			for (L2PcInstance members : player.getParty().getPartyMembers())
			{
				members.sendMessage("Congratulations! You killed The SuperMonster!");
				
				if (Config.SM_GIVE_ITEM)
					rewardWinner(members);
				
				if (Config.SM_REWARD_PARTY_HERO && !player.isHero())
				{
					members.setHero(true);
					members.sendMessage("You are now hero untill relogin!");
				}
				
				if (Config.SM_REWARD_PARTY_NOBLE && !members.isNoble())
				{
					members.setNoble(true, true);
					members.sendMessage("You have become noblesse!");
				}
				
				members.broadcastUserInfo();
			}
		}
		else
		{
			player.sendMessage("Congratulations! You killed The SuperMonster!");
			
			if (Config.SM_GIVE_ITEM)
				rewardWinner(player);
			
			if (Config.SM_GIVE_HERO && !player.isHero())
			{
				player.setHero(true);
			}
			
			if (Config.SM_GIVE_NOBLE && !player.isNoble())
			{
				player.setNoble(true, true);
			}
			
			player.broadcastUserInfo();
		}
		
		return null;
	}
	
	static void rewardWinner(L2PcInstance player)
	{
		// Check for nullpointer
		if (player == null)
			return;
		
		// Iterate over all rewards
		for (int[] reward : Config.SM_ITEM_REWARD)
		{
			PcInventory inv = player.getInventory();
			
			// Check for stackable item, non stackabe items need to be added one by one
			if (ItemTable.getInstance().createDummyItem(reward[0]).isStackable())
			{
				inv.addItem("SuperMonster", reward[0], reward[1], player, player);
			}
			else
			{
				for (int i = 0; i < reward[1]; ++i)
				{
					inv.addItem("SuperMonster", reward[0], 1, player, player);
				}
			}
		}
		
		StatusUpdate statusUpdate = new StatusUpdate(player);
		statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
		player.sendPacket(statusUpdate);
	}
	
	public static void main(String args[])
	{
		new SuperMonster();
	}
}
Edited by xAddytzu
Posted (edited)
EnableSuperMonster = False

SuperMonsters = 0

configs are redundant, if id is 0 it should be considered as false (otherwise if you put true you register script for id 0 which doesn't exist). Simply check id array length > 0.

 


 

I'm not sure if hero status is saved on database using it that way, for noble it's normally fine.

 


 

It's old writting style, scripts are on core now and main method is dropped.

 


 

Finally you should better put the whole content of

			player.sendMessage("Congratulations! You killed The SuperMonster!");
			
			if (Config.SM_GIVE_ITEM)
				rewardWinner(player);
			
			if (Config.SM_GIVE_HERO && !player.isHero())
			{
				player.setHero(true);
			}
			
			if (Config.SM_GIVE_NOBLE && !player.isNoble())
			{
				player.setNoble(true, true);
			}
			
			player.broadcastUserInfo();

into rewardWinner because it's redundant and you make 0 special check on party more than on single case. So L2PcInstance player is fine in any case. Even worst, you got messages only if the guy is on party not if he is solo because you badly copied paste without verifying if content was 1:1 copy from team case.

 


 

Last and not least you normally don't need to check null case.

Edited by Tryskell

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Posts

    • And Discord: https://discord.gg/3aYqWNqb
    • Ofc: https://discord.gg/3aYqWNqb
    • You can find some H5 skins shared in old L2 modding Discords, but most of the higher‑quality ones are either paid or come bundled with full client edits. I usually mix in commissioned work and whatever I can patch myself. On a side note, I fund a lot of these commissions by selling off game items through instant sell cs2 skins, which has been a quick way for me to get some cash for projects.
    • There is no need for gRPC in this case, even tho originally it was gRPC based but since we don't need it to be bi-directional, we switched to simple http requests for the web calls and SSEs for the data streamed from the server. There are distributed locks in place to precent race conditions between actions that can happen between multiple web instances and the server.   Local models can also be slow depending on the model, and most external models can actually be faster than local ones if you use Flash 2.5 or something along those lines. I am running on 512GB of Unified Memory on my Mac Studio M3 Ultra so the speed of the local model for a small model is pretty good but I tested it with Gemini too and it works equally as fast and in some cases faster. The way it works is that I'm using pgvector (one of the benefits of moving to Postgres) to search the data and see what the player can see etc and there is some batching of the next few actions for 2-4 seconds for the user until the next LLM request fires. The batching also includes branching on logic so if they for example fall under some HP they will move to kiting instead of attacking or maybe they heal etc.   Everything is authed and permission-based. The server and the backend of the frontend have secure communication between them, either with a symmetric key (not recommended for production) or a certificate (the recommended way), so there is no worry. It's all tied to the account's access level, etc., so nobody can make an action that they normally wouldn't be allowed to do. Even the MCP is token-based, and there are prompt injection protections in place. The MCP is audited, and every mutation needs confirmation. The admin area is only accessible to the admin account anyway so normal users can't access it.  
  • Topics

×
×
  • Create New...

Important Information

This community uses essential cookies to function properly. Non-essential cookies and third-party services are used only with your consent. Read our Privacy Policy and We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue..