View difference between Paste ID: EsNPasDD and ek6kFxb9
SHOW: | | - or go back to the newest paste.
1
Index: com/l2jserver/gameserver/GameServer.java
2
===================================================================
3
--- com/l2jserver/gameserver/GameServer.java	(revision 5685)
4
+++ com/l2jserver/gameserver/GameServer.java	(working copy)
5
@@ -49,6 +49,7 @@
6
 import com.l2jserver.gameserver.datatables.EnchantOptionsData;
7
 import com.l2jserver.gameserver.datatables.EventDroplist;
8
 import com.l2jserver.gameserver.datatables.ExperienceTable;
9
+import com.l2jserver.gameserver.datatables.FencesTable;
10
 import com.l2jserver.gameserver.datatables.FishData;
11
 import com.l2jserver.gameserver.datatables.FishingMonstersData;
12
 import com.l2jserver.gameserver.datatables.FishingRodsData;
13
@@ -256,7 +257,7 @@
14
 			PathFinding.getInstance();
15
 		}
16
 		
17
-		printSection("NPCs");
18
+		printSection("WorldObjects");
19
 		HerbDropTable.getInstance();
20
 		NpcTable.getInstance();
21
 		NpcWalkerRoutesData.getInstance();
22
@@ -269,6 +270,7 @@
23
 		FortManager.getInstance().loadInstances();
24
 		NpcBufferTable.getInstance();
25
 		SpawnTable.getInstance();
26
+		FencesTable.getInstance();
27
 		HellboundManager.getInstance();
28
 		RaidBossSpawnManager.getInstance();
29
 		DayNightSpawnManager.getInstance().trim().notifyChangeMode();
