View difference between Paste ID: 65v2RfMq and xZsdZcM9
SHOW: | | - or go back to the newest paste.
1
ZombieLimit = get("zombies.MaxZombies")-- HOW MANY ZOMBIES SHOULD EXIST AT MAXIMUM?
2
ZombieStreaming = get("zombies.StreamMethod") -- 1 to constantly stream zombies, 0 to only allow zombies to spawn via createZombie function, 2 to only allow spawning at set spawnpoints
3
ZombiePedSkins = {13,22,56,67,68,69,70,92,97,105,107,108,126,127,128,152,162,167,188,195,206,209,212,229,230,258,264,277,280,287 } --ALTERNATE SKIN LISTS FOR ZOMBIES (SHORTER LIST IS TEXTURED ZOMBIES ONLY)
4
--ZombiePedSkins = {7,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,43,44,45,36,37,38,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,66,67,68,69,70,71,72,73,75,76,77,78,79,80,81,82,83,85,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,112,113,114,115,116,117,118,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,150,151,152,153,154,155,156,157,158,159,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,209,210,211,212,213,214,215,216,217,218,219,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,275,276,277,278,279,280,281,282,283,284,285,286,287,288 }
5
ZombieSpeed = get("zombies.Speed")
6
if ZombieSpeed == 0 then --super slow zombies (goofy looking)
7
	chaseanim = "WALK_drunk"
8
	checkspeed = 2000
9
elseif ZombieSpeed == 1 then -- normal speed
10
	chaseanim = "run_old"
11
	checkspeed = 1000
12
elseif ZombieSpeed == 2 then -- rocket zombies (possibly stressful on server)
13
	chaseanim = "Run_Wuzi"
14
	checkspeed = 680
15
else -- defaults back to normal
16
	chaseanim = "run_old"
17
	checkspeed = 1000
18
end
19
resourceRoot = getResourceRootElement()
20
moancount =0
21
moanlimit = 10
22
everyZombie = { }
23
24
--IDLE BEHAVIOUR OF A ZOMBIE
25
function Zomb_Idle (ped)
26
	if isElement(ped) then
27
		if ( getElementData ( ped, "status" ) == "idle" ) and ( isPedDead ( ped ) == false ) and (getElementData (ped, "zombie") == true) then
28
			local action = math.random( 1, 6 )
29
			if action < 4 then -- walk a random direction
30
				local rdmangle = math.random( 1, 359 )
31
				setPedRotation( ped, rdmangle )
32
				setPedAnimation ( ped, "PED", "Player_Sneak", -1, true, true, true)
33
				setTimer ( Zomb_Idle, 7000, 1, ped )
34
			elseif action == 4 then -- get on the ground
35
				setPedAnimation ( ped, "MEDIC", "cpr", -1, false, true, true)
36
				setTimer ( Zomb_Idle, 4000, 1, ped )
37
			elseif action == 5 then -- stand still doing nothing
38
				setPedAnimation ( ped )
39
				setTimer ( Zomb_Idle, 4000, 1, ped )
40
			end
41
		end
42
	end
43
end
44
45
--BEHAVIOUR WHILE CHASING PLAYERS
46
function Zomb_chase (ped, Zx, Zy, Zz )
47
	if isElement(ped) then
48
		if (getElementData ( ped, "status" ) == "chasing") and (getElementData (ped, "zombie") == true) then
49
			local x, y, z = getElementPosition( ped )
50
			if (getElementData ( ped, "target" ) == nil) and getElementData ( ped, "Tx" ) ~= false then			
51
				local Px = getElementData ( ped, "Tx" )
52
				local Py = getElementData ( ped, "Ty" )
53
				local Pz = getElementData ( ped, "Tz" )
54
				local Pdistance = (getDistanceBetweenPoints3D( Px, Py, Pz, x, y, z ))
55
				if (Pdistance < 1.5 ) then
56
					setTimer ( function (ped) if ( isElement ( ped ) ) then setElementData ( ped, "status", "idle" ) end end, 2000, 1, ped )
57
				end
58
			end
59
			local distance = (getDistanceBetweenPoints3D( x, y, z, Zx, Zy, Zz ))			
60
			if (distance < 1 ) then -- IF THE PED HASNT MOVED
61
				if (getElementData ( ped, "target" ) == nil) then
62
					local giveup = math.random( 1, 15 )
63
					if giveup == 1 then
