Archived copy of warcraft-source.com, the Warcraft: Source (WCS) forum (2007–2011), rebuilt from the Internet Archive by wc3mods.net. This page was captured on 2009-02-26 (original capture). Home · Forum · All archived topics · Downloads
Warcraft-Source.com - WCS mod for CSS
February 26, 2009, 02:08:56 AM *
Welcome, Guest. Please login or register.
Login with username, password and session length
News: WCS Tournament being opened for applications!

Post here for signups!
Google  
  Home   Forum   Help Search Login Register   *
Pages: 1 [2] 3 4   Go Down
  Print  
Current Topic Rating: ***** You have not rated this topic. Select a rating:
Author Topic: How to code your first Python Race...  (Read 1419 times)
freddukes
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United Kingdom

Posts: 287



« on: February 17, 2008, 04:22:22 AM »

Right, python works by Local Variables... This means that all variables defined inside the script, will stay inside the script. Why you ask? Of course, to make it easier for the script to know where everything is, and save Huge amounts of speed. This also now means, that all your variables to not have to be unique... (Of course there are a few exceptions, which I'll tell you about later...)

If you don't know already, python uses things called 'methods' otherwise known function. They act VERY similarly to an Eventscript block... you define a method by calling the command 'def' e.g.

Code
GeSHi (python):
def MyMethod():
 

Now, note 2 different things here compared with ESS Blocks. The first being the brackets, I'll explain what these mean later, but for now, just ignore them. Look at the colon after the ()... A colon (Smiley means that the following line will be an indented line... You will only ever have a : at the end of certain lines: such as;

for X in X:
while X <condition> X:
if x <condition> x:
def x:

These are the most common... You can probably guess what each one does, so I not explain. Right, now lets go back to the brackets thing in myFunction... Now listen closely, this is one of the hardest things you'll EVER learn in python (truely, once you've got your head round this, you'll realise just how easy python is...)

now, I said all values are local right... Local  means that they are only recognised WITHIN THE FUNCTION YOU DECLARE THEM!!!... e.g.

Code
GeSHi (python):
def myFunction():
   msg = 'hello'
 
def mySecondFunction():
   es.msg(msg)
 

This code would bring up an error saying 'msg referenced before assignment'. This means that the variable hasn't been assigned yet, and this is true because when you declared msg, it 'scope' (how local/global the variable is) is only inside myFunction. This means I cannot call the variable made in myFunction to another function... That is, unless I tell it to. Now, there are 2 common ways of making a variable recognised in other functions, I will explain them now... Right, the first way, and the 'best' way, is to simply 'pass' the variable from one function to the next. This is useful, because the variable is still only recognised in 2 different functions, so it saves space Wink... Always try and keep the scope of the variables as low as possible. We pass the variable on from one function to the next, by using the brackets Smiley such as...

Code
GeSHi (python):
def myFunction():
   message = 'hello'
   mySecondFunction(message)
 
def mySecondFunction(msg):
   es.msg(msg)
 

Now.. You may think 'what the hell is he doing'... Right, well to do a method, you just simply type the method out. This is very similar to es_doblock scriptname/block... imagine that... Now to call the method, you just have to use the method name. Simple, yes... Now as you can see, this time, I've typed something inside the brackets. Inside the brackets, is my variable; message... On the sending function... (e.g. the one Passing the variable)... The variable HAS to be the same name as you originally declared it.. e.g. I declared 'hello' to the variable message, thus I must pass the variable name as message. However, on the receiving end, I can call the variable whatever I want... In this case, I've renamed message msg... This is (in my opinion) the hardest way to make a variable global, however, it's the best. When's the best time to use this sort of global variable? When you are simply going from one function to the next. However, if one function does not 'call' (call just means 'doblock'), then there is no way to pass the function, so we must use other means.

The second way, (and in my opinion the easier, but slower way..) is to call the command global at the top of the function before you set any variables... lets have a look at that method again, this time though, myMethod will not call mySecondMethod:

Code
GeSHi (python):
def myMethod():
   global message
   message = 'hello'
 
def mySecondMethod():
   es.msg(message)
 

Now as you can see, in this case, I cannot re-name the variable. This is because that variable has been made global to the script, so the value inside the variable will only be able to be recognised by the same variable name... e.g. if I define message to be hello, msg will contain nothing... The second thing many people get confused about, is when NOT to use a global... the global command will simply make a variable global, when a value inside the variable is changed/set... This means I can read the value, do whatever I want with the value, unless I don't change it, then I don't need a global.. e.g.

Code
GeSHi (python):
def myMethod():
   global message
   message = 'hello'
 
def mySecondMethod():
   if message == 'hello':
       es.msg(message)
 

As you can see, I haven't changed the value in any way shape or form in mySecondMethod, so I don't need a global... The general rule for if it needs a global or not is if it has a single "=" sign (note in python 2 "==" means 'equalto', whereas one "=" means equals... DONT get these 2 mixed up).

Now, so that's one of the hardest things you'll learn in python... not that hard is it ^_^...

The last thing I want to talk to you about is ways of grouping information together... Keygroups are slow ways of storing informations... The new ways are: lists, sets and dicts. (there are also keyvalues which act in the exact same way as keygroups, but they're a lot more complex... We'll leave those out for now, you don't need them.) Dicts, (short for dictionarys) are sooooooooo useful once you know how to use them correctly. It's how the information of the users will be stored on the server, it's just as fast as SQLite, (if not faster,) and they're easier to edit/change/save/do what you want to. Imagine dicts as keygroups... We'll say that a dict is the keygroup itself, and then a dict has a 'key'. However, this is where it get's cooler.. whereas a normal keygroup can only have a keygroup -> key -> keyvalue... dicts can have keygroup -> key -> key -> key -> key -> key -> keyvalue Smiley... It can contain as MANY keys as you want Smiley (This is useful to say store all of the WCS settings in, all your XP in, and each race etc...) with dicts, virtually all information can be kept inside the same dict... now, how do you create a dict? simple

Code
GeSHi (python):
my_dict = {}
 

That is it, you've just created your dict.. now who said python was tough Tongue... Okay, let's add things to the dict...

Code
GeSHi (python):
my_dict['my_key'] = 5
 

You've actualy just assigned a keyvalue to a key Smiley yet another thing we can do, we can have dicts as short or long as possible... Here, we've assigned the value of '5' to the root 'my_key'. To access the value again you just do

Code
GeSHi (python):
my_value = my_dict['my_key']
 

Yes, it really is that simple.. To add 2 keys to my_dict, you can just do this..

Code
GeSHi (python):
my_dict['my_key']['my_secondkey'] = 4
 

But note... You can only ADD another key on when you've added the PREVIOUS key on.. e.g.

Code
GeSHi (python):
my_dict = {}
my_dict['my_key']['my_secondkey'] = 4
# This is incorrect
 
my_dict = {}
my_dict['my_key'] = {}
my_dict['my_key']['my_secondkey'] = 4
# correct
 

As you can see, you have to build them up one at a time.. there is an advanced way to do it so you can do it in one line, but lets not confuse you yet Smiley... That's it for dicts really... As you can see, they are extremely handy for storing data...

The next way, is a list. Lists and sets really are both 'lists' and they virtually do the same thing. For this reason, we'll just teach you lists as they're easier to understand, and more useful to you. Okay, now like a dict, you have to first create your list.. to do this just type:

Code
GeSHi (python):
list = []
 

This will create a list Smiley... Yes it is that simple... Now, a list is only good for... well, holding a list of items.. for example, many people use lists to define the pistols list..

Code
GeSHi (python):
list = ["deagle","usp","glock","fiveseven","elite","p228"]
 

These are useful for 'for' and 'in' commands... This is a lot faster than saying

Code
GeSHi (python):
list = "deagleuspglockfivesevenelitep228"
 

as for example if we wanted to test if usp was in list in the second case.. it'd be...

usp == dea.. False
usp == eag.. False
usp == agl.. False
usp == gle.. False
usp == leu.. False
usp == lus... False
usp == usp.. True

Imagine if we was trying to test if if something was in p228, it'd take ages.. however, with a list the usp case would be

usp == deagle false
usp == usp true...

It tests each seperate item individually.. likewise for the for command..

Code
GeSHi (python):
for gun in pistols:
   es.msg("found %s"%gun)
 

I'll tell you what the %s does now... the %s is a substitute for any string... if you've used es_format or es_formatv before it is virtually the same, only instead of numbers, it's 's'.. Now at the end of the string (e.g. the end of the quotation mark" you have to define that the 'string replacement' starts there... so to define that, you put a %... Now anything that follows the % will be the variable to be replaced into the string... If you have more than one variable, they need to be inside brackets..
Code
GeSHi (python):
for gun in pistols:
   gun2 = 'weapon_%s'%gun
   es.msg("found %s : %s"%(gun,gun2))
   # displays found deagle: weapon_deagle
 

Now, lets begin to learn the syntax of creating your own race...

Code
GeSHi (python):
###################
# Import module
import es
import random
import gamethread
 
import wcs
from wcs import wcs
 
###################
#    PUBLISH INFO
info = es.AddonInfo()
info.name = 'My First Race'
info.author = 'Freddukes'
 
###################
#     RACE INFO
#
RaceName = 'first race'
# This is the name of the mod... We assign it to a global variable for easy reference
# It must be exactly the same name as the file name, including capital letters
race = wcs.Race(RaceName)
race.registerWeaponRestriction('allow only',(['knife','glock','usp']))
 
###################
#    SKILL INFO
# Syntax: registerSkill("skill name", <amount of levels>, <level interval>, "description")
 
race.registerSkill('My first skill',1,1,"A test to see if my skill works")
race.registerSkill("I am god",4,3,"Random chance to put you in god mode")
 
##################
#     Ultimate Info
# Syntax: registerUltimate("ultimate name", <required race level>, <max level>, <Level Interval>, "Description")
 
race.registerUltimate("I am ledgend",8,4,2,"Makes you turn red and everyones screen in a distance goes blury"
 
 
 
def player_spawn(event_var):
   userid = int(event_var['userid'])
   # This returns the integer of the userid... All events return as string, we want the userid as a number (integer)
 
   first_level = wcs.GetLevel(userid, RaceName, 'My first skill')
   # Returns the value of the level 'firstrace' and stores it in first_level
 
   if first_level:
# If first level is True, I.E a positive number
       es.tell(userid,'#green','Look, Your skill worked!'
 
   god_level = wcs.GetLevel(userid, RaceName, 'I am God')
   if god_level:
       wcs_rand = random.randint(1,5)
# gets a random number between 1 and 5
 
       if wcs_rand <= god_level:
           player = wcs.Command(userid)
# Register the player for a custom command skill
 
           player.God(30)
# Turn the player into god mode for 30 seconds
 
 
 
def player_ultimate(event_var):
   # Triggered whenever a user has used his ultimate and the ultimate counter is set to 0
 
   player = wcs.Command(userid)
# Register the player for a custom command skill
 
   player.SetCoolDown('I am ledgend',30)
# Registers the cooldown effect for 30 seconds for the I am ledgend ultimate.
 
   ledgend_level = wcs.GetLevel(userid, RaceName,"I am ledgend")
 
   player.Near(ledgend_level * 50, shake)
# The distance effected is the level multiplied by 50... Everyone inside this distance will now be passed through to the 'shake' function
 
 
 
def shake(userid, attacker):
# Attacker is the person to run the ultimate, userid is the victim who was close to him
 
   player = wcs.Command(userid)
# Register the player for custom comand skill
 
   player.Shake(5,10)
# Shake the victims screen for 5 seconds with a 'violence' of 10
 
   att = wcs.Command(attacker)
# register the attacker for custom command skill
 
   att.Color('red')
# Turn the attacker red
 
   gamethread.delayed(5,att.Color)
   # Reset the color of the user after 5 seconds
 

Hopefully you can understand how much freedom you've now got. This is just a small example, some libs (even though not useful) will let you send e-mails to people etc. Some Librarys will also let you browse the internet and open sites, download things. With python, the worlds the limit Wink

-freddukes
« Last Edit: March 03, 2008, 01:34:52 AM by freddukes » Logged

 
Jeff
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United States United States

Posts: 458



WWW
beastrace91
« Reply #16 on: February 18, 2008, 06:46:59 AM »

Good first try! Here your code fixed some that should do what I think you intended it to:

Code
GeSHi (python):
def player_spawn(userid, team):
   player = wcs.Command(userid)
#Gets our users mole ranks
   mole = wcs.getLevel(userid, 'Race Name', 'Mole')
#If they have mole ranks then we run this next block
if mole:
#Now your codes which where great other than some spacing issues
   if team = 3:
mole = 'player/t_phoenix'
   elif team = 2:
mole = 'player/ct_urban'
   player.Model(mole)

~J3ff
Logged

qenzoz
Level 7 Expert
*****
Offline Offline

Denmark Denmark

Posts: 161

Ehm..?



balulah_qenzoz

myServer 77.66.39.8:27029
(Warning: click connects through Steam)
« Reply #17 on: February 18, 2008, 06:49:06 AM »

Thank you very much. Cheesy
Logged

freddukes
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United Kingdom

Posts: 287



« Reply #18 on: February 18, 2008, 08:21:37 AM »

Quote from: quenz
Code
GeSHi (python):
def player_spawn(userid, team):
   player = wcs.Command(userid)
   mole = wcs.getLevel(userid, 'Race Name', 'Mole')
   if team = 3: mole = 'player/t_phoenix'
   elif team = 2: mole = 'player/ct_urban'
       player.Model(mole)

Actually  this should work, apart from the fact people are defining their methods incorrect, I've seen a couple of people getting confused over this...

def player_spawn(event_var): <--- Takes only ONE argument, It is the base dict for what you call your Event_var's.. You may see me and Jeff and other people using 'ev' instead of event_var there; just remember, you can call it whatever you want... If you DO call it something different, you have to use that instead of event_var.. e.g. if you placed 'ev' inside the brackets:

es.msg('hello %s'%ev['es_username'])

This makes it simpler to write, but harder for begginers to get the hang of it...

-freddukes
Logged

qenzoz
Level 7 Expert
*****
Offline Offline

Denmark Denmark

Posts: 161

Ehm..?



balulah_qenzoz

myServer 77.66.39.8:27029
(Warning: click connects through Steam)
« Reply #19 on: February 18, 2008, 12:57:08 PM »

Yeah ok, btw is es.msg that message u get when u active that skill?... Or?Tongue

and maybe my mole should like like this with the "ev"
Code
GeSHi (python):
def player_spawn(ev):
   userid = ev['userid']
   team = ev['team']
   player = wcs.Command(userid)
   mole = wcs.getLevel(userid, team, 'Race Name', 'Mole')
   if team = 3: mole = 'player/t_phoenix'
   elif team = 2: mole = 'player/ct_urban'
       player.Model(mole)
 

or is this just like an big error?Tongue
But i am trying hehe Smiley
Logged

freddukes
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United Kingdom

Posts: 287



« Reply #20 on: February 18, 2008, 08:59:40 PM »

Should work if you use ev['es_userteam']
Logged

WCA | Rasmus [DK]
<wcs race coder>
WCS Supporter
Level 7 Expert
*****
Offline Offline

Denmark Denmark

Posts: 1330




Rasmus4J
rasmus4j

myServer 85.190.17.115:27015
(Warning: click connects through Steam)
« Reply #21 on: February 18, 2008, 09:51:31 PM »

what does the ev do?
Logged

where would you put the comma in the following telegram from a wife, to her husband in the navy?
"Not getting any better hurry home!"
http://cache.www.gametracker.com/server_info/85.190.17.115:27015/b_560x95.png[/img][/url]
Frodo
WCS ESP Dev Team
Level 7 Expert

Offline Offline

Posts: 854


Actinosphaerium eichhorni


WWW
ckenduro
aulix
« Reply #22 on: February 18, 2008, 09:55:22 PM »

"ev" is just like event_var
Logged


Actually I found it as best Bux ever. Everything's automated!
HOLLIDAY
<Race Maker>
Watchdogs
Level 7 Expert
*****
Offline Offline

Posts: 2029



WWW
Wc3_HOLLIDAY_Wc3
wc3hollidaywc3

myServer 8.2.0.222:27015
(Warning: click connects through Steam)
« Reply #23 on: February 18, 2008, 10:14:59 PM »

what about effects? ive seen est_effects used in python but dont quite get how to use them
i know that races will have effects right?
how will you do this?
Logged


freddukes
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United Kingdom

Posts: 287



« Reply #24 on: February 18, 2008, 10:20:03 PM »

I'm doing it now... I'm wrapping EVERY single one of the effect commands, and making them 'easier' to use... effectively, when they're finished they'll run somewhat like this..

Code
GeSHi (python):
effect = wcs.Effect('filter here such as #c etc')
effect.sfx1(<arguments>)
effect.sfx2(<arguments>)
effect.sfx3(<arguments>)
 
and so forth... THe thing which I'm making easier is I've virtually removed all the arguments you don't user (like delay) and set them optional... If you want an optional command, you'll have to use the variable name... e.g.
 
effect.sfx1(<arguments>,delay=3)
 
The reason I did this for is because 99% of the time, you don't use a delay. I've done this with many other default settings that most people generally keep the same... The average effect will be about 6 - 7 arguments...
 
-freddukes
Logged

HOLLIDAY
<Race Maker>
Watchdogs
Level 7 Expert
*****
Offline Offline

Posts: 2029



WWW
Wc3_HOLLIDAY_Wc3
wc3hollidaywc3

myServer 8.2.0.222:27015
(Warning: click connects through Steam)
« Reply #25 on: February 18, 2008, 10:29:58 PM »

your wrong about the delay...the delay is a must with the effects
you might not see alot of effects use the delay but so much can be done with the delay....
with the delay and alpha settings creats animation...
Logged


freddukes
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United Kingdom

Posts: 287



« Reply #26 on: February 18, 2008, 11:13:18 PM »

well I've never seen delay being used :S That's my personal opinion.. If you need a delay, all you need to do is add delay=<delay> at the end of the command, it's worth it to have less syntax for the people who don't use delay (which is the majority...)
Logged

Jeff
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United States United States

Posts: 458



WWW
beastrace91
« Reply #27 on: February 19, 2008, 01:38:53 AM »

what about effects? ive seen est_effects used in python but dont quite get how to use them
i know that races will have effects right?
how will you do this?

The races will have effects if you script them with effects Smiley

The base races will have some basic effects at least, but remember each race is now it's own script... so other than the wrapper dukes is making, this will be no different from using an effect in any other .py script... if you really must know or do not want to use the wrapper for whatever reason you can use est_ effects/commands just like any other server command in python... by using es.server.cmd/queuecmd

~J3ff
Logged

HOLLIDAY
<Race Maker>
Watchdogs
Level 7 Expert
*****
Offline Offline

Posts: 2029



WWW
Wc3_HOLLIDAY_Wc3
wc3hollidaywc3

myServer 8.2.0.222:27015
(Warning: click connects through Steam)
« Reply #28 on: February 19, 2008, 02:21:32 AM »

wrapper? what is this?
Logged


Jeff
WCS ESP Dev Team
Level 7 Expert

Offline Offline

United States United States

Posts: 458



WWW
beastrace91
« Reply #29 on: February 19, 2008, 02:32:01 AM »

A wrapper means that you will be able to access commands using only local python commands and not server wide commands due to our code running them for you, thus making it easier for you to work with.

~J3ff
Logged

Zero Skillz
Level 7 Expert
*****
Offline Offline

United States United States

Posts: 525




Zero Skillz (<-[SD]->madcow)
madcow767
« Reply #30 on: February 19, 2008, 04:24:48 AM »

hey just a question, if i post a race here will you convert to python for me? kinda like a before and after kind of thing.. i think it will make things worlds easier.. if you see what i'm saying. so ya once i get my new race out of testing i will post it here and i would like to see it converted or i can just post one i already made but ya would you do it for me?
Logged

Pages: 1 [2] 3 4   Go Up
  Print  
 
Jump to:  

Last 7 Shouts:
Crowoner
February 25, 2009, 07:05:17 PM
lol i can't execute the program it gives me error CreateProcess Failed; Code 14001
February 25, 2009, 04:23:37 PM
or else test it on a ded and then do the same
February 25, 2009, 04:23:24 PM
download it and you can >.>
February 25, 2009, 04:21:37 PM
the server is rented i can't use hlsw
February 25, 2009, 04:09:53 PM
can you get the logs (with HLSW) when you say shopmenu2?
with eventscripts_debug 1 please :p
February 25, 2009, 04:04:15 PM
Yes it's all ok ... made es_load gold in autoexec all files are right as the tutorial of gold 0.4 says
no missing file I suppose as it's original
February 25, 2009, 04:01:04 PM
is it loaded well?
have you the "official" version?
no missing file? nothing else wrong?
Recent
[Today at 01:26:31 AM]

[Today at 01:24:52 AM]

[Today at 12:38:51 AM]

[Today at 12:34:28 AM]

[Today at 12:12:17 AM]

[February 25, 2009, 11:45:05 PM]

[February 25, 2009, 10:06:36 PM]

[February 25, 2009, 07:55:08 PM]

[February 25, 2009, 07:53:02 PM]

[February 25, 2009, 07:43:19 PM]
Theme switch

Powered by MySQL Powered by PHP Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC
TinyPortal v0.9.8 © Bloc
Valid XHTML 1.0! Valid CSS!
Page created in 0.223 seconds with 28 queries.