30
Index: com/l2jserver/gameserver/datatables/FencesTable.java
31
===================================================================
32
--- com/l2jserver/gameserver/datatables/FencesTable.java	(revision 0)
33
+++ com/l2jserver/gameserver/datatables/FencesTable.java	(revision 0)
34
@@ -0,0 +1,173 @@
35
+/*
36
+ * This program is free software: you can redistribute it and/or modify it under
37
+ * the terms of the GNU General Public License as published by the Free Software
38
+ * Foundation, either version 3 of the License, or (at your option) any later
39
+ * version.
40
+ *
41
+ * This program is distributed in the hope that it will be useful, but WITHOUT
42
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
44
+ * details.
45
+ *
46
+ * You should have received a copy of the GNU General Public License along with
47
+ * this program. If not, see <http://www.gnu.org/licenses/>.
48
+ */
49
+package com.l2jserver.gameserver.datatables;
50
+
51
+import java.sql.Connection;
52
+import java.sql.PreparedStatement;
53
+import java.sql.ResultSet;
54
+import java.sql.SQLException;
55
+import java.util.HashMap;
56
+import java.util.Map;
57
+import java.util.logging.Level;
58
+import java.util.logging.Logger;
59
+
60
+import com.l2jserver.L2DatabaseFactory;
61
+import com.l2jserver.gameserver.model.Location;
62
+import com.l2jserver.gameserver.model.actor.instance.L2FenceInstance;
63
+import com.l2jserver.util.StringUtil;
64
+
65
+/**
66
+ * @author Nik based on Christian's work.
67
+ */
68
+public class FencesTable
69
+{
70
+	protected static final Logger _log = Logger.getLogger(FencesTable.class.getName());
71
+	
72
+	private static final class SingletonHolder
73
+	{
74
+		protected static final FencesTable _instance = new FencesTable();
75
+	}
76
+	
77
+	public static FencesTable getInstance()
78
+	{
79
+		return SingletonHolder._instance;
80
+	}
81
+	
82
+	private final Map<Integer, L2FenceInstance> _fences = new HashMap<>();
83
+	
84
+	protected FencesTable()
85
+	{
86
+		load();
87
+		_log.log(Level.INFO, StringUtil.concat("Loaded ", String.valueOf(_fences.size()), " stored fences."));
88
+	}
89
+	
90
+	private void load()
91
+	{
92
+		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
93
+			PreparedStatement stmt = con.prepareStatement("SELECT * FROM fences"))
94
+		{
95
+			ResultSet res = stmt.executeQuery();
96
+			while (res.next())
97
+			{
98
+				L2FenceInstance fence = new L2FenceInstance(res.getInt("object_id"), res.getInt("state"), res.getInt("x"), res.getInt("y"), res.getInt("z"), res.getInt("width"), res.getInt("length"), res.getInt("height"));
99
+				fence.setStoredToDB(true); // They are loaded from DB, therefore they are stored there.
100
+				fence.spawnMe();
101
+			}
102
+		}
103
+		catch (SQLException sqle)
104
+		{
105
+			_log.log(Level.WARNING, "Exception while loading fences: ", sqle);
106
+		}
107
+	}
108
+	
109
+	public void reload()
110
+	{
111
+		for (L2FenceInstance fence : _fences.values())
112
+		{
113
+			// Do not delete temp fences, they aren't stored in DB therefore they won't be reloaded, but deleted.
114
+			if (!fence.isStoredToDB())
115
+			{
116
+				fence.decayMe();
117
+			}
118
+		}
119
+		
120
+		load();
121
+	}
122
+	
123
+	public void addFence(L2FenceInstance fence)
124
+	{
125
+		_fences.put(fence.getObjectId(), fence);
126
+	}
127
+	
128-
+	public void getFence(int objectId)
128+
+	public L2FenceInstance getFence(int objectId)
129
+	{
130-
+		_fences.get(objectId);
130+
+		return _fences.get(objectId);
131
+	}
132
+	
133
+	public L2FenceInstance removeFence(int objectId)
134
+	{
135
+		return _fences.remove(objectId);
136
+	}
137
+	
138
+	public void deleteFence(int objectId, boolean deleteFromDB)
139
+	{
140
+		L2FenceInstance fence = removeFence(objectId);
141
+		if (fence != null)
142
+		{
143
+			fence.decayMe();
144
+		}
145
+		
146
+		if (deleteFromDB)
147
+		{
148
+			deleteStoredFence(objectId);
149
+		}
150
+	}
151
+	
152
+	/**
153
+	 * @param fence - Stores the fence to the database.
154
+	 */
155
+	public void storeFence(L2FenceInstance fence)
156
+	{
157
+		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
158
+			PreparedStatement stmt = con.prepareStatement("INSERT INTO fences (object_id,state,x,y,z,width,length,height) VALUES(?,?,?,?,?,?,?,?)"))
159
+		{
160
+			stmt.setInt(1, fence.getObjectId());
161
+			stmt.setInt(2, fence.getX());
162
+			stmt.setInt(3, fence.getY());
163
+			stmt.setInt(4, fence.getZ());
164
+			stmt.setInt(5, fence.getWidth());
165
+			stmt.setInt(6, fence.getLength());
166
+			stmt.setInt(6, fence.getHeight());
167
+			stmt.executeUpdate();
168
+		}
169
+		catch (SQLException sqle)
170
+		{
171
+			_log.log(Level.WARNING, "Error while storing fence:", sqle);
172
+		}
173
+	}
174
+	
175
+	public boolean deleteStoredFence(int objectId)
176
+	{
177
+		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
178
+			PreparedStatement stmt = con.prepareStatement("DELETE FROM fences WHERE object_id=?");)
179
+		{
180
+			
181
+			stmt.setInt(1, objectId);
182
+			if (stmt.executeUpdate() > 0)
183
+			{
184
+				return true;
185
+			}
186
+		}
187
+		catch (SQLException sqle)
188
+		{
189
+			_log.log(Level.WARNING, "Error while deleting stored fence:", sqle);
190
+		}
191
+		
192
+		return false;
193
+	}
194
+	
195
+	public boolean checkIfBetweenFences(Location loc1, Location loc2)
196
+	{
197
+		for (L2FenceInstance fence : _fences.values())
198
+		{
199
+			if (!fence.canSee(loc1, loc2))
200
+			{
201
+				return true;
202
+			}
203
+		}
204
+		
205
+		return true;
206
+	}
207
+}
208
Index: com/l2jserver/gameserver/model/L2Object.java
209
===================================================================
210
--- com/l2jserver/gameserver/model/L2Object.java	(revision 5685)
211
+++ com/l2jserver/gameserver/model/L2Object.java	(working copy)
212
@@ -64,6 +64,7 @@
213
 		L2Object(null),