64
						setElementData ( ped, "status", "idle" )
65
					else
66
						local action = math.random( 1, 2 )
67
						if action == 1 then
68
							setPedAnimation ( ped )
69
							triggerClientEvent ( "Zomb_Punch", getRootElement(), ped )
70
							setTimer ( function (ped) if ( isElement ( ped ) ) then setPedAnimation ( ped, "ped", chaseanim, -1, true, true, true ) end end, 800, 1, ped )
71
							setTimer ( Zomb_chase, 2000, 1, ped, x, y, z )
72
						elseif action == 2 then
73
							setPedAnimation ( ped )
74
							triggerClientEvent ( "Zomb_Jump", getRootElement(), ped )
75
							setTimer ( Zomb_chase, 3500, 1, ped, x, y, z )
76
						end
77
					end
78
				else 
79
					local Ptarget = (getElementData ( ped, "target" ))
80
					if isElement(Ptarget) then
81
						local Px, Py, Pz = getElementPosition( Ptarget )
82
						local Pdistance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
83
						if (Pdistance < 1.2 ) then -- ATTACK A PLAYER IF THEY ARE CLOSE
84
							if ( isPedDead ( Ptarget ) ) then --EAT A DEAD PLAYER
85
								setPedAnimation ( ped )
86
								setPedAnimation ( ped, "MEDIC", "cpr", -1, false, true, false)
87
								setTimer ( function (ped) if ( isElement ( ped ) ) then setElementData ( ped, "status", "idle" ) end end, 10000, 1, ped )
88
								setTimer ( function (ped) if ( isElement ( ped ) ) then setPedRotation ( ped, getPedRotation(ped)-180) end end, 10000, 1, ped )
89
								zmoan(ped)
90
							else
91
								local action = math.random( 1, 6 )
92
								if action == 1 then
93
									setPedAnimation ( ped)
94
									triggerClientEvent ( "Zomb_Jump", getRootElement(), ped )
95
									setTimer ( Zomb_chase, 2000, 1, ped, x, y, z )
96
								else
97
									setPedAnimation ( ped)
98
									triggerClientEvent ( "Zomb_Punch", getRootElement(), ped )
99
									setTimer ( function (ped) if ( isElement ( ped ) ) then setPedAnimation ( ped, "ped", chaseanim, -1, true, true, true ) end end, 800, 1, ped )
100
									setTimer ( Zomb_chase, 2000, 1, ped, x, y, z )
101
								end
102
							end
103
						else
104
							if ( isPedDead (Ptarget) ) then
105
							setTimer ( function (ped) if ( isElement ( ped ) ) then setElementData ( ped, "status", "idle" ) end end, 2000, 1, ped )
106
							setTimer ( function (ped) if ( isElement ( ped ) ) then setPedRotation ( ped, getPedRotation(ped)-180) end end, 1800, 1, ped )
107
							else
108
								local action = math.random( 1, 2 )
109
								if action == 1 then
110
									setPedAnimation ( ped)
111
									triggerClientEvent ( "Zomb_Punch", getRootElement(), ped )
112
									setTimer ( function (ped) if ( isElement ( ped ) ) then setPedAnimation ( ped, "ped", chaseanim, -1, true, true, true ) end end, 800, 1, ped )
113
									setTimer ( Zomb_chase, 2000, 1, ped, x, y, z )
114
								elseif action == 2 then
115
									setPedAnimation ( ped)
116
									triggerClientEvent ( "Zomb_Jump", getRootElement(), ped )
117
									setTimer ( Zomb_chase, 2000, 1, ped, x, y, z )
118
								end
119
							end
120
						end
121
					else
122
						setElementData ( ped, "status", "idle" )
123
					end
124
				end
125
			else
126
				setPedAnimation ( ped, "ped", chaseanim, -1, true, true, true) --KEEP WALKING
127
				setTimer ( Zomb_chase, checkspeed, 1, ped, x, y, z ) --CHECK AGAIN
128
			end
129
		end
130
	end
131
end
132
133
--SET THE DIRECTION OF THE ZOMBIE
134
function setangle ()
135
	for theKey,ped in ipairs(everyZombie) do
136
		if isElement(ped) then
137
			if ( getElementData ( ped, "status" ) == "chasing" ) then
138
				local x
139
				local y
140
				local z
141
				local px
142
				local py
143
				local pz
144
				if ( getElementData ( ped, "target" ) ~= nil ) then
