mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-05-20 08:26:59 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
612cfe22d9 | ||
|
|
1e311904cc | ||
|
|
8ceee35492 | ||
|
|
40b677f871 | ||
|
|
57e7ee1894 | ||
|
|
61069e6d49 | ||
|
|
0521b167fb | ||
|
|
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
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[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.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Ionic.Zlib;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
using Ionic.Zlib;
|
||||
|
||||
namespace FFXIVClassic.Common
|
||||
namespace Meteor.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BasePacketHeader
|
||||
@@ -242,6 +264,13 @@ namespace FFXIVClassic.Common
|
||||
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);
|
||||
|
||||
var packet = new BasePacket(header, data);
|
||||
@@ -266,7 +295,15 @@ namespace FFXIVClassic.Common
|
||||
data = new byte[header.packetSize - 0x10];
|
||||
|
||||
//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);
|
||||
|
||||
Debug.Assert(data != null);
|
||||
@@ -291,6 +328,13 @@ namespace FFXIVClassic.Common
|
||||
//Get packet size
|
||||
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);
|
||||
return packet;
|
||||
}
|
||||
@@ -390,17 +434,31 @@ namespace FFXIVClassic.Common
|
||||
{
|
||||
zipStream.CopyTo(resultStream);
|
||||
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 resultStream = new MemoryStream())
|
||||
{
|
||||
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)]
|
||||
public sealed class BitfieldLengthAttribute : Attribute
|
||||
@@ -60,7 +81,7 @@ namespace FFXIVClassic.Common
|
||||
// Calculate a bitmask of the desired length
|
||||
long mask = 0;
|
||||
for (int i = 0; i < fieldLength; i++)
|
||||
mask |= 1 << i;
|
||||
mask |= 1L << i;
|
||||
|
||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props') AND '$(OS)' == 'Windows_NT'" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props') AND '$(OS)' == 'Windows_NT'" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Meteor.Common</RootNamespace>
|
||||
<AssemblyName>Meteor.Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<NuGetPackageImportStamp>792e4711</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<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>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DotNetZip">
|
||||
<HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf, Version=3.19.4.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Google.Protobuf.3.19.4\lib\net45\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4, Version=1.2.6.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\K4os.Compression.LZ4.1.2.6\lib\net46\K4os.Compression.LZ4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4.Streams, Version=1.2.6.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\K4os.Compression.LZ4.Streams.1.2.6\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Hash.xxHash, Version=1.0.6.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\K4os.Hash.xxHash.1.0.6\lib\net46\K4os.Hash.xxHash.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=8.0.31.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MySql.Data.8.0.31\lib\net452\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.5.0\lib\net45\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="ZstdNet, Version=1.4.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MySql.Data.8.0.31\lib\net452\ZstdNet.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BasePacket.cs" />
|
||||
<Compile Include="Bitfield.cs" />
|
||||
<Compile Include="Blowfish.cs" />
|
||||
<Compile Include="EfficientHashTables.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sql.cs" />
|
||||
<Compile Include="STA_INIFile.cs" />
|
||||
<Compile Include="SubPacket.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Vector3.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
+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
|
||||
{
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
@@ -3,13 +3,14 @@
|
||||
// *******************************
|
||||
// *** (C)2009-2013 S.T.A. snc ***
|
||||
// *******************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic.Common
|
||||
namespace Meteor.Common
|
||||
{
|
||||
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 FFXIVClassic.Common;
|
||||
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace FFXIVClassic.Common
|
||||
namespace Meteor.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
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.Text;
|
||||
|
||||
namespace FFXIVClassic.Common
|
||||
namespace Meteor.Common
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
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()
|
||||
{
|
||||
@@ -84,10 +106,10 @@ namespace FFXIVClassic.Common
|
||||
return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray());
|
||||
}
|
||||
|
||||
public static uint UnixTimeStampUTC()
|
||||
public static uint UnixTimeStampUTC(DateTime? time = null)
|
||||
{
|
||||
uint unixTimeStamp;
|
||||
var currentTime = DateTime.Now;
|
||||
var currentTime = time ?? DateTime.Now;
|
||||
var zuluTime = currentTime.ToUniversalTime();
|
||||
var unixEpoch = new DateTime(1970, 1, 1);
|
||||
unixTimeStamp = (uint)zuluTime.Subtract(unixEpoch).TotalSeconds;
|
||||
@@ -95,10 +117,10 @@ namespace FFXIVClassic.Common
|
||||
return unixTimeStamp;
|
||||
}
|
||||
|
||||
public static ulong MilisUnixTimeStampUTC()
|
||||
public static ulong MilisUnixTimeStampUTC(DateTime? time = null)
|
||||
{
|
||||
ulong unixTimeStamp;
|
||||
var currentTime = DateTime.Now;
|
||||
var currentTime = time ?? DateTime.Now;
|
||||
var zuluTime = currentTime.ToUniversalTime();
|
||||
var unixEpoch = new DateTime(1970, 1, 1);
|
||||
unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds;
|
||||
@@ -106,6 +128,11 @@ namespace FFXIVClassic.Common
|
||||
return unixTimeStamp;
|
||||
}
|
||||
|
||||
public static DateTime UnixTimeStampToDateTime(uint timestamp)
|
||||
{
|
||||
return epoch.AddSeconds(timestamp);
|
||||
}
|
||||
|
||||
public static ulong SwapEndian(ulong input)
|
||||
{
|
||||
return 0x00000000000000FF & (input >> 56) |
|
||||
@@ -139,6 +166,12 @@ namespace FFXIVClassic.Common
|
||||
return input;
|
||||
}
|
||||
|
||||
public static ushort SwapEndian(ushort input)
|
||||
{
|
||||
return (ushort)(((input << 8) & 0xff00) |
|
||||
((input >> 8) & 0x00ff));
|
||||
}
|
||||
|
||||
public static uint MurmurHash2(string key, uint seed)
|
||||
{
|
||||
// 'm' and 'r' are mixing constants generated offline.
|
||||
@@ -232,6 +265,15 @@ namespace FFXIVClassic.Common
|
||||
return secondDigit + firstDigit;
|
||||
}
|
||||
|
||||
public static string ReadNullTermString(BinaryReader reader, int maxSize = 0x20)
|
||||
{
|
||||
return Encoding.ASCII.GetString(reader.ReadBytes(maxSize)).Trim(new[] { '\0' });
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -351,5 +393,95 @@ namespace FFXIVClassic.Common
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /></startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
|
||||
<package id="Google.Protobuf" version="3.19.4" targetFramework="net472" />
|
||||
<package id="K4os.Compression.LZ4" version="1.2.6" targetFramework="net472" />
|
||||
<package id="K4os.Compression.LZ4.Streams" version="1.2.6" targetFramework="net472" />
|
||||
<package id="K4os.Hash.xxHash" version="1.0.6" targetFramework="net472" />
|
||||
<package id="MySql.Data" version="8.0.31" targetFramework="net472" />
|
||||
<package id="NLog" version="4.5.0" targetFramework="net451" />
|
||||
<package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" />
|
||||
</packages>
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,110 @@
|
||||
@ECHO OFF
|
||||
REM SETLOCAL
|
||||
SET CWD = %~dp0
|
||||
|
||||
REM Echo Launch dir: "%~dp0"
|
||||
REM Echo Current dir: "%CD%"
|
||||
|
||||
REM =============
|
||||
REM COPY LOBBY CONFIG
|
||||
REM =============
|
||||
REM Required files: lobby_config.ini
|
||||
|
||||
SET /a foundlfolders = 0
|
||||
|
||||
if exist "%~dp0\..\Lobby Server\bin\Debug" (
|
||||
SET /a foundlfolders = %foundlfolders% + 1
|
||||
echo Found Lobby Debug build folder.
|
||||
|
||||
echo Copying lobby_config.ini if needed...
|
||||
xcopy lobby_config.ini "%~dp0\..\Lobby Server\bin\Debug\" /d /y /q
|
||||
)
|
||||
|
||||
if exist "%~dp0\..\Lobby Server\bin\Release" (
|
||||
SET /a foundlfolders = %foundlfolders% + 1
|
||||
echo Found Lobby Release build folder.
|
||||
|
||||
echo Copying lobby_config.ini if needed...
|
||||
xcopy lobby_config.ini "%~dp0\..\Lobby Server\bin\Release\" /d /y /q
|
||||
)
|
||||
|
||||
if %foundlfolders% LSS 1 (
|
||||
echo Could not find debug or release folder for the Lobby server. Please compile the project first!
|
||||
)
|
||||
|
||||
REM =============
|
||||
REM COPY WORLD CONFIG
|
||||
REM =============
|
||||
REM Required files: world_config.ini
|
||||
|
||||
SET /a foundwfolders = 0
|
||||
|
||||
if exist "%~dp0\..\World Server\bin\Debug" (
|
||||
SET /a foundwfolders = %foundwfolders% + 1
|
||||
echo Found World Debug build folder.
|
||||
|
||||
echo Copying world_config.ini if needed...
|
||||
xcopy world_config.ini "%~dp0\..\World Server\bin\Debug\" /d /y /q
|
||||
)
|
||||
|
||||
if exist "%~dp0\..\World Server\bin\Release" (
|
||||
SET /a foundwfolders = %foundwfolders% + 1
|
||||
echo Found World Release build folder.
|
||||
|
||||
echo Copying world_config.ini if needed...
|
||||
xcopy world_config.ini "%~dp0\..\World Server\bin\Release\" /d /y /q
|
||||
)
|
||||
|
||||
if %foundwfolders% LSS 1 (
|
||||
echo Could not find debug or release folder for the World server. Please compile the project first!
|
||||
)
|
||||
|
||||
REM =============
|
||||
REM COPY MAP CONFIG
|
||||
REM =============
|
||||
REM Required files: map_config.ini staticactors.bin scripts/
|
||||
|
||||
SET /a foundmfolders = 0
|
||||
|
||||
if exist "%~dp0\..\Map Server\bin\Debug" (
|
||||
SET /a foundmfolders = %foundmfolders% + 1
|
||||
echo Found Map Debug build folder.
|
||||
|
||||
echo Copying map_config.ini if needed...
|
||||
xcopy map_config.ini "%~dp0\..\Map Server\bin\Debug\" /d /y /q
|
||||
|
||||
if exist staticactors.bin (
|
||||
echo Copying staticactors.bin if needed...
|
||||
xcopy staticactors.bin "%~dp0\..\Map Server\bin\Debug\" /d /y /q
|
||||
) else (
|
||||
echo Cannot copy the staticactors.bin file because it doesn't exist in data\
|
||||
)
|
||||
|
||||
|
||||
echo Copying scripts folder if needed...
|
||||
xcopy scripts "%~dp0\..\Map Server\bin\Debug\scripts\" /e /d /y /s /q
|
||||
)
|
||||
|
||||
if exist "%~dp0\..\Map Server\bin\Release" (
|
||||
SET /a foundmfolders = %foundmfolders% + 1
|
||||
echo Found Map Release build folder.
|
||||
|
||||
echo Copying map_config.ini if needed...
|
||||
xcopy map_config.ini "%~dp0\..\Map Server\bin\Release\" /d /y /q
|
||||
|
||||
if exist staticactors.bin (
|
||||
echo Copying staticactors.bin if needed...
|
||||
xcopy staticactors.bin "%~dp0\..\Map Server\bin\Release\" /d /y /q
|
||||
) else (
|
||||
echo Cannot copy the staticactors.bin file because it doesn't exist in data\
|
||||
)
|
||||
|
||||
echo Copying scripts folder if needed...
|
||||
xcopy scripts "%~dp0\..\Map Server\bin\Release\scripts\" /e /d /y /s /q
|
||||
)
|
||||
|
||||
if %foundmfolders% LSS 1 (
|
||||
echo Could not find debug or release folder for the Map server. Please compile the project first!
|
||||
)
|
||||
|
||||
Pause
|
||||
@@ -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
|
||||
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.
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,152 @@
|
||||
--[[
|
||||
|
||||
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, triggerName)
|
||||
|
||||
local npcCity = city[npc:GetActorClassId()] or 1;
|
||||
local wardPlaceName = 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 questAreaName = 0; --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[4];
|
||||
|
||||
if (currZone == 133 or currZone == 230 or currZone == 155 or currZone == 206 or currZone == 175 or currZone == 209) then
|
||||
exitPlaceName = 0; -- If in city, hide city menu option
|
||||
elseif (currZone == 232 or currZone == 234 or currZone == 233) then
|
||||
gcHQPlaceName = 0; -- If in GC Office, hide office menu option
|
||||
end
|
||||
|
||||
choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, wardPlaceName, gcHQPlaceName, questAreaName, showItemSearchCounter, itemSearchId);
|
||||
|
||||
while (true) do
|
||||
|
||||
if choice == wardPlaceName 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 == 0 or choice == -3) then -- Menu Closed
|
||||
break;
|
||||
end
|
||||
|
||||
choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, wardPlaceName, gcHQPlaceName, questAreaName, showItemSearchCounter, itemSearchId);
|
||||
|
||||
end
|
||||
|
||||
player:EndEvent();
|
||||
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
+2
@@ -9,8 +9,10 @@ function onEventStarted(player, npc, triggerName)
|
||||
choice = callClientFunction(player, "askLogout", player);
|
||||
|
||||
if (choice == 2) then
|
||||
player:SetSleeping();
|
||||
player:QuitGame();
|
||||
elseif (choice == 3) then
|
||||
player:SetSleeping();
|
||||
player:Logout();
|
||||
elseif (choice == 4) then
|
||||
player:SendMessage(33, "", "Heck the bed");
|
||||
File renamed without changes.
File renamed without changes.
+2
-2
@@ -31,7 +31,7 @@ function onEventStarted(player, npc, triggerName)
|
||||
itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice);
|
||||
|
||||
if (itemId ~= nil) then
|
||||
player:GetInventory(INVENTORY_NORMAL):RemoveItem(itemId, 1);
|
||||
player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(itemId, 1);
|
||||
end
|
||||
|
||||
elseif (storageChoice == 2) then
|
||||
@@ -44,7 +44,7 @@ function onEventStarted(player, npc, triggerName)
|
||||
itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice);
|
||||
|
||||
if (itemId ~= nil) then
|
||||
player:GetInventory(INVENTORY_NORMAL):AddItem(itemId, 1);
|
||||
player:GetItemPackage(INVENTORY_NORMAL):AddItem(itemId, 1);
|
||||
end
|
||||
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
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:SendGameMessageDisplayIDSender(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,119 @@
|
||||
--[[
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
function init(npc)
|
||||
return false, false, 0, 0;
|
||||
end
|
||||
|
||||
function onEventStarted(player, npc, triggerName)
|
||||
local curLevel = 20; -- TODO: pull from character
|
||||
local hasIssuance = player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(gcIssuances[npc:GetActorClassId()]);
|
||||
local hasChocobo = player.hasChocobo;
|
||||
|
||||
if (hasChocobo == false) then -- Let GMs auto have the issuance for debugging
|
||||
hasIssuance = true;
|
||||
end
|
||||
|
||||
local hasFunds = (player:GetCurrentGil() >= rentalPrice);
|
||||
|
||||
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[npc:GetActorClassId()];
|
||||
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[npc:GetActorClassId()], 1);
|
||||
|
||||
--Warp with the special chocobo warp mode.
|
||||
mountChocobo(player);
|
||||
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()][1], nil, 0, SPAWN_CHOCOBO_GET, cityExits[npc:GetActorClassId()][2], cityExits[npc:GetActorClassId()][3], cityExits[npc:GetActorClassId()][4], cityExits[npc:GetActorClassId()][5]);
|
||||
end
|
||||
|
||||
elseif(menuChoice == 2) then -- Summon Bird
|
||||
mountChocobo(player);
|
||||
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()][1], nil, 0, SPAWN_NO_ANIM, cityExits[npc:GetActorClassId()][2], cityExits[npc:GetActorClassId()][3], cityExits[npc:GetActorClassId()][4], cityExits[npc:GetActorClassId()][5]);
|
||||
elseif(menuChoice == 3) then -- Change Barding
|
||||
callClientFunction(player, "eventTalkStepBreak", player);
|
||||
elseif(menuChoice == 5) then -- Rent Bird
|
||||
mountChocobo(player, true, 1);
|
||||
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()][1], nil, 0, SPAWN_CHOCOBO_RENTAL, cityExits[npc:GetActorClassId()][2], cityExits[npc:GetActorClassId()][3], cityExits[npc:GetActorClassId()][4], cityExits[npc:GetActorClassId()][5]);
|
||||
else
|
||||
callClientFunction(player, "eventTalkStepBreak", player);
|
||||
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, 5.0, 10.0, 10.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,120 @@
|
||||
--[[
|
||||
|
||||
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() - Ends talk
|
||||
--]]
|
||||
|
||||
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, "playereventTalkStepBreak");
|
||||
player:EndEvent();
|
||||
else
|
||||
-- callClientFunction(player, "eventAfterWarpOtherZone", player); -- Commented out for now to prevent double fade-to-black for warp
|
||||
player:EndEvent();
|
||||
GetWorldManager():DoZoneChange(player, aethernet[city][choice].zone, nil, 0, 15, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r);
|
||||
end
|
||||
end
|
||||
|
||||
player:EndEvent();
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
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.
File renamed without changes.
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,84 @@
|
||||
--[[
|
||||
|
||||
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
|
||||
File renamed without changes.
@@ -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;
|
||||
|
||||
function onBeginLogin(player)
|
||||
|
||||
--New character, set the initial quest
|
||||
if (player:GetPlayTime(false) == 0) then
|
||||
initialTown = player:GetInitialTown();
|
||||
@@ -60,7 +59,6 @@ function onBeginLogin(player)
|
||||
player:GetQuest(110009):ClearQuestData();
|
||||
player:GetQuest(110009):ClearQuestFlags();
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function onLogin(player)
|
||||
@@ -83,26 +81,26 @@ function initClassItems(player)
|
||||
|
||||
--DoW
|
||||
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});
|
||||
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});
|
||||
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});
|
||||
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});
|
||||
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});
|
||||
--DoM
|
||||
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});
|
||||
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});
|
||||
|
||||
--DoH
|
||||
@@ -126,50 +124,50 @@ end
|
||||
function initRaceItems(player)
|
||||
|
||||
if (player.playerWork.tribe == 1) then --Hyur Midlander Male
|
||||
player:GetInventory(0):AddItem(8040001);
|
||||
player:GetInventory(0):AddItem(8060001);
|
||||
player:GetItemPackage(0):AddItem(8040001);
|
||||
player:GetItemPackage(0):AddItem(8060001);
|
||||
elseif (player.playerWork.tribe == 2) then --Hyur Midlander Female
|
||||
player:GetInventory(0):AddItem(8040002);
|
||||
player:GetInventory(0):AddItem(8060002);
|
||||
player:GetItemPackage(0):AddItem(8040002);
|
||||
player:GetItemPackage(0):AddItem(8060002);
|
||||
elseif (player.playerWork.tribe == 3) then --Hyur Highlander Male
|
||||
player:GetInventory(0):AddItem(8040003);
|
||||
player:GetInventory(0):AddItem(8060003);
|
||||
player:GetItemPackage(0):AddItem(8040003);
|
||||
player:GetItemPackage(0):AddItem(8060003);
|
||||
elseif (player.playerWork.tribe == 4) then --Elezen Wildwood Male
|
||||
player:GetInventory(0):AddItem(8040004);
|
||||
player:GetInventory(0):AddItem(8060004);
|
||||
player:GetItemPackage(0):AddItem(8040004);
|
||||
player:GetItemPackage(0):AddItem(8060004);
|
||||
elseif (player.playerWork.tribe == 5) then --Elezen Wildwood Female
|
||||
player:GetInventory(0):AddItem(8040006);
|
||||
player:GetInventory(0):AddItem(8060006);
|
||||
player:GetItemPackage(0):AddItem(8040006);
|
||||
player:GetItemPackage(0):AddItem(8060006);
|
||||
elseif (player.playerWork.tribe == 6) then --Elezen Duskwight Male
|
||||
player:GetInventory(0):AddItem(8040005);
|
||||
player:GetInventory(0):AddItem(8060005);
|
||||
player:GetItemPackage(0):AddItem(8040005);
|
||||
player:GetItemPackage(0):AddItem(8060005);
|
||||
elseif (player.playerWork.tribe == 7) then --Elezen Duskwight Female
|
||||
player:GetInventory(0):AddItem(8040007);
|
||||
player:GetInventory(0):AddItem(8060007);
|
||||
player:GetItemPackage(0):AddItem(8040007);
|
||||
player:GetItemPackage(0):AddItem(8060007);
|
||||
elseif (player.playerWork.tribe == 8) then --Lalafell Plainsfolk Male
|
||||
player:GetInventory(0):AddItem(8040008);
|
||||
player:GetInventory(0):AddItem(8060008);
|
||||
player:GetItemPackage(0):AddItem(8040008);
|
||||
player:GetItemPackage(0):AddItem(8060008);
|
||||
elseif (player.playerWork.tribe == 9) then --Lalafell Plainsfolk Female
|
||||
player:GetInventory(0):AddItem(8040010);
|
||||
player:GetInventory(0):AddItem(8060010);
|
||||
player:GetItemPackage(0):AddItem(8040010);
|
||||
player:GetItemPackage(0):AddItem(8060010);
|
||||
elseif (player.playerWork.tribe == 10) then --Lalafell Dunesfolk Male
|
||||
player:GetInventory(0):AddItem(8040009);
|
||||
player:GetInventory(0):AddItem(8060009);
|
||||
player:GetItemPackage(0):AddItem(8040009);
|
||||
player:GetItemPackage(0):AddItem(8060009);
|
||||
elseif (player.playerWork.tribe == 11) then --Lalafell Dunesfolk Female
|
||||
player:GetInventory(0):AddItem(8040011);
|
||||
player:GetInventory(0):AddItem(8060011);
|
||||
player:GetItemPackage(0):AddItem(8040011);
|
||||
player:GetItemPackage(0):AddItem(8060011);
|
||||
elseif (player.playerWork.tribe == 12) then --Miqo'te Seekers of the Sun
|
||||
player:GetInventory(0):AddItem(8040012);
|
||||
player:GetInventory(0):AddItem(8060012);
|
||||
player:GetItemPackage(0):AddItem(8040012);
|
||||
player:GetItemPackage(0):AddItem(8060012);
|
||||
elseif (player.playerWork.tribe == 13) then --Miqo'te Seekers of the Moon
|
||||
player:GetInventory(0):AddItem(8040013);
|
||||
player:GetInventory(0):AddItem(8060013);
|
||||
player:GetItemPackage(0):AddItem(8040013);
|
||||
player:GetItemPackage(0):AddItem(8060013);
|
||||
elseif (player.playerWork.tribe == 14) then --Roegadyn Sea Wolf
|
||||
player:GetInventory(0):AddItem(8040014);
|
||||
player:GetInventory(0):AddItem(8060014);
|
||||
player:GetItemPackage(0):AddItem(8040014);
|
||||
player:GetItemPackage(0):AddItem(8060014);
|
||||
elseif (player.playerWork.tribe == 15) then --Roegadyn Hellsguard
|
||||
player:GetInventory(0):AddItem(8040015);
|
||||
player:GetInventory(0):AddItem(8060015);
|
||||
player:GetItemPackage(0):AddItem(8040015);
|
||||
player:GetItemPackage(0):AddItem(8060015);
|
||||
end
|
||||
|
||||
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, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||
player.Ability(command.actorId, targetActor);
|
||||
player:endEvent();
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
require("global")
|
||||
|
||||
function onEventStarted(player, command, triggerName, 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, triggerName)
|
||||
|
||||
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, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||
player.Ability(command.actorId, 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, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||
player.Cast(command.actorId, 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, triggerName, 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.actorId, 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, triggerName, name, arg1, arg2, arg3, bazaarActorId)
|
||||
|
||||
local bazaarActor = nil;
|
||||
|
||||
if (name ~= nil) then
|
||||
bazaarActor = player:GetZone():FindPCInZone(name);
|
||||
elseif (bazaarActorId ~= nil) then
|
||||
bazaarActor = player:GetZone():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
|
||||
@@ -0,0 +1,58 @@
|
||||
--[[
|
||||
|
||||
BazaarDealCommand Script
|
||||
|
||||
Handles various bazaar transfer options
|
||||
|
||||
All bazaar args have a Reward (The item the person who fufills the request gets) and a Seek (The item the player wants, either gil or an item).
|
||||
|
||||
Args:
|
||||
|
||||
rewardItem: Item reference to what will be given to the buyer. If it's gil the itemID will be given instead. If offering an item to seek; reward/seek are combined and put here.
|
||||
seekItem: Item reference to what the buyer will give us. If it's gil the itemID will be given instead,
|
||||
bazaarMode: The tag value to set in the bazaar item's data.
|
||||
arg1: Always nil
|
||||
bazaarActor: The actor who owns this bazaar
|
||||
rewardAmount: The amount of rewardItem the buyer will get.
|
||||
seekAmount: The amount of seekItem we want.
|
||||
|
||||
--]]
|
||||
|
||||
require ("global")
|
||||
|
||||
function onEventStarted(player, actor, triggerName, rewardItem, seekItem, bazaarMode, arg1, bazaarActor, rewardAmount, seekAmount, arg2, arg3, type9ItemIds)
|
||||
|
||||
local rewarding = nil;
|
||||
local seeking = nil;
|
||||
|
||||
--Handle special case for offering an item.
|
||||
if (seekItem == nil) then
|
||||
rewarding = player:GetItemPackage(rewardItem.offerPackageId):GetItemAtSlot(rewardItem.offerSlot);
|
||||
seeking = player:GetItemPackage(rewardItem.seekPackageId):GetItemAtSlot(rewardItem.seekSlot);
|
||||
end
|
||||
|
||||
--Handle Reward
|
||||
if (rewarding == nil) then
|
||||
if (type(rewardItem) == "number") then
|
||||
rewarding = player:GetItemPackage(INVENTORY_CURRENCY):GetItemByCatelogId(rewardItem);
|
||||
else
|
||||
rewarding = player:GetItem(rewardItem);
|
||||
end
|
||||
end
|
||||
|
||||
--Handle Seek
|
||||
if (seeking == nil) then
|
||||
if (type(seekItem) == "number") then
|
||||
seeking = player:GetItemPackage(INVENTORY_CURRENCY):GetItemByCatelogId(seekItem);
|
||||
else
|
||||
seeking = player:GetItem(seekItem);
|
||||
end
|
||||
end
|
||||
|
||||
result = GetWorldManager():AddToBazaar(player, rewarding, seeking, rewardAmount, seekAmount, bazaarMode);
|
||||
|
||||
|
||||
|
||||
player:EndEvent();
|
||||
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
--[[
|
||||
|
||||
BazaarTradeCommand Script
|
||||
|
||||
Handles bazaar trade
|
||||
|
||||
All bazaar args have a Reward (The item the person who fufills the request gets) and a Seek (The item the player wants, either gil or an item).
|
||||
|
||||
--]]
|
||||
|
||||
--TODO REFACTOR
|
||||
|
||||
function onEventStarted(player, actor, triggerName, rewardItem, seekItemOrCost, seekAmount, arg1, bazaarActorId, rewardAmount, rewardItemId, nameIndex, arg2, type9ItemIds)
|
||||
|
||||
local originalReward = nil;
|
||||
local originalSeek = nil;
|
||||
local bazaarActor = nil;
|
||||
|
||||
--Get the bazaar actor
|
||||
if (bazaarActorId ~= nil) then
|
||||
bazaarActor = player:GetZone():FindActorInArea(bazaarActorId);
|
||||
end
|
||||
|
||||
--Abort if no actor
|
||||
if (bazaarActor == nil) then
|
||||
player:SendGameMessage(player, worldMaster, 25111, 0x20);
|
||||
player:EndEvent();
|
||||
return;
|
||||
end
|
||||
|
||||
--If seekItem is a number, we are buying an item (ExecuteBazaarBuy)
|
||||
if (type(seekItemOrCost) == "number") then
|
||||
if (player:GetCurrentGil() >= seekItemOrCost) then
|
||||
if (GetWorldManager():BazaarBuyOperation(bazaarActor, player, bazaarActor:GetItem(rewardItem), rewardAmount, seekItemOrCost)) then
|
||||
else
|
||||
player:SendGameMessage(player, worldMaster, 25111, 0x20);
|
||||
end
|
||||
else
|
||||
player:SendGameMessage(player, worldMaster, 40252, 0x20);
|
||||
end
|
||||
else --Else we are fufilling a sought out item (ExecuteBazaarSell)
|
||||
local rewardItem = bazaarActor:GetItem(rewardItem);
|
||||
local seekItem = player:GetItem(seekItemOrCost);
|
||||
if (rewardItem ~= nil and seekItem ~= nil) then
|
||||
if (GetWorldManager():BazaarSellOperation(bazaarActor, player, rewardItem, rewardAmount, seekItem, seekAmount)) then
|
||||
else
|
||||
player:SendGameMessage(player, worldMaster, 25111, 0x20);
|
||||
end
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
player:EndEvent();
|
||||
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
--[[
|
||||
|
||||
BazaarUndealCommand Script
|
||||
|
||||
Handles canceling bazaar items
|
||||
|
||||
25107 - Your bazaar is either full or already contains that unique item.
|
||||
25111 - Unable to complete transaction.
|
||||
25112 - You are unable to remove the item from your bazaar. You cannot hold any more items.
|
||||
25113 - Offered and sought items cannot be identical.
|
||||
25114 - Items in less than mint condition cannot be offered.
|
||||
25115 - Items in less than mint condition cannot be placed in your bazaar.
|
||||
|
||||
--]]
|
||||
|
||||
function onEventStarted(player, actor, triggerName, rewardItem, seekItem, bazaarType, narg, bazaarActor, rewardAmount, seekAmount, narg, narg, type9ItemIds)
|
||||
|
||||
GetWorldManager():RemoveFromBazaar(player, player:GetItem(rewardItem));
|
||||
|
||||
player:EndEvent();
|
||||
|
||||
end
|
||||
File renamed without changes.
@@ -0,0 +1,6 @@
|
||||
function onEventStarted(player, caller, commandRequest, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
|
||||
player:SetCurrentJob(17);
|
||||
|
||||
player:EndEvent();
|
||||
end
|
||||
File renamed without changes.
+7
-3
@@ -29,10 +29,14 @@ function onEventStarted(player, actor, triggerName, isGoobbue)
|
||||
|
||||
worldMaster = GetWorldMaster();
|
||||
|
||||
if (player:GetMountState() == 1) then
|
||||
player:SendGameMessage(player, worldMaster, 26003, 0x20);
|
||||
if (player.rentalExpireTime != 0) then
|
||||
player:SendGameMessage(player, worldMaster, 26004, 0x20); --You dismount.
|
||||
else
|
||||
player:SendGameMessage(player, worldMaster, 26021, 0x20);
|
||||
if (player:GetMountState() == 1) then
|
||||
player:SendGameMessage(player, worldMaster, 26003, 0x20); --You dismount X.
|
||||
else
|
||||
player:SendGameMessage(player, worldMaster, 26021, 0x20); --You dismount your Gobbue.
|
||||
end
|
||||
end
|
||||
|
||||
player:SetMountState(0);
|
||||
File renamed without changes.
Loaded 100 of 1927 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user