214
 		L2ItemInstance(L2Object),
215
 		L2Character(L2Object),
216
+		L2FenceInstance(L2Object),
217
 		L2Npc(L2Character),
218
 		L2Playable(L2Character),
219
 		L2Summon(L2Playable),
220
Index: com/l2jserver/gameserver/model/actor/instance/L2FenceInstance.java
221
===================================================================
222
--- com/l2jserver/gameserver/model/actor/instance/L2FenceInstance.java	(revision 0)
223
+++ com/l2jserver/gameserver/model/actor/instance/L2FenceInstance.java	(revision 0)
224
@@ -0,0 +1,214 @@
225
+/*
226
+ * This program is free software: you can redistribute it and/or modify it under
227
+ * the terms of the GNU General Public License as published by the Free Software
228
+ * Foundation, either version 3 of the License, or (at your option) any later
229
+ * version.
230
+ * 
231
+ * This program is distributed in the hope that it will be useful, but WITHOUT
232
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
233
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
234
+ * details.
235
+ * 
236
+ * You should have received a copy of the GNU General Public License along with
237
+ * this program. If not, see <http://www.gnu.org/licenses/>.
238
+ */
239
+
240
+package com.l2jserver.gameserver.model.actor.instance;
241
+
242
+import java.awt.Rectangle;
243
+
244
+import com.l2jserver.gameserver.datatables.FencesTable;
245
+import com.l2jserver.gameserver.idfactory.IdFactory;
246
+import com.l2jserver.gameserver.model.L2Object;
247
+import com.l2jserver.gameserver.model.Location;
248
+import com.l2jserver.gameserver.model.actor.L2Character;
249
+import com.l2jserver.gameserver.network.serverpackets.ExColosseumFenceInfo;
250
+
251
+/**
252
+ * @author Nik
253
+ */
254
+public final class L2FenceInstance extends L2Object
255
+{
256
+	public static final int HIDDEN = 0;
257
+	public static final int UNCLOSED = 1;
258
+	public static final int CLOSED = 2;
259
+	
260
+	private int _state;
261
+	private final int _width;
262
+	private final int _length;
263
+	private int _height;
264
+	private Rectangle _shape;
265
+	private boolean _storedToDB = false;
266
+	
267
+	public L2FenceInstance(int objectId, int state, int x, int y, int z, int width, int length, int height)
268
+	{
269
+		super(objectId);
270
+		setInstanceType(InstanceType.L2FenceInstance);
271
+		initPosition();
272
+		setXYZ(x, y, z);
273
+		
274
+		if ((state < 0) || (state > 2))
275
+		{
276
+			state = 0;
277
+		}
278
+		_state = state;
279
+		_width = width;
280
+		_length = length;
281
+		_height = height;
282
+		_shape = new Rectangle(getX(), getY(), _width, _length);
283
+	}
284
+	
285
+	public L2FenceInstance(int x, int y, int z, int width, int length)
286
+	{
287
+		super(IdFactory.getInstance().getNextId());
288
+		setInstanceType(InstanceType.L2FenceInstance);
289
+		initPosition();
290
+		setXYZ(x, y, z);
291
+		_state = CLOSED; // Its a better default than HIDDEN.
292
+		_width = width;
293
+		_length = length;
294
+		_height = 50;
295
+		_shape = new Rectangle(getX(), getY(), _width, _length);
296
+	}
297
+	
298
+	public boolean isLocInside(Location loc)
299
+	{
300
+		boolean isInsideZ = (loc.getZ() >= getZ()) && (loc.getZ() <= (getZ() + _height));
301
+		return _shape.contains(loc.getX(), loc.getY()) && isInsideZ && (getInstanceId() == loc.getInstanceId());
302
+	}
303
+	
304
+	public boolean isLocOutside(Location loc)
305
+	{
306
+		return !isLocInside(loc);
307
+	}
308
+	
309
+	/**
310
+	 * @param x1 - obj1's X loc
311
+	 * @param y1 - obj1's Y loc
312
+	 * @param x2 - obj2's X loc
313
+	 * @param y2 - obj2's Y loc
314
+	 * @return can obj1 see obj2 through this fence (their LOS do not intersect the fence's bounds). <B>No Z</B> checks are done. <B>No Instance</B> checks are done.
315
+	 */
316
+	public boolean canSee(int x1, int y1, int x2, int y2)
317
+	{
318
+		return !_shape.intersectsLine(x1, y1, x2, y2);
319
+	}
320
+	
321
+	/**
322
+	 * @param loc1 - obj1's xyz & instanceId location
323
+	 * @param loc2 - obj2's xyz & instanceId location
324
+	 * @return can obj1 see obj2 through this fence (their LOS do not intersect the fence's bounds). <B>Z</B> checks are done. <B>Instance</B> checks are done.
325
+	 */
326
+	public boolean canSee(Location loc1, Location loc2)
327
+	{
328
+		if ((getState() == CLOSED) && (loc1.getInstanceId() == loc2.getInstanceId()))
329
+		{
330
+			// Those Z checks are probably not 100% accurate, rework them if it must.
331
+			int higherZ = loc1.getZ() >= loc2.getZ() ? loc1.getZ() : loc2.getZ();
332
+			if ((higherZ >= getZ()) && (higherZ <= (getZ() + _height)))
333
+			{
334
+				return canSee(loc1.getX(), loc1.getY(), loc2.getX(), loc2.getY());
335
+			}
336
+		}
337
+		
338
+		return true;
339
+	}
340
+	
341
+	/**
342
+	 * @param obj1
343
+	 * @param obj2
344
+	 * @return can obj1 see obj2 through this fence (their LOS do not intersect the fence's bounds). <B>Z</B> checks are done. <B>Instance</B> checks are done.
345
+	 */
346
+	public boolean canSee(L2Object obj1, L2Object obj2)
347
+	{
348
+		if ((getState() == CLOSED) && (obj1.getInstanceId() == obj2.getInstanceId()))
349
+		{
350
+			// Those Z checks are probably not 100% accurate, rework them if it must.
351
+			int higherZ = obj1.getZ() >= obj2.getZ() ? obj1.getZ() : obj2.getZ();
352
+			if ((higherZ >= getZ()) && (higherZ <= (getZ() + _height)))
353
+			{
354
+				return canSee(obj1.getX(), obj1.getY(), obj2.getX(), obj2.getY());
355
+			}
356
+		}
357
+		
358
+		return true;
359
+	}
360
+	
361
+	@Override
362
+	public void sendInfo(L2PcInstance activeChar)
363
+	{
364
+		activeChar.sendPacket(new ExColosseumFenceInfo(this));
365
+	}
366
+	
367
+	@Override
368
+	public boolean isAutoAttackable(L2Character attacker)
369
+	{
370
+		return false;
371
+	}
372
+	
373
+	/**
374
+	 * Also removes the fence from FencesTable, but its not removed from DB
375
+	 */
376
+	@Override
377
+	public void decayMe()
378
+	{
379
+		FencesTable.getInstance().removeFence(getObjectId());
380
+	}
381
+	
382
+	@Override
383
+	public void onSpawn()
384
+	{
385
+		// Maybe someone for some reason decided to respawn this fence on different XYZ. RESHAPE!!!
386
+		_shape = new Rectangle(getX(), getY(), _width, _length);
387
+		FencesTable.getInstance().addFence(this);
388
+	}
389
+	
390
+	/**
391
+	 * @param height - how high the fence is :D :D Although the client height of the fence is ~50, you can set it to as much as you want. <BR>
392
+	 *            Setting it to lower might result in some strange LOS checks. Setting it too high might result in weird LOS checks in all the floors of TOI :P
393
+	 */
394
+	public void setHeight(int height)
395
+	{
396
+		_height = height;
397
+	}
398
+	
399
+	public void setState(int state)
400
+	{
401
+		if ((state < 0) || (state > 2))
402
+		{
403
+			state = 0;
404
+		}
405
+		
406
+		_state = state;
407
+	}
408
+	
409
+	public int getState()
410
+	{
411
+		return _state;
412
+	}
413
+	
414
+	public int getWidth()
415
+	{
416
+		return _width;
417
+	}
418
+	
419
+	public int getLength()
420
+	{
421
+		return _length;
422
+	}
423
+	
424
+	public int getHeight()
425
+	{
426
+		return _height;
427
+	}
428
+	
429
+	public void setStoredToDB(boolean storedToDB)
430
+	{
431
+		_storedToDB = storedToDB;
432
+	}
433
+	
434
+	public boolean isStoredToDB()
435
+	{
436
+		return _storedToDB;
437
+	}
438
+}
439
\ No newline at end of file
440
Index: com/l2jserver/gameserver/GeoEngine.java
441
===================================================================
442
--- com/l2jserver/gameserver/GeoEngine.java	(revision 5685)
443
+++ com/l2jserver/gameserver/GeoEngine.java	(working copy)
444
@@ -34,6 +34,7 @@
445
 
