Random added empties switch state

How would it be possible to choose randomly from a bunch added empty’s from a hidden layers placed in many different places?And how would i switch that empty’s state with python?

I want to improve on the endless runner car game i posted in works in progress and game demos.I need a script like this.

switching states in python is confusing and hard to read. it would be better to create a property (integer, bool, string) to contol if-then statements. then an outside program can change that property, and the script reroutes accordingly.

## Properties = {STATE: "IDLE"} ##

OWNER = GameObject

if OWNER["STATE"] == "IDLE":
    #code

elif OWNER["STATE'] == "ACTIVE":
    #code

a_list = []

added = addObject blabla
a_list.append(added)

creates a list of added objects.

then

import random

random.choice(a_list)

this will select a random entry from the list.

as deadalus said changing states in python is painful due to the the states are not as it should be (my opinion)
like state1 could have the name state 100 in python(rough example), so its hard to figure out the exact states.

i would use a property on the empty that tells what state you are in then use the logic state controls to switch states, or just activate actions according to the property with the property sensor.

use a dictionary and random?

pseudo


{states}[random]

These are tow different and independent operations.

A) randomly chose an object (or object name) from the available objects to act as template object.
B) chose a position, orientation, scale and apply that to the emitter object
C) add a new object with the emitter object and the previously chosen template object

emitter object = copy position, orientation and scale from
template object = copy logic bricks, mesh and physics from

The same way you do with any other game object:


gameobject.state = stateBitMap

I could not figure it out.

Here is my code.

import bge
import random


a_list = []


added = addObject.addObject(obj, own, Empty)
a_list.append(added)


random.choice(a_list)
cont = bge.logic.getCurrentController()
act = cont.actuators["StateMask_2"]
type = act.operation
act.operation = 1

why do you need states so bad? whats the end result your wanting the code to do?

To place only one npc on a random terrain tile that had been added in a endless runner videogame.

not tested but should work, you need to give all variables, you missed some.
and to create a list you want the list creator(a_list) called only once, not every time the script gets called.


import bge
import random


#outside a function runs only once
a_list = []


#call this in module mode #(rename as you wish)
def random_something():
    
    cont = bge.logic.getCurrentController()


    own = cont.owner # forgot this one
    obj = ???? # this one as well
    Empty = 0 # to let it live forever, note 3rd variable should be the duration the object lives


    added = own.scene.addObject(obj, own, Empty) # what, from, duration. Empty is no duration also a double addObject
    a_list.append(added)


    test = random.choice(a_list)
    print(test)

as i read you just need to grab the empties and then do something with it
that can be done like this:


def do_stuff(): #(rename as you wish)
    
    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    #creates a list with all empties that are currently in the scene; that has a property called npc_spawn
    list_with_empties = [obj for obj in own.scene.objects if 'npc_spawn' in obj]
    random_empty = random.choice(list_with_empties)

I tried this but i get no error.What could be wrong?

def add_friedly_npc (): 
    
    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    
    list_with_empties = [obj for obj in own.scene.objects if 'npc_spawn' in obj]
    random_empty = random.choice(list_with_empties)


act = cont.actuators["StateMask_2"]
type = act.operation
act.operation = 1

If I understand you correctly you want to select a random “character type” that wasn’t selected before?

Think about that:

  • have a list of available character types
  • each time you want to create a character you select a random character type, create such a character and remove the character type from the list of available character types.
  • when the list is empty you created characters off all types

Be aware the list has to persist longer than a frame.

example:



import bge
import random

owner = bge.logic.getCurrentController().owner
scene = owner.scene

availableCharacterTypes = owner.get("available character types")
if availableCharacterTypes = None:
    availableCharacterTypes  = [object for object in scene.objectsInactive if "character" in object]
    owner["available character types"] = availableCharacterTypes 

emitter = owner # or whatever you want
selectedCharacterType = <b>random.choice(availableCharacterTypes)</b>
availableCharacterTypes.remove(selectedCharacterType)

addedCharacter = scene.addObject(emitter, selectedCharacterType)


untested - there might by typing errors.

alternative way:

  • create a list of available character types
  • sort them in random order
  • when adding characters pick and remove the first one


import bge
import random

owner = bge.logic.getCurrentController().owner
scene = owner.scene

availableCharacterTypes = owner.get("available character types")
if availableCharacterTypes = None:
    availableCharacterTypes  = [object for object in scene.objectsInactive if "character" in object]
    <b>random.shuffle(availableCharacterTypes)</b>
    owner["available character types"] = availableCharacterTypes 

emitter = owner # or whatever you want
selectedCharacterType = <b>availableCharacterTypes.pop()</b>

addedCharacter = scene.addObject(emitter, selectedCharacterType)


no idea if the state script is right (never used states / with python) but did you add a property ‘npc_spawn’ to the empties?
and you got a typo, add_friedly_npc () - or with an N -> friendly

also you are running the state code outside the function, tab it so it gets inside the function

This is actually how it looks.I did add the property npc_spawn to the emptys.

def add_friendly_npc (): 
    
    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    
    list_with_empties = [obj for obj in own.scene.objects if 'npc_spawn' in obj]
    random_empty = random.choice(list_with_empties)


    act = cont.actuators["StateMask_2"]
    type = act.operation
    act.operation = 1

Are you running it in module mode or in script mode?

The python brick, put it on module, then scriptname.add_friendly_npc
(script it self needs to end with .py so scriptname.py)

but you dont use the list with empties so nothing it can do, only thing your script does atm is creating a list, and set the actuators operation on 1 nothing else.

and to be sure if the list is there just put print(random_empty) below it.

I wanted it to set one of those actuators operation on 1 for meshes with the property npc_spawn.

The error in the console says there is no attribute main.So it does not work as is.

I wanted to randomly spawn a npc at a far away location.So i found one on blender stack exchange that i could modify.