Jump to content
Official BF Editor Forums
Sign in to follow this  
nathan91193

Send Message To Players When They Spawn.

Recommended Posts

I bought a book on python about 3 weeks ago in an attempt to pick up BF2 scripting. I've been programming in other languages for the past 4 years, and python seems pretty simple. I don't understand what could be wrong with this code.

All I want to do is send some sort of message in orange text at the top left of the screen to players when they spawn. Here is what I have right now.

test.py

import bf2
import host


def start():
host.registerHandler("PlayerSpawn",onPlayerSpawn)

def onPlayerSpawn(self):
host.rcon_invoke("game.sayAll \"" + "§C1001 How are you? §C1001" + "\"")

gpm_cq.py

import test
t = test.start()

I've got them in the "gamemodes" folder of the server files. And of course, the rest of the default code for "gpm_cq.py" is there as well, I just didn't copy it into this post. I get no error message when starting the server or playing on the server. But when I spawn, I don't get the message "How are you?"

Thank you to those who try to help.

Edited by nathan91193

Share this post


Link to post
Share on other sites

First i suggest you don't init your test script from gpm_cq.py . Instead use your __init__.py in the /gamemodes folder:

import test
test.start()

You now need to hook your OnPlayerSpawn function into the chain for that event :

#test.py
message = 'welcome to the python factory'
import host
import bf2

def start():
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
#now its time to use the stuff
def myPlayerSpawn(player,soldier):
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

Note that i use the SayTeam channel here , the SayAll channel is either 12 or 14, can't remember atm :P note that the handler has a different name from that in gpm_cq.py to distinguish it.

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

Ohh ok thanks that makes sense. I didn't really understand the usage of events, just kinda took a random shot at it, haha. I'll try what you said and get back to you.

I saw host.sgl_sendTextMessage on bf2tech.org, but it had a note by it saying it wasn't reliable or something, I'll give it a shot though.

Oh and by the way, should "print" print something on the dedicated server console?

Thanks

EDIT: You honestly have no idea how happy I am, hahaha. It works perfectly, thanks man!

Edited by nathan91193

Share this post


Link to post
Share on other sites

Glad you could make it work :lol: The print statement does appear in the console - of course you can safely delete it . Its only there to show you how to get messages out of python for debugging. Only keep the indenting - python is very picky .

The 'host.sgl_sendTextMessage' is a bit bugged, thats right. But the SayTeam and the SayAll channel do a good job ( its the one used by the server to issue game messages ) . The python gurus at bf2tech did find the 'SayPlayer' channel not working so you can't send text to a single player. DICE for years promised to fix it but obviously they never really succeeded. ( Maybe it does work in 1.5 ? Never tried :P )

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

DICE for years promised to fix it but obviously they never really succeeded. ( Maybe it does work in 1.5 ? Never tried :P )

i tried but it didnt work.... But maybe i did something wrong :P

Share this post


Link to post
Share on other sites

I'm trying to run this test script but nothing happenes. I would run the debugger and try to figure out why it isn't working but for some reason my mouse doesn't move in-game in debugger... so I can't spawn in the debugger.

Maybe someone can help me get the script working? I went into \gamemodes and edited the following files.

__init__.py

import test
test.start()

test.py

#test.py
message = 'welcome to the python factory'
import host
import bf2

def start():
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
#now its time to use the stuff
def myPlayerSpawn(player,soldier):
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

Did I miss something?

Edited by TacoTacoTaco

Share this post


Link to post
Share on other sites

There's a control conflict between BF2 1.5 and the older BF2_r.EXE - . The debugger will probably even destroy your profile in /My Documents/Battlefield 2/Profiles. Next time rename your /My Documents/Battlefield 2/ folder before attempting to launch either EXE.

python is picky about indentation. Do you see the message 'test initialized' in the console of the debugger before the mouse freezes ? That would be a hint if the script is fired at all. Both scripts should be placed in <YourMod>/python/game/gamemodes. Also make sure that the __init__.py file really has double underscores two times :P

Share this post


Link to post
Share on other sites

Hmm... I appreciate the suggestions and I checked for all those things. I made sure the titles were all lowercase, I made sure the files I'm editing are in \gamemodes and made sure __init__.py had two underscores on each side. I also checked if the console in debugger said "test initialized" (it didn't). I'm assuming you mean the console that comes up when ` is pressed.

No success yet. I don't know about the indentation but I copied it directly from here and left all lines unedited so the indentation should be perfect.

Btw, thanks for the advice about the debugger mschoeldgen, deleting the my documents/battlefield 2 folder didn't stop my mouse from freezing in debugger but it did fix a couple other problems =).

Edited by TacoTacoTaco

Share this post


Link to post
Share on other sites

Obviously the script is never launched else you'd see the message. We now need to know about your setup :

* do you run a mod of your own ?

* have you copied a complete /python folder from e.g. BF2 before attempting your own scripts ?

* did you switch of the 'extension suppression' from windows ( 'hide known file extensions' ) . Switch off this 'feature' as it might interfere with correct filenaming.