446
 import com.l2jserver.Config;
447
 import com.l2jserver.gameserver.datatables.DoorTable;
448
+import com.l2jserver.gameserver.datatables.FencesTable;
449
 import com.l2jserver.gameserver.model.L2Object;
450
 import com.l2jserver.gameserver.model.L2Spawn;
451
 import com.l2jserver.gameserver.model.L2World;
452
@@ -101,6 +102,12 @@
453
 		{
454
 			return false;
455
 		}
456
+		
457
+		if (FencesTable.getInstance().checkIfBetweenFences(new Location(cha), new Location(target.getX(), target.getY(), target.getZ(), 0, cha.getInstanceId())))
458
+		{
459
+			return false;
460
+		}
461
+		
462
 		if (cha.getZ() >= target.getZ())
463
 		{
464
 			return canSeeTarget(cha.getX(), cha.getY(), cha.getZ(), target.getX(), target.getY(), target.getZ());
465
@@ -138,6 +145,10 @@
466
 		{
467
 			return true; // door coordinates are hinge coords..
468
 		}
469
+		if (FencesTable.getInstance().checkIfBetweenFences(new Location(cha), new Location(target)))
470
+		{
471
+			return false;
472
+		}
473
 		if (target instanceof L2DefenderInstance)
474
 		{
475
 			z2 += 30; // well they don't move closer to balcony fence at the moment :(
476
@@ -189,6 +200,10 @@
477
 		{
478
 			return startpoint;
479
 		}
480
+		if (FencesTable.getInstance().checkIfBetweenFences(new Location(x, y, z, 0, instanceId), new Location(tx, ty, tz, 0, instanceId)))
481
+		{
482
+			return startpoint;
483
+		}
484
 		
485
 		Location destiny = new Location(tx, ty, tz);
486
 		return moveCheck(startpoint, destiny, (x - L2World.MAP_MIN_X) >> 4, (y - L2World.MAP_MIN_Y) >> 4, z, (tx - L2World.MAP_MIN_X) >> 4, (ty - L2World.MAP_MIN_Y) >> 4, tz);
487
Index: com/l2jserver/gameserver/idfactory/IdFactory.java
488
===================================================================
489
--- com/l2jserver/gameserver/idfactory/IdFactory.java	(revision 5685)
490
+++ com/l2jserver/gameserver/idfactory/IdFactory.java	(working copy)
491
@@ -102,7 +102,8 @@
492
 		"SELECT ally_id     FROM clan_data             WHERE ally_id >= ?     AND ally_id < ?",
493
 		"SELECT leader_id   FROM clan_data             WHERE leader_id >= ?   AND leader_id < ?",
494
 		"SELECT item_obj_id FROM pets                  WHERE item_obj_id >= ? AND item_obj_id < ?",
495
-		"SELECT object_id   FROM itemsonground        WHERE object_id >= ?   AND object_id < ?"
496
+		"SELECT object_id   FROM itemsonground        WHERE object_id >= ?   AND object_id < ?",
497
+		"SELECT object_id   FROM fences        WHERE object_id >= ?   AND object_id < ?"
498
 	};
499
 	
500
 	private static final String[] TIMESTAMPS_CLEAN =
501
@@ -400,6 +401,20 @@
502
 					temp.add(rs.getInt(1));
503
 				}