145
					local ptarget = getElementData ( ped, "target" )
146
					if isElement(ptarget) then
147
						x, y, z = getElementPosition( ptarget )
148
						px, py, pz = getElementPosition( ped )
149
					else
150
						setElementData ( ped, "status", "idle" )
151
						x, y, z = getElementPosition( ped )
152
						px, py, pz = getElementPosition( ped )
153
					end
154
					zombangle = ( 360 - math.deg ( math.atan2 ( ( x - px ), ( y - py ) ) ) ) % 360 --MAGIC SPELL TO MAKE PEDS LOOK AT YOU
155
					setPedRotation( ped, zombangle )
156
				elseif ( getElementData ( ped, "target" ) == nil ) and (getElementData ( ped, "Tx" ) ~= false) then --IF THE PED IS AFTER THE PLAYERS LAST KNOWN WHEREABOUTS
157
					x = getElementData ( ped, "Tx" )
158
					y = getElementData ( ped, "Ty" )
159
					z = getElementData ( ped, "Tz" )
160
					px, py, pz = getElementPosition( ped )
161
					zombangle = ( 360 - math.deg ( math.atan2 ( ( x - px ), ( y - py ) ) ) ) % 360 --MAGIC SPELL TO MAKE PEDS LOOK AT YOU
162
					setPedRotation( ped, zombangle )
163
				end
164
			end
165
		end
166
	end
167
end
168
169
--SETS THE ZOMBIE ACTIVITY WHEN STATUS CHANGES
170
addEventHandler ( "onElementDataChange", getRootElement(),
171
function ( dataName )
172
	if getElementType ( source ) == "ped" and dataName == "status" then
173
		if (getElementData (source, "zombie") == true) then
174
			if ( isPedDead ( source ) == false ) then
175
				if (getElementData ( source, "status" ) ==  "chasing" ) then
176
					local Zx, Zy, Zz = getElementPosition( source )
177
					setTimer ( Zomb_chase, 1000, 1, source, Zx, Zy, Zz )
178
					local newtarget = (getElementData ( source, "target" ))
179
					if isElement (newtarget) then
180
						if getElementType ( newtarget ) == "player" then
181
							setElementSyncer ( source, newtarget )
182
						end
183
					end
184
					zmoan(source)
185
				elseif (getElementData ( source, "status" ) ==  "idle" ) then
186
					setTimer ( Zomb_Idle, 1000, 1, source)
187
				elseif (getElementData ( source, "status" ) ==  "throatslashing" ) then
188
					local tx,ty,tz = getElementPosition( source )
189
					local ptarget = getElementData ( source, "target" )
190
					if isElement(ptarget) then
191
						local vx,vy,vz = getElementPosition( ptarget )
192
						local zombdistance = (getDistanceBetweenPoints3D (tx, ty, tz, vx, vy, vz))
193
						if (zombdistance < .8) then
194
							zmoan(source)
195
							setPedAnimation ( source, "knife", "KILL_Knife_Player", -1, false, false, true)
196
							setPedAnimation ( ptarget, "knife", "KILL_Knife_Ped_Damage", -1, false, false, true)
197
							setTimer ( Playerthroatbitten, 2300, 1, ptarget, source) 
198
							setTimer ( function (source) if ( isElement ( source ) ) then setElementData ( source, "status", "idle" ) end end, 5000, 1, source )
199
						else
200
							setElementData ( source, "status", "idle" )
201
						end
202
					else
203
						setElementData ( source, "status", "idle" )
204
					end
205
				end
206
			elseif (getElementData ( source, "status" ) ==  "dead" ) then
207
				setTimer ( Zomb_delete, 10000, 1, source)
208
			end
209
		end
210
	end
211
end)
212
213
--RESOURCE START/INITIAL SETUP
214
function outbreak(startedResource)
215
	newZombieLimit = get("" .. getResourceName(startedResource) .. ".Zlimit")
216
	if newZombieLimit ~= false then
217
		if newZombieLimit > ZombieLimit then 
218
			newZombieLimit = ZombieLimit
219
		end
220
	else
221
		newZombieLimit = ZombieLimit
222
	end
223
	WoodTimer = setTimer ( WoodSetup, 2000, 1) -- CHECKS FOR BARRIERS
224
	if startedResource == getThisResource() then
225
        getResourceFromName("scoreboard"), "scoreboardAddColumn", "Zombie kills"--		call(getResourceFromName("scoreboard"), "scoreboardAddColumn", "Zombie kills") --ADDS TO SCOREBOARD
