Jump to content
hippokittie

Random Item spawns?

Recommended Posts

So I am rather new to c++ and lua programming. I understand the basics of what the code I want is, just not how to express them. I want to choose between a number of things to randomly spawn in specific locations (like have one location but every time you return it is a diffrent item). I have the prefabs set up in the engine, and I want to assosiate those prefabs in the code with a number, and have the random number generator (which I have and it works) pick a number and then after that number is picked, spawn the item. I understand that for each piece I would have to do an If() statment, but don't understand how to make it spawn on the axis I set up in the map. Also The code I tried (but deleted because of it making leadwerks crash when it activated) would choose the number, but not be able to read what the number was supposed to be assosiated with. Any help, even just points in the right direction, would be very appreciated.

 

#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
//clear the screen.
clrscr();
//declare variables as int.
int high,low,random;
//get the data.
cout<<"Enter higher limit:";
cin>>high;
cout<<"Enter lower limit:";
cin>>low;
//generate random number
random = (rand() % (high-low+1) + low);
//print the numbers
cout<<random<<endl;
//get character
getch();
}

that is my random number generator code (that I use to choose the items( I use the code several diffrent time for diffrent items))

Share this post


Link to post

Well there is no easy AlignToTerrain() function that I know of so for making the item spawn on the correct axis you will probably need to do some coding. What I do in my game is spawn the item above its location and give it a mass of above 1. Then once the item hits the ground its mass goes to 0 and it sits still.

It would look something like this in code -

 

local item=self.item:Instance() --spawn item

item:SetPosition(self.itemlocation+Vec3(0,1,0)) --set Item above spawn location

item:SetMass(1) --set Items mass to 1 so it begins falling

item.script.falling=true --set falling to true so that the items Collision() function will work

 

function Script:Collision() --this collision function needs to be within the Items Script.

if self.falling then --check for falling

if entity:GetCollisionType()==Collision.Scene and not entity.script then --terrain check

self.entity:SetMass(0) --set mass to 0 to become still

end

end

end

 

That won't work for everything but maybe it will help a bit.

For getting numbers that are relative to items you would need something like this to spawn the item -

 

local item=self.item[self.itemnumber]:Instance()

 

Let me know if this helps at all!

Share this post


Link to post

Well there is no easy AlignToTerrain() function that I know of so for making the item spawn on the correct axis you will probably need to do some coding. What I do in my game is spawn the item above its location and give it a mass of above 1. Then once the item hits the ground its mass goes to 0 and it sits still.

It would look something like this in code -

 

local item=self.item:Instance() --spawn item

item:SetPosition(self.itemlocation+Vec3(0,1,0)) --set Item above spawn location

item:SetMass(1) --set Items mass to 1 so it begins falling

item.script.falling=true --set falling to true so that the items Collision() function will work

 

function Script:Collision() --this collision function needs to be within the Items Script.

if self.falling then --check for falling

if entity:GetCollisionType()==Collision.Scene and not entity.script then --terrain check

self.entity:SetMass(0) --set mass to 0 to become still

end

end

end

 

That won't work for everything but maybe it will help a bit.

For getting numbers that are relative to items you would need something like this to spawn the item -

 

local item=self.item[self.itemnumber]:Instance()

 

Let me know if this helps at all!

 

Sorry I am rather new like I said, but how do I define what number corrisponds with what item. Would I replace self.item.instance with self.gladios.instance?(gladios is one of the weapons). or local item=self.gladios(self.1):instance() ? along with that, if I do get it spawning, wouldnt the mass make it roll off my the shelf its ment to be on? I saw someone who wrote a code for spawning monsters in a set location, but they had to define the rotation as well, would that also be needed? Thank you again for responding, just trying to figure out things :D

Share this post


Link to post

One thing before I go on; are you using the Indie Edition (Lua) or Standard (C++)? Everything I am saying is relative to Lua but it can probably be translated to C++.

edit -- it seems you are using C++ so this example code I'm posting won't copy over exactly. You will need to change it a bit to get it to work.

 

local item=self.gladios(self.1):instance()

Is close but I was implying you could create a table for your items. This would make the number correspondence much easier.

For example in your Start() function you can assign numbers to a "item" table. In code it would look like this -

function Script:Start()

self.item={} --self.item is now a table

self.item[1]=self.gladios --the first item in your table is gladios now

self.item[2]=self.weapon2 --add other weapons

self.item[3]=self.weapon3

end

Then when you want to instance(spawn) one of those items randomly you would do -

 

local item=self.item[math.random(1,3)]:Instance()

 

This makes a new Instance of one of the items assigned to your self.item table using a random number.

You can replace math.random(1,3) with whatever number your random number generator creates.

 

wouldnt the mass make it roll off my the shelf its ment to be on? I saw someone who wrote a code for spawning monsters in a set location, but they had to define the rotation as well, would that also be needed?

 