504
 			}
505
+			
506
+			try (ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM fences"))
507
+			{
508
+				rs.next();
509
+				temp.ensureCapacity(temp.size() + rs.getInt(1));
510
+			}
511
+			
512
+			try (ResultSet rs = s.executeQuery("SELECT object_id FROM fences"))
513
+			{
514
+				while (rs.next())
515
+				{
516
+					temp.add(rs.getInt(1));
517
+				}
518
+			}
519
 			temp.sort();
520
 			return temp.toArray();
521
 		}
522
Index: com/l2jserver/gameserver/network/serverpackets/ExColosseumFenceInfo.java
523
===================================================================
524
--- com/l2jserver/gameserver/network/serverpackets/ExColosseumFenceInfo.java	(revision 0)
525
+++ com/l2jserver/gameserver/network/serverpackets/ExColosseumFenceInfo.java	(revision 0)
526
@@ -0,0 +1,57 @@
527
+/*
528
+ * This program is free software: you can redistribute it and/or modify it under
529
+ * the terms of the GNU General Public License as published by the Free Software
530
+ * Foundation, either version 3 of the License, or (at your option) any later
531
+ * version.
532
+ *
533
+ * This program is distributed in the hope that it will be useful, but WITHOUT
534
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
535
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
536
+ * details.
537
+ *
538
+ * You should have received a copy of the GNU General Public License along with
539
+ * this program. If not, see <http://www.gnu.org/licenses/>.
540
+ */
541
+package com.l2jserver.gameserver.network.serverpackets;
542
+
543
+import com.l2jserver.gameserver.model.actor.instance.L2FenceInstance;
544
+
545
+/**
546
+ * OP: 0xFE<br>
547
+ * OP2: 0x0003<br>
548
+ * Format: ddddddd<br>
549
+ * - d: object id<br>
550
+ * - d: state(0=hidden, 1=unconnected corners, 2=connected corners)<br>
551
+ * - d: x<br>
552
+ * - d: y<br>
553
+ * - d: z<br>
554
+ * - d: a side length<br>
555
+ * - d: b side length<br>
556
+ */
557
+public class ExColosseumFenceInfo extends L2GameServerPacket
558
+{
559
+	private final L2FenceInstance _fence;
560
+	
561
+	public ExColosseumFenceInfo(L2FenceInstance fence)
562
+	{
563
+		_fence = fence;
564
+	}
565
+	
566
+	/**
567
+	 * @see com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket#writeImpl()
568
+	 */
569
+	@Override
570
+	protected void writeImpl()
571
+	{
572
+		writeC(0xfe);
573
+		writeH(0x0003);
574
+		
575
+		writeD(_fence.getObjectId());
576
+		writeD(_fence.getState());
577
+		writeD(_fence.getX());
578
+		writeD(_fence.getY());
579
+		writeD(_fence.getZ());
580
+		writeD(_fence.getWidth());
581
+		writeD(_fence.getLength());
582
+	}
583
+}
584
\ No newline at end of file