226
		local allplayers = getElementsByType ( "player" )
227
		for pKey,thep in ipairs(allplayers) do
228
			setElementData ( thep, "dangercount", 0 )
229
		end	
230
		local alivePlayers = getAlivePlayers ()
231
		for playerKey, playerValue in ipairs(alivePlayers) do
232
			setElementData ( playerValue, "alreadyspawned", true  )
233
		end
234
		if ZombieSpeed == 2 then
235
			MainTimer1 = setTimer ( setangle, 200, 0) -- KEEPS ZOMBIES FACING THE RIGHT DIRECTION (fast)
236
		else
237
			MainTimer1 = setTimer ( setangle, 400, 0) -- KEEPS ZOMBIES FACING THE RIGHT DIRECTION
238
		end
239
		MainTimer3 = setTimer ( clearFarZombies, 3000, 0) --KEEPS ALL THE ZOMBIES CLOSE TO PLAYERS	
240
		if ZombieStreaming == 1 then
241
			MainTimer2 = setTimer ( SpawnZombie, 2500, 0 ) --Spawns zombies in random locations
242
		elseif ZombieStreaming == 2 then
243
			MainTimer2 = setTimer ( SpawnpointZombie, 2500, 0 ) --spawns zombies in zombie spawnpoints
244
		end
245
	end
246
end
247
addEventHandler("onResourceStart", getRootElement(), outbreak)
248
249
function player_Connect()
250
	setElementData ( source, "dangercount", 0 )
251
end
252
addEventHandler ( "onPlayerConnect", getRootElement(), player_Connect )
253
254
function WoodSetup()
255
	local allcols = getElementsByType ( "colshape" ) --clears off old wood cols
256
	for colKey, colValue in ipairs(allcols) do
257
		if ( getElementData ( colValue, "purpose" ) =="zombiewood" ) then
258
			destroyElement(colValue)
259
		end
260
	end	
261
	local allobjects = getElementsByType ( "object" ) --SETS UP ALL THE WOOD BARRIERS
262
	for objectKey, objectValue in ipairs(allobjects) do
263
		if ( getElementData ( objectValue, "purpose" ) =="zombiewood" ) then
264
			setElementDimension ( objectValue, 26 )
265
			local x,y,z = getElementPosition( objectValue )
266
			local thecol = createColSphere ( x, y, z, 1.6 )
267
			setElementData ( thecol, "purpose", "zombiewood" )
268
			setElementParent ( thecol, objectValue )
269
		end
270
	end	
271
end
272
273
function ReduceMoancount()
274
	moancount = moancount-1
275
end
276
277
function zmoan(zombie)
278
	if moancount < moanlimit then
279
		moancount = moancount+1
280
		local randnum = math.random( 1, 10 )
281
		triggerClientEvent ( "Zomb_Moan", getRootElement(), zombie, randnum )
282
		setTimer ( ReduceMoancount, 800, 1 )
283
	end
284
end
285
286
--CLEARS A DEAD ZOMBIE
287
function Zomb_delete (ped)
288
	if isElement(ped) then
289
		if (getElementData (ped, "zombie") == true) then
290
			for theKey,thePed in ipairs(everyZombie) do
291
				if ped == thePed then
292
					table.remove( everyZombie, theKey )
293
					break
294
				end
295
			end
296
			destroyElement ( ped )
297
		end
298
	end
299
end
300
301
--HEADSHOTS
302
addEvent( "headboom", true )
303
function Zheadhit ( ped,attacker, weapon, bodypart)
304
	if (getElementData (ped, "zombie") == true) then
305
		killPed ( ped, attacker, weapon, bodypart )
306
		setPedHeadless  ( ped, true )
307
	end
308
end
309
addEventHandler( "headboom", getRootElement(), Zheadhit )
310
311
--KILL FROM ZOMBIE ATTACK
312
addEvent( "playereaten", true )
313
function Playerinfected ( player, attacker, weapon, bodypart)
314
    killPed ( player, attacker, weapon, bodypart )
315
end
316
addEventHandler( "playereaten", getRootElement(), Playerinfected )
317
318
--CHECKS FOR ZOMBIE GRABBING FROM BEHIND
319
function Playerthroatbitten ( player, attacker)
320
	local Zx, Zy, Zz = getElementPosition( attacker )
