Compare commits
158 Commits
v1.0.0
...
feat/postg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9d2da1f35 | ||
|
|
9101cd189c | ||
|
|
196e3efec7 | ||
|
|
7adce5e2af | ||
|
|
c9aa049874 | ||
|
|
58d6603946 | ||
|
|
bfd9f68805 | ||
|
|
44c2b77595 | ||
|
|
5148d76f9f | ||
|
|
45bfc395be | ||
|
|
8052814028 | ||
|
|
e4430a3860 | ||
|
|
f2b8ced976 | ||
|
|
a4f8086da1 | ||
|
|
e295a24d98 | ||
|
|
64f99a29c6 | ||
|
|
40425ac4e1 | ||
|
|
2b6ef9feb5 | ||
|
|
e38344ceae | ||
|
|
5d81e05458 | ||
|
|
af02f8b744 | ||
|
|
7661cd0f75 | ||
|
|
167937bb88 | ||
|
|
988d898d6f | ||
|
|
e35060da2a | ||
|
|
c0ee1f8ffe | ||
|
|
99006c2dda | ||
|
|
f142e21bbb | ||
|
|
1c6245fa6c | ||
|
|
a307afae3c | ||
|
|
50524a7740 | ||
|
|
d00b4ed678 | ||
|
|
b45620154c | ||
|
|
5450c29178 | ||
|
|
fa666c98e6 | ||
|
|
902f1a154e | ||
|
|
4e1aa1eb1a | ||
|
|
a580e44bc9 | ||
|
|
da4a467453 | ||
|
|
0bb14e415e | ||
|
|
0a8591aa08 | ||
|
|
813768ec47 | ||
|
|
5595f5763b | ||
|
|
1be775394e | ||
|
|
55c9d4abbb | ||
|
|
93bbe868cb | ||
|
|
ec39f0fa06 | ||
|
|
439280947c | ||
|
|
5abae50be5 | ||
|
|
082e0c0486 | ||
|
|
2044166967 | ||
|
|
f33d4fbc1c | ||
|
|
0f2ef341ce | ||
|
|
c7f835da0d | ||
|
|
647e67f6e8 | ||
|
|
bf9c02bc16 | ||
|
|
1d5c26e67c | ||
|
|
b85233359f | ||
|
|
7335914695 | ||
|
|
b4e673baab | ||
|
|
767c4402e7 | ||
|
|
a9967d53b1 | ||
|
|
00fc3ed1a1 | ||
|
|
98d76ad45e | ||
|
|
0c9643fd7e | ||
|
|
ce5dee39ae | ||
|
|
e57d2a9ee2 | ||
|
|
f827e23ccc | ||
|
|
f8726640c3 | ||
|
|
4778482cdd | ||
|
|
7297cd09b6 | ||
|
|
08eeeb54dc | ||
|
|
abbec8120e | ||
|
|
23a8a33e5f | ||
|
|
758347f7bc | ||
|
|
1b6c0167de | ||
|
|
8bce0922d9 | ||
|
|
f41268cdde | ||
|
|
719b079cbc | ||
|
|
7bd5fa387d | ||
|
|
09a75e89c9 | ||
|
|
559fe2d550 | ||
|
|
a7d03cf8c0 | ||
|
|
033d91ed71 | ||
|
|
392a350eab | ||
|
|
f33df59f49 | ||
|
|
cd75e85bec | ||
|
|
cb31121fe7 | ||
|
|
d5682a5f65 | ||
|
|
f6d06ba82a | ||
|
|
bbee8d7caa | ||
|
|
5b5888cf65 | ||
|
|
48d9aaa871 | ||
|
|
f44083aeba | ||
|
|
810dbcc1d7 | ||
|
|
449ab01bc2 | ||
|
|
2686b2b02d | ||
|
|
e9819fac87 | ||
|
|
4e39142fb3 | ||
|
|
e52f646558 | ||
|
|
02d4ff524a | ||
|
|
05b7ec77c8 | ||
|
|
f6aa8ceba6 | ||
|
|
b3ec325e95 | ||
|
|
e31465a1b5 | ||
|
|
84ad5b4db8 | ||
|
|
855b66c459 | ||
|
|
46f767d79c | ||
|
|
785f74ed21 | ||
|
|
699da37f06 | ||
|
|
c3badba73b | ||
|
|
5f0e9a355b | ||
|
|
39d759595d | ||
|
|
fe9dd75a23 | ||
|
|
2139147dcd | ||
|
|
c71ca7f4d5 | ||
|
|
705efb4340 | ||
|
|
ec1450cec1 | ||
|
|
290bf78db3 | ||
|
|
02c1fe46f3 | ||
|
|
7315dd80fc | ||
|
|
a496c0f2b4 | ||
|
|
ab0239ba84 | ||
|
|
f2f3abdb32 | ||
|
|
5a35b55d7a | ||
|
|
02aa4a237f | ||
|
|
cc88d382e6 | ||
|
|
a95fa2efc1 | ||
|
|
45e2b93724 | ||
|
|
fa3481fa99 | ||
|
|
eed94ec34a | ||
|
|
a6a7a26ebc | ||
|
|
7ed7b25268 | ||
|
|
703ae30a27 | ||
|
|
6bf8785f22 | ||
|
|
53768555a2 | ||
|
|
a70f4e303d | ||
|
|
7a848cf6a1 | ||
|
|
0be48568d7 | ||
|
|
1fd0963401 | ||
|
|
d2d4b442d2 | ||
|
|
9d6574d3ba | ||
|
|
f2ca67aba4 | ||
|
|
6073b20d65 | ||
|
|
b329709776 | ||
|
|
932f9fc443 | ||
|
|
c0c0a2d2d9 | ||
|
|
5cecb7adb6 | ||
|
|
26357a8d7b | ||
|
|
9819fd5bb1 | ||
|
|
adbdb89917 | ||
|
|
b7c79800eb | ||
|
|
55e1f65bbd | ||
|
|
d018b0f5e5 | ||
|
|
12745c207d | ||
|
|
f6f3c9c3e3 | ||
|
|
8bb825ef02 | ||
|
|
f1192279bf |
22
config.yaml
22
config.yaml
@@ -165,6 +165,14 @@ server:
|
||||
DB_PASS: ""
|
||||
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
||||
|
||||
PG_DB_URL: "jdbc:postgresql://localhost:5432/cosmic"
|
||||
PG_DB_SCHEMA: "cosmic"
|
||||
PG_DB_ADMIN_USERNAME: "cosmic_admin"
|
||||
PG_DB_ADMIN_PASSWORD: "redsnailshell"
|
||||
PG_DB_USERNAME: "cosmic_server"
|
||||
PG_DB_PASSWORD: "bluesnailshell"
|
||||
PG_DB_CLEAN: false # !!! WARNING !!! Deletes the entire database - starts from scratch.
|
||||
|
||||
#Login Configuration
|
||||
WORLDS: 1 #Initial number of worlds on the server.
|
||||
WLDLIST_SIZE: 21 #Max possible worlds on the server.
|
||||
@@ -185,7 +193,6 @@ server:
|
||||
BYPASS_PIN_EXPIRATION: 15 #Enables PIN bypass, which will remain active for that account by that client machine for N minutes. Set 0 to disable.
|
||||
|
||||
AUTOMATIC_REGISTER: true #Automatically register players when they login with a nonexistent username.
|
||||
BCRYPT_MIGRATION: true #Performs a migration from old SHA-1 and SHA-512 password to bcrypt.
|
||||
COLLECTIVE_CHARSLOT: false #Available character slots are contabilized globally rather than per world server.
|
||||
DETERRED_MULTICLIENT: false #Enables detection of multi-client and suspicious remote IP on the login system.
|
||||
#Besides blocking logging in with several client sessions on the same machine, this also blocks suspicious login attempts for players that tries to login on an account using several diferent remote addresses.
|
||||
@@ -234,7 +241,6 @@ server:
|
||||
USE_AUTOBAN: false #Commands the server to detect infractors automatically.
|
||||
USE_AUTOBAN_LOG: true #Log autoban related messages. Still logs even with USE_AUTOBAN disabled.
|
||||
USE_EXP_GAIN_LOG: false #Logs characters exp gains; logs world rate & coupon exp, total gained exp, and current exp, level can be calculated from "ExpTable".
|
||||
USE_AUTOSAVE: true #Enables server autosaving feature (saves characters to DB each 1 hour).
|
||||
USE_SERVER_AUTOASSIGNER: false #HeavenMS-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
|
||||
USE_REFRESH_RANK_MOVE: true
|
||||
USE_ENFORCE_ADMIN_ACCOUNT: false #Forces accounts having GM characters to be treated as a "GM account" by the client (localhost). Some of the GM account perks is the ability to FLY, but unable to TRADE.
|
||||
@@ -246,7 +252,6 @@ server:
|
||||
USE_ENFORCE_ITEM_SUGGESTION: false #Forces the Owl of Minerva and the Cash Shop to always display the defined item array instead of those featured by the players.
|
||||
USE_ENFORCE_UNMERCHABLE_CASH: true #Forces players to not sell CASH items via merchants, drops of it disappears.
|
||||
USE_ENFORCE_UNMERCHABLE_PET: true #Forces players to not sell pets via merchants, drops of it disappears. (since non-named pets gets dirty name and other possible DB-related issues)
|
||||
USE_ENFORCE_MERCHANT_SAVE: true #Forces automatic DB save on merchant owners, at every item movement on shop.
|
||||
USE_ENFORCE_MDOOR_POSITION: false #Forces mystic door to be spawned near spawnpoints.
|
||||
USE_SPAWN_CLEAN_MDOOR: false #Makes mystic doors to be spawned without deploy animation. This clears disconnecting issues that may happen when trying to cancel doors a couple seconds after deployment.
|
||||
USE_SPAWN_RELEVANT_LOOT: true #Forces to only spawn loots that are collectable by the player or any of their party members.
|
||||
@@ -283,10 +288,6 @@ server:
|
||||
USE_MAKER_PERMISSIVE_ATKUP: false #Allows players to use attack-based strengthening gems on non-weapon items.
|
||||
USE_MAKER_FEE_HEURISTICS: true #Apply compiled values for stimulants and reagents into the Maker fee calculations (max error revolves around 50k mesos). Set false to use basic constant values instead (results are never higher than requested by the client-side).
|
||||
|
||||
#Custom Configuration
|
||||
USE_ENABLE_CUSTOM_NPC_SCRIPT: false #Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay) or quests.
|
||||
USE_STARTER_MERGE: false #Allows any players to use the Equipment Merge custom mechanic (as opposed to the high-level, Maker lv3 requisites).
|
||||
|
||||
#Commands Configuration
|
||||
BLOCK_GENERATE_CASH_ITEM: false #Prevents creation of cash items with the item/drop command.
|
||||
USE_WHOLE_SERVER_RANKING: false #Enables a ranking pool made from every character registered on the server for the "ranks" command, instead of separated by worlds.
|
||||
@@ -359,7 +360,6 @@ server:
|
||||
USE_FULL_HOLY_SYMBOL: false #Holy symbol doesn't require EXP sharers to work in full.
|
||||
|
||||
#Character Configuration
|
||||
USE_ADD_SLOTS_BY_LEVEL: false #Slots are added each 20 levels.
|
||||
USE_ADD_RATES_BY_LEVEL: false #Rates are added each 20 levels.
|
||||
USE_STACK_COUPON_RATES: false #Multiple coupons effects builds up together.
|
||||
USE_PERFECT_PITCH: false #For lvl 30 or above, each lvlup grants player 1 perfect pitch.
|
||||
@@ -367,12 +367,6 @@ server:
|
||||
#Quest Configuration
|
||||
USE_QUEST_RATE: false #Exp/Meso gained by quests uses fixed server exp/meso rate times quest rate as multiplier, instead of player rates.
|
||||
|
||||
#Quest Points Configuration
|
||||
QUEST_POINT_REPEATABLE_INTERVAL: 25 #Minimum interval between repeatable quest completions for quest points to be awarded.
|
||||
QUEST_POINT_REQUIREMENT: 0 #Exchange factor between N quest points to +1 fame, set 0 to disable the entire quest point mechanism.
|
||||
QUEST_POINT_PER_QUEST_COMPLETE: 0 #Each completed quest awards N quest points, set 0 to disable.
|
||||
QUEST_POINT_PER_EVENT_CLEAR: 0 #Each completed event instance awards N quest points, set 0 to disable.
|
||||
|
||||
#Guild Configuration
|
||||
CREATE_GUILD_MIN_PARTNERS: 6 #Minimum number of members on Guild Headquarters to establish a new guild.
|
||||
CREATE_GUILD_COST: 1500000
|
||||
|
||||
2
database/.gitignore
vendored
Normal file
2
database/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
docker-db-data/*
|
||||
docker-pg-db-data/*
|
||||
3
database/docker-db-data/.gitignore
vendored
3
database/docker-db-data/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
*
|
||||
*/
|
||||
!.gitignore
|
||||
3
database/postgres-scripts/create-db-and-admin-user.sql
Normal file
3
database/postgres-scripts/create-db-and-admin-user.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
CREATE DATABASE cosmic;
|
||||
CREATE USER cosmic_admin WITH CREATEROLE ENCRYPTED PASSWORD 'redsnailshell';
|
||||
GRANT ALL PRIVILEGES ON DATABASE cosmic TO cosmic_admin;
|
||||
1
database/sql/1-db_database.sql
Normal file
1
database/sql/1-db_database.sql
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -4,6 +4,7 @@ services:
|
||||
build: .
|
||||
depends_on:
|
||||
- db
|
||||
- pg_db
|
||||
ports:
|
||||
# Login server
|
||||
- "8484:8484"
|
||||
@@ -19,7 +20,8 @@ services:
|
||||
- ./wz:/opt/server/wz
|
||||
environment:
|
||||
DB_HOST: "db" ## Remember if this is present it will OVERRIDE the host in the config.yaml, if you put here anything other than db, you'll need to change the config.yaml jdbc string to port 3307, and not port 3306
|
||||
|
||||
PG_DB_HOST: "pg_db"
|
||||
|
||||
db:
|
||||
image: mysql:8.4.0
|
||||
environment:
|
||||
@@ -30,3 +32,13 @@ services:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- ./database/docker-db-data:/var/lib/mysql
|
||||
|
||||
pg_db:
|
||||
image: postgres:15.0
|
||||
ports:
|
||||
- "5433:5432"
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- ./database/docker-pg-db-data:/var/lib/postgresql/data
|
||||
- ./database/postgres-scripts:/docker-entrypoint-initdb.d
|
||||
|
||||
45
pom.xml
45
pom.xml
@@ -69,6 +69,11 @@
|
||||
<liquibase-core.version>4.32.0</liquibase-core.version> <!-- Database migrations -->
|
||||
<junit.version>5.13.1</junit.version> <!-- Unit test -->
|
||||
<mockito.version>5.18.0</mockito.version> <!-- Unit test -->
|
||||
<testcontainers.version>1.20.1</testcontainers.version> <!-- Docker test with real temporary database -->
|
||||
<postgresql.version>42.5.4</postgresql.version> <!-- PostgreSQL JDBC driver -->
|
||||
<flyway.version>9.15.1</flyway.version> <!-- Database migration -->
|
||||
<caffeine.version>3.1.4</caffeine.version> <!-- Caching -->
|
||||
<lombok.version>1.18.34</lombok.version> <!-- Code generation -->
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -82,6 +87,17 @@
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<version>${jcip-annotations.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>${caffeine.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Database -->
|
||||
<dependency>
|
||||
@@ -94,11 +110,21 @@
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>${mysql-connector-j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jdbi</groupId>
|
||||
<artifactId>jdbi3-core</artifactId>
|
||||
<version>${jdbi-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>${flyway.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
@@ -192,6 +218,25 @@
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>mysql</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Rooney
|
||||
Map Name (Map ID)
|
||||
Used to exchange VP for Maple Leaves, and Maple Leaves for rewards.
|
||||
*/
|
||||
|
||||
var itemToUse = 4001126;
|
||||
|
||||
var chairs = [3010000, 3010001, 3010002, 3010003, 3010004, 3010005, 3010006, 3010007, 3010008, 3010009, 3010010, 3010011, 3010012, 3010013, 3010015, 3010016, 3010017, 3010018, 3010019, 3010022, 3010023, 3010024, 3010025, 3010026, 3010028, 3010040, 3010041, 3010043, 3010045, 3010046, 3010047, 3010057, 3010058, 3010060, 3010061, 3010062, 3010063, 3010064, 3010065, 3010066, 3010067, 3010069, 3010071, 3010072, 3010073, 3010080, 3010081, 3010082, 3010083, 3010084, 3010085, 3010097, 3010098, 3010099, 3010101, 3010106, 3010116, 3011000, 3012005, 3012010, 3012011];
|
||||
var scrolls = [2040603, 2044503, 2041024, 2041025, 2044703, 2044603, 2043303, 2040807, 2040806, 2040006, 2040007, 2043103, 2043203, 2043003, 2040506, 2044403, 2040903, 2040709, 2040710, 2040711, 2044303, 2043803, 2040403, 2044103, 2044203, 2044003, 2043703];
|
||||
var weapons = [1302020, 1302030, 1302033, 1302058, 1302064, 1302080, 1312032, 1322054, 1332025, 1332055, 1332056, 1372034, 1382009, 1382012, 1382039, 1402039, 1412011, 1412027, 1422014, 1422029, 1432012, 1432040, 1432046, 1442024, 1442030, 1442051, 1452016, 1452022, 1452045, 1462014, 1462019, 1462040, 1472030, 1472032, 1472055, 1482020, 1482021, 1482022, 1492020, 1492021, 1492022, 1092030, 1092045, 1092046, 1092047];
|
||||
|
||||
var nxAmount = 3000;
|
||||
var chairAmount = 2;
|
||||
var weaponAmount = 2;
|
||||
var buffAmount = 2;
|
||||
var hiredMerchantLength = 7;
|
||||
|
||||
var buff1ID = 2022273;
|
||||
var buff2ID = 2022179;
|
||||
var status;
|
||||
var vp;
|
||||
var choice;
|
||||
|
||||
function start() {
|
||||
//vp = cm.getClient().getVotePoints();
|
||||
//if(vp == null)
|
||||
vp = 0;
|
||||
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode < 0) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
if (status == 0 && mode == 1) {
|
||||
if (cm.getPlayer().getLevel() < 20) {
|
||||
cm.sendOk("Hello, I am the Vote Point exchanger for #rMapleSolaxia#k!\r\n\r\nI am sorry, but I can only exchange Vote Points for players #blevel 20 or over#k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
var outStr = "Hello, I am the Vote Point exchanger for #rMapleSolaxia#k!\r\n";
|
||||
outStr += "You currently have #r#c" + itemToUse + "##k #t" + itemToUse + "# and #r" + vp + "#k Vote Points.#b\r\n\r\n";
|
||||
outStr += "#L0#I would like to exchange my vote points for Maple Leaves#l\r\n";
|
||||
outStr += "#L1#I would like to exchange 1 #t" + itemToUse + "# for " + nxAmount + " NX Cash#l\r\n";
|
||||
outStr += "#L2#I would like to exchange 1 #t" + itemToUse + "# for " + chairAmount + " Random Chair" + (chairAmount > 1 ? "s" : "") + "#l\r\n";
|
||||
outStr += "#L3#I would like to exchange 1 #t" + itemToUse + "# for " + weaponAmount + " Maple Weapons#l\r\n";
|
||||
outStr += "#L4#I would like to exchange 1 #t" + itemToUse + "# for " + buffAmount + " #t" + buff1ID + "#s and " + buffAmount + " #t" + buff2ID + "#s#l\r\n";
|
||||
outStr += "#L5#I would like to exchange 1 #t" + itemToUse + "# for a " + hiredMerchantLength + " Day Hired Merchant#l\r\n";
|
||||
cm.sendSimple(outStr);
|
||||
} else if (status == 1) {
|
||||
choice = selection;
|
||||
|
||||
if (selection > 0) {
|
||||
if (!cm.haveItem(itemToUse) && vp == 0) {
|
||||
cm.sendOk("I'm sorry, but you don't have any #t" + itemToUse + " or Vote Points.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (selection == 0) {
|
||||
// Exchange VP for leaves
|
||||
if (vp <= 0) {
|
||||
cm.sendOk("I'm sorry, but you don't have any Vote Points to exchange!");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
cm.sendYesNo("Would you like to exchange " + vp + " Vote Point" + (vp > 0 ? "s" : "") + " for " + vp + " #t" + itemToUse + "# " + (vp > 0 ? "s" : "") + "?");
|
||||
} else if (selection == 1) {
|
||||
// Exchange 1 Leaf for Cash
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + nxAmount + " NX Cash?");
|
||||
} else if (selection == 2) {
|
||||
// Exchange 1 Leaf for Chair
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + chairAmount + " Random Chair" + (chairAmount > 1 ? "s" : "") + "?");
|
||||
} else if (selection == 3) {
|
||||
// Exchange 1 Leaf for Maple Weapons
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + weaponAmount + " Random Maple Weapons?");
|
||||
} else if (selection == 4) {
|
||||
// Exchange 1 Leaf for Apples/Cheese
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + buffAmount + " #t" + buff1ID + "# and #t" + buff2ID + "#?");
|
||||
} else if (selection == 5) {
|
||||
// Echange 1 Leaf for Merchant
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for a " + hiredMerchantLength + " Day Hired Merchant?");
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (status == 2) {
|
||||
var useVP = false;
|
||||
if (!cm.hasItem(itemToUse) && vp > 0) {
|
||||
useVP = true;
|
||||
}
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
if (choice == 0) {
|
||||
// VP Exchange
|
||||
if (!cm.canHold(itemToUse)) {
|
||||
cm.sendOk("It looks like you don't have enough space in your #rETC#k inventory to hold the #t" + itemToUse + "#" + (vp > 0 ? "s" : "") + ".");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.getClient().useVotePoints(vp);
|
||||
cm.gainItem(itemToUse, vp);
|
||||
cm.dispose();
|
||||
} else if (choice == 1) {
|
||||
// Leaf for Cash
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.getPlayer().getCashShop().gainCash(1, nxAmount);
|
||||
const PacketCreator = Java.type('tools.PacketCreator');
|
||||
cm.getPlayer().sendPacket(PacketCreator.earnTitleMessage("You have earned " + nxAmount + " NX"));
|
||||
cm.logLeaf(nxAmount + " NX");
|
||||
cm.dispose();
|
||||
} else if (choice == 2) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.SETUP).isFull(chairAmount)) {
|
||||
|
||||
var chairStr = "";
|
||||
for (var i = 0; i < chairAmount; i++) {
|
||||
var chair = chairs[Math.floor(Math.random() * chairs.length)];
|
||||
cm.gainItem(chair, 1, true);
|
||||
chairStr += chair + " ";
|
||||
}
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf("Chair ID: " + chairStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 3) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.EQUIP).isFull(weaponAmount)) {
|
||||
|
||||
var weaponStr = "";
|
||||
for (var i = 0; i < weaponAmount; i++) {
|
||||
var weapon = weapons[Math.floor(Math.random() * weapons.length)];
|
||||
cm.gainItem(weapon, 1, true, true);
|
||||
weaponStr += weapon + " ";
|
||||
}
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf("Maple Weapon IDs: " + weaponStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 4) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.USE).isFull(2)) {
|
||||
cm.gainItem(buff1ID, buffAmount, true);
|
||||
cm.gainItem(buff2ID, buffAmount, true);
|
||||
cm.gainItem(itemToUse, -1);
|
||||
cm.logLeaf(buffAmount + " cheeses and apples");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 5) {
|
||||
if (!cm.haveItem(5030000, 1)) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.CASH).isFull(1)) {
|
||||
cm.gainItem(5030000, 1, false, true, 1000 * 60 * 60 * 24 * hiredMerchantLength);
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf(hiredMerchantLength + " day hired merchant");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold these items!");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("I can't give you a merchant if you already have one!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function start() {
|
||||
const ShopFactory = Java.type('server.ShopFactory');
|
||||
ShopFactory.getInstance().getShop(11000).sendShop(cm.getClient());
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -21,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -239,9 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -269,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -445,170 +412,7 @@ function action(mode, type, selection) {
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
1.0 - First Version by Drago (MapleStorySA)
|
||||
2.0 - Second Version by Ronan (HeavenMS)
|
||||
3.0 - Third Version by Jayd - translated CPQ contents to English and added Pirate items
|
||||
Special thanks to 頼晏 (ryantpayton) for also stepping in to translate CPQ scripts.
|
||||
---------------------------------------------------------------------------------------------------
|
||||
**/
|
||||
|
||||
@@ -20,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,9 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -268,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -439,175 +407,12 @@ function action(mode, type, selection) {
|
||||
cm.sendNext("Oh, and do not worry about turning into a ghost. In the Monster Carnival, #byou will not lose EXP after death#k. So it's really an experience like no other!");
|
||||
cm.dispose();
|
||||
} else if (select == 2) {
|
||||
cm.sendNext("#bProtetor#k basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
cm.sendNext("#bProtector#k is basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
}
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
1.0 - First Version by Drago (MapleStorySA)
|
||||
2.0 - Second Version by Ronan (HeavenMS)
|
||||
3.0 - Third Version by Jayd - translated CPQ contents to English and added Pirate items
|
||||
Special thanks to 頼晏 (ryantpayton) for also stepping in to translate CPQ scripts.
|
||||
---------------------------------------------------------------------------------------------------
|
||||
**/
|
||||
|
||||
@@ -20,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,6 +48,7 @@ function action(mode, type, selection) {
|
||||
status--;
|
||||
}
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (cm.getPlayer().getMapId() == 980000010) {
|
||||
if (status == 0) {
|
||||
cm.sendNext("I hope you had fun at the Monster Carnival!");
|
||||
@@ -222,9 +212,9 @@ function action(mode, type, selection) {
|
||||
}
|
||||
} else {
|
||||
var party = cm.getParty().getMembers();
|
||||
if ((selection >= 0 && selection <= 3) && party.size() < 1) {
|
||||
if ((selection >= 0 && selection <= 3) && party.size() < (YamlConfig.config.server.USE_ENABLE_SOLO_EXPEDITIONS ? 1 : 2)) {
|
||||
cm.sendOk("You need at least 2 players to participate in the battle!");
|
||||
} else if ((selection >= 4 && selection <= 5) && party.size() < 1) {
|
||||
} else if ((selection >= 4 && selection <= 5) && party.size() < (YamlConfig.config.server.USE_ENABLE_SOLO_EXPEDITIONS ? 1 : 3)) {
|
||||
cm.sendOk("You need at least 3 players to participate in the battle!");
|
||||
} else {
|
||||
cm.cpqLobby(selection);
|
||||
@@ -237,11 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -269,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -310,7 +277,7 @@ function action(mode, type, selection) {
|
||||
}
|
||||
} else if (select == 2) {//S2 Warrior 26 S3 Magician 6 S4 Bowman 6 S5 Thief 8
|
||||
status = 10;
|
||||
cm.sendSimple("Please make sure you have #t4001129# for the weapon you want. Select the weapon you would like to trade #t4001129#. The choices I have are really good, and I'm not the one who speaks to the people who say it! \r\n#b#L0# #z1302004# (" + n3 + " coins)#l\r\n#L1# #z1402006# (" + n3 + " coins)#l\r\n#L2# #z1302009# (" + n4 + " coins)#l\r\n#L3# #z1402007# (" + n4 + " coins)#l\r\n#L4# #z1302010# (" + n5 + " coins)#l\r\n#L5# #z1402003# (" + n5 + " coins)#l\r\n#L6# #z1312006# (" + n3 + " coins)#l\r\n#L7# #z1412004# (" + n3 + " coins)#l\r\n#L8# #z1312007# (" + n4 + " coins)#l\r\n#L9# #z1412005# (" + n4 + " coins)#l\r\n#L10# #z1312008# (" + n5 + " coins)#l\r\n#L11# #z1412003# (" + n5 + " coins)#l\r\n#L12# Continue to the next page(1/2)#l");
|
||||
cm.sendSimple("Please make sure you have # t4001129 # for the weapon you want. Select the weapon you would like to trade # t4001129 #. The choices I have are really good, and I'm not the one who speaks to the people who say it! \r\n#b#L0# #z1302004# (" + n3 + " coins)#l\r\n#L1# #z1402006# (" + n3 + " coins)#l\r\n#L2# #z1302009# (" + n4 + " coins)#l\r\n#L3# #z1402007# (" + n4 + " coins)#l\r\n#L4# #z1302010# (" + n5 + " coins)#l\r\n#L5# #z1402003# (" + n5 + " coins)#l\r\n#L6# #z1312006# (" + n3 + " coins)#l\r\n#L7# #z1412004# (" + n3 + " coins)#l\r\n#L8# #z1312007# (" + n4 + " coins)#l\r\n#L9# #z1412005# (" + n4 + " coins)#l\r\n#L10# #z1312008# (" + n5 + " coins)#l\r\n#L11# #z1412003# (" + n5 + " coins)#l\r\n#L12# Continue to the next page (1/2)#l");
|
||||
} else if (select == 3) {
|
||||
status = 20;
|
||||
cm.sendSimple("Select the weapon you would like to trade. The weapons I have here are extremely attractive. See for yourself! \r\n#b#L0# #z1372001# (" + n3 + " coins)#l\r\n#L1# #z1382018# (" + n3 + " coins)#l\r\n#L2# #z1372012# (" + n4 + " coins)#l\r\n#L3# #z1382019# (" + n4 + " coins)#l\r\n#L4# #z1382001# (" + n5 + " coins)#l\r\n#L5# #z1372007# (" + n5 + " coins)#l");
|
||||
@@ -440,175 +407,12 @@ function action(mode, type, selection) {
|
||||
cm.sendNext("Oh, and do not worry about turning into a ghost. In the Monster Carnival, #byou will not lose EXP after death#k. So it's really an experience like no other!");
|
||||
cm.dispose();
|
||||
} else if (select == 2) {
|
||||
cm.sendNext("#bProtetor#k basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
cm.sendNext("#bProtector#k is basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
}
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -40,10 +40,7 @@ function action(mode, type, selection) {
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.openShopNPC(2082014);
|
||||
} else if (cm.isQuestStarted(3749)) {
|
||||
if (cm.isQuestStarted(3749)) {
|
||||
cm.sendOk("We've already located the enemy's ultimate weapon! Follow along the ship's bow area ahead and you will find my sister #b#p2082013##k. Report to her for futher instructions on the mission.");
|
||||
} else {
|
||||
cm.sendDefault();
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
var status = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
cm.openShopNPC(2100002);
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
var status = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
cm.openShopNPC(2100003);
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -17,127 +17,9 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Coco
|
||||
Refining NPC:
|
||||
* Chaos scroll SYNTHETIZER (rofl)
|
||||
*
|
||||
* @author RonanLana (ronancpl)
|
||||
*/
|
||||
|
||||
var status = 0;
|
||||
var selectedType = -1;
|
||||
var selectedItem = -1;
|
||||
var item;
|
||||
var mats;
|
||||
var matQty;
|
||||
var cost;
|
||||
var qty;
|
||||
var equip;
|
||||
var last_use; //last item is a use item
|
||||
/* Coco */
|
||||
|
||||
function start() {
|
||||
cm.getPlayer().setCS(true);
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
cm.sendOk("Oh, ok... Talk back to us when you want to make business.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("Hi, I'm #b#p" + cm.getNpc() + "##k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var selStr = "Hey traveler! Come, come closer... We offer a #bhuge opportunity of business#k to you. If you want to know what it is, keep listening...";
|
||||
cm.sendNext(selStr);
|
||||
} else if (status == 1) {
|
||||
var selStr = "We've got here the knowledge to synthetize the mighty #b#t2049100##k! Of course, making one is not an easy task... But worry not! Just gather some material to me and a fee of #b1,200,000 mesos#k for our services to #bobtain it#k. You still want to do it?";
|
||||
cm.sendYesNo(selStr);
|
||||
} else if (status == 2) {
|
||||
//selectedItem = selection;
|
||||
selectedItem = 0;
|
||||
|
||||
var itemSet = [2049100, 7777777];
|
||||
var matSet = new Array([4031203, 4001356, 4000136, 4000082, 4001126, 4080100, 4000021, 4003005]);
|
||||
var matQtySet = new Array([100, 60, 40, 80, 10, 8, 200, 120]);
|
||||
var costSet = [1200000, 7777777];
|
||||
item = itemSet[selectedItem];
|
||||
mats = matSet[selectedItem];
|
||||
matQty = matQtySet[selectedItem];
|
||||
cost = costSet[selectedItem];
|
||||
|
||||
var prompt = "So, you want us to make some #t" + item + "#? In that case, how many do you want us to make?";
|
||||
cm.sendGetNumber(prompt, 1, 1, 100)
|
||||
} else if (status == 3) {
|
||||
qty = (selection > 0) ? selection : (selection < 0 ? -selection : 1);
|
||||
last_use = false;
|
||||
|
||||
var prompt = "You want us to make ";
|
||||
if (qty == 1) {
|
||||
prompt += "a #t" + item + "#?";
|
||||
} else {
|
||||
prompt += qty + " #t" + item + "#?";
|
||||
}
|
||||
|
||||
prompt += " In that case, we're going to need specific items from you in order to make it. Make sure you have room in your inventory, though!#b";
|
||||
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
prompt += "\r\n#i" + mats[i] + "# " + matQty[i] * qty + " #t" + mats[i] + "#";
|
||||
}
|
||||
} else {
|
||||
prompt += "\r\n#i" + mats + "# " + matQty * qty + " #t" + mats + "#";
|
||||
}
|
||||
|
||||
if (cost > 0) {
|
||||
prompt += "\r\n#i4031138# " + cost * qty + " meso";
|
||||
}
|
||||
cm.sendYesNo(prompt);
|
||||
} else if (status == 4) {
|
||||
var complete = true;
|
||||
|
||||
if (cm.getMeso() < cost * qty) {
|
||||
cm.sendOk("Come on! We're not here doing you a favor! We all need money to live properly, so bring the cash so we make deal and start the synthesis.");
|
||||
} else if (!cm.canHold(item, qty)) {
|
||||
cm.sendOk("You didn't check if you got a slot to spare on your inventory before our business, no?");
|
||||
} else {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; complete && i < mats.length; i++) {
|
||||
if (matQty[i] * qty == 1) {
|
||||
complete = cm.haveItem(mats[i]);
|
||||
} else {
|
||||
complete = cm.haveItem(mats[i], matQty[i] * qty);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
complete = cm.haveItem(mats, matQty * qty);
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
cm.sendOk("You kidding, right? We won't be able to start the process without all the ingredients at hands. Go get all of them and then talk to us!");
|
||||
} else {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
cm.gainItem(mats[i], -matQty[i] * qty);
|
||||
}
|
||||
} else {
|
||||
cm.gainItem(mats, -matQty * qty);
|
||||
}
|
||||
cm.gainMeso(-cost * qty);
|
||||
cm.gainItem(item, qty);
|
||||
cm.sendOk("Wow... can't believe it worked! To think for a moment that it could f... Ahem. Of course it worked, all work of ours are very efficient! Nice doing business with you.");
|
||||
}
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -19,208 +19,9 @@
|
||||
*/
|
||||
/* NPC: Agent E (9000036)
|
||||
Victoria Road : Henesys
|
||||
|
||||
Refining NPC:
|
||||
* Accessories refiner
|
||||
*
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status = -1;
|
||||
var selectedType = -1;
|
||||
var selectedItem = -1;
|
||||
var item;
|
||||
var items;
|
||||
var mats;
|
||||
var matQty;
|
||||
var cost;
|
||||
var qty = 1;
|
||||
var equip;
|
||||
var maxEqp = 0;
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("Hi, I'm #b#p" + cm.getNpc() + "##k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.getPlayer().setCS(true);
|
||||
var selStr = "Hello, I am the #bAccessory NPC Crafter#k! My works are widely recognized to be too fine, up to the point at which all my items mimic not only the appearance but too the attributes of them! Everything I charge is some 'ingredients' to make them and, of course, a fee for my services. On what kind of equipment are you interessed?#b";
|
||||
var options = ["Pendants", "Face accessories", "Eye accessories", "Belts & medals", "Rings"/*,"#t4032496#"*/];
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
cm.sendSimple(selStr);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
status++;
|
||||
if (mode != 1) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (status == 0) {
|
||||
if (selection == 0) { //pendants
|
||||
var selStr = "Well, I've got these pendants on my repertoire:#b";
|
||||
items = [1122018, 1122007, 1122001, 1122003, 1122004, 1122006, 1122002, 1122005, 1122058];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 1) { //face accessory
|
||||
var selStr = "Hmm, face accessories? There you go: #b";
|
||||
items = [1012181, 1012182, 1012183, 1012184, 1012185, 1012186, 1012108, 1012109, 1012110, 1012111];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 2) { //eye accessory
|
||||
var selStr = "Got hard sight? Okay, so which glasses do you want me to make?#b";
|
||||
items = [1022073, 1022088, 1022103, 1022089, 1022082];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 3) { //belt & medal
|
||||
var selStr = "Hmm... For these, things get a little tricky. Since these items are too short and too similar one another, I don't really know what item will emerge when I finish the synthesis. Still wanna try for something?";
|
||||
items = [];
|
||||
maxEqp = 0;
|
||||
|
||||
for (var x = 1132005; x < 1132017; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142000; x < 1142102; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142107; x < 1142121; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142122; x < 1142143; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
selStr += "\r\n#L" + i + "##bTry it!#b";
|
||||
|
||||
} else if (selection == 4) { //ring refine
|
||||
var selStr = "Rings, huh? These are my specialty, go check it yourself!#b";
|
||||
items = [1112407, 1112408, 1112401, 1112413, 1112414, 1112405, 1112402];
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
|
||||
}/*else if (selection == 5) { //make necklace
|
||||
var selStr = "Need to make #t4032496#?#b";
|
||||
items = [4032496];
|
||||
for (var i = 0; i < items.length; i++)
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##l";
|
||||
}*/
|
||||
selectedType = selection;
|
||||
cm.sendSimple(selStr);
|
||||
} else if (status == 1) {
|
||||
if (selectedType != 3) {
|
||||
selectedItem = selection;
|
||||
}
|
||||
|
||||
if (selectedType == 0) { //pendant refine
|
||||
var matSet = [[4003004, 4030012, 4001356, 4000026], [4000026, 4001356, 4000073, 4001006], [4001343, 4011002, 4003004, 4003005], [4001343, 4011006, 4003004, 4003005], [4000091, 4011005, 4003004, 4003005], [4000091, 4011001, 4003004, 4003005], [4000469, 4011000, 4003004, 4003005], [4000469, 4011004, 4003004, 4003005], [1122007, 4003002, 4000413]];
|
||||
var matQtySet = [[20, 20, 5, 1], [5, 5, 10, 1], [10, 2, 20, 4], [10, 1, 20, 4], [15, 3, 30, 6], [15, 3, 30, 6], [20, 5, 20, 8], [20, 4, 40, 8], [1, 1, 1]];
|
||||
var costSet = [150000, 500000, 200000, 200000, 300000, 300000, 400000, 400000, 2500000];
|
||||
} else if (selectedType == 1) { //face accessory refine
|
||||
var matSet = [[4006000, 4003004], [4006000, 4003004, 4000026], [4006000, 4003004, 4000026, 4000082, 4003002], [4006000, 4003005], [4006000, 4003005, 4000026], [4006000, 4003005, 4000026, 4000082, 4003002], [4001006, 4011008], [4001006, 4011008], [4001006, 4011008], [4001006, 4011008]];
|
||||
var matQtySet = [[5, 5], [5, 5, 5], [5, 5, 5, 5, 1], [5, 5], [5, 5, 5], [5, 5, 5, 5, 1], [1, 1], [1, 1], [1, 1], [1, 1]];
|
||||
var costSet = [100000, 200000, 300000, 125000, 250000, 375000, 500000, 500000, 500000, 500000, 25000, 25000, 25000, 25000];
|
||||
} else if (selectedType == 2) { //eye accessory refine
|
||||
var matSet = [[4001006, 4003002, 4000082, 4031203], [4001005, 4011008], [4001005, 4011008], [4001005, 4011008, 4000082], [4001006, 4003002, 4003000, 4003001]];
|
||||
var matQtySet = [[2, 2, 5, 10], [3, 2], [4, 3], [5, 3, 10], [2, 2, 10, 5]];
|
||||
var costSet = [250000, 250000, 300000, 400000, 200000];
|
||||
} else if (selectedType == 3) { //belt & medals refine
|
||||
var matSet = [[4001006, 4003005, 4003004], [7777, 7777]];
|
||||
var matQtySet = [[2, 5, 10], [7777, 7777]];
|
||||
var costSet = [15000, 7777];
|
||||
} else if (selectedType == 4) { //ring refine
|
||||
var matSet = [[4003001, 4001344, 4006000], [4003001, 4001344, 4006000], [4021004, 4011008], [4011008, 4001006], [1112413, 2022039], [1112414, 4000176], [4011007, 4021009]];
|
||||
var matQtySet = [[2, 2, 2], [2, 2, 2], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1]];
|
||||
var costSet = [10000, 10000, 10000, 20000, 15000, 15000, 10000];
|
||||
}/*else if (selectedType == 5) { //necklace refine
|
||||
var matSet = [[4011007, 4011008, 4021009]];
|
||||
var matQtySet = [[1, 1, 1]];
|
||||
var costSet = [10000];
|
||||
}*/
|
||||
|
||||
if (selectedType == 3) {
|
||||
selectedItem = Math.floor(Math.random() * maxEqp);
|
||||
item = items[selectedItem];
|
||||
mats = matSet[0];
|
||||
matQty = matQtySet[0];
|
||||
cost = costSet[0];
|
||||
} else {
|
||||
item = items[selectedItem];
|
||||
mats = matSet[selectedItem];
|
||||
matQty = matQtySet[selectedItem];
|
||||
cost = costSet[selectedItem];
|
||||
}
|
||||
|
||||
var prompt = "You want me to make ";
|
||||
if (selectedType != 3) {
|
||||
if (qty == 1) {
|
||||
prompt += "a #b#t" + item + "##k?";
|
||||
} else {
|
||||
prompt += "#b" + qty + " #t" + item + "##k?";
|
||||
}
|
||||
} else {
|
||||
prompt += "a #bbelt#k or a #bmedal#k?";
|
||||
}
|
||||
|
||||
prompt += " Right! I will need some items to make that item. Make sure you have a #bfree slot#k in your inventory!#b";
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
prompt += "\r\n#i" + mats[i] + "# " + (matQty[i] * qty) + " #t" + mats[i] + "#";
|
||||
}
|
||||
} else {
|
||||
prompt += "\r\n#i" + mats + "# " + (matQty * qty) + " #t" + mats + "#";
|
||||
}
|
||||
if (cost > 0) {
|
||||
prompt += "\r\n#i4031138# " + (cost * qty) + " meso";
|
||||
}
|
||||
cm.sendYesNo(prompt);
|
||||
} else if (status == 2) {
|
||||
if (cm.getMeso() < (cost * qty)) {
|
||||
cm.sendOk("This is the fee I charge to make my items! No credit.");
|
||||
} else {
|
||||
var complete = true;
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; complete && i < mats.length; i++) {
|
||||
if (!cm.haveItem(mats[i], matQty[i] * qty)) {
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
} else if (!cm.haveItem(mats, matQty * qty)) {
|
||||
complete = false;
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
cm.sendOk("Are you sure you got all the items required? Double check it!");
|
||||
} else {
|
||||
if (cm.canHold(item, qty)) {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
cm.gainItem(mats[i], -(matQty[i] * qty));
|
||||
}
|
||||
} else {
|
||||
cm.gainItem(mats, -(matQty * qty));
|
||||
}
|
||||
cm.gainMeso(-(cost * qty));
|
||||
|
||||
cm.gainItem(item, qty);
|
||||
cm.sendOk("The item is done! Take and try this piece of art yourself.");
|
||||
} else {
|
||||
cm.sendOk("You got no free slot on your inventory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -19,72 +19,9 @@
|
||||
*/
|
||||
/* Dalair
|
||||
Medal NPC.
|
||||
|
||||
NPC Equipment Merger:
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status;
|
||||
var mergeFee = 50000;
|
||||
var name;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var levelLimit = !cm.getPlayer().isCygnus() ? 160 : 110;
|
||||
var selStr = "The medal ranking system is currently unavailable... Therefore, I am providing the #bEquipment Merge#k service! ";
|
||||
|
||||
const MakerProcessor = Java.type('client.processor.action.MakerProcessor');
|
||||
if (!YamlConfig.config.server.USE_STARTER_MERGE && (cm.getPlayer().getLevel() < levelLimit || MakerProcessor.getMakerSkillLevel(cm.getPlayer()) < 3)) {
|
||||
selStr += "However, you must have #rMaker level 3#k and at least #rlevel 110#k (Cygnus Knight), #rlevel 160#k (other classes) and a fund of #r" + cm.numberWithCommas(mergeFee) + " mesos#k to use the service.";
|
||||
cm.sendOk(selStr);
|
||||
cm.dispose();
|
||||
} else if (cm.getMeso() < mergeFee) {
|
||||
selStr += "I'm sorry, but this service tax is of #r" + cm.numberWithCommas(mergeFee) + " mesos#k, which it seems you unfortunately don't have right now... Please, stop by again later.";
|
||||
cm.sendOk(selStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
selStr += "For the fee of #r" + cm.numberWithCommas(mergeFee) + "#k mesos, merge unnecessary equipments in your inventory into your currently equipped gears to get stat boosts into them, statups based on the attributes of the items used on the merge!";
|
||||
cm.sendNext(selStr);
|
||||
}
|
||||
} else if (status == 1) {
|
||||
selStr = "#rWARNING#b: Make sure you have your items ready to merge at the slots #rAFTER#b the item you have selected to merge.#k Any items #bunder#k the item selected will be merged thoroughly.\r\n\r\nNote that equipments receiving bonuses from merge are going to become #rUntradeable#k thereon, and equipments that already received the merge bonus #rcannot be used for merge#k.\r\n\r\n";
|
||||
cm.sendGetText(selStr);
|
||||
} else if (status == 2) {
|
||||
name = cm.getText();
|
||||
|
||||
if (cm.getPlayer().mergeAllItemsFromName(name)) {
|
||||
cm.gainMeso(-mergeFee);
|
||||
cm.sendOk("Merging complete! Thanks for using the service and enjoy your new equipment stats.");
|
||||
} else {
|
||||
cm.sendOk("There is no #b'" + name + "'#k in your #bEQUIP#k inventory!");
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -19,54 +19,9 @@
|
||||
*/
|
||||
/* NPC: Donation Box (9000041)
|
||||
Victoria Road : Henesys
|
||||
|
||||
NPC Bazaar:
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var options = ["EQUIP", "USE", "SET-UP", "ETC"];
|
||||
var name;
|
||||
var status;
|
||||
var selectedType = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
status++;
|
||||
if (mode != 1) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var selStr = "Hello, I am the #bBazaar NPC#k! Sell to me any item on your inventory you don't need. #rWARNING#b: Make sure you have your items ready to sell at the slots #rAFTER#b the item you have selected to sell.#k Any items #bunder#k the item selected will be sold thoroughly.";
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
cm.sendSimple(selStr);
|
||||
} else if (status == 1) {
|
||||
selectedType = selection;
|
||||
cm.sendGetText("From what item on your #r" + options[selectedType] + "#k inventory do you want to start the transaction?");
|
||||
} else if (status == 2) {
|
||||
name = cm.getText();
|
||||
var res = cm.getPlayer().sellAllItemsFromName(selectedType + 1, name);
|
||||
|
||||
if (res > -1) {
|
||||
cm.sendOk("Transaction complete! You received #r" + cm.numberWithCommas(res) + " mesos#k from this action.");
|
||||
} else {
|
||||
cm.sendOk("There is no #b'" + name + "'#k in your #b" + options[selectedType] + "#k inventory!");
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,88 @@
|
||||
/**
|
||||
*9201098 - Mo
|
||||
*@author Ronan
|
||||
* 9201098 - Mo
|
||||
* @author Ronan
|
||||
* @author Ponk
|
||||
*/
|
||||
|
||||
let status = 0;
|
||||
let selectedItem = undefined;
|
||||
|
||||
/*
|
||||
References:
|
||||
- https://www.youtube.com/watch?v=g6y2zmCGglI
|
||||
- https://www.youtube.com/watch?v=CttmlVWLJKM
|
||||
*/
|
||||
function start() {
|
||||
if (cm.getQuestStatus(8224) == 2) {
|
||||
cm.openShopNPC(9201099);
|
||||
} else {
|
||||
cm.sendOk("Hm, at who do you think you are looking at?");
|
||||
if (cm.getQuestStatus(8224) !== 2) {
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
cm.sendSimple("Name's Mo. I've got Mo' items for Mo' mesos. What business do you bring me?\r\n#L0##bI'd like to buy some items#k");
|
||||
}
|
||||
|
||||
function action(action, type, selection) {
|
||||
if (!action) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status === 0) {
|
||||
let index = 0;
|
||||
const selections = "#e" + shopItems()
|
||||
.map(i => {
|
||||
const mesoText = i.quantity === 1 ? "meso" : `meso per ${i.quantity} arrows`;
|
||||
return `\r\n#L${index++}##i${i.itemId}# #z${i.itemId}# #b${i.cost} ${mesoText}#k`;
|
||||
})
|
||||
.join("");
|
||||
cm.sendSimple("An ally of the Raven Ninja Clan is welcome to buy from me!" + selections);
|
||||
status++;
|
||||
} else if (status === 1 && selection !== -1) {
|
||||
selectedItem = shopItems()[selection];
|
||||
cm.sendAcceptDecline("Are you sure you want to buy it?");
|
||||
status++;
|
||||
} else if (status === 2) {
|
||||
if (!selectedItem) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (!cm.hasMeso(selectedItem.cost)) {
|
||||
cm.sendOk("You don't have enough mesos.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (!cm.canHold(selectedItem.itemId, selectedItem.quantity)) {
|
||||
cm.sendOk("There's no room in your inventory.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.loseMeso(selectedItem.cost);
|
||||
cm.gainItem(selectedItem.itemId, selectedItem.quantity);
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
function shopItems() {
|
||||
return [
|
||||
{itemId: 2050004, quantity: 1, cost: 400}, // All-Cure Potion
|
||||
{itemId: 2050000, quantity: 1, cost: 200}, // Antidote
|
||||
{itemId: 2020012, quantity: 1, cost: 4500}, // Melting Cheese
|
||||
{itemId: 2020013, quantity: 1, cost: 5000}, // Reindeer Milk
|
||||
{itemId: 2020014, quantity: 1, cost: 8100}, // Sunrise Dew
|
||||
{itemId: 2020015, quantity: 1, cost: 9690}, // Sunset Dew
|
||||
{itemId: 2050001, quantity: 1, cost: 200}, // Eyedrop
|
||||
{itemId: 2050002, quantity: 1, cost: 300}, // Tonic
|
||||
{itemId: 2050003, quantity: 1, cost: 500}, // Holy Water
|
||||
{itemId: 2022000, quantity: 1, cost: 1650}, // Pure Water
|
||||
{itemId: 2002017, quantity: 1, cost: 5000}, // Warrior Elixir
|
||||
{itemId: 2060004, quantity: 2000, cost: 40_000}, // Diamond Arrow for Bow
|
||||
{itemId: 2061004, quantity: 2000, cost: 40_000}, // Diamond Arrow for Crossbow
|
||||
{itemId: 2070010, quantity: 1, cost: 2000}, // Icicle
|
||||
{itemId: 2022003, quantity: 1, cost: 1100}, // Unagi
|
||||
{itemId: 2000006, quantity: 1, cost: 620}, // Mana Elixir
|
||||
{itemId: 2022002, quantity: 1, cost: 1000}, // Cider
|
||||
{itemId: 2030020, quantity: 1, cost: 400}, // Return to New Leaf City Scroll
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,13 +4,6 @@
|
||||
*/
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.openShopNPC(9201101);
|
||||
} else {
|
||||
//cm.sendOk("The patrol in New Leaf City is always ready. No creatures are able to break through to the city.");
|
||||
cm.sendDefault();
|
||||
}
|
||||
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ var staff_heading = "!";
|
||||
var levels = ["Common", "Donator", "JrGM", "GM", "SuperGM", "Developer", "Admin"];
|
||||
var commands;
|
||||
|
||||
// Expectation: "ce" bound to an instance of java.client.command.CommandsExecutor
|
||||
function writeHeavenMSCommands() {
|
||||
const CommandsExecutor = Java.type('client.command.CommandsExecutor');
|
||||
commands = CommandsExecutor.getInstance().getGmCommands();
|
||||
commands = ce.getGmCommands();
|
||||
}
|
||||
|
||||
function start() {
|
||||
|
||||
@@ -21,37 +21,6 @@
|
||||
Default Maple TV
|
||||
*/
|
||||
|
||||
var status;
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.dispose();
|
||||
cm.openNpc(9201088, "scroll_generator");
|
||||
return;
|
||||
}
|
||||
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
// do nothing
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -1,452 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* NPC: MapleTV / Larry
|
||||
|
||||
Exchanger NPC:
|
||||
* Scroll generator
|
||||
*
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status;
|
||||
|
||||
var jobWeaponRestricted = [[[2043000, 2043100, 2044000, 2044100, 2043200, 2044200]], [[2043000, 2043100, 2044000, 2044100], [2043000, 2043200, 2044000, 2044200], [2044300, 2044400]], [[2043700, 2043800], [2043700, 2043800], [2043700, 2043800]], [[2044500], [2044600]], [[2044700], [2043300]], [[2044800], [2044900]]];
|
||||
var aranWeaponRestricted = [jobWeaponRestricted[1][2][1]];
|
||||
|
||||
var tier1Scrolls = [];
|
||||
var tier2Scrolls = [2040000, 2040400, 2040500, 2040600, 2040700, 2040800, 2040900];
|
||||
var tier3Scrolls = [2048000, 2049200, 2041000, 2041100, 2041300, 2040100, 2040200, 2040300];
|
||||
|
||||
var typeTierScrolls = [["PAD", "MAD"], ["STR", "DEX", "INT", "LUK", "ACC", "EVA", "Speed", "Jump"], ["PDD", "MDD", "MHP", "MMP"]];
|
||||
|
||||
var sgItems = [4003004, 4003005, 4001006, 4006000, 4006001, 4030012];
|
||||
var sgToBucket = [100, 50, 37.5, 37.5, 37.5, 200];
|
||||
var mesoToBucket = 2800000;
|
||||
|
||||
var sgAppliedItems = [0, 0, 0, 0, 0, 0];
|
||||
var sgAppliedMeso = 0;
|
||||
|
||||
var sgBuckets = 0.0;
|
||||
var sgBookBuckets = 0.0;
|
||||
var sgItemBuckets = 0.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
cm.sendNext("This is the MapleTV Scroll Generator broadcast. Place your supplies or mesos earned throughout your adventure to redeem a prize! You can place #bany amount of supplies#k, however take note that placing #rdifferent supplies#k with #rbigger shots of any of them#k will improve the reward possibilities!");
|
||||
} else if (status == 1) {
|
||||
var sendStr;
|
||||
|
||||
//print("Book: " + sgBookBuckets + " Item: " + sgItemBuckets);
|
||||
|
||||
if (sgItemBuckets > 0.0) {
|
||||
sendStr = "With the items you have currently placed, you have #r" + sgBuckets + "#k buckets (#r" + (sgItemBuckets < 1.0 ? sgItemBuckets.toFixed(2) : Math.floor(sgItemBuckets)) + "#k supply buckets) for claiming a prize. Place supplies:";
|
||||
} else {
|
||||
sendStr = "You have placed no supplies yet. Place supplies:";
|
||||
}
|
||||
|
||||
var listStr = "";
|
||||
var i;
|
||||
for (i = 0; i < sgItems.length; i++) {
|
||||
listStr += "#b#L" + i + "##t" + sgItems[i] + "##k";
|
||||
if (sgAppliedItems[i] > 0) {
|
||||
listStr += " - " + sgAppliedItems[i];
|
||||
}
|
||||
listStr += "#l\r\n";
|
||||
}
|
||||
|
||||
listStr += "#b#L" + i + "#Mesos#k";
|
||||
if (sgAppliedMeso > 0) {
|
||||
listStr += " - " + sgAppliedMeso;
|
||||
}
|
||||
listStr += "#l\r\n";
|
||||
|
||||
cm.sendSimple(sendStr + "\r\n\r\n" + listStr + "#r#L" + (sgItems.length + 2) + "#Retrieve a prize!#l#k\r\n");
|
||||
} else if (status == 2) {
|
||||
if (selection == (sgItems.length + 2)) {
|
||||
if (sgItemBuckets < 1.0) {
|
||||
cm.sendPrev("You have set not enough supplies. Insert at least one bucket of #bsupplies#k to claim a prize.");
|
||||
} else {
|
||||
generateRandomScroll();
|
||||
cm.dispose();
|
||||
}
|
||||
} else {
|
||||
var tickSel;
|
||||
if (selection < sgItems.length) {
|
||||
tickSel = "of #b#t" + sgItems[selection] + "##k";
|
||||
curItemQty = cm.getItemQuantity(sgItems[selection]);
|
||||
} else {
|
||||
tickSel = "#bmesos#k";
|
||||
curItemQty = cm.getMeso();
|
||||
}
|
||||
|
||||
curItemSel = selection;
|
||||
if (curItemQty > 0) {
|
||||
cm.sendGetText("How many " + tickSel + " do you want to provide? (#r" + curItemQty + "#k available)#k");
|
||||
} else {
|
||||
cm.sendPrev("You have got #rnone#k " + tickSel + " to provide for Scroll Generation. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
}
|
||||
} else if (status == 3) {
|
||||
var text = cm.getText();
|
||||
|
||||
try {
|
||||
var placedQty = parseInt(text);
|
||||
if (isNaN(placedQty) || placedQty < 0) {
|
||||
throw true;
|
||||
}
|
||||
|
||||
if (placedQty > curItemQty) {
|
||||
cm.sendPrev("You cannot insert the given amount of #r" + (curItemSel < sgItems.length ? "#t" + sgItems[curItemSel] + "#" : "mesos") + "#k (#r" + curItemQty + "#k available). Click '#rBack#k' to return to the main interface.");
|
||||
} else {
|
||||
if (curItemSel < sgItems.length) {
|
||||
sgApplyItem(curItemSel, placedQty);
|
||||
} else {
|
||||
sgApplyMeso(placedQty);
|
||||
}
|
||||
|
||||
cm.sendPrev("Operation succeeded. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
} catch (err) {
|
||||
cm.sendPrev("You must enter a positive number of supplies to insert. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
|
||||
status = 2;
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getJobTierScrolls() {
|
||||
var scrolls = [];
|
||||
|
||||
var job = cm.getPlayer().getJob();
|
||||
var jobScrolls = jobWeaponRestricted[Math.floor(cm.getPlayer().getJobStyle().getId() / 100)];
|
||||
|
||||
const GameConstants = Java.type('constants.game.GameConstants');
|
||||
var jobBranch = GameConstants.getJobBranch(job);
|
||||
if (jobBranch >= 2) {
|
||||
Array.prototype.push.apply(scrolls, jobScrolls[Math.floor((job.getId() / 10) % 10) - 1]);
|
||||
} else {
|
||||
for (var i = 0; i < jobScrolls.length; i++) {
|
||||
Array.prototype.push.apply(scrolls, jobScrolls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
function getScrollTypePool(rewardTier) {
|
||||
var scrolls = [];
|
||||
switch (rewardTier) {
|
||||
case 1:
|
||||
if (cm.getPlayer().isAran()) {
|
||||
Array.prototype.push.apply(scrolls, aranWeaponRestricted);
|
||||
} else {
|
||||
Array.prototype.push.apply(scrolls, getJobTierScrolls());
|
||||
}
|
||||
|
||||
Array.prototype.push.apply(scrolls, tier1Scrolls);
|
||||
break;
|
||||
case 2:
|
||||
Array.prototype.push.apply(scrolls, tier2Scrolls);
|
||||
break;
|
||||
default:
|
||||
Array.prototype.push.apply(scrolls, tier3Scrolls);
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
function getScrollTier(scrollStats) {
|
||||
for (var i = 0; i < typeTierScrolls.length; i++) {
|
||||
for (var j = 0; j < typeTierScrolls[i].length; j++) {
|
||||
if (scrollStats.get(typeTierScrolls[i][j]) > 0) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
function getScrollSuccessTier(scrollStats) {
|
||||
var prop = scrollStats.get("success");
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (prop > 90) {
|
||||
return 3;
|
||||
} else if (prop < 50) {
|
||||
return YamlConfig.config.server.SCROLL_CHANCE_ROLLS > 2 ? 2 : 1;
|
||||
} else {
|
||||
return YamlConfig.config.server.SCROLL_CHANCE_ROLLS > 2 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
function getAvailableScrollsPool(baseScrolls, rewardTier, successTier) {
|
||||
var scrolls = [];
|
||||
const ItemInformationProvider = Java.type('server.ItemInformationProvider');
|
||||
var ii = ItemInformationProvider.getInstance();
|
||||
|
||||
for (var i = 0; i < baseScrolls.length; i++) {
|
||||
for (var j = 0; j < 100; j++) {
|
||||
var scrollid = baseScrolls[i] + j;
|
||||
var scrollStats = ii.getEquipStats(scrollid);
|
||||
if (scrollStats != null && ii.getScrollReqs(scrollid).isEmpty()) {
|
||||
var scrollTier = getScrollTier(scrollStats);
|
||||
if (scrollTier == rewardTier && successTier == getScrollSuccessTier(scrollStats)) {
|
||||
scrolls.push(scrollid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
// passive tier buckets...
|
||||
|
||||
function getLevelTier(level) {
|
||||
return Math.floor((level - 1) / 15) + 1;
|
||||
}
|
||||
|
||||
function getPlayerCardTierPower() {
|
||||
var cardset = cm.getPlayer().getMonsterBook().getCardSet();
|
||||
var countTier = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
for (var iterator = cardset.iterator(); iterator.hasNext();) {
|
||||
var ce = iterator.next();
|
||||
|
||||
var cardid = ce.getKey();
|
||||
var ceTier = Math.floor(cardid / 1000) % 10;
|
||||
countTier[ceTier] += ce.getValue();
|
||||
|
||||
if (ceTier >= 8) { // is special card
|
||||
const LifeFactory = Java.type('server.life.LifeFactory');
|
||||
const ItemInformationProvider = Java.type('server.ItemInformationProvider');
|
||||
var mobLevel = LifeFactory.getMonsterLevel(ItemInformationProvider.getInstance().getCardMobId(cardid));
|
||||
var mobTier = getLevelTier(mobLevel) - 1;
|
||||
|
||||
countTier[mobTier] += (ce.getValue() * 1.2);
|
||||
}
|
||||
}
|
||||
|
||||
return countTier;
|
||||
}
|
||||
|
||||
function calculateMobBookTierBuckets(tierSize, playerCards, tier) {
|
||||
if (tier < 1) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
tier--; // started at 1
|
||||
var tierHitRate = playerCards[tier] / (tierSize[tier] * 5);
|
||||
if (tierHitRate > 0.5) {
|
||||
tierHitRate = 0.5;
|
||||
}
|
||||
|
||||
return tierHitRate * 4;
|
||||
}
|
||||
|
||||
function calculateMobBookBuckets() {
|
||||
var book = cm.getPlayer().getMonsterBook();
|
||||
var bookLevelMult = 0.9 + (0.1 * book.getBookLevel());
|
||||
|
||||
var playerLevelTier = getLevelTier(cm.getPlayer().getLevel());
|
||||
if (playerLevelTier > 8) {
|
||||
playerLevelTier = 8;
|
||||
}
|
||||
|
||||
const MonsterBook = Java.type('client.MonsterBook');
|
||||
var tierSize = MonsterBook.getCardTierSize();
|
||||
var playerCards = getPlayerCardTierPower();
|
||||
|
||||
var prevBuckets = calculateMobBookTierBuckets(tierSize, playerCards, playerLevelTier - 1);
|
||||
var currBuckets = calculateMobBookTierBuckets(tierSize, playerCards, playerLevelTier);
|
||||
|
||||
return (prevBuckets + currBuckets) * bookLevelMult;
|
||||
}
|
||||
|
||||
function recalcBuckets() {
|
||||
sgBookBuckets = calculateMobBookBuckets();
|
||||
sgItemBuckets = calculateSuppliesBuckets();
|
||||
|
||||
var buckets = sgBookBuckets + sgItemBuckets;
|
||||
if (buckets > 6.0) {
|
||||
sgBuckets = 6;
|
||||
} else {
|
||||
sgBuckets = Math.floor(buckets);
|
||||
}
|
||||
}
|
||||
|
||||
// variable buckets...
|
||||
|
||||
function sgApplyItem(idx, amount) {
|
||||
if (sgAppliedItems[idx] != amount) {
|
||||
sgAppliedItems[idx] = amount;
|
||||
recalcBuckets();
|
||||
}
|
||||
}
|
||||
|
||||
function sgApplyMeso(amount) {
|
||||
if (sgAppliedMeso != amount) {
|
||||
sgAppliedMeso = amount;
|
||||
recalcBuckets();
|
||||
}
|
||||
}
|
||||
|
||||
function calculateSuppliesBuckets() {
|
||||
var suppliesHitRate = 0.0;
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
suppliesHitRate += sgAppliedItems[i] / sgToBucket[i];
|
||||
}
|
||||
suppliesHitRate *= 2;
|
||||
|
||||
suppliesHitRate += (sgAppliedMeso / mesoToBucket);
|
||||
return suppliesHitRate;
|
||||
}
|
||||
|
||||
function calculateScrollTiers() {
|
||||
var buckets = sgBuckets;
|
||||
var tiers = [0, 0, 0];
|
||||
while (buckets > 0) {
|
||||
var pool = [];
|
||||
for (var i = 0; i < tiers.length; i++) {
|
||||
if (tiers[i] < 2) {
|
||||
pool.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
var rnd = pool[Math.floor(Math.random() * pool.length)];
|
||||
|
||||
tiers[rnd]++;
|
||||
buckets--;
|
||||
}
|
||||
|
||||
// normalize tiers
|
||||
for (var i = 0; i < tiers.length; i++) {
|
||||
tiers[i] = 3 - tiers[i];
|
||||
}
|
||||
|
||||
return tiers;
|
||||
}
|
||||
|
||||
function getRandomScrollFromTiers(tiers) {
|
||||
var typeTier = tiers[0], subtypeTier = tiers[1], successTier = tiers[2];
|
||||
var scrollTypePool = getScrollTypePool(typeTier);
|
||||
var scrollPool = getAvailableScrollsPool(scrollTypePool, subtypeTier, successTier);
|
||||
|
||||
if (scrollPool.length > 0) {
|
||||
return scrollPool[Math.floor(Math.random() * scrollPool.length)];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function getRandomScrollFromRightPermutations(tiers) {
|
||||
for (var i = 2; i >= 0; i--) {
|
||||
for (var j = i - 1; j >= 0; j--) {
|
||||
if (tiers[i] >= 3) {
|
||||
break;
|
||||
} else if (tiers[j] > 1) {
|
||||
tiers[i]++;
|
||||
tiers[j]--;
|
||||
|
||||
var itemid = getRandomScrollFromTiers(tiers);
|
||||
if (itemid != -1) {
|
||||
return itemid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function getRandomScroll(tiers) {
|
||||
var itemid = getRandomScrollFromTiers(tiers);
|
||||
if (itemid == -1) {
|
||||
// worst case shift-right permutations...
|
||||
itemid = getRandomScrollFromRightPermutations(tiers);
|
||||
}
|
||||
|
||||
return itemid;
|
||||
}
|
||||
|
||||
function performExchange(sgItemid, sgCount) {
|
||||
if (cm.getMeso() < sgAppliedMeso) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
var itemid = sgItems[i];
|
||||
var count = sgAppliedItems[i];
|
||||
if (count > 0 && !cm.haveItem(itemid, count)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cm.gainMeso(-sgAppliedMeso);
|
||||
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
var itemid = sgItems[i];
|
||||
var count = sgAppliedItems[i];
|
||||
cm.gainItem(itemid, -count);
|
||||
}
|
||||
|
||||
cm.gainItem(sgItemid, sgCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
function generateRandomScroll() {
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
if (cm.getPlayer().getInventory(InventoryType.USE).getNumFreeSlot() >= 1) {
|
||||
var itemid = getRandomScroll(calculateScrollTiers());
|
||||
if (itemid != -1) {
|
||||
if (performExchange(itemid, 1)) {
|
||||
cm.sendNext("Transaction accepted! You have received a #r#t" + itemid + "##k.");
|
||||
} else {
|
||||
cm.sendOk("Oh, it looks like some items are missing... Please double-check provided items in your inventory before trying to exchange.");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("Sorry for the inconvenience, but it seems there are no scrolls on store right now... Try again later.");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("Please look out for a slot available on your USE inventory before trying for a scroll.");
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public abstract class AbstractCharacterObject extends AbstractAnimatedMapObject
|
||||
protected MapleMap map;
|
||||
protected int str, dex, luk, int_, hp, maxhp, mp, maxmp;
|
||||
protected int hpMpApUsed, remainingAp;
|
||||
protected int[] remainingSp = new int[10];
|
||||
protected int[] remainingSp = new int[10]; // TODO: change to a simple int. Evan is not in v83, so why support it?
|
||||
protected transient int clientmaxhp, clientmaxmp, localmaxhp = 50, localmaxmp = 5;
|
||||
protected float transienthp = Float.NEGATIVE_INFINITY, transientmp = Float.NEGATIVE_INFINITY;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
package client;
|
||||
|
||||
import model.CharacterIdentity;
|
||||
import net.packet.Packet;
|
||||
import net.server.PlayerStorage;
|
||||
import tools.DatabaseConnection;
|
||||
@@ -48,7 +49,7 @@ public class BuddyList {
|
||||
|
||||
private final Map<Integer, BuddylistEntry> buddies = new LinkedHashMap<>();
|
||||
private int capacity;
|
||||
private final Deque<CharacterNameAndId> pendingRequests = new LinkedList<>();
|
||||
private final Deque<CharacterIdentity> pendingRequests = new LinkedList<>();
|
||||
|
||||
public BuddyList(int capacity) {
|
||||
this.capacity = capacity;
|
||||
@@ -150,7 +151,7 @@ public class BuddyList {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
if (rs.getInt("pending") == 1) {
|
||||
pendingRequests.push(new CharacterNameAndId(rs.getInt("buddyid"), rs.getString("buddyname")));
|
||||
pendingRequests.push(new CharacterIdentity(rs.getString("buddyname"), rs.getInt("buddyid")));
|
||||
} else {
|
||||
put(new BuddylistEntry(rs.getString("buddyname"), rs.getString("group"), rs.getInt("buddyid"), (byte) -1, true));
|
||||
}
|
||||
@@ -167,7 +168,7 @@ public class BuddyList {
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterNameAndId pollPendingRequest() {
|
||||
public CharacterIdentity pollPendingRequest() {
|
||||
return pendingRequests.pollLast();
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ public class BuddyList {
|
||||
if (pendingRequests.isEmpty()) {
|
||||
c.sendPacket(PacketCreator.requestBuddylistAdd(cidFrom, c.getPlayer().getId(), nameFrom));
|
||||
} else {
|
||||
pendingRequests.push(new CharacterNameAndId(cidFrom, nameFrom));
|
||||
pendingRequests.push(new CharacterIdentity(nameFrom, cidFrom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
66
src/main/java/client/CharacterStats.java
Normal file
66
src/main/java/client/CharacterStats.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package client;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@Builder
|
||||
public record CharacterStats(
|
||||
int account,
|
||||
int world,
|
||||
String name,
|
||||
int id,
|
||||
int level,
|
||||
int fame,
|
||||
int str,
|
||||
int dex,
|
||||
int luk,
|
||||
int int_,
|
||||
int exp,
|
||||
int gachaExp,
|
||||
int hp,
|
||||
int mp,
|
||||
int maxHp,
|
||||
int maxMp,
|
||||
int sp,
|
||||
int ap,
|
||||
int gmLevel,
|
||||
int skin,
|
||||
int gender,
|
||||
int job,
|
||||
int hair,
|
||||
int face,
|
||||
int mapId,
|
||||
int meso,
|
||||
int hpMpApUsed,
|
||||
int spawnPortal,
|
||||
Integer party,
|
||||
int buddyCapacity,
|
||||
Integer messenger,
|
||||
Integer messengerPosition,
|
||||
Integer mountLevel,
|
||||
Integer mountExp,
|
||||
Integer mountTiredness,
|
||||
int equipSlots,
|
||||
int useSlots,
|
||||
int setupSlots,
|
||||
int etcSlots,
|
||||
Integer monsterBookCover,
|
||||
Integer dojoVanquisherStage,
|
||||
int dojoPoints,
|
||||
Integer dojoStage,
|
||||
boolean dojoTutorialComplete,
|
||||
int dojoVanquisherKills,
|
||||
int matchCardWins,
|
||||
int matchCardLosses,
|
||||
int matchCardTies,
|
||||
int omokWins,
|
||||
int omokLosses,
|
||||
int omokTies,
|
||||
String dataString,
|
||||
Long jailExpiration,
|
||||
Integer partnerId,
|
||||
Integer marriageItemId,
|
||||
Long lastExpGainTime,
|
||||
int ariantPoints,
|
||||
boolean canRecvPartySearchInvite
|
||||
) {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
10
src/main/java/client/Gender.java
Normal file
10
src/main/java/client/Gender.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package client;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public class Gender {
|
||||
public static final byte MALE = 0;
|
||||
public static final byte FEMALE = 1;
|
||||
public static final byte NOT_SET = 10;
|
||||
}
|
||||
29
src/main/java/client/LoginState.java
Normal file
29
src/main/java/client/LoginState.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public enum LoginState {
|
||||
LOGGED_OUT(0),
|
||||
SERVER_TRANSITION(1),
|
||||
LOGGED_IN(2);
|
||||
|
||||
private final byte value;
|
||||
|
||||
LoginState(int value) {
|
||||
this.value = (byte) value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Optional<LoginState> fromValue(int value) {
|
||||
return Arrays.stream(values())
|
||||
.filter(v -> v.getValue() == value)
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@@ -1,225 +1,110 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package client;
|
||||
|
||||
import tools.DatabaseConnection;
|
||||
import database.monsterbook.MonsterCard;
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class MonsterBook {
|
||||
private int specialCard = 0;
|
||||
private int normalCard = 0;
|
||||
private int bookLevel = 1;
|
||||
private final Map<Integer, Integer> cards = new LinkedHashMap<>();
|
||||
private final Lock lock = new ReentrantLock();
|
||||
// TODO: add tests
|
||||
@ThreadSafe
|
||||
public class MonsterBook {
|
||||
private final Map<Integer, MonsterCard> cards;
|
||||
private int bookLevel;
|
||||
|
||||
public Set<Entry<Integer, Integer>> getCardSet() {
|
||||
lock.lock();
|
||||
try {
|
||||
return new HashSet<>(cards.entrySet());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
public MonsterBook(List<MonsterCard> monsterCards) {
|
||||
this.cards = monsterCards.stream()
|
||||
.collect(Collectors.toMap(MonsterCard::cardId, Function.identity()));
|
||||
}
|
||||
|
||||
public void addCard(final Client c, final int cardid) {
|
||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.showForeignCardEffect(c.getPlayer().getId()), false);
|
||||
public synchronized List<MonsterCard> getCards() {
|
||||
return new ArrayList<>(cards.values());
|
||||
}
|
||||
|
||||
Integer qty;
|
||||
lock.lock();
|
||||
try {
|
||||
qty = cards.get(cardid);
|
||||
|
||||
if (qty != null) {
|
||||
if (qty < 5) {
|
||||
cards.put(cardid, qty + 1);
|
||||
}
|
||||
} else {
|
||||
cards.put(cardid, 1);
|
||||
qty = 0;
|
||||
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
public synchronized void addCard(int cardId, Client client) {
|
||||
var monsterCard = cards.get(cardId);
|
||||
if (monsterCard != null && monsterCard.isMaxLevel()) {
|
||||
client.sendPacket(PacketCreator.addMonsterCardAlreadyFull());
|
||||
return;
|
||||
}
|
||||
|
||||
if (qty < 5) {
|
||||
if (qty == 0) { // leveling system only accounts unique cards
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
c.sendPacket(PacketCreator.addCard(false, cardid, qty + 1));
|
||||
c.sendPacket(PacketCreator.showGainCard());
|
||||
boolean isNewCard = monsterCard == null;
|
||||
final MonsterCard card;
|
||||
if (isNewCard) {
|
||||
card = new MonsterCard(cardId, (byte) 1);
|
||||
cards.put(cardId, card);
|
||||
calculateAndSetLevel();
|
||||
} else {
|
||||
c.sendPacket(PacketCreator.addCard(true, cardid, 5));
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
int collectionExp = (normalCard + specialCard);
|
||||
|
||||
int level = 0, expToNextlevel = 1;
|
||||
do {
|
||||
level++;
|
||||
expToNextlevel += level * 10;
|
||||
} while (collectionExp >= expToNextlevel);
|
||||
|
||||
bookLevel = level; // thanks IxianMace for noticing book level differing between book UI and character info UI
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBookLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
return bookLevel;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(cards);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard + normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getNormalCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSpecialCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCards(final int charid) throws SQLException {
|
||||
lock.lock();
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
|
||||
ps.setInt(1, charid);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
int cardid;
|
||||
int level;
|
||||
while (rs.next()) {
|
||||
cardid = rs.getInt("cardid");
|
||||
level = rs.getInt("level");
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
cards.put(cardid, level);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
card = new MonsterCard(cardId, (byte) (monsterCard.level() + 1));
|
||||
cards.put(cardId, card);
|
||||
}
|
||||
|
||||
calculateLevel();
|
||||
var chr = client.getPlayer();
|
||||
chr.sendPacket(PacketCreator.addMonsterCard(card));
|
||||
chr.sendPacket(PacketCreator.showMonsterCardEffect());
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.showForeignMonsterCardEffect(chr.getId()), false);
|
||||
}
|
||||
|
||||
public void saveCards(Connection con, int chrId) throws SQLException {
|
||||
private synchronized void calculateAndSetLevel() {
|
||||
int collectionExp = getTotalCards();
|
||||
|
||||
int level = 0;
|
||||
int expToNextLevel = 1;
|
||||
do {
|
||||
level++;
|
||||
expToNextLevel += level * 10;
|
||||
} while (collectionExp >= expToNextLevel);
|
||||
|
||||
this.bookLevel = level;
|
||||
}
|
||||
|
||||
public synchronized int getBookLevel() {
|
||||
return bookLevel;
|
||||
}
|
||||
|
||||
public synchronized int getNormalCards() {
|
||||
return (int) cards.values().stream()
|
||||
.filter(Predicate.not(MonsterCard::isSpecial))
|
||||
.count();
|
||||
}
|
||||
|
||||
public synchronized int getSpecialCards() {
|
||||
return (int) cards.values().stream()
|
||||
.filter(MonsterCard::isSpecial)
|
||||
.count();
|
||||
}
|
||||
|
||||
public synchronized int getTotalCards() {
|
||||
return cards.size();
|
||||
}
|
||||
|
||||
public synchronized void saveCards(Connection con, int chrId) throws SQLException {
|
||||
final String query = """
|
||||
INSERT INTO monsterbook (charid, cardid, level)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE level = ?;
|
||||
""";
|
||||
try (final PreparedStatement ps = con.prepareStatement(query)) {
|
||||
for (Map.Entry<Integer, Integer> cardAndLevel : cards.entrySet()) {
|
||||
final int card = cardAndLevel.getKey();
|
||||
final int level = cardAndLevel.getValue();
|
||||
for (MonsterCard card : cards.values()) {
|
||||
// insert
|
||||
ps.setInt(1, chrId);
|
||||
ps.setInt(2, card);
|
||||
ps.setInt(3, level);
|
||||
ps.setInt(2, card.cardId());
|
||||
ps.setInt(3, card.level());
|
||||
|
||||
// update
|
||||
ps.setInt(4, level);
|
||||
ps.setInt(4, card.level());
|
||||
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] getCardTierSize() {
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM monstercarddata GROUP BY floor(cardid / 1000);", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet rs = ps.executeQuery()) {
|
||||
rs.last();
|
||||
int[] tierSizes = new int[rs.getRow()];
|
||||
rs.beforeFirst();
|
||||
|
||||
while (rs.next()) {
|
||||
tierSizes[rs.getRow() - 1] = rs.getInt(1);
|
||||
}
|
||||
|
||||
return tierSizes;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +88,6 @@ public enum AutobanFactory {
|
||||
return expiretime;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanManager ban, String reason) {
|
||||
ban.addPoint(this, reason);
|
||||
}
|
||||
|
||||
public void alert(Character chr, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr != null && isIgnored(chr.getId())) {
|
||||
@@ -105,13 +101,6 @@ public enum AutobanFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public void autoban(Character chr, String value) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.autoban("Autobanned for (" + this.name() + ": " + value + ")");
|
||||
//chr.sendPolice("You will be disconnected for (" + this.name() + ": " + value + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle ignored status for a character id.
|
||||
* An ignored character will not trigger GM alerts.
|
||||
|
||||
@@ -7,6 +7,7 @@ package client.autoban;
|
||||
|
||||
import client.Character;
|
||||
import config.YamlConfig;
|
||||
import net.netty.GameViolationException;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -35,35 +36,27 @@ public class AutobanManager {
|
||||
this.chr = chr;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanFactory fac, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr.isGM() || chr.isBanned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTime.containsKey(fac)) {
|
||||
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||
}
|
||||
}
|
||||
if (fac.getExpire() != -1) {
|
||||
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||
}
|
||||
|
||||
if (points.containsKey(fac)) {
|
||||
points.put(fac, points.get(fac) + 1);
|
||||
} else {
|
||||
points.put(fac, 1);
|
||||
}
|
||||
|
||||
if (points.get(fac) >= fac.getMaximum()) {
|
||||
chr.autoban(reason);
|
||||
/**
|
||||
* @return true if the added point should result in an autoban
|
||||
*/
|
||||
public boolean addPoint(AutobanFactory fac) {
|
||||
if (lastTime.containsKey(fac)) {
|
||||
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||
}
|
||||
}
|
||||
if (YamlConfig.config.server.USE_AUTOBAN_LOG) {
|
||||
// Lets log every single point too.
|
||||
log.info("Autoban - chr {} caused {} {}", Character.makeMapleReadable(chr.getName()), fac.name(), reason);
|
||||
|
||||
if (fac.getExpire() != -1) {
|
||||
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||
}
|
||||
|
||||
if (points.containsKey(fac)) {
|
||||
points.put(fac, points.get(fac) + 1);
|
||||
} else {
|
||||
points.put(fac, 1);
|
||||
}
|
||||
|
||||
return points.get(fac) >= fac.getMaximum();
|
||||
}
|
||||
|
||||
public void addMiss() {
|
||||
@@ -118,11 +111,10 @@ public class AutobanManager {
|
||||
if (this.timestamp[type] == time) {
|
||||
this.timestampcounter[type]++;
|
||||
if (this.timestampcounter[type] >= times) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.getClient().disconnect(false, false);
|
||||
}
|
||||
|
||||
log.info("Autoban - Chr {} was caught spamming TYPE {} and has been disconnected", chr, type);
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
throw new GameViolationException("Auto ban");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.timestamp[type] = time;
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class Command {
|
||||
protected int rank;
|
||||
protected String description;
|
||||
|
||||
public abstract void execute(Client client, String[] params);
|
||||
public abstract void execute(Client client, String[] params, CommandContext ctx);
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
|
||||
19
src/main/java/client/command/CommandContext.java
Normal file
19
src/main/java/client/command/CommandContext.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package client.command;
|
||||
|
||||
import database.character.CharacterSaver;
|
||||
import database.drop.DropProvider;
|
||||
import server.shop.ShopFactory;
|
||||
import service.BanService;
|
||||
import service.TransitionService;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public record CommandContext(CommandsExecutor commandsExecutor, DropProvider dropProvider, ShopFactory shopFactory,
|
||||
CharacterSaver characterSaver, TransitionService transitionService, BanService banService
|
||||
) {
|
||||
|
||||
public CommandContext with(CommandsExecutor ce) {
|
||||
return new CommandContext(ce, dropProvider, shopFactory, characterSaver, transitionService, banService);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
package client.command;
|
||||
|
||||
import client.Client;
|
||||
import client.command.commands.gm0.ChangeLanguageCommand;
|
||||
import client.command.commands.gm0.DisposeCommand;
|
||||
import client.command.commands.gm0.DropLimitCommand;
|
||||
import client.command.commands.gm0.EnableAuthCommand;
|
||||
@@ -38,7 +37,6 @@ import client.command.commands.gm0.MapOwnerClaimCommand;
|
||||
import client.command.commands.gm0.OnlineCommand;
|
||||
import client.command.commands.gm0.RanksCommand;
|
||||
import client.command.commands.gm0.RatesCommand;
|
||||
import client.command.commands.gm0.ReadPointsCommand;
|
||||
import client.command.commands.gm0.ReportBugCommand;
|
||||
import client.command.commands.gm0.ShowRatesCommand;
|
||||
import client.command.commands.gm0.StaffCommand;
|
||||
@@ -106,8 +104,6 @@ import client.command.commands.gm3.FameCommand;
|
||||
import client.command.commands.gm3.FlyCommand;
|
||||
import client.command.commands.gm3.GiveMesosCommand;
|
||||
import client.command.commands.gm3.GiveNxCommand;
|
||||
import client.command.commands.gm3.GiveRpCommand;
|
||||
import client.command.commands.gm3.GiveVpCommand;
|
||||
import client.command.commands.gm3.HairCommand;
|
||||
import client.command.commands.gm3.HealMapCommand;
|
||||
import client.command.commands.gm3.HealPersonCommand;
|
||||
@@ -189,15 +185,10 @@ import client.command.commands.gm6.EraseAllPNpcsCommand;
|
||||
import client.command.commands.gm6.GetAccCommand;
|
||||
import client.command.commands.gm6.MapPlayersCommand;
|
||||
import client.command.commands.gm6.SaveAllCommand;
|
||||
import client.command.commands.gm6.ServerAddChannelCommand;
|
||||
import client.command.commands.gm6.ServerAddWorldCommand;
|
||||
import client.command.commands.gm6.ServerRemoveChannelCommand;
|
||||
import client.command.commands.gm6.ServerRemoveWorldCommand;
|
||||
import client.command.commands.gm6.SetGmLevelCommand;
|
||||
import client.command.commands.gm6.ShutdownCommand;
|
||||
import client.command.commands.gm6.SpawnAllPNpcsCommand;
|
||||
import client.command.commands.gm6.SupplyRateCouponCommand;
|
||||
import client.command.commands.gm6.WarpWorldCommand;
|
||||
import constants.id.MapId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -210,16 +201,27 @@ import java.util.List;
|
||||
|
||||
public class CommandsExecutor {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommandsExecutor.class);
|
||||
private static final CommandsExecutor instance = new CommandsExecutor();
|
||||
private static final char USER_HEADING = '@';
|
||||
private static final char GM_HEADING = '!';
|
||||
|
||||
private final HashMap<String, Command> registeredCommands = new HashMap<>();
|
||||
private final List<Pair<List<String>, List<String>>> commandsNameDesc = new ArrayList<>();
|
||||
private final CommandContext commandContext;
|
||||
private Pair<List<String>, List<String>> levelCommandsCursor;
|
||||
|
||||
public static CommandsExecutor getInstance() {
|
||||
return instance;
|
||||
public CommandsExecutor(CommandContext commandContext) {
|
||||
this.commandContext = commandContext.with(this);
|
||||
registerCommands();
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
registerLv0Commands();
|
||||
registerLv1Commands();
|
||||
registerLv2Commands();
|
||||
registerLv3Commands();
|
||||
registerLv4Commands();
|
||||
registerLv5Commands();
|
||||
registerLv6Commands();
|
||||
}
|
||||
|
||||
public static boolean isCommand(Client client, String content) {
|
||||
@@ -230,16 +232,6 @@ public class CommandsExecutor {
|
||||
return heading == USER_HEADING;
|
||||
}
|
||||
|
||||
private CommandsExecutor() {
|
||||
registerLv0Commands();
|
||||
registerLv1Commands();
|
||||
registerLv2Commands();
|
||||
registerLv3Commands();
|
||||
registerLv4Commands();
|
||||
registerLv5Commands();
|
||||
registerLv6Commands();
|
||||
}
|
||||
|
||||
public List<Pair<List<String>, List<String>>> getGmCommands() {
|
||||
return commandsNameDesc;
|
||||
}
|
||||
@@ -287,7 +279,7 @@ public class CommandsExecutor {
|
||||
params = new String[]{};
|
||||
}
|
||||
|
||||
command.execute(client, params);
|
||||
command.execute(client, params, commandContext);
|
||||
log.info("Chr {} used command {}", client.getPlayer().getName(), command.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@@ -347,14 +339,12 @@ public class CommandsExecutor {
|
||||
addCommand("uptime", UptimeCommand.class);
|
||||
addCommand("gacha", GachaCommand.class);
|
||||
addCommand("dispose", DisposeCommand.class);
|
||||
addCommand("changel", ChangeLanguageCommand.class);
|
||||
addCommand("equiplv", EquipLvCommand.class);
|
||||
addCommand("showrates", ShowRatesCommand.class);
|
||||
addCommand("rates", RatesCommand.class);
|
||||
addCommand("online", OnlineCommand.class);
|
||||
addCommand("gm", GmCommand.class);
|
||||
addCommand("reportbug", ReportBugCommand.class);
|
||||
addCommand("points", ReadPointsCommand.class);
|
||||
addCommand("joinevent", JoinEventCommand.class);
|
||||
addCommand("leaveevent", LeaveEventCommand.class);
|
||||
addCommand("ranks", RanksCommand.class);
|
||||
@@ -454,9 +444,7 @@ public class CommandsExecutor {
|
||||
addCommand("togglewhitechat", 3, ChatCommand.class);
|
||||
addCommand("fame", 3, FameCommand.class);
|
||||
addCommand("givenx", 3, GiveNxCommand.class);
|
||||
addCommand("givevp", 3, GiveVpCommand.class);
|
||||
addCommand("givems", 3, GiveMesosCommand.class);
|
||||
addCommand("giverp", 3, GiveRpCommand.class);
|
||||
addCommand("expeds", 3, ExpedsCommand.class);
|
||||
addCommand("kill", 3, KillCommand.class);
|
||||
addCommand("seed", 3, SeedCommand.class);
|
||||
@@ -542,7 +530,6 @@ public class CommandsExecutor {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("setgmlevel", 6, SetGmLevelCommand.class);
|
||||
addCommand("warpworld", 6, WarpWorldCommand.class);
|
||||
addCommand("saveall", 6, SaveAllCommand.class);
|
||||
addCommand("dcall", 6, DCAllCommand.class);
|
||||
addCommand("mapplayers", 6, MapPlayersCommand.class);
|
||||
@@ -553,10 +540,6 @@ public class CommandsExecutor {
|
||||
addCommand("supplyratecoupon", 6, SupplyRateCouponCommand.class);
|
||||
addCommand("spawnallpnpcs", 6, SpawnAllPNpcsCommand.class);
|
||||
addCommand("eraseallpnpcs", 6, EraseAllPNpcsCommand.class);
|
||||
addCommand("addchannel", 6, ServerAddChannelCommand.class);
|
||||
addCommand("addworld", 6, ServerAddWorldCommand.class);
|
||||
addCommand("removechannel", 6, ServerRemoveChannelCommand.class);
|
||||
addCommand("removeworld", 6, ServerRemoveWorldCommand.class);
|
||||
addCommand("devtest", 6, DevtestCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ChangeLanguageCommand extends Command {
|
||||
{
|
||||
setDescription("Change language settings.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (params.length < 1) {
|
||||
c.getPlayer().yellowMessage("Syntax: !changel <0=ptb, 1=esp, 2=eng>");
|
||||
return;
|
||||
}
|
||||
c.setLanguage(Integer.parseInt(params[0]));
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import scripting.npc.NPCScriptManager;
|
||||
import scripting.quest.QuestScriptManager;
|
||||
import tools.PacketCreator;
|
||||
@@ -35,7 +36,7 @@ public class DisposeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
NPCScriptManager.getInstance().dispose(c);
|
||||
QuestScriptManager.getInstance().dispose(c);
|
||||
c.sendPacket(PacketCreator.enableActions());
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class DropLimitCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class DropLimitCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
int dropCount = c.getPlayer().getMap().getDroppedItemCount();
|
||||
if (((float) dropCount) / YamlConfig.config.server.ITEM_LIMIT_ON_MAP < 0.75f) {
|
||||
c.getPlayer().showHint("Current drop count: #b" + dropCount + "#k / #e" + YamlConfig.config.server.ITEM_LIMIT_ON_MAP + "#n", 300);
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.coordinator.login.LoginBypassCoordinator;
|
||||
|
||||
public class EnableAuthCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class EnableAuthCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
LoginBypassCoordinator.getInstance().unregisterLoginBypassEntry(c.getHwid(), c.getAccID());
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class EquipLvCommand extends Command {
|
||||
{
|
||||
@@ -32,7 +33,7 @@ public class EquipLvCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getPlayer().showAllEquipFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.gachapon.Gachapon;
|
||||
@@ -35,7 +36,7 @@ public class GachaCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Gachapon.GachaponType gacha = null;
|
||||
String search = c.getPlayer().getLastCommandMessage();
|
||||
String gachaName = "";
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -40,7 +41,7 @@ public class GmCommand extends Command {
|
||||
private static final Logger log = LoggerFactory.getLogger(GmCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
String[] tips = {
|
||||
"Please only use @gm in emergencies or to report somebody.",
|
||||
"To report a bug or make a suggestion, use the forum.",
|
||||
|
||||
@@ -25,15 +25,19 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HelpCommand extends Command {
|
||||
{
|
||||
setDescription("Show available commands.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
client.getAbstractPlayerInteraction().openNpc(NpcId.STEWARD, "commands");
|
||||
public void execute(Client client, String[] params, CommandContext ctx) {
|
||||
Map<String, Object> bindings = Map.of("ce", ctx.commandsExecutor());
|
||||
client.getAbstractPlayerInteraction().openNpc(NpcId.STEWARD, "commands", bindings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.MapId;
|
||||
import server.events.gm.Event;
|
||||
import server.maps.FieldLimit;
|
||||
@@ -36,7 +37,7 @@ public class JoinEventCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (!FieldLimit.CANNOTMIGRATE.check(player.getMap().getFieldLimit())) {
|
||||
Event event = c.getChannelServer().getEvent();
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class LeaveEventCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class LeaveEventCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int returnMap = player.getSavedLocation("EVENT");
|
||||
if (returnMap != -1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class MapOwnerClaimCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
Character chr = c.getPlayer();
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class OnlineCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Channel ch : Server.getInstance().getChannelsFromWorld(player.getWorld())) {
|
||||
player.yellowMessage("Players in Channel " + ch.getId() + ":");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import net.server.Server;
|
||||
import net.server.guild.GuildPackets;
|
||||
@@ -39,7 +40,7 @@ public class RanksCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
List<Pair<String, Integer>> worldRanking = Server.getInstance().getWorldPlayerRanking(player.getWorld());
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class RatesCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class RatesCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
// travel rates not applicable since it's intrinsically a server/environment rate rather than a character rate
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ReadPointsCommand extends Command {
|
||||
{
|
||||
setDescription("Show point total.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
|
||||
Character player = client.getPlayer();
|
||||
if (params.length > 2) {
|
||||
player.yellowMessage("Syntax: @points (rp|vp|all)");
|
||||
return;
|
||||
} else if (params.length == 0) {
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (params[0]) {
|
||||
case "rp":
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints());
|
||||
break;
|
||||
case "vp":
|
||||
player.yellowMessage("VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
default:
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -39,7 +40,7 @@ public class ReportBugCommand extends Command {
|
||||
private static final Logger log = LoggerFactory.getLogger(ReportBugCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ShowRatesCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ShowRatesCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
String showMsg = "#eEXP RATE#n" + "\r\n";
|
||||
showMsg += "World EXP Rate: #k" + c.getWorldServer().getExpRate() + "x#k" + "\r\n";
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
|
||||
public class StaffCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class StaffCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getAbstractPlayerInteraction().openNpc(NpcId.HERACLE, "credits");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatDexCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatDexCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatIntCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatIntCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatLukCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatLukCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatStrCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatStrCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
int amount;
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -37,7 +38,7 @@ public class TimeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
public void execute(Client client, String[] params, CommandContext ctx) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getDefault());
|
||||
client.getPlayer().yellowMessage("Cosmic Server Time: " + dateFormat.format(new Date()));
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class ToggleExpCommand extends Command {
|
||||
{
|
||||
@@ -32,7 +33,7 @@ public class ToggleExpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
c.getPlayer().toggleExpGain(); // Vcoc's idea
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
@@ -38,7 +39,7 @@ public class UptimeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
long milliseconds = System.currentTimeMillis() - Server.uptime;
|
||||
int seconds = (int) (milliseconds / SECONDS.toMillis(1)) % 60;
|
||||
int minutes = (int) ((milliseconds / MINUTES.toMillis(1)) % 60);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.life.Monster;
|
||||
|
||||
public class BossHpCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class BossHpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.isBoss() && monster.getHp() > 0) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffMeCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class BuffMeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(4101004).getEffect(SkillFactory.getSkill(4101004).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(2311003).getEffect(SkillFactory.getSkill(2311003).getMaxLevel()).applyTo(player);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.game.GameConstants;
|
||||
import constants.id.NpcId;
|
||||
import server.maps.FieldLimit;
|
||||
@@ -77,7 +78,7 @@ public class GotoCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
String sendStr = "Syntax: #b@goto <map name>#k. Available areas:\r\n\r\n#rTowns:#k\r\n" + GOTO_TOWNS_INFO;
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.life.Monster;
|
||||
|
||||
public class MobHpCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class MobHpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.getHp() > 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterDropEntry;
|
||||
@@ -40,7 +41,7 @@ public class WhatDropsFromCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whatdropsfrom <monster name>");
|
||||
@@ -56,7 +57,7 @@ public class WhatDropsFromCommand extends Command {
|
||||
int mobId = data.getLeft();
|
||||
String mobName = data.getRight();
|
||||
output += mobName + " drops the following items:\r\n\r\n";
|
||||
for (MonsterDropEntry drop : MonsterInformationProvider.getInstance().retrieveDrop(mobId)) {
|
||||
for (MonsterDropEntry drop : ctx.dropProvider().getMonsterDropEntries(mobId)) {
|
||||
try {
|
||||
String name = ItemInformationProvider.getInstance().getName(drop.itemId);
|
||||
if (name == null || name.equals("null") || drop.chance == 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterInformationProvider;
|
||||
@@ -43,7 +44,7 @@ public class WhoDropsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whodrops <item name>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ApCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ApCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !ap [<playername>] <newap>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.MobId;
|
||||
import net.server.Server;
|
||||
import server.life.LifeFactory;
|
||||
@@ -37,7 +38,7 @@ public class BombCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length > 0) {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
|
||||
@@ -28,6 +28,7 @@ import client.Client;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffCommand extends Command {
|
||||
{
|
||||
@@ -35,7 +36,7 @@ public class BuffCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !buff <buffid>");
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffMapCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class BuffMapCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101001).getEffect(SkillFactory.getSkill(9101001).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(9101002).getEffect(SkillFactory.getSkill(9101002).getMaxLevel()).applyTo(player, true);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class ClearDropsCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class ClearDropsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
player.getMap().clearDrops(player);
|
||||
player.dropMessage(5, "Cleared dropped items");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.maps.SavedLocationType;
|
||||
|
||||
public class ClearSavedLocationsCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ClearSavedLocationsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer(), victim;
|
||||
|
||||
if (params.length > 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.manipulator.InventoryManipulator;
|
||||
@@ -36,7 +37,7 @@ public class ClearSlotCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !clearslot <all, equip, use, setup, etc or cash.>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class DcCommand extends Command {
|
||||
{
|
||||
@@ -33,21 +34,22 @@ public class DcCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !dc <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
String chrName = params[0];
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(chrName);
|
||||
if (victim == null) {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(chrName);
|
||||
if (victim == null) {
|
||||
victim = player.getMap().getCharacterByName(params[0]);
|
||||
victim = player.getMap().getCharacterByName(chrName);
|
||||
if (victim != null) {
|
||||
try {//sometimes bugged because the map = null
|
||||
victim.getClient().disconnect(true, false);
|
||||
ctx.transitionService().disconnect(victim.getClient(), true);
|
||||
player.getMap().removePlayer(victim);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -60,6 +62,6 @@ public class DcCommand extends Command {
|
||||
if (player.gmLevel() < victim.gmLevel()) {
|
||||
victim = player;
|
||||
}
|
||||
victim.getClient().disconnect(false, false);
|
||||
ctx.transitionService().disconnect(victim.getClient(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class EmpowerMeCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class EmpowerMeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
final int[] array = {2311003, 2301004, 1301007, 4101004, 2001002, 1101007, 1005, 2301003, 5121009, 1111002, 4111001, 4111002, 4211003, 4211005, 1321000, 2321004, 3121002};
|
||||
for (int i : array) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
@@ -31,7 +32,7 @@ public class GachaListCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getAbstractPlayerInteraction().openNpc(10000, "gachaponInfo");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,17 @@ package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.ShopFactory;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class GmShopCommand extends Command {
|
||||
{
|
||||
setDescription("Open the GM shop.");
|
||||
}
|
||||
|
||||
private static final int GM_SHOP_ID = 1337;
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
ShopFactory.getInstance().getShop(1337).sendShop(c);
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
ctx.shopFactory().getShop(GM_SHOP_ID).ifPresent(shop -> shop.sendShop(c));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class HealCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class HealCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
player.healHpMp();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class HideCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class HideCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101004).getEffect(SkillFactory.getSkill(9101004).getMaxLevel()).applyTo(player);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.game.NpcChat;
|
||||
import constants.id.NpcId;
|
||||
import server.ThreadManager;
|
||||
@@ -86,7 +87,7 @@ public class IdCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, final String[] params) {
|
||||
public void execute(Client client, final String[] params, CommandContext ctx) {
|
||||
final Character chr = client.getPlayer();
|
||||
if (params.length < 2) {
|
||||
chr.yellowMessage("Syntax: !id <type> <query>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import client.inventory.Pet;
|
||||
import client.inventory.manipulator.InventoryManipulator;
|
||||
import config.YamlConfig;
|
||||
@@ -40,7 +41,7 @@ public class ItemCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.Pet;
|
||||
@@ -41,7 +42,7 @@ public class ItemDropCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.MapId;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.Portal;
|
||||
@@ -38,7 +39,7 @@ public class JailCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !jail <playername> [<minutes>]");
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.Job;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class JobCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class JobCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length == 1) {
|
||||
int jobid = Integer.parseInt(params[0]);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class LevelCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class LevelCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !level <newlevel>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class LevelProCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class LevelProCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !levelpro <newlevel>");
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.maps.MapItem;
|
||||
import server.maps.MapObject;
|
||||
import server.maps.MapObjectType;
|
||||
@@ -39,7 +40,7 @@ public class LootCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
List<MapObject> items = c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.ITEM));
|
||||
for (MapObject item : items) {
|
||||
MapItem mapItem = (MapItem) item;
|
||||
|
||||
@@ -29,6 +29,7 @@ import client.Job;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import provider.Data;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.wz.WZFiles;
|
||||
@@ -39,7 +40,7 @@ public class MaxSkillCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) {
|
||||
try {
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.Stat;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class MaxStatCommand extends Command {
|
||||
@@ -35,7 +36,7 @@ public class MaxStatCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
player.loseExp(player.getExp(), false, false);
|
||||
player.setLevel(255);
|
||||
|
||||
@@ -3,6 +3,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.life.MobSkill;
|
||||
import server.life.MobSkillFactory;
|
||||
import server.life.MobSkillType;
|
||||
@@ -16,7 +17,7 @@ public class MobSkillCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
public void execute(Client client, String[] params, CommandContext ctx) {
|
||||
if (params.length < 2) {
|
||||
throw new IllegalArgumentException("Mob skill command requires two args: mob skill id and level");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
public class ReachCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ReachCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !reach <playername>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import constants.inventory.ItemConstants;
|
||||
@@ -37,7 +38,7 @@ public class RechargeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
ItemInformationProvider ii = ItemInformationProvider.getInstance();
|
||||
for (Item torecharge : c.getPlayer().getInventory(InventoryType.USE).list()) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import client.Job;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import provider.Data;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.wz.WZFiles;
|
||||
@@ -39,7 +40,7 @@ public class ResetSkillCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) {
|
||||
try {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import provider.Data;
|
||||
import provider.DataProvider;
|
||||
@@ -53,7 +54,7 @@ public class SearchCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 2) {
|
||||
player.yellowMessage("Syntax: !search <type> <name>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class SetSlotCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class SetSlotCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !setslot <newlevel>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class SetStatCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class SetStatCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !setstat <newstat>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class SpCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class SpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !sp [<playername>] <newsp>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
import server.maps.MapleMap;
|
||||
@@ -36,7 +37,7 @@ public class SummonCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !warphere <playername>");
|
||||
@@ -62,7 +63,7 @@ public class SummonCommand extends Command {
|
||||
|
||||
if (player.getClient().getChannel() != victim.getClient().getChannel()) {//And then change channel if needed.
|
||||
victim.dropMessage("Changing channel, please wait a moment.");
|
||||
victim.getClient().changeChannel(player.getClient().getChannel());
|
||||
ctx.transitionService().changeChannel(victim.getClient(), player.getClient().getChannel());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user