* did you try to 'print' something from e.g. gpm_cq.py

Case:

Note that a folder named e.g. '/Python' will not be recognized, but a '/python' foder will. Windoze will often try to capitalize the first letter which is fatal here.

The script itself should be fool-proof - another happy beginner was able to launch it without problems.

And yes , with 'console' i mean the thing which you can open with the ^ key or 'Home' key.

Also note that python errors are logged in the server.log of the debugger.

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

1. Yes, I'm running my own mod.

2. I tried the script with only the __init__.py and test.py files in python\game\gamemodes. I also tried the script after copying the bf2\python folder into my mod. I also tried the script with the default \python folder and files created in my mod folder.

3. That feature is disabled.

After looking through the logs I see this: "D:\DiceCanada\BoosterPack2\Code\BF2\Game\Python\PythonHost.cpp(1032): Info: Python: python: stdout: test initialized" I'm not sure if that means the script is launching? I never saw the message printed in the console in-game though and I don't see any messages on spawn.

I also made sure all the folders: python, game, and gamemodes are uncapitalized.

One thing I noticed is that when I copied the python folder from bf2, including the gpm_coop.py, into my mod I still didn't have co-op mode on the dropdown list when creating a local server. I only see conquest and for some reason single player? It doesn't look like my mod is even picking up the files in the python folder.

Edited by TacoTacoTaco

Share this post


Link to post
Share on other sites

No, the pure existence of the python gamemode handler doesn't mean the gamemode shows up in the map list. This is unrelated and only depends on the file /menu/External/Flashmenu/gamemodes.con

The message only appears in the console if you run a debugger game. If you're running the retail EXE the cited message shows that the script is initialized.

I'd say you're nearly there and only a small typo or indentation problem in the DEF stands in the way. Or even another problem like a non-working HUD :P

If you're desperate let me know and i'll prepare a small download for those files.

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

i got it to work ok, how would we go about changing the message color, and only show the message when a player joins the server and not just at spawning, seeing the message everytime you spawn can get annoying, lol.

Share this post


Link to post
Share on other sites

For colour/size changing; you've got 2 options for each.

By default it's small and green (as you know).

To make it large; put §3 before (and you can swap back by putting §3 afterwards)

To make it orange; put §C1001 before (and same thing with toggling back).

Sadly the red and blue of kill messages are kinda hardcoded.

Share this post


Link to post
Share on other sites
For colour/size changing; you've got 2 options for each.

By default it's small and green (as you know).

To make it large; put §3 before (and you can swap back by putting §3 afterwards)

To make it orange; put §C1001 before (and same thing with toggling back).

Sadly the red and blue of kill messages are kinda hardcoded.

Were do you put these codes in? In what file? Cause I got this message thing working thanks to you all!! :D

EDIT: Would it be possible to make a code that says e.g. " 5 controlpoints remaining" and when you capture on of the controlpoints it then says "4 controlpoints remaining". Cause I thought it might have something to do with these codes we have used here, but just adding something repeatative, till it goes to "0 controlpoints remaining" after you have captured all the enemy CP's.

This was just an example using the "# controlpoints" thing.

EDIT again: Maybe something a little simmilar to this :P?:

#test.py
message = '5 controlpoints remaining'
import host
import bf2

def start():
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
#now its time to use the stuff
def myPlayerSpawn(player,soldier):
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

# update control point	
cp.cp_setParam('playerId', playerId) #always set player first
if newTeam != -1 and cp.cp_getParam('team') != newTeam:
	cp.cp_setParam('team', newTeam)
onCPTrigger(cp.triggerId, cp, 0, 0, 0)
updateCaptureStatus ()

message = '4 controlpoints remaining'
def start():
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
#now its time to use the stuff
def myPlayerSpawn(player,soldier):
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

That was just a try :)

Edited by Dogbox

Share this post


Link to post
Share on other sites

Oh dear haha, that won't work.

I think the problem you're having is that you're assuming it goes down the file and then waits for the next function, but in reality here's what that will do in order of execution:

message = '5 controlpoints remaining'
import host
import bf2
message = '4 controlpoints remaining'
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

# update control point	
cp.cp_setParam('playerId', playerId) #always set player first
if newTeam != -1 and cp.cp_getParam('team') != newTeam:
	cp.cp_setParam('team', newTeam)
onCPTrigger(cp.triggerId, cp, 0, 0, 0)
updateCaptureStatus ()
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

# update control point	
cp.cp_setParam('playerId', playerId) #always set player first
if newTeam != -1 and cp.cp_getParam('team') != newTeam:
	cp.cp_setParam('team', newTeam)
onCPTrigger(cp.triggerId, cp, 0, 0, 0)
updateCaptureStatus ()
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

So essentially it will straight away set the message to 4 remaining, and then the start function being called twice will register the myPlayerSpawn twice, and then because you have myPlayerSpawn twice anyway, it will multiply again to 4 times xD

Edited by UberWazuSoldier

Share this post


Link to post
Share on other sites