321
	local Px, Py, Pz = getElementPosition( player )
322
	local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
323
	if (distance < 1) then
324
		killPed ( player, attacker, weapon, bodypart )
325
	else
326
		setPedAnimation (player)
327
	end
328
end
329
330
--ADJUSTS PLAYERS ZOMBIE KILL SCORE
331
function deanimated( ammo, attacker, weapon, bodypart )
332
	if (attacker) then
333
		if (getElementType ( attacker ) == "player") and (getElementType ( source ) == "ped") then
334
			if (getElementData (source, "zombie") == true) then
335
				local oldZcount = getElementData ( attacker, "Zombie kills" )
336
				if oldZcount ~= false then
337
					setElementData ( attacker, "Zombie kills", oldZcount+1  )
338
					triggerEvent ( "onZombieWasted", source, attacker, weapon, bodypart )
339
				else
340
					setElementData ( attacker, "Zombie kills", 1  )
341
					triggerEvent ( "onZombieWasted", source, attacker, weapon, bodypart )				
342
				end
343
			end
344
		end
345
	end
346
end
347
addEventHandler("onPedWasted", resourceRoot, deanimated)
348
349
--STUFF TO ALLOW PLAYERS TO PLACE BOARDS
350
function boarditup( player, key, keyState )
351
	local rightspot = 0
352
	local allcols = getElementsByType ( "colshape" )
353
	for ColKey,theCol in ipairs(allcols) do
354
		if (getElementData ( theCol, "purpose" ) == "zombiewood" ) then
355
			if (isElementWithinColShape ( player, theCol )) then
356
				local rightcol = theCol
357
				local Cx, Cy, Cz = getElementPosition( rightcol )
358
				local Bx, By, Bz = getElementPosition( player )
359
				woodangle = ( 360 - math.deg ( math.atan2 ( ( Cx - Bx ), ( Cy - By ) ) ) ) % 360
360
				setPedRotation( player, woodangle )
361
				setPedAnimation(player, "riot", "RIOT_PUNCHES", 3000, true, true, true )
362
				local wx, wy, wz = getElementPosition( player )
363
				setTimer( doneboarding, 2000, 1, player, rightcol, wx, wy, wz )
364
			end
365
		end
366
	end
367
end
368
addCommandHandler ( "construct", boarditup )
369
	
370
function doneboarding(player, rightcol, wx, wy, wz)
371
	setPedAnimation(player)
372
	local newx, newy, newz = getElementPosition( player )
373
	local distance = (getDistanceBetweenPoints3D( wx, wy, wz, newx, newy, newz ))			
374
	if (distance < .7 ) then
375
		newwood = getElementParent ( rightcol )
376
		setElementDimension ( newwood, 25 )
377
		setTimer( setElementDimension, 50, 1, newwood, 0)
378
	end
379
end
380
381
382
--SPAWN ZOMBIE (now can be cancelled!)
383
384
addEvent( "onZombieSpawn", true )
385
function RanSpawn_Z ( gx, gy, gz, rot)
386
	local safezone = 0
387
	local allradars = getElementsByType("radararea")
388
	for theKey,theradar in ipairs(allradars) do
389
		if getElementData(theradar, "zombieProof") == true then
390
			if isInsideRadarArea ( theradar, gx, gy ) then
391
				safezone = 1
392
			end
393
		end
394
	end
395
	if safezone == 0 then
396
		if table.getn ( everyZombie ) < newZombieLimit then
397
			if not rot then
398
				rot = math.random (1,359)
399
			end
400
			randomZskin = math.random ( 1, table.getn ( ZombiePedSkins ) )			
401
			local zomb = createPed( tonumber( ZombiePedSkins[randomZskin] ), gx, gy, gz )
402
			if zomb ~= false then
403
				setElementData ( zomb, "zombie", true  )
404
				table.insert( everyZombie, zomb )	
405
				setTimer ( function (zomb, rot) if ( isElement ( zomb ) ) then setPedRotation ( zomb, rot ) end end, 500, 1, zomb, rot )
406
				setTimer ( function (zomb) if ( isElement ( zomb ) ) then setPedAnimation ( zomb, "ped", chaseanim, -1, true, true, true ) end end, 1000, 1, zomb )
407
				setTimer ( function (zomb) if ( isElement ( zomb ) ) then setElementData ( zomb, "status", "idle" ) end end, 2000, 1, zomb )