Yeah the method I described in my first post is better for spawning things like resources outdoors because it requires space for the entity to drop into place but it does set the entities mass back to 0 once it hits the ground which prevents rolling and other physics things.

If you have a fixed location for your spawn points you should be able to just adjust the entities rotation before placing it into position with SetRotation(). That requires a bit of testing to find the perfect rotation for the set spawn point but it should work fine once you get it.

Share this post


Link to post

I changed my script to lua (as the random number thing is easier, but now I am more lost haha)

I tried a bit of fusing around with my code, and it stopped giving me errors, but now nothing spawns still. Did I do something wrong?

Script.SpawnRate = 1 --float
Script.Spawncount = 1--int
--[[
function Script:Start()
self.item={}
self.item[1]=self.Gladios
self.item[1]=self.Spear

self.counter = 0


end
]]--
--[[
function Script:UpdateWorld()

end
]]--
--[[
function Script:UpdatePhysics()
if self.counter >= Spawncount then return end
local a = math.random(0,1)
if Time:GetCurrent() > self.lastSpawnTime + (self.SpawnRate * 1000) then
self.counter = self.counter + 1
self.lastSpawnTime = Time:GetCurrent()
local Gladios = Prefab:Load("Map Assets/greate maze/weapons/gladios.pfb")
local Spear = Prefab:Load("Map Assets/great maze/weapons/Spear.pfb")
item:SetPosition(self.itemlocation+Vec3(0,1,0))
local item=self.item[math.random(1,3)]:Instance() 
end
]]--

Share this post


Link to post

If you have those comment sections in there, nothing will happen at all. The only part of the script that gets executed are the first two lines.

 

--[[ and ]]-- are for multi line commenting.

Share this post


Link to post

i removed the comment lines (and fixed a few bugs it found) bu now there is the error "attempt to perform arithmetic on field 'lastSpawnTime' (a nil value)". Is there someting wrong with the script there? and is there something wrong after that as well?

Share this post


Link to post

What Aggror said and you are over-riding your 'self.item' table in the Start function. You created a table but set both variables to 'self.item[1]'... should change to a [0] & [1].

 

And you haven't associated the actual prefabs being loaded to the variable names.

 

And you are doing a math.random between 1 & 3 but don't have that many table elements for self.item.

 

The error you just had is because the line should be:

if self.counter >= self.Spawncount then...

'Spawncount' is undefined (nil) and in itself is a different variable from Script.Spawncount (=self.Spawncount inside a Script function)

 

The same issue will occur with 'lastSpawnTime' since it is not defined.

Share this post


Link to post

What Aggror said and you are over-riding your 'self.item' table in the Start function. You created a table but set both variables to 'self.item[1]'... should change to a [0] & [1].

 

And you haven't associated the actual prefabs being loaded to the variable names.

 

And you are doing a math.random between 1 & 3 but don't have that many table elements for self.item.

 

The error you just had is because the line should be:

if self.counter >= self.Spawncount then...

'Spawncount' is undefined (nil) and in itself is a different variable from Script.Spawncount (=self.Spawncount inside a Script function)

 

The same issue will occur with 'lastSpawnTime' since it is not defined.

 

Alright, so I fixed the spawn cound issue, and found and issue with spawn count. fixed that issue and now am stuck with a error saying "attempting to index nill value" with my code "local item=self.item[math.random(1,3)]:Instance() " I have 3 items (added a bow to it) but something isnt clicking with it. do I need to refrence the script again in the function Script:start? Or make mention of the index in the update?

Share this post


Link to post

in your script is self.Gladios equal to anything? You need to make it reference the prefab if you haven't done that. Something like -

Script.Gladios=Prefab:Load("Project/Prefabs/prefabname.pfb")

 

If that isn't the issue then could I see how your script looks now?

Share this post


Link to post

I think this grabs everything you are trying to do. It lets you pick the prefabs to be loaded, the number of spawned items, and the time in seconds between spawns. Right now it spawns the prefab 2 meters above the scripted entity.

Script.spawnrate = 5 --float

Script.spawncount = 5--int

Script.item ={}

Script.item[0] = "Prefabs/Props/barrel01a.pfb" --path

Script.item[1] = "Prefabs/Props/cardboardbox.pfb" --path

 

function Script:Spawn(rand)

self.spawn = Prefab:Load(self.item[rand])

local entpos = self.entity:GetPosition(true)

self.spawn:SetPosition(entpos.x, entpos.y + 2, entpos.z, true)

self.spawntime = Time:Millisecs()

end

 

function Script:Start()

self.spawntime = Time:Millisecs()

self.counter = 0

end

 

function Script:UpdateWorld()

if self.counter < self.spawncount then

if Time:Millisecs() > self.spawntime + (self.spawnrate * 1000) then

self.counter = self.counter + 1

math.randomseed(Time:GetCurrent())

local rand = math.random(0,1)

self:Spawn(rand)

end

end

end

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...