mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	Compare commits
	
		
			475 Commits
		
	
	
		
			master
			...
			ioncannon/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 63f0b024ac | ||
|  | 67db1035ed | ||
|  | c865975df7 | ||
|  | aef0f2b400 | ||
|  | 16c62a08d8 | ||
|  | 6cb107870f | ||
|  | 9a2f8ef89a | ||
|  | 524f415b44 | ||
|  | 5c0d2c1d7f | ||
|  | a7b1b79461 | ||
|  | c3b4735cc5 | ||
|  | ac22637b4f | ||
|  | 01d05b5cee | ||
|  | d50bfef2e5 | ||
|  | a5a039ce3d | ||
|  | 514610f006 | ||
|  | 159242068d | ||
|  | a6ee42094c | ||
|  | 6bbe272d48 | ||
|  | 938cca0298 | ||
|  | e53e54b4bf | ||
|  | f6ff56299f | ||
|  | a1bb84e80d | ||
|  | 4d2c80a8ee | ||
|  | c2169576c2 | ||
|  | 4d424e57f9 | ||
|  | 4494b30285 | ||
|  | 74713f3dd6 | ||
|  | b08827568c | ||
|  | b34f214e67 | ||
|  | e94c037fb5 | ||
|  | 65ee91e49c | ||
|  | 01ec313ffb | ||
|  | ebba56602c | ||
|  | 49c6fdbd51 | ||
|  | 08557f41fb | ||
|  | a618e69dbd | ||
|  | 02fe9e070d | ||
|  | bf20993e58 | ||
|  | 2817560217 | ||
|  | 765cf194c5 | ||
|  | b57f91470a | ||
|  | 2cb6a9f6bd | ||
|  | b773098abf | ||
|  | f491c63b98 | ||
|  | 023527efa3 | ||
|  | 96f9119cca | ||
|  | f84899ff2e | ||
|  | a87244d13b | ||
|  | c5198783a1 | ||
|  | b9ab842fdd | ||
|  | e8ee907477 | ||
|  | b4227cdc44 | ||
|  | 59f4e4bbd5 | ||
|  | c9f18f5415 | ||
|  | 495bdf4ba6 | ||
|  | b46160763c | ||
|  | 3393eb4c9d | ||
|  | 7de153dde1 | ||
|  | 0faa056589 | ||
|  | 90115f7c83 | ||
|  | 682ddd9cae | ||
|  | 8c70d0ddb6 | ||
|  | 5c49563790 | ||
|  | c6a372ad83 | ||
|  | d2e814b4ee | ||
|  | 0cdeb5d9ac | ||
|  | fac8f269e7 | ||
|  | d06152be07 | ||
|  | 0b67f8e436 | ||
|  | 7fea45e1f8 | ||
|  | 696d355ae9 | ||
|  | bbbab356af | ||
|  | 594e08f990 | ||
|  | 89287844f7 | ||
|  | c240096eb8 | ||
|  | 08e7a9cfd4 | ||
|  | 25f1b0fd95 | ||
|  | c677479a03 | ||
|  | 306f4ef346 | ||
|  | a2c4d077e9 | ||
|  | 7e5ca6e013 | ||
|  | 02cb0a3f43 | ||
|  | dc1458c52d | ||
|  | 1523ae200b | ||
|  | aae051d73f | ||
|  | 9097e557ed | ||
|  | cfe6ef2e5e | ||
|  | d26aaed953 | ||
|  | 8d5f4465e3 | ||
|  | 214d730a58 | ||
|  | b6c9825b2d | ||
|  | acf953e909 | ||
|  | 4fe8f77887 | ||
|  | 96cb8070be | ||
|  | 9f077190a3 | ||
|  | 0465bf6b8d | ||
|  | 0ac53e23ad | ||
|  | e6d5d5a530 | ||
|  | 335efcc81e | ||
|  | fb9d4026a5 | ||
|  | 68a2685cf1 | ||
|  | 8b3431e557 | ||
|  | b11007b263 | ||
|  | 2cbb48621b | ||
|  | f574f5b103 | ||
|  | 8d647ae6b0 | ||
|  | f374ee3be9 | ||
|  | 37d04344ae | ||
|  | 68e55a1c76 | ||
|  | 4e0cf36552 | ||
|  | 4e5a07afa4 | ||
|  | 563118372a | ||
|  | 4fc5762d41 | ||
|  | 56ba641e2a | ||
|  | 3ad30460d8 | ||
|  | ff074c8394 | ||
|  | bad51717c2 | ||
|  | 26fd79bea5 | ||
|  | 6e869af4fb | ||
|  | 93c90df797 | ||
|  | c38caffaf1 | ||
|  | 958a87edf2 | ||
|  | 2279ee7017 | ||
|  | df49eefadb | ||
|  | 6e1f13d17a | ||
|  | bbf49123b6 | ||
|  | 48d996bd4f | ||
|  | 8ddcd24704 | ||
|  | 1c5fd48d03 | ||
|  | 31ec4efdcf | ||
|  | 20b1ec18a9 | ||
|  | 41b891feaf | ||
|  | 47a2eddaf0 | ||
|  | 2e5cf8dfec | ||
|  | eecb5ac8a1 | ||
|  | 99c8aff702 | ||
|  | d588dd0348 | ||
|  | 7883143089 | ||
|  | c753e61b62 | ||
|  | 42f0046ee7 | ||
|  | aa54fb11cc | ||
|  | e4d43d952b | ||
|  | ae3a6f1b27 | ||
|  | 5724cf53bf | ||
|  | 0ec9c5576c | ||
|  | 96641865bc | ||
|  | ea7bf4b86d | ||
|  | 94d1915acb | ||
|  | 02e41f6103 | ||
|  | b627ecf0fe | ||
|  | ca4f00cfe3 | ||
|  | 8687e43191 | ||
|  | d3027c3b26 | ||
|  | afd056d82d | ||
|  | e6802d514c | ||
|  | 66ed26617d | ||
|  | f5bf5956b2 | ||
|  | c14b117947 | ||
|  | 91549bff7a | ||
|  | 18ef69f3d1 | ||
|  | 104f3daf7c | ||
|  | b85b35a2b6 | ||
|  | 0f61c4c0e1 | ||
|  | 7587a6e142 | ||
|  | 8940e65885 | ||
|  | 29ec6a9a88 | ||
|  | 3e26c491d4 | ||
|  | 9fd0e96b0e | ||
|  | a9619a4b3c | ||
|  | 8276c5c247 | ||
|  | e9b3f4e51e | ||
|  | 187d8300b0 | ||
|  | 8da65938b7 | ||
|  | a92b558c88 | ||
|  | 57f3de66f8 | ||
|  | 561114833c | ||
|  | 324026874a | ||
|  | dbdff59e0f | ||
|  | a996797beb | ||
|  | 32330d557c | ||
|  | ec85cfd590 | ||
|  | 89c6191710 | ||
|  | eb43a7523d | ||
|  | f5ebb3fb3b | ||
|  | 8a03c40af9 | ||
|  | a07aa12783 | ||
|  | e91960040c | ||
|  | fea8638775 | ||
|  | c286df6a91 | ||
|  | 3dcd9af6c0 | ||
|  | 4fbc388457 | ||
|  | f2e34174c4 | ||
|  | 90078eb2e8 | ||
|  | 7339e08172 | ||
|  | 1fddfd50a6 | ||
|  | 2e906ae090 | ||
|  | 8ba3c195f2 | ||
|  | e96cc0c758 | ||
|  | 2195b0b7dc | ||
|  | ecf07317fc | ||
|  | 69d4b19979 | ||
|  | fdb767f155 | ||
|  | e1c86a4898 | ||
|  | 88ff22e55e | ||
|  | d49516c03e | ||
|  | 42ee97d467 | ||
|  | 8f92fde00e | ||
|  | 3104478263 | ||
|  | a92ece58c1 | ||
|  | 6fcfd58b33 | ||
|  | 905cbf7d3c | ||
|  | 4c850ea768 | ||
|  | afe1e59889 | ||
|  | f3fe8c1de8 | ||
|  | 4e054ca947 | ||
|  | eb949a8602 | ||
|  | 315452d121 | ||
|  | 1a9a8c2116 | ||
|  | 97dcd765eb | ||
|  | e00bb48386 | ||
|  | ef117204b3 | ||
|  | 9cda72f1ab | ||
|  | a99a129d9a | ||
|  | 6ae181fa0a | ||
|  | 1f3c98312c | ||
|  | db0aac3647 | ||
|  | 00017468cc | ||
|  | 4f80023156 | ||
|  | 6127ad44cc | ||
|  | d7c383d04a | ||
|  | 357805d04c | ||
|  | 706a9fa721 | ||
|  | 289e4dc24b | ||
|  | a458608322 | ||
|  | 3e58cdbd6c | ||
|  | 3068a0c41b | ||
|  | 26ef649a6c | ||
|  | cc07e1f453 | ||
|  | 75c6708ac5 | ||
|  | ee1f4b0888 | ||
|  | f6104812a5 | ||
|  | d0dca62a91 | ||
|  | 3b451849ae | ||
|  | 9889b6011b | ||
|  | 9b566abb3d | ||
|  | 37cca32de8 | ||
|  | 02e1b8a82f | ||
|  | 267961233f | ||
|  | d673670604 | ||
|  | b955c38a2a | ||
|  | 044d7e5207 | ||
|  | c1fdad2156 | ||
|  | f038b525c6 | ||
|  | bcb609e4f6 | ||
|  | 163f240cf9 | ||
|  | 3066efeebb | ||
|  | 10017b7e8c | ||
|  | 1e4a1cf263 | ||
|  | 080f9ea23d | ||
|  | e236e1d207 | ||
|  | 1b69f5fc87 | ||
|  | e4956edf50 | ||
|  | 384d134f1d | ||
|  | f361ee61cd | ||
|  | 7e6e51c6bf | ||
|  | 5bdc760a5f | ||
|  | 83ae7df6d9 | ||
|  | 7c7742fb35 | ||
|  | c55145d715 | ||
|  | 42aa3d7512 | ||
|  | 07c467e1af | ||
|  | bec0cae0eb | ||
|  | 5bb3cc3b4e | ||
|  | d614ea6968 | ||
|  | 1579aa3d6a | ||
|  | cf30eef39e | ||
|  | 8c5375f609 | ||
|  | c442dc9ecd | ||
|  | ace4dfe58f | ||
|  | 79f2edf406 | ||
|  | 0209f3e617 | ||
|  | e799e8327f | ||
|  | 0f7e6f359d | ||
|  | 0739532c7d | ||
|  | d23a84d6cf | ||
|  | 8de606051a | ||
|  | a7e59fa7e4 | ||
|  | 922fb80f3d | ||
|  | 8c9f841d63 | ||
|  | c5ce2ec771 | ||
|  | 0492bc4c59 | ||
|  | 7abfbd5953 | ||
|  | 1d3dd99414 | ||
|  | c3c19c3592 | ||
|  | a19517cce4 | ||
|  | 880b1f3066 | ||
|  | 0b13b590a0 | ||
|  | 8aeaee1b19 | ||
|  | 29e3f61b6b | ||
|  | bbd4fcef3b | ||
|  | 13727caf14 | ||
|  | aba748cb5d | ||
|  | 611140568e | ||
|  | 08dfd22bfa | ||
|  | 5fd48fad6b | ||
|  | 7e2246e8d8 | ||
|  | 1e9d61c838 | ||
|  | b8d6a943aa | ||
|  | f30360f245 | ||
|  | 359ea8a40e | ||
|  | 127ac15936 | ||
|  | 0cb2fe1a68 | ||
|  | c0312079ef | ||
|  | a9d4e621e3 | ||
|  | 08c5980b22 | ||
|  | f5ea82f735 | ||
|  | 81c97105b7 | ||
|  | 837c7a9223 | ||
|  | cd60c571ac | ||
|  | 205d3619d6 | ||
|  | 1275c8b5da | ||
|  | b2e273d7cf | ||
|  | 88233cf6d2 | ||
|  | 05eca7f22e | ||
|  | 7a02d38e94 | ||
|  | af121f52bd | ||
|  | e8c9904e1d | ||
|  | bbac4b0fce | ||
|  | 3850860440 | ||
|  | bb31bb0f23 | ||
|  | b191da416b | ||
|  | 2a489953db | ||
|  | fe4b9cb2bf | ||
|  | 95b003cc2b | ||
|  | 27200b8df5 | ||
|  | 520ae7a119 | ||
|  | 460722d3d5 | ||
|  | 92de857cda | ||
|  | 4323eb5385 | ||
|  | 324ebab2d2 | ||
|  | 5ccc2435b0 | ||
|  | 13708a2361 | ||
|  | 59e3b2379a | ||
|  | 9fc99faa5c | ||
|  | 116a573f85 | ||
|  | a0c4d80c5e | ||
|  | 8ae4fbc045 | ||
|  | e819603432 | ||
|  | bab81a809c | ||
|  | 441c1a6383 | ||
|  | 58334a0e5f | ||
|  | 94491903f7 | ||
|  | f3a823af03 | ||
|  | 5dfbc0f249 | ||
|  | ab98f3662f | ||
|  | 33f8709d76 | ||
|  | 56491266cc | ||
|  | c7e38b8b00 | ||
|  | 9649d755a9 | ||
|  | e581727625 | ||
|  | 06e0c32062 | ||
|  | 77203bca4c | ||
|  | 7b1f95cd77 | ||
|  | ba8184db89 | ||
|  | da621dfc0e | ||
|  | ce5030acd1 | ||
|  | a309e651da | ||
|  | 16e99040e0 | ||
|  | 3f82ca1244 | ||
|  | 8f487689ba | ||
|  | b092d447cc | ||
|  | 4160622556 | ||
|  | 64006d2351 | ||
|  | 52c707d66e | ||
|  | 9174801fdb | ||
|  | 9529a1374e | ||
|  | 8755ca4f33 | ||
|  | a14e36fadc | ||
|  | bc95c139de | ||
|  | 40ad1d8a29 | ||
|  | 76f073d85f | ||
|  | 9077c60b96 | ||
|  | 645a1fb4fb | ||
|  | 7c30b95c4b | ||
|  | 2bfaf376ef | ||
|  | 68a2d5f0b9 | ||
|  | 5bec522c8e | ||
|  | 81d82cd7a8 | ||
|  | f437b36f5a | ||
|  | b5054debea | ||
|  | 4e39b082f1 | ||
|  | 62484e2f87 | ||
|  | 50b4f517f2 | ||
|  | 2b5a6997f4 | ||
|  | 4978813c27 | ||
|  | 6e1983031b | ||
|  | c5cc7c2f00 | ||
|  | c55acba1b6 | ||
|  | 4c7928da78 | ||
|  | 517bdc0638 | ||
|  | 2cee5ff573 | ||
|  | c3fd8f917e | ||
|  | 91afda04ca | ||
|  | e60da4f7b4 | ||
|  | 67485eafc0 | ||
|  | d81832f256 | ||
|  | 7ad40f625a | ||
|  | 71d5bbc9ff | ||
|  | 37b8203dae | ||
|  | f4016e1a12 | ||
|  | 6c74222b68 | ||
|  | 6f5a480cbd | ||
|  | 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 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,6 @@ | |||||||
| *.userprefs | *.userprefs | ||||||
|  |  | ||||||
| # Build results | # Build results | ||||||
| [Dd]ebug/ |  | ||||||
| [Dd]ebugPublic/ | [Dd]ebugPublic/ | ||||||
| [Rr]elease/ | [Rr]elease/ | ||||||
| [Rr]eleases/ | [Rr]eleases/ | ||||||
|   | |||||||
| @@ -1,13 +1,35 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
|  | 
 | ||||||
|  | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||||
|  | 
 | ||||||
