Developer Store
Support
Member Forums

Screenshots
FAQ
Documentation
License
Known Issues
Downloads

MMOWorkshop.com Store Opened!
Torque MMO Kit - Open Sourced!
Torque MMO Kit - 1.5.2 Port Alpha Test
Torque MMO Kit - OSX Status

GarageGames.com irc.prairiegames.com
#mmoworkshop

PyTorque
TGB Web Browser


Prairie Games

mpratt - MMO Game
xapken - nice
foodstamp - Another Day Another Step Accomplished
hallsofvalhalla - After a long epiphany
Leathel - FoHO pre-Alpha 2.42
OldRod - More Musings on the MMO Industry
J.C. Smith - 0.0.4.1 Build Notes
Wolf Dreamer - Pointless blog of pointless things
... MORE BLOGS!

ZoneLink
cant compile world
UPDATE: renamed to server errors
The Repopulation (J.C-Xerves)
Floating Text..
ITEM VARIANTS ERADICATED... (for...
AFX Projectile Bug
Tips/Warnings on Organizing UI A...
Wont receive passwords
Mega Terrain Functionality?

This is a change to the Populator code to what I invisioned it before I tried to use it :-). This allows you to place a Spawnpoint much like a normal spawn point and call it POPULATOR_x and it will us that spawnpoint to randomly load mobs in that spawn group a 200x200 square around that area (100 in all directions). The mobs will roam around the area with the randomly generated walking points. You can use more than 1 populator in a zone and you can reuse populators to make the population more dense or what not.

This is good for open areas and probably not the best idea for a closed off area like a cave, fortress, city, etc.

--Xerves

mud/world/spawn.py

In the Spawnpoint class find the following bit of code:

        if group.startswith("POPULATOR_"):
            p,num=group.split("_")
            num = int(num)
            if zone.populatorGroups.has_key(num):
                group = zone.populatorGroups[num]
            else:
                groups = []
                fgroups = []
                gengroups = []
                for sg in zone.zone.spawnGroups:
                    if sg.targetName or sg.popFreq<0:
                        continue
                    unique = False
                    for sinfo in sg.spawninfos:
                        if sinfo.spawn.flags&RPG_SPAWN_UNIQUE:
                            unique=True
                            break
                    if unique:
                        print "Warning: pop group contains a unique spawn",sg.groupName
                        continue
                    if "CMT_RANK" in sg.groupName:
                        gengroups.append(sg)
                    elif "PRT_RANK" in sg.groupName:
                        gengroups.append(sg)
                    elif "MGE_RANK" in sg.groupName:
                        gengroups.append(sg)
                    elif "RGE_RANK" in sg.groupName:
                        gengroups.append(sg)
                    elif sg.popFreq>1:
                        fgroups.append(sg)
                    else:
                        groups.append(sg)
                
                
                if len(gengroups):
                    g= None
                    if len(gengroups)==1:
                        g=gengroups[0]
                    else:
                        g=gengroups[random.randint(0,len(gengroups)-1)]
                    if g.popFreq>1:
                        fgroups.append(g)
                    else:
                        groups.append(g)
                        
                for g in fgroups:
                    if not random.randint(0,g.popFreq):
                        groups.append(g)
                        
                if not len(groups):
                    print "WARNING!!!!! No spawn for populator"
                elif len(groups)==1:
                    group=groups[0].groupName.upper()
                else:
                    group=groups[random.randint(0,len(groups)-1)].groupName.upper()
                zone.populatorGroups[num]=group

You need to comment out this whole if check here using the """ at the begining of the check and """ at the end. You can delete it to if you like.

/mud/simulation/populator.py

Replace this whole file with this code. I made a variety of changes.

# Copyright (C) 2004-2007 Prairie Games, Inc
# Please see LICENSE.TXT for details

from tgenative import *
from mud.tgepython.console import TGEExport
import random
from mud.simulation.shared.simdata import SpawnpointInfo
import math

#Change the area covered.  Will make the pops more dense too
POPULATOR_AREA = 200
#Maximum amount of enemies loaded.  Also used to generated a random value
POPULATOR_POPMAX = 7

