mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-05-20 08:26:59 -04:00
Compare commits
480
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63f0b024ac | ||
|
|
67db1035ed | ||
|
|
c865975df7 | ||
|
|
aef0f2b400 | ||
|
|
16c62a08d8 | ||
|
|
6cb107870f | ||
|
|
9a2f8ef89a | ||
|
|
524f415b44 | ||
|
|
5c0d2c1d7f | ||
|
|
a7b1b79461 | ||
|
|
c3b4735cc5 | ||
|
|
ac22637b4f | ||
|
|
01d05b5cee | ||
|
|
d50bfef2e5 | ||
|
|
a5a039ce3d | ||
|
|
514610f006 | ||
|
|
159242068d | ||
|
|
a6ee42094c | ||
|
|
6bbe272d48 | ||
|
|
938cca0298 | ||
|
|
e53e54b4bf | ||
|
|
f6ff56299f | ||
|
|
a1bb84e80d | ||
|
|
4d2c80a8ee | ||
|
|
c2169576c2 | ||
|
|
4d424e57f9 | ||
|
|
4494b30285 | ||
|
|
74713f3dd6 | ||
|
|
b08827568c | ||
|
|
b34f214e67 | ||
|
|
e94c037fb5 | ||
|
|
65ee91e49c | ||
|
|
01ec313ffb | ||
|
|
ebba56602c | ||
|
|
49c6fdbd51 | ||
|
|
08557f41fb | ||
|
|
a618e69dbd | ||
|
|
02fe9e070d | ||
|
|
bf20993e58 | ||
|
|
2817560217 | ||
|
|
765cf194c5 | ||
|
|
b57f91470a | ||
|
|
2cb6a9f6bd | ||
|
|
b773098abf | ||
|
|
f491c63b98 | ||
|
|
023527efa3 | ||
|
|
96f9119cca | ||
|
|
f84899ff2e | ||
|
|
a87244d13b | ||
|
|
c5198783a1 | ||
|
|
b9ab842fdd | ||
|
|
e8ee907477 | ||
|
|
b4227cdc44 | ||
|
|
59f4e4bbd5 | ||
|
|
c9f18f5415 | ||
|
|
495bdf4ba6 | ||
|
|
b46160763c | ||
|
|
3393eb4c9d | ||
|
|
7de153dde1 | ||
|
|
0faa056589 | ||
|
|
90115f7c83 | ||
|
|
682ddd9cae | ||
|
|
8c70d0ddb6 | ||
|
|
5c49563790 | ||
|
|
c6a372ad83 | ||
|
|
d2e814b4ee | ||
|
|
0cdeb5d9ac | ||
|
|
fac8f269e7 | ||
|
|
d06152be07 | ||
|
|
0b67f8e436 | ||
|
|
7fea45e1f8 | ||
|
|
696d355ae9 | ||
|
|
bbbab356af | ||
|
|
594e08f990 | ||
|
|
89287844f7 | ||
|
|
c240096eb8 | ||
|
|
08e7a9cfd4 | ||
|
|
25f1b0fd95 | ||
|
|
c677479a03 | ||
|
|
306f4ef346 | ||
|
|
a2c4d077e9 | ||
|
|
7e5ca6e013 | ||
|
|
02cb0a3f43 | ||
|
|
dc1458c52d | ||
|
|
1523ae200b | ||
|
|
aae051d73f | ||
|
|
9097e557ed | ||
|
|
cfe6ef2e5e | ||
|
|
d26aaed953 | ||
|
|
8d5f4465e3 | ||
|
|
214d730a58 | ||
|
|
b6c9825b2d | ||
|
|
acf953e909 | ||
|
|
4fe8f77887 | ||
|
|
96cb8070be | ||
|
|
9f077190a3 | ||
|
|
0465bf6b8d | ||
|
|
0ac53e23ad | ||
|
|
e6d5d5a530 | ||
|
|
335efcc81e | ||
|
|
fb9d4026a5 | ||
|
|
68a2685cf1 | ||
|
|
8b3431e557 | ||
|
|
b11007b263 | ||
|
|
2cbb48621b | ||
|
|
f574f5b103 | ||
|
|
8d647ae6b0 | ||
|
|
f374ee3be9 | ||
|
|
37d04344ae | ||
|
|
68e55a1c76 | ||
|
|
4e0cf36552 | ||
|
|
4e5a07afa4 | ||
|
|
563118372a | ||
|
|
4fc5762d41 | ||
|
|
56ba641e2a | ||
|
|
3ad30460d8 | ||
|
|
ff074c8394 | ||
|
|
bad51717c2 | ||
|
|
26fd79bea5 | ||
|
|
6e869af4fb | ||
|
|
93c90df797 | ||
|
|
c38caffaf1 | ||
|
|
958a87edf2 | ||
|
|
2279ee7017 | ||
|
|
df49eefadb | ||
|
|
6e1f13d17a | ||
|
|
bbf49123b6 | ||
|
|
48d996bd4f | ||
|
|
8ddcd24704 | ||
|
|
1c5fd48d03 | ||
|
|
31ec4efdcf | ||
|
|
20b1ec18a9 | ||
|
|
41b891feaf | ||
|
|
47a2eddaf0 | ||
|
|
2e5cf8dfec | ||
|
|
eecb5ac8a1 | ||
|
|
99c8aff702 | ||
|
|
d588dd0348 | ||
|
|
7883143089 | ||
|
|
c753e61b62 | ||
|
|
42f0046ee7 | ||
|
|
aa54fb11cc | ||
|
|
e4d43d952b | ||
|
|
ae3a6f1b27 | ||
|
|
5724cf53bf | ||
|
|
0ec9c5576c | ||
|
|
96641865bc | ||
|
|
ea7bf4b86d | ||
|
|
94d1915acb | ||
|
|
02e41f6103 | ||
|
|
b627ecf0fe | ||
|
|
ca4f00cfe3 | ||
|
|
8687e43191 | ||
|
|
d3027c3b26 | ||
|
|
afd056d82d | ||
|
|
e6802d514c | ||
|
|
66ed26617d | ||
|
|
f5bf5956b2 | ||
|
|
c14b117947 | ||
|
|
91549bff7a | ||
|
|
18ef69f3d1 | ||
|
|
104f3daf7c | ||
|
|
b85b35a2b6 | ||
|
|
0f61c4c0e1 | ||
|
|
7587a6e142 | ||
|
|
8940e65885 | ||
|
|
29ec6a9a88 | ||
|
|
3e26c491d4 | ||
|
|
9fd0e96b0e | ||
|
|
a9619a4b3c | ||
|
|
8276c5c247 | ||
|
|
e9b3f4e51e | ||
|
|
187d8300b0 | ||
|
|
8da65938b7 | ||
|
|
a92b558c88 | ||
|
|
57f3de66f8 | ||
|
|
561114833c | ||
|
|
324026874a | ||
|
|
dbdff59e0f | ||
|
|
a996797beb | ||
|
|
32330d557c | ||
|
|
ec85cfd590 | ||
|
|
89c6191710 | ||
|
|
eb43a7523d | ||
|
|
f5ebb3fb3b | ||
|
|
8a03c40af9 | ||
|
|
a07aa12783 | ||
|
|
e91960040c | ||
|
|
fea8638775 | ||
|
|
c286df6a91 | ||
|
|
3dcd9af6c0 | ||
|
|
4fbc388457 | ||
|
|
f2e34174c4 | ||
|
|
90078eb2e8 | ||
|
|
7339e08172 | ||
|
|
1fddfd50a6 | ||
|
|
2e906ae090 | ||
|
|
8ba3c195f2 | ||
|
|
e96cc0c758 | ||
|
|
2195b0b7dc | ||
|
|
ecf07317fc | ||
|
|
69d4b19979 | ||
|
|
fdb767f155 | ||
|
|
e1c86a4898 | ||
|
|
88ff22e55e | ||
|
|
d49516c03e | ||
|
|
42ee97d467 | ||
|
|
8f92fde00e | ||
|
|
3104478263 | ||
|
|
a92ece58c1 | ||
|
|
6fcfd58b33 | ||
|
|
905cbf7d3c | ||
|
|
4c850ea768 | ||
|
|
afe1e59889 | ||
|
|
f3fe8c1de8 | ||
|
|
4e054ca947 | ||
|
|
eb949a8602 | ||
|
|
315452d121 | ||
|
|
1a9a8c2116 | ||
|
|
97dcd765eb | ||
|
|
e00bb48386 | ||
|
|
ef117204b3 | ||
|
|
9cda72f1ab | ||
|
|
a99a129d9a | ||
|
|
6ae181fa0a | ||
|
|
1f3c98312c | ||
|
|
db0aac3647 | ||
|
|
00017468cc | ||
|
|
4f80023156 | ||
|
|
6127ad44cc | ||
|
|
d7c383d04a | ||
|
|
357805d04c | ||
|
|
706a9fa721 | ||
|
|
289e4dc24b | ||
|
|
a458608322 | ||
|
|
3e58cdbd6c | ||
|
|
3068a0c41b | ||
|
|
26ef649a6c | ||
|
|
cc07e1f453 | ||
|
|
75c6708ac5 | ||
|
|
ee1f4b0888 | ||
|
|
f6104812a5 | ||
|
|
d0dca62a91 | ||
|
|
3b451849ae | ||
|
|
9889b6011b | ||
|
|
9b566abb3d | ||
|
|
37cca32de8 | ||
|
|
02e1b8a82f | ||
|
|
267961233f | ||
|
|
d673670604 | ||
|
|
b955c38a2a | ||
|
|
044d7e5207 | ||
|
|
c1fdad2156 | ||
|
|
f038b525c6 | ||
|
|
bcb609e4f6 | ||
|
|
163f240cf9 | ||
|
|
3066efeebb | ||
|
|
10017b7e8c | ||
|
|
1e4a1cf263 | ||
|
|
080f9ea23d | ||
|
|
e236e1d207 | ||
|
|
1b69f5fc87 | ||
|
|
e4956edf50 | ||
|
|
384d134f1d | ||
|
|
f361ee61cd | ||
|
|
7e6e51c6bf | ||
|
|
5bdc760a5f | ||
|
|
83ae7df6d9 | ||
|
|
7c7742fb35 | ||
|
|
c55145d715 | ||
|
|
42aa3d7512 | ||
|
|
07c467e1af | ||
|
|
bec0cae0eb | ||
|
|
5bb3cc3b4e | ||
|
|
d614ea6968 | ||
|
|
1579aa3d6a | ||
|
|
cf30eef39e | ||
|
|
8c5375f609 | ||
|
|
c442dc9ecd | ||
|
|
ace4dfe58f | ||
|
|
79f2edf406 | ||
|
|
0209f3e617 | ||
|
|
e799e8327f | ||
|
|
0f7e6f359d | ||
|
|
0739532c7d | ||
|
|
d23a84d6cf | ||
|
|
8de606051a | ||
|
|
a7e59fa7e4 | ||
|
|
922fb80f3d | ||
|
|
8c9f841d63 | ||
|
|
c5ce2ec771 | ||
|
|
0492bc4c59 | ||
|
|
7abfbd5953 | ||
|
|
1d3dd99414 | ||
|
|
c3c19c3592 | ||
|
|
a19517cce4 | ||
|
|
880b1f3066 | ||
|
|
0b13b590a0 | ||
|
|
8aeaee1b19 | ||
|
|
29e3f61b6b | ||
|
|
bbd4fcef3b | ||
|
|
13727caf14 | ||
|
|
aba748cb5d | ||
|
|
611140568e | ||
|
|
08dfd22bfa | ||
|
|
5fd48fad6b | ||
|
|
7e2246e8d8 | ||
|
|
1e9d61c838 | ||
|
|
b8d6a943aa | ||
|
|
f30360f245 | ||
|
|
359ea8a40e | ||
|
|
127ac15936 | ||
|
|
0cb2fe1a68 | ||
|
|
c0312079ef | ||
|
|
a9d4e621e3 | ||
|
|
08c5980b22 | ||
|
|
f5ea82f735 | ||
|
|
81c97105b7 | ||
|
|
837c7a9223 | ||
|
|
cd60c571ac | ||
|
|
205d3619d6 | ||
|
|
1275c8b5da | ||
|
|
b2e273d7cf | ||
|
|
88233cf6d2 | ||
|
|
05eca7f22e | ||
|
|
7a02d38e94 | ||
|
|
af121f52bd | ||
|
|
e8c9904e1d | ||
|
|
bbac4b0fce | ||
|
|
3850860440 | ||
|
|
bb31bb0f23 | ||
|
|
b191da416b | ||
|
|
2a489953db | ||
|
|
fe4b9cb2bf | ||
|
|
95b003cc2b | ||
|
|
27200b8df5 | ||
|
|
520ae7a119 | ||
|
|
460722d3d5 | ||
|
|
92de857cda | ||
|
|
4323eb5385 | ||
|
|
324ebab2d2 | ||
|
|
5ccc2435b0 | ||
|
|
13708a2361 | ||
|
|
59e3b2379a | ||
|
|
9fc99faa5c | ||
|
|
116a573f85 | ||
|
|
a0c4d80c5e | ||
|
|
8ae4fbc045 | ||
|
|
e819603432 | ||
|
|
bab81a809c | ||
|
|
441c1a6383 | ||
|
|
58334a0e5f | ||
|
|
94491903f7 | ||
|
|
f3a823af03 | ||
|
|
5dfbc0f249 | ||
|
|
ab98f3662f | ||
|
|
33f8709d76 | ||
|
|
56491266cc | ||
|
|
c7e38b8b00 | ||
|
|
9649d755a9 | ||
|
|
e581727625 | ||
|
|
06e0c32062 | ||
|
|
77203bca4c | ||
|
|
7b1f95cd77 | ||
|
|
ba8184db89 | ||
|
|
da621dfc0e | ||
|
|
ce5030acd1 | ||
|
|
a309e651da | ||
|
|
16e99040e0 | ||
|
|
3f82ca1244 | ||
|
|
8f487689ba | ||
|
|
b092d447cc | ||
|
|
4160622556 | ||
|
|
64006d2351 | ||
|
|
52c707d66e | ||
|
|
9174801fdb | ||
|
|
9529a1374e | ||
|
|
8755ca4f33 | ||
|
|
a14e36fadc | ||
|
|
bc95c139de | ||
|
|
40ad1d8a29 | ||
|
|
76f073d85f | ||
|
|
9077c60b96 | ||
|
|
645a1fb4fb | ||
|
|
7c30b95c4b | ||
|
|
2bfaf376ef | ||
|
|
68a2d5f0b9 | ||
|
|
5bec522c8e | ||
|
|
81d82cd7a8 | ||
|
|
f437b36f5a | ||
|
|
b5054debea | ||
|
|
4e39b082f1 | ||
|
|
62484e2f87 | ||
|
|
50b4f517f2 | ||
|
|
2b5a6997f4 | ||
|
|
4978813c27 | ||
|
|
6e1983031b | ||
|
|
c5cc7c2f00 | ||
|
|
4762811347 | ||
|
|
c55acba1b6 | ||
|
|
4c7928da78 | ||
|
|
517bdc0638 | ||
|
|
2cee5ff573 | ||
|
|
c3fd8f917e | ||
|
|
91afda04ca | ||
|
|
e60da4f7b4 | ||
|
|
67485eafc0 | ||
|
|
d81832f256 | ||
|
|
7ad40f625a | ||
|
|
71d5bbc9ff | ||
|
|
37b8203dae | ||
|
|
f4016e1a12 | ||
|
|
6c74222b68 | ||
|
|
7e4fc52b9e | ||
|
|
e5a9658b5a | ||
|
|
6f5a480cbd | ||
|
|
ce2d22d984 | ||
|
|
52da0a671f | ||
|
|
922f3ccd1e | ||
|
|
c070f5b80e | ||
|
|
1ae15df64c | ||
|
|
9024f3fad6 | ||
|
|
452f1cc8c0 | ||
|
|
11bbb023d9 | ||
|
|
88abd59ec3 | ||
|
|
5e2487c8cc | ||
|
|
9bb298b2f3 | ||
|
|
cbbfa4ed95 | ||
|
|
54af893570 | ||
|
|
c79b5c9992 | ||
|
|
e390138258 | ||
|
|
35f9251056 | ||
|
|
86bf0eec81 | ||
|
|
ebd295bfa4 | ||
|
|
a89fc64555 | ||
|
|
1856cc0634 | ||
|
|
68657e1edc | ||
|
|
c7b87c0d89 | ||
|
|
8bebba64b3 | ||
|
|
ddad27a5f9 | ||
|
|
53207a9ff0 | ||
|
|
d9d185d7e6 | ||
|
|
13af16ec0e | ||
|
|
f4687942af | ||
|
|
7c08420206 | ||
|
|
3734f22fc2 | ||
|
|
7ab40a30f1 | ||
|
|
4032258e76 | ||
|
|
4dee26e136 | ||
|
|
86a2e4aff3 | ||
|
|
b2e86d282a | ||
|
|
efdec5e472 | ||
|
|
84d5eee1fc | ||
|
|
59fab08230 | ||
|
|
1637bba167 | ||
|
|
4ed8f3e5e2 | ||
|
|
c55c0b327d | ||
|
|
4695193aa0 | ||
|
|
247b5ca709 | ||
|
|
d895357182 | ||
|
|
cc1929a9fb | ||
|
|
100f3ae156 | ||
|
|
e56238a10c | ||
|
|
62055eff04 | ||
|
|
6b023ceb3c | ||
|
|
637f7f3d95 | ||
|
|
c162fb0eab | ||
|
|
2c9ae60bbf | ||
|
|
b9bfe5e985 | ||
|
|
3bcaa4cc3e | ||
|
|
04890660c0 | ||
|
|
c70cf022b7 | ||
|
|
872e56f8f9 | ||
|
|
b640c87c69 | ||
|
|
dd552ba69d | ||
|
|
e09cb197b3 | ||
|
|
a62475e81e | ||
|
|
bd97e72774 | ||
|
|
4ad37f1011 | ||
|
|
d72a2af641 |
No files matched your search
@@ -15,7 +15,6 @@
|
|||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
[Rr]elease/
|
[Rr]elease/
|
||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
|
|||||||
@@ -1,13 +1,35 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using Ionic.Zlib;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
using Ionic.Zlib;
|
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct BasePacketHeader
|
public struct BasePacketHeader
|
||||||
@@ -242,6 +264,13 @@ namespace FFXIVClassic.Common
|
|||||||
offset += (ushort)subpacketData.Length;
|
offset += (ushort)subpacketData.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Compress this array into a new one if needed
|
||||||
|
if (isCompressed)
|
||||||
|
{
|
||||||
|
data = CompressData(data);
|
||||||
|
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);
|
Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);
|
||||||
|
|
||||||
var packet = new BasePacket(header, data);
|
var packet = new BasePacket(header, data);
|
||||||
@@ -266,7 +295,15 @@ namespace FFXIVClassic.Common
|
|||||||
data = new byte[header.packetSize - 0x10];
|
data = new byte[header.packetSize - 0x10];
|
||||||
|
|
||||||
//Add Subpackets
|
//Add Subpackets
|
||||||
var subpacketData = subpacket.GetBytes();
|
byte[] subpacketData = subpacket.GetBytes();
|
||||||
|
|
||||||
|
//Compress this array into a new one if needed
|
||||||
|
if (isCompressed)
|
||||||
|
{
|
||||||
|
subpacketData = CompressData(subpacketData);
|
||||||
|
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);
|
Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);
|
||||||
|
|
||||||
Debug.Assert(data != null);
|
Debug.Assert(data != null);
|
||||||
@@ -291,6 +328,13 @@ namespace FFXIVClassic.Common
|
|||||||
//Get packet size
|
//Get packet size
|
||||||
header.packetSize += (ushort) data.Length;
|
header.packetSize += (ushort) data.Length;
|
||||||
|
|
||||||
|
//Compress this array into a new one if needed
|
||||||
|
if (isCompressed)
|
||||||
|
{
|
||||||
|
data = CompressData(data);
|
||||||
|
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
var packet = new BasePacket(header, data);
|
var packet = new BasePacket(header, data);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@@ -390,17 +434,31 @@ namespace FFXIVClassic.Common
|
|||||||
{
|
{
|
||||||
zipStream.CopyTo(resultStream);
|
zipStream.CopyTo(resultStream);
|
||||||
packet.data = resultStream.ToArray();
|
packet.data = resultStream.ToArray();
|
||||||
|
packet.header.isCompressed = 0;
|
||||||
|
packet.header.packetSize = (ushort)(BASEPACKET_SIZE + packet.data.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe void CompressPacket(ref BasePacket packet)
|
public static unsafe BasePacket CompressPacket(BasePacket uncompressedPacket)
|
||||||
{
|
{
|
||||||
using (var compressedStream = new MemoryStream(packet.data))
|
using (var compressedStream = new MemoryStream(uncompressedPacket.data))
|
||||||
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
||||||
using (var resultStream = new MemoryStream())
|
using (var resultStream = new MemoryStream())
|
||||||
{
|
{
|
||||||
zipStream.CopyTo(resultStream);
|
zipStream.CopyTo(resultStream);
|
||||||
packet.data = resultStream.ToArray();
|
BasePacket compressedPacket = BasePacket.CreatePacket(resultStream.ToArray(), uncompressedPacket.header.isAuthenticated == 1, true);
|
||||||
|
return compressedPacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe byte[] CompressData(byte[] data)
|
||||||
|
{
|
||||||
|
using (var compressedStream = new MemoryStream(data))
|
||||||
|
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
||||||
|
using (var resultStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
zipStream.CopyTo(resultStream);
|
||||||
|
return resultStream.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,27 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||||
public sealed class BitfieldLengthAttribute : Attribute
|
public sealed class BitfieldLengthAttribute : Attribute
|
||||||
@@ -60,7 +81,7 @@ namespace FFXIVClassic.Common
|
|||||||
// Calculate a bitmask of the desired length
|
// Calculate a bitmask of the desired length
|
||||||
long mask = 0;
|
long mask = 0;
|
||||||
for (int i = 0; i < fieldLength; i++)
|
for (int i = 0; i < fieldLength; i++)
|
||||||
mask |= 1 << i;
|
mask |= 1L << i;
|
||||||
|
|
||||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||||
|
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
|
{
|
||||||
|
public class Bitstream
|
||||||
|
{
|
||||||
|
private byte[] Data;
|
||||||
|
|
||||||
|
public Bitstream(uint numBits, bool setAllTrue = false)
|
||||||
|
{
|
||||||
|
Debug.Assert(numBits % 8 == 0);
|
||||||
|
Debug.Assert(numBits % 4 == 0);
|
||||||
|
Data = new byte[numBits / 8];
|
||||||
|
|
||||||
|
if (setAllTrue)
|
||||||
|
SetAll(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitstream(bool[] boolArray)
|
||||||
|
{
|
||||||
|
Data = Utils.ConvertBoolArrayToBinaryStream(boolArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitstream(byte[] byteArray)
|
||||||
|
{
|
||||||
|
Data = byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAll(bool to)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] = Data[i + 1] = Data[i + 2] = Data[i + 3] = (byte)(to ? 0xFF : 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTo(Bitstream result)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == result.Data.Length);
|
||||||
|
for (int i = 0; i < result.Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] = result.Data[i];
|
||||||
|
Data[i + 1] = result.Data[i + 1];
|
||||||
|
Data[i + 2] = result.Data[i + 2];
|
||||||
|
Data[i + 3] = result.Data[i + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTo(bool[] result)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == result.Length / 8);
|
||||||
|
Data = Utils.ConvertBoolArrayToBinaryStream(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Get(uint at)
|
||||||
|
{
|
||||||
|
return Get((int)at);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Get(int at)
|
||||||
|
{
|
||||||
|
int bytePos = at / 8;
|
||||||
|
int bitPos = at % 8;
|
||||||
|
|
||||||
|
return (Data[bytePos] & (1 << bitPos)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(uint at)
|
||||||
|
{
|
||||||
|
Set((int)at);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(int at)
|
||||||
|
{
|
||||||
|
int bytePos = at / 8;
|
||||||
|
int bitPos = at % 8;
|
||||||
|
Data[bytePos] |= (byte)(1 << bitPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(uint at)
|
||||||
|
{
|
||||||
|
Clear((int)at);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(int at)
|
||||||
|
{
|
||||||
|
int bytePos = at / 8;
|
||||||
|
int bitPos = at % 8;
|
||||||
|
Data[bytePos] &= (byte)~(1 << bitPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NOT()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] = (byte)~Data[i];
|
||||||
|
Data[i + 1] = (byte)~Data[i + 1];
|
||||||
|
Data[i + 2] = (byte)~Data[i + 2];
|
||||||
|
Data[i + 3] = (byte)~Data[i + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OR(Bitstream other)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == other.Data.Length);
|
||||||
|
for (int i = 0; i < Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] |= other.Data[i];
|
||||||
|
Data[i + 1] |= other.Data[i + 1];
|
||||||
|
Data[i + 2] |= other.Data[i + 2];
|
||||||
|
Data[i + 3] |= other.Data[i + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AND(Bitstream other)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == other.Data.Length);
|
||||||
|
for (int i = 0; i < Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] &= other.Data[i];
|
||||||
|
Data[i + 1] &= other.Data[i + 1];
|
||||||
|
Data[i + 2] &= other.Data[i + 2];
|
||||||
|
Data[i + 3] &= other.Data[i + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void XOR(Bitstream other)
|
||||||
|
{
|
||||||
|
Debug.Assert(Data.Length == other.Data.Length);
|
||||||
|
for (int i = 0; i < Data.Length; i += 4)
|
||||||
|
{
|
||||||
|
Data[i] ^= other.Data[i];
|
||||||
|
Data[i + 1] ^= other.Data[i + 1];
|
||||||
|
Data[i + 2] ^= other.Data[i + 2];
|
||||||
|
Data[i + 3] ^= other.Data[i + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitstream Copy()
|
||||||
|
{
|
||||||
|
byte[] copy = new byte[Data.Length];
|
||||||
|
Array.Copy(Data, copy, Data.Length);
|
||||||
|
return new Bitstream(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetBytes()
|
||||||
|
{
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetSlice(ushort from, ushort to)
|
||||||
|
{
|
||||||
|
int remainder = ((to - from) % 8 != 0) ? 1 : 0;
|
||||||
|
byte[] toReturn = new byte[((to - from) / 8) + remainder + 1];
|
||||||
|
toReturn[toReturn.Length - 1] = 0x3;
|
||||||
|
|
||||||
|
|
||||||
|
byte curByte = 0;
|
||||||
|
|
||||||
|
int destByteIndx = 0;
|
||||||
|
int destShiftIndx = 0;
|
||||||
|
int srcByteIndx = from / 8;
|
||||||
|
int srcShiftIndx = from % 8;
|
||||||
|
|
||||||
|
for (int i = from; i <= to; i++)
|
||||||
|
{
|
||||||
|
// Skip Zeros
|
||||||
|
if (Data[srcByteIndx] == 0)
|
||||||
|
{
|
||||||
|
srcByteIndx++;
|
||||||
|
srcShiftIndx = 0;
|
||||||
|
destByteIndx++;
|
||||||
|
i += 8;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool val = (Data[srcByteIndx] & (1 << srcShiftIndx++)) != 0;
|
||||||
|
|
||||||
|
curByte |= (byte)((val ? 1 : 0) << destShiftIndx++);
|
||||||
|
if (srcShiftIndx == 8)
|
||||||
|
{
|
||||||
|
srcShiftIndx = 0;
|
||||||
|
srcByteIndx++;
|
||||||
|
}
|
||||||
|
if (destShiftIndx == 8)
|
||||||
|
{
|
||||||
|
toReturn[destByteIndx++] = curByte;
|
||||||
|
destShiftIndx = 0;
|
||||||
|
curByte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destByteIndx == toReturn.Length - 2)
|
||||||
|
toReturn[destByteIndx] = curByte;
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,27 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
public class Blowfish
|
public class Blowfish
|
||||||
{
|
{
|
||||||
+33
-5
@@ -8,9 +8,9 @@
|
|||||||
<ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid>
|
<ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>FFXIVClassic.Common</RootNamespace>
|
<RootNamespace>Meteor.Common</RootNamespace>
|
||||||
<AssemblyName>FFXIVClassic.Common</AssemblyName>
|
<AssemblyName>Meteor.Common</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
</TargetFrameworkProfile>
|
</TargetFrameworkProfile>
|
||||||
@@ -36,6 +36,27 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="DotNetZip">
|
<Reference Include="DotNetZip">
|
||||||
@@ -46,11 +67,16 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.5.0\lib\net45\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.IO.Compression" />
|
||||||
|
<Reference Include="System.Numerics" />
|
||||||
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
|
<Reference Include="System.Transactions" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
@@ -61,6 +87,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BasePacket.cs" />
|
<Compile Include="BasePacket.cs" />
|
||||||
<Compile Include="Bitfield.cs" />
|
<Compile Include="Bitfield.cs" />
|
||||||
|
<Compile Include="Bitstream.cs" />
|
||||||
<Compile Include="Blowfish.cs" />
|
<Compile Include="Blowfish.cs" />
|
||||||
<Compile Include="EfficientHashTables.cs" />
|
<Compile Include="EfficientHashTables.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
@@ -68,6 +95,7 @@
|
|||||||
<Compile Include="STA_INIFile.cs" />
|
<Compile Include="STA_INIFile.cs" />
|
||||||
<Compile Include="SubPacket.cs" />
|
<Compile Include="SubPacket.cs" />
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
|
<Compile Include="Vector3.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
+23
-2
@@ -1,6 +1,27 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
namespace EfficientHashTables
|
namespace EfficientHashTables
|
||||||
{
|
{
|
||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
@@ -3,13 +3,14 @@
|
|||||||
// *******************************
|
// *******************************
|
||||||
// *** (C)2009-2013 S.T.A. snc ***
|
// *** (C)2009-2013 S.T.A. snc ***
|
||||||
// *******************************
|
// *******************************
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
public class INIFile
|
public class INIFile
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
|
{
|
||||||
|
// todo:
|
||||||
|
// havent decided whether it's worth wrapping every sql class
|
||||||
|
// so i'll just leave it with logger for now
|
||||||
|
public class Sql
|
||||||
|
{
|
||||||
|
public static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,31 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FFXIVClassic.Common;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SubPacketHeader
|
public struct SubPacketHeader
|
||||||
@@ -1,12 +1,34 @@
|
|||||||
using System;
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic.Common
|
namespace Meteor.Common
|
||||||
{
|
{
|
||||||
public static class Utils
|
public static class Utils
|
||||||
{
|
{
|
||||||
private static readonly uint[] _lookup32 = CreateLookup32();
|
private static readonly uint[] _lookup32 = CreateLookup32();
|
||||||
|
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
|
||||||
private static uint[] CreateLookup32()
|
private static uint[] CreateLookup32()
|
||||||
{
|
{
|
||||||
@@ -84,10 +106,10 @@ namespace FFXIVClassic.Common
|
|||||||
return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
|
return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint UnixTimeStampUTC()
|
public static uint UnixTimeStampUTC(DateTime? time = null)
|
||||||
{
|
{
|
||||||
uint unixTimeStamp;
|
uint unixTimeStamp;
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = time ?? DateTime.Now;
|
||||||
var zuluTime = currentTime.ToUniversalTime();
|
var zuluTime = currentTime.ToUniversalTime();
|
||||||
var unixEpoch = new DateTime(1970, 1, 1);
|
var unixEpoch = new DateTime(1970, 1, 1);
|
||||||
unixTimeStamp = (uint)zuluTime.Subtract(unixEpoch).TotalSeconds;
|
unixTimeStamp = (uint)zuluTime.Subtract(unixEpoch).TotalSeconds;
|
||||||
@@ -95,10 +117,10 @@ namespace FFXIVClassic.Common
|
|||||||
return unixTimeStamp;
|
return unixTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong MilisUnixTimeStampUTC()
|
public static ulong MilisUnixTimeStampUTC(DateTime? time = null)
|
||||||
{
|
{
|
||||||
ulong unixTimeStamp;
|
ulong unixTimeStamp;
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = time ?? DateTime.Now;
|
||||||
var zuluTime = currentTime.ToUniversalTime();
|
var zuluTime = currentTime.ToUniversalTime();
|
||||||
var unixEpoch = new DateTime(1970, 1, 1);
|
var unixEpoch = new DateTime(1970, 1, 1);
|
||||||
unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds;
|
unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds;
|
||||||
@@ -106,6 +128,11 @@ namespace FFXIVClassic.Common
|
|||||||
return unixTimeStamp;
|
return unixTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DateTime UnixTimeStampToDateTime(uint timestamp)
|
||||||
|
{
|
||||||
|
return epoch.AddSeconds(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
public static ulong SwapEndian(ulong input)
|
public static ulong SwapEndian(ulong input)
|
||||||
{
|
{
|
||||||
return 0x00000000000000FF & (input >> 56) |
|
return 0x00000000000000FF & (input >> 56) |
|
||||||
@@ -139,6 +166,12 @@ namespace FFXIVClassic.Common
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ushort SwapEndian(ushort input)
|
||||||
|
{
|
||||||
|
return (ushort)(((input << 8) & 0xff00) |
|
||||||
|
((input >> 8) & 0x00ff));
|
||||||
|
}
|
||||||
|
|
||||||
public static uint MurmurHash2(string key, uint seed)
|
public static uint MurmurHash2(string key, uint seed)
|
||||||
{
|
{
|
||||||
// 'm' and 'r' are mixing constants generated offline.
|
// 'm' and 'r' are mixing constants generated offline.
|
||||||
@@ -212,7 +245,7 @@ namespace FFXIVClassic.Common
|
|||||||
{
|
{
|
||||||
for (var bitCount = 0; bitCount < 8; bitCount++)
|
for (var bitCount = 0; bitCount < 8; bitCount++)
|
||||||
{
|
{
|
||||||
if (i + bitCount >= array.Length)
|
if (i + bitCount >= array.Length - 1)
|
||||||
break;
|
break;
|
||||||
data[dataCounter] = (byte)(((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]);
|
data[dataCounter] = (byte)(((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]);
|
||||||
}
|
}
|
||||||
@@ -222,6 +255,26 @@ namespace FFXIVClassic.Common
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool[] ConvertBinaryStreamToBoolArray(byte[] bytes)
|
||||||
|
{
|
||||||
|
bool[] data = new bool[bytes.Length * 8];
|
||||||
|
|
||||||
|
int boolCounter = 0;
|
||||||
|
for (int i = 0; i < bytes.Length; i ++)
|
||||||
|
{
|
||||||
|
if (bytes[i] == 0)
|
||||||
|
{
|
||||||
|
boolCounter += 8;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int bitCount = 0; bitCount < 8; bitCount++)
|
||||||
|
data[boolCounter++] = (bytes[i] >> bitCount & 1) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ToStringBase63(int number)
|
public static string ToStringBase63(int number)
|
||||||
{
|
{
|
||||||
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
@@ -232,6 +285,28 @@ namespace FFXIVClassic.Common
|
|||||||
return secondDigit + firstDigit;
|
return secondDigit + firstDigit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ReadNullTermString(BinaryReader reader, int maxSize = 0x20)
|
||||||
|
{
|
||||||
|
long pos = reader.BaseStream.Position;
|
||||||
|
int size = 0;
|
||||||
|
for (int i = 0; i < maxSize; i++)
|
||||||
|
{
|
||||||
|
if (reader.ReadByte() == 0)
|
||||||
|
{
|
||||||
|
size = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.BaseStream.Seek(pos, SeekOrigin.Begin);
|
||||||
|
string result = Encoding.ASCII.GetString(reader.ReadBytes(size));
|
||||||
|
reader.BaseStream.Seek(pos + maxSize, SeekOrigin.Begin);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteNullTermString(BinaryWriter writer, string value, int maxSize = 0x20)
|
||||||
|
{
|
||||||
|
writer.Write(Encoding.ASCII.GetBytes(value), 0, Encoding.ASCII.GetByteCount(value) >= maxSize ? maxSize : Encoding.ASCII.GetByteCount(value));
|
||||||
|
}
|
||||||
|
|
||||||
public static string FFXIVLoginStringDecodeBinary(string path)
|
public static string FFXIVLoginStringDecodeBinary(string path)
|
||||||
{
|
{
|
||||||
@@ -351,5 +426,95 @@ namespace FFXIVClassic.Common
|
|||||||
{
|
{
|
||||||
return (value >> bits) | (value << (16 - bits));
|
return (value >> bits) | (value << (16 - bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T Clamp<T>(this T value, T min, T max) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
if (value.CompareTo(min) < 0)
|
||||||
|
return min;
|
||||||
|
else if (value.CompareTo(max) > 0)
|
||||||
|
return max;
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Min<T>(this T value, T min) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
if (value.CompareTo(min) > 0)
|
||||||
|
return min;
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Max<T>(this T value, T max) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
if (value.CompareTo(max) < 0)
|
||||||
|
return max;
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float DistanceSquared(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return DistanceSquared(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Distance(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return Distance(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Distance(float x, float y, float z, float x2, float y2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && y == y2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return (float)Math.Sqrt(DistanceSquared(x, y, z, x2, y2, z2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float DistanceSquared(float x, float y, float z, float x2, float y2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && y == y2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
// todo: my maths is shit
|
||||||
|
var dx = x - x2;
|
||||||
|
var dy = y - y2;
|
||||||
|
var dz = z - z2;
|
||||||
|
|
||||||
|
return dx * dx + dy * dy + dz * dz;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Distance of just the x and z valeus, ignoring y
|
||||||
|
public static float XZDistanceSquared(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return XZDistanceSquared(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float XZDistance(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return XZDistance(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float XZDistance(float x, float z, float x2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return (float)Math.Sqrt(XZDistanceSquared(x, z, x2, z2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float XZDistanceSquared(float x, float z, float x2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
// todo: mz maths is shit
|
||||||
|
var dx = x - x2;
|
||||||
|
var dz = z - z2;
|
||||||
|
|
||||||
|
return dx * dx + dz * dz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||||
|
|
||||||
|
This file is part of Project Meteor Server.
|
||||||
|
|
||||||
|
Project Meteor Server 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, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Project Meteor Server is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Meteor.Common
|
||||||
|
{
|
||||||
|
public class Vector3
|
||||||
|
{
|
||||||
|
public float X;
|
||||||
|
public float Y;
|
||||||
|
public float Z;
|
||||||
|
public static Vector3 Zero = new Vector3();
|
||||||
|
|
||||||
|
public Vector3(float x, float y, float z)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3()
|
||||||
|
{
|
||||||
|
X = 0.0f;
|
||||||
|
Y = 0.0f;
|
||||||
|
Z = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
Vector3 newVec = new Vector3(lhs.X, lhs.Y, lhs.Z);
|
||||||
|
newVec.X += rhs.X;
|
||||||
|
newVec.Y += rhs.Y;
|
||||||
|
newVec.Z += rhs.Z;
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator *(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X * rhs.X, lhs.Y * rhs.Y, lhs.Z * rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator *(float scalar, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(scalar * rhs.X, scalar * rhs.Y, scalar * rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator /(Vector3 lhs, float scalar)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X / scalar, lhs.Y / scalar, lhs.Z / scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return !(lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return (lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Length()
|
||||||
|
{
|
||||||
|
return (float)Math.Sqrt(this.LengthSquared());
|
||||||
|
}
|
||||||
|
|
||||||
|
public float LengthSquared()
|
||||||
|
{
|
||||||
|
return (this.X * this.X) + (this.Y * this.Y) + (this.Z * this.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return (lhs.X * rhs.X) + (lhs.Y * rhs.Y) + (lhs.Z * rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetAngle(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return GetAngle(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetAngle(float x, float z, float x2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
var angle = (float)(Math.Atan((z2 - z) / (x2 - x)));
|
||||||
|
return (float)(x > x2 ? angle + Math.PI : angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 NewHorizontalVector(float angle, float extents)
|
||||||
|
{
|
||||||
|
var newVec = new Vector3();
|
||||||
|
newVec.Y = this.Y;
|
||||||
|
newVec.X = this.X + (float)Math.Cos(angle) * extents;
|
||||||
|
newVec.Z = this.Z + (float)Math.Sin(angle) * extents;
|
||||||
|
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsWithinCircle(Vector3 center, float maxRadius, float minRadius)
|
||||||
|
{
|
||||||
|
if (this.X == center.X && this.Z == center.Z)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
float diffX = center.X - this.X;
|
||||||
|
float diffZ = center.Z - this.Z;
|
||||||
|
|
||||||
|
float distance = Utils.XZDistance(center.X, center.Z, X, Z);
|
||||||
|
|
||||||
|
return distance <= maxRadius && distance >= minRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsWithinBox(Vector3 upperLeftCorner, Vector3 lowerRightCorner)
|
||||||
|
{
|
||||||
|
return upperLeftCorner.X <= this.X &&
|
||||||
|
upperLeftCorner.Y <= this.Y &&
|
||||||
|
upperLeftCorner.Z <= this.Z &&
|
||||||
|
lowerRightCorner.X >= this.X &&
|
||||||
|
lowerRightCorner.Y >= this.Y &&
|
||||||
|
lowerRightCorner.Z >= this.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checks if this vector is in a cone, note it doesn't check for distance
|
||||||
|
public bool IsWithinCone(Vector3 coneCenter, float coneRotation, float coneAngle)
|
||||||
|
{
|
||||||
|
float angleToTarget = GetAngle(coneCenter, this);
|
||||||
|
float halfAngleOfAoe = (float) (coneAngle * Math.PI / 2);
|
||||||
|
float rotationToAdd = coneRotation + halfAngleOfAoe;
|
||||||
|
|
||||||
|
//This is the angle relative to the lower angle of the cone
|
||||||
|
angleToTarget = (angleToTarget + rotationToAdd - (0.5f * (float)Math.PI)) % (2 * (float) Math.PI);
|
||||||
|
|
||||||
|
//If the relative angle is less than the total angle of the cone, the target is inside the cone
|
||||||
|
return angleToTarget >= 0 && angleToTarget <= (coneAngle * Math.PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
var vector = obj as Vector3;
|
||||||
|
return vector != null &&
|
||||||
|
X == vector.X &&
|
||||||
|
Y == vector.Y &&
|
||||||
|
Z == vector.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
var hashCode = -307843816;
|
||||||
|
hashCode = hashCode * -1521134295 + X.GetHashCode();
|
||||||
|
hashCode = hashCode * -1521134295 + Y.GetHashCode();
|
||||||
|
hashCode = hashCode * -1521134295 + Z.GetHashCode();
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<system.data>
|
<system.data>
|
||||||
<DbProviderFactories>
|
<DbProviderFactories>
|
||||||
@@ -6,4 +6,4 @@
|
|||||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
|
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
|
||||||
</DbProviderFactories>
|
</DbProviderFactories>
|
||||||
</system.data>
|
</system.data>
|
||||||
</configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
|
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
|
||||||
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
||||||
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
<package id="NLog" version="4.5.0" targetFramework="net451" />
|
||||||
</packages>
|
</packages>
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,58 @@
|
|||||||
|
-- todo: add enums for status effects in global.lua
|
||||||
|
require("global")
|
||||||
|
require("battleutils")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
statId - see BattleTemp.cs
|
||||||
|
modifier - Modifier.Intelligence, Modifier.Mind (see Modifier.cs)
|
||||||
|
multiplier -
|
||||||
|
]]
|
||||||
|
function HandleHealingSkill(caster, target, skill, action, statId, modifierId, multiplier, baseAmount)
|
||||||
|
potency = potency or 1.0;
|
||||||
|
healAmount = baseAmount;
|
||||||
|
|
||||||
|
-- todo: shit based on mnd
|
||||||
|
local mind = caster.GetMod(Modifier.Mind);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HandleAttackSkill(caster, target, skill, action, statId, modifierId, multiplier, baseAmount)
|
||||||
|
-- todo: actually handle this
|
||||||
|
damage = baseAmount or math.random(1,10) * 10;
|
||||||
|
|
||||||
|
return damage;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HandleStoneskin(caster, target, skill, action, statId, modifierId, damage)
|
||||||
|
--[[
|
||||||
|
if target.statusEffects.HasStatusEffect(StatusEffect.Stoneskin) then
|
||||||
|
-- todo: damage reduction
|
||||||
|
return true;
|
||||||
|
end;
|
||||||
|
]]
|
||||||
|
return false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
--For abilities that inflict statuses, like aegis boon or taunt
|
||||||
|
function onStatusAbilityFinish(caster, target, skill, action)
|
||||||
|
--action.CalcHitType(caster, target, skill);
|
||||||
|
action.DoAction(caster, target, skill);
|
||||||
|
action.TryStatus(caster, target, skill, false);
|
||||||
|
|
||||||
|
return action.amount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onAttackAbilityFinish(caster, target, skill, action)
|
||||||
|
local damage = math.random(50, 150);
|
||||||
|
action.amount = damage;
|
||||||
|
action.DoAction(caster, target, skill);
|
||||||
|
|
||||||
|
return action.amount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onHealAbilityFinish(caster, target, skill, action)
|
||||||
|
local amount = math.random(150, 250);
|
||||||
|
action.amount = amount;
|
||||||
|
action.DoAction(caster, target, skill);
|
||||||
|
action.TryStatus(caster, target, skill, true);
|
||||||
|
return action.amount;
|
||||||
|
end;
|
||||||
File renamed without changes.
@@ -0,0 +1,117 @@
|
|||||||
|
require ("global")
|
||||||
|
require ("magic")
|
||||||
|
require ("weaponskill")
|
||||||
|
|
||||||
|
allyGlobal =
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function allyGlobal.onSpawn(ally, target)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onEngage(ally, target)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onAttack(ally, target, damage)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onDamageTaken(ally, attacker, damage)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onCombatTick(ally, target, tick, contentGroupCharas)
|
||||||
|
allyGlobal.HelpPlayers(ally, contentGroupCharas)
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onDeath(ally, player, lastAttacker)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.onDespawn(ally)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
|
||||||
|
print("helpPlayers");
|
||||||
|
if contentGroupCharas and not ally.IsEngaged() then
|
||||||
|
print("contentGroup exists");
|
||||||
|
for chara in contentGroupCharas do
|
||||||
|
print("looping");
|
||||||
|
if chara then
|
||||||
|
-- probably a player, or another ally
|
||||||
|
-- todo: queue support actions, heal, try pull hate off player etc
|
||||||
|
if chara.IsPlayer() then
|
||||||
|
print("chara is a player");
|
||||||
|
-- do stuff
|
||||||
|
if not ally.IsEngaged() then
|
||||||
|
if chara.IsEngaged() then
|
||||||
|
allyGlobal.EngageTarget(ally, chara.target, nil);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif chara.IsMonster() and chara.IsEngaged() then
|
||||||
|
if not ally.IsEngaged() then
|
||||||
|
print("Engaging monster that is engaged");
|
||||||
|
allyGlobal.EngageTarget(ally, chara, nil);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.tryAggro(ally, contentGroupCharas)
|
||||||
|
local count = 0;
|
||||||
|
if contentGroupCharas and not ally.IsEngaged() then
|
||||||
|
for i = 0, #contentGroupCharas - 1 do
|
||||||
|
if contentGroupCharas[i] and ally then
|
||||||
|
if contentGroupCharas[i].IsPlayer() then
|
||||||
|
-- probably a player, or another ally
|
||||||
|
-- todo: queue support actions, heal, try pull hate off player etc
|
||||||
|
if contentGroupCharas[i].target then
|
||||||
|
if ally.aiContainer:GetTargetFind():CanTarget(contentGroupCharas[i].target) and contentGroupCharas[i].target.IsMonster() and contentGroupCharas[i].target.hateContainer:HasHateForTarget(contentGroupCharas[i]) then
|
||||||
|
-- do stuff
|
||||||
|
allyGlobal.EngageTarget(ally, contentGroupCharas[i].target, nil);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif contentGroupCharas[i].IsMonster() and contentGroupCharas[i].IsEngaged() then
|
||||||
|
if not ally.IsEngaged() then
|
||||||
|
print("Engaging monster that is engaged");
|
||||||
|
allyGlobal.EngageTarget(ally, contentGroupCharas[i], nil);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.HealPlayer(ally, player)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.SupportAction(ally, player)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function allyGlobal.EngageTarget(ally, target, contentGroupCharas)
|
||||||
|
if contentGroupCharas then
|
||||||
|
for chara in contentGroupCharas do
|
||||||
|
if chara.IsMonster() then
|
||||||
|
if chara.allegiance ~= ally.allegiance then
|
||||||
|
ally.Engage(chara)
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif target then
|
||||||
|
print("Engaging");
|
||||||
|
ally.Engage(target)
|
||||||
|
ally.hateContainer.AddBaseHate(target);
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceMenuMan Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
callClientFunction(player, "debugMenuEvent", player);
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
|
|
||||||
File renamed without changes.
@@ -0,0 +1,3 @@
|
|||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0, 0, 0;
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
File renamed without changes.
File renamed without changes.
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
require ("global")
|
require ("global")
|
||||||
|
|
||||||
function init(npc)
|
function init(npc)
|
||||||
return false, false, 0, 0;
|
return false, false, 0, 0, 0, 0;
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,19 @@
|
|||||||
|
require ("global")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
BgKeepout Script
|
||||||
|
|
||||||
|
Used to send a msg to the player that they cannot proceed passed this point. Invisible walls are
|
||||||
|
linked to this object.
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 60001, 0x20);
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,95 @@
|
|||||||
|
require ("global")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Elevator Standard Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
elevatorAskLimsa001(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 1.
|
||||||
|
elevatorAskLimsa002(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 2.
|
||||||
|
elevatorAskLimsa003(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 3.
|
||||||
|
elevatorAskUldah001(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 1.
|
||||||
|
elevatorAskUldah002(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 2.
|
||||||
|
elevatorAskUldah003(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 3.
|
||||||
|
elevatorQuestAskEvent(questId) - Special quest related elevator dialog.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
Script to control the elevators in Limsa Lominsa and Ul'dah. Each elevator entrance has a specific event for it's floor.
|
||||||
|
The only param is used to either show the ask dialog to the player or player the appropriate cutscene given the choice
|
||||||
|
made.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
local actorClassId = npc.GetActorClassId();
|
||||||
|
|
||||||
|
-- Limsa; Crow's Lift Level 1
|
||||||
|
if (actorClassId == 1290007) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskLimsa001", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa001", 1);
|
||||||
|
endEventAndWarp(player, 133, -447, 40, 220, -1.574);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa001", 2);
|
||||||
|
endEventAndWarp(player, 133, -458, 92, 175, -0.383);
|
||||||
|
end
|
||||||
|
-- Limsa; Crow's Lift Level 2
|
||||||
|
elseif (actorClassId == 1290008) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskLimsa002", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa002", 1);
|
||||||
|
endEventAndWarp(player, 133, -447, 19, 220, -1.574);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa002", 2);
|
||||||
|
endEventAndWarp(player, 133, -458, 92, 175, -0.383);
|
||||||
|
end
|
||||||
|
-- Limsa; Crow's Lift Level 3
|
||||||
|
elseif (actorClassId == 1290009) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskLimsa003", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa003", 1);
|
||||||
|
endEventAndWarp(player, 133, -447, 19, 220, -1.574);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskLimsa003", 2);
|
||||||
|
endEventAndWarp(player, 133, -447, 40, 220, -1.574);
|
||||||
|
end
|
||||||
|
-- Ul'dah; Wellhead Lift Level 1
|
||||||
|
elseif (actorClassId == 1090460) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskUldah001", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah001", 1);
|
||||||
|
endEventAndWarp(player, 209, -116.78, 222, 115.7, 2.85);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah001", 2);
|
||||||
|
endEventAndWarp(player, 209, -121.60, 269.8, 135.28, -0.268);
|
||||||
|
end
|
||||||
|
-- Ul'dah; Wellhead Lift Level 2
|
||||||
|
elseif (actorClassId == 1090461) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskUldah002", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah002", 1);
|
||||||
|
endEventAndWarp(player, 175, -116.78, 198, 115.7, -2.8911);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah002", 2);
|
||||||
|
endEventAndWarp(player, 209, -121.60, 269.8, 135.28, -0.268);
|
||||||
|
end
|
||||||
|
-- Ul'dah; Wellhead Lift Level 3
|
||||||
|
elseif (actorClassId == 1090462) then
|
||||||
|
local floorChoice = callClientFunction(player, "elevatorAskUldah003", 0);
|
||||||
|
if (floorChoice == 1) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah003", 1);
|
||||||
|
endEventAndWarp(player, 175, -116.78, 198, 115.7, -2.8911);
|
||||||
|
elseif (floorChoice == 2) then
|
||||||
|
callClientFunction(player, "elevatorAskUldah003", 2);
|
||||||
|
endEventAndWarp(player, 209, -116.78, 222, 115.7, 2.85);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function endEventAndWarp(player, zoneId, x, y, z, rotation)
|
||||||
|
player:EndEvent();
|
||||||
|
GetWorldManager():DoZoneChange(player, zoneId, nil, 0, 15, x, y, z, rotation);
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,163 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
MarketEntrance Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
Parameters mostly rely on the xtx_placeName sheet for its strings.
|
||||||
|
|
||||||
|
eventPushChoiceAreaOrQuest(
|
||||||
|
exitPlaceName[Fronds, etc], - Retail only showed it when inside a Market Ward/Office Set to 0 to hide the menu.
|
||||||
|
showMarketWards/Houses - If > 0, client script adds nation-specific Mercentile Houses as well.
|
||||||
|
gcHQPlaceName, - Set to the placeName id for the Grand Company office of that city
|
||||||
|
questAreaName, - Set to the placeName id of applicable quest instance, ex. Sailors Ward.
|
||||||
|
showItemSearchCounter, - If true, shows the Item Search menu
|
||||||
|
itemSearchId - If > 0 & showItemSearchCounter = true, displays the item name with a "Stop Searching"
|
||||||
|
)
|
||||||
|
eventPushStepPrvMarket(
|
||||||
|
staringWard, - Sets the starting placeName id
|
||||||
|
wardCount, - Valid number 1-20. Sets the amount of market ward entries. Client continues sequentially from startingWard id.
|
||||||
|
excludeWard - Hides the ward in the list that matches the id. Use on the ward you're currently in.
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MarketEntrance City TriggerBox details
|
||||||
|
Limsa - !warp 230 -416.5 40 446 ActorClass Id = 1090238
|
||||||
|
bgObj Id - [0xB3B] 2875
|
||||||
|
Layout Id - [0x79 ] 121 (0x29d90001)
|
||||||
|
Condition - in
|
||||||
|
reactName - dwti - Not a typo compared to the other cities
|
||||||
|
Gridania - !warp 206 -192.57 23.48 -1407.58 ActorClass Id = 1090264
|
||||||
|
|
||||||
|
bgObj Id - [0xCFA] 3322
|
||||||
|
Layout Id - [0x141] 321 (0x29b00001)
|
||||||
|
Condition - in
|
||||||
|
reactName - dtwi
|
||||||
|
Ul'dah - !warp 175 -235 189 50.5 ActorClass Id = 1500394
|
||||||
|
bgObj Id - [0x102F] 4143
|
||||||
|
Layout Id - [0x1A5] 421 (0x615a0001)
|
||||||
|
Condition - in
|
||||||
|
reactName - dtwi
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
CITY_INFO = { -- wardPlaceName, exitPlaceName, gcHQPlaceName, questAreaName, wardListStart, wardListCount
|
||||||
|
{1093, 1087, 1512, 1091, 1261, 20}, -- Limsa
|
||||||
|
{2099, 2091, 2526, 2095, 2261, 20}, -- Gridania
|
||||||
|
{3098, 3091, 3514, 3095, 3261, 20}, -- Ul'dah
|
||||||
|
}
|
||||||
|
|
||||||
|
-- TO-DO: Add some X/Z pos jitter to Entrances/Exits when called
|
||||||
|
MARKETWARD_ENTRANCE = {
|
||||||
|
{134, 160, 0, 135}, -- Limsa Market
|
||||||
|
{160, 160, 0, 138}, -- Gridania Market
|
||||||
|
{180, 160, 0, 185} -- Ul'dah Market
|
||||||
|
}
|
||||||
|
|
||||||
|
MARKETWARD_EXIT = {
|
||||||
|
{230, -420, 41, 435, -3.14}, -- Educated guess for Limsa, need video reference to confirm
|
||||||
|
{206, -180, 22, -1408, 1.5},
|
||||||
|
{175, -210, 190, 25, 0.65}
|
||||||
|
}
|
||||||
|
|
||||||
|
GC_ENTRANCE = {
|
||||||
|
[1512] = {232, 160, 0, -155}, -- Maelstrom Command
|
||||||
|
[2526] = {234, 160, 0, -155}, -- Adders' Nest
|
||||||
|
[3514] = {233, 160, 0, -155} -- Hall of Flames
|
||||||
|
}
|
||||||
|
|
||||||
|
city = {
|
||||||
|
[1090238] = 1, -- Limsa Market Ward Entrance
|
||||||
|
[1090264] = 2, -- Gridania Market Ward Entrance
|
||||||
|
[1090265] = 3, -- Ul'dah Market Ward Entrance
|
||||||
|
[1500392] = 1, -- Limsa : M'septha
|
||||||
|
[1500393] = 2, -- Gridania : Torsefers
|
||||||
|
[1500394] = 3, -- Ul'dah : Edine
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
local npcCity = city[npc:GetActorClassId()] or 1;
|
||||||
|
local marketPlaceName = CITY_INFO[npcCity][1]; -- Market Wards category name. Identical in all languages except Japanese
|
||||||
|
local exitPlaceName = CITY_INFO[npcCity][2]; -- Central Limsa Lominsa / Heartstream / The Fronds
|
||||||
|
local gcHQPlaceName = CITY_INFO[npcCity][3]; -- Maelstrom Command / Adders' Nest / Hall of Flames
|
||||||
|
local questPlaceName = CITY_INFO[npcCity][4]; -- Sailors Ward / Peasants Ward / Merchants Ward
|
||||||
|
local wardListStart = CITY_INFO[npcCity][5]; -- Starting id for the market wards
|
||||||
|
local wardListCount = CITY_INFO[npcCity][6]; -- Amount of wards in the list
|
||||||
|
local showItemSearchCounter = false;
|
||||||
|
local itemSearchId = 11000125;
|
||||||
|
|
||||||
|
local worldMaster = GetWorldMaster();
|
||||||
|
local pos = player:GetPos();
|
||||||
|
local currZone = pos[5];
|
||||||
|
local currRegion = player.CurrentArea.RegionId;
|
||||||
|
local quests = player:GetQuestsForNpc(npc);
|
||||||
|
|
||||||
|
-- City entrance specific stuff
|
||||||
|
if (currRegion == 101 or currRegion == 103 or currRegion == 104) then
|
||||||
|
exitPlaceName = 0; -- If in city, hide city menu option
|
||||||
|
|
||||||
|
-- If no quests attached to this entrence, don't show quest area
|
||||||
|
if (#quests == 0) then
|
||||||
|
questPlaceName = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If in GC Office, hide office menu option
|
||||||
|
if (currZone == 232 or currZone == 234 or currZone == 233) then
|
||||||
|
gcHQPlaceName = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, marketPlaceName, gcHQPlaceName, questPlaceName, showItemSearchCounter, itemSearchId);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
if choice == marketPlaceName then -- Market Wards
|
||||||
|
wardSelect = callClientFunction(player, "eventPushStepPrvMarket", wardListStart, wardListCount, 0);
|
||||||
|
|
||||||
|
if wardSelect and (wardSelect >= wardListStart and wardSelect <= (wardListStart+wardListCount)) then
|
||||||
|
player:SendGameMessage(player, worldMaster, 60004, 0x20, wardSelect);
|
||||||
|
warp = MARKETWARD_ENTRANCE[npcCity];
|
||||||
|
playerRot = math.random(-3.14, 3.14);
|
||||||
|
wait(1);
|
||||||
|
GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], playerRot);
|
||||||
|
player:SendDataPacket("attention", worldMaster, "", 60003, wardSelect);
|
||||||
|
-- Temp: Pop-up display after Ward zone-in. Client should automate this with PrivateArea's properly setup
|
||||||
|
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif (choice == 1519 or choice == 2534 or choice == 3533) then -- Mercentile Wards
|
||||||
|
player:SendMessage(0x20, "", "[MarketEntrance] DEBUG: "..choice);
|
||||||
|
elseif (choice == 1512 or choice == 2526 or choice == 3514) then -- GC Office
|
||||||
|
warp = GC_ENTRANCE[choice];
|
||||||
|
player:SendGameMessage(player, worldMaster, 60004, 0x20, choice);
|
||||||
|
wait(1);
|
||||||
|
GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], math.pi);
|
||||||
|
break;
|
||||||
|
elseif (choice == 1087 or choice == 2091 or choice == 3091) then -- Exiting to City
|
||||||
|
player:SendGameMessage(player, worldMaster, 60004, 0x20, choice);
|
||||||
|
warp = MARKETWARD_EXIT[npcCity];
|
||||||
|
wait(1);
|
||||||
|
GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], warp[5]);
|
||||||
|
break;
|
||||||
|
elseif (choice == 2095 or choice == 3095) then -- Quest
|
||||||
|
quests[1]:OnPush(player, npc, eventName);
|
||||||
|
return;
|
||||||
|
elseif (choice == 0 or choice == -3) then -- Menu Closed
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, marketPlaceName, gcHQPlaceName, questAreaName, showItemSearchCounter, itemSearchId);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
end
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,63 @@
|
|||||||
|
require ("global")
|
||||||
|
|
||||||
|
DREAM_ITEM = {
|
||||||
|
{[1] = 3010419, [2] = 3010420, [3] = 3010421}, -- Mizzenmast/Roost/Hourglass Biscuit
|
||||||
|
3010003, -- Boiled Egg
|
||||||
|
3010101, -- Grilled Carp
|
||||||
|
3010001, -- Meat Miq'abob
|
||||||
|
3010402, -- Ginger Cookie
|
||||||
|
3020001, -- Potion
|
||||||
|
3020101, -- Ether
|
||||||
|
1000003, -- 5x Crystal Shards (Fire)
|
||||||
|
1000004, -- 5x Crystal Shards (Ice)
|
||||||
|
1000005, -- 5x Crystal Shards (Wind)
|
||||||
|
1000006, -- 5x Crystal Shards (Earth)
|
||||||
|
1000007, -- 5x Crystal Shards (Lightning)
|
||||||
|
1000008 -- 5x Crystal Shards (Water)
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local choice = callClientFunction(player, "askLogout", player);
|
||||||
|
|
||||||
|
-- Quit
|
||||||
|
if (choice == 2) then
|
||||||
|
player:SetSleeping();
|
||||||
|
player:QuitGame();
|
||||||
|
-- Logout
|
||||||
|
elseif (choice == 3) then
|
||||||
|
player:SetSleeping();
|
||||||
|
player:Logout();
|
||||||
|
-- Heck the bed
|
||||||
|
elseif (choice == 4) then
|
||||||
|
-- Give items based on dream
|
||||||
|
local dreamCode = player:GetLoginDreamCode();
|
||||||
|
if (dreamCode >= 21 and dreamCode <= 33) then
|
||||||
|
local innCode = player:GetInnCode();
|
||||||
|
local itemCode = DREAM_ITEM[dreamCode - 20];
|
||||||
|
|
||||||
|
-- Get biscuit for inn
|
||||||
|
if (dreamCode == 21) then
|
||||||
|
itemCode = itemCode[innCode];
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If crystals you get x5 otherwise x1.
|
||||||
|
if (dreamCode > = 28 and dreamCode <= 33) then
|
||||||
|
player:AddItem(itemCode, 5);
|
||||||
|
else
|
||||||
|
player:AddItem(itemCode, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clear the code so they player doesn't keep getting things
|
||||||
|
player:SetLoginDreamCode(0);
|
||||||
|
else
|
||||||
|
-- Otherwise show standard message
|
||||||
|
player:SendGameMessage(player, npc, 7, 0x20);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
ObjectEventDoor Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventDoorMoveAsk() - Shows confirm to move into event
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local choice = callClientFunction(player, "eventDoorMoveAsk");
|
||||||
|
|
||||||
|
if (choice == 1) then
|
||||||
|
local activeQuests = player:GetQuestsForNpc(npc);
|
||||||
|
-- Either let the player choose the quest or start it if it's the only one.
|
||||||
|
local chosenQuest;
|
||||||
|
if (#activeQuests > 1) then
|
||||||
|
local currentPage = 0;
|
||||||
|
local numPages = math.floor((#activeQuests-1)/4) + 1;
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
local page, index = callClientFunction(player, "switchEvent", activeQuests[currentPage * 4 + 1], activeQuests[currentPage * 4 + 2], possibleQuests[currentPage * 4 + 3], possibleQuests[currentPage * 4 + 4], currentPage + 1, numPages, 0x3F1);
|
||||||
|
|
||||||
|
if (page == 0) then
|
||||||
|
chosenQuest = activeQuests[(currentPage * 4) + index];
|
||||||
|
break;
|
||||||
|
elseif (page > 0) then
|
||||||
|
currentPage = page - 1;
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif (#activeQuests == 1) then
|
||||||
|
chosenQuest = activeQuests[1];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (chosenQuest ~= nil) then
|
||||||
|
chosenQuest:OnPush(player, npc, eventName);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
+1
-1
@@ -4,7 +4,7 @@ function init(npc)
|
|||||||
return false, false, 0, 0;
|
return false, false, 0, 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
function onEventStarted(player, npc, triggerName)
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
defaultFst = GetStaticActor("DftFst");
|
defaultFst = GetStaticActor("DftFst");
|
||||||
choice = callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithInn_ExitDoor", nil, nil, nil);
|
choice = callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithInn_ExitDoor", nil, nil, nil);
|
||||||
|
|
||||||
+2
-2
@@ -31,7 +31,7 @@ function onEventStarted(player, npc, triggerName)
|
|||||||
itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice);
|
itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice);
|
||||||
|
|
||||||
if (itemId ~= nil) then
|
if (itemId ~= nil) then
|
||||||
player:GetInventory(INVENTORY_NORMAL):RemoveItem(itemId, 1);
|
player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(itemId, 1);
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif (storageChoice == 2) then
|
elseif (storageChoice == 2) then
|
||||||
@@ -44,7 +44,7 @@ function onEventStarted(player, npc, triggerName)
|
|||||||
itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice);
|
itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice);
|
||||||
|
|
||||||
if (itemId ~= nil) then
|
if (itemId ~= nil) then
|
||||||
player:GetInventory(INVENTORY_NORMAL):AddItem(itemId, 1);
|
player:GetItemPackage(INVENTORY_NORMAL):AddItem(itemId, 1);
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
File renamed without changes.
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
function init(npc)
|
function init(npc)
|
||||||
return false, false, 0, 0;
|
return false, false, 0, 0;
|
||||||
end
|
end
|
||||||
@@ -7,7 +9,7 @@ function onEventStarted(player, npc, triggerName)
|
|||||||
worldMaster = GetWorldMaster();
|
worldMaster = GetWorldMaster();
|
||||||
player:SendGameMessage(player, worldMaster, 34109, 0x20);
|
player:SendGameMessage(player, worldMaster, 34109, 0x20);
|
||||||
elseif (triggerName == "exit") then
|
elseif (triggerName == "exit") then
|
||||||
GetWorldManager():DoPlayerMoveInZone(player, 5);
|
GetWorldManager():DoPlayerMoveInZone(player, 356.09, 3.74, -701.62, -1.4);
|
||||||
end
|
end
|
||||||
player:EndEvent();
|
player:EndEvent();
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
|
||||||
|
if (eventType == ETYPE_PUSH) then
|
||||||
|
if (eventName == "caution") then
|
||||||
|
worldMaster = GetWorldMaster();
|
||||||
|
player:SendGameMessage(player, worldMaster, 34109, 0x20);
|
||||||
|
elseif (eventName == "exit") then
|
||||||
|
GetWorldManager():DoPlayerMoveInZone(player, 5.36433, 196, 133.656, -2.84938);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
PrivateAreaPastExit
|
||||||
|
|
||||||
|
This object contains the player inside a PrivateAreaPast, stopping them from escaping it's bounds. It is the
|
||||||
|
object that generates the circle graphic on the minimap. This object always has two push triggers, an inner
|
||||||
|
and outer inverted circle. The inner one is named "caution" and the outer one is named "exit". When the player
|
||||||
|
leaves the inner circle a warning is shown and when they leave the outer circle they either leave the instance
|
||||||
|
or get warped back to the center.
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
function init(privAreaExit)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, privAreaExit, eventType, eventName)
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
if (eventName == "caution") then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 34109, MESSAGE_TYPE_SYSTEM); -- You are about to leave the instance.
|
||||||
|
elseif (eventName == "exit") then
|
||||||
|
local area = privAreaExit.CurrentArea;
|
||||||
|
if (area.IsPrivate()) then
|
||||||
|
-- If you can leave, warp to public zone and show message.
|
||||||
|
if (area.CanExitPrivateArea()) then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 34110, MESSAGE_TYPE_SYSTEM); -- You have left the instance.
|
||||||
|
--GetWorldManager():WarpToPublicArea(player);
|
||||||
|
-- Otherwise warp back to the center of the zone.
|
||||||
|
else
|
||||||
|
--GetWorldManager():WarpToCharaPosition(player, privAreaExit);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,56 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
RetainerFurniture Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventPushStepOpenRetainerMenu() - Opens menu to choose retainer
|
||||||
|
eventRingBell() - Plays the bell ring animation
|
||||||
|
eventPushRetainerCallCaution() - Shows warning that a open bazaar will be closed if retainer chosen
|
||||||
|
eventTalkRetainerMenu(hasPossessions, showDispatchChoice) - Opens retainer menu.
|
||||||
|
eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
|
||||||
|
eventTalkRetainerMannequin(0:Enable/1:Disable) - Shows dialog to enable/disable modeling.
|
||||||
|
eventTalkRetainerItemTrade(operationCode) - Operate RetainerTradeWidget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
|
||||||
|
eventTalkRetainerItemList(operationCode) - Operate Bazaar Widget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
|
||||||
|
eventReturnResult(resultCode, ?) - Redraws the RetainerTrade UI.
|
||||||
|
eventTalkSelectBazaarStreet(limitsWardChoices) - Shows the dialog to send a retainer to a street. Set to 20.
|
||||||
|
eventTalkFinish() - Finishs the talk with retainer
|
||||||
|
eventPlayerTurn(rotation) - Turns the player
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("retainer")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
retainerNumber = callClientFunction(player, "eventPushStepOpenRetainerMenu");
|
||||||
|
|
||||||
|
if (retainerNumber == nil or retainerNumber == 0) then
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventRingBell");
|
||||||
|
retainer = player:SpawnMyRetainer(npc, retainerNumber);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
choice = callClientFunction(player, "eventTalkRetainerMenu", false, true);
|
||||||
|
if (choice == 1) then
|
||||||
|
doItemTrade(player, retainer);
|
||||||
|
elseif (choice == 2) then
|
||||||
|
doBazaar(player, retainer);
|
||||||
|
elseif (choice == 7) then
|
||||||
|
callClientFunction(player, "eventTalkRetainerMannequin", 0);
|
||||||
|
elseif (choice == 8) then
|
||||||
|
callClientFunction(player, "eventTalkSelectBazaarStreet", 20);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:DespawnMyRetainer();
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
TaskBoard
|
||||||
|
|
||||||
|
Operates the Task Board actor located in each of the Adventurers' Guilds.
|
||||||
|
Calls from the Noc000 static actor, which also applies to specific guild NPCs involved in that as well.
|
||||||
|
|
||||||
|
Functions: (only including those from Noc000 which apply to the Task Board)
|
||||||
|
|
||||||
|
pETaskBoardAskLimsa()
|
||||||
|
Desc: Show guild menu with valid options for Limsa Lominsa.
|
||||||
|
Params: None
|
||||||
|
Returns: Value dictating which item on the list was selected.
|
||||||
|
|
||||||
|
pETaskBoardAskUldah()
|
||||||
|
Desc: Show guild menu with valid options for Ul'dah.
|
||||||
|
Params: None
|
||||||
|
Returns: Value dictating which item on the list was selected.
|
||||||
|
|
||||||
|
pETaskBoardAskGridania()
|
||||||
|
Desc: Show guild menu with valid options for Gridania.
|
||||||
|
Params: None
|
||||||
|
Returns: Value dictating which item on the list was selected.
|
||||||
|
|
||||||
|
pETaskBoardGuild(guildId)
|
||||||
|
Desc: Plays back a message "The following tasks are available:".
|
||||||
|
Params: * guildId - Class Id from xtx_text_jobName. EN doesn't make use of it, but JP/DE/FR do. Thanks Koji.
|
||||||
|
|
||||||
|
pETaskBoardOrder(recommendedLvl itemId, hq, amount)
|
||||||
|
Desc: Takes the params and tells the player what the guild still needs turned in.
|
||||||
|
Params: * recommendedLvl - Recommended level the player be at
|
||||||
|
* itemId - Id of the item from xtx_itemName
|
||||||
|
* hq - Quality of item (1 = NQ, 2 = +1, 3 = +2 4 = +3)
|
||||||
|
* amount - Amount needed (The amount the player needs to turn-in, not the amount guild needs overall)
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
local guildItem = {
|
||||||
|
-- [guildId] = { (recommendedLvl itemId, hq, amount, 2nd-recommendedLvl 2nd-itemId, 2nd-hq, 2nd-amount) }
|
||||||
|
[29] = {1, 4100604, 1, 1, 10, 4030706, 1, 1}, -- Carpenters'
|
||||||
|
[30] = {1, 4040004, 1, 1, 10, 4030004, 1, 1}, -- Blacksmiths'
|
||||||
|
[31] = {1, 6080009, 1, 1, 10, 8070606, 1, 1}, -- Armorers'
|
||||||
|
[32] = {1, 5020007, 1, 1, 10,10004103, 1, 1}, -- Goldsmiths'
|
||||||
|
[33] = {1, 4020107, 1, 1, 10, 8031514, 1, 1}, -- Leatherworkers'
|
||||||
|
[34] = {1, 8030819, 1, 1, 10, 8030821, 1, 1}, -- Weavers'
|
||||||
|
[35] = {1, 3011530, 1,12, 10, 3020527, 1, 4}, -- Alchemists'
|
||||||
|
[36] = {1, 3010103, 1, 6, 10, 3011503, 1, 6}, -- Culinarians'
|
||||||
|
[39] = {1,10009101, 1,10, 10,10001116, 1,10}, -- Miners'
|
||||||
|
[40] = {1,10005403, 1,10, 10,10008106, 1,10}, -- Botanists'
|
||||||
|
[41] = {1, 3011106, 1,10, 10, 3011113, 1,10} -- Fishermans'
|
||||||
|
}
|
||||||
|
|
||||||
|
local menuToGuild = { -- Get a guild id from a given task board's Return result
|
||||||
|
[1] = {0, 30, 31, 36, 41}, -- Limsa
|
||||||
|
[2] = {0, 29, 33, 40, 0}, -- Gridania
|
||||||
|
[3] = {0, 32, 34, 35, 39} -- Ul'dah
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
local questNOC = GetStaticActor("Noc000");
|
||||||
|
local npcId = npc:GetActorClassId();
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
local guildId = 0;
|
||||||
|
|
||||||
|
if (npcId == 1200193) then -- Limsa
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskLimsa");
|
||||||
|
|
||||||
|
if (choice == 1 or choice == nil) then
|
||||||
|
break; -- Exited menu
|
||||||
|
else
|
||||||
|
guildId = menuToGuild[1][choice];
|
||||||
|
end
|
||||||
|
elseif (npcId == 1200194) then -- Ul'dah
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskUldah");
|
||||||
|
|
||||||
|
if (choice == 1 or choice == nil) then
|
||||||
|
break; -- Exited menu
|
||||||
|
else
|
||||||
|
guildId = menuToGuild[3][choice];
|
||||||
|
end
|
||||||
|
else -- Gridania
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskGridania");
|
||||||
|
|
||||||
|
if (choice == 1 or choice == nil) then
|
||||||
|
break; -- Exited menu
|
||||||
|
else
|
||||||
|
guildId = menuToGuild[2][choice];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (guildId > 0) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardGuild", guildId);
|
||||||
|
local gItem = guildItem[guildId]
|
||||||
|
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardOrder", unpack(gItem, 1, 4));
|
||||||
|
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardOrder", unpack(gItem, 5, 8));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
+1
-1
@@ -107,7 +107,7 @@ function doLevequestInit(player, aetheryte)
|
|||||||
|
|
||||||
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
|
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
|
||||||
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
|
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
|
||||||
director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player);
|
director = player.CurrentArea:CreateGuildleveDirector(glId, difficulty, player);
|
||||||
player:AddDirector(director);
|
player:AddDirector(director);
|
||||||
director:StartDirector(true, glId)
|
director:StartDirector(true, glId)
|
||||||
|
|
||||||
+25
-1
@@ -33,6 +33,30 @@ end
|
|||||||
|
|
||||||
function onEventStarted(player, aetheryte, triggerName)
|
function onEventStarted(player, aetheryte, triggerName)
|
||||||
|
|
||||||
|
-- Main Scenario Intro Quests
|
||||||
|
if (player:HasQuest(110002) == true) then
|
||||||
|
require ("quests/man/man0l1");
|
||||||
|
local quest = player:GetQuest("Man0l1");
|
||||||
|
if (quest:GetSequence() == SEQ_003) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, quest, "processEvent025");
|
||||||
|
quest:StartSequence(SEQ_005);
|
||||||
|
end
|
||||||
|
elseif (player:HasQuest(110006) == true) then
|
||||||
|
require ("quests/man/man0g1");
|
||||||
|
local quest = player:GetQuest("Man0g1");
|
||||||
|
if (quest:GetSequence() == SEQ_005) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, quest, "processEvent013");
|
||||||
|
--quest:StartSequence(???);
|
||||||
|
end
|
||||||
|
elseif (player:HasQuest(110010) == true) then
|
||||||
|
require ("quests/man/man0u1");
|
||||||
|
local quest = player:GetQuest("Man0u1");
|
||||||
|
if (quest:GetSequence() == SEQ_005) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, quest, "processEvent013");
|
||||||
|
quest:StartSequence(SEQ_010);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (player:GetGuildleveDirector() ~= nil) then
|
if (player:GetGuildleveDirector() ~= nil) then
|
||||||
doGuildleveMenu(player, aetheryte);
|
doGuildleveMenu(player, aetheryte);
|
||||||
else
|
else
|
||||||
@@ -142,7 +166,7 @@ function doLevequestInit(player, aetheryte)
|
|||||||
|
|
||||||
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
|
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
|
||||||
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
|
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
|
||||||
director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player);
|
director = player.CurrentArea:CreateGuildleveDirector(glId, difficulty, player);
|
||||||
player:AddDirector(director);
|
player:AddDirector(director);
|
||||||
director:StartDirector(true, glId);
|
director:StartDirector(true, glId);
|
||||||
|
|
||||||
File renamed without changes.
@@ -0,0 +1,159 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceBlackMarketeer Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome(player) - Start Text
|
||||||
|
eventSellItemAsk(player, itemName, tradePrice) - Requires GC Affiliation. Trade menu for Commemorative Coin
|
||||||
|
eventAskMainMenu(player, index) - Shows menu prompt to purchase with gil or with GC seals
|
||||||
|
eventTalkBye(player) - Says bye text
|
||||||
|
eventTalkStepBreak() - Ends talk, NPC turns to face original position
|
||||||
|
|
||||||
|
eventSealShopMenuOpen() - Opens menu for purchasing with grand company seals
|
||||||
|
eventSealShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item
|
||||||
|
eventSealShopMenuClose() - Closes seal menu
|
||||||
|
eventGilShopMenuOpen() - Opens menu for purchasing with gil
|
||||||
|
eventGilShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item
|
||||||
|
eventGilShopMenuClose() - Closes gil menu
|
||||||
|
|
||||||
|
Class applies to only three NPCs
|
||||||
|
Actorclass Id - 1500293 : Momoroon, Limsa Lominsa
|
||||||
|
Actorclass Id - 1500294 : Gagaroon, Gridania
|
||||||
|
Actorclass Id - 1500295 : Lalaroon, Ul'dah
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("shop")
|
||||||
|
|
||||||
|
shopInfo = { -- [ index ] = { itemId, gilPrice, sealPrice, city, itemCategory }
|
||||||
|
[1001] = {3020202, 100, 10000, 1, 1},
|
||||||
|
[1002] = {3020509, 400, 40000, 1, 1},
|
||||||
|
[1003] = {3020510, 400, 40000, 1, 1},
|
||||||
|
[1004] = {3020504, 1000, 100000, 1, 1},
|
||||||
|
[1005] = {3020505, 1000, 100000, 1, 1},
|
||||||
|
[1101] = {9040018, 1500, 150000, 1, 2},
|
||||||
|
[1102] = {9010025, 2000, 200000, 1, 2},
|
||||||
|
[1301] = {2001014, 4000, 400000, 1, 4},
|
||||||
|
[2001] = {3020203, 100, 10000, 2, 1},
|
||||||
|
[2002] = {3020509, 400, 40000, 2, 1},
|
||||||
|
[2003] = {3020510, 400, 40000, 2, 1},
|
||||||
|
[2004] = {3020504, 1000, 100000, 2, 1},
|
||||||
|
[2005] = {3020505, 1000, 100000, 2, 1},
|
||||||
|
[2101] = {9040018, 1500, 150000, 2, 2},
|
||||||
|
[2102] = {9010025, 2000, 200000, 2, 2},
|
||||||
|
[2301] = {2001015, 4000, 400000, 2, 4},
|
||||||
|
[3001] = {3020204, 100, 10000, 3, 1},
|
||||||
|
[3002] = {3020509, 400, 40000, 3, 1},
|
||||||
|
[3003] = {3020510, 400, 40000, 3, 1},
|
||||||
|
[3004] = {3020504, 1000, 100000, 3, 1},
|
||||||
|
[3005] = {3020505, 1000, 100000, 3, 1},
|
||||||
|
[3101] = {9040018, 1500, 150000, 3, 2},
|
||||||
|
[3102] = {9010025, 2000, 200000, 3, 2},
|
||||||
|
[3301] = {2001016, 4000, 400000, 3, 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
commemorativeCoin = 10011251;
|
||||||
|
commemorativeCoinValue = 25000;
|
||||||
|
gilCurrency = 1000001;
|
||||||
|
playerGC = player.gcCurrent
|
||||||
|
playerGCSeal = 1000200 + playerGC;
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkWelcome", player);
|
||||||
|
|
||||||
|
if player:GetItemPackage(INVENTORY_NORMAL):HasItem(commemorativeCoin) and playerGC > 0 then
|
||||||
|
-- Checks for player having a commemorative coin, show window trade option if so.
|
||||||
|
coinChoice = callClientFunction(player, "eventSellItemAsk", player, commemorativeCoin, commemorativeCoinValue);
|
||||||
|
if coinChoice == 1 then
|
||||||
|
currencyType = callClientFunction(player, "eventAskMainMenu", player);
|
||||||
|
elseif coinChoice == 2 then
|
||||||
|
-- You trade <itemQuantity1> <itemName1> <itemQuality1> for <itemQuantity2> <itemName2> <itemQuality2>.
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, commemorativeCoin, 1, playerGCSeal, 1, 1, commemorativeCoinValue);
|
||||||
|
player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(commemorativeCoin, 1);
|
||||||
|
player:GetItemPackage(INVENTORY_CURRENCY):addItem(playerGCSeal, 25000, 1)
|
||||||
|
-- TODO: Add handling for checking GC seals limit and not going over it
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- If no grand company alignment, go straight to the shop that uses gil, otherwise show gc seal option.
|
||||||
|
if playerGC == 0 then
|
||||||
|
processGilShop(player);
|
||||||
|
else
|
||||||
|
currencyType = callClientFunction(player, "eventAskMainMenu", player);
|
||||||
|
if currencyType == 1 then
|
||||||
|
processGilShop(player);
|
||||||
|
elseif currencyType == 2 then
|
||||||
|
processSealShop(player);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkBye", player);
|
||||||
|
callClientFunction(player, "eventTalkStepBreak", player);
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function processGilShop(player)
|
||||||
|
|
||||||
|
callClientFunction(player, "eventGilShopMenuOpen", player);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
unk1, buyResult = callClientFunction(player, "eventGilShopMenuAsk", player);
|
||||||
|
printf(unk1);
|
||||||
|
if (buyResult == 0 or buyResult == -1) then
|
||||||
|
callClientFunction(player, "eventGilShopMenuClose", player);
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
if shopInfo[buyResult] == nil then
|
||||||
|
-- Prevent server crash from someone trying to buy a non-existent item via packet injection.
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
-- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list
|
||||||
|
if shopInfo[buyResult][5] == 4 then
|
||||||
|
location = INVENTORY_KEYITEMS;
|
||||||
|
else
|
||||||
|
location = INVENTORY_NORMAL;
|
||||||
|
end
|
||||||
|
|
||||||
|
purchaseItem(player, location, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][3], gilCurrency);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function processSealShop(player)
|
||||||
|
|
||||||
|
callClientFunction(player, "eventSealShopMenuOpen", player);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
unk1, buyResult = callClientFunction(player, "eventSealShopMenuAsk", player);
|
||||||
|
|
||||||
|
if (buyResult == 0 or buyResult == -1) then
|
||||||
|
callClientFunction(player, "eventSealShopMenuClose", player);
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
if shopInfo[buyResult] == nil then
|
||||||
|
-- Prevent server crash from someone trying to buy a non-existent item via packet injection.
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
-- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list
|
||||||
|
if shopInfo[buyResult][5] == 4 then
|
||||||
|
location = INVENTORY_KEYITEMS;
|
||||||
|
else
|
||||||
|
location = INVENTORY_NORMAL;
|
||||||
|
end
|
||||||
|
|
||||||
|
purchaseItem(player, location, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][2], playerGCSeal);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
File renamed without changes.
@@ -0,0 +1,26 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceBranchVendor Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome(player) - Starts talk turn and
|
||||||
|
eventSearchItemAsk(nil, stopSearchingItemId) -
|
||||||
|
eventTalkStepBreak() - Finishes the talk turn.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkWelcome", player);
|
||||||
|
callClientFunction(player, "eventSearchItemAsk", nil, 0);
|
||||||
|
callClientFunction(player, "eventTalkStepBreak", player);
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
end
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,41 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCaravanAdviser Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
adviserDeffault() - Not a typo. NPC dialog talking about a chocobo. Resets their sight on you, perhaps used on closing dialog?
|
||||||
|
adviserAsk() - Brings up a menu for caravan info, or purchasing gysahl greens
|
||||||
|
adviserAdvise() - NPC dialog discussing feeding chocobos
|
||||||
|
adviserSales(price) - Gysahl purchase dialog and prompt
|
||||||
|
adviserBuy() - Dialog to play after purchasing gysahl greens
|
||||||
|
adviserBuyNG() - NPC plays /shrug animation.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local gysahlPrice = 20;
|
||||||
|
local choice = callClientFunction(player, "adviserAsk");
|
||||||
|
|
||||||
|
if choice == 1 then
|
||||||
|
callClientFunction(player, "adviserAdvise");
|
||||||
|
elseif choice == 2 then
|
||||||
|
local purchaseChoice = callClientFunction(player, "adviserSales", gysahlPrice);
|
||||||
|
|
||||||
|
if purchaseChoice == 1 then
|
||||||
|
callClientFunction(player, "adviserBuy");
|
||||||
|
elseif purchaseChoice == 2 then
|
||||||
|
callClientFunction(player, "adviserBuyNG");
|
||||||
|
end
|
||||||
|
elseif choice == 3 then
|
||||||
|
callClientFunction(player, "adviserDeffault")
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCaravanGuide Script
|
||||||
|
|
||||||
|
This script handles the caravan guide class, which is for the actor who escorts the chocobos behind them during Caravan Security events.
|
||||||
|
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
caravanGuardCancel() - Menu prompt to abandon the caravan
|
||||||
|
|
||||||
|
caravanGuardReward(cargo, nil, areaName, playerGC, killCount, areaName2)
|
||||||
|
- Reward dialog for completing the caravan
|
||||||
|
- cargo = 0 (none) through 9 (all) for varying degrees of success dialog
|
||||||
|
- If playerGC doesn't match the GC of the areaName region, NPC mentions you don't need their seals.
|
||||||
|
- killCount shows an extra dialog if 40-49 enemies were slain, and a different one at 50+
|
||||||
|
|
||||||
|
caravanGuardNotReward() - Dialog stating you didn't contribute to the event at all
|
||||||
|
caravanGuardFailReward(areaName, areaName2) - Failure dialog, NPC offers free gysahl green, then offers free teleport back to aetheryte
|
||||||
|
caravanGuardThanks(name1, name2, name3) - Dialog for joining the caravan. NPC names the three chocobos. Name IDs from xtx_displayName
|
||||||
|
caravanGuardOffer(areaName, areaName2, playerGC) - Dialog for who to talk to for joining the caravan.
|
||||||
|
caravanGuardAmple(areaName, areaName2) - Dialog for NPC taking a break?
|
||||||
|
caravanGuardSuccess() - Dialog when you reached destination?
|
||||||
|
caravanGuardFailure(areaName, areaName2) - Failure dialog for mentioned area.
|
||||||
|
caravanGuardIgnore() - Resets NPC state for player? Or used for players not flagged for the event.
|
||||||
|
caravanGuardBonusReward(nil, isBonus?) - NPC says variation on a piece of dialog from the boolean passed
|
||||||
|
caravanGuardNotBonusReward() - Inventory full flavour dialog
|
||||||
|
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Functions employing areaName/areaName2 add their value together in the client's script to get the area name. Said area values are...
|
||||||
|
1 = Wineport, 2 = Quarrymill, 3 = Silver Bazaar, 4 = Aleport, 5 = Hyrstmill, 6 = Golden Bazaar
|
||||||
|
|
||||||
|
areaName will always be 1-3 for caravanGuardReward to function as expected for GC-related dialog
|
||||||
|
areaName2 will always be either 0 or 3. 0 for the lower level caravan area name, 3 for the higher level.
|
||||||
|
|
||||||
|
populaceCaravanGuide sheet:
|
||||||
|
ID Dialog Comment
|
||||||
|
6 It is time. Come, let us ride. - Caravan begins.
|
||||||
|
12 We've arrived at last! Come and speak to me when you're ready to claim your reward. - Caravan completed.
|
||||||
|
23 We're under attack! The chocobos! Protect the chocobos! - Caravan aggros monsters
|
||||||
|
27 Gods, have we already come this far? At this pace, we stand to make good time. - Says between 50% & 90% of the way to desgination? Can be said more than once per run
|
||||||
|
28 Well fought, friend. I thank the gods you're with us. Come, onward! - Cleared monsters that caravan aggro'd
|
||||||
|
|
||||||
|
TO-DO:
|
||||||
|
Document actors involved. Should be six of them.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local areaName = 1;
|
||||||
|
local areaName2 = 3;
|
||||||
|
local playerGC = 1;
|
||||||
|
local cargo = 9;
|
||||||
|
local killCount = 50;
|
||||||
|
callClientFunction(player, "caravanGuardOffer", areaName, areaName2, playerGC);
|
||||||
|
--callClientFunction(player, "caravanGuardReward", cargo, nil, areaName, playerGC, killCount, areaName2);
|
||||||
|
--player:SendGameMessageLocalizedDisplayName(npc, 6, MESSAGE_TYPE_SAY, npc.displayNameId);
|
||||||
|
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCaravanManager Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
caravanGuardEntry(areaGC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCountRequired, levelRequired)
|
||||||
|
- Dialog for signing up for caravan. areaGC(1-3) & areaName(0 or 3) added together to get location name.
|
||||||
|
- If difficulty => 40 on areaGC 1-3 & areaName 0, NPC mentions it's be a tougher trip
|
||||||
|
|
||||||
|
caravanGuardQuestion(areaName1, areaName2, escortMax, isSameGC?, playerGC?) - Ask about the caravan escort
|
||||||
|
caravanGuardJoinOK(areaName1, areaName2, playerGC) - Dialog for successfully joining the caravan
|
||||||
|
caravanGuardJoinNG(nil, maxEscorts, playerGC) - Dialog dictating how many escorts total filled the run.
|
||||||
|
caravanGuardAmple(nil, playerGC, playerGC) - Dialog for caravan escort being full.
|
||||||
|
caravanGuardOther(npcGC) - Dialog where NPC mentions you're not part of the given Grand Company parameter
|
||||||
|
caravanGuardSigh() - NPC does a shrug animation
|
||||||
|
caravanGuardHuh() - NPC does /huh
|
||||||
|
caravanGuardCancel(nil, playerGC) - Dialog for canceling caravan escort.
|
||||||
|
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Some NPC dialog address you differently if your GC rank is Chief Sergeant (id 27) or higher, but only in non-English languages.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local GC = 3;
|
||||||
|
local playerGC = 1;
|
||||||
|
local areaName = 0;
|
||||||
|
local level = 25;
|
||||||
|
local playerCount = 8;
|
||||||
|
local difficulty = 41;
|
||||||
|
local hasRoomForGCSeals = false;
|
||||||
|
local isSameGC = true;
|
||||||
|
local escortMax = 8;
|
||||||
|
areaName1 = 1;
|
||||||
|
areaName2 = 3;
|
||||||
|
|
||||||
|
-- callClientFunction(player, "caravanGuardCancel", nil, 3);
|
||||||
|
|
||||||
|
callClientFunction(player, "caravanGuardEntry", GC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCount, level);
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceChocoboLender Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome(player) - Start Text
|
||||||
|
eventAskMainMenu(player, curLevel, hasFundsForRent, isPresentChocoboIssuance, isSummonMyChocobo, isChangeBarding, currentChocoboWare) - Shows the main menu
|
||||||
|
eventTalkMyChocobo(player) - Starts the cutscene for getting a chocobo
|
||||||
|
eventSetChocoboName(true) - Opens the set name dialog
|
||||||
|
eventAfterChocoboName(player) - Called if player done naming chocobo, shows cutscene, returns state and waits to teleport outside city.
|
||||||
|
eventCancelChocoboName(player) - Called if player cancels naming chocobo, returns state.
|
||||||
|
eventTalkStepBreak(player) - Finishes talkTurn and says a goodbye
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* Rent price and time seems to be hardcoded into the client. Price is always 800gil and time is 10m.
|
||||||
|
* The func eventSetChocoboName *requires* the actor with id `1080101` to be present in the client instance or it will crash (thanks Jorge for finding that).
|
||||||
|
* Special spawn codes must be sent for getting your chocobo or renting for it to work properly.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
local rentalPrice = 800;
|
||||||
|
local rentalTime = 10;
|
||||||
|
|
||||||
|
local gcIssuances = {
|
||||||
|
[1500006] = 2001004,
|
||||||
|
[1500061] = 2001005,
|
||||||
|
[1000840] = 2001006,
|
||||||
|
[1500059] = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
local startAppearances = {
|
||||||
|
[1500006] = CHOCOBO_LIMSA1,
|
||||||
|
[1500061] = CHOCOBO_GRIDANIA1,
|
||||||
|
[1000840] = CHOCOBO_ULDAH1
|
||||||
|
};
|
||||||
|
|
||||||
|
local cityExits = {
|
||||||
|
[1500006] = {133, -6.032, 46.356, 132.572, 3.034},
|
||||||
|
[1500061] = {150, 333.271, 5.889, -943.275, 0.794},
|
||||||
|
[1000840] = {170, -26.088, 181.846, -79.438, 2.579},
|
||||||
|
[1500059] = {172, -2133.028, 15.476, -421.471, 1.5}
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local classId = npc:GetActorClassId();
|
||||||
|
local curLevel = 20; -- TODO: pull from character
|
||||||
|
local hasIssuance = player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(gcIssuances[classId]);
|
||||||
|
local hasChocobo = player.hasChocobo;
|
||||||
|
|
||||||
|
if (hasChocobo == false) then -- Let GMs auto have the issuance for debugging
|
||||||
|
hasIssuance = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
local hasFunds = (player:GetCurrentGil() >= rentalPrice);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ((classId == 1000840) and (player:HasQuest(110009))) then -- Cross-script Man0u0 dialog
|
||||||
|
local sequence = player:GetQuest(110009):getSequence();
|
||||||
|
|
||||||
|
if (sequence == 0) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, GetStaticActor("Man0u0"), "processEvent000_13");
|
||||||
|
elseif (sequence == 10) then
|
||||||
|
callClientFunction(player, "delegateEvent", player, GetStaticActor("Man0u0"), "processEvent020_7");
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkWelcome", player);
|
||||||
|
|
||||||
|
local menuChoice = callClientFunction(player, "eventAskMainMenu", player, curLevel, hasFunds, hasIssuance, hasChocobo, hasChocobo, 0);
|
||||||
|
|
||||||
|
if (menuChoice == 1) then -- Issuance option
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkMyChocobo", player);
|
||||||
|
local nameResponse = callClientFunction(player, "eventSetChocoboName", true);
|
||||||
|
|
||||||
|
if (nameResponse == "") then -- Cancel Chocobo naming
|
||||||
|
callClientFunction(player, "eventCancelChocoboName", player);
|
||||||
|
callClientFunction(player, "eventTalkStepBreak", player);
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
local appearance = startAppearances[classId];
|
||||||
|
player:IssueChocobo(appearance, nameResponse);
|
||||||
|
|
||||||
|
callClientFunction(player, "eventAfterChocoboName", player);
|
||||||
|
|
||||||
|
--Add Chocobo License and remove issuance
|
||||||
|
if (player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(2001007) == false) then
|
||||||
|
player:GetItemPackage(INVENTORY_KEYITEMS):AddItem(2001007);
|
||||||
|
end
|
||||||
|
player:GetItemPackage(INVENTORY_KEYITEMS):RemoveItem(gcIssuances[classId], 1);
|
||||||
|
|
||||||
|
--Warp with the special chocobo warp mode.
|
||||||
|
mountChocobo(player);
|
||||||
|
GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_CHOCOBO_GET, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif(menuChoice == 2) then -- Summon Bird
|
||||||
|
mountChocobo(player);
|
||||||
|
GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_NO_ANIM, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]);
|
||||||
|
elseif(menuChoice == 3) then -- Change Barding
|
||||||
|
callClientFunction(player, "eventTalkStepBreak", player);
|
||||||
|
elseif(menuChoice == 5) then -- Rent Bird
|
||||||
|
mountChocobo(player, true, 10);
|
||||||
|
GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_CHOCOBO_RENTAL, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]);
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkStepBreak", player);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
function mountChocobo(player, isRental, rentalMinutes)
|
||||||
|
if (isRental) then
|
||||||
|
player:ChangeMusic(64);
|
||||||
|
player:StartChocoboRental(rentalMinutes);
|
||||||
|
else
|
||||||
|
player:ChangeMusic(83);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:SendMountAppearance();
|
||||||
|
player:SetMountState(1);
|
||||||
|
player:ChangeSpeed(0.0, 3.6, 9.0, 9.0);
|
||||||
|
player:ChangeState(15);
|
||||||
|
end
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyBuffer Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome(player, boolean) - Welcome dialog. Boolean seems to be related to rank?
|
||||||
|
eventTalkBufEffect() - Dialog for applying Sanction
|
||||||
|
eventTalkBufEffectAfter(player) - Dialog after applying Sanction
|
||||||
|
eventTalkStepBreak() - Returns to NPC's neutral state
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
local gcRep = {
|
||||||
|
[1500388] = 1, -- Maelstrom Representative
|
||||||
|
[1500389] = 2, -- Adder Representative
|
||||||
|
[1500390] = 3, -- Flame Representative
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local playerGC = player.gcCurrent;
|
||||||
|
local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah};
|
||||||
|
|
||||||
|
local choice = callClientFunction(player, "eventTalkWelcome", player, true);
|
||||||
|
|
||||||
|
if (choice == 1 and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then
|
||||||
|
callClientFunction(player, "eventTalkBufEffect");
|
||||||
|
callClientFunction(player, "eventTalkBufEffectAfter", player);
|
||||||
|
-- TODO: Add Sanction buff
|
||||||
|
else
|
||||||
|
player:SendMessage(0x20, "", "Quit hex editing your memory.");
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyGLPublisher Script
|
||||||
|
|
||||||
|
xtx_gcRank for GC Rank values
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
talkOutsider() - Dialog for no affiliated with GC. Seems to always read Maelstrom?
|
||||||
|
talkOfferWelcome(unk1) - Errors
|
||||||
|
askCompanyLeve() - Errors
|
||||||
|
askLeveDetail(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8) - Errors
|
||||||
|
|
||||||
|
eventGLDifficulty() - Difficulty window, returns player choice
|
||||||
|
eventGLStart(leveName, difficulty, unk1) - leveName from xtx_guildleve
|
||||||
|
|
||||||
|
talkAfterOffer()
|
||||||
|
talkOfferLimit()
|
||||||
|
|
||||||
|
finishTalkTurn() - Resets NPC target/facing
|
||||||
|
|
||||||
|
eventGLPlay(leveName, guardianFavor, favorCost, difficulty) - Menu for active levequest
|
||||||
|
eventGLShinpu(guardianFavor, favorCost) - Menu to accept favor buff. evenGLPlay() calls it
|
||||||
|
eventGLThanks() - Errors
|
||||||
|
|
||||||
|
eventGLReward( -- Leve reward screen
|
||||||
|
guildleveId,
|
||||||
|
clearTime,
|
||||||
|
missionBonus,
|
||||||
|
difficultyBonus,
|
||||||
|
factionNumber,
|
||||||
|
factionBonus,
|
||||||
|
factionCredit,
|
||||||
|
glRewardItem,
|
||||||
|
glRewardNumber,
|
||||||
|
glRewardSubItem,
|
||||||
|
glRewardSubNumber,
|
||||||
|
difficulty
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
gcOfficer = {
|
||||||
|
[1500222] = 1, -- Storm Sergeant Hammil
|
||||||
|
[1500223] = 1, -- Storm Sergeant Sternn
|
||||||
|
[1500224] = 2, -- Serpent Sergeant Cordwyk
|
||||||
|
[1500225] = 2, -- Serpent Sergeant Lodall
|
||||||
|
[1500226] = 3, -- Flame Sergeant Byrne
|
||||||
|
[1500227] = 3, -- Flame Sergeant Dalvag
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
callClientFunction(player, "talkOutsider");
|
||||||
|
|
||||||
|
callClientFunction(player, "finishTalkTurn");
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyGuide Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome() - Dialog for new recruits
|
||||||
|
eventTalkProvisional() - Message for when rank isn't high enough?
|
||||||
|
eventTalkExclusive() - Message for wrong GC.
|
||||||
|
eventTalkComMember(nil, npc, isFoundationDay) - Information menus for various GC related activities
|
||||||
|
eventTalkStepBreak() - Returns to NPC's neutral state
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
local gcRep = {
|
||||||
|
[1001737] = 1, -- Maelstrom Representative
|
||||||
|
[1001738] = 2, -- Adder Representative
|
||||||
|
[1001739] = 3, -- Flame Representative
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local playerGC = player.gcCurrent;
|
||||||
|
local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah};
|
||||||
|
local npcGC = gcRep[npc:GetActorClassId()];
|
||||||
|
|
||||||
|
if (playerGC ~= npcGC and playerGCRanks[playerGC] == 127) then
|
||||||
|
callClientFunction(player, "eventTalkWelcome");
|
||||||
|
elseif (playerGC == npcGC and playerGCRanks[playerGC] == 127) then
|
||||||
|
callClientFunction(player, "eventTalkProvisional");
|
||||||
|
elseif (playerGC ~= npcGC and playerGCRanks[playerGC] ~= 127) then
|
||||||
|
callClientFunction(player, "eventTalkExclusive");
|
||||||
|
elseif (playerGC == npcGC and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then
|
||||||
|
callClientFunction(player, "eventTalkComMember", nil, npc, true);
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyOfficer Script
|
||||||
|
|
||||||
|
xtx_gcRank for GC Rank values
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome() - Welcome dialog
|
||||||
|
eventTalkWelcomeQuest() - Same as Welcome dialog?
|
||||||
|
eventTalkPreJoin() - Dialog for starting GC rank?
|
||||||
|
eventTalkExclusive() - Dialog to play when you're not of that GC?
|
||||||
|
eventTalkJoinedOnly() - Reads like chat-end dialog for your GC.
|
||||||
|
eventTalkJoined(gcRank, gcRank, isCanAfford, isShowPromotion) - Menu to ask about/for promotion
|
||||||
|
|
||||||
|
eventDoRankUp(gcRank, gcRank) - Plays rank-up animation and opens GC window.
|
||||||
|
eventRankUpDone(???, ???) - Has your character do the GC salute? Values seem to do nothing?
|
||||||
|
eventRankCategoryUpBefore(gcRank) - 11/21/31 - Mentions which GC quest you need to clear to continue promotion
|
||||||
|
eventRankCategoryUpAfter() - Follow-up dialog after ranking up
|
||||||
|
eventTalkQuestUncomplete() - Quest prerequisite dialog for ranking up to Second Lieutenant (1.23b rank cap)
|
||||||
|
eventTalkFestival() - Foundation Day 2011 event dialog. Server needs to reward 1000 GC seals after.
|
||||||
|
eventTalkFestival2() - Foundation Day 2011 event dialog. Seems to reward more seals, unsure how many.
|
||||||
|
eventTalkFestival2012(value) - Foundation Day 2012 event dialog. Rewards amount of seals dictated by value, retail used 5000.
|
||||||
|
|
||||||
|
eventTalkStepBreak() - Resets NPC target/facing
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
gcOfficer = {
|
||||||
|
[1500199] = 1, -- Limsa Officer
|
||||||
|
[1500200] = 2, -- Grid Officer
|
||||||
|
[1500198] = 3, -- Flame Officer
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
playerGC = player.gcCurrent;
|
||||||
|
playerGCSeal = 1000200 + playerGC;
|
||||||
|
playerCurrentRank = 13;
|
||||||
|
playerRankUpCost = 1500;
|
||||||
|
playerNextRank = 15;
|
||||||
|
currentRankCap = 31; -- Second Lieutenant
|
||||||
|
npcId = npc:GetActorClassId();
|
||||||
|
|
||||||
|
if playerGC == gcOfficer[npcId] then
|
||||||
|
callClientFunction(player, "eventTalkWelcome");
|
||||||
|
if playerCurrentRank < currentRankCap then
|
||||||
|
if player:GetItemPackage(INVENTORY_CURRENCY):HasItem(playerGCSeal, playerRankUpCost) then
|
||||||
|
-- Show Promotion window, allow paying
|
||||||
|
local choice = callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, true, true);
|
||||||
|
|
||||||
|
-- If promotion accepted
|
||||||
|
if choice == 1 then
|
||||||
|
callClientFunction(player, "eventDoRankUp", playerNextRank, playerNextRank);
|
||||||
|
-- TODO: Table GC info or get it in source/sql. Handle actual upgrade of GC rank/seal cap/cost/etc.
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- Show Promotion window, show dialog you can't afford promotion
|
||||||
|
callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, false, true);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank);
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkJoinedOnly");
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkExclusive");
|
||||||
|
end
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,510 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyShop Script
|
||||||
|
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkStepCantUse() -- When player tries to buy from another GC's shop
|
||||||
|
eventTalkPreJoin() -- Dialog for the shop
|
||||||
|
eventTalkPreJoinQuest() -- Tutorial dialog for the shop?
|
||||||
|
eventTalkJoined(???) -- Dialog for the shop, they salute. Orphaned parameter?
|
||||||
|
|
||||||
|
eventTalkFestival() -- Festival Day Event Dialog
|
||||||
|
eventTalkFestival2() -- Festival Day Event Follow-up Dialog
|
||||||
|
|
||||||
|
eventTalkMainMenu(???, ???) -- Shop menu for picking GC items
|
||||||
|
eventShopMenuOpen() -- Sets up shop menu. Calls getSpecialEventWork, value 8 shows GC firework & 11 a Patriot's Choker
|
||||||
|
eventShopMenuAsk() -- Opens up the shop menu.
|
||||||
|
eventShopMenuClose()
|
||||||
|
|
||||||
|
eventGuideChocoboWhistle(???) -- Tutorial dialog after purchasing Chocobo issuance slip. Orphaned parameter?
|
||||||
|
eventGuideTownTransport(index) -- Tutorial dialog after purchasing an aetherpass. Index is item ID.
|
||||||
|
eventAskChocoboCustomize(index, price) -- Chocobo Barding purchase dialog. Index is item ID.
|
||||||
|
eventChocoboCustomize() -- Follow-up dialog if you purchase Chocobo Barding.
|
||||||
|
|
||||||
|
getGrandCompanyNumber() -- Returns GC value of the NPC
|
||||||
|
getShopItemStartIndex(index) -- Gets starting index value based on GC shop
|
||||||
|
getShopItemEndIndex(index) -- Gets ending index value based on GC shop
|
||||||
|
getShopSellingItemMax(???) --
|
||||||
|
getShopSellingItemDetail(player, ???, ???)
|
||||||
|
|
||||||
|
eventTalkStepBreak() -- Returns NPC to their starting direction
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("shop")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
gcOfficer = {
|
||||||
|
[1500202] = 1, -- Limsa Shop
|
||||||
|
[1500203] = 2, -- Grid Shop
|
||||||
|
[1500201] = 3, -- Flame Shop
|
||||||
|
}
|
||||||
|
|
||||||
|
shopInfo = { -- [index] = { itemID, itemQuality, itemQuantity, itemCost, gcRank, city, special, itemCategory }
|
||||||
|
[100001] = {3010403, 1, 10, 20, 0, 1, 0, 1},
|
||||||
|
[100002] = {3010402, 1, 10, 30, 0, 1, 0, 1},
|
||||||
|
[100003] = {3020202, 1, 1, 50, 0, 1, 0, 1},
|
||||||
|
[100004] = {3020406, 1, 20, 10, 0, 1, 0, 1},
|
||||||
|
[100005] = {3020403, 1, 10, 15, 0, 1, 0, 1},
|
||||||
|
[100006] = {3020402, 1, 5, 60, 0, 1, 0, 1},
|
||||||
|
[100007] = {3020404, 1, 5, 100, 0, 1, 0, 1},
|
||||||
|
[100008] = {3020528, 1, 5, 50, 0, 1, 0, 1},
|
||||||
|
[100009] = {3020516, 1, 5, 50, 0, 1, 0, 1},
|
||||||
|
[100010] = {3020411, 1, 1, 15, 0, 1, 0, 1},
|
||||||
|
[100011] = {3020412, 1, 1, 200, 0, 1, 0, 1},
|
||||||
|
[100012] = {3020509, 1, 1, 200, 0, 1, 0, 1},
|
||||||
|
[100013] = {3020510, 1, 1, 200, 0, 1, 0, 1},
|
||||||
|
[100014] = {10013001, 1, 20, 5, 0, 1, 0, 1},
|
||||||
|
[100015] = {10013002, 1, 20, 25, 0, 1, 0, 1},
|
||||||
|
[100016] = {10013003, 1, 20, 45, 0, 1, 0, 1},
|
||||||
|
[100017] = {10013004, 1, 20, 100, 0, 1, 0, 1},
|
||||||
|
[100018] = {10013005, 1, 20, 150, 0, 1, 0, 1},
|
||||||
|
[100019] = {3910402, 1, 99, 85, 0, 1, 0, 1},
|
||||||
|
[100020] = {3910103, 1, 99, 120, 0, 1, 0, 1},
|
||||||
|
[100021] = {3910203, 1, 99, 120, 0, 1, 0, 1},
|
||||||
|
[100022] = {3910305, 1, 99, 85, 0, 1, 0, 1},
|
||||||
|
[100023] = {3920004, 1, 999, 50, 0, 1, 0, 1},
|
||||||
|
[100024] = {3920006, 1, 999, 70, 0, 1, 0, 1},
|
||||||
|
[100025] = {3920003, 1, 999, 115, 0, 1, 0, 1},
|
||||||
|
[100026] = {3910005, 1, 99, 75, 0, 1, 0, 1},
|
||||||
|
[100027] = {3910006, 1, 99, 90, 0, 1, 0, 1},
|
||||||
|
[100028] = {3940011, 1, 20, 20, 0, 1, 0, 1},
|
||||||
|
[100029] = {3940010, 1, 20, 30, 0, 1, 0, 1},
|
||||||
|
[100030] = {3020504, 1, 1, 400, 15, 1, 0, 1},
|
||||||
|
[100031] = {3020505, 1, 1, 400, 15, 1, 0, 1},
|
||||||
|
[100032] = {3020506, 1, 1, 300, 31, 1, 0, 1},
|
||||||
|
[101001] = {4040010, 1, 1, 500, 0, 1, 0, 2},
|
||||||
|
[101002] = {4040110, 1, 1, 1000, 0, 1, 0, 2},
|
||||||
|
[101003] = {4040205, 1, 1, 1400, 0, 1, 0, 2},
|
||||||
|
[101004] = {4040305, 1, 1, 3000, 0, 1, 0, 2},
|
||||||
|
[101005] = {4040204, 1, 1, 4000, 0, 1, 0, 2},
|
||||||
|
[101006] = {4080304, 1, 1, 950, 0, 1, 0, 2},
|
||||||
|
[101007] = {4080211, 1, 1, 1000, 0, 1, 0, 2},
|
||||||
|
[101008] = {4080106, 1, 1, 2000, 0, 1, 0, 2},
|
||||||
|
[101009] = {4080303, 1, 1, 4000, 0, 1, 0, 2},
|
||||||
|
[101010] = {5020010, 1, 1, 900, 0, 1, 0, 2},
|
||||||
|
[101011] = {5020209, 1, 1, 1000, 0, 1, 0, 2},
|
||||||
|
[101012] = {5020213, 1, 1, 1600, 0, 1, 0, 2},
|
||||||
|
[101013] = {5020305, 1, 1, 4000, 0, 1, 0, 2},
|
||||||
|
[101014] = {8030350, 1, 1, 750, 0, 1, 0, 2},
|
||||||
|
[101015] = {8030447, 1, 1, 750, 0, 1, 0, 2},
|
||||||
|
[101016] = {8031223, 1, 1, 750, 0, 1, 0, 2},
|
||||||
|
[101017] = {8032008, 1, 1, 750, 0, 1, 0, 2},
|
||||||
|
[101018] = {9050029, 1, 1, 900, 0, 1, 0, 2},
|
||||||
|
[101019] = {9050044, 1, 1, 1900, 0, 1, 0, 2},
|
||||||
|
[101020] = {9040032, 1, 1, 950, 0, 1, 0, 2},
|
||||||
|
[101021] = {9040025, 1, 1, 1500, 0, 1, 0, 2},
|
||||||
|
[101022] = {8013201, 1, 1, 1000, 11, 1, 0, 2},
|
||||||
|
[101023] = {8032601, 1, 1, 1000, 11, 1, 0, 2},
|
||||||
|
[101024] = {8071301, 1, 1, 1000, 11, 1, 0, 2},
|
||||||
|
[101025] = {8081701, 1, 1, 1000, 11, 1, 0, 2},
|
||||||
|
[101026] = {8050620, 1, 1, 1200, 11, 1, 0, 2},
|
||||||
|
[101027] = {8050243, 1, 1, 1200, 11, 1, 0, 2},
|
||||||
|
[101028] = {8050344, 1, 1, 1200, 11, 1, 0, 2},
|
||||||
|
[101029] = {8050028, 1, 1, 1200, 11, 1, 0, 2},
|
||||||
|
[101030] = {8090706, 1, 1, 1200, 11, 1, 0, 2},
|
||||||
|
[101031] = {4030205, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101032] = {4020306, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101033] = {4040014, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101034] = {4080408, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101035] = {4070310, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101036] = {5030307, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101037] = {5020112, 1, 1, 2500, 13, 1, 0, 2},
|
||||||
|
[101038] = {4100205, 1, 1, 2000, 13, 1, 0, 2},
|
||||||
|
[101039] = {8011609, 1, 1, 3000, 15, 1, 0, 2},
|
||||||
|
[101040] = {8032311, 1, 1, 3000, 15, 1, 0, 2},
|
||||||
|
[101041] = {8071017, 1, 1, 3000, 15, 1, 0, 2},
|
||||||
|
[101042] = {8050132, 1, 1, 3000, 15, 1, 0, 2},
|
||||||
|
[101043] = {8081123, 1, 1, 3000, 15, 1, 0, 2},
|
||||||
|
[101044] = {4030117, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101045] = {4020210, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101046] = {4040406, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101047] = {4080107, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101048] = {4070108, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101049] = {5030111, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101050] = {5020013, 1, 1, 4500, 17, 1, 0, 2},
|
||||||
|
[101051] = {4100405, 1, 1, 4000, 17, 1, 0, 2},
|
||||||
|
[101052] = {8011610, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101053] = {8032312, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101054] = {8071018, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101055] = {8050133, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101056] = {8050769, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101057] = {8081124, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101058] = {8080565, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101059] = {8090609, 1, 1, 5000, 21, 1, 0, 2},
|
||||||
|
[101060] = {9050021, 1, 1, 1000, 21, 1, 0, 2},
|
||||||
|
[101061] = {9050022, 1, 1, 1000, 21, 1, 0, 2},
|
||||||
|
[101062] = {9010025, 1, 1, 1000, 21, 1, 0, 2},
|
||||||
|
[101063] = {4100804, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101064] = {8013614, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101065] = {8032820, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101066] = {8051516, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101067] = {8071520, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101068] = {9030060, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101069] = {9050067, 1, 1, 5500, 23, 1, 0, 2},
|
||||||
|
[101070] = {8013615, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101071] = {8013616, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101072] = {8032821, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101073] = {8071521, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101074] = {8081914, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101075] = {9040065, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101076] = {9010061, 1, 1, 6000, 25, 1, 0, 2},
|
||||||
|
[101077] = {4100805, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101078] = {4020408, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101079] = {4040508, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101080] = {4080508, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101081] = {4070408, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101082] = {5030408, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101083] = {5020408, 1, 1, 6500, 27, 1, 0, 2},
|
||||||
|
[101084] = {4030604, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101085] = {4020404, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101086] = {4040504, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101087] = {4080504, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101088] = {4070404, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101089] = {5030404, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101090] = {5020404, 1, 1, 25000, 31, 1, 0, 2},
|
||||||
|
[101091] = {8013204, 1, 1, 6000, 31, 1, 0, 2},
|
||||||
|
[101092] = {8032604, 1, 1, 6000, 31, 1, 0, 2},
|
||||||
|
[101093] = {8071304, 1, 1, 6000, 31, 1, 0, 2},
|
||||||
|
[101094] = {8081704, 1, 1, 6000, 31, 1, 0, 2},
|
||||||
|
[102001] = {3020601, 1, 20, 5, 0, 1, 8, 3},
|
||||||
|
[102002] = {9040018, 1, 1, 1000, 11, 1, 11, 3},
|
||||||
|
[103001] = {2001004, 1, 1, 3000, 11, 1, 0, 4},
|
||||||
|
[103002] = {2001014, 1, 1, 3000, 15, 1, 0, 4},
|
||||||
|
[103003] = {2001017, 1, 1, 2000, 21, 1, 0, 4},
|
||||||
|
[103004] = {2001018, 1, 1, 3000, 21, 1, 0, 4},
|
||||||
|
[103005] = {2001019, 1, 1, 4000, 21, 1, 0, 4},
|
||||||
|
[103006] = {2001026, 1, 1, 25000, 27, 1, 0, 4},
|
||||||
|
[200001] = {3010403, 1, 10, 20, 0, 2, 0, 1},
|
||||||
|
[200002] = {3010402, 1, 10, 30, 0, 2, 0, 1},
|
||||||
|
[200003] = {3020203, 1, 1, 50, 0, 2, 0, 1},
|
||||||
|
[200004] = {3020406, 1, 20, 10, 0, 2, 0, 1},
|
||||||
|
[200005] = {3020403, 1, 10, 15, 0, 2, 0, 1},
|
||||||
|
[200006] = {3020402, 1, 5, 60, 0, 2, 0, 1},
|
||||||
|
[200007] = {3020404, 1, 5, 100, 0, 2, 0, 1},
|
||||||
|
[200008] = {3020528, 1, 5, 50, 0, 2, 0, 1},
|
||||||
|
[200009] = {3020516, 1, 5, 50, 0, 2, 0, 1},
|
||||||
|
[200010] = {3020411, 1, 1, 15, 0, 2, 0, 1},
|
||||||
|
[200011] = {3020412, 1, 1, 200, 0, 2, 0, 1},
|
||||||
|
[200012] = {3020509, 1, 1, 200, 0, 2, 0, 1},
|
||||||
|
[200013] = {3020510, 1, 1, 200, 0, 2, 0, 1},
|
||||||
|
[200014] = {10013001, 1, 20, 5, 0, 2, 0, 1},
|
||||||
|
[200015] = {10013002, 1, 20, 25, 0, 2, 0, 1},
|
||||||
|
[200016] = {10013003, 1, 20, 45, 0, 2, 0, 1},
|
||||||
|
[200017] = {10013004, 1, 20, 100, 0, 2, 0, 1},
|
||||||
|
[200018] = {10013005, 1, 20, 150, 0, 2, 0, 1},
|
||||||
|
[200019] = {3910402, 1, 99, 85, 0, 2, 0, 1},
|
||||||
|
[200020] = {3910103, 1, 99, 120, 0, 2, 0, 1},
|
||||||
|
[200021] = {3910203, 1, 99, 120, 0, 2, 0, 1},
|
||||||
|
[200022] = {3910305, 1, 99, 85, 0, 2, 0, 1},
|
||||||
|
[200023] = {3920004, 1, 999, 50, 0, 2, 0, 1},
|
||||||
|
[200024] = {3920006, 1, 999, 70, 0, 2, 0, 1},
|
||||||
|
[200025] = {3920003, 1, 999, 115, 0, 2, 0, 1},
|
||||||
|
[200026] = {3910005, 1, 99, 75, 0, 2, 0, 1},
|
||||||
|
[200027] = {3910006, 1, 99, 90, 0, 2, 0, 1},
|
||||||
|
[200028] = {3940011, 1, 20, 20, 0, 2, 0, 1},
|
||||||
|
[200029] = {3940010, 1, 20, 30, 0, 2, 0, 1},
|
||||||
|
[200030] = {3020504, 1, 1, 400, 15, 2, 0, 1},
|
||||||
|
[200031] = {3020505, 1, 1, 400, 15, 2, 0, 1},
|
||||||
|
[200032] = {3020506, 1, 1, 300, 31, 2, 0, 1},
|
||||||
|
[201001] = {5030107, 1, 1, 350, 0, 2, 0, 2},
|
||||||
|
[201002] = {5030207, 1, 1, 750, 0, 2, 0, 2},
|
||||||
|
[201003] = {5030206, 1, 1, 1000, 0, 2, 0, 2},
|
||||||
|
[201004] = {5030029, 1, 1, 1500, 0, 2, 0, 2},
|
||||||
|
[201005] = {5030031, 1, 1, 2400, 0, 2, 0, 2},
|
||||||
|
[201006] = {5030209, 1, 1, 3000, 0, 2, 0, 2},
|
||||||
|
[201007] = {5030028, 1, 1, 4000, 0, 2, 0, 2},
|
||||||
|
[201008] = {4020109, 1, 1, 800, 0, 2, 0, 2},
|
||||||
|
[201009] = {4020106, 1, 1, 1000, 0, 2, 0, 2},
|
||||||
|
[201010] = {4020008, 1, 1, 2200, 0, 2, 0, 2},
|
||||||
|
[201011] = {4020305, 1, 1, 4000, 0, 2, 0, 2},
|
||||||
|
[201012] = {4100005, 1, 1, 1000, 0, 2, 0, 2},
|
||||||
|
[201013] = {4100109, 1, 1, 4000, 0, 2, 0, 2},
|
||||||
|
[201014] = {8030035, 1, 1, 750, 0, 2, 0, 2},
|
||||||
|
[201015] = {8030919, 1, 1, 750, 0, 2, 0, 2},
|
||||||
|
[201016] = {8031821, 1, 1, 750, 0, 2, 0, 2},
|
||||||
|
[201017] = {8032220, 1, 1, 750, 0, 2, 0, 2},
|
||||||
|
[201018] = {9050029, 1, 1, 900, 0, 2, 0, 2},
|
||||||
|
[201019] = {9050044, 1, 1, 1900, 0, 2, 0, 2},
|
||||||
|
[201020] = {9040035, 1, 1, 950, 0, 2, 0, 2},
|
||||||
|
[201021] = {9040025, 1, 1, 1500, 0, 2, 0, 2},
|
||||||
|
[201022] = {8013202, 1, 1, 1000, 11, 2, 0, 2},
|
||||||
|
[201023] = {8032602, 1, 1, 1000, 11, 2, 0, 2},
|
||||||
|
[201024] = {8071302, 1, 1, 1000, 11, 2, 0, 2},
|
||||||
|
[201025] = {8081702, 1, 1, 1000, 11, 2, 0, 2},
|
||||||
|
[201026] = {8050148, 1, 1, 1200, 11, 2, 0, 2},
|
||||||
|
[201027] = {8050244, 1, 1, 1200, 11, 2, 0, 2},
|
||||||
|
[201028] = {8051222, 1, 1, 1200, 11, 2, 0, 2},
|
||||||
|
[201029] = {8050029, 1, 1, 1200, 11, 2, 0, 2},
|
||||||
|
[201030] = {8090707, 1, 1, 1200, 11, 2, 0, 2},
|
||||||
|
[201031] = {4030710, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201032] = {4020211, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201033] = {4040407, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201034] = {4080213, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201035] = {4070215, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201036] = {5030113, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201037] = {5020014, 1, 1, 2500, 13, 2, 0, 2},
|
||||||
|
[201038] = {4100608, 1, 1, 2000, 13, 2, 0, 2},
|
||||||
|
[201039] = {8010566, 1, 1, 3000, 15, 2, 0, 2},
|
||||||
|
[201040] = {8030625, 1, 1, 3000, 15, 2, 0, 2},
|
||||||
|
[201041] = {8070724, 1, 1, 3000, 15, 2, 0, 2},
|
||||||
|
[201042] = {8050618, 1, 1, 3000, 15, 2, 0, 2},
|
||||||
|
[201043] = {8080715, 1, 1, 3000, 15, 2, 0, 2},
|
||||||
|
[201044] = {4030016, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201045] = {4020012, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201046] = {4040111, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201047] = {4080010, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201048] = {4070013, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201049] = {5030308, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201050] = {5020113, 1, 1, 4500, 17, 2, 0, 2},
|
||||||
|
[201051] = {4100507, 1, 1, 4000, 17, 2, 0, 2},
|
||||||
|
[201052] = {8010567, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201053] = {8030626, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201054] = {8070725, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201055] = {8050619, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201056] = {8050768, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201057] = {8080716, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201058] = {8080564, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201059] = {8090506, 1, 1, 5000, 21, 2, 0, 2},
|
||||||
|
[201060] = {9050025, 1, 1, 1000, 21, 2, 0, 2},
|
||||||
|
[201061] = {9050026, 1, 1, 1000, 21, 2, 0, 2},
|
||||||
|
[201062] = {9010025, 1, 1, 1000, 21, 2, 0, 2},
|
||||||
|
[201063] = {4100806, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201064] = {8013617, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201065] = {8032822, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201066] = {8051517, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201067] = {8071522, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201068] = {9030061, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201069] = {9050068, 1, 1, 5500, 23, 2, 0, 2},
|
||||||
|
[201070] = {8013618, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201071] = {8013619, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201072] = {8032823, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201073] = {8071523, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201074] = {8081915, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201075] = {9040066, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201076] = {9010062, 1, 1, 6000, 25, 2, 0, 2},
|
||||||
|
[201077] = {4100807, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201078] = {4020409, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201079] = {4040509, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201080] = {4080509, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201081] = {4070409, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201082] = {5030409, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201083] = {5020409, 1, 1, 6500, 27, 2, 0, 2},
|
||||||
|
[201084] = {4030605, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201085] = {4020405, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201086] = {4040505, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201087] = {4080505, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201088] = {4070405, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201089] = {5030405, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201090] = {5020405, 1, 1, 25000, 31, 2, 0, 2},
|
||||||
|
[201091] = {8013205, 1, 1, 6000, 31, 2, 0, 2},
|
||||||
|
[201092] = {8032605, 1, 1, 6000, 31, 2, 0, 2},
|
||||||
|
[201093] = {8071305, 1, 1, 6000, 31, 2, 0, 2},
|
||||||
|
[201094] = {8081705, 1, 1, 6000, 31, 2, 0, 2},
|
||||||
|
[202001] = {3020603, 1, 20, 5, 0, 2, 8, 3},
|
||||||
|
[202002] = {9040018, 1, 1, 1000, 11, 2, 11, 3},
|
||||||
|
[203001] = {2001005, 1, 1, 3000, 11, 2, 0, 4},
|
||||||
|
[203002] = {2001015, 1, 1, 3000, 15, 2, 0, 4},
|
||||||
|
[203003] = {2001020, 1, 1, 2000, 21, 2, 0, 4},
|
||||||
|
[203004] = {2001021, 1, 1, 3000, 21, 2, 0, 4},
|
||||||
|
[203005] = {2001022, 1, 1, 4000, 21, 2, 0, 4},
|
||||||
|
[203006] = {2001026, 1, 1, 25000, 27, 2, 0, 4},
|
||||||
|
[300001] = {3010403, 1, 10, 20, 0, 3, 0, 1},
|
||||||
|
[300002] = {3010402, 1, 10, 30, 0, 3, 0, 1},
|
||||||
|
[300003] = {3020204, 1, 1, 50, 0, 3, 0, 1},
|
||||||
|
[300004] = {3020406, 1, 20, 10, 0, 3, 0, 1},
|
||||||
|
[300005] = {3020403, 1, 10, 15, 0, 3, 0, 1},
|
||||||
|
[300006] = {3020402, 1, 5, 60, 0, 3, 0, 1},
|
||||||
|
[300007] = {3020404, 1, 5, 100, 0, 3, 0, 1},
|
||||||
|
[300008] = {3020528, 1, 5, 50, 0, 3, 0, 1},
|
||||||
|
[300009] = {3020516, 1, 5, 50, 0, 3, 0, 1},
|
||||||
|
[300010] = {3020411, 1, 1, 15, 0, 3, 0, 1},
|
||||||
|
[300011] = {3020412, 1, 1, 200, 0, 3, 0, 1},
|
||||||
|
[300012] = {3020509, 1, 1, 200, 0, 3, 0, 1},
|
||||||
|
[300013] = {3020510, 1, 1, 200, 0, 3, 0, 1},
|
||||||
|
[300014] = {10013001, 1, 20, 5, 0, 3, 0, 1},
|
||||||
|
[300015] = {10013002, 1, 20, 25, 0, 3, 0, 1},
|
||||||
|
[300016] = {10013003, 1, 20, 45, 0, 3, 0, 1},
|
||||||
|
[300017] = {10013004, 1, 20, 100, 0, 3, 0, 1},
|
||||||
|
[300018] = {10013005, 1, 20, 150, 0, 3, 0, 1},
|
||||||
|
[300019] = {3910402, 1, 99, 85, 0, 3, 0, 1},
|
||||||
|
[300020] = {3910103, 1, 99, 120, 0, 3, 0, 1},
|
||||||
|
[300021] = {3910203, 1, 99, 120, 0, 3, 0, 1},
|
||||||
|
[300022] = {3910305, 1, 99, 85, 0, 3, 0, 1},
|
||||||
|
[300023] = {3920004, 1, 999, 50, 0, 3, 0, 1},
|
||||||
|
[300024] = {3920006, 1, 999, 70, 0, 3, 0, 1},
|
||||||
|
[300025] = {3920003, 1, 999, 115, 0, 3, 0, 1},
|
||||||
|
[300026] = {3910005, 1, 99, 75, 0, 3, 0, 1},
|
||||||
|
[300027] = {3910006, 1, 99, 90, 0, 3, 0, 1},
|
||||||
|
[300028] = {3940011, 1, 20, 20, 0, 3, 0, 1},
|
||||||
|
[300029] = {3940010, 1, 20, 30, 0, 3, 0, 1},
|
||||||
|
[300030] = {3020504, 1, 1, 400, 15, 3, 0, 1},
|
||||||
|
[300031] = {3020505, 1, 1, 400, 15, 3, 0, 1},
|
||||||
|
[300032] = {3020506, 1, 1, 300, 31, 3, 0, 1},
|
||||||
|
[301001] = {4030006, 1, 1, 400, 0, 3, 0, 2},
|
||||||
|
[301002] = {4030015, 1, 1, 1000, 0, 3, 0, 2},
|
||||||
|
[301003] = {4030405, 1, 1, 1600, 0, 3, 0, 2},
|
||||||
|
[301004] = {4030506, 1, 1, 3200, 0, 3, 0, 2},
|
||||||
|
[301005] = {4030505, 1, 1, 4000, 0, 3, 0, 2},
|
||||||
|
[301006] = {4070011, 1, 1, 550, 0, 3, 0, 2},
|
||||||
|
[301007] = {4070105, 1, 1, 1000, 0, 3, 0, 2},
|
||||||
|
[301008] = {4070212, 1, 1, 1500, 0, 3, 0, 2},
|
||||||
|
[301009] = {4070211, 1, 1, 4000, 0, 3, 0, 2},
|
||||||
|
[301010] = {4100710, 1, 1, 450, 0, 3, 0, 2},
|
||||||
|
[301011] = {4100403, 1, 1, 1000, 0, 3, 0, 2},
|
||||||
|
[301012] = {4100404, 1, 1, 1900, 0, 3, 0, 2},
|
||||||
|
[301013] = {4100306, 1, 1, 4000, 0, 3, 0, 2},
|
||||||
|
[301014] = {8030248, 1, 1, 750, 0, 3, 0, 2},
|
||||||
|
[301015] = {8030548, 1, 1, 750, 0, 3, 0, 2},
|
||||||
|
[301016] = {8031021, 1, 1, 750, 0, 3, 0, 2},
|
||||||
|
[301017] = {8031513, 1, 1, 750, 0, 3, 0, 2},
|
||||||
|
[301018] = {9050029, 1, 1, 900, 0, 3, 0, 2},
|
||||||
|
[301019] = {9050044, 1, 1, 1900, 0, 3, 0, 2},
|
||||||
|
[301020] = {9040036, 1, 1, 950, 0, 3, 0, 2},
|
||||||
|
[301021] = {9040025, 1, 1, 1500, 0, 3, 0, 2},
|
||||||
|
[301022] = {8013203, 1, 1, 1000, 11, 3, 0, 2},
|
||||||
|
[301023] = {8032603, 1, 1, 1000, 11, 3, 0, 2},
|
||||||
|
[301024] = {8071303, 1, 1, 1000, 11, 3, 0, 2},
|
||||||
|
[301025] = {8081703, 1, 1, 1000, 11, 3, 0, 2},
|
||||||
|
[301026] = {8050520, 1, 1, 1200, 11, 3, 0, 2},
|
||||||
|
[301027] = {8051024, 1, 1, 1200, 11, 3, 0, 2},
|
||||||
|
[301028] = {8050345, 1, 1, 1200, 11, 3, 0, 2},
|
||||||
|
[301029] = {8050449, 1, 1, 1200, 11, 3, 0, 2},
|
||||||
|
[301030] = {8090708, 1, 1, 1200, 11, 3, 0, 2},
|
||||||
|
[301031] = {4030305, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301032] = {4020011, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301033] = {4040208, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301034] = {4080306, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301035] = {4070012, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301036] = {5030037, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301037] = {5020217, 1, 1, 2500, 13, 3, 0, 2},
|
||||||
|
[301038] = {4100112, 1, 1, 2000, 13, 3, 0, 2},
|
||||||
|
[301039] = {8011522, 1, 1, 3000, 15, 3, 0, 2},
|
||||||
|
[301040] = {8030744, 1, 1, 3000, 15, 3, 0, 2},
|
||||||
|
[301041] = {8070361, 1, 1, 3000, 15, 3, 0, 2},
|
||||||
|
[301042] = {8050766, 1, 1, 3000, 15, 3, 0, 2},
|
||||||
|
[301043] = {8080562, 1, 1, 3000, 15, 3, 0, 2},
|
||||||
|
[301044] = {4030408, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301045] = {4020113, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301046] = {4040306, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301047] = {4080409, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301048] = {4070311, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301049] = {5030210, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301050] = {5020307, 1, 1, 4500, 17, 3, 0, 2},
|
||||||
|
[301051] = {4100712, 1, 1, 4000, 17, 3, 0, 2},
|
||||||
|
[301052] = {8011523, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301053] = {8030745, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301054] = {8070362, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301055] = {8050811, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301056] = {8050767, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301057] = {8080015, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301058] = {8080563, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301059] = {8090709, 1, 1, 5000, 21, 3, 0, 2},
|
||||||
|
[301060] = {9050023, 1, 1, 1000, 21, 3, 0, 2},
|
||||||
|
[301061] = {9050024, 1, 1, 1000, 21, 3, 0, 2},
|
||||||
|
[301062] = {9010025, 1, 1, 1000, 21, 3, 0, 2},
|
||||||
|
[301063] = {4100808, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301064] = {8013620, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301065] = {8032824, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301066] = {8051518, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301067] = {8071524, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301068] = {9030062, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301069] = {9050069, 1, 1, 5500, 23, 3, 0, 2},
|
||||||
|
[301070] = {8013621, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301071] = {8013622, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301072] = {8032825, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301073] = {8071525, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301074] = {8081916, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301075] = {9040067, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301076] = {9010063, 1, 1, 6000, 25, 3, 0, 2},
|
||||||
|
[301077] = {4100809, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301078] = {4020410, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301079] = {4040510, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301080] = {4080510, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301081] = {4070410, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301082] = {5030410, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301083] = {5020410, 1, 1, 6500, 27, 3, 0, 2},
|
||||||
|
[301084] = {4030606, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301085] = {4020406, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301086] = {4040506, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301087] = {4080506, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301088] = {4070406, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301089] = {5030406, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301090] = {5020406, 1, 1, 25000, 31, 3, 0, 2},
|
||||||
|
[301091] = {8013206, 1, 1, 6000, 31, 3, 0, 2},
|
||||||
|
[301092] = {8032606, 1, 1, 6000, 31, 3, 0, 2},
|
||||||
|
[301093] = {8071306, 1, 1, 6000, 31, 3, 0, 2},
|
||||||
|
[301094] = {8081706, 1, 1, 6000, 31, 3, 0, 2},
|
||||||
|
[302001] = {3020602, 1, 20, 5, 0, 3, 8, 3},
|
||||||
|
[302002] = {9040018, 1, 1, 1000, 11, 3, 11, 3},
|
||||||
|
[303001] = {2001006, 1, 1, 3000, 11, 3, 0, 4},
|
||||||
|
[303002] = {2001016, 1, 1, 3000, 15, 3, 0, 4},
|
||||||
|
[303003] = {2001023, 1, 1, 2000, 21, 3, 0, 4},
|
||||||
|
[303004] = {2001024, 1, 1, 3000, 21, 3, 0, 4},
|
||||||
|
[303005] = {2001025, 1, 1, 4000, 21, 3, 0, 4},
|
||||||
|
[303006] = {2001026, 1, 1, 25000, 27, 3, 0, 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
skipGCcheck = 0; -- 0 No, 1 Yes
|
||||||
|
playerGC = player.gcCurrent;
|
||||||
|
playerGCSeal = 1000200 + playerGC;
|
||||||
|
playerCurrentRank = 13;
|
||||||
|
npcId = npc:GetActorClassId();
|
||||||
|
|
||||||
|
if (playerGC == gcOfficer[npcId] or skipGCcheck == 1) then
|
||||||
|
callClientFunction(player, "eventTalkPreJoin");
|
||||||
|
--player:SendMessage(0x20, "", "[Info]: Client takes awhile to load GC shops");
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
eventTalkChoice = callClientFunction(player, "eventTalkMainMenu", 8, 11);
|
||||||
|
--player:SendMessage(0x20, "", "eventTalkMainMenu: " .. tostring(eventTalkChoice));
|
||||||
|
|
||||||
|
if (eventTalkChoice == 1) then
|
||||||
|
t1, t2, t3 = callClientFunction(player, "eventShopMenuOpen");
|
||||||
|
|
||||||
|
--player:SendMessage(0x20, "", "eventShopMenuOpen: " .. tostring(t1) .. ", ".. tostring(t2) .. ", ".. tostring(t3));
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
-- TODO: ADD RANK CHECK, CITY CHECK, AND ITEM-RANGE CHECK
|
||||||
|
|
||||||
|
buyResult, buyIndex = callClientFunction(player, "eventShopMenuAsk");
|
||||||
|
|
||||||
|
if (buyIndex == -1) then
|
||||||
|
callClientFunction(player, "eventShopMenuClose");
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
-- [index] = { itemID, itemQuality, itemQuantity, itemCost gcRank, city, special, itemCategory }
|
||||||
|
if (shopInfo[buyIndex][8] == 4) then
|
||||||
|
location = INVENTORY_KEYITEMS;
|
||||||
|
else
|
||||||
|
location = INVENTORY_NORMAL;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
purchaseItem(player, location, shopInfo[buyIndex][1], shopInfo[buyIndex][3], shopInfo[buyIndex][2], shopInfo[buyIndex][4], playerGCSeal);
|
||||||
|
end
|
||||||
|
|
||||||
|
--player:SendMessage(0x20, "", "Player picked an item at gcSealShopIndex " .. tostring(buyResult) .. ", ".. tostring(buyIndex));
|
||||||
|
|
||||||
|
elseif (eventTalkChoice == -1) then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkStepCantUse");
|
||||||
|
end
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,464 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanySupply Script
|
||||||
|
|
||||||
|
This class handles the menus for player's delivering specific items in exchange for grand company seals.
|
||||||
|
The supply/provision schedule runs on a weekly rotation, which resets Monday at 12AM JST, with eight rotations total to cycle through.
|
||||||
|
Each desired item has a server-wide max that it can be turned in, and when that is fulfilled, it moves to the next item in that week's list to work on.
|
||||||
|
|
||||||
|
NPCs involved in the script use the Noc001 script for dialog and menu interactions.
|
||||||
|
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkPreJoin() - Dialog when you're not affiliated
|
||||||
|
eventTalkExclusive() - Dialog when you're part of a GC but not the one of the actor?
|
||||||
|
eventTalkJoined() - Salutes then softlocks the client due to removed dialog strings. Obsolete function.
|
||||||
|
|
||||||
|
eventQuestItemMenuOpen(itemId, itemPrice, itemPriceHq, supplyType) - supplyType: 1 = Supply, 2 = Provisioning, 3 = Totorak, 4 = Dzmael, 5 = Primal, 6 = NM drops
|
||||||
|
eventQuestItemMenuSelect(quantity, quality, unk) - Brings up the shop-style menu for viewing item detail and confirming item delivery. Args appear to do nothing on client?
|
||||||
|
eventQuestItemMenuClose() - Closes menu
|
||||||
|
|
||||||
|
eventQuestSupplyItemActor(unk1) -- Client calls this automatically for setting up Expeditionary window in some manner
|
||||||
|
eventQuestSupplyItemID(unk1, unk2) -- eventQuestSupplyItemActor() calls this to sets item ranges based on category
|
||||||
|
|
||||||
|
getEventQuestSupplyMode() - Returns current supply mode set by eventQuestItemMenuOpen()
|
||||||
|
eventTalkStepBreak() - Resets actor engage state
|
||||||
|
|
||||||
|
|
||||||
|
Noc001 Functions:
|
||||||
|
|
||||||
|
pENPCAskSupplyWelcome(npcGC) -- Welcome dialog
|
||||||
|
pENPCAskSupply(npcGC) -- Brings up the delivery selection menu
|
||||||
|
eventQuestAskExWelcome(npcGC) -- Dialog when you pick Expeditionary
|
||||||
|
eventQuestAskExArea(npcGC) -- Brings up the Expeditionary selection menu
|
||||||
|
pENPCAskNowTalk(npcGC) -- Dialog for picking Delivery Status from pENPCAskSupply()
|
||||||
|
|
||||||
|
nowSup(itemId1, current1, max1, itemId2, current2, max2, itemId3, current3, max3) -- Says current 3 items and current amount delivered vs. max it'll take
|
||||||
|
nowSupAddItem(itemId, current, max) -- Lists bonus item
|
||||||
|
pItem(itemId1, unk1, itemId2, unk2, itemId3, unk3, itemId4, unk4) -- Lists which item(s) you want to delivery. Fourth item is the bonus, set 0 for hidden.
|
||||||
|
|
||||||
|
showSupplyLimit(minutes, seconds, current, required) -- Shows time remaining to finish delivery, shows current/required amount
|
||||||
|
eventShowPrizeMessage(npcGC) -- Reward dialog for handing something in?
|
||||||
|
|
||||||
|
pELimitErr() -- Error msg for GC no longer accepting items.
|
||||||
|
pETradeErr() -- Transaction error. Inventory error?
|
||||||
|
pETradeErrLimit(minutes, seconds, current, required) -- Transaction error. Shows time remaining and current/required amount
|
||||||
|
pESuppylMaxErrKeyWait(isShowLimit, minutes, seconds, current, required) -- Error msg for delivery quota already filled. Optional timer/amount display
|
||||||
|
pESuppylSealMaxErr() -- Error msg for capped on GC seals, transaction incomplete
|
||||||
|
|
||||||
|
eventQuestCantEx(npcGC) -- Dialog explaining you need to be Private Second Class to do Expeditionary missions
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("shop")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
local gcRep = {
|
||||||
|
[1500210] = 1, -- Maelstrom Representative
|
||||||
|
[1500211] = 2, -- Adder Representative
|
||||||
|
[1500212] = 3, -- Flame Representative
|
||||||
|
}
|
||||||
|
|
||||||
|
local gcItems = { -- Debug purposes. Static item list with seal value and max turn-in.
|
||||||
|
[111] = {id = 10002015, seals = 8, cap = 1900},
|
||||||
|
[112] = {id = 8031419, seals = 68, cap = 300},
|
||||||
|
[113] = {id = 3010011, seals = 3, cap = 5000},
|
||||||
|
[114] = {id = 8011108, seals = 89, cap = 400},
|
||||||
|
|
||||||
|
[115] = {id = 10004001, seals = 5, cap = 3000},
|
||||||
|
[116] = {id = 10008109, seals = 3, cap = 5000},
|
||||||
|
[117] = {id = 12000180, seals = 5, cap = 3000},
|
||||||
|
[118] = {id = 10004026, seals = 9, cap = 3400},
|
||||||
|
|
||||||
|
[121] = {id = 10008211, seals = 5, cap = 3000},
|
||||||
|
[122] = {id = 3020407, seals = 5, cap = 2500},
|
||||||
|
[123] = {id = 8030220, seals = 92, cap = 200},
|
||||||
|
[124] = {id = 8030922, seals = 99, cap = 400},
|
||||||
|
|
||||||
|
[125] = {id = 10001014, seals = 3, cap = 5000},
|
||||||
|
[126] = {id = 10008007, seals = 5, cap = 3000},
|
||||||
|
[127] = {id = 3011217, seals = 3, cap = 5000},
|
||||||
|
[128] = {id = 3011207, seals = 3, cap = 6000},
|
||||||
|
|
||||||
|
[131] = {id = 4030204, seals = 69, cap = 300},
|
||||||
|
[132] = {id = 10004103, seals = 9, cap = 1700},
|
||||||
|
[133] = {id = 10009208, seals = 6, cap = 3000},
|
||||||
|
[134] = {id = 1, seals = 1, cap = 1}, -- Unknown
|
||||||
|
|
||||||
|
[135] = {id = 10004008, seals = 9, cap = 1700},
|
||||||
|
[136] = {id = 10008007, seals = 5, cap = 3000},
|
||||||
|
[137] = {id = 3011201, seals = 5, cap = 3000},
|
||||||
|
[138] = {id = 10009401, seals = 6, cap = 6000},
|
||||||
|
|
||||||
|
[211] = {id = 10002012, seals = 5, cap = 3000},
|
||||||
|
[212] = {id = 4100007, seals = 51, cap = 300},
|
||||||
|
[213] = {id = 3010108, seals = 2, cap = 3000},
|
||||||
|
[214] = {id = 8080825, seals = 42, cap = 800},
|
||||||
|
|
||||||
|
[215] = {id = 10004003, seals = 5, cap = 3000},
|
||||||
|
[216] = {id = 10002012, seals = 3, cap = 5000},
|
||||||
|
[217] = {id = 3011104, seals = 2, cap = 3000},
|
||||||
|
[218] = {id = 3011107, seals = 3, cap = 6000},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local gcWeek = { -- Debug purposes. Static weekly item lists. [week] = { [city] = {[category] = { info } } }
|
||||||
|
[1] = {
|
||||||
|
[1] = { -- Limsa
|
||||||
|
[1] = { -- Supply
|
||||||
|
gcItems[111],
|
||||||
|
gcItems[112],
|
||||||
|
gcItems[113],
|
||||||
|
gcItems[114],
|
||||||
|
},
|
||||||
|
[2] = { -- Provision
|
||||||
|
gcItems[115],
|
||||||
|
gcItems[116],
|
||||||
|
gcItems[117],
|
||||||
|
gcItems[118],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[2] = { -- Gridania
|
||||||
|
[1] = { -- Supply
|
||||||
|
gcItems[121],
|
||||||
|
gcItems[122],
|
||||||
|
gcItems[123],
|
||||||
|
gcItems[124],
|
||||||
|
},
|
||||||
|
[2] = { -- Provision
|
||||||
|
gcItems[125],
|
||||||
|
gcItems[126],
|
||||||
|
gcItems[127],
|
||||||
|
gcItems[128],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[3] = { -- Ul'dah
|
||||||
|
[1] = { -- Supply
|
||||||
|
gcItems[131],
|
||||||
|
gcItems[132],
|
||||||
|
gcItems[133],
|
||||||
|
gcItems[134],
|
||||||
|
},
|
||||||
|
[2] = { -- Provision
|
||||||
|
gcItems[135],
|
||||||
|
gcItems[136],
|
||||||
|
gcItems[137],
|
||||||
|
gcItems[138],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
[2] = {
|
||||||
|
[1] = { -- Limsa
|
||||||
|
[1] = { -- Supply
|
||||||
|
gcItems[211],
|
||||||
|
gcItems[212],
|
||||||
|
gcItems[213],
|
||||||
|
gcItems[214],
|
||||||
|
},
|
||||||
|
[2] = { -- Provision
|
||||||
|
gcItems[215],
|
||||||
|
gcItems[216],
|
||||||
|
gcItems[217],
|
||||||
|
gcItems[218],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
local gcDelivery = { -- Debug purposes. Holds values for current turned in amount and 4th item bonus status.
|
||||||
|
week = 1,
|
||||||
|
currentCount = {
|
||||||
|
{
|
||||||
|
{49, 81, 5000, 5}, {2402, 4779, 589, 2} -- Limsa Supply/Provision
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{1, 2, 3, 4}, {5, 6, 7, 8} -- Gridania Supply/Provision
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{10, 32, 9, 18}, {23, 49, 9, 300} -- Ul'dah Supply/Provision
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bonus = { {1, 1}, {0,1}, {0,1} }; -- City -> {Supply, Provision}
|
||||||
|
timeRemainingMinutes = 99,
|
||||||
|
timeRemainingSeconds = 59,
|
||||||
|
}
|
||||||
|
|
||||||
|
local supplyQuest = GetStaticActor("Noc001");
|
||||||
|
local skipGCcheck = false; -- Debug
|
||||||
|
local skipRankCheck = false; -- Debug
|
||||||
|
local gcCheckProceed = false; -- Debug
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local playerGC = player.gcCurrent;
|
||||||
|
local limsaRank = player.gcRankLimsa;
|
||||||
|
local gridaniaRank = player.gcRankGridania;
|
||||||
|
local uldahRank = player.gcRankUldah;
|
||||||
|
local playerGCSeal = 1000200 + playerGC;
|
||||||
|
|
||||||
|
local npcId = npc:GetActorClassId();
|
||||||
|
local npcGC = gcRep[npcId];
|
||||||
|
|
||||||
|
if (skipGCcheck == true) then
|
||||||
|
gcCheckProceed = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((playerGC ~= npcGC) and skipGCcheck == false) then
|
||||||
|
if (playerGC == 0) then
|
||||||
|
callClientFunction(player, "eventTalkPreJoin");
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkExclusive");
|
||||||
|
end
|
||||||
|
else
|
||||||
|
gcCheckProceed = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
if gcCheckProceed then
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskSupplyWelcome", gcRep[npcId]);
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskSupply", gcRep[npcId]);
|
||||||
|
|
||||||
|
if (choice == 2) then -- Supply
|
||||||
|
deliveryMenuInfo(player, npcGC, 1);
|
||||||
|
|
||||||
|
elseif (choice == 3) then -- Provision
|
||||||
|
deliveryMenuInfo(player, npcGC, 2);
|
||||||
|
|
||||||
|
elseif (choice == 4) then -- Expeditionary
|
||||||
|
local proceed = false;
|
||||||
|
|
||||||
|
if (skipRankCheck == true) then
|
||||||
|
proceed = true;
|
||||||
|
else
|
||||||
|
if (playerGC == 1 and limsaRank >= 13 and limsaRank <= 111)
|
||||||
|
or (playerGC == 2 and gridaniaRank >= 13 and gridaniaRank <= 111)
|
||||||
|
or (playerGC == 3 and uldahRank >= 13 and uldahRank <= 111) then
|
||||||
|
proceed = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if proceed == true then
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestAskExWelcome", gcRep[npcId]);
|
||||||
|
while (true) do
|
||||||
|
local exChoice = callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestAskExArea", gcRep[npcId]);
|
||||||
|
|
||||||
|
if (exChoice >= 3) then
|
||||||
|
deliveryMenuOpen(player, npc, 0,0,0, exChoice);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestCantEx",gcRep[npcId]);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif (choice == 5) then -- Requested item
|
||||||
|
deliveryStatus(player, npcGC);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
wait(1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
player:endEvent()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function deliveryMenuInfo(player, city, category)
|
||||||
|
|
||||||
|
local gcContents = getWeeklyItems(city, category);
|
||||||
|
local gcCurrent = getCurrentCount(city, category);
|
||||||
|
local supplyChoice = 0;
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
if gcDelivery.bonus[city][category] == 1 then -- Show fourth item if condition is met, otherwise show three.
|
||||||
|
|
||||||
|
supplyChoice = callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"pItem",
|
||||||
|
gcContents[1].id,
|
||||||
|
1,
|
||||||
|
gcContents[2].id,
|
||||||
|
1,
|
||||||
|
gcContents[3].id,
|
||||||
|
1,
|
||||||
|
gcContents[4].id,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
else
|
||||||
|
supplyChoice = callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"pItem",
|
||||||
|
gcContents[1].id,
|
||||||
|
1,
|
||||||
|
gcContents[2].id,
|
||||||
|
1,
|
||||||
|
gcContents[3].id,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if supplyChoice >= 2 then
|
||||||
|
|
||||||
|
if gcCurrent[supplyChoice-1] < gcContents[supplyChoice-1].cap then
|
||||||
|
local hqPrice = math.ceil(gcContents[supplyChoice-1].seals * 1.5);
|
||||||
|
|
||||||
|
deliveryMenuOpen
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
npc,
|
||||||
|
gcContents[supplyChoice-1].id,
|
||||||
|
gcContents[supplyChoice-1].seals,
|
||||||
|
hqPrice,
|
||||||
|
category
|
||||||
|
);
|
||||||
|
|
||||||
|
else
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "pESuppylMaxErrKeyWait");
|
||||||
|
end
|
||||||
|
elseif supplyChoice == 1 then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
wait(1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function deliveryMenuOpen(player, npc, itemId, price, hqPrice, supplyType)
|
||||||
|
|
||||||
|
callClientFunction(player, "eventQuestItemMenuOpen", itemId, price, hqPrice, supplyType);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
local choice, quantity, quality, itemSlot, Type7Param = callClientFunction(player, "eventQuestItemMenuSelect");
|
||||||
|
|
||||||
|
if choice == false then
|
||||||
|
callClientFunction(player, "eventQuestItemMenuClose");
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
player:SendMessage(0x20, "", "Choice: " .. tostring(choice));
|
||||||
|
player:SendMessage(0x20, "", "Quantity: " .. tostring(quantity));
|
||||||
|
player:SendMessage(0x20, "", "Quality: " .. tostring(quality));
|
||||||
|
player:SendMessage(0x20, "", "Slot: " .. tostring(itemSlot)); -- Broke at some point, always return 0, investigate sometime
|
||||||
|
player:SendMessage(0x20, "", "Type7Param: " .. tostring(Type7Param.slot));
|
||||||
|
--]]
|
||||||
|
|
||||||
|
pickedItem = GetItemGamedata(player:GetItemPackage(INVENTORY_NORMAL):GetItemAtSlot(Type7Param.slot).itemId).name;
|
||||||
|
player:SendMessage(0x20, "", "Player tried to deliver " .. quantity .. " " .. pickedItem);
|
||||||
|
|
||||||
|
-- TODO: Add error handling for capped seals, no-long-available-to-deliver, etc
|
||||||
|
wait(1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function deliveryStatus(player, city)
|
||||||
|
local gcContents = getWeeklyItems(city, 1);
|
||||||
|
local gcCurrent = getCurrentCount(city, 1);
|
||||||
|
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskNowTalk", gcRep[npcId]);
|
||||||
|
callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"nowSup",
|
||||||
|
gcContents[1].id,
|
||||||
|
gcCurrent[1],
|
||||||
|
gcContents[1].cap,
|
||||||
|
gcContents[2].id,
|
||||||
|
gcCurrent[2],
|
||||||
|
gcContents[2].cap,
|
||||||
|
gcContents[3].id,
|
||||||
|
gcCurrent[3],
|
||||||
|
gcContents[3].cap
|
||||||
|
);
|
||||||
|
if gcDelivery.bonus[city][1] == 1 then
|
||||||
|
callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"nowSupAddItem",
|
||||||
|
gcContents[4].id,
|
||||||
|
gcCurrent[4],
|
||||||
|
gcContents[4].cap
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
gcContents = getWeeklyItems(city, 2);
|
||||||
|
gcCurrent = getCurrentCount(city, 2);
|
||||||
|
|
||||||
|
callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"nowSup",
|
||||||
|
gcContents[1].id,
|
||||||
|
gcCurrent[1],
|
||||||
|
gcContents[1].cap,
|
||||||
|
gcContents[2].id,
|
||||||
|
gcCurrent[2],
|
||||||
|
gcContents[2].cap,
|
||||||
|
gcContents[3].id,
|
||||||
|
gcCurrent[3],
|
||||||
|
gcContents[3].cap
|
||||||
|
);
|
||||||
|
if gcDelivery.bonus[city][2] == 1 then
|
||||||
|
callClientFunction
|
||||||
|
(
|
||||||
|
player,
|
||||||
|
"delegateEvent",
|
||||||
|
player,
|
||||||
|
supplyQuest,
|
||||||
|
"nowSupAddItem",
|
||||||
|
gcContents[4].id,
|
||||||
|
gcCurrent[4],
|
||||||
|
gcContents[4].cap
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
callClientFunction(player, "delegateEvent", player, supplyQuest, "showSupplyLimit", gcDelivery.timeRemainingMinutes, gcDelivery.timeRemainingSeconds, 2, 8);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function getWeeklyItems(city, category)
|
||||||
|
return gcWeek[gcDelivery.week][city][category]
|
||||||
|
end
|
||||||
|
|
||||||
|
function getCurrentCount(city, category)
|
||||||
|
return gcDelivery.currentCount[city][category];
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceCompanyWarp Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkWelcome(player) - Start Text
|
||||||
|
eventAskMainMenu(player, index) - Shows teleport menu, hides the teleport location at index value to prevent warping to the spot you're at
|
||||||
|
eventAfterWarpOtherZone(player) - Fades out for warp
|
||||||
|
eventTalkStepBreak() - Holds the client up for whatever reason?
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
warpNpc =
|
||||||
|
{ --[actorId] = {warpIndex, cityId} -- ()s around name indicate missing NPC + Aethernet
|
||||||
|
[1500321] = {1, 1}, -- (Storm Private Gardner)
|
||||||
|
[1500331] = {2, 1}, -- (Storm Private Rich)
|
||||||
|
[1500323] = {3, 1}, -- (Storm Private Potter)
|
||||||
|
[1500330] = {4, 1}, -- (Storm Private Hunt)
|
||||||
|
[1500322] = {5, 1}, -- (Storm Private Abel)
|
||||||
|
[1500332] = {6, 1}, -- (Storm Private Stone)
|
||||||
|
[1500339] = {7, 1}, -- (Storm Private Holt)
|
||||||
|
[1500324] = {1, 2}, -- serpent_private_white
|
||||||
|
[1500334] = {2, 2}, -- serpent_private_hill
|
||||||
|
[1500326] = {3, 2}, -- serpent_private_carver
|
||||||
|
[1500333] = {4, 2}, -- serpent_private_stone
|
||||||
|
[1500325] = {5, 2}, -- serpent_private_holmes
|
||||||
|
[1500335] = {6, 2}, -- serpent_private_kirk
|
||||||
|
[1500327] = {1, 3}, -- flame_private_newton
|
||||||
|
[1500337] = {2, 3}, -- (Flame Private Tanner)
|
||||||
|
[1500329] = {3, 3}, -- (Flame Private Morning)
|
||||||
|
[1500336] = {4, 3}, -- (Flame Private Covey)
|
||||||
|
[1500328] = {5, 3}, -- flame_private_allen
|
||||||
|
[1500338] = {6, 3}, -- (Flame Private Yar)
|
||||||
|
}
|
||||||
|
|
||||||
|
aethernet =
|
||||||
|
{
|
||||||
|
{ -- 1: Limsa
|
||||||
|
{zone = 230, x = -424.140, y = 42.000, z = 371.988, r = -2.472}, -- 1 - Aetheryte Plaza
|
||||||
|
{zone = 133, x = -439.744, y = 40.000, z = 234.376, r = 0.287}, -- 2 - Drowning Wench
|
||||||
|
{zone = 230, x = -498.131, y = 43.622, z = 60.818, r = 0.254}, -- 3 - The Bismarck
|
||||||
|
{zone = 230, x = -759.331, y = 12.000, z = 239.413, r = -0.869}, -- 4 - Ferry Docks
|
||||||
|
{zone = 230, x = -623.582, y = 4.000, z = 369.318, r = 1.736}, -- 5 - Fisherman's Bottom
|
||||||
|
{zone = 230, x = -525.536, y = 18.000, z = 173.735, r = 3.082}, -- 6 - The Octant
|
||||||
|
{zone = 133, x = -231.711, y = 12.000, z = 193.573, r = -0.786}, -- 7 - Procession of Terns
|
||||||
|
{zone = 128, x = -20.783, y = 42.214, z = 146.946, r = 2.046}, -- 8 - Zephyr Gate
|
||||||
|
},
|
||||||
|
{ -- 2: Gridania
|
||||||
|
{zone = 206, x = -107.878, y = 17.524, z = -1343.871, r = 0.657}, -- 1 - Aetheryte Plaza
|
||||||
|
{zone = 155, x = 96.868, y = 3.480, z = -1211.040, r = 2.582}, -- 2 - Carline Canopy
|
||||||
|
{zone = 206, x = 86.942, y = 19.789, z = -1420.891, r = 2.965}, -- 3 - Atelier Fen-Yil
|
||||||
|
{zone = 206, x = -84.621, y = 19.061, z = -1502.665, r = 0.756}, -- 4 - Whistling Miller
|
||||||
|
{zone = 206, x = 205.101, y = 9.526, z = -1245.405, r = -1.749}, -- 5 - Quiver's Hold
|
||||||
|
{zone = 206, x = 160.578, y = 25.061, z = -1556.662, r = 1.896}, -- 6 - Wailing Barracks
|
||||||
|
{zone = 150, x = 318.838, y = 4.036, z = -992.071, r = -0.307}, -- 7 - Mistalle Bridges
|
||||||
|
{zone = 206, x = -192.167, y = 4.466, z = -1061.777, r = -0.026}, -- 8 - Berlends Bridges
|
||||||
|
},
|
||||||
|
{ -- 3: Ul'dah
|
||||||
|
{zone = 175, x = -190.574, y = 190.000, z = 18.086, r = 2.190}, -- 1 - Aetheryte Plaza
|
||||||
|
{zone = 175, x = -36.513, y = 192.000, z = 37.130, r = -0.490}, -- 2 - Quicksand
|
||||||
|
{zone = 209, x = -192.971, y = 230.000, z = 209.348, r = 2.860}, -- 3 - Frondale's Phrontistery
|
||||||
|
{zone = 209, x = -60.243, y = 200.000, z = 257.718, r = -1.276}, -- 4 - Onyx Lane
|
||||||
|
{zone = 209, x = -147.633, y = 198.000, z = 160.064, r = -1.600}, -- 5 - Gold Court
|
||||||
|
{zone = 209, x = -263.776, y = 202.000, z = 206.699, r = -3.135}, -- 6 - Arrzaneth Ossuary
|
||||||
|
{zone = 170, x = -29.721, y = 182.635, z = -76.313, r = 2.625}, -- 7 - Gate of Nald
|
||||||
|
{zone = 170, x = 129.957, y = 183.862, z = 220.719, r = 1.515}, -- 8 - Gate of Thal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local passLimsa = 2001014;
|
||||||
|
local passGrid = 2001015;
|
||||||
|
local passUldah = 2001016;
|
||||||
|
passCheck = 1; -- 0 = Check player for Aetherpass keyitem. 1 = Ignore it.
|
||||||
|
|
||||||
|
npcId = npc:GetActorClassId();
|
||||||
|
city = warpNpc[npcId][2];
|
||||||
|
|
||||||
|
if (city == 1) then
|
||||||
|
if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passLimsa) then
|
||||||
|
passCheck = 1;
|
||||||
|
else
|
||||||
|
if (passCheck == 0) then callClientFunction(player, "eventTalkWelcome", player); end
|
||||||
|
end;
|
||||||
|
elseif (city == 2) then
|
||||||
|
-- if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passGrid) then
|
||||||
|
passCheck = 1;
|
||||||
|
-- else
|
||||||
|
-- if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end
|
||||||
|
--end;
|
||||||
|
elseif (city == 3) then
|
||||||
|
if (player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passUldah)) then
|
||||||
|
passCheck = 1;
|
||||||
|
else
|
||||||
|
if (passCheck == 0) then callClientFunction(player, "eventTalkWelcome", player); end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if (passCheck == 1) then
|
||||||
|
choice = callClientFunction(player, "eventAskMainMenu", player, warpNpc[npcId][1]);
|
||||||
|
|
||||||
|
|
||||||
|
if (choice ~= 0) then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
callClientFunction(player, "eventAfterWarpOtherZone", player);
|
||||||
|
wait(1);
|
||||||
|
player:EndEvent();
|
||||||
|
local player_zone = player:GetPos()[5];
|
||||||
|
spawnType = 0x0A;
|
||||||
|
if (player_zone == aethernet[city][choice].zone) then
|
||||||
|
|
||||||
|
GetWorldManager():DoPlayerMoveInZone(player, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r, spawnType);
|
||||||
|
else
|
||||||
|
GetWorldManager():DoZoneChange(player, aethernet[city][choice].zone, nil, 0, spawnType, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,68 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceFlyingShip Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventIn(player, hasTicket, nil?, travelPrice) - If hasTicket == nil, say no money text.
|
||||||
|
eventOut(isAborting) - Set isAborting to 30010 if player didn't "use" the airship. Shows no refund warning.
|
||||||
|
eventNG(player) - Message said when player is talking to the wrong npc.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
-- Special case for A Slippery Stone and Cutthroat Prices
|
||||||
|
if (player:HasQuest(110737) == true) then
|
||||||
|
require ("quests/etc/etc3g3");
|
||||||
|
local quest = player:GetQuest("Etc3g3");
|
||||||
|
if (quest:GetSequence() == SEQ_000) then
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent_005");
|
||||||
|
if (choice == 1) then
|
||||||
|
quest:StartSequence(SEQ_001);
|
||||||
|
addPlayerToAirship(player, 2);
|
||||||
|
end
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
elseif (player:HasQuest(110728) == true) then
|
||||||
|
require ("quests/etc/etc3u3");
|
||||||
|
local quest = player:GetQuest("Etc3u3");
|
||||||
|
if (quest:GetSequence() == SEQ_000) then
|
||||||
|
local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent_005");
|
||||||
|
if (choice == 1) then
|
||||||
|
quest:StartSequence(SEQ_001);
|
||||||
|
addPlayerToAirship(player, 3);
|
||||||
|
end
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise normal operation
|
||||||
|
callClientFunction(player, "eventIn", player, false, nil, 5);
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
function addPlayerToAirship(player, city)
|
||||||
|
if (city == 1) then
|
||||||
|
-- Limsa Airship
|
||||||
|
GetWorldManager():WarpToPosition(player, -764.519, -3.146, 384.154, 1.575);
|
||||||
|
--GetWorldManager():AddPlayerToShipList(player, 2);
|
||||||
|
elseif (city == 2) then
|
||||||
|
-- Gridania Airship
|
||||||
|
GetWorldManager():WarpToPosition(player, 54.47, -7, -1198.54, -0.02);
|
||||||
|
--GetWorldManager():AddPlayerToShipList(player, 3);
|
||||||
|
elseif (city == 3) then
|
||||||
|
-- Ul'dah Airship
|
||||||
|
GetWorldManager():WarpToPosition(player, -126.580, 271.2, 156.435, -1.35);
|
||||||
|
--GetWorldManager():AddPlayerToShipList(player, 4);
|
||||||
|
end
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,51 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceItemRepairer Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
talkWelcome(player, sayWelcomeText, currentLevel?, changes 1500243 from "welcome" to "well met") - Opens the main menu
|
||||||
|
selectItem(nil, pageNumber, ?, condition1, condition2, condition3, condition4, condition5) - Select item slot.
|
||||||
|
confirmRepairItem(player, price, itemId, hq grade) - Shows the confirm box for item repair.
|
||||||
|
confirmUseFacility(player, price) - Shows confirm box for using facility. Default price is 11k?
|
||||||
|
finishTalkTurn() - Call at end to stop npc from staring at the player (eeeek)
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
result = callClientFunction(player, "talkWelcome", player, true, 20, false);
|
||||||
|
|
||||||
|
if (result == 1) then
|
||||||
|
local currentPage = 1;
|
||||||
|
local slotToRepair = nil;
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
slot, page, listIndx = callClientFunction(player, "selectItem", nil, currentPage, 4, 2, 55, 55, 55, 55);
|
||||||
|
|
||||||
|
if (slot == nil and page ~= nil) then
|
||||||
|
currentPage = page;
|
||||||
|
else
|
||||||
|
slotToRepair = slot;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (slotToRepair ~= nil) then
|
||||||
|
callClientFunction(player, "confirmRepairItem", player, 100, 8032827, 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif (result == 2) then
|
||||||
|
callClientFunction(player, "confirmUseFacility", player);
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "finishTalkTurn");
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceLinkshellManager Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkStep1(noLinkshellActive) - Says intro. If noLinkshellActive = true, say newbie stuff.
|
||||||
|
eventTalkStep2(noLinkshellActive) - Shows menu, if noLinkshellActive = true, only give ability to make linkshell.
|
||||||
|
eventTalkStepMakeupDone() - Confirm when creating LS
|
||||||
|
eventTalkStepModifyDone() - Confirm when modding LS
|
||||||
|
eventTalkStepBreakDone() - Confirm when deleting LS
|
||||||
|
|
||||||
|
Text IDs:
|
||||||
|
|
||||||
|
25121 - That [@SWITCH($E8(1),linkshell,company)] name is already being used.
|
||||||
|
25122 - That [@SWITCH($E8(1),linkshell,company)] name cannot be used.
|
||||||
|
25123 - The [@SWITCH($E8(1),linkshell,company)] “[@STRING($EA(2))]” has been [@SWITCH($E8(1),created,founded)].
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function createLinkshell(player, name, crest)
|
||||||
|
GetWorldManager():RequestWorldLinkshellCreate(player, name, crest);
|
||||||
|
return waitForSignal("ls_result");
|
||||||
|
end
|
||||||
|
|
||||||
|
function modifyLinkshell(player, name, crest)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function disbandLinkshell(player, name, crest)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
local hasNoActiveLS = false;
|
||||||
|
|
||||||
|
callClientFunction(player, "eventTalkStep1", hasNoActiveLS);
|
||||||
|
local command, lsName, crestId = callClientFunction(player, "eventTalkStep2", hasNoActiveLS);
|
||||||
|
|
||||||
|
--Create
|
||||||
|
if (command == 3) then
|
||||||
|
local result = createLinkshell(player, lsName, crestId);
|
||||||
|
if (result == 0) then
|
||||||
|
callClientFunction(player, "eventTalkStepMakeupDone");
|
||||||
|
elseif (result == 1) then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 25121, 0x20); --LS already exists
|
||||||
|
callClientFunction(player, "eventTalkStepBreakDone");
|
||||||
|
elseif (result == 2) then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 25122, 0x20); --Cannot use this name (reserved/banned)
|
||||||
|
callClientFunction(player, "eventTalkStepBreakDone");
|
||||||
|
elseif (result == 3) then
|
||||||
|
end
|
||||||
|
--Modify
|
||||||
|
elseif (command == 4) then
|
||||||
|
modifyLinkshell(player, lsName, crestId);
|
||||||
|
callClientFunction(player, "eventTalkStepModifyDone");
|
||||||
|
--Disband
|
||||||
|
elseif (command == 5) then
|
||||||
|
disbandLinkshell(player, lsName, crestId);
|
||||||
|
callClientFunction(player, "eventTalkStepBreakDone");
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,381 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulacePassiveGLPublisher
|
||||||
|
|
||||||
|
Operates the Local Levequest selection menus.
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
askOfferPack(player)
|
||||||
|
Desc: Show class selection menu.
|
||||||
|
Params: * player - The player actor.
|
||||||
|
Returns: Value dictating which item on the list was selected (1-8 for class, nil if exited/canceled)
|
||||||
|
|
||||||
|
askOfferRank(player)
|
||||||
|
Desc: Show Level selection menu.
|
||||||
|
Params: * player - The player actor.
|
||||||
|
Returns: Value dictating which item on the list was selected (1 = Lv01, 2 = Lv20, 3 = Lv40, nil if exited/canceled)
|
||||||
|
|
||||||
|
askOfferQuest(player, ?, questId1, questId2, questId3, questId4, questId5, questId6, questId7, questId8)
|
||||||
|
Desc: Show Leve quest selection menu with up to 8 questId entries
|
||||||
|
Params: * player - The player actor.
|
||||||
|
* ? - Unused param. Capture has a 2.
|
||||||
|
* questId 1-8 - The local levequests available up to 8 quests.
|
||||||
|
Returns: 1 through 8 for an accepted leve in the order sent, -1 for hitting "Return", and Nil for "Cancel"
|
||||||
|
|
||||||
|
confirmOffer(player, questId)
|
||||||
|
Desc: Opens prompt asking whether to activate the leve and begin it.
|
||||||
|
Params: * player - The player actor.
|
||||||
|
* questId - The quest being confirmed.
|
||||||
|
Returns: Boolean - True on Yes, false on No or hitting escape.
|
||||||
|
|
||||||
|
confirmMaxOffer(player)
|
||||||
|
Desc: Opens ask widget stating you'll be capped on leves after accepting.
|
||||||
|
Params: * player - The player actor. Unused.
|
||||||
|
Returns: Boolean - True on Accept, false on "Quit" or hitting escape.
|
||||||
|
|
||||||
|
talkOfferWelcome(player, numAllowance)
|
||||||
|
Desc: NPC intro dialog as well as stating your available leve allowances.
|
||||||
|
Params: * player - The player actor.
|
||||||
|
* numAllowance - The number of leve allowances the player still has.
|
||||||
|
|
||||||
|
talkOfferDecide()
|
||||||
|
Desc: Makes the NPC say dialog following the acceptance of a leve.
|
||||||
|
Params: None
|
||||||
|
|
||||||
|
talkOfferMaxOver()
|
||||||
|
Desc: Makes the NPC say dialog stating the player is carrying too many leves currently.
|
||||||
|
Params: None
|
||||||
|
|
||||||
|
finishTalkTurn()
|
||||||
|
Desc: Ends the npc actor's turn towards you. Call this at the end of the script or the
|
||||||
|
npc will be stuck "facing" the player.
|
||||||
|
Params: None
|
||||||
|
|
||||||
|
selectDiscardGuildleve()
|
||||||
|
Desc: Opens the Journal widget to select a leve to discard. This is a follow-up to askDiscardGuildleve().
|
||||||
|
Params: None
|
||||||
|
Returns: Quest Actor
|
||||||
|
|
||||||
|
confirmJournal(questId, difficulty, unused, itemsCompleted, remainingMats, hasMaterials, unused)
|
||||||
|
Desc: Opens askJournalDetailWidget displaying current status of the leve.
|
||||||
|
Params: * questId - The current quest being confirmed.
|
||||||
|
* difficulty - The difficulty of the quest.
|
||||||
|
* unused - Unused param.
|
||||||
|
* itemsComplete - Sets the number of items crafted.
|
||||||
|
* remainingMats - Sets the remaining materials.
|
||||||
|
* hasMaterials - If set to 1, shows the progress section.
|
||||||
|
* unused - While loaded into widget, it doesn't do anything with this journalType (13).
|
||||||
|
Returns: True on "Exchange", Nil on "Return" or hitting Escape key
|
||||||
|
|
||||||
|
askDiscardGuildleve()
|
||||||
|
Desc: Opens an ask widget, stating the player cannot accept any more guildleves and if they'd want to return one to make room.
|
||||||
|
Params: None
|
||||||
|
Returns: Boolean
|
||||||
|
|
||||||
|
confirmDiscardGuildleve(?, questId, guildleveId)
|
||||||
|
Desc: Opens an ask widget, confirming the returning of the selected guildleve.
|
||||||
|
Params: * ? - Most likely a player actor, but unused.
|
||||||
|
* questId - The dialog is "Returning <quest>. Are you certain?". This is the questId being returned.
|
||||||
|
* guildleveId - This is mostly unused, Japanese localization has a weird switch to use this. Can be nil.
|
||||||
|
Returns: Boolean
|
||||||
|
|
||||||
|
askRetryRegionalleve(questId, numAllowance)
|
||||||
|
Desc: Opens an ask widget to re-attempt leve questId while showing leveAllowances. If no is selected, a second widget appears to confirm abandoning it.
|
||||||
|
Params: * questId - The questId being retried.
|
||||||
|
* numAllowance - The number of leve allowances the player still has.
|
||||||
|
Returns: Menu1 - Is 1 if yes is selected, 2 if no. Nil if Escape is hit (resend function in this case?)
|
||||||
|
Menu2 - Is 1 if yes is selected (leve abandoned), 2 if no. Nil if Menu1 isn't set to 2
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
50141 - You have <num> leve allowances remaining.
|
||||||
|
50142 - You have run out of leve allowances. You cannot accept any more levequests at this time.
|
||||||
|
50143 - You cannot accept any more levequests at this time.
|
||||||
|
|
||||||
|
Local Leves:
|
||||||
|
|
||||||
|
~~Limsa~~
|
||||||
|
|
||||||
|
CRP: Baderon's New Counter (120007)
|
||||||
|
The Mad Fisher (120017)
|
||||||
|
Building Bridges (120039)
|
||||||
|
High Stakes (120047)
|
||||||
|
Training and Trees (120061)
|
||||||
|
|
||||||
|
BSM: Baderon's New Sword (120005)
|
||||||
|
Got Ingots (120013)
|
||||||
|
Ship Shape (120014)
|
||||||
|
A Want of Weapons (120015)
|
||||||
|
Skull Valley Delivery (120035)
|
||||||
|
Fruit's of a Vintner's Whinings (120043)
|
||||||
|
Premiums Paid (120051)
|
||||||
|
Training and Trading (120059)
|
||||||
|
Waiting on Weapons (120067)
|
||||||
|
|
||||||
|
ARM: Baderon's New Barbuts (120009)
|
||||||
|
Seeing Sallets to the See (120019)
|
||||||
|
A Step Ahead (120020)
|
||||||
|
Mailed Sailors (120021)
|
||||||
|
Running Rings (120036)
|
||||||
|
Watching the Shore (120044)
|
||||||
|
Watching the Knoll (120052)
|
||||||
|
Rings Around the Rock (120063)
|
||||||
|
Dead Ringers (120068)
|
||||||
|
|
||||||
|
GSM: Baderon's New Bands (120010)
|
||||||
|
2 x 2 Eyes (120022)
|
||||||
|
Going Brandanas (120041)
|
||||||
|
Brand New Brands (120049)
|
||||||
|
Staves to Fashion (120064)
|
||||||
|
|
||||||
|
LTW: Baderon's New Shoes (120008)
|
||||||
|
The Mad Tanner (120018)
|
||||||
|
Under Foot (120040)
|
||||||
|
Shoeing the Shore (120048)
|
||||||
|
Training and Tanning (120062)
|
||||||
|
|
||||||
|
|
||||||
|
WVR: Baderon's New Clothes (120006)
|
||||||
|
The Mad Hatter (120016)
|
||||||
|
Wear and Tear (120038)
|
||||||
|
Outfitting the Shore (120046)
|
||||||
|
Training and Tailoring (120060)
|
||||||
|
|
||||||
|
ALC: Baderon's New Soles (120011)
|
||||||
|
A Sticky Situation (120023)
|
||||||
|
Feeding Trainees (120042)
|
||||||
|
Suffering Soldiers (120050)
|
||||||
|
Training and Eating (120065)
|
||||||
|
|
||||||
|
|
||||||
|
CUL: Baderon's New Breakfast (120012)
|
||||||
|
Tall, Cool One (120024)
|
||||||
|
The Captain's Cravings (120025)
|
||||||
|
A Feast Fit for an Admiral (120026)
|
||||||
|
Supper at the Skull (120037)
|
||||||
|
The Last Supper (120045)
|
||||||
|
A Meal to Remember (120053)
|
||||||
|
Just Desserts (120066)
|
||||||
|
A Job Well Done (120069)
|
||||||
|
|
||||||
|
~~Gridania~~
|
||||||
|
|
||||||
|
CRP: A Mother's Carpentry (120203)
|
||||||
|
Shields for the Masses (120211)
|
||||||
|
Canes for the Citizens (120212)
|
||||||
|
High Tension (120213)
|
||||||
|
Bowing to Pressure (120223)
|
||||||
|
Pole Positioning (120229)
|
||||||
|
Driving up the Wall (120237)
|
||||||
|
Restocking the Stockade (120245)
|
||||||
|
Plinks Aplenty (120247)
|
||||||
|
|
||||||
|
BSM: A Mother's Metallurgy (120201)
|
||||||
|
It's All in the File (120209)
|
||||||
|
Training in Bentbranch (120221)
|
||||||
|
Re-crating the Scene (120231)
|
||||||
|
Training in Emerald Moss (120239)
|
||||||
|
|
||||||
|
ARM: A Mother's Foundry (120205)
|
||||||
|
Tending to Tendons (120217)
|
||||||
|
A Little Rusty (120225)
|
||||||
|
Springripple Rising (120233)
|
||||||
|
In Sod We Rust (120241)
|
||||||
|
|
||||||
|
GSM: A Mother's Jewelry (120206)
|
||||||
|
The Band's Bands (120218)
|
||||||
|
Dusting the Knuckles (120226)
|
||||||
|
In Arm's Reach (120234)
|
||||||
|
Knuckling Down (120242)
|
||||||
|
|
||||||
|
LTW: A Mother's Booties (120204)
|
||||||
|
Strapped for Straps (120214)
|
||||||
|
Fire and Hide (120215)
|
||||||
|
Choke Hold (120216)
|
||||||
|
Work of Friction (120224)
|
||||||
|
Hungry Like the Wolves (120230)
|
||||||
|
Back in the Harness (120238)
|
||||||
|
Morbol Measures (120246)
|
||||||
|
Harnessing Help (120248)
|
||||||
|
|
||||||
|
WVR: A Mother's Frippery (120202)
|
||||||
|
Quelling Bloody Rumors (120210)
|
||||||
|
Clearing Bentbranch (120222)
|
||||||
|
Clearing Nine Ivies (120232)
|
||||||
|
Clearing Emerald Moss (120240)
|
||||||
|
|
||||||
|
ALC: A Mother's Delicacies (120207)
|
||||||
|
Mixing It Up (120219)
|
||||||
|
Keeping It Green (120227)
|
||||||
|
Arboreal Alchemy (120235)
|
||||||
|
Growing Strains (120243)
|
||||||
|
|
||||||
|
CUL: A Mother's Muselix (120208)
|
||||||
|
Better Baker's Bounty (120220)
|
||||||
|
On a Full Belly (120228)
|
||||||
|
A Well-Deserved Dinner (120236)
|
||||||
|
Seafood Smorgasbord (120244)
|
||||||
|
|
||||||
|
~~Uldah~~
|
||||||
|
|
||||||
|
CRP: Momodi's Sturdy Supports (120403)
|
||||||
|
The Walk of Death (120413)
|
||||||
|
Pointed Ambitions (120425)
|
||||||
|
Off With Their Heads (120435)
|
||||||
|
Act of Pure Weevil (120443)
|
||||||
|
|
||||||
|
BSM: Momodi's Dancing Daggers (120401)
|
||||||
|
Pointy Props (120409)
|
||||||
|
Hammering the Point (120423)
|
||||||
|
Molten Metal (120434)
|
||||||
|
Looking to Horizon (120442)
|
||||||
|
|
||||||
|
ARM: Momodi's Sturdy Suits (120405)
|
||||||
|
Battered and Bent (120415)
|
||||||
|
Arming the Unarmed (120427)
|
||||||
|
Provisioning Drybone (120437)
|
||||||
|
Buckling Under (120445)
|
||||||
|
|
||||||
|
GSM: Momodi's Radiant Rings (120406)
|
||||||
|
A Scarcity of Scepters (120416)
|
||||||
|
Pleasure and Pain (120417)
|
||||||
|
In the Sultana's Wake (120418)
|
||||||
|
A Shining Example (120428)
|
||||||
|
A Drybone Induction (120432)
|
||||||
|
A Horizon Promotion (120440)
|
||||||
|
A Bluefog Induction (120448)
|
||||||
|
A Broken Water Promotion (120451)
|
||||||
|
|
||||||
|
LTW: Momodi's Sashed Shoes (120404)
|
||||||
|
Showing Some Leg (120414)
|
||||||
|
World-weary Souls (120426)
|
||||||
|
Camp Drybone Cares (120436)
|
||||||
|
I Would Walk 500 Malms (120444)
|
||||||
|
|
||||||
|
WVR: Momodi's Budget Breeches (120402)
|
||||||
|
Just for Kecks (120410)
|
||||||
|
Pants Make the Man (120411)
|
||||||
|
Holes in Their Defense (120412)
|
||||||
|
Hanging by a Thread (120424)
|
||||||
|
Exposed to the Elements (120433)
|
||||||
|
Busier Than the Blades (120441)
|
||||||
|
A Spot in the Shade (120449)
|
||||||
|
Fire on the Water (120452)
|
||||||
|
|
||||||
|
ALC: Momodi's Condiment Conundrum (120407)
|
||||||
|
Exports of Import (120419)
|
||||||
|
Fertile Lies (120420)
|
||||||
|
A Blind Fool (120421)
|
||||||
|
Saint Allene's Fire (120429)
|
||||||
|
Treating Steel (120431)
|
||||||
|
Blue in the Eye (120439)
|
||||||
|
Preserving the Region (120447)
|
||||||
|
Provisioning Broken Water (120450)
|
||||||
|
|
||||||
|
CUL: Momodi's Breakfast Bread (120408)
|
||||||
|
Finger Food (120422)
|
||||||
|
Irrational Behavior (120430)
|
||||||
|
Tender Victuals (120438)
|
||||||
|
Some Like It Wet (120446)
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
local limsaLocalLeves = {
|
||||||
|
{120007, 120017, 120039, 120047, 120061}, --CRP
|
||||||
|
{120005, 120013, 120014, 120015, 120035, 120043, 120051, 120059, 120067}, --BSM
|
||||||
|
{120009, 120019, 120020, 120021, 120036, 120044, 120052, 120063, 120068}, --ARM
|
||||||
|
{120010, 120022, 120041, 120049, 120064}, --GSM
|
||||||
|
{120008, 120018, 120040, 120048, 120062}, --LTW
|
||||||
|
{120006, 120016, 120038, 120046, 120060}, --WVR
|
||||||
|
{120011, 120023, 120042, 120050, 120065}, --ALC
|
||||||
|
{120012, 120024, 120025, 120026, 120037, 120045, 120053, 120066, 120069} --CUL
|
||||||
|
};
|
||||||
|
|
||||||
|
local gridaniaLocalLeves = {
|
||||||
|
{120203, 120211, 120212, 120213, 120223, 120229, 120237, 120245, 120247}, --CRP
|
||||||
|
{120201, 120209, 120221, 120231, 120239}, --BSM
|
||||||
|
{120205, 120217, 120225, 120233, 120241}, --ARM
|
||||||
|
{120206, 120218, 120226, 120234, 120242}, --GSM
|
||||||
|
{120204, 120214, 120215, 120216, 120224, 120230, 120238, 120246, 120248}, --LTW
|
||||||
|
{120202, 120210, 120222, 120232, 120240}, --WVR
|
||||||
|
{120207, 120219, 120227, 120235, 120243}, --ALC
|
||||||
|
{120208, 120220, 120228, 120236, 120244} --CUL
|
||||||
|
};
|
||||||
|
|
||||||
|
local uldahLocalLeves = {
|
||||||
|
{120403, 120413, 120425, 120435, 120443}, --CRP
|
||||||
|
{120401, 120409, 120423, 120434, 120442}, --BSM
|
||||||
|
{120405, 120415, 120427, 120437, 120445}, --ARM
|
||||||
|
{120406, 120416, 120417, 120418, 120428, 120432, 120440, 120448, 120451}, --GSM
|
||||||
|
{120404, 120414, 120426, 120436, 120444}, --LTW
|
||||||
|
{120402, 120410, 120411, 120412, 120424, 120433, 120441, 120449, 120452}, --WVR
|
||||||
|
{120407, 120419, 120420, 120421, 120429, 120431, 120439, 120447, 120450}, --ALC
|
||||||
|
{120408, 120422, 120430, 120438, 120446} --CUL
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
local leveAllowances = 16;
|
||||||
|
local quest = 120438;
|
||||||
|
|
||||||
|
callClientFunction(player, "confirmJournal", quest, 1);
|
||||||
|
callClientFunction(player, "confirmJournal", quest, 2);
|
||||||
|
callClientFunction(player, "confirmJournal", quest, 3);
|
||||||
|
callClientFunction(player, "confirmJournal", quest, 4);
|
||||||
|
--[[callClientFunction(player, "talkOfferWelcome", player, leveAllowances);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
-- Class Menu
|
||||||
|
local classChoice = callClientFunction(player, "askOfferPack");
|
||||||
|
|
||||||
|
if (classChoice != nil) then
|
||||||
|
while (true) do
|
||||||
|
-- Level Difficulty Menu
|
||||||
|
local levelChoice = callClientFunction(player, "askOfferRank");
|
||||||
|
|
||||||
|
if levelChoice != nil then
|
||||||
|
if levelChoice == 1 then
|
||||||
|
local levequest = callClientFunction(player, "askOfferQuest", player, 1, 120438, 120025);
|
||||||
|
if (levequest != nil and levequest > 0) then
|
||||||
|
player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve));
|
||||||
|
player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif levelChoice == 2 then
|
||||||
|
pickedLeve = callClientFunction(player, "askOfferQuest", player, 1, 120026, 120027);
|
||||||
|
if (pickedLeve != nil) or (pickedLeve != -1) then
|
||||||
|
player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve));
|
||||||
|
player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif levelChoice == 3 then
|
||||||
|
pickedLeve = callClientFunction(player, "askOfferQuest", player, 1, 120028, 120029);
|
||||||
|
if (pickedLeve != nil) or (pickedLeve != -1) then
|
||||||
|
player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve));
|
||||||
|
player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end]]--
|
||||||
|
|
||||||
|
callClientFunction(player, "finishTalkTurn");
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
function getAvailableLeves(class, rank)
|
||||||
|
|
||||||
|
end
|
||||||
File renamed without changes.
@@ -0,0 +1,145 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceRetainerManager Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkStep1(true) - Intro tutorial if no retainer
|
||||||
|
newEventTalkStep1(sayIntro) - Seems to be a post-Tanaka version of the intro????
|
||||||
|
eventTalkStep2() - Choose retainer yourself (go to race select) or let npc do it
|
||||||
|
eventTaklSelectCutSeane(cutsceneName, actorClassId1, actorClassId2, actorClassId3, actorClassId4, actorClassId5) - Starts the advance cutscene to choose a retainer. 5 retainer actorClassId's are given.
|
||||||
|
eventTalkStep4(actorClassId) - Opens up the retainer naming dialog
|
||||||
|
eventTalkStepFinalAnswer(actorClassId) - Confirm Dialog
|
||||||
|
eventTalkStepError(errorCode) - Error dialog, 1: No Extra Retainers, 2: Server Busy.
|
||||||
|
eventTalkStepFinish()
|
||||||
|
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
local npcActorClass = npc:GetActorClassId()
|
||||||
|
local retainerIndex = 3001100;
|
||||||
|
local cutscene = "rtn0l010" -- Defaulting to Limsa for now for testing
|
||||||
|
|
||||||
|
if npcActorClass == 1000166 then
|
||||||
|
cutscene = "rtn0l010";
|
||||||
|
retainerIndex = 3001101;
|
||||||
|
elseif npcActorClass == 1000865 then
|
||||||
|
cutscene = "rtn0u010";
|
||||||
|
retainerIndex = 3002101;
|
||||||
|
elseif npcActorClass == 1001184 then
|
||||||
|
cutscene = "rtn0g010";
|
||||||
|
retainerIndex = 3003101;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
introChoice = callClientFunction(player, "newEventTalkStep1", false);
|
||||||
|
|
||||||
|
if (introChoice == 1) then
|
||||||
|
|
||||||
|
-- Choose Retainer or Random
|
||||||
|
raceChoice = callClientFunction(player, "eventTalkStep2");
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
|
||||||
|
if (retainerChoice == 0) then
|
||||||
|
raceChoice = callClientFunction(player, "eventTalkStep22");
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if (raceChoice == 0) then
|
||||||
|
--Choose random actorId from a valid set for the city
|
||||||
|
|
||||||
|
math.randomseed(os.time());
|
||||||
|
local randomRetainer = math.random(retainerIndex, (retainerIndex+74));
|
||||||
|
|
||||||
|
retainerName = callClientFunction(player, "eventTalkStep4", randomRetainer);
|
||||||
|
|
||||||
|
if (retainerName ~= "") then
|
||||||
|
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", randomRetainer);
|
||||||
|
|
||||||
|
if (confirmChoice == 1) then
|
||||||
|
callClientFunction(player, "eventTalkStepFinish");
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
elseif (confirmChoice == 3) then
|
||||||
|
raceChoice = 0;
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
raceChoice = -1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
elseif (raceChoice > 0) and (raceChoice < 16) then
|
||||||
|
--Choose 5 random but correct actor ids for the city and race/tribe
|
||||||
|
|
||||||
|
local retainerRace = ((retainerIndex) + (5*(raceChoice-1)));
|
||||||
|
local retainerRaceChoices = {retainerRace, retainerRace+1, retainerRace+2, retainerRace+3, retainerRace+4};
|
||||||
|
|
||||||
|
-- Randomize the appearance order of the available five
|
||||||
|
shuffle(retainerRaceChoices);
|
||||||
|
|
||||||
|
retainerChoice = callClientFunction(player, "eventTaklSelectCutSeane", cutscene, retainerRaceChoices[1], retainerRaceChoices[2], retainerRaceChoices[3], retainerRaceChoices[4], retainerRaceChoices[5]);
|
||||||
|
|
||||||
|
if (retainerChoice == -1) then
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
elseif (retainerChoice > 0) then
|
||||||
|
--Retainer chosen, choose name
|
||||||
|
retainerName = callClientFunction(player, "eventTalkStep4", retainerRaceChoices[retainerChoice]);
|
||||||
|
|
||||||
|
if (retainerName ~= "") then
|
||||||
|
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", retainerRaceChoices[retainerChoice]);
|
||||||
|
|
||||||
|
if (confirmChoice == 1) then
|
||||||
|
callClientFunction(player, "eventTalkStepFinish");
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
elseif (confirmChoice == 3) then
|
||||||
|
retainerChoice = 0;
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkStepBreak");
|
||||||
|
raceChoice = -1;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function shuffle(tbl)
|
||||||
|
for i = #tbl, 2, -1 do
|
||||||
|
local j = math.random(i)
|
||||||
|
tbl[i], tbl[j] = tbl[j], tbl[i]
|
||||||
|
end
|
||||||
|
return tbl
|
||||||
|
end
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceSpecialEventCryer Script
|
||||||
|
|
||||||
|
Actor Class script to handle the 6 NPCs (technically 3, the actors were duped) involved in the Foundation Day 2011 & 2012 events.
|
||||||
|
In 2011 they appear to be used for recruitment information for their respective Grand Company.
|
||||||
|
In 2012, they were used for exchanging Over-aspected Crystals/Clusters for GC seals as part of the ongoing Atomos event.
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
For 2011.
|
||||||
|
eventTalkStep0(joined) - NPC dialog about joining their cause to fight back Imperials. joined = 0 or 1. Function has hardcoded actor IDs, won't work with 2012 versions
|
||||||
|
eventTalkNotGCmenber(npcGC) - NPC dialog when you're not part of their grand company.
|
||||||
|
|
||||||
|
For 2012.
|
||||||
|
eventTalkCrystalExchange(player, npcGC, hasCrystal) - NPC dialog explaining they want over-aspected crystals. Brings up crystal exchange prompt if hasCrystal = 1.
|
||||||
|
eventTalkCsOverflow(player, npcGC) - Error message that you can't hold the seals being offered.
|
||||||
|
eventTalkCrystalExchange2(player, npcGC) - NPC dialog for accepting exchange of crystals for seals
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local gcRep = {
|
||||||
|
[1001619] = 1, -- Maelstrom Representative 2011
|
||||||
|
[1002105] = 1, -- Maelstrom Representative 2012
|
||||||
|
[1001623] = 2, -- Adder Representative 2011
|
||||||
|
[1002109] = 2, -- Adder Representative 2012
|
||||||
|
[1001627] = 3, -- Flame Representative 2011
|
||||||
|
[1002113] = 3, -- Flame Representative 2012
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
local playerGC = player.gcCurrent;
|
||||||
|
local npcId = npc:GetActorClassId();
|
||||||
|
local npcGC = gcRep[npcId];
|
||||||
|
local npcGCSeal = 1000200 + npcGC;
|
||||||
|
local hasCrystal = 1;
|
||||||
|
local crystal = 3020537;
|
||||||
|
local cluster = 3020413;
|
||||||
|
local eventMode = 2012;
|
||||||
|
|
||||||
|
if eventMode == 2011 then
|
||||||
|
if playerGC == 0 then
|
||||||
|
callClientFunction(player, "eventTalkStep0", 0);
|
||||||
|
elseif playerGC == npcGC then
|
||||||
|
callClientFunction(player, "eventTalkStep0", 1);
|
||||||
|
else
|
||||||
|
callClientFunction(player, "eventTalkNotGCmenber", npcGC);
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif eventMode == 2012 then
|
||||||
|
choice = callClientFunction(player, "eventTalkCrystalExchange", player, npcGC, hasCrystal);
|
||||||
|
|
||||||
|
if choice == 1 then
|
||||||
|
--callClientFunction(player, "eventTalkCsOverflow", player, npcGC);
|
||||||
|
player:SendMessage(0x20, "", "You pretend to hand over four over-aspected crystals.");
|
||||||
|
callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);
|
||||||
|
|
||||||
|
local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 1000, 1);
|
||||||
|
if invCheck == INV_ERROR_SUCCESS then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, crystal, 1, npcGCSeal, 1, 4, 1000);
|
||||||
|
end
|
||||||
|
elseif choice == 2 then
|
||||||
|
player:SendMessage(0x20, "", "You pretend to hand over an over-aspected cluster.");
|
||||||
|
--callClientFunction(player, "eventTalkCsOverflow", player, npcGC);
|
||||||
|
callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);
|
||||||
|
|
||||||
|
local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 3000, 1);
|
||||||
|
if invCheck == INV_ERROR_SUCCESS then
|
||||||
|
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, cluster, 1, npcGCSeal, 1, 1, 3000);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
require("global");
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Populace Standard Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventSwitch(questId1, questId2, questId3, questId4, currentPage, maxPages, titleId) - Shows a dialog box with which quest to trigger
|
||||||
|
when more than one quest is active for this npc.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
This scripts fires for all normal standard ENpcs in the world. Because of how the FFXIV dialog system works, everything is technically
|
||||||
|
a quest; including the DefaultTalk responses. This script checks both static default quests and any relevant ones for that actor class
|
||||||
|
id. If only one exists; it is automatically triggered otherwise a dialog box will appear for the player to choose what quest to do.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
local chosenQuest = nil;
|
||||||
|
|
||||||
|
if (eventType == 1) then
|
||||||
|
local defaultTalk = player:GetDefaultTalkQuest(npc);
|
||||||
|
local tutorialTalk = player:GetTutorialQuest(npc);
|
||||||
|
local activeQuests = player:GetQuestsForNpc(npc);
|
||||||
|
local possibleQuests = {};
|
||||||
|
|
||||||
|
-- Create the switch table for this npc
|
||||||
|
if (defaultTalk ~= nil and eventType == ETYPE_TALK) then
|
||||||
|
table.insert(possibleQuests, defaultTalk);
|
||||||
|
end
|
||||||
|
if (tutorialTalk ~= nil and eventType == ETYPE_TALK) then
|
||||||
|
table.insert(possibleQuests, tutorialTalk);
|
||||||
|
end
|
||||||
|
if (activeQuests ~= nil) then
|
||||||
|
for i=1,#activeQuests do
|
||||||
|
table.insert(possibleQuests, activeQuests[i]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Either let the player choose the quest or start it if it's the only one.
|
||||||
|
if (#possibleQuests > 1) then
|
||||||
|
local currentPage = 0;
|
||||||
|
local numPages = math.floor((#possibleQuests-1)/4) + 1;
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
local page, index = callClientFunction(player, "switchEvent", possibleQuests[currentPage * 4 + 1], possibleQuests[currentPage * 4 + 2], possibleQuests[currentPage * 4 + 3], possibleQuests[currentPage * 4 + 4], currentPage + 1, numPages, 0x3F1);
|
||||||
|
|
||||||
|
if (page == 0) then
|
||||||
|
chosenQuest = possibleQuests[(currentPage * 4) + index];
|
||||||
|
break;
|
||||||
|
elseif (page > 0) then
|
||||||
|
currentPage = page - 1;
|
||||||
|
else
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif (#possibleQuests == 1) then
|
||||||
|
chosenQuest = possibleQuests[1];
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local activeQuests = player:GetQuestsForNpc(npc);
|
||||||
|
if (#activeQuests != 0) then
|
||||||
|
chosenQuest = activeQuests[1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run the quest event or tell the devs it's missing.
|
||||||
|
if (chosenQuest ~= nil) then
|
||||||
|
doQuestEvent(player, npc, chosenQuest, eventType, eventName);
|
||||||
|
else
|
||||||
|
local msg = string.format("ERROR: This PopulaceStandard actor has no defaultTalk or quest set. \nActor Class Id: %s\nEvent Name: %s", tostring(npc:GetActorClassId()), eventName);
|
||||||
|
printf(msg);
|
||||||
|
player:SendMessage(0x20, "", msg);
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function doQuestEvent(player, npc, quest, eventType, eventName)
|
||||||
|
if (eventType == 0) then
|
||||||
|
quest:OnCommand(player, npc, eventName);
|
||||||
|
elseif (eventType == 1) then
|
||||||
|
quest:OnTalk(player, npc);
|
||||||
|
elseif (eventType == 2) then
|
||||||
|
quest:OnPush(player, npc, eventName);
|
||||||
|
elseif (eventType == 3) then
|
||||||
|
quest:OnEmote(player, npc, eventName);
|
||||||
|
elseif (eventType == 5) then
|
||||||
|
quest:OnNotice(player, npc, eventName);
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
InstanceRaidGuide Script
|
||||||
|
|
||||||
|
Functions;
|
||||||
|
askEnterInstanceRaid(arg1) -- Opens a widget asking to enter the given Raid id.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
|
||||||
|
if ((npc == 1002090) or (npc == 1002091)) then
|
||||||
|
-- This won't work due to how init() works, but old scripts had it, keeping it here for now
|
||||||
|
return false, false, 0, 0, 491, 2;
|
||||||
|
else
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, eventType, eventName)
|
||||||
|
|
||||||
|
npcId = npc:GetActorClassId()
|
||||||
|
|
||||||
|
if (npcId == 1002090) then -- Serpent Private Hodder (Stewart) : Gcl107
|
||||||
|
|
||||||
|
callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkWithStewart_001"); -- "defaultTalkWithStewart_002" -- Post-Raid dialog?
|
||||||
|
|
||||||
|
--[[
|
||||||
|
choice = callClientFunction(player, "delegateEvent", player, GetStaticActor("Gcl107"), "processEventStewart", 15);
|
||||||
|
|
||||||
|
if (choice == 1) then
|
||||||
|
callClientFunction(player, "askEnterInstanceRaid", 15); -- Rivenroad
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
elseif (npcId == 1002091) then -- Serpent Private Dauremant (Trisselle) : Sum6w0
|
||||||
|
|
||||||
|
callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkWithTrisselle_001"); -- "defaultTalkWithTrisselle_002" -- No idea for context.
|
||||||
|
|
||||||
|
--[[
|
||||||
|
choice = callClientFunction(player, "delegateEvent", player, GetStaticActor("Sum6w0"), "processEventTrisselle", 16)
|
||||||
|
|
||||||
|
if (choice == 1) then
|
||||||
|
callClientFunction(player, "askEnterInstanceRaid", 16); -- Rivenroad (Hard)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
elseif (npcId == 1060022) then -- Louisoix
|
||||||
|
callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkLouisoix_001");
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceGuildShop Script
|
||||||
|
|
||||||
|
In 1.20, the devs removed Guild Marks as acquirable. In 1.21, this class was set up to allow exchanging them for
|
||||||
|
a variety of materia/crystals/gil, as well as refunding traits purchased with marks. Traits used to be purchased
|
||||||
|
to slot in, where-as with late-XIV they are just automatically unlocked once the appropriate level is met.
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
cashbackTalkCommand(arg1 through arg10) -- Dialog for refunding purchased skills prior to Job update. Args are xtx_command values for command names.
|
||||||
|
cashbackTalk(nil, refundAmount, arg3 through arg10) -- Dialog for refunding treaties to guild marks. Arg3 through 10 use xtx_itemName values.
|
||||||
|
selectMode(nil, npcId, isShowExchange, guildCurrency, unk) -- Menus for exchanging leftover marks, undoing class points, and learning about guild. Unk seems related to point resetting
|
||||||
|
|
||||||
|
maskShopListIndex(shopPack?, isSomething) -- Presumably hides an item in the shop list. Needs to be called after openShopBuy or errors client.
|
||||||
|
guildExplain(npcId, player) -- Guild Mark tutorial dialog. selectMode calls this on its own
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("shop")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
guildShopInfo = { -- [actor id] = { saySheetId, guildmarkCurrency }
|
||||||
|
[1000157] = {9, 1000103}, -- Marauder, S'raemha
|
||||||
|
[1000158] = {24, 1000120}, -- Culinarian, Noline
|
||||||
|
[1000162] = {18, 1000114}, -- Blacksmith, Qhas Chalahko
|
||||||
|
[1000164] = {16, 1000123}, -- Fishermen, Faucillien
|
||||||
|
[1000459] = {21, 1000117}, -- Leatherworker, Gallia
|
||||||
|
[1000460] = {13, 1000111}, -- Conjurer, Hetzkin
|
||||||
|
[1000461] = {15, 1000122}, -- Botanist, Kipopo
|
||||||
|
[1000462] = {11, 1000107}, -- Lancer, Clarembald
|
||||||
|
[1000464] = {10, 1000106}, -- Archer, Cassandra
|
||||||
|
[1000466] = {17, 1000113}, -- Carpenter, Frances
|
||||||
|
[1000631] = {8, 1000102}, -- Gladiator, Coynach
|
||||||
|
[1000632] = {7, 1000101}, -- Pugilist, Moruith
|
||||||
|
[1000633] = {12, 1000110}, -- Thaumaturge, Nyunoeya
|
||||||
|
[1000634] = {23, 1000119}, -- Alchemist, Kylene
|
||||||
|
[1000635] = {20, 1000116}, -- Goldsmith, Hnaufrid
|
||||||
|
[1000636] = {22, 1000118}, -- Weaver, Lafla Morfla
|
||||||
|
[1000637] = {14, 1000121}, -- Miner, Shilgen
|
||||||
|
[1001461] = {19, 1000115}, -- Armorer, Notrelchamps
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onEventStarted(player, npc)
|
||||||
|
|
||||||
|
local npcId = npc:GetActorClassId();
|
||||||
|
local saySheetId = guildShopInfo[npcId][1];
|
||||||
|
local shopCurrency = guildShopInfo[npcId][2];
|
||||||
|
local gilCurrency = 1000001;
|
||||||
|
local keepersHymn = 3020410;
|
||||||
|
local shopPack = 0;
|
||||||
|
|
||||||
|
callClientFunction(player, "welcomeTalk", nil, saySheetId, player);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
local choice = callClientFunction(player, "selectMode", nil, npcId, true, shopCurrency, 100);
|
||||||
|
|
||||||
|
if (choice == 3) then -- Undo Point Allotment
|
||||||
|
-- TODO: Add point reset handling
|
||||||
|
elseif (choice == 4) then -- Leave menu selected
|
||||||
|
player:EndEvent();
|
||||||
|
break;
|
||||||
|
elseif (choice == nil) then -- Escape key hit to leave menu
|
||||||
|
player:EndEvent();
|
||||||
|
break
|
||||||
|
elseif (choice >= 102 and choice <= 120) then -- Exchange marks for Materia
|
||||||
|
shopPack = choice + 18; -- Index offset
|
||||||
|
if (choice == 119) then
|
||||||
|
shopPack = shopPack + 1;
|
||||||
|
elseif (choice == 120) then -- Exchange marks for Crystals
|
||||||
|
shopPack = 144;
|
||||||
|
end;
|
||||||
|
processGuildShop(player, shopPack, shopCurrency);
|
||||||
|
elseif (choice == 121) then -- Exchange marks for Gil. 1 mark = 4 gil
|
||||||
|
local markAmount = player:GetItemPackage(INVENTORY_CURRENCY):GetItemQuantity(shopCurrency);
|
||||||
|
purchaseItem(player, INVENTORY_CURRENCY, gilCurrency, markAmount*4, 1, markAmount, shopCurrency);
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function processGuildShop(player, choice, currency)
|
||||||
|
|
||||||
|
callClientFunction(player, "openShopBuy", player, choice, currency);
|
||||||
|
--callClientFunction(player, "maskShopListIndex", 137, true);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
buyResult, quantity = callClientFunction(player, "selectShopBuy", player);
|
||||||
|
|
||||||
|
if (buyResult == 0) then
|
||||||
|
callClientFunction(player, "closeShopBuy", player);
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
player:SendMessage(0x20, "", string.format("Player purchased %s item(s) at index %s in shopPack %s.", quantity, buyResult, choice));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,655 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
PopulaceShopSalesman Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
welcomeTalk(sheetId, player) - Start Message
|
||||||
|
selectMode(askMode) - Shows buy/sell modes. If askmode > 0 show guild tutorial. If askmode == -7/-8/-9 show nothing. Else show affinity/condition tutorials.
|
||||||
|
selectModeOfClassVendor() - Opens categories for class weapons and gear
|
||||||
|
selectModeOfMultiWeaponVendor(consumptionmenuId) - Opens categories for weapons/tools (war/magic/land/hand). Arg consumptionmenuId appends location of item repair person. -1: Ul'dah, -2: Gridania, -3: Limsa
|
||||||
|
selectModeOfMultiArmorVendor(consumptionmenuId) - Opens categories for armor in different slots. Arg consumptionmenuId appends location of item repair person. -1: Ul'dah, -2: Gridania, -3: Limsa
|
||||||
|
|
||||||
|
openShopBuy(player, shopPack, CurrencyItemId) - ShopPack: Items to appear in window. CurrencyItemId: What is being used to buy these items.
|
||||||
|
selectShopBuy(player) - Call after openShopBuy() to open widget
|
||||||
|
closeShopBuy(player) - Closes the buy window
|
||||||
|
|
||||||
|
openShopSell(player) - Call this to open sell window
|
||||||
|
selectShopSell(player) - Call after openShopSell()
|
||||||
|
closeShopSell(player) - Closes the sell window
|
||||||
|
|
||||||
|
confirmSellingItem(itemId, quality, quantity, gil) - Simple Sell confirmation window
|
||||||
|
|
||||||
|
selectFacility(?, sheetId, 3) - Opens the facility chooser.
|
||||||
|
confirmUseFacility(player, cost) - Facility cost confirm
|
||||||
|
|
||||||
|
informSellPrice(1, chosenItem, price) - Shows sell confirm window. ChosenItem must be correct.
|
||||||
|
|
||||||
|
startTutorial(nil, menuId) - Opens up a tutorial menu for each guild type based on menuId
|
||||||
|
|
||||||
|
finishTalkTurn() - Done at the end.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("shop")
|
||||||
|
|
||||||
|
shopInfo = {
|
||||||
|
--[[
|
||||||
|
[actorclass id] =
|
||||||
|
{
|
||||||
|
welcomeText - Dialog for the NPC to speak when interacting
|
||||||
|
menuId, - Displays certain menu/dialog. 29-36 = DoH Facilities menus. -1 Ul'dah, -2 Gridania, -3 Limsa. -7/-8/-9/nil show nothing
|
||||||
|
shopMode, - Type of shop. 0 = Single shop pack, 1 = Class vendor, 2 = Weapon vendor, 3 = Armor vendor, 4 = Hamlet vendor
|
||||||
|
shopPack{s}, - The item table index to send the client containing the list of items to display, shopmode 2/3 have a static list
|
||||||
|
}
|
||||||
|
--]]
|
||||||
|
[1000159] = {34, 36, 0, 1016},
|
||||||
|
[1000163] = {49, 31, 0, 1017},
|
||||||
|
[1000165] = {74, -8, 0, 1019},
|
||||||
|
[1001458] = {44, 30, 0, 1018},
|
||||||
|
[1500142] = {266, -1, 0, 5001},
|
||||||
|
[1500143] = {267, -1, 0, 5002},
|
||||||
|
[1500144] = {268, -1, 0, 5003},
|
||||||
|
[1500145] = {269, -1, 0, 5004},
|
||||||
|
[1500146] = {269, -1, 0, 5005},
|
||||||
|
[1500147] = {270, -1, 0, 5006},
|
||||||
|
[1500150] = {266, -8, 0, 5001},
|
||||||
|
[1500151] = {267, -8, 0, 5002},
|
||||||
|
[1500152] = {268, -8, 0, 5003},
|
||||||
|
[1500153] = {269, -8, 0, 5004},
|
||||||
|
[1500154] = {269, -8, 0, 5005},
|
||||||
|
[1500155] = {270, -8, 0, 5006},
|
||||||
|
[1500158] = {266, -8, 0, 5001},
|
||||||
|
[1500159] = {267, -8, 0, 5002},
|
||||||
|
[1500160] = {268, -8, 0, 5003},
|
||||||
|
[1500161] = {269, -8, 0, 5004},
|
||||||
|
[1500162] = {269, -8, 0, 5005},
|
||||||
|
[1500163] = {270, -8, 0, 5006},
|
||||||
|
[1500401] = {317, -8, 0, 1013},
|
||||||
|
[1500405] = {320, -8, 0, 1013},
|
||||||
|
[1500407] = {321, -8, 0, 1012},
|
||||||
|
[1500411] = {322, -8, 0, 2017},
|
||||||
|
[1500414] = {324, -8, 0, 1012},
|
||||||
|
[1500419] = {327, -8, 0, 1012},
|
||||||
|
[1500422] = {332, -8, 0, 1013},
|
||||||
|
[1500423] = {331, -8, 0, 2017},
|
||||||
|
[1500429] = {328, -8, 0, 2017},
|
||||||
|
[1500430] = {281, -8, 4, 5122},
|
||||||
|
[1500431] = {281, -8, 4, 5118},
|
||||||
|
[1500432] = {281, -8, 4, 5120},
|
||||||
|
[1600001] = {6, -8, 0, 1006},
|
||||||
|
[1600002] = {7, -8, 0, 1007},
|
||||||
|
[1600003] = {8, -8, 0, 1008},
|
||||||
|
[1600004] = {9, -8, 0, 1009},
|
||||||
|
[1600005] = {10, -8, 0, 1010},
|
||||||
|
[1600006] = {11, -8, 0, 1011},
|
||||||
|
[1600007] = {12, -8, 0, 1012},
|
||||||
|
[1600008] = {13, -8, 0, 1013},
|
||||||
|
[1600009] = {14, -8, 0, 1014},
|
||||||
|
[1600010] = {15, -8, 0, 1015},
|
||||||
|
[1600011] = {1, -8, 0, 1001},
|
||||||
|
[1600012] = {2, -8, 0, 1002},
|
||||||
|
[1600013] = {3, -8, 0, 1003},
|
||||||
|
[1600014] = {4, -8, 0, 1004},
|
||||||
|
[1600016] = {5, -8, 0, 1005},
|
||||||
|
[1600017] = {39, 29, 0, 2020},
|
||||||
|
[1600018] = {59, 33, 0, 2021},
|
||||||
|
[1600019] = {75, -8, 0, 2022},
|
||||||
|
[1600020] = {77, -8, 0, 2010},
|
||||||
|
[1600021] = {78, -8, 0, 2011},
|
||||||
|
[1600022] = {79, -8, 0, 2012},
|
||||||
|
[1600023] = {80, -8, 0, 2013},
|
||||||
|
[1600024] = {81, -8, 0, 2014},
|
||||||
|
[1600025] = {82, -8, 0, 2015},
|
||||||
|
[1600026] = {83, -8, 0, 2016},
|
||||||
|
[1600027] = {84, -8, 0, 2017},
|
||||||
|
[1600028] = {85, -8, 0, 2018},
|
||||||
|
[1600029] = {86, -8, 0, 2019},
|
||||||
|
[1600030] = {87, -8, 0, 2001},
|
||||||
|
[1600031] = {88, -8, 0, 2003},
|
||||||
|
[1600032] = {89, -8, 0, 2002},
|
||||||
|
[1600033] = {90, -8, 0, 2004},
|
||||||
|
[1600034] = {91, -8, 0, 2005},
|
||||||
|
[1600035] = {92, -8, 0, 2006},
|
||||||
|
[1600036] = {93, -8, 0, 2007},
|
||||||
|
[1600037] = {94, -8, 0, 2008},
|
||||||
|
[1600039] = {69, 35, 0, 3020},
|
||||||
|
[1600040] = {54, 32, 0, 3019},
|
||||||
|
[1600041] = {64, 34, 0, 3021},
|
||||||
|
[1600042] = {76, -8, 0, 3022},
|
||||||
|
[1600043] = {96, -8, 0, 3009},
|
||||||
|
[1600044] = {97, -8, 0, 3010},
|
||||||
|
[1600045] = {98, -8, 0, 3011},
|
||||||
|
[1600046] = {99, -8, 0, 3012},
|
||||||
|
[1600047] = {100, -8, 0, 3013},
|
||||||
|
[1600048] = {101, -8, 0, 3014},
|
||||||
|
[1600049] = {102, -8, 0, 3016},
|
||||||
|
[1600050] = {103, -8, 0, 3015},
|
||||||
|
[1600051] = {104, -8, 0, 3017},
|
||||||
|
[1600052] = {105, -8, 0, 3004},
|
||||||
|
[1600053] = {106, -8, 0, 3007},
|
||||||
|
[1600054] = {107, -8, 0, 3018},
|
||||||
|
[1600055] = {108, -8, 0, 3006},
|
||||||
|
[1600056] = {109, -8, 0, 3005},
|
||||||
|
[1600057] = {110, -8, 0, 3002},
|
||||||
|
[1600058] = {111, -8, 0, 3003},
|
||||||
|
[1600059] = {112, -8, 0, 3001},
|
||||||
|
[1600061] = {95, -8, 0, 2009},
|
||||||
|
[1600062] = {113, -8, 0, 3008},
|
||||||
|
[1600063] = {114, -8, 0, 4001},
|
||||||
|
[1600064] = {235, -8, 0, 2023},
|
||||||
|
[1600065] = {236, -8, 0, 1020},
|
||||||
|
[1600066] = {237, -8, 0, 3023},
|
||||||
|
[1600067] = {238, -8, 0, 5007},
|
||||||
|
[1600068] = {239, -8, 0, 5007},
|
||||||
|
[1600069] = {240, -1, 0, 5007},
|
||||||
|
[1600070] = {241, -8, 0, 5008},
|
||||||
|
[1600071] = {242, -8, 0, 5008},
|
||||||
|
[1600072] = {243, -8, 0, 5008},
|
||||||
|
[1600073] = {244, -8, 1, 5009},
|
||||||
|
[1600074] = {245, -8, 1, 5015},
|
||||||
|
[1600075] = {246, -8, 1, 5021},
|
||||||
|
[1600076] = {247, -8, 1, 5027},
|
||||||
|
[1600077] = {248, -8, 1, 5033},
|
||||||
|
[1600078] = {249, -8, 1, 5039},
|
||||||
|
[1600079] = {250, -8, 1, 5045},
|
||||||
|
[1600080] = {251, -8, 1, 5051},
|
||||||
|
[1600081] = {252, -8, 1, 5057},
|
||||||
|
[1600082] = {253, -8, 1, 5063},
|
||||||
|
[1600083] = {254, -8, 1, 5069},
|
||||||
|
[1600084] = {255, -8, 1, 5075},
|
||||||
|
[1600085] = {256, -8, 1, 5081},
|
||||||
|
[1600086] = {257, -8, 1, 5087},
|
||||||
|
[1600087] = {258, -8, 1, 5093},
|
||||||
|
[1600088] = {259, -8, 1, 5099},
|
||||||
|
[1600089] = {260, -8, 1, 5105},
|
||||||
|
[1600090] = {261, -8, 1, 5111},
|
||||||
|
[1600092] = {263, -8, 0, 2024},
|
||||||
|
[1600093] = {264, -8, 0, 1021},
|
||||||
|
[1600094] = {265, -8, 0, 3024},
|
||||||
|
[1600095] = {281, -8, 0, 1005},
|
||||||
|
[1600096] = {281, -8, 0, 2009},
|
||||||
|
[1600097] = {281, -8, 0, 4001},
|
||||||
|
[1600098] = {281, -8, 0, 4002},
|
||||||
|
[1600099] = {281, -8, 0, 2009},
|
||||||
|
[1600100] = {281, -2, 2, 0},
|
||||||
|
[1600101] = {281, -8, 0, 2009},
|
||||||
|
[1600103] = {281, -8, 0, 3008},
|
||||||
|
[1600104] = {281, -8, 0, 3008},
|
||||||
|
[1600107] = {281, -8, 3, 0},
|
||||||
|
[1600108] = {281, -8, 0, 3008},
|
||||||
|
[1600109] = {281, -3, 2, 0},
|
||||||
|
[1600110] = {281, -8, 0, 4001},
|
||||||
|
[1600111] = {281, -8, 0, 2009},
|
||||||
|
[1600112] = {281, -8, 0, 4002},
|
||||||
|
[1600113] = {281, -8, 0, 4001},
|
||||||
|
[1600117] = {281, -8, 0, 2009},
|
||||||
|
[1600119] = {281, -2, 3, 0},
|
||||||
|
[1600120] = {281, -8, 0, 3008},
|
||||||
|
[1600121] = {281, -8, 0, 2009},
|
||||||
|
[1600122] = {281, -8, 0, 3008},
|
||||||
|
[1600125] = {281, -8, 0, 1005},
|
||||||
|
[1600126] = {281, -8, 0, 3008},
|
||||||
|
[1600129] = {281, -1, 3, 0},
|
||||||
|
[1600130] = {281, -8, 0, 4001},
|
||||||
|
[1600133] = {281, -1, 2, 0},
|
||||||
|
[1600137] = {281, -8, 0, 1005},
|
||||||
|
[1600142] = {281, -8, 0, 1005},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
shopRange = { --shopRangeStart, shopRangeEnd
|
||||||
|
[101] = {101001, 101010};
|
||||||
|
[102] = {102001, 102010};
|
||||||
|
[103] = {103001, 103010};
|
||||||
|
[104] = {104001, 104010};
|
||||||
|
[105] = {105001, 105010};
|
||||||
|
[106] = {106001, 106010};
|
||||||
|
[107] = {107001, 107010};
|
||||||
|
[108] = {108001, 108017};
|
||||||
|
[109] = {109001, 109015};
|
||||||
|
[110] = {110001, 110018};
|
||||||
|
[111] = {111001, 111018};
|
||||||
|
[112] = {112001, 112018};
|
||||||
|
[113] = {113001, 113019};
|
||||||
|
[114] = {114001, 114015};
|
||||||
|
[115] = {115001, 115015};
|
||||||
|
[116] = {116001, 116010};
|
||||||
|
[117] = {117001, 117010};
|
||||||
|
[118] = {118001, 118010};
|
||||||
|
[120] = {120001, 120012};
|
||||||
|
[121] = {121001, 121012};
|
||||||
|
[122] = {122001, 122012};
|
||||||
|
[123] = {123001, 123012};
|
||||||
|
[124] = {124001, 124012};
|
||||||
|
[125] = {125001, 125012};
|
||||||
|
[126] = {126001, 126012};
|
||||||
|
[127] = {127001, 127012};
|
||||||
|
[128] = {128001, 128012};
|
||||||
|
[129] = {129001, 129016};
|
||||||
|
[130] = {130001, 130012};
|
||||||
|
[131] = {131001, 131012};
|
||||||
|
[132] = {132001, 132012};
|
||||||
|
[133] = {133001, 133012};
|
||||||
|
[134] = {134001, 134016};
|
||||||
|
[135] = {135001, 135012};
|
||||||
|
[136] = {136001, 136012};
|
||||||
|
[137] = {137001, 137012};
|
||||||
|
[138] = {138001, 138012};
|
||||||
|
[139] = {139001, 139012};
|
||||||
|
[140] = {140001, 140012};
|
||||||
|
[141] = {141001, 141012};
|
||||||
|
[142] = {142001, 142012};
|
||||||
|
[143] = {143001, 143016};
|
||||||
|
[144] = {144001, 144018};
|
||||||
|
[145] = {1071001, 1071002};
|
||||||
|
[146] = {1072001, 1072006};
|
||||||
|
[1001] = {1001001, 1001008};
|
||||||
|
[1002] = {1002001, 1002008};
|
||||||
|
[1003] = {1003001, 1003007};
|
||||||
|
[1004] = {1004001, 1004002};
|
||||||
|
[1005] = {1005001, 1005017};
|
||||||
|
[1006] = {1006001, 1006006};
|
||||||
|
[1007] = {1007001, 1007010};
|
||||||
|
[1008] = {1008001, 1008009};
|
||||||
|
[1009] = {1009001, 1009012};
|
||||||
|
[1010] = {1010001, 1010014};
|
||||||
|
[1011] = {1011001, 1011010};
|
||||||
|
[1012] = {1012001, 1012007};
|
||||||
|
[1013] = {1013001, 1013011};
|
||||||
|
[1014] = {1014001, 1014006};
|
||||||
|
[1015] = {1015001, 1015007};
|
||||||
|
[1016] = {1016001, 1016016};
|
||||||
|
[1017] = {1018001, 1018010};
|
||||||
|
[1018] = {1017001, 1017013};
|
||||||
|
[1019] = {1019001, 1019005};
|
||||||
|
[1020] = {1066001, 1066004};
|
||||||
|
[1021] = {1069001, 1069005};
|
||||||
|
[2001] = {1020001, 1020008};
|
||||||
|
[2002] = {1021001, 1021006};
|
||||||
|
[2003] = {1022001, 1022007};
|
||||||
|
[2004] = {1023001, 1023008};
|
||||||
|
[2005] = {1024001, 1024003};
|
||||||
|
[2006] = {1025001, 1025008};
|
||||||
|
[2007] = {1026001, 1026006};
|
||||||
|
[2008] = {1027001, 1027004};
|
||||||
|
[2009] = {1028001, 1028016};
|
||||||
|
[2010] = {1029001, 1029009};
|
||||||
|
[2011] = {1030001, 1030008};
|
||||||
|
[2012] = {1031001, 1031010};
|
||||||
|
[2013] = {1032001, 1032010};
|
||||||
|
[2014] = {1033001, 1033012};
|
||||||
|
[2015] = {1034001, 1034015};
|
||||||
|
[2016] = {1035001, 1035013};
|
||||||
|
[2017] = {1036001, 1036006};
|
||||||
|
[2018] = {1037001, 1037006};
|
||||||
|
[2019] = {1038001, 1038008};
|
||||||
|
[2020] = {1039001, 1039009};
|
||||||
|
[2021] = {1040001, 1040010};
|
||||||
|
[2022] = {1041001, 1041005};
|
||||||
|
[2023] = {1065001, 1065006};
|
||||||
|
[2024] = {1068001, 1068006};
|
||||||
|
[3001] = {1042001, 1042008};
|
||||||
|
[3002] = {1043001, 1043008};
|
||||||
|
[3003] = {1044001, 1044008};
|
||||||
|
[3004] = {1045001, 1045008};
|
||||||
|
[3005] = {1046001, 1046010};
|
||||||
|
[3006] = {1047001, 1047008};
|
||||||
|
[3007] = {1048001, 1048006};
|
||||||
|
[3008] = {1049001, 1049016};
|
||||||
|
[3009] = {1050001, 1050013};
|
||||||
|
[3010] = {1051001, 1051008};
|
||||||
|
[3011] = {1052001, 1052009};
|
||||||
|
[3012] = {1053001, 1053010};
|
||||||
|
[3013] = {1054001, 1054006};
|
||||||
|
[3014] = {1055001, 1055013};
|
||||||
|
[3015] = {1056001, 1056005};
|
||||||
|
[3016] = {1057001, 1057008};
|
||||||
|
[3017] = {1058001, 1058011};
|
||||||
|
[3018] = {1059001, 1059007};
|
||||||
|
[3019] = {1060001, 1060011};
|
||||||
|
[3020] = {1061001, 1061014};
|
||||||
|
[3021] = {1062001, 1062016};
|
||||||
|
[3022] = {1063001, 1063004};
|
||||||
|
[3023] = {1067001, 1067008};
|
||||||
|
[3024] = {1070001, 1070004};
|
||||||
|
[4001] = {1064001, 1064011};
|
||||||
|
[4002] = {1064001, 1064011};
|
||||||
|
[5001] = {2001001, 2001018};
|
||||||
|
[5002] = {2002001, 2002006};
|
||||||
|
[5003] = {2003001, 2003010};
|
||||||
|
[5004] = {2004001, 2004009};
|
||||||
|
[5005] = {2005001, 2005010};
|
||||||
|
[5006] = {2006001, 2006012};
|
||||||
|
[5007] = {2007001, 2007010};
|
||||||
|
[5008] = {2008001, 2008016};
|
||||||
|
[5009] = {2009001, 2009007};
|
||||||
|
[5010] = {2009101, 2009104};
|
||||||
|
[5011] = {2009201, 2009204};
|
||||||
|
[5012] = {2009301, 2009304};
|
||||||
|
[5013] = {2009401, 2009404};
|
||||||
|
[5014] = {2009501, 2009504};
|
||||||
|
[5015] = {2010001, 2010004};
|
||||||
|
[5016] = {2010101, 2010104};
|
||||||
|
[5017] = {2010201, 2010204};
|
||||||
|
[5018] = {2010301, 2010304};
|
||||||
|
[5019] = {2010401, 2010404};
|
||||||
|
[5020] = {2010501, 2010504};
|
||||||
|
[5021] = {2011001, 2011004};
|
||||||
|
[5022] = {2011101, 2011104};
|
||||||
|
[5023] = {2011201, 2011204};
|
||||||
|
[5024] = {2011301, 2011304};
|
||||||
|
[5025] = {2011401, 2011404};
|
||||||
|
[5026] = {2011501, 2011504};
|
||||||
|
[5027] = {2012001, 2012007};
|
||||||
|
[5028] = {2012101, 2012104};
|
||||||
|
[5029] = {2012201, 2012204};
|
||||||
|
[5030] = {2012301, 2012304};
|
||||||
|
[5031] = {2012401, 2012404};
|
||||||
|
[5032] = {2012501, 2012504};
|
||||||
|
[5033] = {2013001, 2013004};
|
||||||
|
[5034] = {2013101, 2013104};
|
||||||
|
[5035] = {2013201, 2013204};
|
||||||
|
[5036] = {2013301, 2013304};
|
||||||
|
[5037] = {2013401, 2013404};
|
||||||
|
[5038] = {2013501, 2013504};
|
||||||
|
[5039] = {2014001, 2014007};
|
||||||
|
[5040] = {2014101, 2014104};
|
||||||
|
[5041] = {2014201, 2014204};
|
||||||
|
[5042] = {2014301, 2014304};
|
||||||
|
[5043] = {2014401, 2014404};
|
||||||
|
[5044] = {2014501, 2014504};
|
||||||
|
[5045] = {2015001, 2015007};
|
||||||
|
[5046] = {2015101, 2015104};
|
||||||
|
[5047] = {2015201, 2015204};
|
||||||
|
[5048] = {2015301, 2015304};
|
||||||
|
[5049] = {2015401, 2015404};
|
||||||
|
[5050] = {2015501, 2015504};
|
||||||
|
[5051] = {2016001, 2016006};
|
||||||
|
[5052] = {2016101, 2016104};
|
||||||
|
[5053] = {2016201, 2016204};
|
||||||
|
[5054] = {2016301, 2016304};
|
||||||
|
[5055] = {2016401, 2016404};
|
||||||
|
[5056] = {2016501, 2016504};
|
||||||
|
[5057] = {2017001, 2017006};
|
||||||
|
[5058] = {2017101, 2017104};
|
||||||
|
[5059] = {2017201, 2017204};
|
||||||
|
[5060] = {2017301, 2017304};
|
||||||
|
[5061] = {2017401, 2017404};
|
||||||
|
[5062] = {2017501, 2017504};
|
||||||
|
[5063] = {2018001, 2018006};
|
||||||
|
[5064] = {2018101, 2018104};
|
||||||
|
[5065] = {2018201, 2018204};
|
||||||
|
[5066] = {2018301, 2018304};
|
||||||
|
[5067] = {2018401, 2018404};
|
||||||
|
[5068] = {2018501, 2018504};
|
||||||
|
[5069] = {2019001, 2019006};
|
||||||
|
[5070] = {2019101, 2019104};
|
||||||
|
[5071] = {2019201, 2019204};
|
||||||
|
[5072] = {2019301, 2019304};
|
||||||
|
[5073] = {2019401, 2019404};
|
||||||
|
[5074] = {2019501, 2019504};
|
||||||
|
[5075] = {2020001, 2020006};
|
||||||
|
[5076] = {2020101, 2020104};
|
||||||
|
[5077] = {2020201, 2020204};
|
||||||
|
[5078] = {2020301, 2020304};
|
||||||
|
[5079] = {2020401, 2020404};
|
||||||
|
[5080] = {2020501, 2020504};
|
||||||
|
[5081] = {2021001, 2021006};
|
||||||
|
[5082] = {2021101, 2021104};
|
||||||
|
[5083] = {2021201, 2021204};
|
||||||
|
[5084] = {2021301, 2021304};
|
||||||
|
[5085] = {2021401, 2021404};
|
||||||
|
[5086] = {2021501, 2021504};
|
||||||
|
[5087] = {2022001, 2022006};
|
||||||
|
[5088] = {2022101, 2022104};
|
||||||
|
[5089] = {2022201, 2022204};
|
||||||
|
[5090] = {2022301, 2022304};
|
||||||
|
[5091] = {2022401, 2022404};
|
||||||
|
[5092] = {2022501, 2022504};
|
||||||
|
[5093] = {2023001, 2023006};
|
||||||
|
[5094] = {2023101, 2023104};
|
||||||
|
[5095] = {2023201, 2023204};
|
||||||
|
[5096] = {2023301, 2023304};
|
||||||
|
[5097] = {2023401, 2023404};
|
||||||
|
[5098] = {2023501, 2023504};
|
||||||
|
[5099] = {2024001, 2024006};
|
||||||
|
[5100] = {2024101, 2024104};
|
||||||
|
[5101] = {2024201, 2024204};
|
||||||
|
[5102] = {2024301, 2024304};
|
||||||
|
[5103] = {2024401, 2024404};
|
||||||
|
[5104] = {2024501, 2024504};
|
||||||
|
[5105] = {2025001, 2025006};
|
||||||
|
[5106] = {2025101, 2025104};
|
||||||
|
[5107] = {2025201, 2025204};
|
||||||
|
[5108] = {2025301, 2025304};
|
||||||
|
[5109] = {2025401, 2025404};
|
||||||
|
[5110] = {2025501, 2025504};
|
||||||
|
[5111] = {2026001, 2026006};
|
||||||
|
[5112] = {2026101, 2026104};
|
||||||
|
[5113] = {2026201, 2026204};
|
||||||
|
[5114] = {2026301, 2026304};
|
||||||
|
[5115] = {2026401, 2026404};
|
||||||
|
[5116] = {2026501, 2026504};
|
||||||
|
[5117] = {2026601, 2026606};
|
||||||
|
[5118] = {2026701, 2026708};
|
||||||
|
[5119] = {2026801, 2026808};
|
||||||
|
[5120] = {2026901, 2026908};
|
||||||
|
[5121] = {2027001, 2027008};
|
||||||
|
[5122] = {2027101, 2027110};
|
||||||
|
[5123] = {2027201, 2027211};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, npc, triggerName)
|
||||||
|
|
||||||
|
npcId = npc:GetActorClassId();
|
||||||
|
|
||||||
|
if shopInfo[npcId] == nil then
|
||||||
|
errorMsg = string.format("This PopulaceShopSalesman actor has no shop set. Actor Class Id: %s", npcId);
|
||||||
|
player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "", errorMsg );
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
end;
|
||||||
|
|
||||||
|
local shopCurrency = 1000001;
|
||||||
|
local welcomeText = 1;
|
||||||
|
local menuId = shopInfo[npcId][2];
|
||||||
|
local shopCategory = shopInfo[npcId][3];
|
||||||
|
|
||||||
|
local itemShop = 0;
|
||||||
|
local classShop = 1;
|
||||||
|
local weaponShop = 2;
|
||||||
|
local armorShop = 3;
|
||||||
|
local hamletShop = 4;
|
||||||
|
|
||||||
|
local weaponShopPack = {5001,5002,5007,5008};
|
||||||
|
local armorShopPack = {5004,5005,5006,5003};
|
||||||
|
|
||||||
|
local menuBuy = 1;
|
||||||
|
local menuBuyCount = 1; -- For Shops with multiple buying categories
|
||||||
|
local menuSell = 2;
|
||||||
|
local menuFacility = 3;
|
||||||
|
local menuTutorial = 4;
|
||||||
|
local menuClose = -3;
|
||||||
|
local menuHasFacility = false;
|
||||||
|
local menuHasTutorial = false;
|
||||||
|
|
||||||
|
local shopPack = shopInfo[npcId][4]; -- Starting value for the shopPack of the current NPC Actor
|
||||||
|
local chosenShopPackage = 0; -- Var to send to openShopMenu() once desired shopPack is determined
|
||||||
|
local choice;
|
||||||
|
|
||||||
|
callClientFunction(player, "welcomeTalk", shopInfo[npcId][welcomeText], player);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
|
||||||
|
if (shopCategory == itemShop) then
|
||||||
|
choice = callClientFunction(player, "selectMode", menuId);
|
||||||
|
menuHasFacility = true;
|
||||||
|
menuHasTutorial = true;
|
||||||
|
elseif (shopCategory == classShop) then
|
||||||
|
choice = callClientFunction(player, "selectModeOfClassVendor");
|
||||||
|
menuBuyCount = 6;
|
||||||
|
menuSell = 0;
|
||||||
|
elseif (shopCategory == weaponShop) then
|
||||||
|
choice = callClientFunction(player, "selectModeOfMultiWeaponVendor", menuId);
|
||||||
|
menuBuyCount = 4;
|
||||||
|
menuSell = 0;
|
||||||
|
elseif (shopCategory == armorShop) then
|
||||||
|
choice = callClientFunction(player, "selectModeOfMultiArmorVendor", menuId);
|
||||||
|
menuBuyCount = 4;
|
||||||
|
menuSell = 0;
|
||||||
|
elseif (shopCategory == hamletShop) then
|
||||||
|
choice = callClientFunction(player, "selectMode", menuId);
|
||||||
|
|
||||||
|
local hamletRegion = shopPack;
|
||||||
|
local hamletPackAleport = {5117, 5122, 5123};
|
||||||
|
local hamletPackHyrstmill = {5117, 5118, 5119};
|
||||||
|
local hamletPackGoldenBazaar = {5117, 5120, 5121};
|
||||||
|
local hamletLevel = 3; -- Defaulting to highest value for now
|
||||||
|
|
||||||
|
if hamletRegion == 5122 then -- Aleport
|
||||||
|
-- hamletLevel = GetHamletStatus(idAleport);
|
||||||
|
shopPack = hamletPackAleport[hamletLevel] or 5117;
|
||||||
|
elseif hamletRegion == 5118 then -- Hyrstmill
|
||||||
|
-- hamletLevel = GetHamletStatus(idHyrstmill);
|
||||||
|
shopPack = hamletPackHyrstmill[hamletLevel] or 5117;
|
||||||
|
elseif hamletRegion == 5120 then -- The Golden Bazaar
|
||||||
|
-- hamletLevel = GetHamletStatus(idGoldenBazaar);
|
||||||
|
shopPack = hamletPackGoldenBazaar[hamletLevel] or 5117;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if choice and (choice >= menuBuy and choice <= menuBuyCount) then
|
||||||
|
--player:SendMessage(0x20,"", "Menu option: "..choice);
|
||||||
|
|
||||||
|
if (shopCategory == weaponShop) then
|
||||||
|
chosenShopPackage = weaponShopPack[choice];
|
||||||
|
elseif (shopCategory == armorShop) then
|
||||||
|
chosenShopPackage = armorShopPack[choice];
|
||||||
|
else
|
||||||
|
chosenShopPackage = ((shopPack-1) + choice);
|
||||||
|
end
|
||||||
|
|
||||||
|
openShopMenu(
|
||||||
|
player,
|
||||||
|
menuId,
|
||||||
|
chosenShopPackage,
|
||||||
|
shopRange[chosenShopPackage][1],
|
||||||
|
shopRange[chosenShopPackage][2],
|
||||||
|
shopCurrency
|
||||||
|
);
|
||||||
|
|
||||||
|
elseif (choice == menuSell) then
|
||||||
|
openSellMenu(player);
|
||||||
|
|
||||||
|
elseif (choice == menuFacility) and (menuHasFacility == true) then
|
||||||
|
if menuId > 0 then
|
||||||
|
local classFacility = (shopInfo[npcId][1] + 1) or 35;
|
||||||
|
facilityChoice = callClientFunction(player, "selectFacility", nil, classFacility, 3);
|
||||||
|
|
||||||
|
if facilityChoice == 1 then
|
||||||
|
callClientFunction(player, "confirmUseFacility", player, 200);
|
||||||
|
elseif facilityChoice == 2 then
|
||||||
|
callClientFunction(player, "confirmUseFacility", player, 400);
|
||||||
|
elseif facilityChoice == 3 then
|
||||||
|
callClientFunction(player, "confirmUseFacility", player, 1000);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif (choice == menuTutorial) and (menuHasTutorial == true) then
|
||||||
|
callClientFunction(player, "startTutorial", nil, menuId);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (choice == menuClose or choice == nil) then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "finishTalkTurn", player);
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function openShopMenu(player, menuId, shopPack, itemRangeStart, itemRangeEnd, shopCurrency)
|
||||||
|
|
||||||
|
callClientFunction(player, "openShopBuy", player, shopPack, shopCurrency);
|
||||||
|
|
||||||
|
player:SendMessage(0x20, "", "shopPack: "..shopPack.." Range: "..itemRangeStart.."-"..itemRangeEnd);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
buyResult, quantity = callClientFunction(player, "selectShopBuy", player);
|
||||||
|
|
||||||
|
if (buyResult == 0) then
|
||||||
|
callClientFunction(player, "closeShopBuy", player);
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
if itemRangeStart and itemRangeEnd then
|
||||||
|
itemChosen = (itemRangeStart - 1) + buyResult;
|
||||||
|
|
||||||
|
if (((itemRangeStart-1) + itemChosen) < itemRangeStart) or (itemChosen > itemRangeEnd) then
|
||||||
|
player:SendMessage(0x20, "", "[ERROR] Client selected item exceeds the valid range.");
|
||||||
|
callClientFunction(player, "finishTalkTurn", player);
|
||||||
|
player:EndEvent();
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
player:SendMessage(0x20, "", "Item chosen: " .. itemChosen .. " Quantity: ".. quantity);
|
||||||
|
|
||||||
|
--[[
|
||||||
|
TO-DO: Request item information from server table and throw result to purchaseItem()
|
||||||
|
|
||||||
|
requestItem = GetItemShopInfoThing(itemChosen);
|
||||||
|
purchaseItem(player, INVENTORY_NORMAL, requestItem.id, quantity, requestItem.quality, requestItem.price, shopCurrency);
|
||||||
|
--]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function openSellMenu(player)
|
||||||
|
callClientFunction(player, "openShopSell", player);
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
sellResult, sellQuantity, sellState, unknown, sellItemSlot = callClientFunction(player, "selectShopSell", player);
|
||||||
|
|
||||||
|
if (sellResult == nil) then
|
||||||
|
callClientFunction(player, "closeShopSell", player);
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
if sellState == 1 then
|
||||||
|
itemToSell = player:GetItemPackage(INVENTORY_NORMAL):GetItemAtSlot(sellItemSlot-1);
|
||||||
|
gItemSellId = itemToSell.itemId;
|
||||||
|
gItemQuality = itemToSell.quality;
|
||||||
|
gItemPrice = GetItemGamedata(gItemSellId);
|
||||||
|
gItemPrice = gItemPrice.sellPrice;
|
||||||
|
|
||||||
|
|
||||||
|
if gItemQuality == 2 then -- +1
|
||||||
|
gItemPrice = (math.floor(gItemPrice * 1.10));
|
||||||
|
elseif gItemQuality == 3 then -- +2
|
||||||
|
gItemPrice = (math.floor(gItemPrice * 1.25));
|
||||||
|
elseif gItemQuality == 4 then -- +3
|
||||||
|
gItemPrice = (math.floor(gItemPrice * 1.50));
|
||||||
|
end
|
||||||
|
|
||||||
|
callClientFunction(player, "informSellPrice", 1, sellItemSlot, gItemPrice);
|
||||||
|
|
||||||
|
elseif sellState == nil then
|
||||||
|
sellItem(player, gItemSellId, sellQuantity, gItemQuality, gItemPrice, sellItemSlot-1, shopCurrency);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
OrdinaryRetainer Script
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
|
||||||
|
eventTalkRetainerOther() -
|
||||||
|
eventTalkRetainerMenu(mode, hasPossessions) - Opens the main menu. If mode == 2, hide dismiss option.
|
||||||
|
eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
|
||||||
|
eventTalkRetainerMannequin(0:enable/1:disable confirm) - Show bazaar modeling confirmation.
|
||||||
|
eventTalkRetainerItemTrade(operationCode) - Operate RetainerTradeWidget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
|
||||||
|
eventTalkRetainerItemList(operationCode) - Operate Bazaar Widget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
|
||||||
|
eventReturnResult(resultCode, ?) - Redraws the RetainerTrade UI.
|
||||||
|
sayToPlayer(actorClassId, messageType, argument) - Makes the retainer say a phrase to the player.
|
||||||
|
eventTalkFinish() - Stops npc from looking at player.
|
||||||
|
eventPlayerTurn(angle) - Turns player to angle.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
require ("retainer")
|
||||||
|
|
||||||
|
function init(npc)
|
||||||
|
return false, false, 0, 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function onEventStarted(player, retainer, triggerName)
|
||||||
|
|
||||||
|
while (true) do
|
||||||
|
choice = callClientFunction(player, "eventTalkRetainerMenu", 1);
|
||||||
|
if (choice == 1) then
|
||||||
|
doItemTrade(player, retainer);
|
||||||
|
elseif (choice == 2) then
|
||||||
|
doBazaar(player, retainer);
|
||||||
|
elseif (choice == 7) then
|
||||||
|
callClientFunction(player, "eventTalkRetainerMannequin", 0);
|
||||||
|
elseif (choice == 5) then
|
||||||
|
player:DespawnMyRetainer();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
local initClassItems, initRaceItems;
|
local initClassItems, initRaceItems;
|
||||||
|
|
||||||
function onBeginLogin(player)
|
function onBeginLogin(player)
|
||||||
|
|
||||||
--New character, set the initial quest
|
--New character, set the initial quest
|
||||||
if (player:GetPlayTime(false) == 0) then
|
if (player:GetPlayTime(false) == 0) then
|
||||||
initialTown = player:GetInitialTown();
|
initialTown = player:GetInitialTown();
|
||||||
@@ -20,7 +19,7 @@ function onBeginLogin(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--For Opening. Set Director and reset position incase d/c
|
--For Opening. Set Director and reset position incase d/c
|
||||||
if (player:HasQuest(110001) == true and player:GetZoneID() == 193) then
|
if (player:HasQuest(110001) == true and player.CurrentArea.ZoneId == 193) then
|
||||||
director = player:GetZone():CreateDirector("OpeningDirector", false);
|
director = player:GetZone():CreateDirector("OpeningDirector", false);
|
||||||
player:AddDirector(director);
|
player:AddDirector(director);
|
||||||
director:StartDirector(true);
|
director:StartDirector(true);
|
||||||
@@ -33,7 +32,7 @@ function onBeginLogin(player)
|
|||||||
player.rotation = 0.025;
|
player.rotation = 0.025;
|
||||||
player:GetQuest(110001):ClearQuestData();
|
player:GetQuest(110001):ClearQuestData();
|
||||||
player:GetQuest(110001):ClearQuestFlags();
|
player:GetQuest(110001):ClearQuestFlags();
|
||||||
elseif (player:HasQuest(110005) == true and player:GetZoneID() == 166) then
|
elseif (player:HasQuest(110005) == true and player.CurrentArea.ZoneId == 166) then
|
||||||
director = player:GetZone():CreateDirector("OpeningDirector", false);
|
director = player:GetZone():CreateDirector("OpeningDirector", false);
|
||||||
player:AddDirector(director);
|
player:AddDirector(director);
|
||||||
director:StartDirector(false);
|
director:StartDirector(false);
|
||||||
@@ -46,7 +45,7 @@ function onBeginLogin(player)
|
|||||||
player.rotation = -1.26721;
|
player.rotation = -1.26721;
|
||||||
player:GetQuest(110005):ClearQuestData();
|
player:GetQuest(110005):ClearQuestData();
|
||||||
player:GetQuest(110005):ClearQuestFlags();
|
player:GetQuest(110005):ClearQuestFlags();
|
||||||
elseif (player:HasQuest(110009) == true and player:GetZoneID() == 184) then
|
elseif (player:HasQuest(110009) == true and player.CurrentArea.ZoneId == 184) then
|
||||||
--director = player:GetZone():CreateDirector("OpeningDirector", false);
|
--director = player:GetZone():CreateDirector("OpeningDirector", false);
|
||||||
--player:AddDirector(director);
|
--player:AddDirector(director);
|
||||||
--director:StartDirector(false);
|
--director:StartDirector(false);
|
||||||
@@ -60,7 +59,6 @@ function onBeginLogin(player)
|
|||||||
player:GetQuest(110009):ClearQuestData();
|
player:GetQuest(110009):ClearQuestData();
|
||||||
player:GetQuest(110009):ClearQuestFlags();
|
player:GetQuest(110009):ClearQuestFlags();
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function onLogin(player)
|
function onLogin(player)
|
||||||
@@ -83,26 +81,26 @@ function initClassItems(player)
|
|||||||
|
|
||||||
--DoW
|
--DoW
|
||||||
if (player.charaWork.parameterSave.state_mainSkill[0] == 2) then --PUG
|
if (player.charaWork.parameterSave.state_mainSkill[0] == 2) then --PUG
|
||||||
player:GetInventory(0):AddItem({4020001, 8030701, 8050728, 8080601, 8090307});
|
player:GetItemPackage(0):AddItem({4020001, 8030701, 8050728, 8080601, 8090307});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 3) then --GLA
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 3) then --GLA
|
||||||
player:GetInventory(0):AddItem({4030010, 8031120, 8050245, 8080601, 8090307});
|
player:GetItemPackage(0):AddItem({4030010, 8031120, 8050245, 8080601, 8090307});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 4) then --MRD
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 4) then --MRD
|
||||||
player:GetInventory(0):AddItem({4040001, 8011001, 8050621, 8070346, 8090307});
|
player:GetItemPackage(0):AddItem({4040001, 8011001, 8050621, 8070346, 8090307});
|
||||||
player:GetEquipment():SetEquipment({0, 8, 12, 13, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 8, 12, 13, 15},{0, 1, 2, 3, 4});
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 7) then --ARC
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 7) then --ARC
|
||||||
player:GetInventory(0):AddItem({4070001, 8030601, 8050622, 8080601, 8090307});
|
player:GetItemPackage(0):AddItem({4070001, 8030601, 8050622, 8080601, 8090307});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 8) then --LNC
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 8) then --LNC
|
||||||
player:GetInventory(0):AddItem({4080201, 8030801, 8051015, 8080501, 8090307});
|
player:GetItemPackage(0):AddItem({4080201, 8030801, 8051015, 8080501, 8090307});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
--DoM
|
--DoM
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 22) then --THM
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 22) then --THM
|
||||||
player:GetInventory(0):AddItem({5020001, 8030245, 8050346, 8080346, 8090208});
|
player:GetItemPackage(0):AddItem({5020001, 8030245, 8050346, 8080346, 8090208});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 23) then --CNJ
|
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 23) then --CNJ
|
||||||
player:GetInventory(0):AddItem({5030101, 8030445, 8050031, 8080246, 8090208});
|
player:GetItemPackage(0):AddItem({5030101, 8030445, 8050031, 8080246, 8090208});
|
||||||
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
|
||||||
|
|
||||||
--DoH
|
--DoH
|
||||||
@@ -126,50 +124,50 @@ end
|
|||||||
function initRaceItems(player)
|
function initRaceItems(player)
|
||||||
|
|
||||||
if (player.playerWork.tribe == 1) then --Hyur Midlander Male
|
if (player.playerWork.tribe == 1) then --Hyur Midlander Male
|
||||||
player:GetInventory(0):AddItem(8040001);
|
player:GetItemPackage(0):AddItem(8040001);
|
||||||
player:GetInventory(0):AddItem(8060001);
|
player:GetItemPackage(0):AddItem(8060001);
|
||||||
elseif (player.playerWork.tribe == 2) then --Hyur Midlander Female
|
elseif (player.playerWork.tribe == 2) then --Hyur Midlander Female
|
||||||
player:GetInventory(0):AddItem(8040002);
|
player:GetItemPackage(0):AddItem(8040002);
|
||||||
player:GetInventory(0):AddItem(8060002);
|
player:GetItemPackage(0):AddItem(8060002);
|
||||||
elseif (player.playerWork.tribe == 3) then --Hyur Highlander Male
|
elseif (player.playerWork.tribe == 3) then --Hyur Highlander Male
|
||||||
player:GetInventory(0):AddItem(8040003);
|
player:GetItemPackage(0):AddItem(8040003);
|
||||||
player:GetInventory(0):AddItem(8060003);
|
player:GetItemPackage(0):AddItem(8060003);
|
||||||
elseif (player.playerWork.tribe == 4) then --Elezen Wildwood Male
|
elseif (player.playerWork.tribe == 4) then --Elezen Wildwood Male
|
||||||
player:GetInventory(0):AddItem(8040004);
|
player:GetItemPackage(0):AddItem(8040004);
|
||||||
player:GetInventory(0):AddItem(8060004);
|
player:GetItemPackage(0):AddItem(8060004);
|
||||||
elseif (player.playerWork.tribe == 5) then --Elezen Wildwood Female
|
elseif (player.playerWork.tribe == 5) then --Elezen Wildwood Female
|
||||||
player:GetInventory(0):AddItem(8040006);
|
player:GetItemPackage(0):AddItem(8040006);
|
||||||
player:GetInventory(0):AddItem(8060006);
|
player:GetItemPackage(0):AddItem(8060006);
|
||||||
elseif (player.playerWork.tribe == 6) then --Elezen Duskwight Male
|
elseif (player.playerWork.tribe == 6) then --Elezen Duskwight Male
|
||||||
player:GetInventory(0):AddItem(8040005);
|
player:GetItemPackage(0):AddItem(8040005);
|
||||||
player:GetInventory(0):AddItem(8060005);
|
player:GetItemPackage(0):AddItem(8060005);
|
||||||
elseif (player.playerWork.tribe == 7) then --Elezen Duskwight Female
|
elseif (player.playerWork.tribe == 7) then --Elezen Duskwight Female
|
||||||
player:GetInventory(0):AddItem(8040007);
|
player:GetItemPackage(0):AddItem(8040007);
|
||||||
player:GetInventory(0):AddItem(8060007);
|
player:GetItemPackage(0):AddItem(8060007);
|
||||||
elseif (player.playerWork.tribe == 8) then --Lalafell Plainsfolk Male
|
elseif (player.playerWork.tribe == 8) then --Lalafell Plainsfolk Male
|
||||||
player:GetInventory(0):AddItem(8040008);
|
player:GetItemPackage(0):AddItem(8040008);
|
||||||
player:GetInventory(0):AddItem(8060008);
|
player:GetItemPackage(0):AddItem(8060008);
|
||||||
elseif (player.playerWork.tribe == 9) then --Lalafell Plainsfolk Female
|
elseif (player.playerWork.tribe == 9) then --Lalafell Plainsfolk Female
|
||||||
player:GetInventory(0):AddItem(8040010);
|
player:GetItemPackage(0):AddItem(8040010);
|
||||||
player:GetInventory(0):AddItem(8060010);
|
player:GetItemPackage(0):AddItem(8060010);
|
||||||
elseif (player.playerWork.tribe == 10) then --Lalafell Dunesfolk Male
|
elseif (player.playerWork.tribe == 10) then --Lalafell Dunesfolk Male
|
||||||
player:GetInventory(0):AddItem(8040009);
|
player:GetItemPackage(0):AddItem(8040009);
|
||||||
player:GetInventory(0):AddItem(8060009);
|
player:GetItemPackage(0):AddItem(8060009);
|
||||||
elseif (player.playerWork.tribe == 11) then --Lalafell Dunesfolk Female
|
elseif (player.playerWork.tribe == 11) then --Lalafell Dunesfolk Female
|
||||||
player:GetInventory(0):AddItem(8040011);
|
player:GetItemPackage(0):AddItem(8040011);
|
||||||
player:GetInventory(0):AddItem(8060011);
|
player:GetItemPackage(0):AddItem(8060011);
|
||||||
elseif (player.playerWork.tribe == 12) then --Miqo'te Seekers of the Sun
|
elseif (player.playerWork.tribe == 12) then --Miqo'te Seekers of the Sun
|
||||||
player:GetInventory(0):AddItem(8040012);
|
player:GetItemPackage(0):AddItem(8040012);
|
||||||
player:GetInventory(0):AddItem(8060012);
|
player:GetItemPackage(0):AddItem(8060012);
|
||||||
elseif (player.playerWork.tribe == 13) then --Miqo'te Seekers of the Moon
|
elseif (player.playerWork.tribe == 13) then --Miqo'te Seekers of the Moon
|
||||||
player:GetInventory(0):AddItem(8040013);
|
player:GetItemPackage(0):AddItem(8040013);
|
||||||
player:GetInventory(0):AddItem(8060013);
|
player:GetItemPackage(0):AddItem(8060013);
|
||||||
elseif (player.playerWork.tribe == 14) then --Roegadyn Sea Wolf
|
elseif (player.playerWork.tribe == 14) then --Roegadyn Sea Wolf
|
||||||
player:GetInventory(0):AddItem(8040014);
|
player:GetItemPackage(0):AddItem(8040014);
|
||||||
player:GetInventory(0):AddItem(8060014);
|
player:GetItemPackage(0):AddItem(8060014);
|
||||||
elseif (player.playerWork.tribe == 15) then --Roegadyn Hellsguard
|
elseif (player.playerWork.tribe == 15) then --Roegadyn Hellsguard
|
||||||
player:GetInventory(0):AddItem(8040015);
|
player:GetItemPackage(0):AddItem(8040015);
|
||||||
player:GetInventory(0):AddItem(8060015);
|
player:GetItemPackage(0):AddItem(8060015);
|
||||||
end
|
end
|
||||||
|
|
||||||
player:GetEquipment():SetEquipment({9, 11},{5,6});
|
player:GetEquipment():SetEquipment({9, 11},{5,6});
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
CommandType =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
AutoAttack = 1,
|
||||||
|
Weaponskill = 2,
|
||||||
|
Ability = 3,
|
||||||
|
Spell = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionType =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Physical = 1,
|
||||||
|
Magic = 2,
|
||||||
|
Heal = 3,
|
||||||
|
Status = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionProperty =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Physical = 1,
|
||||||
|
Magic = 2,
|
||||||
|
Heal = 4,
|
||||||
|
Status = 8,
|
||||||
|
Ranged = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
DamageTakenType =
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Attack,
|
||||||
|
Magic,
|
||||||
|
Weaponskill,
|
||||||
|
Ability
|
||||||
|
}
|
||||||
|
|
||||||
|
HitDirection =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Front = 1,
|
||||||
|
Right = 2,
|
||||||
|
Rear = 4,
|
||||||
|
Left = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
HitType =
|
||||||
|
{
|
||||||
|
Miss = 0,
|
||||||
|
Evade = 1,
|
||||||
|
Parry = 2,
|
||||||
|
Block = 3,
|
||||||
|
Resist = 4,
|
||||||
|
Hit = 5,
|
||||||
|
Crit = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetFindAOEType =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Circle = 1,
|
||||||
|
Cone = 2,
|
||||||
|
Box = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusEffectFlags =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
--Loss flags - Do we need loseonattacking/caststart? Could just be done with activate flags
|
||||||
|
LoseOnDeath = bit32.lshift(1, 0), -- effects removed on death
|
||||||
|
LoseOnZoning = bit32.lshift(1, 1), -- effects removed on zoning
|
||||||
|
LoseOnEsuna = bit32.lshift(1, 2), -- effects which can be removed with esuna (debuffs)
|
||||||
|
LoseOnDispel = bit32.lshift(1, 3), -- some buffs which player might be able to dispel from mob
|
||||||
|
LoseOnLogout = bit32.lshift(1, 4), -- effects removed on logging out
|
||||||
|
LoseOnAttacking = bit32.lshift(1, 5), -- effects removed when owner attacks another entity
|
||||||
|
LoseOnCastStart = bit32.lshift(1, 6), -- effects removed when owner starts casting
|
||||||
|
LoseOnAggro = bit32.lshift(1, 7), -- effects removed when owner gains enmity (swiftsong)
|
||||||
|
LoseOnClassChange = bit32.lshift(1, 8), --Effect falls off whhen changing class
|
||||||
|
|
||||||
|
--Activate flags
|
||||||
|
ActivateOnCastStart = bit32.lshift(1, 9), --Activates when a cast starts.
|
||||||
|
ActivateOnCommandStart = bit32.lshift(1, 10), --Activates when a command is used, before iterating over targets. Used for things like power surge, excruciate.
|
||||||
|
ActivateOnCommandFinish = bit32.lshift(1, 11), --Activates when the command is finished, after all targets have been iterated over. Used for things like Excruciate and Resonance falling off.
|
||||||
|
ActivateOnPreactionTarget = bit32.lshift(1, 12), --Activates after initial rates are calculated for an action against owner
|
||||||
|
ActivateOnPreactionCaster = bit32.lshift(1, 13), --Activates after initial rates are calculated for an action by owner
|
||||||
|
ActivateOnDamageTaken = bit32.lshift(1, 14),
|
||||||
|
ActivateOnHealed = bit32.lshift(1, 15),
|
||||||
|
|
||||||
|
--Should these be rolled into DamageTaken?
|
||||||
|
ActivateOnMiss = bit32.lshift(1, 16), --Activates when owner misses
|
||||||
|
ActivateOnEvade = bit32.lshift(1, 17), --Activates when owner evades
|
||||||
|
ActivateOnParry = bit32.lshift(1, 18), --Activates when owner parries
|
||||||
|
ActivateOnBlock = bit32.lshift(1, 19), --Activates when owner evades
|
||||||
|
ActivateOnHit = bit32.lshift(1, 20), --Activates when owner hits
|
||||||
|
ActivateOnCrit = bit32.lshift(1, 21), --Activates when owner crits
|
||||||
|
|
||||||
|
--Prevent flags. Sleep/stun/petrify/etc combine these
|
||||||
|
PreventSpell = bit32.lshift(1, 22), -- effects which prevent using spells, such as silence
|
||||||
|
PreventWeaponSkill = bit32.lshift(1, 23), -- effects which prevent using weaponskills, such as pacification
|
||||||
|
PreventAbility = bit32.lshift(1, 24), -- effects which prevent using abilities, such as amnesia
|
||||||
|
PreventAttack = bit32.lshift(1, 25), -- effects which prevent basic attacks
|
||||||
|
PreventMovement = bit32.lshift(1, 26), -- effects which prevent movement such as bind, still allows turning in place
|
||||||
|
PreventTurn = bit32.lshift(1, 27), -- effects which prevent turning, such as stun
|
||||||
|
PreventUntarget = bit32.lshift(1, 28), -- effects which prevent changing targets, such as fixation
|
||||||
|
Stance = bit32.lshift(1, 29) -- effects that do not have a timer
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
require ("global")
|
||||||
|
require ("utils")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
AttackWeaponSkill Script
|
||||||
|
|
||||||
|
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local attackMagicHandlers = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
player.Ability(command.Id, targetActor);
|
||||||
|
player:endEvent();
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
require ("global")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
ActivateCommand Script
|
||||||
|
|
||||||
|
Switches between active and passive mode states
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName)
|
||||||
|
|
||||||
|
if (player.currentMainState == 0x0000) then
|
||||||
|
player.Engage(0, 0x0002);
|
||||||
|
elseif (player.currentMainState == 0x0002) then
|
||||||
|
player.Disengage(0x0000);
|
||||||
|
end
|
||||||
|
player:endEvent();
|
||||||
|
sendSignal("playerActive");
|
||||||
|
end;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
require ("global")
|
||||||
|
require ("utils")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
AttackWeaponSkill Script
|
||||||
|
|
||||||
|
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local attackMagicHandlers = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
player.Ability(command.Id, targetActor);
|
||||||
|
player:endEvent();
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
require ("global")
|
||||||
|
require ("utils")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
AttackWeaponSkill Script
|
||||||
|
|
||||||
|
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local attackMagicHandlers = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
player.Cast(command.Id, targetActor);
|
||||||
|
player:endEvent();
|
||||||
|
end;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
require ("global")
|
||||||
|
require ("utils")
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
AttackWeaponSkill Script
|
||||||
|
|
||||||
|
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
--Are they in active mode?
|
||||||
|
if (player:GetState() != 2) then
|
||||||
|
player:SendGameMessage(GetWorldMaster(), 32503, 0x20);
|
||||||
|
player:endEvent();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if not player.aiContainer.IsEngaged() then
|
||||||
|
player.Engage(targetActor);
|
||||||
|
end;
|
||||||
|
player.WeaponSkill(command.Id, targetActor);
|
||||||
|
player:endEvent();
|
||||||
|
end;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
BazaarCheckCommand Script
|
||||||
|
|
||||||
|
Handles what happens when you examine a player's bazaar
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require ("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, actor, eventType, eventName, name, arg1, arg2, arg3, bazaarActorId)
|
||||||
|
|
||||||
|
local bazaarActor = nil;
|
||||||
|
|
||||||
|
if (name ~= nil) then
|
||||||
|
bazaarActor = player.CurrentArea:FindPCInZone(name);
|
||||||
|
elseif (bazaarActorId ~= nil) then
|
||||||
|
bazaarActor = player.CurrentArea:FindActorInArea(bazaarActorId);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (bazaarActor ~= nil) then
|
||||||
|
player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "", "Currently disabled due to freezing characters.");
|
||||||
|
--callClientFunction(player, "delegateCommand", GetStaticActor("BazaarCheckCommand"), "processChackBazaar");
|
||||||
|
else
|
||||||
|
--Show error
|
||||||
|
end
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
|
||||||
|
end
|
||||||
Loaded 100 of 2035 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user