|  | using Ionic.Zlib; | ||||||
| using NLog; | using NLog; | ||||||
| using NLog.Targets; | using NLog.Targets; | ||||||
| using Ionic.Zlib; |  | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | namespace Meteor.Common | ||||||
| { | { | ||||||
|     [StructLayout(LayoutKind.Sequential)] |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     public struct BasePacketHeader |     public struct BasePacketHeader | ||||||
| @@ -239,7 +261,14 @@ namespace FFXIVClassic.Common | |||||||
|             { |             { | ||||||
|                 var subpacketData = subpacket.GetBytes(); |                 var subpacketData = subpacket.GetBytes(); | ||||||
|                 Array.Copy(subpacketData, 0, data, offset, subpacketData.Length); |                 Array.Copy(subpacketData, 0, data, offset, subpacketData.Length); | ||||||
|                 offset += (ushort) subpacketData.Length; |                 offset += (ushort)subpacketData.Length; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //Compress this array into a new one if needed | ||||||
|  |             if (isCompressed) | ||||||
|  |             { | ||||||
|  |                 data = CompressData(data); | ||||||
|  |                 header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset); |             Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset); | ||||||
| @@ -266,7 +295,15 @@ namespace FFXIVClassic.Common | |||||||
|             data = new byte[header.packetSize - 0x10]; |             data = new byte[header.packetSize - 0x10]; | ||||||
| 
 | 
 | ||||||
|             //Add Subpackets |             //Add Subpackets | ||||||
|             var subpacketData = subpacket.GetBytes(); |             byte[] subpacketData = subpacket.GetBytes(); | ||||||
|  | 
 | ||||||
|  |             //Compress this array into a new one if needed | ||||||
|  |             if (isCompressed) | ||||||
|  |             { | ||||||
|  |                 subpacketData = CompressData(subpacketData); | ||||||
|  |                 header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             Array.Copy(subpacketData, 0, data, 0, subpacketData.Length); |             Array.Copy(subpacketData, 0, data, 0, subpacketData.Length); | ||||||
| 
 | 
 | ||||||
|             Debug.Assert(data != null); |             Debug.Assert(data != null); | ||||||
| @@ -291,6 +328,13 @@ namespace FFXIVClassic.Common | |||||||
|             //Get packet size |             //Get packet size | ||||||
|             header.packetSize += (ushort) data.Length; |             header.packetSize += (ushort) data.Length; | ||||||
| 
 | 
 | ||||||
|  |             //Compress this array into a new one if needed | ||||||
|  |             if (isCompressed) | ||||||
|  |             { | ||||||
|  |                 data = CompressData(data); | ||||||
|  |                 header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             var packet = new BasePacket(header, data); |             var packet = new BasePacket(header, data); | ||||||
|             return packet; |             return packet; | ||||||
|         } |         } | ||||||
| @@ -390,17 +434,31 @@ namespace FFXIVClassic.Common | |||||||
|             { |             { | ||||||
|                 zipStream.CopyTo(resultStream); |                 zipStream.CopyTo(resultStream); | ||||||
|                 packet.data = resultStream.ToArray(); |                 packet.data = resultStream.ToArray(); | ||||||
|  |                 packet.header.isCompressed = 0; | ||||||
|  |                 packet.header.packetSize = (ushort)(BASEPACKET_SIZE + packet.data.Length); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public static unsafe void CompressPacket(ref BasePacket packet) |         public static unsafe BasePacket CompressPacket(BasePacket uncompressedPacket) | ||||||
|         { |         { | ||||||
|             using (var compressedStream = new MemoryStream(packet.data)) |             using (var compressedStream = new MemoryStream(uncompressedPacket.data)) | ||||||
|             using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress)) |             using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress)) | ||||||
|             using (var resultStream = new MemoryStream()) |             using (var resultStream = new MemoryStream()) | ||||||
|             { |             { | ||||||
|                 zipStream.CopyTo(resultStream); |                 zipStream.CopyTo(resultStream); | ||||||
|                 packet.data = resultStream.ToArray(); |                 BasePacket compressedPacket = BasePacket.CreatePacket(resultStream.ToArray(), uncompressedPacket.header.isAuthenticated == 1, true); | ||||||
|  |                 return compressedPacket; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static unsafe byte[] CompressData(byte[] data) | ||||||
|  |         { | ||||||
|  |             using (var compressedStream = new MemoryStream(data)) | ||||||
|  |             using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress)) | ||||||
|  |             using (var resultStream = new MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 zipStream.CopyTo(resultStream); | ||||||
|  |                 return resultStream.ToArray(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @@ -1,6 +1,27 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | 
 | ||||||
|  | namespace Meteor.Common | ||||||
| { | { | ||||||
|     [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] |     [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] | ||||||
|     public sealed class BitfieldLengthAttribute : Attribute |     public sealed class BitfieldLengthAttribute : Attribute | ||||||
| @@ -60,7 +81,7 @@ namespace FFXIVClassic.Common | |||||||
|                     // Calculate a bitmask of the desired length |                     // Calculate a bitmask of the desired length | ||||||
|                     long mask = 0; |                     long mask = 0; | ||||||
|                     for (int i = 0; i < fieldLength; i++) |                     for (int i = 0; i < fieldLength; i++) | ||||||
|                         mask |= 1 << i; |                         mask |= 1L << i; | ||||||
| 
 | 
 | ||||||
|                     r |= ((UInt32)f.GetValue(t) & mask) << offset; |                     r |= ((UInt32)f.GetValue(t) & mask) << offset; | ||||||
| 
 | 
 | ||||||
							
								
								
									
										204
									
								
								Common Class Lib/Bitstream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								Common Class Lib/Bitstream.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Meteor.Common | ||||||
|  | { | ||||||
|  |     public class Bitstream | ||||||
|  |     { | ||||||
|  |         private byte[] Data; | ||||||
|  |  | ||||||
|  |         public Bitstream(uint numBits, bool setAllTrue = false) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(numBits % 8 == 0); | ||||||
|  |             Debug.Assert(numBits % 4 == 0); | ||||||
|  |             Data = new byte[numBits / 8]; | ||||||
|  |  | ||||||
|  |             if (setAllTrue) | ||||||
|  |                 SetAll(true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Bitstream(bool[] boolArray) | ||||||
|  |         { | ||||||
|  |             Data = Utils.ConvertBoolArrayToBinaryStream(boolArray); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private Bitstream(byte[] byteArray) | ||||||
|  |         { | ||||||
|  |             Data = byteArray; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetAll(bool to) | ||||||
|  |         { | ||||||
|  |             for (int i = 0; i < Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] = Data[i + 1] = Data[i + 2] = Data[i + 3] = (byte)(to ? 0xFF : 0x00); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetTo(Bitstream result) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(Data.Length == result.Data.Length); | ||||||
|  |             for (int i = 0; i < result.Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] = result.Data[i]; | ||||||
|  |                 Data[i + 1] = result.Data[i + 1]; | ||||||
|  |                 Data[i + 2] = result.Data[i + 2]; | ||||||
|  |                 Data[i + 3] = result.Data[i + 3]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetTo(bool[] result) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(Data.Length == result.Length / 8); | ||||||
|  |             Data = Utils.ConvertBoolArrayToBinaryStream(result); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool Get(uint at) | ||||||
|  |         { | ||||||
|  |             return Get((int)at); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool Get(int at) | ||||||
|  |         { | ||||||
|  |             int bytePos = at / 8; | ||||||
|  |             int bitPos = at % 8; | ||||||
|  |  | ||||||
|  |             return (Data[bytePos] & (1 << bitPos)) != 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Set(uint at) | ||||||
|  |         { | ||||||
|  |             Set((int)at); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Set(int at) | ||||||
|  |         { | ||||||
|  |             int bytePos = at / 8; | ||||||
|  |             int bitPos = at % 8; | ||||||
|  |             Data[bytePos] |= (byte)(1 << bitPos); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Clear(uint at) | ||||||
|  |         { | ||||||
|  |             Clear((int)at); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Clear(int at) | ||||||
|  |         { | ||||||
|  |             int bytePos = at / 8; | ||||||
|  |             int bitPos = at % 8; | ||||||
|  |             Data[bytePos] &= (byte)~(1 << bitPos); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void NOT() | ||||||
|  |         { | ||||||
|  |             for (int i = 0; i < Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] = (byte)~Data[i]; | ||||||
|  |                 Data[i + 1] = (byte)~Data[i + 1]; | ||||||
|  |                 Data[i + 2] = (byte)~Data[i + 2]; | ||||||
|  |                 Data[i + 3] = (byte)~Data[i + 3]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void OR(Bitstream other) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(Data.Length == other.Data.Length); | ||||||
|  |             for (int i = 0; i < Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] |= other.Data[i]; | ||||||
|  |                 Data[i + 1] |= other.Data[i + 1]; | ||||||
|  |                 Data[i + 2] |= other.Data[i + 2]; | ||||||
|  |                 Data[i + 3] |= other.Data[i + 3]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void AND(Bitstream other) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(Data.Length == other.Data.Length); | ||||||
|  |             for (int i = 0; i < Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] &= other.Data[i]; | ||||||
|  |                 Data[i + 1] &= other.Data[i + 1]; | ||||||
|  |                 Data[i + 2] &= other.Data[i + 2]; | ||||||
|  |                 Data[i + 3] &= other.Data[i + 3]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void XOR(Bitstream other) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(Data.Length == other.Data.Length); | ||||||
|  |             for (int i = 0; i < Data.Length; i += 4) | ||||||
|  |             { | ||||||
|  |                 Data[i] ^= other.Data[i]; | ||||||
|  |                 Data[i + 1] ^= other.Data[i + 1]; | ||||||
|  |                 Data[i + 2] ^= other.Data[i + 2]; | ||||||
|  |                 Data[i + 3] ^= other.Data[i + 3]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Bitstream Copy() | ||||||
|  |         { | ||||||
|  |             byte[] copy = new byte[Data.Length]; | ||||||
|  |             Array.Copy(Data, copy, Data.Length); | ||||||
|  |             return new Bitstream(copy); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public byte[] GetBytes() | ||||||
|  |         { | ||||||
|  |             return Data; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public byte[] GetSlice(ushort from, ushort to) | ||||||
|  |         { | ||||||
|  |             int remainder = ((to - from) % 8 != 0) ? 1 : 0; | ||||||
|  |             byte[] toReturn = new byte[((to - from) / 8) + remainder + 1]; | ||||||
|  |             toReturn[toReturn.Length - 1] = 0x3; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             byte curByte = 0; | ||||||
|  |  | ||||||
|  |             int destByteIndx = 0; | ||||||
|  |             int destShiftIndx = 0; | ||||||
|  |             int srcByteIndx = from / 8; | ||||||
|  |             int srcShiftIndx = from % 8; | ||||||
|  |  | ||||||
|  |             for (int i = from; i <= to; i++) | ||||||
|  |             { | ||||||
|  |                 // Skip Zeros | ||||||
|  |                 if (Data[srcByteIndx] == 0) | ||||||
|  |                 { | ||||||
|  |                     srcByteIndx++; | ||||||
|  |                     srcShiftIndx = 0; | ||||||
|  |                     destByteIndx++; | ||||||
|  |                     i += 8; | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 bool val = (Data[srcByteIndx] & (1 << srcShiftIndx++)) != 0; | ||||||
|  |  | ||||||
|  |                 curByte |= (byte)((val ? 1 : 0) << destShiftIndx++); | ||||||
|  |                 if (srcShiftIndx == 8) | ||||||
|  |                 { | ||||||
|  |                     srcShiftIndx = 0; | ||||||
|  |                     srcByteIndx++; | ||||||
|  |                 } | ||||||
|  |                 if (destShiftIndx == 8) | ||||||
|  |                 { | ||||||
|  |                     toReturn[destByteIndx++] = curByte; | ||||||
|  |                     destShiftIndx = 0; | ||||||
|  |                     curByte = 0; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (destByteIndx == toReturn.Length - 2) | ||||||
|  |                 toReturn[destByteIndx] = curByte; | ||||||
|  |  | ||||||
|  |             return toReturn; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,6 +1,27 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | 
 | ||||||
|  | namespace Meteor.Common | ||||||
| { | { | ||||||
|     public class Blowfish |     public class Blowfish | ||||||
|     {    |     {    | ||||||
| @@ -8,9 +8,9 @@ | |||||||
|     <ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid> |     <ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid> | ||||||
|     <OutputType>Library</OutputType> |     <OutputType>Library</OutputType> | ||||||
|     <AppDesignerFolder>Properties</AppDesignerFolder> |     <AppDesignerFolder>Properties</AppDesignerFolder> | ||||||
|     <RootNamespace>FFXIVClassic.Common</RootNamespace> |     <RootNamespace>Meteor.Common</RootNamespace> | ||||||
|     <AssemblyName>FFXIVClassic.Common</AssemblyName> |     <AssemblyName>Meteor.Common</AssemblyName> | ||||||
|     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |     <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> | ||||||
|     <FileAlignment>512</FileAlignment> |     <FileAlignment>512</FileAlignment> | ||||||
|     <TargetFrameworkProfile> |     <TargetFrameworkProfile> | ||||||
|     </TargetFrameworkProfile> |     </TargetFrameworkProfile> | ||||||
| @@ -36,6 +36,27 @@ | |||||||
|     <ErrorReport>prompt</ErrorReport> |     <ErrorReport>prompt</ErrorReport> | ||||||
|     <WarningLevel>4</WarningLevel> |     <WarningLevel>4</WarningLevel> | ||||||
|     <Prefer32Bit>false</Prefer32Bit> |     <Prefer32Bit>false</Prefer32Bit> | ||||||
|  |     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> | ||||||
|  |     <DebugSymbols>true</DebugSymbols> | ||||||
|  |     <OutputPath>bin\Debug\</OutputPath> | ||||||
|  |     <DefineConstants>DEBUG;TRACE</DefineConstants> | ||||||
|  |     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||||
|  |     <DebugType>full</DebugType> | ||||||
|  |     <PlatformTarget>x64</PlatformTarget> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> | ||||||
|  |     <OutputPath>bin\x64\Release\</OutputPath> | ||||||
|  |     <DefineConstants>TRACE</DefineConstants> | ||||||
|  |     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||||
|  |     <Optimize>true</Optimize> | ||||||
|  |     <DebugType>pdbonly</DebugType> | ||||||
|  |     <PlatformTarget>x64</PlatformTarget> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Reference Include="DotNetZip"> |     <Reference Include="DotNetZip"> | ||||||
| @@ -46,11 +67,16 @@ | |||||||
|       <Private>True</Private> |       <Private>True</Private> | ||||||
|     </Reference> |     </Reference> | ||||||
|     <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> |     <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> | ||||||
|       <HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath> |       <HintPath>..\packages\NLog.4.5.0\lib\net45\NLog.dll</HintPath> | ||||||
|       <Private>True</Private> |  | ||||||
|     </Reference> |     </Reference> | ||||||
|     <Reference Include="System" /> |     <Reference Include="System" /> | ||||||
|  |     <Reference Include="System.Configuration" /> | ||||||
|     <Reference Include="System.Core" /> |     <Reference Include="System.Core" /> | ||||||
|  |     <Reference Include="System.IO.Compression" /> | ||||||
|  |     <Reference Include="System.Numerics" /> | ||||||
|  |     <Reference Include="System.Runtime.Serialization" /> | ||||||
|  |     <Reference Include="System.ServiceModel" /> | ||||||
|  |     <Reference Include="System.Transactions" /> | ||||||
|     <Reference Include="System.Xml.Linq" /> |     <Reference Include="System.Xml.Linq" /> | ||||||
|     <Reference Include="System.Data.DataSetExtensions" /> |     <Reference Include="System.Data.DataSetExtensions" /> | ||||||
|     <Reference Include="Microsoft.CSharp" /> |     <Reference Include="Microsoft.CSharp" /> | ||||||
| @@ -61,6 +87,7 @@ | |||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Compile Include="BasePacket.cs" /> |     <Compile Include="BasePacket.cs" /> | ||||||
|     <Compile Include="Bitfield.cs" /> |     <Compile Include="Bitfield.cs" /> | ||||||
|  |     <Compile Include="Bitstream.cs" /> | ||||||
|     <Compile Include="Blowfish.cs" /> |     <Compile Include="Blowfish.cs" /> | ||||||
|     <Compile Include="EfficientHashTables.cs" /> |     <Compile Include="EfficientHashTables.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
| @@ -68,6 +95,7 @@ | |||||||
|     <Compile Include="STA_INIFile.cs" /> |     <Compile Include="STA_INIFile.cs" /> | ||||||
|     <Compile Include="SubPacket.cs" /> |     <Compile Include="SubPacket.cs" /> | ||||||
|     <Compile Include="Utils.cs" /> |     <Compile Include="Utils.cs" /> | ||||||
|  |     <Compile Include="Vector3.cs" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="app.config" /> |     <None Include="app.config" /> | ||||||
| @@ -1,6 +1,27 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | 
 | ||||||
|  | namespace Meteor.Common | ||||||
| { | { | ||||||
|     namespace EfficientHashTables |     namespace EfficientHashTables | ||||||
|     { |     { | ||||||
| @@ -1,5 +1,4 @@ | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Runtime.CompilerServices; |  | ||||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||||
| 
 | 
 | ||||||
| // General Information about an assembly is controlled through the following  | // General Information about an assembly is controlled through the following  | ||||||
| @@ -3,13 +3,14 @@ | |||||||
| // ******************************* | // ******************************* | ||||||
| // *** (C)2009-2013 S.T.A. snc *** | // *** (C)2009-2013 S.T.A. snc *** | ||||||
| // ******************************* | // ******************************* | ||||||
|  | 
 | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Globalization; | using System.Globalization; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Text; | using System.Text; | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | namespace Meteor.Common | ||||||
| { | { | ||||||
| 	public class INIFile | 	public class INIFile | ||||||
| 	{ | 	{ | ||||||
							
								
								
									
										33
									
								
								Common Class Lib/Sql.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Common Class Lib/Sql.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
|  |  | ||||||
|  | This file is part of Project Meteor Server. | ||||||
|  |  | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  |  | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  |  | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | using NLog; | ||||||
|  |  | ||||||
|  | namespace Meteor.Common | ||||||
|  | { | ||||||
|  |     // todo: | ||||||
|  |     // havent decided whether it's worth wrapping every sql class | ||||||
|  |     // so i'll just leave it with logger for now | ||||||
|  |     public class Sql | ||||||
|  |     { | ||||||
|  |         public static Logger Log = LogManager.GetCurrentClassLogger(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,10 +1,31 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
|  | 
 | ||||||
|  | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||||
| using FFXIVClassic.Common; | 
 | ||||||
| using NLog; | using NLog; | ||||||
| using NLog.Targets; | using NLog.Targets; | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | namespace Meteor.Common | ||||||
| { | { | ||||||
|     [StructLayout(LayoutKind.Sequential)] |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     public struct SubPacketHeader |     public struct SubPacketHeader | ||||||
| @@ -1,12 +1,34 @@ | |||||||
| using System; | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
|  | 
 | ||||||
|  | This file is part of Project Meteor Server. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Text; | using System.Text; | ||||||
| 
 | 
 | ||||||
| namespace FFXIVClassic.Common | namespace Meteor.Common | ||||||
| { | { | ||||||
|     public static class Utils |     public static class Utils | ||||||
|     { |     { | ||||||
|         private static readonly uint[] _lookup32 = CreateLookup32(); |         private static readonly uint[] _lookup32 = CreateLookup32(); | ||||||
|  |         private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); | ||||||
| 
 | 
 | ||||||
|         private static uint[] CreateLookup32() |         private static uint[] CreateLookup32() | ||||||
|         { |         { | ||||||
| @@ -84,10 +106,10 @@ namespace FFXIVClassic.Common | |||||||
|             return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray()); |             return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public static uint UnixTimeStampUTC() |         public static uint UnixTimeStampUTC(DateTime? time = null) | ||||||
|         { |         { | ||||||
|             uint unixTimeStamp; |             uint unixTimeStamp; | ||||||
|             var currentTime = DateTime.Now; |             var currentTime = time ?? DateTime.Now; | ||||||
|             var zuluTime = currentTime.ToUniversalTime(); |             var zuluTime = currentTime.ToUniversalTime(); | ||||||
|             var unixEpoch = new DateTime(1970, 1, 1); |             var unixEpoch = new DateTime(1970, 1, 1); | ||||||
|             unixTimeStamp = (uint)zuluTime.Subtract(unixEpoch).TotalSeconds; |             unixTimeStamp = (uint)zuluTime.Subtract(unixEpoch).TotalSeconds; | ||||||
| @@ -95,10 +117,10 @@ namespace FFXIVClassic.Common | |||||||
|             return unixTimeStamp; |             return unixTimeStamp; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public static ulong MilisUnixTimeStampUTC() |         public static ulong MilisUnixTimeStampUTC(DateTime? time = null) | ||||||
|         { |         { | ||||||
|             ulong unixTimeStamp; |             ulong unixTimeStamp; | ||||||
|             var currentTime = DateTime.Now; |             var currentTime = time ?? DateTime.Now; | ||||||
|             var zuluTime = currentTime.ToUniversalTime(); |             var zuluTime = currentTime.ToUniversalTime(); | ||||||
|             var unixEpoch = new DateTime(1970, 1, 1); |             var unixEpoch = new DateTime(1970, 1, 1); | ||||||
|             unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds; |             unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds; | ||||||
| @@ -106,6 +128,11 @@ namespace FFXIVClassic.Common | |||||||
|             return unixTimeStamp; |             return unixTimeStamp; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public static DateTime UnixTimeStampToDateTime(uint timestamp) | ||||||
|  |         { | ||||||
|  |             return epoch.AddSeconds(timestamp); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public static ulong SwapEndian(ulong input) |         public static ulong SwapEndian(ulong input) | ||||||
|         { |         { | ||||||
|             return 0x00000000000000FF & (input >> 56) | |             return 0x00000000000000FF & (input >> 56) | | ||||||
| @@ -139,6 +166,12 @@ namespace FFXIVClassic.Common | |||||||
|             return input; |             return input; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public static ushort SwapEndian(ushort input) | ||||||
|  |         { | ||||||
|  |             return (ushort)(((input << 8) & 0xff00) | | ||||||
|  |                             ((input >> 8) & 0x00ff)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public static uint MurmurHash2(string key, uint seed) |         public static uint MurmurHash2(string key, uint seed) | ||||||
|         { |         { | ||||||
|             // 'm' and 'r' are mixing constants generated offline. |             // 'm' and 'r' are mixing constants generated offline. | ||||||
| @@ -212,7 +245,7 @@ namespace FFXIVClassic.Common | |||||||
|             { |             { | ||||||
|                 for (var bitCount = 0; bitCount < 8; bitCount++) |                 for (var bitCount = 0; bitCount < 8; bitCount++) | ||||||
|                 { |                 { | ||||||
|                     if (i + bitCount >= array.Length) |                     if (i + bitCount >= array.Length - 1) | ||||||
|                         break; |                         break; | ||||||
|                     data[dataCounter] = (byte)(((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]); |                     data[dataCounter] = (byte)(((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]); | ||||||
|                 } |                 } | ||||||
| @@ -222,6 +255,26 @@ namespace FFXIVClassic.Common | |||||||
|             return data; |             return data; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public static bool[] ConvertBinaryStreamToBoolArray(byte[] bytes) | ||||||
|  |         { | ||||||
|  |             bool[] data = new bool[bytes.Length * 8]; | ||||||
|  | 
 | ||||||
|  |             int boolCounter = 0; | ||||||
|  |             for (int i = 0; i < bytes.Length; i ++) | ||||||
|  |             { | ||||||
|  |                 if (bytes[i] == 0) | ||||||
|  |                 { | ||||||
|  |                     boolCounter += 8; | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 for (int bitCount = 0; bitCount < 8; bitCount++) | ||||||
|  |                     data[boolCounter++] = (bytes[i] >> bitCount & 1) == 1;                 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return data; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public static string ToStringBase63(int number) |         public static string ToStringBase63(int number) | ||||||
|         { |         { | ||||||
|             var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |             var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||||||
| @@ -232,6 +285,28 @@ namespace FFXIVClassic.Common | |||||||
|             return secondDigit + firstDigit; |             return secondDigit + firstDigit; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public static string ReadNullTermString(BinaryReader reader, int maxSize = 0x20) | ||||||
|  |         { | ||||||
|  |             long pos = reader.BaseStream.Position; | ||||||
|  |             int size = 0; | ||||||
|  |             for (int i = 0; i < maxSize; i++) | ||||||
|  |             { | ||||||
|  |                 if (reader.ReadByte() == 0) | ||||||
|  |                 { | ||||||
|  |                     size = i; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             reader.BaseStream.Seek(pos, SeekOrigin.Begin); | ||||||
|  |             string result =  Encoding.ASCII.GetString(reader.ReadBytes(size)); | ||||||
|  |             reader.BaseStream.Seek(pos + maxSize, SeekOrigin.Begin); | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static void WriteNullTermString(BinaryWriter writer, string value, int maxSize = 0x20) | ||||||
|  |         { | ||||||
|  |             writer.Write(Encoding.ASCII.GetBytes(value), 0, Encoding.ASCII.GetByteCount(value) >= maxSize ? maxSize : Encoding.ASCII.GetByteCount(value)); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         public static string FFXIVLoginStringDecodeBinary(string path) |         public static string FFXIVLoginStringDecodeBinary(string path) | ||||||
|         { |         { | ||||||
| @@ -351,5 +426,95 @@ namespace FFXIVClassic.Common | |||||||
|         { |         { | ||||||
|             return (value >> bits) | (value << (16 - bits)); |             return (value >> bits) | (value << (16 - bits)); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         public static T Clamp<T>(this T value, T min, T max) where T : IComparable<T> | ||||||
|  |         { | ||||||
|  |             if (value.CompareTo(min) < 0) | ||||||
|  |                 return min; | ||||||
|  |             else if (value.CompareTo(max) > 0) | ||||||
|  |                 return max; | ||||||
|  |             else | ||||||
|  |                 return value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static T Min<T>(this T value, T min) where T : IComparable<T> | ||||||
|  |         { | ||||||
|  |             if (value.CompareTo(min) > 0) | ||||||
|  |                 return min; | ||||||
|  |             else | ||||||
|  |                 return value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static T Max<T>(this T value, T max) where T : IComparable<T> | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             if (value.CompareTo(max) < 0) | ||||||
|  |                 return max; | ||||||
|  |             else | ||||||
|  |                 return value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float DistanceSquared(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return DistanceSquared(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float Distance(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return Distance(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float Distance(float x, float y, float z, float x2, float y2, float z2) | ||||||
|  |         { | ||||||
|  |             if (x == x2 && y == y2 && z == z2) | ||||||
|  |                 return 0.0f; | ||||||
|  | 
 | ||||||
|  |             return (float)Math.Sqrt(DistanceSquared(x, y, z, x2, y2, z2)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float DistanceSquared(float x, float y, float z, float x2, float y2, float z2) | ||||||
|  |         { | ||||||
|  |             if (x == x2 && y == y2 && z == z2) | ||||||
|  |                 return 0.0f; | ||||||
|  | 
 | ||||||
|  |             // todo: my maths is shit | ||||||
|  |             var dx = x - x2; | ||||||
|  |             var dy = y - y2; | ||||||
|  |             var dz = z - z2; | ||||||
|  | 
 | ||||||
|  |             return dx * dx + dy * dy + dz * dz; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Distance of just the x and z valeus, ignoring y | ||||||
|  |         public static float XZDistanceSquared(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return XZDistanceSquared(lhs.X, lhs.Z, rhs.X, rhs.Z); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float XZDistance(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return XZDistance(lhs.X, lhs.Z, rhs.X, rhs.Z); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static float XZDistance(float x, float z, float x2, float z2) | ||||||
|  |         { | ||||||
|  |             if (x == x2 && z == z2) | ||||||
|  |                 return 0.0f; | ||||||
|  | 
 | ||||||
|  |             return (float)Math.Sqrt(XZDistanceSquared(x, z, x2, z2)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         public static float XZDistanceSquared(float x, float z, float x2, float z2) | ||||||
|  |         { | ||||||
|  |             if (x == x2 && z == z2) | ||||||
|  |                 return 0.0f; | ||||||
|  | 
 | ||||||
|  |             // todo: mz maths is shit | ||||||
|  |             var dx = x - x2; | ||||||
|  |             var dz = z - z2; | ||||||
|  | 
 | ||||||
|  |             return dx * dx + dz * dz; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										180
									
								
								Common Class Lib/Vector3.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Common Class Lib/Vector3.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | |||||||
|  | /* | ||||||
|  | =========================================================================== | ||||||
|  | Copyright (C) 2015-2019 Project Meteor Dev Team | ||||||
|  |  | ||||||
|  | This file is part of Project Meteor Server. | ||||||
|  |  | ||||||
|  | Project Meteor Server is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  |  | ||||||
|  | Project Meteor Server is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | GNU Affero General Public License for more details. | ||||||
|  |  | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>. | ||||||
|  | =========================================================================== | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Meteor.Common | ||||||
|  | { | ||||||
|  |     public class Vector3 | ||||||
|  |     { | ||||||
|  |         public float X; | ||||||
|  |         public float Y; | ||||||
|  |         public float Z; | ||||||
|  |         public static Vector3 Zero = new Vector3(); | ||||||
|  |  | ||||||
|  |         public Vector3(float x, float y, float z) | ||||||
|  |         { | ||||||
|  |             X = x; | ||||||
|  |             Y = y; | ||||||
|  |             Z = z; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Vector3() | ||||||
|  |         { | ||||||
|  |             X = 0.0f; | ||||||
|  |             Y = 0.0f; | ||||||
|  |             Z = 0.0f; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Vector3 operator +(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             Vector3 newVec = new Vector3(lhs.X, lhs.Y, lhs.Z); | ||||||
|  |             newVec.X += rhs.X; | ||||||
|  |             newVec.Y += rhs.Y; | ||||||
|  |             newVec.Z += rhs.Z; | ||||||
|  |             return newVec; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Vector3 operator -(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return new Vector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Vector3 operator *(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return new Vector3(lhs.X * rhs.X, lhs.Y * rhs.Y, lhs.Z * rhs.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Vector3 operator *(float scalar, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return new Vector3(scalar * rhs.X, scalar * rhs.Y, scalar * rhs.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Vector3 operator /(Vector3 lhs, float scalar) | ||||||
|  |         { | ||||||
|  |             return new Vector3(lhs.X / scalar, lhs.Y / scalar, lhs.Z / scalar); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static bool operator !=(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return !(lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static bool operator ==(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return (lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z); | ||||||
|  |         }      | ||||||
|  |  | ||||||
|  |         public float Length() | ||||||
|  |         { | ||||||
|  |             return (float)Math.Sqrt(this.LengthSquared()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public float LengthSquared() | ||||||
|  |         { | ||||||
|  |             return (this.X * this.X) + (this.Y * this.Y) + (this.Z * this.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static float Dot(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return (lhs.X * rhs.X) + (lhs.Y * rhs.Y) + (lhs.Z * rhs.Z); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static float GetAngle(Vector3 lhs, Vector3 rhs) | ||||||
|  |         { | ||||||
|  |             return GetAngle(lhs.X, lhs.Z, rhs.X, rhs.Z);  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static float GetAngle(float x, float z, float x2, float z2) | ||||||
|  |         { | ||||||
|  |             if (x == x2) | ||||||
|  |                 return 0.0f; | ||||||
|  |  | ||||||
|  |             var angle = (float)(Math.Atan((z2 - z) / (x2 - x))); | ||||||
|  |             return (float)(x > x2 ? angle + Math.PI : angle); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Vector3 NewHorizontalVector(float angle, float extents) | ||||||
|  |         { | ||||||
|  |             var newVec = new Vector3(); | ||||||
|  |             newVec.Y = this.Y; | ||||||
|  |             newVec.X = this.X + (float)Math.Cos(angle) * extents; | ||||||
|  |             newVec.Z = this.Z + (float)Math.Sin(angle) * extents; | ||||||
|  |  | ||||||
|  |             return newVec; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool IsWithinCircle(Vector3 center, float maxRadius, float minRadius) | ||||||
|  |         { | ||||||
|  |             if (this.X == center.X && this.Z == center.Z) | ||||||
|  |                 return true; | ||||||
|  |  | ||||||
|  |             float diffX = center.X - this.X; | ||||||
|  |             float diffZ = center.Z - this.Z; | ||||||
|  |  | ||||||
|  |             float distance = Utils.XZDistance(center.X, center.Z, X, Z); | ||||||
|  |  | ||||||
|  |             return distance <= maxRadius && distance >= minRadius; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool IsWithinBox(Vector3 upperLeftCorner, Vector3 lowerRightCorner) | ||||||
|  |         { | ||||||
|  |             return upperLeftCorner.X <= this.X && | ||||||
|  |                 upperLeftCorner.Y <= this.Y && | ||||||
|  |                 upperLeftCorner.Z <= this.Z && | ||||||
|  |                 lowerRightCorner.X >= this.X && | ||||||
|  |                 lowerRightCorner.Y >= this.Y && | ||||||
|  |                 lowerRightCorner.Z >= this.Z; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //Checks if this vector is in a cone, note it doesn't check for distance | ||||||
|  |         public bool IsWithinCone(Vector3 coneCenter, float coneRotation, float coneAngle) | ||||||
|  |         { | ||||||
|  |             float angleToTarget = GetAngle(coneCenter, this); | ||||||
|  |             float halfAngleOfAoe = (float) (coneAngle * Math.PI / 2); | ||||||
|  |             float rotationToAdd = coneRotation + halfAngleOfAoe; | ||||||
|  |  | ||||||
|  |             //This is the angle relative to the lower angle of the cone | ||||||
|  |             angleToTarget = (angleToTarget + rotationToAdd - (0.5f * (float)Math.PI)) % (2 * (float) Math.PI); | ||||||
|  |  | ||||||
|  |             //If the relative angle is less than the total angle of the cone, the target is inside the cone | ||||||
|  |             return angleToTarget >= 0 && angleToTarget <= (coneAngle * Math.PI); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override bool Equals(object obj) | ||||||
|  |         { | ||||||
|  |             var vector = obj as Vector3; | ||||||
|  |             return vector != null && | ||||||
|  |                    X == vector.X && | ||||||
|  |                    Y == vector.Y && | ||||||
|  |                    Z == vector.Z; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override int GetHashCode() | ||||||
|  |         { | ||||||
|  |             var hashCode = -307843816; | ||||||
|  |             hashCode = hashCode * -1521134295 + X.GetHashCode(); | ||||||
|  |             hashCode = hashCode * -1521134295 + Y.GetHashCode(); | ||||||
|  |             hashCode = hashCode * -1521134295 + Z.GetHashCode(); | ||||||
|  |             return hashCode; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,9 +1,9 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <configuration> | <configuration> | ||||||
|   <system.data> |   <system.data> | ||||||
|     <DbProviderFactories> |     <DbProviderFactories> | ||||||
|       <remove invariant="MySql.Data.MySqlClient" /> |       <remove invariant="MySql.Data.MySqlClient"/> | ||||||
|       <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /> |       <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/> | ||||||
|     </DbProviderFactories> |     </DbProviderFactories> | ||||||
|   </system.data> |   </system.data> | ||||||
| </configuration> | <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration> | ||||||
| @@ -2,5 +2,5 @@ | |||||||
| <packages> | <packages> | ||||||
|   <package id="DotNetZip" version="1.10.1" targetFramework="net45" /> |   <package id="DotNetZip" version="1.10.1" targetFramework="net45" /> | ||||||
|   <package id="MySql.Data" version="6.9.8" targetFramework="net45" /> |   <package id="MySql.Data" version="6.9.8" targetFramework="net45" /> | ||||||
|   <package id="NLog" version="4.3.5" targetFramework="net45" /> |   <package id="NLog" version="4.5.0" targetFramework="net451" /> | ||||||
| </packages> | </packages> | ||||||
							
								
								
									
										58
									
								
								Data/scripts/ability.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Data/scripts/ability.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
							
								
								
									
										117
									
								
								Data/scripts/ally.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								Data/scripts/ally.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
							
								
								
									
										19
									
								
								Data/scripts/base/chara/npc/debug/PopulaceMenuMan.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Data/scripts/base/chara/npc/debug/PopulaceMenuMan.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceMenuMan Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |     return false, false, 0, 0;   | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName)     | ||||||
|  |     callClientFunction(player, "debugMenuEvent", player);  | ||||||
|  |     player:endEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0, 0, 0;	 | ||||||
|  | end | ||||||
							
								
								
									
										9
									
								
								Data/scripts/base/chara/npc/mapobj/MapObjShipPort.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Data/scripts/base/chara/npc/mapobj/MapObjShipPort.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName)     | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| require ("global") | require ("global") | ||||||
| 
 | 
 | ||||||
| function init(npc) | function init(npc) | ||||||
| 	return false, false, 0, 0;	 | 	return false, false, 0, 0, 0, 0;	 | ||||||
| end | end | ||||||
							
								
								
									
										19
									
								
								Data/scripts/base/chara/npc/object/BgKeepout.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Data/scripts/base/chara/npc/object/BgKeepout.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | BgKeepout Script | ||||||
|  |  | ||||||
|  | Used to send a msg to the player that they cannot proceed passed this point. Invisible walls are | ||||||
|  | linked to this object. | ||||||
|  |  | ||||||
|  | ]] | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	player:SendGameMessage(player, GetWorldMaster(), 60001, 0x20); | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										95
									
								
								Data/scripts/base/chara/npc/object/ElevatorStandard.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								Data/scripts/base/chara/npc/object/ElevatorStandard.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | Elevator Standard Script | ||||||
|  |  | ||||||
|  | Functions:  | ||||||
|  |  | ||||||
|  | elevatorAskLimsa001(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 1. | ||||||
|  | elevatorAskLimsa002(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 2. | ||||||
|  | elevatorAskLimsa003(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Crow's Head Lift Lvl 3. | ||||||
|  | elevatorAskUldah001(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 1. | ||||||
|  | elevatorAskUldah002(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 2. | ||||||
|  | elevatorAskUldah003(eventNum) - Shows the ask dialog, and plays the event cutscenes for the Wellhead Lift Lvl 3. | ||||||
|  | elevatorQuestAskEvent(questId) - Special quest related elevator dialog. | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  |  | ||||||
|  | Script to control the elevators in Limsa Lominsa and Ul'dah. Each elevator entrance has a specific event for it's floor. | ||||||
|  | The only param is used to either show the ask dialog to the player or player the appropriate cutscene given the choice  | ||||||
|  | made. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName) | ||||||
|  | 	local actorClassId = npc.GetActorClassId(); | ||||||
|  | 	 | ||||||
|  | 	-- Limsa; Crow's Lift Level 1 | ||||||
|  | 	if (actorClassId == 1290007) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskLimsa001", 0);	 | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa001", 1); | ||||||
|  | 			endEventAndWarp(player, 133, -447, 40, 220, -1.574);	 | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa001", 2);	 | ||||||
|  | 			endEventAndWarp(player, 133, -458, 92, 175, -0.383);	 | ||||||
|  | 		end | ||||||
|  | 	-- Limsa; Crow's Lift Level 2 | ||||||
|  | 	elseif (actorClassId == 1290008) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskLimsa002", 0);	 | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa002", 1);		 | ||||||
|  | 			endEventAndWarp(player, 133, -447, 19, 220, -1.574); | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa002", 2);			 | ||||||
|  | 			endEventAndWarp(player, 133, -458, 92, 175, -0.383);	 | ||||||
|  | 		end | ||||||
|  | 	-- Limsa; Crow's Lift Level 3 | ||||||
|  | 	elseif (actorClassId == 1290009) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskLimsa003", 0);	 | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa003", 1); | ||||||
|  | 			endEventAndWarp(player, 133, -447, 19, 220, -1.574); | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskLimsa003", 2); | ||||||
|  | 			endEventAndWarp(player, 133, -447, 40, 220, -1.574); | ||||||
|  | 		end | ||||||
|  | 	-- Ul'dah; Wellhead Lift Level 1 | ||||||
|  | 	elseif (actorClassId == 1090460) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskUldah001", 0); | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah001", 1); | ||||||
|  | 			endEventAndWarp(player, 209, -116.78, 222, 115.7, 2.85); | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah001", 2); | ||||||
|  | 			endEventAndWarp(player, 209, -121.60, 269.8, 135.28, -0.268); | ||||||
|  | 		end | ||||||
|  | 	-- Ul'dah; Wellhead Lift Level 2 | ||||||
|  | 	elseif (actorClassId == 1090461) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskUldah002", 0);	 | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah002", 1); | ||||||
|  | 			endEventAndWarp(player, 175, -116.78, 198, 115.7, -2.8911); | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah002", 2); | ||||||
|  | 			endEventAndWarp(player, 209, -121.60, 269.8, 135.28, -0.268); | ||||||
|  | 		end | ||||||
|  | 	-- Ul'dah; Wellhead Lift Level 3 | ||||||
|  | 	elseif (actorClassId == 1090462) then | ||||||
|  | 		local floorChoice = callClientFunction(player, "elevatorAskUldah003", 0);	 | ||||||
|  | 		if (floorChoice == 1) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah003", 1);		 | ||||||
|  | 			endEventAndWarp(player, 175, -116.78, 198, 115.7, -2.8911); | ||||||
|  | 		elseif (floorChoice == 2) then | ||||||
|  | 			callClientFunction(player, "elevatorAskUldah003", 2); | ||||||
|  | 			endEventAndWarp(player, 209, -116.78, 222, 115.7, 2.85); | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function endEventAndWarp(player, zoneId, x, y, z, rotation) | ||||||
|  | 	player:EndEvent(); | ||||||
|  | 	GetWorldManager():DoZoneChange(player, zoneId, nil, 0, 15, x, y, z, rotation); | ||||||
|  | end | ||||||
							
								
								
									
										163
									
								
								Data/scripts/base/chara/npc/object/MarketEntrance.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								Data/scripts/base/chara/npc/object/MarketEntrance.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | MarketEntrance Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | Parameters mostly rely on the xtx_placeName sheet for its strings. | ||||||
|  |  | ||||||
|  | eventPushChoiceAreaOrQuest( | ||||||
|  |     exitPlaceName[Fronds, etc],     - Retail only showed it when inside a Market Ward/Office  Set to 0 to hide the menu. | ||||||
|  |     showMarketWards/Houses          - If > 0, client script adds nation-specific Mercentile Houses as well. | ||||||
|  |     gcHQPlaceName,                  - Set to the placeName id for the Grand Company office of that city | ||||||
|  |     questAreaName,                  - Set to the placeName id of applicable quest instance, ex. Sailors Ward. | ||||||
|  |     showItemSearchCounter,          - If true, shows the Item Search menu | ||||||
|  |     itemSearchId                    - If > 0 & showItemSearchCounter = true, displays the item name with a "Stop Searching" | ||||||
|  | ) | ||||||
|  | eventPushStepPrvMarket( | ||||||
|  |     staringWard,                    - Sets the starting placeName id | ||||||
|  |     wardCount,                      - Valid number 1-20. Sets the amount of market ward entries. Client continues sequentially from startingWard id. | ||||||
|  |     excludeWard                     - Hides the ward in the list that matches the id.  Use on the ward you're currently in. | ||||||
|  | )  | ||||||
|  |    | ||||||
|  |    | ||||||
|  | MarketEntrance City TriggerBox details | ||||||
|  | Limsa    - !warp 230 -416.5 40 446              ActorClass Id = 1090238 | ||||||
|  |     bgObj  Id - [0xB3B] 2875 | ||||||
|  |     Layout Id - [0x79 ] 121  (0x29d90001) | ||||||
|  |     Condition - in | ||||||
|  |     reactName - dwti    - Not a typo compared to the other cities | ||||||
|  | Gridania - !warp 206 -192.57 23.48 -1407.58     ActorClass Id = 1090264 | ||||||
|  |  | ||||||
|  |     bgObj  Id - [0xCFA] 3322 | ||||||
|  |     Layout Id - [0x141]  321 (0x29b00001) | ||||||
|  |     Condition - in | ||||||
|  |     reactName - dtwi | ||||||
|  | Ul'dah   - !warp 175 -235 189 50.5              ActorClass Id = 1500394 | ||||||
|  |     bgObj  Id - [0x102F] 4143 | ||||||
|  |     Layout Id - [0x1A5] 421  (0x615a0001) | ||||||
|  |     Condition - in | ||||||
|  |     reactName - dtwi | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0; | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CITY_INFO = { -- wardPlaceName, exitPlaceName, gcHQPlaceName, questAreaName, wardListStart, wardListCount | ||||||
|  |     {1093, 1087, 1512, 1091, 1261, 20}, -- Limsa | ||||||
|  |     {2099, 2091, 2526, 2095, 2261, 20}, -- Gridania | ||||||
|  |     {3098, 3091, 3514, 3095, 3261, 20}, -- Ul'dah | ||||||
|  | } | ||||||
|  |  | ||||||
|  | -- TO-DO:  Add some X/Z pos jitter to Entrances/Exits when called | ||||||
|  | MARKETWARD_ENTRANCE = { | ||||||
|  |     {134, 160, 0, 135}, -- Limsa Market | ||||||
|  |     {160, 160, 0, 138}, -- Gridania Market | ||||||
|  |     {180, 160, 0, 185}  -- Ul'dah Market | ||||||
|  | } | ||||||
|  |  | ||||||
|  | MARKETWARD_EXIT = { | ||||||
|  |     {230, -420, 41, 435, -3.14},  -- Educated guess for Limsa, need video reference to confirm | ||||||
|  |     {206, -180, 22, -1408, 1.5}, | ||||||
|  |     {175, -210, 190, 25, 0.65} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | GC_ENTRANCE = {  | ||||||
|  |     [1512] = {232, 160, 0, -155}, -- Maelstrom Command | ||||||
|  |     [2526] = {234, 160, 0, -155}, -- Adders' Nest | ||||||
|  |     [3514] = {233, 160, 0, -155}  -- Hall of Flames | ||||||
|  | } | ||||||
|  |  | ||||||
|  | city = { | ||||||
|  |     [1090238] = 1, -- Limsa Market Ward Entrance | ||||||
|  |     [1090264] = 2, -- Gridania Market Ward Entrance | ||||||
|  |     [1090265] = 3, -- Ul'dah Market Ward Entrance | ||||||
|  |     [1500392] = 1, -- Limsa     : M'septha | ||||||
|  |     [1500393] = 2, -- Gridania  : Torsefers | ||||||
|  |     [1500394] = 3, -- Ul'dah    : Edine | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName)	 | ||||||
|  |     local npcCity = city[npc:GetActorClassId()] or 1; | ||||||
|  |     local marketPlaceName = CITY_INFO[npcCity][1];        -- Market Wards category name. Identical in all languages except Japanese | ||||||
|  |     local exitPlaceName = CITY_INFO[npcCity][2];        -- Central Limsa Lominsa / Heartstream / The Fronds | ||||||
|  |     local gcHQPlaceName = CITY_INFO[npcCity][3];        -- Maelstrom Command / Adders' Nest / Hall of Flames | ||||||
|  |     local questPlaceName = CITY_INFO[npcCity][4];   		-- Sailors Ward / Peasants Ward / Merchants Ward | ||||||
|  |     local wardListStart = CITY_INFO[npcCity][5];        -- Starting id for the market wards | ||||||
|  |     local wardListCount = CITY_INFO[npcCity][6];        -- Amount of wards in the list | ||||||
|  |     local showItemSearchCounter = false; | ||||||
|  |     local itemSearchId = 11000125;    | ||||||
|  |      | ||||||
|  |     local worldMaster = GetWorldMaster();  | ||||||
|  |     local pos = player:GetPos(); | ||||||
|  |     local currZone = pos[5]; | ||||||
|  | 	local currRegion = player.CurrentArea.RegionId;	 | ||||||
|  | 	local quests = player:GetQuestsForNpc(npc); | ||||||
|  |      | ||||||
|  | 	-- City entrance specific stuff | ||||||
|  |     if (currRegion == 101 or currRegion == 103 or currRegion == 104) then  | ||||||
|  |         exitPlaceName = 0;  -- If in city, hide city menu option | ||||||
|  | 		 | ||||||
|  | 		-- If no quests attached to this entrence, don't show quest area | ||||||
|  | 		if (#quests == 0) then | ||||||
|  | 			questPlaceName = 0; | ||||||
|  | 		end | ||||||
|  |     end | ||||||
|  | 	 | ||||||
|  | 	-- If in GC Office, hide office menu option | ||||||
|  | 	if (currZone == 232 or currZone == 234 or currZone == 233) then  | ||||||
|  |         gcHQPlaceName = 0;   | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, marketPlaceName, gcHQPlaceName, questPlaceName, showItemSearchCounter, itemSearchId); | ||||||
|  |          | ||||||
|  |     while (true) do | ||||||
|  |          | ||||||
|  |         if choice == marketPlaceName then -- Market Wards | ||||||
|  |             wardSelect = callClientFunction(player, "eventPushStepPrvMarket", wardListStart, wardListCount, 0); | ||||||
|  |              | ||||||
|  |             if wardSelect and (wardSelect >= wardListStart and wardSelect <= (wardListStart+wardListCount)) then | ||||||
|  |                 player:SendGameMessage(player, worldMaster, 60004, 0x20, wardSelect); | ||||||
|  |                 warp = MARKETWARD_ENTRANCE[npcCity]; | ||||||
|  |                 playerRot = math.random(-3.14, 3.14); | ||||||
|  |                 wait(1); | ||||||
|  |                 GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], playerRot); | ||||||
|  |                 player:SendDataPacket("attention", worldMaster, "", 60003, wardSelect); | ||||||
|  |                 -- Temp: Pop-up display after Ward zone-in.  Client should automate this with PrivateArea's properly setup | ||||||
|  |  | ||||||
|  |                 break; | ||||||
|  |             end | ||||||
|  |              | ||||||
|  |         elseif (choice == 1519 or choice == 2534 or choice == 3533) then -- Mercentile Wards | ||||||
|  |                 player:SendMessage(0x20, "", "[MarketEntrance] DEBUG: "..choice); | ||||||
|  |         elseif (choice == 1512 or choice == 2526 or choice == 3514) then -- GC Office | ||||||
|  |                 warp = GC_ENTRANCE[choice]; | ||||||
|  |                 player:SendGameMessage(player, worldMaster, 60004, 0x20, choice); | ||||||
|  |                 wait(1); | ||||||
|  |                 GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], math.pi); | ||||||
|  |                 break; | ||||||
|  |         elseif (choice == 1087 or choice == 2091 or choice == 3091) then -- Exiting to City | ||||||
|  |                 player:SendGameMessage(player, worldMaster, 60004, 0x20, choice); | ||||||
|  |                 warp = MARKETWARD_EXIT[npcCity]; | ||||||
|  |                 wait(1); | ||||||
|  |                 GetWorldManager():DoZoneChange(player, warp[1], nil, 0, 0x02, warp[2], warp[3], warp[4], warp[5]);           | ||||||
|  |                 break; | ||||||
|  | 		elseif (choice == 2095 or choice == 3095) then -- Quest | ||||||
|  | 			quests[1]:OnPush(player, npc, eventName); | ||||||
|  | 			return; | ||||||
|  |         elseif (choice == 0 or choice == -3) then -- Menu Closed | ||||||
|  |             break;   | ||||||
|  |         end  | ||||||
|  |          | ||||||
|  |         choice = callClientFunction(player, "eventPushChoiceAreaOrQuest", exitPlaceName, marketPlaceName, gcHQPlaceName, questAreaName, showItemSearchCounter, itemSearchId); | ||||||
|  |            | ||||||
|  |     end | ||||||
|  |      | ||||||
|  | 	player:EndEvent();	 | ||||||
|  |      | ||||||
|  | end | ||||||
							
								
								
									
										63
									
								
								Data/scripts/base/chara/npc/object/ObjectBed.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Data/scripts/base/chara/npc/object/ObjectBed.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | DREAM_ITEM = { | ||||||
|  | 	{[1] = 3010419, [2] = 3010420, [3] = 3010421}, -- Mizzenmast/Roost/Hourglass Biscuit | ||||||
|  | 	3010003, -- Boiled Egg | ||||||
|  | 	3010101, -- Grilled Carp | ||||||
|  | 	3010001, -- Meat Miq'abob | ||||||
|  | 	3010402, -- Ginger Cookie | ||||||
|  | 	3020001, -- Potion | ||||||
|  | 	3020101, -- Ether | ||||||
|  | 	1000003, -- 5x Crystal Shards (Fire) | ||||||
|  | 	1000004, -- 5x Crystal Shards (Ice) | ||||||
|  | 	1000005, -- 5x Crystal Shards (Wind) | ||||||
|  | 	1000006, -- 5x Crystal Shards (Earth) | ||||||
|  | 	1000007, -- 5x Crystal Shards (Lightning) | ||||||
|  | 	1000008  -- 5x Crystal Shards (Water) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	local choice = callClientFunction(player, "askLogout", player); | ||||||
|  | 	 | ||||||
|  | 	-- Quit | ||||||
|  | 	if (choice == 2) then | ||||||
|  | 		player:SetSleeping(); | ||||||
|  | 		player:QuitGame(); | ||||||
|  | 	-- Logout | ||||||
|  | 	elseif (choice == 3) then | ||||||
|  | 		player:SetSleeping(); | ||||||
|  | 		player:Logout(); | ||||||
|  | 	-- Heck the bed | ||||||
|  | 	elseif (choice == 4) then | ||||||
|  | 		-- Give items based on dream | ||||||
|  | 		local dreamCode = player:GetLoginDreamCode();		 | ||||||
|  | 		if (dreamCode >= 21 and dreamCode <= 33) then | ||||||
|  | 			local innCode = player:GetInnCode(); | ||||||
|  | 			local itemCode = DREAM_ITEM[dreamCode - 20]; | ||||||
|  | 			 | ||||||
|  | 			-- Get biscuit for inn | ||||||
|  | 			if (dreamCode == 21) then | ||||||
|  | 				itemCode = itemCode[innCode]; | ||||||
|  | 			end | ||||||
|  | 			 | ||||||
|  | 			-- If crystals you get x5 otherwise x1. | ||||||
|  | 			if (dreamCode > = 28 and dreamCode <= 33) then | ||||||
|  | 				player:AddItem(itemCode, 5); | ||||||
|  | 			else | ||||||
|  | 				player:AddItem(itemCode, 1); | ||||||
|  | 			end | ||||||
|  | 			 | ||||||
|  | 			-- Clear the code so they player doesn't keep getting things | ||||||
|  | 			player:SetLoginDreamCode(0); | ||||||
|  | 		else | ||||||
|  | 			-- Otherwise show standard message | ||||||
|  | 			player:SendGameMessage(player, npc, 7, 0x20); | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										52
									
								
								Data/scripts/base/chara/npc/object/ObjectEventDoor.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Data/scripts/base/chara/npc/object/ObjectEventDoor.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | ObjectEventDoor Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventDoorMoveAsk() - Shows confirm to move into event | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName)	 | ||||||
|  | 	local choice = callClientFunction(player, "eventDoorMoveAsk"); | ||||||
|  | 	 | ||||||
|  | 	if (choice == 1) then | ||||||
|  | 		local activeQuests = player:GetQuestsForNpc(npc); | ||||||
|  | 		-- Either let the player choose the quest or start it if it's the only one. | ||||||
|  | 		local chosenQuest; | ||||||
|  | 		if (#activeQuests > 1) then | ||||||
|  | 			local currentPage = 0; | ||||||
|  | 			local numPages = math.floor((#activeQuests-1)/4) + 1; | ||||||
|  | 			 | ||||||
|  | 			while (true) do | ||||||
|  | 				local page, index = callClientFunction(player, "switchEvent", activeQuests[currentPage * 4 + 1], activeQuests[currentPage * 4 + 2], possibleQuests[currentPage * 4 + 3], possibleQuests[currentPage * 4 + 4], currentPage + 1, numPages, 0x3F1); | ||||||
|  | 				 | ||||||
|  | 				if (page == 0) then | ||||||
|  | 					chosenQuest = activeQuests[(currentPage * 4) + index]; | ||||||
|  | 					break; | ||||||
|  | 				elseif (page > 0) then | ||||||
|  | 					currentPage = page - 1; | ||||||
|  | 				else | ||||||
|  | 					player:EndEvent(); | ||||||
|  | 					return; | ||||||
|  | 				end | ||||||
|  | 			end			 | ||||||
|  | 		elseif (#activeQuests == 1) then | ||||||
|  | 			chosenQuest = activeQuests[1]; | ||||||
|  | 		end | ||||||
|  | 		 | ||||||
|  | 		if (chosenQuest ~= nil) then | ||||||
|  | 			chosenQuest:OnPush(player, npc, eventName);		 | ||||||
|  | 			return; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent();	 | ||||||
|  | end | ||||||
| @@ -4,7 +4,7 @@ function init(npc) | |||||||
| 	return false, false, 0, 0;	 | 	return false, false, 0, 0;	 | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function onEventStarted(player, npc, triggerName) | function onEventStarted(player, npc, eventType, eventName) | ||||||
| 	defaultFst = GetStaticActor("DftFst"); | 	defaultFst = GetStaticActor("DftFst"); | ||||||
| 	choice = callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithInn_ExitDoor", nil, nil, nil); | 	choice = callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithInn_ExitDoor", nil, nil, nil); | ||||||
| 	 | 	 | ||||||
| @@ -31,7 +31,7 @@ function onEventStarted(player, npc, triggerName) | |||||||
| 		itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice); | 		itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice); | ||||||
| 			 | 			 | ||||||
| 		if (itemId ~= nil) then | 		if (itemId ~= nil) then | ||||||
| 			player:GetInventory(INVENTORY_NORMAL):RemoveItem(itemId, 1); | 			player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(itemId, 1); | ||||||
| 		end | 		end | ||||||
| 		 | 		 | ||||||
| 	elseif (storageChoice == 2) then | 	elseif (storageChoice == 2) then | ||||||
| @@ -44,7 +44,7 @@ function onEventStarted(player, npc, triggerName) | |||||||
| 		itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice); | 		itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice); | ||||||
| 		 | 		 | ||||||
| 		if (itemId ~= nil) then | 		if (itemId ~= nil) then | ||||||
| 			player:GetInventory(INVENTORY_NORMAL):AddItem(itemId, 1); | 			player:GetItemPackage(INVENTORY_NORMAL):AddItem(itemId, 1); | ||||||
| 		end | 		end | ||||||
| 	 | 	 | ||||||
| 	end | 	end | ||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | require("global"); | ||||||
|  | 
 | ||||||
| function init(npc) | function init(npc) | ||||||
| 	return false, false, 0, 0;	 | 	return false, false, 0, 0;	 | ||||||
| end | end | ||||||
| @@ -7,7 +9,7 @@ function onEventStarted(player, npc, triggerName) | |||||||
| 		worldMaster = GetWorldMaster(); | 		worldMaster = GetWorldMaster(); | ||||||
| 		player:SendGameMessage(player, worldMaster, 34109, 0x20); | 		player:SendGameMessage(player, worldMaster, 34109, 0x20); | ||||||
| 	elseif (triggerName == "exit") then | 	elseif (triggerName == "exit") then | ||||||
| 		GetWorldManager():DoPlayerMoveInZone(player, 5); | 		GetWorldManager():DoPlayerMoveInZone(player, 356.09, 3.74, -701.62, -1.4); | ||||||
| 	end | 	end | ||||||
| 	player:EndEvent(); | 	player:EndEvent(); | ||||||
| end | end | ||||||
							
								
								
									
										18
									
								
								Data/scripts/base/chara/npc/object/OpeningStoperW0B1.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Data/scripts/base/chara/npc/object/OpeningStoperW0B1.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName) | ||||||
|  |  | ||||||
|  |     if (eventType == ETYPE_PUSH) then | ||||||
|  |         if (eventName == "caution") then | ||||||
|  |             worldMaster = GetWorldMaster(); | ||||||
|  |             player:SendGameMessage(player, worldMaster, 34109, 0x20); | ||||||
|  |         elseif (eventName == "exit") then | ||||||
|  |             GetWorldManager():DoPlayerMoveInZone(player, 5.36433, 196, 133.656, -2.84938); | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										9
									
								
								Data/scripts/base/chara/npc/object/OpeningTown.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Data/scripts/base/chara/npc/object/OpeningTown.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName)     | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName) | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										37
									
								
								Data/scripts/base/chara/npc/object/PrivateAreaPastExit.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Data/scripts/base/chara/npc/object/PrivateAreaPastExit.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PrivateAreaPastExit | ||||||
|  |  | ||||||
|  | This object contains the player inside a PrivateAreaPast, stopping them from escaping it's bounds. It is the | ||||||
|  | object that generates the circle graphic on the minimap. This object always has two push triggers, an inner | ||||||
|  | and outer inverted circle. The inner one is named "caution" and the outer one is named "exit". When the player | ||||||
|  | leaves the inner circle a warning is shown and when they leave the outer circle they either leave the instance | ||||||
|  | or get warped back to the center. | ||||||
|  |  | ||||||
|  | ]] | ||||||
|  |  | ||||||
|  | function init(privAreaExit) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, privAreaExit, eventType, eventName) | ||||||
|  | 	player:EndEvent(); | ||||||
|  | 	 | ||||||
|  | 	if (eventName == "caution") then | ||||||
|  | 		player:SendGameMessage(player, GetWorldMaster(), 34109, MESSAGE_TYPE_SYSTEM); -- You are about to leave the instance. | ||||||
|  | 	elseif (eventName == "exit") then | ||||||
|  | 		local area = privAreaExit.CurrentArea; | ||||||
|  | 		if (area.IsPrivate()) then | ||||||
|  | 			-- If you can leave, warp to public zone and show message. | ||||||
|  | 			if (area.CanExitPrivateArea()) then | ||||||
|  | 				player:SendGameMessage(player, GetWorldMaster(), 34110, MESSAGE_TYPE_SYSTEM); -- You have left the instance. | ||||||
|  | 				--GetWorldManager():WarpToPublicArea(player); | ||||||
|  | 			-- Otherwise warp back to the center of the zone. | ||||||
|  | 			else | ||||||
|  | 				--GetWorldManager():WarpToCharaPosition(player, privAreaExit); | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | end | ||||||
							
								
								
									
										56
									
								
								Data/scripts/base/chara/npc/object/RetainerFurniture.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Data/scripts/base/chara/npc/object/RetainerFurniture.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
							
								
								
									
										108
									
								
								Data/scripts/base/chara/npc/object/TaskBoard.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								Data/scripts/base/chara/npc/object/TaskBoard.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | TaskBoard | ||||||
|  |  | ||||||
|  | Operates the Task Board actor located in each of the Adventurers' Guilds. | ||||||
|  | Calls from the Noc000 static actor, which also applies to specific guild NPCs involved in that as well. | ||||||
|  |  | ||||||
|  | Functions:  (only including those from Noc000 which apply to the Task Board) | ||||||
|  |  | ||||||
|  | pETaskBoardAskLimsa() | ||||||
|  |     Desc: Show guild menu with valid options for Limsa Lominsa. | ||||||
|  |     Params: None | ||||||
|  |     Returns: Value dictating which item on the list was selected. | ||||||
|  |  | ||||||
|  | pETaskBoardAskUldah() | ||||||
|  |     Desc: Show guild menu with valid options for Ul'dah. | ||||||
|  |     Params: None | ||||||
|  |     Returns: Value dictating which item on the list was selected. | ||||||
|  |  | ||||||
|  | pETaskBoardAskGridania() | ||||||
|  |     Desc: Show guild menu with valid options for Gridania. | ||||||
|  |     Params: None | ||||||
|  |     Returns: Value dictating which item on the list was selected. | ||||||
|  |  | ||||||
|  | pETaskBoardGuild(guildId) | ||||||
|  |     Desc: Plays back a message "The following tasks are available:". | ||||||
|  |     Params: * guildId 			- Class Id from xtx_text_jobName.  EN doesn't make use of it, but JP/DE/FR do.  Thanks Koji. | ||||||
|  |      | ||||||
|  | pETaskBoardOrder(recommendedLvl itemId, hq, amount) | ||||||
|  |     Desc: Takes the params and tells the player what the guild still needs turned in. | ||||||
|  |     Params: * recommendedLvl 	- Recommended level the player be at | ||||||
|  |             * itemId  			- Id of the item from xtx_itemName | ||||||
|  |             * hq     			- Quality of item (1 = NQ, 2 = +1, 3 = +2 4 = +3) | ||||||
|  |             * amount 			- Amount needed (The amount the player needs to turn-in, not the amount guild needs overall) | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | local guildItem = {  | ||||||
|  |     -- [guildId] = { (recommendedLvl itemId, hq, amount, 2nd-recommendedLvl 2nd-itemId, 2nd-hq, 2nd-amount) } | ||||||
|  |     [29] = {1, 4100604, 1, 1, 10, 4030706, 1, 1}, -- Carpenters' | ||||||
|  |     [30] = {1, 4040004, 1, 1, 10, 4030004, 1, 1}, -- Blacksmiths' | ||||||
|  |     [31] = {1, 6080009, 1, 1, 10, 8070606, 1, 1}, -- Armorers' | ||||||
|  |     [32] = {1, 5020007, 1, 1, 10,10004103, 1, 1}, -- Goldsmiths' | ||||||
|  |     [33] = {1, 4020107, 1, 1, 10, 8031514, 1, 1}, -- Leatherworkers' | ||||||
|  |     [34] = {1, 8030819, 1, 1, 10, 8030821, 1, 1}, -- Weavers' | ||||||
|  |     [35] = {1, 3011530, 1,12, 10, 3020527, 1, 4}, -- Alchemists' | ||||||
|  |     [36] = {1, 3010103, 1, 6, 10, 3011503, 1, 6}, -- Culinarians' | ||||||
|  |     [39] = {1,10009101, 1,10, 10,10001116, 1,10}, -- Miners' | ||||||
|  |     [40] = {1,10005403, 1,10, 10,10008106, 1,10}, -- Botanists' | ||||||
|  |     [41] = {1, 3011106, 1,10, 10, 3011113, 1,10}  -- Fishermans'  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | local menuToGuild = {          -- Get a guild id from a given task board's Return result | ||||||
|  |     [1] = {0, 30, 31, 36, 41}, -- Limsa | ||||||
|  |     [2] = {0, 29, 33, 40,  0}, -- Gridania | ||||||
|  |     [3] = {0, 32, 34, 35, 39}  -- Ul'dah | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |     return false, false, 0, 0;   | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |      | ||||||
|  |     local questNOC = GetStaticActor("Noc000"); | ||||||
|  |     local npcId = npc:GetActorClassId(); | ||||||
|  |      | ||||||
|  |     while (true) do	 | ||||||
|  | 		local guildId = 0; | ||||||
|  | 	 | ||||||
|  |         if (npcId == 1200193) then -- Limsa | ||||||
|  |             local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskLimsa"); | ||||||
|  |              | ||||||
|  |             if (choice == 1 or choice == nil) then | ||||||
|  |                 break; -- Exited menu | ||||||
|  |             else | ||||||
|  |                 guildId = menuToGuild[1][choice]; | ||||||
|  |             end             | ||||||
|  |         elseif (npcId == 1200194) then -- Ul'dah    | ||||||
|  |             local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskUldah"); | ||||||
|  |              | ||||||
|  |             if (choice == 1 or choice == nil) then | ||||||
|  |                 break; -- Exited menu | ||||||
|  |             else | ||||||
|  |                 guildId = menuToGuild[3][choice];  | ||||||
|  |             end         | ||||||
|  |         else -- Gridania | ||||||
|  |             local choice = callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskGridania"); | ||||||
|  |                      | ||||||
|  |             if (choice == 1 or choice == nil) then | ||||||
|  |                 break; -- Exited menu | ||||||
|  |             else | ||||||
|  |                 guildId = menuToGuild[2][choice];  | ||||||
|  |             end    | ||||||
|  |         end  | ||||||
|  |                  | ||||||
|  |         if (guildId > 0) then | ||||||
|  |             callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardGuild", guildId); | ||||||
|  |             local gItem = guildItem[guildId] | ||||||
|  |             callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardOrder", unpack(gItem, 1, 4)); | ||||||
|  |             callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardOrder", unpack(gItem, 5, 8));    | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |     player:EndEvent();   | ||||||
|  | end | ||||||
| @@ -107,7 +107,7 @@ function doLevequestInit(player, aetheryte) | |||||||
| 			 | 			 | ||||||
| 				player:SendGameMessage(worldMaster, 50036, 0x20, glId, player); | 				player:SendGameMessage(worldMaster, 50036, 0x20, glId, player); | ||||||
| 				player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));				 | 				player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));				 | ||||||
| 				director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player); | 				director = player.CurrentArea:CreateGuildleveDirector(glId, difficulty, player); | ||||||
| 				player:AddDirector(director); | 				player:AddDirector(director); | ||||||
| 				director:StartDirector(true, glId) | 				director:StartDirector(true, glId) | ||||||
| 			 | 			 | ||||||
| @@ -33,6 +33,30 @@ end | |||||||
| 
 | 
 | ||||||
| function onEventStarted(player, aetheryte, triggerName) | function onEventStarted(player, aetheryte, triggerName) | ||||||
| 	 | 	 | ||||||
|  | 	-- Main Scenario Intro Quests | ||||||
|  | 	if (player:HasQuest(110002) == true) then | ||||||
|  | 		require ("quests/man/man0l1"); | ||||||
|  | 		local quest = player:GetQuest("Man0l1"); | ||||||
|  | 		if (quest:GetSequence() == SEQ_003) then			 | ||||||
|  | 			callClientFunction(player, "delegateEvent", player, quest, "processEvent025"); | ||||||
|  | 			quest:StartSequence(SEQ_005); | ||||||
|  | 		end | ||||||
|  | 	elseif (player:HasQuest(110006) == true) then | ||||||
|  | 		require ("quests/man/man0g1"); | ||||||
|  | 		local quest = player:GetQuest("Man0g1"); | ||||||
|  | 		if (quest:GetSequence() == SEQ_005) then			 | ||||||
|  | 			callClientFunction(player, "delegateEvent", player, quest, "processEvent013"); | ||||||
|  | 			--quest:StartSequence(???); | ||||||
|  | 		end | ||||||
|  | 	elseif (player:HasQuest(110010) == true) then | ||||||
|  | 		require ("quests/man/man0u1"); | ||||||
|  | 		local quest = player:GetQuest("Man0u1"); | ||||||
|  | 		if (quest:GetSequence() == SEQ_005) then			 | ||||||
|  | 			callClientFunction(player, "delegateEvent", player, quest, "processEvent013"); | ||||||
|  | 			quest:StartSequence(SEQ_010); | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
| 	if (player:GetGuildleveDirector() ~= nil) then | 	if (player:GetGuildleveDirector() ~= nil) then | ||||||
| 		doGuildleveMenu(player, aetheryte); | 		doGuildleveMenu(player, aetheryte); | ||||||
| 	else | 	else | ||||||
| @@ -142,7 +166,7 @@ function doLevequestInit(player, aetheryte) | |||||||
| 							 | 							 | ||||||
| 				player:SendGameMessage(worldMaster, 50036, 0x20, glId, player); | 				player:SendGameMessage(worldMaster, 50036, 0x20, glId, player); | ||||||
| 				player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));				 | 				player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));				 | ||||||
| 				director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player); | 				director = player.CurrentArea:CreateGuildleveDirector(glId, difficulty, player); | ||||||
| 				player:AddDirector(director); | 				player:AddDirector(director); | ||||||
| 				director:StartDirector(true, glId); | 				director:StartDirector(true, glId); | ||||||
| 				 | 				 | ||||||
							
								
								
									
										159
									
								
								Data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								Data/scripts/base/chara/npc/populace/PopulaceBlackMarketeer.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  |  | ||||||
| @@ -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 | ||||||
| @@ -0,0 +1,41 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCaravanAdviser Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | adviserDeffault()       - Not a typo.  NPC dialog talking about a chocobo.  Resets their sight on you, perhaps used on closing dialog? | ||||||
|  | adviserAsk()            - Brings up a menu for caravan info, or purchasing gysahl greens | ||||||
|  | adviserAdvise()         - NPC dialog discussing feeding chocobos | ||||||
|  | adviserSales(price)     - Gysahl purchase dialog and prompt | ||||||
|  | adviserBuy()            - Dialog to play after purchasing gysahl greens | ||||||
|  | adviserBuyNG()          - NPC plays /shrug animation.   | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	local gysahlPrice = 20; | ||||||
|  | 	local choice = callClientFunction(player, "adviserAsk"); | ||||||
|  |      | ||||||
|  |     if choice == 1 then | ||||||
|  |         callClientFunction(player, "adviserAdvise"); | ||||||
|  |     elseif choice == 2 then | ||||||
|  |         local purchaseChoice = callClientFunction(player, "adviserSales", gysahlPrice); | ||||||
|  |          | ||||||
|  |         if purchaseChoice == 1 then | ||||||
|  |             callClientFunction(player, "adviserBuy"); | ||||||
|  |         elseif purchaseChoice == 2 then | ||||||
|  |             callClientFunction(player, "adviserBuyNG"); | ||||||
|  |         end | ||||||
|  |     elseif choice == 3 then | ||||||
|  |         callClientFunction(player, "adviserDeffault") | ||||||
|  |     end | ||||||
|  |  | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
| @@ -0,0 +1,68 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCaravanGuide Script | ||||||
|  |  | ||||||
|  | This script handles the caravan guide class, which is for the actor who escorts the chocobos behind them during Caravan Security events.   | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | caravanGuardCancel()                                        - Menu prompt to abandon the caravan | ||||||
|  |  | ||||||
|  | caravanGuardReward(cargo, nil, areaName, playerGC, killCount, areaName2)       | ||||||
|  |                                                             - Reward dialog for completing the caravan | ||||||
|  |                                                             - cargo = 0 (none) through 9 (all) for varying degrees of success dialog | ||||||
|  |                                                             - If playerGC doesn't match the GC of the areaName region, NPC mentions you don't need their seals. | ||||||
|  |                                                             - killCount shows an extra dialog if 40-49 enemies were slain, and a different one at 50+ | ||||||
|  |                                                              | ||||||
|  | caravanGuardNotReward()                                     - Dialog stating you didn't contribute to the event at all | ||||||
|  | caravanGuardFailReward(areaName, areaName2)                 - Failure dialog, NPC offers free gysahl green, then offers free teleport back to aetheryte | ||||||
|  | caravanGuardThanks(name1, name2, name3)                     - Dialog for joining the caravan.  NPC names the three chocobos. Name IDs from xtx_displayName | ||||||
|  | caravanGuardOffer(areaName, areaName2, playerGC)            - Dialog for who to talk to for joining the caravan. | ||||||
|  | caravanGuardAmple(areaName, areaName2)                      - Dialog for NPC taking a break? | ||||||
|  | caravanGuardSuccess()                                       - Dialog when you reached destination? | ||||||
|  | caravanGuardFailure(areaName, areaName2)                    - Failure dialog for mentioned area. | ||||||
|  | caravanGuardIgnore()                                        - Resets NPC state for player?  Or used for players not flagged for the event. | ||||||
|  | caravanGuardBonusReward(nil, isBonus?)                      - NPC says variation on a piece of dialog from the boolean passed | ||||||
|  | caravanGuardNotBonusReward()                                - Inventory full flavour dialog | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  | Functions employing areaName/areaName2 add their value together in the client's script to get the area name.  Said area values are...  | ||||||
|  | 1 = Wineport, 2 = Quarrymill, 3 = Silver Bazaar, 4 = Aleport, 5 = Hyrstmill, 6 = Golden Bazaar | ||||||
|  |  | ||||||
|  | areaName will always be 1-3 for caravanGuardReward to function as expected for GC-related dialog | ||||||
|  | areaName2 will always be either 0 or 3.  0 for the lower level caravan area name, 3 for the higher level. | ||||||
|  |  | ||||||
|  | populaceCaravanGuide sheet: | ||||||
|  | ID  Dialog                                                                                Comment | ||||||
|  | 6	It is time. Come, let us ride.                                                      - Caravan begins. | ||||||
|  | 12	We've arrived at last! Come and speak to me when you're ready to claim your reward. - Caravan completed. | ||||||
|  | 23	We're under attack! The chocobos! Protect the chocobos!                             - Caravan aggros monsters | ||||||
|  | 27	Gods, have we already come this far? At this pace, we stand to make good time.      - Says between 50% & 90% of the way to desgination? Can be said more than once per run | ||||||
|  | 28	Well fought, friend. I thank the gods you're with us. Come, onward!                 - Cleared monsters that caravan aggro'd | ||||||
|  |  | ||||||
|  | TO-DO: | ||||||
|  | Document actors involved.  Should be six of them. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	local areaName = 1; | ||||||
|  |     local areaName2 = 3; | ||||||
|  |     local playerGC = 1; | ||||||
|  |     local cargo = 9; | ||||||
|  |     local killCount = 50; | ||||||
|  |     callClientFunction(player, "caravanGuardOffer", areaName, areaName2, playerGC); | ||||||
|  |     --callClientFunction(player, "caravanGuardReward", cargo, nil, areaName, playerGC, killCount, areaName2);    | ||||||
|  |     --player:SendGameMessageLocalizedDisplayName(npc, 6, MESSAGE_TYPE_SAY, npc.displayNameId); | ||||||
|  |      | ||||||
|  |      | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
| @@ -0,0 +1,49 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCaravanManager Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | caravanGuardEntry(areaGC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCountRequired, levelRequired)  | ||||||
|  |        - Dialog for signing up for caravan. areaGC(1-3) & areaName(0 or 3) added together to get location name.   | ||||||
|  |        - If difficulty => 40 on areaGC 1-3 & areaName 0, NPC mentions it's be a tougher trip | ||||||
|  |         | ||||||
|  | caravanGuardQuestion(areaName1, areaName2, escortMax, isSameGC?, playerGC?) - Ask about the caravan escort | ||||||
|  | caravanGuardJoinOK(areaName1, areaName2, playerGC)   - Dialog for successfully joining the caravan | ||||||
|  | caravanGuardJoinNG(nil, maxEscorts, playerGC)        - Dialog dictating how many escorts total filled the run.   | ||||||
|  | caravanGuardAmple(nil, playerGC, playerGC)           - Dialog for caravan escort being full. | ||||||
|  | caravanGuardOther(npcGC)                             - Dialog where NPC mentions you're not part of the given Grand Company parameter | ||||||
|  | caravanGuardSigh()                                   - NPC does a shrug animation | ||||||
|  | caravanGuardHuh()                                    - NPC does /huh | ||||||
|  | caravanGuardCancel(nil, playerGC)                    - Dialog for canceling caravan escort.  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  | Some NPC dialog address you differently if your GC rank is Chief Sergeant (id 27) or higher, but only in non-English languages. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	local GC = 3; | ||||||
|  |     local playerGC = 1;  | ||||||
|  |     local areaName = 0; | ||||||
|  |     local level = 25; | ||||||
|  |     local playerCount = 8; | ||||||
|  |     local difficulty = 41; | ||||||
|  |     local hasRoomForGCSeals = false; | ||||||
|  | 	local isSameGC = true; | ||||||
|  |     local escortMax = 8; | ||||||
|  |     areaName1 = 1; | ||||||
|  |     areaName2 = 3; | ||||||
|  |      | ||||||
|  |    -- callClientFunction(player, "caravanGuardCancel", nil, 3); | ||||||
|  |      | ||||||
|  |     callClientFunction(player, "caravanGuardEntry", GC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCount, level); | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										136
									
								
								Data/scripts/base/chara/npc/populace/PopulaceChocoboLender.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								Data/scripts/base/chara/npc/populace/PopulaceChocoboLender.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceChocoboLender Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkWelcome(player) - Start Text | ||||||
|  | eventAskMainMenu(player, curLevel, hasFundsForRent, isPresentChocoboIssuance, isSummonMyChocobo, isChangeBarding, currentChocoboWare) - Shows the main menu | ||||||
|  | eventTalkMyChocobo(player) - Starts the cutscene for getting a chocobo | ||||||
|  | eventSetChocoboName(true) - Opens the set name dialog | ||||||
|  | eventAfterChocoboName(player) - Called if player done naming chocobo, shows cutscene, returns state and waits to teleport outside city. | ||||||
|  | eventCancelChocoboName(player) - Called if player cancels naming chocobo, returns state.  | ||||||
|  | eventTalkStepBreak(player) - Finishes talkTurn and says a goodbye | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  |  | ||||||
|  | * Rent price and time seems to be hardcoded into the client. Price is always 800gil and time is 10m. | ||||||
|  | * The func eventSetChocoboName *requires* the actor with id `1080101` to be present in the client instance or it will crash (thanks Jorge for finding that). | ||||||
|  | * Special spawn codes must be sent for getting your chocobo or renting for it to work properly. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | local rentalPrice = 800; | ||||||
|  | local rentalTime = 10; | ||||||
|  |  | ||||||
|  | local gcIssuances = { | ||||||
|  | 	[1500006] = 2001004, | ||||||
|  | 	[1500061] = 2001005, | ||||||
|  | 	[1000840] = 2001006, | ||||||
|  | 	[1500059] = 0 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | local startAppearances = { | ||||||
|  | 	[1500006] = CHOCOBO_LIMSA1, | ||||||
|  | 	[1500061] = CHOCOBO_GRIDANIA1, | ||||||
|  | 	[1000840] = CHOCOBO_ULDAH1 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | local cityExits = { | ||||||
|  | 	[1500006] = {133, -6.032, 46.356, 132.572, 3.034}, | ||||||
|  | 	[1500061] = {150, 333.271, 5.889, -943.275, 0.794}, | ||||||
|  | 	[1000840] = {170, -26.088, 181.846, -79.438, 2.579}, | ||||||
|  |     [1500059] = {172, -2133.028, 15.476, -421.471, 1.5} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName)	 | ||||||
|  |     local classId = npc:GetActorClassId(); | ||||||
|  | 	local curLevel = 20; -- TODO: pull from character | ||||||
|  | 	local hasIssuance = player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(gcIssuances[classId]); | ||||||
|  | 	local hasChocobo = player.hasChocobo; | ||||||
|  | 	 | ||||||
|  | 	if (hasChocobo == false) then -- Let GMs auto have the issuance for debugging  | ||||||
|  | 		hasIssuance = true; | ||||||
|  | 	end	 | ||||||
|  |  | ||||||
|  | 	local hasFunds = (player:GetCurrentGil() >= rentalPrice); | ||||||
|  |      | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     if ((classId == 1000840) and (player:HasQuest(110009))) then -- Cross-script Man0u0 dialog | ||||||
|  |         local sequence = player:GetQuest(110009):getSequence(); | ||||||
|  |          | ||||||
|  |         if (sequence == 0) then | ||||||
|  |             callClientFunction(player, "delegateEvent", player, GetStaticActor("Man0u0"), "processEvent000_13");  | ||||||
|  |         elseif (sequence == 10) then | ||||||
|  |             callClientFunction(player, "delegateEvent", player, GetStaticActor("Man0u0"), "processEvent020_7");  | ||||||
|  |         else | ||||||
|  |             player:EndEvent(); | ||||||
|  |         end | ||||||
|  |     else | ||||||
|  |         callClientFunction(player, "eventTalkWelcome", player); | ||||||
|  |          | ||||||
|  |         local menuChoice = callClientFunction(player, "eventAskMainMenu", player, curLevel, hasFunds, hasIssuance, hasChocobo, hasChocobo, 0); | ||||||
|  |      | ||||||
|  |         if (menuChoice == 1) then -- Issuance option | ||||||
|  |          | ||||||
|  |             callClientFunction(player, "eventTalkMyChocobo", player); | ||||||
|  |             local nameResponse = callClientFunction(player, "eventSetChocoboName", true); | ||||||
|  |      | ||||||
|  |             if (nameResponse == "") then -- Cancel Chocobo naming | ||||||
|  |                 callClientFunction(player, "eventCancelChocoboName", player); | ||||||
|  |                 callClientFunction(player, "eventTalkStepBreak", player); | ||||||
|  |                 player:EndEvent(); | ||||||
|  |                 return; | ||||||
|  |             else		 | ||||||
|  |                 local appearance = startAppearances[classId];			 | ||||||
|  |                 player:IssueChocobo(appearance, nameResponse); | ||||||
|  |                  | ||||||
|  |                 callClientFunction(player, "eventAfterChocoboName", player);			 | ||||||
|  |      | ||||||
|  |                 --Add Chocobo License and remove issuance | ||||||
|  |                 if (player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(2001007) == false) then | ||||||
|  |                     player:GetItemPackage(INVENTORY_KEYITEMS):AddItem(2001007); | ||||||
|  |                 end | ||||||
|  |                 player:GetItemPackage(INVENTORY_KEYITEMS):RemoveItem(gcIssuances[classId], 1); | ||||||
|  |                  | ||||||
|  |                 --Warp with the special chocobo warp mode. | ||||||
|  |                 mountChocobo(player);			 | ||||||
|  |                 GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_CHOCOBO_GET, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]);		 | ||||||
|  |             end | ||||||
|  |                      | ||||||
|  |         elseif(menuChoice == 2) then -- Summon Bird | ||||||
|  |             mountChocobo(player); | ||||||
|  |             GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_NO_ANIM, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]);		 | ||||||
|  |         elseif(menuChoice == 3) then -- Change Barding | ||||||
|  |             callClientFunction(player, "eventTalkStepBreak", player); | ||||||
|  |         elseif(menuChoice == 5) then -- Rent Bird | ||||||
|  |             mountChocobo(player, true, 10); | ||||||
|  |             GetWorldManager():DoZoneChange(player, cityExits[classId][1], nil, 0, SPAWN_CHOCOBO_RENTAL, cityExits[classId][2], cityExits[classId][3], cityExits[classId][4], cityExits[classId][5]); | ||||||
|  |         else | ||||||
|  |             callClientFunction(player, "eventTalkStepBreak", player); | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |      | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function mountChocobo(player, isRental, rentalMinutes) | ||||||
|  | 	if (isRental) then		 | ||||||
|  | 		player:ChangeMusic(64);		 | ||||||
|  | 		player:StartChocoboRental(rentalMinutes); | ||||||
|  | 	else | ||||||
|  | 		player:ChangeMusic(83); | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	player:SendMountAppearance(); | ||||||
|  | 	player:SetMountState(1); | ||||||
|  | 	player:ChangeSpeed(0.0, 3.6, 9.0, 9.0); | ||||||
|  | 	player:ChangeState(15);	 | ||||||
|  | end | ||||||
| @@ -0,0 +1,43 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCompanyBuffer Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkWelcome(player, boolean)       - Welcome dialog.  Boolean seems to be related to rank? | ||||||
|  | eventTalkBufEffect()                    - Dialog for applying Sanction | ||||||
|  | eventTalkBufEffectAfter(player)         - Dialog after applying Sanction | ||||||
|  | eventTalkStepBreak()                    - Returns to NPC's neutral state | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |     return false, false, 0, 0;   | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local gcRep = {  | ||||||
|  |     [1500388] = 1, -- Maelstrom Representative | ||||||
|  |     [1500389] = 2, -- Adder Representative | ||||||
|  |     [1500390] = 3, -- Flame Representative | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |     local playerGC = player.gcCurrent; | ||||||
|  |     local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah}; | ||||||
|  |      | ||||||
|  |     local choice = callClientFunction(player, "eventTalkWelcome", player, true); | ||||||
|  |      | ||||||
|  |     if (choice == 1 and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then | ||||||
|  |         callClientFunction(player, "eventTalkBufEffect"); | ||||||
|  |         callClientFunction(player, "eventTalkBufEffectAfter", player); | ||||||
|  |         -- TODO: Add Sanction buff | ||||||
|  |     else | ||||||
|  |         player:SendMessage(0x20, "", "Quit hex editing your memory."); | ||||||
|  |     end | ||||||
|  |     | ||||||
|  |     callClientFunction(player, "eventTalkStepBreak");  | ||||||
|  |     player:endEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCompanyGLPublisher Script | ||||||
|  |  | ||||||
|  | xtx_gcRank for GC Rank values | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | talkOutsider()                              - Dialog for no affiliated with GC.  Seems to always read Maelstrom? | ||||||
|  | talkOfferWelcome(unk1)                      - Errors | ||||||
|  | askCompanyLeve()                            - Errors | ||||||
|  | askLeveDetail(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8)                             - Errors | ||||||
|  |  | ||||||
|  | eventGLDifficulty()                         - Difficulty window, returns player choice | ||||||
|  | eventGLStart(leveName, difficulty, unk1)    - leveName from xtx_guildleve | ||||||
|  |  | ||||||
|  | talkAfterOffer() | ||||||
|  | talkOfferLimit() | ||||||
|  |  | ||||||
|  | finishTalkTurn()                                            - Resets NPC target/facing | ||||||
|  |  | ||||||
|  | eventGLPlay(leveName, guardianFavor, favorCost, difficulty) - Menu for active levequest | ||||||
|  | eventGLShinpu(guardianFavor, favorCost)                     - Menu to accept favor buff.  evenGLPlay() calls it | ||||||
|  | eventGLThanks()                                             - Errors | ||||||
|  |  | ||||||
|  | eventGLReward(                      -- Leve reward screen | ||||||
|  |     guildleveId,  | ||||||
|  |     clearTime,  | ||||||
|  |     missionBonus,  | ||||||
|  |     difficultyBonus,  | ||||||
|  |     factionNumber,  | ||||||
|  |     factionBonus,  | ||||||
|  |     factionCredit,  | ||||||
|  |     glRewardItem,  | ||||||
|  |     glRewardNumber,  | ||||||
|  |     glRewardSubItem,  | ||||||
|  |     glRewardSubNumber,  | ||||||
|  |     difficulty | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | gcOfficer = {  | ||||||
|  | [1500222] = 1, -- Storm Sergeant Hammil  | ||||||
|  | [1500223] = 1, -- Storm Sergeant Sternn  | ||||||
|  | [1500224] = 2, -- Serpent Sergeant Cordwyk  | ||||||
|  | [1500225] = 2, -- Serpent Sergeant Lodall   | ||||||
|  | [1500226] = 3, -- Flame Sergeant Byrne   | ||||||
|  | [1500227] = 3, -- Flame Sergeant Dalvag | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |  | ||||||
|  |     callClientFunction(player, "talkOutsider"); | ||||||
|  |  | ||||||
|  |     callClientFunction(player, "finishTalkTurn"); | ||||||
|  |     player:endEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCompanyGuide Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkWelcome()                              - Dialog for new recruits | ||||||
|  | eventTalkProvisional()                          - Message for when rank isn't high enough? | ||||||
|  | eventTalkExclusive()                            - Message for wrong GC. | ||||||
|  | eventTalkComMember(nil, npc, isFoundationDay)   - Information menus for various GC related activities | ||||||
|  | eventTalkStepBreak()                            - Returns to NPC's neutral state | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |     return false, false, 0, 0;   | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local gcRep = {  | ||||||
|  |     [1001737] = 1, -- Maelstrom Representative | ||||||
|  |     [1001738] = 2, -- Adder Representative | ||||||
|  |     [1001739] = 3, -- Flame Representative | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |     local playerGC = player.gcCurrent; | ||||||
|  |     local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah}; | ||||||
|  |     local npcGC = gcRep[npc:GetActorClassId()];     | ||||||
|  |      | ||||||
|  |     if (playerGC ~= npcGC and playerGCRanks[playerGC] == 127) then | ||||||
|  |         callClientFunction(player, "eventTalkWelcome"); | ||||||
|  |     elseif (playerGC == npcGC and playerGCRanks[playerGC] == 127) then | ||||||
|  |         callClientFunction(player, "eventTalkProvisional"); | ||||||
|  |     elseif (playerGC ~= npcGC and playerGCRanks[playerGC] ~= 127) then | ||||||
|  |         callClientFunction(player, "eventTalkExclusive"); | ||||||
|  |     elseif (playerGC == npcGC and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then | ||||||
|  |         callClientFunction(player, "eventTalkComMember", nil, npc, true); | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     callClientFunction(player, "eventTalkStepBreak");  | ||||||
|  |     player:endEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCompanyOfficer Script | ||||||
|  |  | ||||||
|  | xtx_gcRank for GC Rank values | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkWelcome()                              - Welcome dialog | ||||||
|  | eventTalkWelcomeQuest()                         - Same as Welcome dialog? | ||||||
|  | eventTalkPreJoin()                              - Dialog for starting GC rank? | ||||||
|  | eventTalkExclusive()                            - Dialog to play when you're not of that GC? | ||||||
|  | eventTalkJoinedOnly()                           - Reads like chat-end dialog for your GC. | ||||||
|  | eventTalkJoined(gcRank, gcRank,  isCanAfford, isShowPromotion)  - Menu to ask about/for promotion | ||||||
|  |  | ||||||
|  | eventDoRankUp(gcRank, gcRank)                   - Plays rank-up animation and opens GC window.  | ||||||
|  | eventRankUpDone(???, ???)                       - Has your character do the GC salute?  Values seem to do nothing? | ||||||
|  | eventRankCategoryUpBefore(gcRank)               - 11/21/31  - Mentions which GC quest you need to clear to continue promotion | ||||||
|  | eventRankCategoryUpAfter()                      - Follow-up dialog after ranking up | ||||||
|  | eventTalkQuestUncomplete()                      - Quest prerequisite dialog for ranking up to Second Lieutenant (1.23b rank cap) | ||||||
|  | eventTalkFestival()                             - Foundation Day 2011 event dialog.  Server needs to reward 1000 GC seals after. | ||||||
|  | eventTalkFestival2()                            - Foundation Day 2011 event dialog.  Seems to reward more seals, unsure how many. | ||||||
|  | eventTalkFestival2012(value)                    - Foundation Day 2012 event dialog.  Rewards amount of seals dictated by value, retail used 5000. | ||||||
|  |  | ||||||
|  | eventTalkStepBreak()                            - Resets NPC target/facing | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | gcOfficer = {  | ||||||
|  | [1500199] = 1, -- Limsa Officer | ||||||
|  | [1500200] = 2, -- Grid Officer | ||||||
|  | [1500198] = 3, -- Flame Officer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |  | ||||||
|  |     playerGC = player.gcCurrent; | ||||||
|  |     playerGCSeal = 1000200 + playerGC; | ||||||
|  |     playerCurrentRank = 13; | ||||||
|  |     playerRankUpCost = 1500; | ||||||
|  |     playerNextRank = 15; | ||||||
|  |     currentRankCap = 31; -- Second Lieutenant | ||||||
|  |     npcId = npc:GetActorClassId(); | ||||||
|  |      | ||||||
|  |     if playerGC == gcOfficer[npcId] then | ||||||
|  |         callClientFunction(player, "eventTalkWelcome"); | ||||||
|  |         if playerCurrentRank < currentRankCap then | ||||||
|  |             if player:GetItemPackage(INVENTORY_CURRENCY):HasItem(playerGCSeal, playerRankUpCost) then | ||||||
|  |                 -- Show Promotion window, allow paying | ||||||
|  |                 local choice = callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, true, true); | ||||||
|  |                  | ||||||
|  |                 -- If promotion accepted | ||||||
|  |                 if choice == 1 then | ||||||
|  |                     callClientFunction(player, "eventDoRankUp", playerNextRank, playerNextRank); | ||||||
|  |                    -- TODO: Table GC info or get it in source/sql.  Handle actual upgrade of GC rank/seal cap/cost/etc. | ||||||
|  |                 end | ||||||
|  |     | ||||||
|  |             else | ||||||
|  |                 -- Show Promotion window, show dialog you can't afford promotion | ||||||
|  |                 callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, false, true); | ||||||
|  |             end | ||||||
|  |         else | ||||||
|  |             callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank); | ||||||
|  |         end | ||||||
|  |          | ||||||
|  |         callClientFunction(player, "eventTalkJoinedOnly"); | ||||||
|  |     else | ||||||
|  |         callClientFunction(player, "eventTalkExclusive"); | ||||||
|  |     end | ||||||
|  |     callClientFunction(player, "eventTalkStepBreak"); | ||||||
|  |     player:endEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										510
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanyShop.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										510
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanyShop.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										464
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanySupply.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										464
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanySupply.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  |  | ||||||
							
								
								
									
										131
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								Data/scripts/base/chara/npc/populace/PopulaceCompanyWarp.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceCompanyWarp Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkWelcome(player)        - Start Text | ||||||
|  | eventAskMainMenu(player, index) - Shows teleport menu, hides the teleport location at index value to prevent warping to the spot you're at | ||||||
|  | eventAfterWarpOtherZone(player) - Fades out for warp | ||||||
|  | eventTalkStepBreak()            - Holds the client up for whatever reason? | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | warpNpc = | ||||||
|  | { --[actorId] = {warpIndex, cityId}   -- ()s around name indicate missing NPC + Aethernet | ||||||
|  |     [1500321] = {1, 1}, -- (Storm Private Gardner)       | ||||||
|  |     [1500331] = {2, 1}, -- (Storm Private Rich) | ||||||
|  |     [1500323] = {3, 1}, -- (Storm Private Potter) | ||||||
|  |     [1500330] = {4, 1}, -- (Storm Private Hunt) | ||||||
|  |     [1500322] = {5, 1}, -- (Storm Private Abel) | ||||||
|  |     [1500332] = {6, 1}, -- (Storm Private Stone) | ||||||
|  |     [1500339] = {7, 1}, -- (Storm Private Holt) | ||||||
|  |     [1500324] = {1, 2}, -- serpent_private_white | ||||||
|  |     [1500334] = {2, 2}, -- serpent_private_hill   | ||||||
|  |     [1500326] = {3, 2}, -- serpent_private_carver     | ||||||
|  |     [1500333] = {4, 2}, -- serpent_private_stone | ||||||
|  |     [1500325] = {5, 2}, -- serpent_private_holmes | ||||||
|  |     [1500335] = {6, 2}, -- serpent_private_kirk | ||||||
|  |     [1500327] = {1, 3}, -- flame_private_newton | ||||||
|  |     [1500337] = {2, 3}, -- (Flame Private Tanner) | ||||||
|  |     [1500329] = {3, 3}, -- (Flame Private Morning) | ||||||
|  |     [1500336] = {4, 3}, -- (Flame Private Covey) | ||||||
|  |     [1500328] = {5, 3}, -- flame_private_allen     | ||||||
|  |     [1500338] = {6, 3}, -- (Flame Private Yar) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | aethernet =  | ||||||
|  | { | ||||||
|  |     {   -- 1: Limsa | ||||||
|  |         {zone = 230, x = -424.140, y = 42.000, z = 371.988, r = -2.472},        -- 1 - Aetheryte Plaza | ||||||
|  |         {zone = 133, x = -439.744, y = 40.000, z = 234.376, r = 0.287},         -- 2 - Drowning Wench | ||||||
|  |         {zone = 230, x = -498.131, y = 43.622, z = 60.818,  r = 0.254},         -- 3 - The Bismarck | ||||||
|  |         {zone = 230, x = -759.331, y = 12.000, z = 239.413, r = -0.869},        -- 4 - Ferry Docks   | ||||||
|  |         {zone = 230, x = -623.582, y = 4.000,  z = 369.318, r = 1.736},         -- 5 - Fisherman's Bottom         | ||||||
|  |         {zone = 230, x = -525.536, y = 18.000, z = 173.735, r = 3.082},         -- 6 - The Octant | ||||||
|  |         {zone = 133, x = -231.711, y = 12.000, z = 193.573, r = -0.786},        -- 7 - Procession of Terns | ||||||
|  |         {zone = 128, x = -20.783,  y = 42.214, z = 146.946, r = 2.046},         -- 8 - Zephyr Gate | ||||||
|  |     }, | ||||||
|  |     {   -- 2: Gridania | ||||||
|  |         {zone = 206, x = -107.878,  y = 17.524, z = -1343.871, r = 0.657},      -- 1 - Aetheryte Plaza | ||||||
|  |         {zone = 155, x =  96.868,   y = 3.480,  z = -1211.040, r = 2.582},      -- 2 - Carline Canopy | ||||||
|  |         {zone = 206, x =  86.942,   y = 19.789, z = -1420.891, r = 2.965},      -- 3 - Atelier Fen-Yil | ||||||
|  |         {zone = 206, x =  -84.621,  y = 19.061, z = -1502.665, r = 0.756},      -- 4 - Whistling Miller | ||||||
|  |         {zone = 206, x =  205.101,  y = 9.526,  z = -1245.405, r = -1.749},     -- 5 - Quiver's Hold | ||||||
|  |         {zone = 206, x =  160.578,  y = 25.061, z = -1556.662, r = 1.896},      -- 6 - Wailing Barracks | ||||||
|  |         {zone = 150, x = 318.838,   y = 4.036,  z = -992.071,  r = -0.307},     -- 7 - Mistalle Bridges | ||||||
|  |         {zone = 206, x = -192.167,  y = 4.466,  z = -1061.777, r = -0.026},     -- 8 - Berlends Bridges | ||||||
|  |     }, | ||||||
|  |     {   -- 3: Ul'dah | ||||||
|  |         {zone = 175, x = -190.574,  y = 190.000, z = 18.086,  r = 2.190},       -- 1 - Aetheryte Plaza | ||||||
|  |         {zone = 175, x = -36.513,   y = 192.000, z = 37.130,  r = -0.490},      -- 2 - Quicksand | ||||||
|  |         {zone = 209, x = -192.971,  y = 230.000, z = 209.348, r = 2.860},       -- 3 - Frondale's Phrontistery | ||||||
|  |         {zone = 209, x = -60.243,   y = 200.000, z = 257.718, r = -1.276},      -- 4 - Onyx Lane | ||||||
|  |         {zone = 209, x = -147.633,  y = 198.000, z = 160.064, r = -1.600},      -- 5 - Gold Court | ||||||
|  |         {zone = 209, x = -263.776,  y = 202.000, z = 206.699, r = -3.135},      -- 6 - Arrzaneth Ossuary | ||||||
|  |         {zone = 170, x = -29.721,   y = 182.635, z = -76.313, r = 2.625},       -- 7 - Gate of Nald | ||||||
|  |         {zone = 170, x = 129.957,   y = 183.862, z = 220.719, r = 1.515},       -- 8 - Gate of Thal | ||||||
|  |     }      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |     local passLimsa = 2001014; | ||||||
|  |     local passGrid  = 2001015; | ||||||
|  |     local passUldah = 2001016; | ||||||
|  |     passCheck = 1;  -- 0 = Check player for Aetherpass keyitem.  1 = Ignore it. | ||||||
|  |      | ||||||
|  |     npcId = npc:GetActorClassId(); | ||||||
|  |     city = warpNpc[npcId][2]; | ||||||
|  |      | ||||||
|  |     if (city == 1) then | ||||||
|  |         if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passLimsa) then | ||||||
|  |             passCheck = 1; | ||||||
|  |         else | ||||||
|  |             if (passCheck == 0) then callClientFunction(player, "eventTalkWelcome", player); end | ||||||
|  |         end; | ||||||
|  |     elseif (city == 2) then | ||||||
|  |       --  if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passGrid) then | ||||||
|  |             passCheck = 1; | ||||||
|  |        -- else | ||||||
|  |          --  if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end | ||||||
|  |         --end; | ||||||
|  |     elseif (city == 3) then | ||||||
|  |         if (player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passUldah)) then | ||||||
|  |             passCheck = 1; | ||||||
|  |         else | ||||||
|  |             if (passCheck == 0) then callClientFunction(player, "eventTalkWelcome", player); end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     if (passCheck == 1) then | ||||||
|  |         choice = callClientFunction(player, "eventAskMainMenu", player, warpNpc[npcId][1]); | ||||||
|  |      | ||||||
|  |          | ||||||
|  |         if (choice ~= 0) then | ||||||
|  |              | ||||||
|  |              | ||||||
|  |             | ||||||
|  |            callClientFunction(player, "eventAfterWarpOtherZone", player); | ||||||
|  |            wait(1); | ||||||
|  |            player:EndEvent(); | ||||||
|  |             local player_zone = player:GetPos()[5]; | ||||||
|  |             spawnType = 0x0A; | ||||||
|  |             if (player_zone == aethernet[city][choice].zone) then | ||||||
|  |                  | ||||||
|  |                 GetWorldManager():DoPlayerMoveInZone(player, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r, spawnType);     | ||||||
|  |             else | ||||||
|  |                 GetWorldManager():DoZoneChange(player, aethernet[city][choice].zone, nil, 0, spawnType, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r);     | ||||||
|  |             end; | ||||||
|  |         else | ||||||
|  |             player:EndEvent(); | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |      | ||||||
|  | end | ||||||
							
								
								
									
										68
									
								
								Data/scripts/base/chara/npc/populace/PopulaceFlyingShip.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								Data/scripts/base/chara/npc/populace/PopulaceFlyingShip.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceFlyingShip Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventIn(player, hasTicket, nil?, travelPrice) - If hasTicket == nil, say no money text. | ||||||
|  | eventOut(isAborting) - Set isAborting to 30010 if player didn't "use" the airship. Shows no refund warning. | ||||||
|  | eventNG(player) - Message said when player is talking to the wrong npc. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  | 	 | ||||||
|  | 	-- Special case for A Slippery Stone and Cutthroat Prices | ||||||
|  | 	if (player:HasQuest(110737) == true) then | ||||||
|  | 		require ("quests/etc/etc3g3"); | ||||||
|  | 		local quest = player:GetQuest("Etc3g3"); | ||||||
|  | 		if (quest:GetSequence() == SEQ_000) then			 | ||||||
|  | 			local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent_005"); | ||||||
|  | 			if (choice == 1) then | ||||||
|  | 				quest:StartSequence(SEQ_001); | ||||||
|  | 				addPlayerToAirship(player, 2); | ||||||
|  | 			end						 | ||||||
|  | 			player:EndEvent(); | ||||||
|  | 			return; | ||||||
|  | 		end | ||||||
|  | 	elseif (player:HasQuest(110728) == true) then | ||||||
|  | 		require ("quests/etc/etc3u3"); | ||||||
|  | 		local quest = player:GetQuest("Etc3u3"); | ||||||
|  | 		if (quest:GetSequence() == SEQ_000) then			 | ||||||
|  | 			local choice = callClientFunction(player, "delegateEvent", player, quest, "processEvent_005"); | ||||||
|  | 			if (choice == 1) then | ||||||
|  | 				quest:StartSequence(SEQ_001); | ||||||
|  | 				addPlayerToAirship(player, 3); | ||||||
|  | 			end						 | ||||||
|  | 			player:EndEvent(); | ||||||
|  | 			return; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	-- Otherwise normal operation | ||||||
|  | 	callClientFunction(player, "eventIn", player, false, nil, 5); | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function addPlayerToAirship(player, city) | ||||||
|  | 	if (city == 1) then | ||||||
|  | 		-- Limsa Airship | ||||||
|  | 		GetWorldManager():WarpToPosition(player, -764.519, -3.146, 384.154, 1.575); | ||||||
|  | 		--GetWorldManager():AddPlayerToShipList(player, 2); | ||||||
|  | 	elseif (city == 2) then | ||||||
|  | 		-- Gridania Airship | ||||||
|  | 		GetWorldManager():WarpToPosition(player, 54.47, -7, -1198.54, -0.02); | ||||||
|  | 		--GetWorldManager():AddPlayerToShipList(player, 3); | ||||||
|  | 	elseif (city == 3) then | ||||||
|  | 		-- Ul'dah Airship | ||||||
|  | 		GetWorldManager():WarpToPosition(player, -126.580, 271.2, 156.435, -1.35); | ||||||
|  | 		--GetWorldManager():AddPlayerToShipList(player, 4); | ||||||
|  | 	end | ||||||
|  | end | ||||||
| @@ -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 | ||||||
| @@ -0,0 +1,381 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulacePassiveGLPublisher | ||||||
|  |  | ||||||
|  | Operates the Local Levequest selection menus. | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | askOfferPack(player)  | ||||||
|  |     Desc: Show class selection menu. | ||||||
|  |     Params: * player		- The player actor. | ||||||
|  |     Returns: Value dictating which item on the list was selected (1-8 for class, nil if exited/canceled) | ||||||
|  |  | ||||||
|  | askOfferRank(player) | ||||||
|  |     Desc: Show Level selection menu. | ||||||
|  |     Params: * player		- The player actor. | ||||||
|  |     Returns: Value dictating which item on the list was selected (1 = Lv01, 2 = Lv20, 3 = Lv40, nil if exited/canceled) | ||||||
|  |  | ||||||
|  | askOfferQuest(player, ?, questId1, questId2, questId3, questId4, questId5, questId6, questId7, questId8) | ||||||
|  |     Desc: Show Leve quest selection menu with up to 8 questId entries | ||||||
|  |     Params: * player		- The player actor. | ||||||
|  | 			* ?				- Unused param. Capture has a 2. | ||||||
|  | 			* questId 1-8	- The local levequests available up to 8 quests. | ||||||
|  |     Returns: 1 through 8 for an accepted leve in the order sent, -1 for hitting "Return", and Nil for "Cancel" | ||||||
|  |      | ||||||
|  | confirmOffer(player, questId) | ||||||
|  |     Desc: Opens prompt asking whether to activate the leve and begin it. | ||||||
|  |     Params: * player		- The player actor. | ||||||
|  | 			* questId		- The quest being confirmed. | ||||||
|  |     Returns: Boolean - True on Yes, false on No or hitting escape. | ||||||
|  |  | ||||||
|  | confirmMaxOffer(player) | ||||||
|  |     Desc: Opens ask widget stating you'll be capped on leves after accepting. | ||||||
|  |     Params: * player		- The player actor. Unused. | ||||||
|  |     Returns: Boolean - True on Accept, false on "Quit" or hitting escape. | ||||||
|  |      | ||||||
|  | talkOfferWelcome(player, numAllowance) | ||||||
|  |     Desc: NPC intro dialog as well as stating your available leve allowances. | ||||||
|  |     Params: * player		- The player actor. | ||||||
|  | 			* numAllowance	- The number of leve allowances the player still has. | ||||||
|  |  | ||||||
|  | talkOfferDecide() | ||||||
|  |     Desc: Makes the NPC say dialog following the acceptance of a leve. | ||||||
|  |     Params: None | ||||||
|  |   | ||||||
|  | talkOfferMaxOver() | ||||||
|  |     Desc: Makes the NPC say dialog stating the player is carrying too many leves currently. | ||||||
|  |     Params: None | ||||||
|  | 	     | ||||||
|  | finishTalkTurn() | ||||||
|  | 	Desc: Ends the npc actor's turn towards you. Call this at the end of the script or the  | ||||||
|  | 		  npc will be stuck "facing" the player. | ||||||
|  | 	Params: None | ||||||
|  |      | ||||||
|  | selectDiscardGuildleve() | ||||||
|  |     Desc: Opens the Journal widget to select a leve to discard. This is a follow-up to askDiscardGuildleve(). | ||||||
|  |     Params: None | ||||||
|  |     Returns: Quest Actor | ||||||
|  |      | ||||||
|  | confirmJournal(questId, difficulty, unused, itemsCompleted, remainingMats, hasMaterials, unused) | ||||||
|  |     Desc: Opens askJournalDetailWidget displaying current status of the leve. | ||||||
|  |     Params: * questId		- The current quest being confirmed. | ||||||
|  | 			* difficulty	- The difficulty of the quest. | ||||||
|  | 			* unused		- Unused param. | ||||||
|  | 			* itemsComplete	- Sets the number of items crafted. | ||||||
|  | 			* remainingMats	- Sets the remaining materials. | ||||||
|  | 			* hasMaterials	- If set to 1, shows the progress section. | ||||||
|  | 			* unused		- While loaded into widget, it doesn't do anything with this journalType (13). | ||||||
|  |     Returns: True on "Exchange", Nil on "Return" or hitting Escape key   | ||||||
|  |  | ||||||
|  | askDiscardGuildleve() | ||||||
|  |     Desc: Opens an ask widget, stating the player cannot accept any more guildleves and if they'd want to return one to make room. | ||||||
|  |     Params: None | ||||||
|  |     Returns: Boolean | ||||||
|  |  | ||||||
|  | confirmDiscardGuildleve(?, questId, guildleveId) | ||||||
|  |     Desc: Opens an ask widget, confirming the returning of the selected guildleve. | ||||||
|  |     Params: * ?				- Most likely a player actor, but unused. | ||||||
|  | 			* questId		- The dialog is "Returning <quest>. Are you certain?". This is the questId being returned. | ||||||
|  | 			* guildleveId	- This is mostly unused, Japanese localization has a weird switch to use this. Can be nil. | ||||||
|  |     Returns: Boolean | ||||||
|  |      | ||||||
|  | askRetryRegionalleve(questId, numAllowance)  | ||||||
|  |     Desc: Opens an ask widget to re-attempt leve questId while showing leveAllowances.  If no is selected, a second widget appears to confirm abandoning it.  | ||||||
|  |     Params: * questId		- The questId being retried. | ||||||
|  | 			* numAllowance	- The number of leve allowances the player still has. | ||||||
|  |     Returns: Menu1 -  Is 1 if yes is selected, 2 if no.  Nil if Escape is hit (resend function in this case?) | ||||||
|  |              Menu2 -  Is 1 if yes is selected (leve abandoned), 2 if no.  Nil if Menu1 isn't set to 2 | ||||||
|  | 			  | ||||||
|  | Notes: | ||||||
|  |  | ||||||
|  | 50141 - You have <num> leve allowances remaining. | ||||||
|  | 50142 - You have run out of leve allowances. You cannot accept any more levequests at this time. | ||||||
|  | 50143 - You cannot accept any more levequests at this time. | ||||||
|  |  | ||||||
|  | Local Leves: | ||||||
|  |  | ||||||
|  | ~~Limsa~~ | ||||||
|  |  | ||||||
|  | CRP: Baderon's New Counter (120007) | ||||||
|  | 	 The Mad Fisher (120017) | ||||||
|  | 	 Building Bridges (120039) | ||||||
|  | 	 High Stakes (120047) | ||||||
|  | 	 Training and Trees (120061) | ||||||
|  |  | ||||||
|  | BSM: Baderon's New Sword (120005) | ||||||
|  | 	 Got Ingots (120013) | ||||||
|  | 	 Ship Shape (120014) | ||||||
|  | 	 A Want of Weapons (120015) | ||||||
|  | 	 Skull Valley Delivery (120035) | ||||||
|  | 	 Fruit's of a Vintner's Whinings (120043) | ||||||
|  | 	 Premiums Paid (120051) | ||||||
|  | 	 Training and Trading (120059) | ||||||
|  | 	 Waiting on Weapons (120067) | ||||||
|  | 	  | ||||||
|  | ARM: Baderon's New Barbuts (120009) | ||||||
|  | 	 Seeing Sallets to the See (120019) | ||||||
|  | 	 A Step Ahead (120020) | ||||||
|  | 	 Mailed Sailors (120021) | ||||||
|  | 	 Running Rings (120036) | ||||||
|  | 	 Watching the Shore (120044) | ||||||
|  | 	 Watching the Knoll (120052) | ||||||
|  | 	 Rings Around the Rock (120063) | ||||||
|  | 	 Dead Ringers (120068) | ||||||
|  | 	  | ||||||
|  | GSM: Baderon's New Bands (120010) | ||||||
|  | 	 2 x 2 Eyes (120022) | ||||||
|  | 	 Going Brandanas (120041) | ||||||
|  | 	 Brand New Brands (120049) | ||||||
|  | 	 Staves to Fashion (120064) | ||||||
|  | 	  | ||||||
|  | LTW: Baderon's New Shoes (120008) | ||||||
|  | 	 The Mad Tanner (120018) | ||||||
|  | 	 Under Foot (120040) | ||||||
|  | 	 Shoeing the Shore (120048) | ||||||
|  | 	 Training and Tanning (120062) | ||||||
|  | 	  | ||||||
|  |  | ||||||
|  | WVR: Baderon's New Clothes (120006) | ||||||
|  | 	 The Mad Hatter (120016) | ||||||
|  | 	 Wear and Tear (120038) | ||||||
|  | 	 Outfitting the Shore (120046) | ||||||
|  | 	 Training and Tailoring (120060) | ||||||
|  | 	  | ||||||
|  | ALC: Baderon's New Soles (120011) | ||||||
|  | 	 A Sticky Situation (120023) | ||||||
|  | 	 Feeding Trainees (120042) | ||||||
|  | 	 Suffering Soldiers (120050) | ||||||
|  | 	 Training and Eating (120065) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CUL: Baderon's New Breakfast (120012) | ||||||
|  | 	 Tall, Cool One (120024) | ||||||
|  | 	 The Captain's Cravings (120025) | ||||||
|  | 	 A Feast Fit for an Admiral (120026) | ||||||
|  | 	 Supper at the Skull (120037) | ||||||
|  | 	 The Last Supper (120045) | ||||||
|  | 	 A Meal to Remember (120053) | ||||||
|  | 	 Just Desserts (120066) | ||||||
|  | 	 A Job Well Done (120069) | ||||||
|  |  | ||||||
|  | ~~Gridania~~ | ||||||
|  |  | ||||||
|  | CRP: A Mother's Carpentry (120203) | ||||||
|  | 	 Shields for the Masses (120211) | ||||||
|  | 	 Canes for the Citizens (120212) | ||||||
|  | 	 High Tension (120213) | ||||||
|  | 	 Bowing to Pressure (120223) | ||||||
|  | 	 Pole Positioning (120229) | ||||||
|  | 	 Driving up the Wall (120237) | ||||||
|  | 	 Restocking the Stockade (120245) | ||||||
|  | 	 Plinks Aplenty (120247) | ||||||
|  | 	  | ||||||
|  | BSM: A Mother's Metallurgy (120201) | ||||||
|  | 	 It's All in the File (120209) | ||||||
|  | 	 Training in Bentbranch (120221) | ||||||
|  | 	 Re-crating the Scene (120231) | ||||||
|  | 	 Training in Emerald Moss (120239) | ||||||
|  | 	  | ||||||
|  | ARM: A Mother's Foundry (120205) | ||||||
|  | 	 Tending to Tendons (120217) | ||||||
|  | 	 A Little Rusty (120225) | ||||||
|  | 	 Springripple Rising (120233) | ||||||
|  | 	 In Sod We Rust (120241) | ||||||
|  | 	  | ||||||
|  | GSM: A Mother's Jewelry (120206) | ||||||
|  | 	 The Band's Bands (120218) | ||||||
|  | 	 Dusting the Knuckles (120226) | ||||||
|  | 	 In Arm's Reach (120234) | ||||||
|  | 	 Knuckling Down (120242) | ||||||
|  | 	  | ||||||
|  | LTW: A Mother's Booties (120204) | ||||||
|  | 	 Strapped for Straps (120214) | ||||||
|  | 	 Fire and Hide (120215) | ||||||
|  | 	 Choke Hold (120216) | ||||||
|  | 	 Work of Friction (120224) | ||||||
|  | 	 Hungry Like the Wolves (120230) | ||||||
|  | 	 Back in the Harness (120238) | ||||||
|  | 	 Morbol Measures (120246) | ||||||
|  | 	 Harnessing Help (120248) | ||||||
|  |  | ||||||
|  | WVR: A Mother's Frippery (120202) | ||||||
|  | 	 Quelling Bloody Rumors (120210) | ||||||
|  | 	 Clearing Bentbranch (120222) | ||||||
|  |  	 Clearing Nine Ivies (120232) | ||||||
|  |  	 Clearing Emerald Moss (120240) | ||||||
|  |  | ||||||
|  | ALC: A Mother's Delicacies (120207) | ||||||
|  | 	 Mixing It Up (120219) | ||||||
|  | 	 Keeping It Green (120227) | ||||||
|  | 	 Arboreal Alchemy (120235) | ||||||
|  | 	 Growing Strains (120243) | ||||||
|  |  | ||||||
|  | CUL: A Mother's Muselix (120208) | ||||||
|  | 	 Better Baker's Bounty (120220) | ||||||
|  | 	 On a Full Belly (120228) | ||||||
|  | 	 A Well-Deserved Dinner (120236) | ||||||
|  | 	 Seafood Smorgasbord (120244) | ||||||
|  |  | ||||||
|  | ~~Uldah~~ | ||||||
|  |  | ||||||
|  | CRP: Momodi's Sturdy Supports (120403) | ||||||
|  | 	 The Walk of Death (120413) | ||||||
|  | 	 Pointed Ambitions (120425) | ||||||
|  | 	 Off With Their Heads (120435) | ||||||
|  | 	 Act of Pure Weevil (120443) | ||||||
|  |  | ||||||
|  | BSM: Momodi's Dancing Daggers (120401) | ||||||
|  | 	 Pointy Props (120409) | ||||||
|  | 	 Hammering the Point (120423) | ||||||
|  | 	 Molten Metal (120434) | ||||||
|  | 	 Looking to Horizon (120442) | ||||||
|  |  | ||||||
|  | ARM: Momodi's Sturdy Suits (120405) | ||||||
|  | 	 Battered and Bent (120415) | ||||||
|  | 	 Arming the Unarmed (120427) | ||||||
|  | 	 Provisioning Drybone (120437) | ||||||
|  | 	 Buckling Under (120445) | ||||||
|  |  | ||||||
|  | GSM: Momodi's Radiant Rings (120406) | ||||||
|  | 	 A Scarcity of Scepters (120416) | ||||||
|  | 	 Pleasure and Pain (120417) | ||||||
|  | 	 In the Sultana's Wake (120418) | ||||||
|  | 	 A Shining Example (120428) | ||||||
|  | 	 A Drybone Induction (120432) | ||||||
|  | 	 A Horizon Promotion (120440) | ||||||
|  | 	 A Bluefog Induction (120448) | ||||||
|  | 	 A Broken Water Promotion (120451) | ||||||
|  |  | ||||||
|  | LTW: Momodi's Sashed Shoes (120404) | ||||||
|  | 	 Showing Some Leg (120414) | ||||||
|  | 	 World-weary Souls (120426) | ||||||
|  | 	 Camp Drybone Cares (120436) | ||||||
|  | 	 I Would Walk 500 Malms (120444) | ||||||
|  |  | ||||||
|  | WVR: Momodi's Budget Breeches (120402) | ||||||
|  | 	 Just for Kecks (120410) | ||||||
|  | 	 Pants Make the Man (120411) | ||||||
|  | 	 Holes in Their Defense (120412) | ||||||
|  | 	 Hanging by a Thread (120424) | ||||||
|  | 	 Exposed to the Elements (120433) | ||||||
|  | 	 Busier Than the Blades (120441) | ||||||
|  | 	 A Spot in the Shade (120449) | ||||||
|  | 	 Fire on the Water (120452) | ||||||
|  |  | ||||||
|  | ALC: Momodi's Condiment Conundrum (120407) | ||||||
|  | 	 Exports of Import (120419) | ||||||
|  | 	 Fertile Lies (120420) | ||||||
|  | 	 A Blind Fool (120421) | ||||||
|  | 	 Saint Allene's Fire (120429) | ||||||
|  | 	 Treating Steel (120431) | ||||||
|  | 	 Blue in the Eye (120439) | ||||||
|  | 	 Preserving the Region (120447) | ||||||
|  | 	 Provisioning Broken Water (120450) | ||||||
|  |  | ||||||
|  | CUL: Momodi's Breakfast Bread (120408) | ||||||
|  | 	 Finger Food (120422) | ||||||
|  | 	 Irrational Behavior (120430) | ||||||
|  | 	 Tender Victuals (120438) | ||||||
|  | 	 Some Like It Wet (120446) | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  | 	  | ||||||
|  | local limsaLocalLeves = { | ||||||
|  | 	{120007, 120017, 120039, 120047, 120061},									--CRP | ||||||
|  | 	{120005, 120013, 120014, 120015, 120035, 120043, 120051, 120059, 120067},	--BSM | ||||||
|  | 	{120009, 120019, 120020, 120021, 120036, 120044, 120052, 120063, 120068},	--ARM | ||||||
|  | 	{120010, 120022, 120041, 120049, 120064},									--GSM | ||||||
|  | 	{120008, 120018, 120040, 120048, 120062},									--LTW | ||||||
|  | 	{120006, 120016, 120038, 120046, 120060},									--WVR | ||||||
|  | 	{120011, 120023, 120042, 120050, 120065},									--ALC | ||||||
|  | 	{120012, 120024, 120025, 120026, 120037, 120045, 120053, 120066, 120069}	--CUL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | local gridaniaLocalLeves = { | ||||||
|  | 	{120203, 120211, 120212, 120213, 120223, 120229, 120237, 120245, 120247},	--CRP | ||||||
|  | 	{120201, 120209, 120221, 120231, 120239},									--BSM | ||||||
|  | 	{120205, 120217, 120225, 120233, 120241},									--ARM | ||||||
|  | 	{120206, 120218, 120226, 120234, 120242},									--GSM | ||||||
|  | 	{120204, 120214, 120215, 120216, 120224, 120230, 120238, 120246, 120248},	--LTW | ||||||
|  | 	{120202, 120210, 120222, 120232, 120240},									--WVR | ||||||
|  | 	{120207, 120219, 120227, 120235, 120243},									--ALC | ||||||
|  | 	{120208, 120220, 120228, 120236, 120244}									--CUL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | local uldahLocalLeves = { | ||||||
|  | 	{120403, 120413, 120425, 120435, 120443},									--CRP | ||||||
|  | 	{120401, 120409, 120423, 120434, 120442},									--BSM | ||||||
|  | 	{120405, 120415, 120427, 120437, 120445},									--ARM | ||||||
|  | 	{120406, 120416, 120417, 120418, 120428, 120432, 120440, 120448, 120451},	--GSM | ||||||
|  | 	{120404, 120414, 120426, 120436, 120444},									--LTW | ||||||
|  | 	{120402, 120410, 120411, 120412, 120424, 120433, 120441, 120449, 120452},	--WVR | ||||||
|  | 	{120407, 120419, 120420, 120421, 120429, 120431, 120439, 120447, 120450},	--ALC | ||||||
|  | 	{120408, 120422, 120430, 120438, 120446}									--CUL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |  | ||||||
|  |     local leveAllowances = 16; | ||||||
|  |     local quest = 120438; | ||||||
|  | 	 | ||||||
|  |     callClientFunction(player, "confirmJournal", quest, 1); | ||||||
|  | 	callClientFunction(player, "confirmJournal", quest, 2); | ||||||
|  | 	callClientFunction(player, "confirmJournal", quest, 3); | ||||||
|  | 	callClientFunction(player, "confirmJournal", quest, 4); | ||||||
|  | 	--[[callClientFunction(player, "talkOfferWelcome", player, leveAllowances); | ||||||
|  |      | ||||||
|  |     while (true) do         | ||||||
|  |         -- Class Menu | ||||||
|  |         local classChoice = callClientFunction(player, "askOfferPack"); | ||||||
|  |       | ||||||
|  |         if (classChoice != nil) then             | ||||||
|  |             while (true) do | ||||||
|  |                 -- Level Difficulty Menu | ||||||
|  |                 local levelChoice = callClientFunction(player, "askOfferRank"); | ||||||
|  |                  | ||||||
|  |                 if levelChoice != nil then | ||||||
|  |                     if levelChoice == 1 then | ||||||
|  |                         local levequest = callClientFunction(player, "askOfferQuest", player, 1, 120438, 120025); | ||||||
|  |                         if (levequest != nil and levequest > 0) then | ||||||
|  |                             player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve)); | ||||||
|  |                             player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances); | ||||||
|  |                         end | ||||||
|  |                          | ||||||
|  |                     elseif levelChoice == 2 then | ||||||
|  |                         pickedLeve = callClientFunction(player, "askOfferQuest", player, 1, 120026, 120027); | ||||||
|  |                         if (pickedLeve != nil) or (pickedLeve != -1) then | ||||||
|  |                             player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve)); | ||||||
|  |                             player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances); | ||||||
|  |                         end | ||||||
|  |                          | ||||||
|  |                     elseif levelChoice == 3 then | ||||||
|  |                         pickedLeve = callClientFunction(player, "askOfferQuest", player, 1, 120028, 120029); | ||||||
|  |                         if (pickedLeve != nil) or (pickedLeve != -1) then | ||||||
|  |                             player:SendMessage(0x20, "", "[DEBUG] Leve : " .. tostring(pickedLeve)); | ||||||
|  |                             player:SendGameMessage(GetWorldMaster(), 50141, 0x20, leveAllowances) | ||||||
|  |                         end | ||||||
|  |                          | ||||||
|  |                     end | ||||||
|  |                 else     | ||||||
|  |                     break | ||||||
|  |                 end | ||||||
|  |             end             | ||||||
|  |         else | ||||||
|  |             break; | ||||||
|  |         end | ||||||
|  |     end]]-- | ||||||
|  |      | ||||||
|  |     callClientFunction(player, "finishTalkTurn"); | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function getAvailableLeves(class, rank) | ||||||
|  | 	 | ||||||
|  | end | ||||||
							
								
								
									
										145
									
								
								Data/scripts/base/chara/npc/populace/PopulaceRetainerManager.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Data/scripts/base/chara/npc/populace/PopulaceRetainerManager.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceRetainerManager Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkStep1(true) - Intro tutorial if no retainer | ||||||
|  | newEventTalkStep1(sayIntro) - Seems to be a post-Tanaka version of the intro???? | ||||||
|  | eventTalkStep2() - Choose retainer yourself (go to race select) or let npc do it | ||||||
|  | eventTaklSelectCutSeane(cutsceneName, actorClassId1, actorClassId2, actorClassId3, actorClassId4, actorClassId5) - Starts the advance cutscene to choose a retainer. 5 retainer actorClassId's are given. | ||||||
|  | eventTalkStep4(actorClassId) - Opens up the retainer naming dialog | ||||||
|  | eventTalkStepFinalAnswer(actorClassId) - Confirm Dialog | ||||||
|  | eventTalkStepError(errorCode) - Error dialog, 1: No Extra Retainers, 2: Server Busy. | ||||||
|  | eventTalkStepFinish() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |     return false, false, 0, 0;   | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |      | ||||||
|  |     local npcActorClass = npc:GetActorClassId() | ||||||
|  |     local retainerIndex = 3001100; | ||||||
|  |     local cutscene = "rtn0l010" -- Defaulting to Limsa for now for testing | ||||||
|  |      | ||||||
|  |     if npcActorClass == 1000166 then | ||||||
|  |         cutscene = "rtn0l010"; | ||||||
|  |         retainerIndex = 3001101; | ||||||
|  |     elseif npcActorClass == 1000865 then | ||||||
|  |         cutscene = "rtn0u010"; | ||||||
|  |         retainerIndex = 3002101;         | ||||||
|  |     elseif npcActorClass == 1001184 then | ||||||
|  |         cutscene = "rtn0g010"; | ||||||
|  |         retainerIndex = 3003101; | ||||||
|  |     else | ||||||
|  |         return; | ||||||
|  |     end | ||||||
|  |    | ||||||
|  |  | ||||||
|  |     introChoice = callClientFunction(player, "newEventTalkStep1", false); | ||||||
|  |      | ||||||
|  |     if (introChoice == 1) then           | ||||||
|  |          | ||||||
|  |         -- Choose Retainer or Random | ||||||
|  |         raceChoice = callClientFunction(player, "eventTalkStep2");   | ||||||
|  |          | ||||||
|  |         while (true) do  | ||||||
|  |  | ||||||
|  |              | ||||||
|  |             if (retainerChoice == 0) then            | ||||||
|  |                 raceChoice = callClientFunction(player, "eventTalkStep22");  | ||||||
|  |             end | ||||||
|  |                  | ||||||
|  |              | ||||||
|  |             if (raceChoice == 0) then  | ||||||
|  |                 --Choose random actorId from a valid set for the city | ||||||
|  |                  | ||||||
|  |                 math.randomseed(os.time()); | ||||||
|  |                 local randomRetainer = math.random(retainerIndex, (retainerIndex+74)); | ||||||
|  |                  | ||||||
|  |                 retainerName = callClientFunction(player, "eventTalkStep4", randomRetainer); | ||||||
|  |  | ||||||
|  |                 if (retainerName ~= "") then | ||||||
|  |                     confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", randomRetainer); | ||||||
|  |  | ||||||
|  |                     if (confirmChoice == 1) then | ||||||
|  |                         callClientFunction(player, "eventTalkStepFinish"); | ||||||
|  |                         player:EndEvent(); | ||||||
|  |                         return; | ||||||
|  |                     elseif (confirmChoice == 3) then | ||||||
|  |                         raceChoice = 0; | ||||||
|  |                     else | ||||||
|  |                         player:EndEvent(); | ||||||
|  |                         return; | ||||||
|  |                     end | ||||||
|  |                 else | ||||||
|  |                     callClientFunction(player, "eventTalkStepBreak"); | ||||||
|  |                     raceChoice = -1; | ||||||
|  |                 end  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             elseif (raceChoice > 0) and (raceChoice < 16) then                         | ||||||
|  |                 --Choose 5 random but correct actor ids for the city and race/tribe | ||||||
|  |                  | ||||||
|  |                 local retainerRace = ((retainerIndex) + (5*(raceChoice-1))); | ||||||
|  |                 local retainerRaceChoices = {retainerRace, retainerRace+1, retainerRace+2, retainerRace+3, retainerRace+4}; | ||||||
|  |                  | ||||||
|  |                 -- Randomize the appearance order of the available five | ||||||
|  |                 shuffle(retainerRaceChoices); | ||||||
|  |                  | ||||||
|  |                 retainerChoice = callClientFunction(player, "eventTaklSelectCutSeane", cutscene, retainerRaceChoices[1], retainerRaceChoices[2], retainerRaceChoices[3], retainerRaceChoices[4], retainerRaceChoices[5]); | ||||||
|  |                  | ||||||
|  |                 if (retainerChoice == -1) then | ||||||
|  |                     player:EndEvent(); | ||||||
|  |                     return;              | ||||||
|  |                 elseif (retainerChoice > 0) then                 | ||||||
|  |                     --Retainer chosen, choose name               | ||||||
|  |                     retainerName = callClientFunction(player, "eventTalkStep4", retainerRaceChoices[retainerChoice]); | ||||||
|  |                      | ||||||
|  |                     if (retainerName ~= "") then | ||||||
|  |                         confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", retainerRaceChoices[retainerChoice]); | ||||||
|  |                          | ||||||
|  |                         if (confirmChoice == 1) then | ||||||
|  |                             callClientFunction(player, "eventTalkStepFinish"); | ||||||
|  |                             player:EndEvent(); | ||||||
|  |                             return; | ||||||
|  |                         elseif (confirmChoice == 3) then | ||||||
|  |                             retainerChoice = 0; | ||||||
|  |                         else | ||||||
|  |                             player:EndEvent(); | ||||||
|  |                             return; | ||||||
|  |                         end | ||||||
|  |                     else | ||||||
|  |                         callClientFunction(player, "eventTalkStepBreak"); | ||||||
|  |                         raceChoice = -1;        | ||||||
|  |                     end | ||||||
|  |                      | ||||||
|  |                 end  | ||||||
|  |             else | ||||||
|  |                 break; | ||||||
|  |             end  | ||||||
|  |          | ||||||
|  |                  | ||||||
|  |         end | ||||||
|  |          | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |     player:EndEvent(); | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function shuffle(tbl) | ||||||
|  |   for i = #tbl, 2, -1 do | ||||||
|  |     local j = math.random(i) | ||||||
|  |     tbl[i], tbl[j] = tbl[j], tbl[i] | ||||||
|  |   end | ||||||
|  |   return tbl | ||||||
|  | end | ||||||
| @@ -0,0 +1,83 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | PopulaceSpecialEventCryer Script | ||||||
|  |  | ||||||
|  | Actor Class script to handle the 6 NPCs (technically 3, the actors were duped) involved in the Foundation Day 2011 & 2012 events.   | ||||||
|  | In 2011 they appear to be used for recruitment information for their respective Grand Company. | ||||||
|  | In 2012, they were used for exchanging Over-aspected Crystals/Clusters for GC seals as part of the ongoing Atomos event. | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | For 2011. | ||||||
|  | eventTalkStep0(joined)      - NPC dialog about joining their cause to fight back Imperials. joined = 0 or 1. Function has hardcoded actor IDs, won't work with 2012 versions | ||||||
|  | eventTalkNotGCmenber(npcGC) - NPC dialog when you're not part of their grand company. | ||||||
|  |  | ||||||
|  | For 2012. | ||||||
|  | eventTalkCrystalExchange(player, npcGC, hasCrystal) - NPC dialog explaining they want over-aspected crystals. Brings up crystal exchange prompt if hasCrystal = 1. | ||||||
|  | eventTalkCsOverflow(player, npcGC)                  - Error message that you can't hold the seals being offered. | ||||||
|  | eventTalkCrystalExchange2(player, npcGC)            - NPC dialog for accepting exchange of crystals for seals | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | local gcRep = {  | ||||||
|  |     [1001619] = 1, -- Maelstrom Representative 2011 | ||||||
|  |     [1002105] = 1, -- Maelstrom Representative 2012 | ||||||
|  |     [1001623] = 2, -- Adder Representative 2011 | ||||||
|  |     [1002109] = 2, -- Adder Representative 2012 | ||||||
|  |     [1001627] = 3, -- Flame Representative 2011 | ||||||
|  |     [1002113] = 3, -- Flame Representative 2012 | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, triggerName) | ||||||
|  |     local playerGC = player.gcCurrent; | ||||||
|  |     local npcId = npc:GetActorClassId(); | ||||||
|  |     local npcGC = gcRep[npcId];  | ||||||
|  |     local npcGCSeal = 1000200 + npcGC; | ||||||
|  |     local hasCrystal = 1; | ||||||
|  |     local crystal = 3020537; | ||||||
|  |     local cluster = 3020413; | ||||||
|  |     local eventMode = 2012; | ||||||
|  |      | ||||||
|  |     if eventMode == 2011 then | ||||||
|  |         if playerGC == 0 then | ||||||
|  |             callClientFunction(player, "eventTalkStep0", 0); | ||||||
|  |         elseif playerGC == npcGC then | ||||||
|  |             callClientFunction(player, "eventTalkStep0", 1);  | ||||||
|  |         else | ||||||
|  |             callClientFunction(player, "eventTalkNotGCmenber", npcGC); | ||||||
|  |         end | ||||||
|  |      | ||||||
|  |     elseif eventMode == 2012 then | ||||||
|  |         choice = callClientFunction(player, "eventTalkCrystalExchange", player, npcGC, hasCrystal); | ||||||
|  |          | ||||||
|  |         if choice == 1 then | ||||||
|  |             --callClientFunction(player, "eventTalkCsOverflow", player, npcGC); | ||||||
|  |             player:SendMessage(0x20, "", "You pretend to hand over four over-aspected crystals."); | ||||||
|  |             callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);  | ||||||
|  |             | ||||||
|  |             local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 1000, 1); | ||||||
|  |             if invCheck == INV_ERROR_SUCCESS then | ||||||
|  |                 player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, crystal, 1, npcGCSeal, 1, 4, 1000); | ||||||
|  |             end | ||||||
|  |         elseif choice == 2 then | ||||||
|  |             player:SendMessage(0x20, "", "You pretend to hand over an over-aspected cluster."); | ||||||
|  |             --callClientFunction(player, "eventTalkCsOverflow", player, npcGC); | ||||||
|  |             callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);  | ||||||
|  |              | ||||||
|  |             local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 3000, 1); | ||||||
|  |             if invCheck == INV_ERROR_SUCCESS then | ||||||
|  |                 player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, cluster, 1, npcGCSeal, 1, 1, 3000); | ||||||
|  |             end             | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										97
									
								
								Data/scripts/base/chara/npc/populace/PopulaceStandard.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Data/scripts/base/chara/npc/populace/PopulaceStandard.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | |||||||
|  | require("global"); | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | Populace Standard Script | ||||||
|  |  | ||||||
|  | Functions:  | ||||||
|  |  | ||||||
|  | eventSwitch(questId1, questId2, questId3, questId4, currentPage, maxPages, titleId)	- Shows a dialog box with which quest to trigger  | ||||||
|  | 																					  when more than one quest is active for this npc. | ||||||
|  |  | ||||||
|  | Notes: | ||||||
|  |  | ||||||
|  | This scripts fires for all normal standard ENpcs in the world. Because of how the FFXIV dialog system works, everything is technically | ||||||
|  | a quest; including the DefaultTalk responses. This script checks both static default quests and any relevant ones for that actor class | ||||||
|  | id. If only one exists; it is automatically triggered otherwise a dialog box will appear for the player to choose what quest to do. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName) | ||||||
|  | 	local chosenQuest = nil; | ||||||
|  |  | ||||||
|  | 	if (eventType == 1) then | ||||||
|  | 		local defaultTalk = player:GetDefaultTalkQuest(npc); | ||||||
|  | 		local tutorialTalk = player:GetTutorialQuest(npc); | ||||||
|  | 		local activeQuests = player:GetQuestsForNpc(npc); | ||||||
|  | 		local possibleQuests = {}; | ||||||
|  | 		 | ||||||
|  | 		-- Create the switch table for this npc | ||||||
|  | 		if (defaultTalk ~= nil and eventType == ETYPE_TALK) then | ||||||
|  | 			table.insert(possibleQuests, defaultTalk); | ||||||
|  | 		end | ||||||
|  | 		if (tutorialTalk ~= nil and eventType == ETYPE_TALK) then | ||||||
|  | 			table.insert(possibleQuests, tutorialTalk); | ||||||
|  | 		end | ||||||
|  | 		if (activeQuests ~= nil) then | ||||||
|  | 			for i=1,#activeQuests do | ||||||
|  | 				table.insert(possibleQuests, activeQuests[i]); | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		 | ||||||
|  | 		-- Either let the player choose the quest or start it if it's the only one. | ||||||
|  | 		if (#possibleQuests > 1) then | ||||||
|  | 			local currentPage = 0; | ||||||
|  | 			local numPages = math.floor((#possibleQuests-1)/4) + 1; | ||||||
|  | 			 | ||||||
|  | 			while (true) do | ||||||
|  | 				local page, index = callClientFunction(player, "switchEvent", possibleQuests[currentPage * 4 + 1], possibleQuests[currentPage * 4 + 2], possibleQuests[currentPage * 4 + 3], possibleQuests[currentPage * 4 + 4], currentPage + 1, numPages, 0x3F1); | ||||||
|  | 				 | ||||||
|  | 				if (page == 0) then | ||||||
|  | 					chosenQuest = possibleQuests[(currentPage * 4) + index]; | ||||||
|  | 					break; | ||||||
|  | 				elseif (page > 0) then | ||||||
|  | 					currentPage = page - 1; | ||||||
|  | 				else | ||||||
|  | 					player:EndEvent(); | ||||||
|  | 					return; | ||||||
|  | 				end | ||||||
|  | 			end			 | ||||||
|  | 		elseif (#possibleQuests == 1) then | ||||||
|  | 			chosenQuest = possibleQuests[1]; | ||||||
|  | 		end | ||||||
|  | 	else | ||||||
|  | 		local activeQuests = player:GetQuestsForNpc(npc); | ||||||
|  | 		if (#activeQuests != 0) then | ||||||
|  | 			chosenQuest = activeQuests[1]; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	-- Run the quest event or tell the devs it's missing. | ||||||
|  | 	if (chosenQuest ~= nil) then | ||||||
|  | 		doQuestEvent(player, npc, chosenQuest, eventType, eventName); | ||||||
|  | 	else | ||||||
|  | 		local msg = string.format("ERROR: This PopulaceStandard actor has no defaultTalk or quest set. \nActor Class Id: %s\nEvent Name: %s", tostring(npc:GetActorClassId()), eventName); | ||||||
|  | 		printf(msg); | ||||||
|  | 		player:SendMessage(0x20, "", msg); | ||||||
|  | 		player:EndEvent(); | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function doQuestEvent(player, npc, quest, eventType, eventName) | ||||||
|  | 	if (eventType == 0) then | ||||||
|  | 		quest:OnCommand(player, npc, eventName); | ||||||
|  | 	elseif (eventType == 1) then | ||||||
|  | 		quest:OnTalk(player, npc); | ||||||
|  | 	elseif (eventType == 2) then | ||||||
|  | 		quest:OnPush(player, npc, eventName); | ||||||
|  | 	elseif (eventType == 3) then | ||||||
|  | 		quest:OnEmote(player, npc, eventName); | ||||||
|  | 	elseif (eventType == 5) then | ||||||
|  | 		quest:OnNotice(player, npc, eventName); | ||||||
|  | 	end | ||||||
|  | end | ||||||
| @@ -0,0 +1,56 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | InstanceRaidGuide Script | ||||||
|  |  | ||||||
|  | Functions; | ||||||
|  | askEnterInstanceRaid(arg1)   -- Opens a widget asking to enter the given Raid id. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  |      | ||||||
|  |     if ((npc == 1002090) or (npc == 1002091))  then | ||||||
|  |         -- This won't work due to how init() works, but old scripts had it, keeping it here for now | ||||||
|  |         return false, false, 0, 0, 491, 2;	 | ||||||
|  |     else | ||||||
|  |         return false, false, 0, 0; | ||||||
|  |     end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, npc, eventType, eventName) | ||||||
|  |  | ||||||
|  |     npcId = npc:GetActorClassId() | ||||||
|  |      | ||||||
|  |     if (npcId == 1002090) then -- Serpent Private Hodder (Stewart) : Gcl107 | ||||||
|  |      | ||||||
|  |         callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkWithStewart_001"); -- "defaultTalkWithStewart_002" -- Post-Raid dialog? | ||||||
|  |          | ||||||
|  |         --[[ | ||||||
|  |         choice = callClientFunction(player, "delegateEvent", player, GetStaticActor("Gcl107"), "processEventStewart", 15); | ||||||
|  |          | ||||||
|  |         if (choice == 1) then | ||||||
|  |             callClientFunction(player, "askEnterInstanceRaid", 15); -- Rivenroad | ||||||
|  |         end | ||||||
|  |         --]] | ||||||
|  |     elseif (npcId == 1002091) then -- Serpent Private Dauremant (Trisselle) : Sum6w0 | ||||||
|  |          | ||||||
|  |         callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkWithTrisselle_001"); -- "defaultTalkWithTrisselle_002" -- No idea for context. | ||||||
|  |          | ||||||
|  |         --[[ | ||||||
|  |         choice = callClientFunction(player, "delegateEvent", player, GetStaticActor("Sum6w0"), "processEventTrisselle", 16) | ||||||
|  |          | ||||||
|  |         if (choice == 1) then | ||||||
|  |             callClientFunction(player, "askEnterInstanceRaid", 16);  -- Rivenroad (Hard) | ||||||
|  |         end | ||||||
|  |         --]] | ||||||
|  |     elseif (npcId == 1060022) then -- Louisoix  | ||||||
|  |         callClientFunction(player, "delegateEvent", player, GetStaticActor("DftFst"), "defaultTalkLouisoix_001"); | ||||||
|  |     end | ||||||
|  |          | ||||||
|  |  | ||||||
|  |          | ||||||
|  |          | ||||||
|  | 	player:EndEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										107
									
								
								Data/scripts/base/chara/npc/populace/shop/PopulaceGuildShop.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								Data/scripts/base/chara/npc/populace/shop/PopulaceGuildShop.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
							
								
								
									
										46
									
								
								Data/scripts/base/chara/npc/retainer/OrdinaryRetainer.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Data/scripts/base/chara/npc/retainer/OrdinaryRetainer.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | OrdinaryRetainer Script | ||||||
|  |  | ||||||
|  | Functions: | ||||||
|  |  | ||||||
|  | eventTalkRetainerOther() -  | ||||||
|  | eventTalkRetainerMenu(mode, hasPossessions) - Opens the main menu. If mode == 2, hide dismiss option. | ||||||
|  | eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation. | ||||||
|  | eventTalkRetainerMannequin(0:enable/1:disable confirm) - Show bazaar modeling confirmation. | ||||||
|  | eventTalkRetainerItemTrade(operationCode) - Operate RetainerTradeWidget. Codes: 1 - Open, 2 - Select Mode, 3 - Close. | ||||||
|  | eventTalkRetainerItemList(operationCode) -  Operate Bazaar Widget. Codes: 1 - Open, 2 - Select Mode, 3 - Close. | ||||||
|  | eventReturnResult(resultCode, ?) - Redraws the RetainerTrade UI. | ||||||
|  | sayToPlayer(actorClassId, messageType, argument) - Makes the retainer say a phrase to the player. | ||||||
|  | eventTalkFinish() - Stops npc from looking at player. | ||||||
|  | eventPlayerTurn(angle) - Turns player to angle. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  | require ("retainer") | ||||||
|  |  | ||||||
|  | function init(npc) | ||||||
|  | 	return false, false, 0, 0;	 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function onEventStarted(player, retainer, triggerName) | ||||||
|  | 	 | ||||||
|  | 	while (true) do | ||||||
|  | 		choice = callClientFunction(player, "eventTalkRetainerMenu", 1); | ||||||
|  | 		if (choice == 1) then | ||||||
|  | 			doItemTrade(player, retainer); | ||||||
|  | 		elseif (choice == 2) then | ||||||
|  | 			doBazaar(player, retainer); | ||||||
|  | 		elseif (choice == 7) then | ||||||
|  | 			callClientFunction(player, "eventTalkRetainerMannequin", 0);		 | ||||||
|  | 		elseif (choice == 5) then | ||||||
|  | 			player:DespawnMyRetainer(); | ||||||
|  | 		else | ||||||
|  | 			break; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent(); | ||||||
|  | 	 | ||||||
|  | end | ||||||
| @@ -1,7 +1,6 @@ | |||||||
| local initClassItems, initRaceItems; | local initClassItems, initRaceItems; | ||||||
| 
 | 
 | ||||||
| function onBeginLogin(player)		 | function onBeginLogin(player)		 | ||||||
| 		 |  | ||||||
| 	--New character, set the initial quest | 	--New character, set the initial quest | ||||||
| 	if (player:GetPlayTime(false) == 0) then | 	if (player:GetPlayTime(false) == 0) then | ||||||
| 		initialTown = player:GetInitialTown(); | 		initialTown = player:GetInitialTown(); | ||||||
| @@ -20,7 +19,7 @@ function onBeginLogin(player) | |||||||
| 	end | 	end | ||||||
| 			 | 			 | ||||||
| 	--For Opening. Set Director and reset position incase d/c | 	--For Opening. Set Director and reset position incase d/c | ||||||
| 	if	   (player:HasQuest(110001) == true and player:GetZoneID() == 193) then | 	if (player:HasQuest(110001) == true and player.CurrentArea.ZoneId == 193) then | ||||||
| 		director = player:GetZone():CreateDirector("OpeningDirector", false);		 | 		director = player:GetZone():CreateDirector("OpeningDirector", false);		 | ||||||
| 		player:AddDirector(director); | 		player:AddDirector(director); | ||||||
| 		director:StartDirector(true); | 		director:StartDirector(true); | ||||||
| @@ -33,7 +32,7 @@ function onBeginLogin(player) | |||||||
| 		player.rotation = 0.025; | 		player.rotation = 0.025; | ||||||
| 		player:GetQuest(110001):ClearQuestData(); | 		player:GetQuest(110001):ClearQuestData(); | ||||||
| 		player:GetQuest(110001):ClearQuestFlags(); | 		player:GetQuest(110001):ClearQuestFlags(); | ||||||
| 	elseif (player:HasQuest(110005) == true and player:GetZoneID() == 166) then  | 	elseif (player:HasQuest(110005) == true and player.CurrentArea.ZoneId == 166) then  | ||||||
| 		director = player:GetZone():CreateDirector("OpeningDirector", false);		 | 		director = player:GetZone():CreateDirector("OpeningDirector", false);		 | ||||||
| 		player:AddDirector(director); | 		player:AddDirector(director); | ||||||
| 		director:StartDirector(false);		 | 		director:StartDirector(false);		 | ||||||
| @@ -46,7 +45,7 @@ function onBeginLogin(player) | |||||||
| 		player.rotation = -1.26721; | 		player.rotation = -1.26721; | ||||||
| 		player:GetQuest(110005):ClearQuestData(); | 		player:GetQuest(110005):ClearQuestData(); | ||||||
| 		player:GetQuest(110005):ClearQuestFlags(); | 		player:GetQuest(110005):ClearQuestFlags(); | ||||||
| 	elseif (player:HasQuest(110009) == true and player:GetZoneID() == 184) then | 	elseif (player:HasQuest(110009) == true and player.CurrentArea.ZoneId == 184) then | ||||||
| 		--director = player:GetZone():CreateDirector("OpeningDirector", false);		 | 		--director = player:GetZone():CreateDirector("OpeningDirector", false);		 | ||||||
| 		--player:AddDirector(director); | 		--player:AddDirector(director); | ||||||
| 		--director:StartDirector(false);		 | 		--director:StartDirector(false);		 | ||||||
| @@ -60,7 +59,6 @@ function onBeginLogin(player) | |||||||
| 		player:GetQuest(110009):ClearQuestData(); | 		player:GetQuest(110009):ClearQuestData(); | ||||||
| 		player:GetQuest(110009):ClearQuestFlags(); | 		player:GetQuest(110009):ClearQuestFlags(); | ||||||
| 	end	 | 	end	 | ||||||
| 	 |  | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function onLogin(player) | function onLogin(player) | ||||||
| @@ -83,26 +81,26 @@ function initClassItems(player) | |||||||
| 
 | 
 | ||||||
| 	--DoW	 | 	--DoW	 | ||||||
| 	if (player.charaWork.parameterSave.state_mainSkill[0] == 2) then 		--PUG | 	if (player.charaWork.parameterSave.state_mainSkill[0] == 2) then 		--PUG | ||||||
| 		player:GetInventory(0):AddItem({4020001, 8030701, 8050728, 8080601, 8090307}); | 		player:GetItemPackage(0):AddItem({4020001, 8030701, 8050728, 8080601, 8090307}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 3) then	--GLA | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 3) then	--GLA | ||||||
| 		player:GetInventory(0):AddItem({4030010, 8031120, 8050245, 8080601, 8090307}); | 		player:GetItemPackage(0):AddItem({4030010, 8031120, 8050245, 8080601, 8090307}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 4) then	--MRD | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 4) then	--MRD | ||||||
| 		player:GetInventory(0):AddItem({4040001, 8011001, 8050621, 8070346, 8090307}); | 		player:GetItemPackage(0):AddItem({4040001, 8011001, 8050621, 8070346, 8090307}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 8, 12, 13, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 8, 12, 13, 15},{0, 1, 2, 3, 4}); | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 7) then	--ARC | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 7) then	--ARC | ||||||
| 		player:GetInventory(0):AddItem({4070001, 8030601, 8050622, 8080601, 8090307}); | 		player:GetItemPackage(0):AddItem({4070001, 8030601, 8050622, 8080601, 8090307}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 8) then	--LNC | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 8) then	--LNC | ||||||
| 		player:GetInventory(0):AddItem({4080201, 8030801, 8051015, 8080501, 8090307}); | 		player:GetItemPackage(0):AddItem({4080201, 8030801, 8051015, 8080501, 8090307}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 	--DoM	 | 	--DoM	 | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 22) then	--THM | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 22) then	--THM | ||||||
| 		player:GetInventory(0):AddItem({5020001, 8030245, 8050346, 8080346, 8090208}); | 		player:GetItemPackage(0):AddItem({5020001, 8030245, 8050346, 8080346, 8090208}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 23) then	--CNJ | 	elseif (player.charaWork.parameterSave.state_mainSkill[0] == 23) then	--CNJ | ||||||
| 		player:GetInventory(0):AddItem({5030101, 8030445, 8050031, 8080246, 8090208}); | 		player:GetItemPackage(0):AddItem({5030101, 8030445, 8050031, 8080246, 8090208}); | ||||||
| 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | 		player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4}); | ||||||
| 		 | 		 | ||||||
| 	--DoH | 	--DoH | ||||||
| @@ -126,50 +124,50 @@ end | |||||||
| function initRaceItems(player) | function initRaceItems(player) | ||||||
| 
 | 
 | ||||||
| 	if (player.playerWork.tribe == 1) then		--Hyur Midlander Male | 	if (player.playerWork.tribe == 1) then		--Hyur Midlander Male | ||||||
| 		player:GetInventory(0):AddItem(8040001); | 		player:GetItemPackage(0):AddItem(8040001); | ||||||
| 		player:GetInventory(0):AddItem(8060001); | 		player:GetItemPackage(0):AddItem(8060001); | ||||||
| 	elseif (player.playerWork.tribe == 2) then	--Hyur Midlander Female | 	elseif (player.playerWork.tribe == 2) then	--Hyur Midlander Female | ||||||
| 		player:GetInventory(0):AddItem(8040002); | 		player:GetItemPackage(0):AddItem(8040002); | ||||||
| 		player:GetInventory(0):AddItem(8060002); | 		player:GetItemPackage(0):AddItem(8060002); | ||||||
| 	elseif (player.playerWork.tribe == 3) then	--Hyur Highlander Male | 	elseif (player.playerWork.tribe == 3) then	--Hyur Highlander Male | ||||||
| 		player:GetInventory(0):AddItem(8040003); | 		player:GetItemPackage(0):AddItem(8040003); | ||||||
| 		player:GetInventory(0):AddItem(8060003); | 		player:GetItemPackage(0):AddItem(8060003); | ||||||
| 	elseif (player.playerWork.tribe == 4) then	--Elezen Wildwood Male | 	elseif (player.playerWork.tribe == 4) then	--Elezen Wildwood Male | ||||||
| 		player:GetInventory(0):AddItem(8040004); | 		player:GetItemPackage(0):AddItem(8040004); | ||||||
| 		player:GetInventory(0):AddItem(8060004); | 		player:GetItemPackage(0):AddItem(8060004); | ||||||
| 	elseif (player.playerWork.tribe == 5) then	--Elezen Wildwood Female | 	elseif (player.playerWork.tribe == 5) then	--Elezen Wildwood Female | ||||||
| 		player:GetInventory(0):AddItem(8040006); | 		player:GetItemPackage(0):AddItem(8040006); | ||||||
| 		player:GetInventory(0):AddItem(8060006); | 		player:GetItemPackage(0):AddItem(8060006); | ||||||
| 	elseif (player.playerWork.tribe == 6) then	--Elezen Duskwight Male | 	elseif (player.playerWork.tribe == 6) then	--Elezen Duskwight Male | ||||||
| 		player:GetInventory(0):AddItem(8040005); | 		player:GetItemPackage(0):AddItem(8040005); | ||||||
| 		player:GetInventory(0):AddItem(8060005); | 		player:GetItemPackage(0):AddItem(8060005); | ||||||
| 	elseif (player.playerWork.tribe == 7) then	--Elezen Duskwight Female | 	elseif (player.playerWork.tribe == 7) then	--Elezen Duskwight Female | ||||||
| 		player:GetInventory(0):AddItem(8040007); | 		player:GetItemPackage(0):AddItem(8040007); | ||||||
| 		player:GetInventory(0):AddItem(8060007); | 		player:GetItemPackage(0):AddItem(8060007); | ||||||
| 	elseif (player.playerWork.tribe == 8) then	--Lalafell Plainsfolk Male | 	elseif (player.playerWork.tribe == 8) then	--Lalafell Plainsfolk Male | ||||||
| 		player:GetInventory(0):AddItem(8040008); | 		player:GetItemPackage(0):AddItem(8040008); | ||||||
| 		player:GetInventory(0):AddItem(8060008); | 		player:GetItemPackage(0):AddItem(8060008); | ||||||
| 	elseif (player.playerWork.tribe == 9) then	--Lalafell Plainsfolk Female | 	elseif (player.playerWork.tribe == 9) then	--Lalafell Plainsfolk Female | ||||||
| 		player:GetInventory(0):AddItem(8040010); | 		player:GetItemPackage(0):AddItem(8040010); | ||||||
| 		player:GetInventory(0):AddItem(8060010); | 		player:GetItemPackage(0):AddItem(8060010); | ||||||
| 	elseif (player.playerWork.tribe == 10) then	--Lalafell Dunesfolk Male | 	elseif (player.playerWork.tribe == 10) then	--Lalafell Dunesfolk Male | ||||||
| 		player:GetInventory(0):AddItem(8040009); | 		player:GetItemPackage(0):AddItem(8040009); | ||||||
| 		player:GetInventory(0):AddItem(8060009); | 		player:GetItemPackage(0):AddItem(8060009); | ||||||
| 	elseif (player.playerWork.tribe == 11) then	--Lalafell Dunesfolk Female | 	elseif (player.playerWork.tribe == 11) then	--Lalafell Dunesfolk Female | ||||||
| 		player:GetInventory(0):AddItem(8040011); | 		player:GetItemPackage(0):AddItem(8040011); | ||||||
| 		player:GetInventory(0):AddItem(8060011); | 		player:GetItemPackage(0):AddItem(8060011); | ||||||
| 	elseif (player.playerWork.tribe == 12) then	--Miqo'te Seekers of the Sun | 	elseif (player.playerWork.tribe == 12) then	--Miqo'te Seekers of the Sun | ||||||
| 		player:GetInventory(0):AddItem(8040012); | 		player:GetItemPackage(0):AddItem(8040012); | ||||||
| 		player:GetInventory(0):AddItem(8060012); | 		player:GetItemPackage(0):AddItem(8060012); | ||||||
| 	elseif (player.playerWork.tribe == 13) then	--Miqo'te Seekers of the Moon | 	elseif (player.playerWork.tribe == 13) then	--Miqo'te Seekers of the Moon | ||||||
| 		player:GetInventory(0):AddItem(8040013); | 		player:GetItemPackage(0):AddItem(8040013); | ||||||
| 		player:GetInventory(0):AddItem(8060013); | 		player:GetItemPackage(0):AddItem(8060013); | ||||||
| 	elseif (player.playerWork.tribe == 14) then	--Roegadyn Sea Wolf | 	elseif (player.playerWork.tribe == 14) then	--Roegadyn Sea Wolf | ||||||
| 		player:GetInventory(0):AddItem(8040014); | 		player:GetItemPackage(0):AddItem(8040014); | ||||||
| 		player:GetInventory(0):AddItem(8060014); | 		player:GetItemPackage(0):AddItem(8060014); | ||||||
| 	elseif (player.playerWork.tribe == 15) then	--Roegadyn Hellsguard | 	elseif (player.playerWork.tribe == 15) then	--Roegadyn Hellsguard | ||||||
| 		player:GetInventory(0):AddItem(8040015); | 		player:GetItemPackage(0):AddItem(8040015); | ||||||
| 		player:GetInventory(0):AddItem(8060015); | 		player:GetItemPackage(0):AddItem(8060015); | ||||||
| 	end | 	end | ||||||
| 
 | 
 | ||||||
| 	player:GetEquipment():SetEquipment({9, 11},{5,6}); | 	player:GetEquipment():SetEquipment({9, 11},{5,6}); | ||||||
							
								
								
									
										107
									
								
								Data/scripts/battleutils.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								Data/scripts/battleutils.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								Data/scripts/commands/Ability.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Data/scripts/commands/Ability.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | require ("global") | ||||||
|  | require ("utils") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | AttackWeaponSkill Script | ||||||
|  |  | ||||||
|  | Finds the correct weaponskill subscript to fire when a weaponskill actor is activated. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | local attackMagicHandlers = { | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8) | ||||||
|  | 	player.Ability(command.Id, targetActor); | ||||||
|  | 	player:endEvent(); | ||||||
|  | end | ||||||
							
								
								
									
										5
									
								
								Data/scripts/commands/AbilityCure.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Data/scripts/commands/AbilityCure.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | require("global") | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8) | ||||||
|  | 	 | ||||||
|  | end | ||||||
							
								
								
									
										20
									
								
								Data/scripts/commands/ActivateCommand.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Data/scripts/commands/ActivateCommand.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | ActivateCommand Script | ||||||
|  |  | ||||||
|  | Switches between active and passive mode states | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName) | ||||||
|  |      | ||||||
|  | 	if (player.currentMainState == 0x0000) then | ||||||
|  | 		player.Engage(0, 0x0002); | ||||||
|  |     elseif (player.currentMainState == 0x0002) then | ||||||
|  |         player.Disengage(0x0000); | ||||||
|  | 	end		 | ||||||
|  | 	player:endEvent(); | ||||||
|  | 	sendSignal("playerActive"); | ||||||
|  | end; | ||||||
							
								
								
									
										20
									
								
								Data/scripts/commands/AttackAbility.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Data/scripts/commands/AttackAbility.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | require ("global") | ||||||
|  | require ("utils") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | AttackWeaponSkill Script | ||||||
|  |  | ||||||
|  | Finds the correct weaponskill subscript to fire when a weaponskill actor is activated. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | local attackMagicHandlers = { | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8) | ||||||
|  | 	player.Ability(command.Id, targetActor); | ||||||
|  | 	player:endEvent(); | ||||||
|  | 	 | ||||||
|  | end | ||||||
							
								
								
									
										19
									
								
								Data/scripts/commands/AttackMagic.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Data/scripts/commands/AttackMagic.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | require ("global") | ||||||
|  | require ("utils") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | AttackWeaponSkill Script | ||||||
|  |  | ||||||
|  | Finds the correct weaponskill subscript to fire when a weaponskill actor is activated. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | local attackMagicHandlers = { | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8) | ||||||
|  | 	player.Cast(command.Id, targetActor); | ||||||
|  | 	player:endEvent(); | ||||||
|  | end; | ||||||
							
								
								
									
										26
									
								
								Data/scripts/commands/AttackWeaponSkill.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Data/scripts/commands/AttackWeaponSkill.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | require ("global") | ||||||
|  | require ("utils") | ||||||
|  |  | ||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | AttackWeaponSkill Script | ||||||
|  |  | ||||||
|  | Finds the correct weaponskill subscript to fire when a weaponskill actor is activated. | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | function onEventStarted(player, command, eventType, eventName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8) | ||||||
|  | 	 | ||||||
|  | 	--Are they in active mode? | ||||||
|  | 	if (player:GetState() != 2) then | ||||||
|  | 		player:SendGameMessage(GetWorldMaster(), 32503, 0x20); | ||||||
|  | 		player:endEvent(); | ||||||
|  | 		return; | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  |     if not player.aiContainer.IsEngaged() then | ||||||
|  |         player.Engage(targetActor); | ||||||
|  |     end; | ||||||
|  |     player.WeaponSkill(command.Id, targetActor); | ||||||
|  | 	player:endEvent(); | ||||||
|  | end; | ||||||
							
								
								
									
										30
									
								
								Data/scripts/commands/BazaarCheckCommand.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Data/scripts/commands/BazaarCheckCommand.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | --[[ | ||||||
|  |  | ||||||
|  | BazaarCheckCommand Script | ||||||
|  |  | ||||||
|  | Handles what happens when you examine a player's bazaar | ||||||
|  |  | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | require ("global") | ||||||
|  |  | ||||||
|  | function onEventStarted(player, actor, eventType, eventName, name, arg1, arg2, arg3, bazaarActorId)	 | ||||||
|  |  | ||||||
|  | 	local bazaarActor = nil; | ||||||
|  |  | ||||||
|  | 	if (name ~= nil) then | ||||||
|  | 		bazaarActor = player.CurrentArea:FindPCInZone(name); | ||||||
|  | 	elseif (bazaarActorId ~= nil) then | ||||||
|  | 		bazaarActor = player.CurrentArea:FindActorInArea(bazaarActorId); | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	if (bazaarActor ~= nil) then | ||||||
|  | 		player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "", "Currently disabled due to freezing characters."); | ||||||
|  | 		--callClientFunction(player, "delegateCommand", GetStaticActor("BazaarCheckCommand"), "processChackBazaar");		 | ||||||
|  | 	else | ||||||
|  | 		--Show error | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
|  | 	player:EndEvent(); | ||||||
|  | 	 | ||||||
|  | end | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user