Hello, complete noob here, i have tried this script

 import bf2
import bf2.Timer
import host

interval = 30   # Number of seconds between announcements
message = "Your announcement message goes here"

def onTimer(data):
 global message
 host.rcon_invoke('game.sayall "%s"' % message)

timer = bf2.Timer(onTimer, interval, 1)
timer.setRecurring(interval)

but it doesn't work it crashes the game saying failed to initilize but when I try MS' it works perfectly. I want to send messages timed after say 10 seconds it switches to another message. and plays would I have to go

message = "Your announcement message goes here"

message = "Your announcement message goes here"

for 2? and how can this work under mods\modname\python\gamemodes\? It said this is for Battlefield2 Server\mods\ECT.

Share this post


Link to post
Share on other sites

@ UberwaszuSoldier: I tried to use that but I crashed several times when trying to load any map. I then went back to the python file where I placed your code in and it didn't even want to open it up. I could open any of the other python files but not the one with your code. I then created a new python file and then placed your code in there again and saved, when I tried to open it again it didn't want to open.

Then I placed ms's code in there and it worked and I could edit it too. So did you test that code out or was it an example?

And could someone explain what I actually wanted to know?:

For colour/size changing; you've got 2 options for each.

By default it's small and green (as you know).

To make it large; put §3 before (and you can swap back by putting §3 afterwards)

To make it orange; put §C1001 before (and same thing with toggling back).

Sadly the red and blue of kill messages are kinda hardcoded.

Were do you put these codes in? In what file?

Edited by Dogbox

Share this post


Link to post
Share on other sites

I noticed for if you want big and orange letters u go

§3 §C1001 'message' §C1001 §3

But how does the timer work say like after 10 seconds, do this.

Share this post


Link to post
Share on other sites

@rhysm_08 : deleted your double post.

It is a necessity with the bf2 implementation of python to hook your handlers into the chain of events. This is true for most ( if not all ) gameplay affecting handlers. Once hooked into that chain, your function will be called if the announced event does happen.

Here's an example of how to hook something into the 'GameStatusChanged' event. This is very useful 'cause here you'd create and kill your stuff dependent on the 'playing' state:

def init():
host.registerGameStatusHandler(onGameStatusChangedABC)
print '[XWW2]python: Anti Bot Camp initialized'

( from the antibotcamp.py script developed in this very forum )

Ok, now we need that onGameStatusChangedABC handler:

def onGameStatusChangedABC(status):
global lastBotPositions
global botCheckTimer
if status == bf2.GameStatus.Playing:
	lastBotPositions = {}
	try: botCheckTimer.destroy()
	except: pass
	botCheckTimer = None
	botCheckTimer = bf2.Timer(botCheckHandler, 45.0, 1)
	botCheckTimer.setRecurring(45.0)
	host.registerHandler('PlayerSpawn', onPlayerSpawnABC)
else:
	if status == bf2.GameStatus.EndGame:
		if botCheckTimer:
			try: botCheckTimer.destroy()
			except: pass
			botCheckTimer = None

If the game is playing ( start of play ) we first check if there's our timer ( should never happen ) and if it is , we kill it. Then we recreate it with a recurring time of 45 seconds and it will periodically call the 'botCheckHandler' function.

For further info examine the development of this script here:

http://bfeditor.org/forums/index.php?showtopic=7410

Its not a bad idea to have a look because that script does some other useful things . like retrieving playerpositions, affect their health and so on.

Share this post


Link to post
Share on other sites

I cant believe this but I'm just having trouble with the simplest thing one can change, the color.

This is my code and I have placed that code everywhere in there but it just keeps crashing:

#test.py
message = §3 §C1001 '5 controlpoints remaining' §3 §C1001
import host
import bf2

def start():
host.registerHandler('PlayerSpawn', myPlayerSpawn)
print 'test initialized'
#now its time to use the stuff
def myPlayerSpawn(player,soldier):
  t = player.getTeam()
  host.sgl_sendTextMessage(0, 13, 0, message, t )

Is this right?

Edited by Dogbox

Share this post


Link to post
Share on other sites
@ UberwaszuSoldier: I tried to use that but I crashed several times when trying to load any map. I then went back to the python file where I placed your code in and it didn't even want to open it up. I could open any of the other python files but not the one with your code. I then created a new python file and then placed your code in there again and saved, when I tried to open it again it didn't want to open.

Then I placed ms's code in there and it worked and I could edit it too. So did you test that code out or was it an example?

And could someone explain what I actually wanted to know?:

Were do you put these codes in? In what file?

Oh that wasn't a fixed up version of the code :lol: , I was just showing what your code was trying to do.

The codes for colour/size are this:

§3 = Toggle big size

§C1001 = Toggle orange

§C1003 is also for toggling orange, and there's lots of others to toggle orange or toggle big. But there's not really much variation other than big orange, small orange, big green, small green.

EDIT: Those go INSIDE the quotations, which is why yours is crashing.

Share this post


Link to post
Share on other sites

Oh yeah thanks Uberwazusoldier! It works now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×