408
				triggerClientEvent ( "Zomb_STFU", getRootElement(), zomb )
409
			end
410
		end
411
	end
412
end
413
addEventHandler( "onZombieSpawn", getRootElement(), RanSpawn_Z )
414
415
416
--SPAWNS ZOMBIES RANDOMLY NEAR PLAYERS
417
function SpawnZombie ()
418
    if not ( ({getTime()})[1] >= 0 and ({getTime()})[1] <= 18 ) then return false end
419
	local pacecount = 0
420
	while pacecount < 5 do	--4 ZOMBIES AT A TIME TO PREVENT FPS DROP
421
		if (table.getn( everyZombie )+pacecount < newZombieLimit ) and (ZombieStreaming == 1) then	
422
			local xcoord = 0
423
			local ycoord = 0
424
			local xdirection = math.random(1,2)
425
			if xdirection == 1 then
426
				xcoord = math.random(15,40)
427
			else
428
				xcoord = math.random(-40,-15)
429
			end
430
			local ydirection = math.random(1,2)
431
			if ydirection == 1 then
432
				ycoord = math.random(15,40)
433
			else
434
				ycoord = math.random(-40,-15)
435
			end
436
			local liveplayers = getAlivePlayers ()
437
			if (table.getn( liveplayers ) > 0 ) then
438
				local lowestcount = 99999
439
				local lowestguy = nil
440
				for PKey,thePlayer in ipairs(liveplayers) do
441
					if isElement(thePlayer) then
442
						if (getElementData (thePlayer, "dangercount")) and (getElementData(thePlayer, "zombieProof") ~= true) and (getElementData(thePlayer, "alreadyspawned" ) == true) then
443
							if (getElementData (thePlayer, "dangercount") < lowestcount) then
444
								local safezone = 0
445
								local gx, gy, gz = getElementPosition( thePlayer )
446
								local allradars = getElementsByType("radararea")
447
								for theKey,theradar in ipairs(allradars) do
448
									if getElementData(theradar, "zombieProof") == true then
449
										if isInsideRadarArea ( theradar, gx, gy ) then
450
											safezone = 1
451
										end
452
									end
453
								end
454
								if safezone == 0 then
455
									lowestguy = thePlayer
456
									lowestcount = getElementData (thePlayer, "dangercount")
457
								end
458
							end
459
						end
460
					end
461
				end
462
				pacecount = pacecount+1
463
				if isElement(lowestguy) then
464
					triggerClientEvent ( "Spawn_Placement", lowestguy, ycoord, xcoord )
465
				else
466
					pacecount = pacecount+1
467
				end
468
			else
469
				pacecount = pacecount+1
470
			end
471
		else
472
			pacecount = pacecount+1
473
		end
474
	end
475
end
476
477
--SPAWNS ZOMBIES IN SPAWNPOINTS NEAR PLAYERS
478
function SpawnpointZombie ()
479
	local pacecount = 0
480
	while pacecount < 6 do	--5 ZOMBIES AT A TIME TO PREVENT FPS DROP
481
		if (table.getn( everyZombie )+pacecount < newZombieLimit ) and (ZombieStreaming == 2) then	
482
			local liveplayers = getAlivePlayers ()
483
			if (table.getn( liveplayers ) > 0 ) then
484
				local lowestcount = 99999
485
				local lowestguy = nil
486
				for PKey,thePlayer in ipairs(liveplayers) do --THIS PART GETS THE PLAYER WITH THE LEAST ZOMBIES ATTACKING
487
					if (getElementData (thePlayer, "dangercount")) and (getElementData(thePlayer, "zombieProof") ~= true) then
488
						if (getElementData (thePlayer, "dangercount") < lowestcount) then
489
							lowestguy = thePlayer
490
							lowestcount = getElementData (thePlayer, "dangercount")
491
						end
492
					end
493
				end
494
				if isElement(lowestguy) then
495
					local zombiespawns = { }
496
					local possiblezombies = getElementsByType ( "Zombie_spawn" )
497
					local Px, Py, Pz = getElementPosition( lowestguy )
498
					for ZombKey,theZomb in ipairs(possiblezombies) do
499
						local Zx, Zy, Zz = getElementPosition( theZomb )
500
						local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
501
						if (distance < 8) then
502
							table.remove( possiblezombies, ZombKey) --IF SPAWN IS TOO CLOSE TO ANY PLAYER
503
						end
504
					end
