Doc
Valued Member!
HOTFIX** 01/01/2013 - UPDATE YOUR CODE
There was an issue with the function creating vehicles with a NULL ObjectUID/Worldspace in some circumstances. I have updated line 53 of the code to fix this - please reapply the pSpawnVehicles function below
The Current System
The way vehicles are currently spawned is a bit strange and is better suited for low vehicle counts (<10). If you set your maximum cars to say, 40, and there are 40 or more spawn points available, then there will always be exactly 40 vehicles on the map. This is a bit silly, because it kind of nullifies the spawn chances - if the spawn chance is 0.1 (10%) and there are only 40 spawn locations then that car will always be in the map. This is why I have completely rescripted the vehicle spawn function.
My New System
In my new system, vehicles are spawned entirely based on their spawn chance - this is better for large vehicle counts. The old way of setting 40 or whatever vehicles as your iSpawnNumVeh in pMain is messy. It's more efficient to attempt to spawn every vehicle in your object_classes and see if their spawn chance let's them spawn or not. Welcome to the world of dynamic vehicle spawns! Some restarts they may be 20 vehicles on your server, on others there may be 40. This is a great way to stop all vehicles spawning at once and prevent people having a headstart on vehicle hoarding. You will no longer need to edit pMain, as it is obsolete (as is pSpawn). Instead all vehicle spawns are taken from object_classes. Every vehicle allowed to spawn in object_classes could appear on the map, but it all depends on it's chance parameter.
RECOMMENDED
Follow this HotFix ASAP (Even if you don't use this function)
Follow this guide afterwards [How-To] Prevent persistent vehicles hacked into database
Setup
You do not need to delete/edit existing functions. Just create a new procedure called pSpawnVehicles (you can name it what you like) with the following code:
pSpawnVehicles
fGetVehCount
fGetSpawnFromChance
database structure changes (*Important)
If you are using pwnoz0rs launcher, now you just need to change pMain() to pSpawnVehicles by editing the .bat file.
You are now good to go! Now you can add more vehicle spawn points to your object_spawns and object_classes and enjoy the new spawning method. If you ever decide to revert to the old pMain system, then just change which function you are calling.
I will soon make an SQL script to add this all in and make the changes for you, but once I have time.
-Doc
EXTRA COURTESY FILES:
- object_spawns.sql* - 92 vehicle spawn locations (comments in description say location)
- object_classes.sql* - object_classes to complement the object_spawns
You may have to tweak object_classes to work with any custom spawn points you added.
I cant remember if description is a field in pwnaz0rs version, if it isn't just add a description text column
*saved as .txt to bypass forum filter
There was an issue with the function creating vehicles with a NULL ObjectUID/Worldspace in some circumstances. I have updated line 53 of the code to fix this - please reapply the pSpawnVehicles function below
The Current System
The way vehicles are currently spawned is a bit strange and is better suited for low vehicle counts (<10). If you set your maximum cars to say, 40, and there are 40 or more spawn points available, then there will always be exactly 40 vehicles on the map. This is a bit silly, because it kind of nullifies the spawn chances - if the spawn chance is 0.1 (10%) and there are only 40 spawn locations then that car will always be in the map. This is why I have completely rescripted the vehicle spawn function.
My New System
In my new system, vehicles are spawned entirely based on their spawn chance - this is better for large vehicle counts. The old way of setting 40 or whatever vehicles as your iSpawnNumVeh in pMain is messy. It's more efficient to attempt to spawn every vehicle in your object_classes and see if their spawn chance let's them spawn or not. Welcome to the world of dynamic vehicle spawns! Some restarts they may be 20 vehicles on your server, on others there may be 40. This is a great way to stop all vehicles spawning at once and prevent people having a headstart on vehicle hoarding. You will no longer need to edit pMain, as it is obsolete (as is pSpawn). Instead all vehicle spawns are taken from object_classes. Every vehicle allowed to spawn in object_classes could appear on the map, but it all depends on it's chance parameter.
RECOMMENDED
Follow this HotFix ASAP (Even if you don't use this function)
Follow this guide afterwards [How-To] Prevent persistent vehicles hacked into database
Setup
You do not need to delete/edit existing functions. Just create a new procedure called pSpawnVehicles (you can name it what you like) with the following code:
pSpawnVehicles
Code:
BEGIN
DECLARE iCurrentVehicles INT(4) DEFAULT 0;
DECLARE loopCounter INT(4) DEFAULT 0;
DECLARE iSpawnAttempts INT(4) DEFAULT 0;
DECLARE iTotalClasses INT(4) DEFAULT 0;
CALL pCleanup();
CALL pFixMaxNum;
SET iCurrentVehicles = fGetVehCount();
SELECT COUNT(*)
INTO iTotalClasses
FROM object_classes;
SELECT SUM(MaxNum) FROM object_classes INTO @iMaxNumTotal;
IF (iCurrentVehicles > @iMaxNumTotal) THEN
SET iSpawnAttempts = @iMaxNumTotal - iCurrentVehicles;
END IF;
WHILE (loopCounter < iTotalClasses) DO
SELECT Classname, Chance, MaxNum, Damage, MaxFuel, Inventory, Hitpoints
INTO @rsClassname, @rsChance, @rsMaxNum, @rsDamage, @rsMaxFuel, @rsInventory, @rsHitpoints
FROM object_classes
LIMIT loopCounter, 1;
SET @initialClassCount = fGetClassCount(@rsClassname);
IF (@initialClassCount < @rsMaxNum) THEN
SET @classloop = 0;
SET @attemptsAtClass = @rsMaxNum - @initialClassCount;
WHILE (@classloop < @attemptsAtClass) DO
SET @luckyDip = fGetSpawnFromChance(@rsChance + (RAND() / 10000));
IF (@luckyDip = 1) THEN
SELECT ObjectUID, Worldspace
INTO @spawnUID, @spawnWorldspace
FROM object_spawns o
WHERE Classname = @rsClassname AND NOT EXISTS (SELECT 1 FROM object_data e WHERE e.ObjectUID = o.ObjectUID)
ORDER BY RAND()
LIMIT 1;
SET @fuel = (FLOOR( (RAND()*@rsMaxFuel) * 10000) / 10000);
INSERT INTO object_data (ObjectUID, Instance, Landmark, Classname, Damage, CharacterID, Worldspace, Inventory, Hitpoints, Fuel, Datestamp)
VALUES (@spawnUID, '1', '0', @rsClassname, @rsDamage, '0', @spawnWorldspace, @rsInventory, @rsHitpoints, @fuel, SYSDATE());
END IF;
SET @classloop = @classloop + 1;
END WHILE;
END IF;
SET loopCounter = loopCounter + 1;
END WHILE;
END
fGetVehCount
A small change can be made to fGetVehCount to utilize the Landmark parameter (read below)
Code:
BEGIN
DECLARE iVehCount SMALLINT(3) DEFAULT 0;
SELECT COUNT(*)
INTO iVehCount
FROM object_data
WHERE
Landmark = '0'
AND Classname != 'dummy'
AND Classname != 'TentStorage'
AND Classname != 'Hedgehog_DZ'
AND Classname != 'Wire_cat1'
AND Classname != 'Sandbag1_DZ'
AND Classname != 'TrapBear';
RETURN iVehCount;
END
fGetSpawnFromChance
If (like me) your fGetSpawnFromChance is empty, you will need to paste the code below in, and set the parameter to `chance` DECIMAL(6,5). Using Navicat, you may have trouble saving this function. To fix this, set the Data Access (in advanced tab) to READS SQL - paste your function/parameter - save the function - now set Data Access to NO SQL and it should save. No idea why it does that, but the method to save it works... somehow.
Code:
BEGIN
DECLARE bspawn TINYINT(1) DEFAULT 0;
IF (RAND() <= chance) THEN
SET bspawn = 1;
END IF;
RETURN bspawn;
END
database structure changes (*Important)
Nearly forgot this part...
New column to objects_classes.
MaxFuel - Varchar(10) DEFAULT 0
(Reason for this should be self-explanatory - fuel on spawn is a random number up to MaxFuel)
Inventory - Text(0) DEFAULT []
(Allows you to set certain vehicles to spawn with a given inventory loadout)
New column to object_data
Landmark - TinyINT(1) DEFAULT 0
(The reason for this is because if you use my guide to add land objects to the database, it interferes with the fGetVehCount. Instead of adding an exception for each new object, it's easier to classify all vehicles as landmark 0 and give all objects landmark 1 when you add them in. If you don't add objects in via object_data, just add this column anyway)
Change to Chance column of object_classes
make the chance column type DECIMAL with the length 6 and decimals 5. This is for consistency.
New column to objects_classes.
MaxFuel - Varchar(10) DEFAULT 0
(Reason for this should be self-explanatory - fuel on spawn is a random number up to MaxFuel)
Inventory - Text(0) DEFAULT []
(Allows you to set certain vehicles to spawn with a given inventory loadout)
New column to object_data
Landmark - TinyINT(1) DEFAULT 0
(The reason for this is because if you use my guide to add land objects to the database, it interferes with the fGetVehCount. Instead of adding an exception for each new object, it's easier to classify all vehicles as landmark 0 and give all objects landmark 1 when you add them in. If you don't add objects in via object_data, just add this column anyway)
Change to Chance column of object_classes
make the chance column type DECIMAL with the length 6 and decimals 5. This is for consistency.
If you are using pwnoz0rs launcher, now you just need to change pMain() to pSpawnVehicles by editing the .bat file.
You are now good to go! Now you can add more vehicle spawn points to your object_spawns and object_classes and enjoy the new spawning method. If you ever decide to revert to the old pMain system, then just change which function you are calling.
I will soon make an SQL script to add this all in and make the changes for you, but once I have time.
-Doc
EXTRA COURTESY FILES:
- object_spawns.sql* - 92 vehicle spawn locations (comments in description say location)
- object_classes.sql* - object_classes to complement the object_spawns
You may have to tweak object_classes to work with any custom spawn points you added.
I cant remember if description is a field in pwnaz0rs version, if it isn't just add a description text column
*saved as .txt to bypass forum filter