class Populator:
    def __init__(self,spawnpoints,paths):
        self.cspawnpoints = spawnpoints
        self.paths = paths        
        self.minz = 1000000
        self.maxz = -1000000
        
        print "Loading Populators:"
        #Find a middle ground for height among spawnpoints
        for sp in self.cspawnpoints: 
            t = sp.transform      
            if t[2] < self.minz:
                self.minz = t[2]
            if t[2] > self.maxz:
                self.maxz = t[2]        
                
        self.midZ = self.minz+(self.maxz-self.minz)/2
        self.spawnpoints = []
        self.paths = {}
        self.waypoints = {}
        
        #Create spawning points and wander groups now using actual POPULATOR_x placers
        for sp in self.cspawnpoints:        
            if sp.group.startswith("POPULATOR_"):   
                p,popnum=sp.group.split("_")
                popnum = int(popnum) 
                t = sp.transform
                bx = t[0]
                by = t[1]
        
                #populator bin (only 1 now per populator) is a 200x200 area with 100 in each direction of the POPULATOR_x placer
                self.bins = {}
                self.binPaths = {}
                #Going to build a list of points, increase /5 for more density
                for y in xrange(by-POPULATOR_AREA/2,by+POPULATOR_AREA/2,POPULATOR_AREA/5):
                    for x in xrange(bx-POPULATOR_AREA/2,bx+POPULATOR_AREA/2,POPULATOR_AREA/5):
                        z = float(TGECall('MyCheckGridPoint',"%f %f %f"%(x,y,self.midZ)))
                        if z:
                            if not self.bins.has_key((bx,by)):
                                self.bins[(bx,by)]=[]
                            self.bins[(bx,by)].append((x,y,z))
        
        
                numpoints = 0
                #Make sure we have enough points to roam on
                for bin,points in self.bins.items():
                    num = len(points)
                    if num < 4:
                        del self.bins[bin]
                        continue
                    numpoints += num
            
                    x = 0            
                    for p1 in points:
                        y = 0
                        for p2 in points:                    
                            if x == y:
                                y+=1
                                continue
                            #if math.fabs(p1[2]-p2[2]<8) #XXX: We actually do need to do this so that mobs are'nt trying to walk up too steep of incluses
                            #but it messes with stuff below, and there might be a bug with waypoints/paths without it
                            result = TGECall('MyCastRay',"%f %f %f"%(p1[0],p1[1],p1[2]+4),"%f %f %f"%(p2[0],p2[1],p2[2]+4))
                    
                            if int(result):
                                if not self.binPaths.has_key(bin):
                                    self.binPaths[bin]={}
                            
                                if not self.binPaths[bin].has_key(x):
                                    self.binPaths[bin][x]=[]
                                self.binPaths[bin][x].append(y)
                        
                            y+=1
                        x+=1
        
                #Build Spawn Points now
                for bin,points in self.bins.iteritems():
                    spcount = 0
                    if self.binPaths.has_key(bin):
                        #Create paths and waypoints if this is a wandering group
                        if len(self.binPaths[bin])>=4 and sp.wanderGroup > -1:
                            self.paths[sp.wanderGroup ]=self.binPaths[bin]
                            self.waypoints[sp.wanderGroup ]=[]
                            for p in points:
                                self.waypoints[sp.wanderGroup].append((p[0],p[1],p[2],1, 0, 0, 0))
                        
                        for p in points:
                            randnum = math.floor(len(points)/POPULATOR_POPMAX)
                            if randnum < 1:
                                randnum = 1
                            #It is typical to have 20 or so points, 20 mobs will be VERY dense
                            if (random.randint(1,randnum) == 1 and spcount < POPULATOR_POPMAX):                                
                                spoint = SpawnpointInfo()
                                rot = TGECall("MyRandomRotation")                        
                                rot = rot.split(" ")                        
                                spoint.transform = (p[0],p[1],p[2],float(rot[0]),float(rot[1]),float(rot[2]),float(rot[3]))
                        
                        
                                spoint.group = "POPULATOR_%i"%popnum
                                spoint.wanderGroup = sp.wanderGroup                                                 
                                self.spawnpoints.append(spoint)    
                                spcount += 1                            
            
                print "POPULATOR_%i loaded with %i points and %i spawnpoints"%(popnum, numpoints, spcount)
                                        
        

def Populate(spawnpoints,paths):
    p = Populator(spawnpoints,paths)
    return p.spawnpoints,p.paths,p.waypoints
    
    

Usage

That is it :-). Now to actually make use of it you need to do the same thing as you would with a normal spawngroup. First create the spawn group.

mob2 = DBSpawnInfo(spawn="Wild Wolf")
sg = DBSpawnGroup(zone="newzone",groupName="POPULATOR_0",popFreq=RPG_FREQ_ALWAYS)
sg.addSpawnInfo(mob2)

mob4 = DBSpawnInfo(spawn="Bat")
sg = DBSpawnGroup(zone="newzone",groupName="POPULATOR_1",popFreq=RPG_FREQ_ALWAYS)
sg.addSpawnInfo(mob4)

This is an example of two spawn groups with a wolf and a bat.

Second you need to create an rpgSpawnPoint for this populator. Go into the zone and edit it and place an rpgSpawnPoint. Call it POPULATOR_0 or any other number you have and then assign a Wandergroup value (-1 is no wander, anything after that will make the group wander). Make sure to set it to a unique value unless you want multiple populator roaming areas.

Save and either /imm recompile or exit out and come back into the game. You should see around 5-7 mobs in the area.

Notes:
* Mobs will load out of the playable area if near the border, they can come in and out of it though so beware of this.
* Not sure what happens if it roams into a teleporter or anything like that.
* Test test test
* You should notice a message that the Populator is loading per zone along with how many points and spawns. Keep an eye on this to make sure enough points are found to create a populator. If it is not check your terrain or use manual spawns.
* The Populator function needs to be turned on when testing offline. It is in the Game Options in the client.