505
					local Px, Py, Pz = getElementPosition( lowestguy )
506
					for ZombKey2,theZomb2 in ipairs(possiblezombies) do
507
						local Zx, Zy, Zz = getElementPosition( theZomb2 )
508
						local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
509
						if (distance < 60) then --AS LONG AS THE SPAWN IS CLOSE ENOUGH TO A PLAYER
510
							table.insert( zombiespawns, theZomb2 )
511
						end
512
					end
513
					if (table.getn( zombiespawns ) >0 ) then--IF THE LOWEST PLAYER HAS ANY CLOSE SPAWNS,USE ONE
514
						local random = math.random ( 1, table.getn ( zombiespawns ) )
515
						local posX = getElementData(zombiespawns[random], "posX") 
516
						local posY = getElementData(zombiespawns[random], "posY") 
517
						local posZ = getElementData(zombiespawns[random], "posZ")
518
						local rot = getElementData(zombiespawns[random], "rotZ")
519
						pacecount = pacecount+1
520
						triggerEvent ( "onZombieSpawn",zombiespawns[random], posX, posY, posZ, rot )			
521
					else--IF THE LOWEST PLAYERS DOESNT HAVE ANY SPAWNS, THEN SEE IF ANYONE HAS ANY
522
						local zombiespawns = { }
523
						local possiblezombies = getElementsByType ( "Zombie_spawn" )
524
						local allplayers = getAlivePlayers ()
525
						for theKey,thePlayer in ipairs(allplayers) do
526
							local Px, Py, Pz = getElementPosition( thePlayer )
527
							for ZombKey,theZomb in ipairs(possiblezombies) do
528
								local Zx, Zy, Zz = getElementPosition( theZomb )
529
								local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
530
								if (distance < 8) then
531
									table.remove( possiblezombies, ZombKey) --IF SPAWN IS TOO CLOSE TO ANY PLAYER
532
								end
533
							end
534
						end
535
						for theKey,thePlayer in ipairs(allplayers) do
536
							local Px, Py, Pz = getElementPosition( thePlayer )
537
							for ZombKey2,theZomb2 in ipairs(possiblezombies) do
538
								local Zx, Zy, Zz = getElementPosition( theZomb2 )
539
								local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
540
								if (distance < 60) then --AS LONG AS THE SPAWN IS CLOSE ENOUGH TO A PLAYER
541
									table.insert( zombiespawns, theZomb2 )
542
								end
543
							end
544
						end
545
						if (table.getn( zombiespawns ) >1 ) then
546
							local random = math.random ( 1, table.getn ( zombiespawns ) )
547
							local posX = getElementData(zombiespawns[random], "posX") 
548
							local posY = getElementData(zombiespawns[random], "posY") 
549
							local posZ = getElementData(zombiespawns[random], "posZ")
550
							local rot = getElementData(zombiespawns[random], "rotZ")
551
							pacecount = pacecount+1
552
							triggerEvent ( "onZombieSpawn",zombiespawns[random], posX, posY, posZ, rot )			
553
						else
554
							pacecount = pacecount+1
555
						end
556
					end
557
				else
558
					pacecount = pacecount+1
559
				end
560
			else
561
				pacecount = pacecount+1
562
			end
563
		else
564
			pacecount = pacecount+1
565
		end
566
	end
567
end
568
569
--DELETES ZOMBIES THAT ARE TOO FAR FROM ANY PLAYERS TO KEEP THEM MORE CONCENTRATED WHILE STREAMING ZOMBIES
570
function clearFarZombies ()
571
	if newZombieLimit ~= false then
572
		local toofarzombies = { }
573
		local allplayers = getElementsByType ( "player" )
574
		for ZombKey,theZomb in ipairs(everyZombie) do
575
			if isElement(theZomb) then
576
				if (getElementData (theZomb, "zombie") == true) then
577
					far = 1
578
					local Zx, Zy, Zz = getElementPosition( theZomb )
579
					for theKey,thePlayer in ipairs(allplayers) do
580
						local Px, Py, Pz = getElementPosition( thePlayer )
581
						local distance = (getDistanceBetweenPoints3D( Px, Py, Pz, Zx, Zy, Zz ))
582
						if (distance < 75) then
583
							far = 0
584
						end
585
					end
586
					if far == 1 then
587
						table.insert( toofarzombies, theZomb )
588
					end
589
				end
590
			else
591
				table.remove( everyZombie, ZombKey )
592
			end
593
		end
594
		if (table.getn( toofarzombies ) >1 ) then
595
			for ZombKey,theZomb in ipairs(toofarzombies) do
596
				if (getElementData (theZomb, "zombie") == true) and  ( getElementData ( theZomb, "forcedtoexist" ) ~= true) then
597
					Zomb_delete (theZomb)
598
				end
599
			end
600
		end
601
	end
602
end
603
604
-- DESTROYS UP TO 13 ZOMBIES THAT ARE IDLE WHEN A PLAYER SPAWNS (TO FORCE NEW ZOMBIES TO SPAWN NEAR THE NEW GUY)
605
function player_Spawn ()
606
	if ZombieStreaming == 1 or ZombieStreaming == 2 then
607
		local relocatecount = 0
608
		for ZombKey,theZomb in ipairs(everyZombie) do
609
			if relocatecount < 14 then
610
				if ( getElementData ( theZomb, "forcedtoexist" ) ~= true) then
611
					if ( getElementData ( theZomb, "status" ) == "idle" ) and ( isPedDead ( theZomb ) == false ) and (getElementData (theZomb, "zombie") == true) then
612
						relocatecount = relocatecount+1
613
						Zomb_delete (theZomb)
614
					end
615
				end
616
			end
617
		end
618
	end
619
	if ( getElementData ( source, "alreadyspawned" ) ~= true) then
620
		setElementData ( source, "alreadyspawned", true  )
621
	end
622
end
623
addEventHandler ( "onPlayerSpawn", getRootElement(), player_Spawn )
624
625
--EXPORTED FUNCTIONS!!!!!!!!!!!!!!
626
function createZombie ( x, y, z, rot, skin, interior, dimension )
627
	if (table.getn( everyZombie ) < newZombieLimit ) then
628
	--this part handles the args
629
		if not x then return false end
630
		if not y then return false end
631
		if not z then return false end
632
		if not rot then
633
			rot = math.random (1,359)
634
		end
635
		if not skin then
636
			randomZskin = math.random ( 1, table.getn ( ZombiePedSkins ) )			
637
			skin = ZombiePedSkins[randomZskin]
638
		end
639
		if not interior then interior = 0 end
640
		if not dimension then dimension = 0 end
641
	--this part spawns the ped
642
		local zomb = createPed (tonumber(skin),tonumber(x),tonumber(y),tonumber(z))--spawns the ped
643
	--if successful, this part applies the zombie settings/args
644
		if (zomb ~= false) then
645
			setTimer ( setElementInterior, 100, 1, zomb, tonumber(interior)) --sets interior
646
			setTimer ( setElementDimension, 100, 1, zomb, tonumber(dimension)) --sets dimension
647
			setElementData ( zomb, "zombie", true  )
648
			setElementData ( zomb, "forcedtoexist", true  )
649
			setTimer ( function (zomb, rot) if ( isElement ( zomb ) ) then setPedRotation ( zomb, rot ) end end, 500, 1, zomb, rot )
650
			setTimer ( function (zomb) if ( isElement ( zomb ) ) then setElementData ( zomb, "status", "idle" ) end end, 2000, 1, zomb )
651
			setTimer ( function (zomb) if ( isElement ( zomb ) ) then setElementData ( zomb, "forcedtoexist", true ) end end, 1000, 1, zomb )
652
			setTimer ( function (zomb) if ( isElement ( zomb ) ) then table.insert( everyZombie, zomb ) end end, 1000, 1, zomb )
653
			triggerClientEvent ( "Zomb_STFU", getRootElement(), zomb )
654
			return zomb --returns the zombie element
655
		else
656
			return false --returns false if there was a problem
657
		end
658
	else
659
		return false --returns false if there was a problem
660
	end
661
end
662
663
--check if a ped is a zombie or not
664
function isPedZombie(ped)
665
	if (isElement(ped)) then
666
		if (getElementData (ped, "zombie") == true) then
667
			return true
668
		else
669
			return false
670
		end
671
	else
672
		return false
673
	end
674
end
675
676
addEvent( "onZombieLostPlayer", true )
677
function ZombieTargetCoords ( x,y,z )
678
	setElementData ( source, "Tx", x, false )
679
	setElementData ( source, "Ty", y, false )
680
	setElementData ( source, "Tz", z, false )
681
end
682
addEventHandler( "onZombieLostPlayer", getRootElement(), ZombieTargetCoords )