Cracking the Terrority Control Code

Incomplete code that isn't ready for use.
35 posts Page 1 of 3 First unread post
danhezee
Former Admin / Co-founder
Former Admin / Co-founder
Posts: 1710
Joined: Wed Oct 03, 2012 12:09 am


Hi guys,

This is a request / discussion thread about scripting for tc. We haven't seen many scripts take advantage of tc. Really I only know of one and that is TOW. I looked through the code for TOW and it looks like you can place as many control points as you like, at any position on the map. That is very powerful, we could create a battlefield like conquest mode or simply allow map makers to set control points to fix locations via map extensions. There are a lot of possibilities here. However, TOW has a lot of other things in that script that obfuscate the code just enough that I am not entirely sure where the hooks are.

My challenge if you choose to accept it is:
Write a script that places 4 control points at {(128,128), (128,384), (384,128), (384,384)}
Challenge complete BR solved it

Bonus challenge, may not be possible:
Write a script that uses /setcp to place a new control point on the map where the player is standing and /removecp to remove the closes control to the player.
Challenge complete BR solved it

The Bonus challenge would allow for gamemodes that change spawn locations after an objective is complete. Blue_Pistol Blue_Sunglasses1 Green_Sunglasses1 Green_Pistol2

Unsolved Challenges:

Challenge 3:
Write a script that has one control point that cannot be captured by the blue and one control that cannot be captured by the green team
Articsledder
Deuced Up
Posts: 209
Joined: Mon Nov 12, 2012 5:13 pm


Anyone up for making it so you can chose spawn points too? I vaguely remember a TC script pre .61 that allowed you to chose your spawn.
BR_
Coder
Coder
Posts: 41
Joined: Wed Nov 14, 2012 3:52 pm


First challenge is done:
Code: Select all
from pyspades.server import Territory

locations = ((128, 128), (128, 384), (384, 128), (384, 384))

def apply_script(protocol, connection, config):
	class CPProtocol(protocol):
		def get_cp_entities(self):
			entities = []
			for i, (x, y) in enumerate(locations):
				entity = Territory(i, self, *(x, y, self.map.get_z(x, y)))
				if i % 2 == 0:
					entity.team = self.blue_team
					self.blue_team.cp = entity
					self.blue_team.spawn_cp = entity
					self.blue_team.cp.disabled = False
				else:
					entity.team = self.green_team
					self.green_team.cp = entity
					self.green_team.spawn_cp = entity
					self.green_team.cp.disabled = False
				entities.append(entity)
			return entities
	return CPProtocol, connection
Working on the others.

Basically, in protocol, override the get_cp_entities function. Return a list of pyspades.server.Territory's, remember to put them on different teams. Set the blue_team and green_team spawn_cp's to one of them, their cp to one of them (not sure what the difference is but it works), and enable them.
Jdrew
Mapper
Mapper
Posts: 4808
Joined: Tue Oct 30, 2012 10:48 pm


I can't wait for all the new game modes!
BR_
Coder
Coder
Posts: 41
Joined: Wed Nov 14, 2012 3:52 pm


Challenge 2 complete. Everyone will spawn in the corner unfortunately, deal with it or change spawnpoint. Inactive CPs are still capturable, so someone might want to change that (not related to the core idea of the challenges).
Code: Select all
from commands import add, admin
from pyspades.constants import *
from pyspades.server import Territory

MAX_CP = 16

cp = []
free = [False] * MAX_CP

@admin
def setcp(self):
	global free
	i = free.index(False)
	free[i] = True
	cp[i].set(self.world_object.position.x, self.world_object.position.y, self.world_object.position.z)
	self.protocol.update_entities()
add(setcp)

@admin
def resetcp(self):
	global free
	free = [False] * MAX_CP
	for entity in cp:
		entity.set(0, 0, 0)
	self.protocol.update_entities()
add(resetcp)

def apply_script(protocol, connection, config):
	class CPProtocol(protocol):
		def get_cp_entities(self):
			global cp
			for i in range(MAX_CP):
				entity = Territory(i, self, *(0, 0, 63))
				if i % 2 == 0:
					entity.team = self.blue_team
				else:
					entity.team = self.green_team
				cp.append(entity)
			return cp
	return CPProtocol, connection
Challenge 3 has pretty much already been done, so I won't redo it unless you get more specific. Arena, for instance, changes the spawn point to the starting room. After that, just put in a few conditions and you've got objective-based spawning.

EDIT: don't need block_action
Last edited by BR_ on Thu Feb 07, 2013 6:44 pm, edited 1 time in total.
danhezee
Former Admin / Co-founder
Former Admin / Co-founder
Posts: 1710
Joined: Wed Oct 03, 2012 12:09 am


Thanks I played with both the scripts. Now to turn it into a gamemode or something cool.
USABxBOOYO
Former Pre-BnS Team
Former Pre-BnS Team
Posts: 267
Joined: Thu Nov 01, 2012 2:35 am


This sounds like it has a lot of potential. One of my biggest gripes with mapmaking was that you couldn't set where you want to spawn, now it looks like that's a thing of the past.

Now we just have to fix the airstrike/dangerzone script to keep your killstreak reward through death :P
Ki11aWi11
Mapper
Mapper
Posts: 106
Joined: Tue Nov 20, 2012 12:39 am


Sweet, I'll have to set up a custom configuration of Capitol for TC/TOW, give it custom intel locations on certain buildings that you have to capture! Can you make the locations x,y,z?
GreaseMonkey
Coder
Coder
Posts: 733
Joined: Tue Oct 30, 2012 11:07 pm


Ki11aWi11 wrote:
Sweet, I'll have to set up a custom configuration of Capitol for TC/TOW, give it custom intel locations on certain buildings that you have to capture! Can you make the locations x,y,z?
Code: Select all
         for i, (x, y) in enumerate(locations):
            entity = Territory(i, self, *(x, y, self.map.get_z(x, y)))
Shouldn't be hard to work out how to add a Z from there.
mr.f
Deuced Up
Posts: 37
Joined: Thu Jan 03, 2013 5:16 am


Challenge accepted!

Ok so here's what I've been able to cook up over the past few days.. I call it Circle of War. It's basically, well, ToW but in a circle.

Script:
Code: Select all
"""
Tug of War game mode, where you must progressively capture the enemy CPs in a 
straight line to win.

Maintainer: mat^2
"""

from pyspades.constants import *
from pyspades.server import Territory
from pyspades.server import Team
import random
from random import choice
import math
from math import pi

HELP = [
    "In Tug of War, you capture your opponents' front CP to advance."
]

class CowTerritory(Territory):
    disabled = True
    
    def add_player(self, player):
        if self.disabled:
            return
        Territory.add_player(self, player)
    
    def enable(self):
        self.disabled = False
    
    def disable(self):
        for player in self.players.copy():
            self.remove_player(player)
        self.disabled = True
        self.progress = float(self.team.id)

def random_up_down(value):
    value /= 2
    return random.uniform(-value, value)

def limit_dimension(value):
    return min(511, max(0, value))

def get_point((x,y),magnitude, angle):
    return (limit_dimension(x + math.cos(angle) * magnitude),
            limit_dimension(y + math.sin(angle) * magnitude))

def apply_script(protocol, connection, config):
    circle_radius = config.get('cow_radius', 150)
    cp_count = config.get('cow_cp_count', 8)
    start_angle = math.radians(config.get('cow_start_angle', 90))
    circle_center = config.get('cow_circle_center',[256,256])
    #circle_center = (255,255)
    
    class CowConnection(connection):
        def get_spawn_location(self):
            if self.team.spawns is None or len(self.team.spawns) is 0:
                print "error"
            else:
                #choose a random spawn_point
                base = choice(self.team.spawns)
            return base.get_spawn_location()
            
        def on_spawn(self, pos):
            for line in HELP:
                self.send_chat(line)
            return connection.on_spawn(self, pos)
            
    class CowProtocol(protocol):
        game_mode = TC_MODE
        
        def get_cp_entities(self):
            # generate positions
            
            map = self.map
            blue_cp = []
            green_cp = []
            
            points = self.get_points()

            # make entities
            index = 0
            entities = []
            self.blue_team.cps = []
            self.green_team.cps = []
            self.blue_team.spawns = []
            self.green_team.spawns = []

            current_team = self.blue_team

            green_start = cp_count/2
            neutral_start = -1

            if cp_count % 2 == 1:
                neutral_start = green_start
                green_start += 1
            
            for x,y in points:
                if index == green_start:
                    current_team = self.green_team

                if index == neutral_start:
                    current_team = None

                entity = CowTerritory(index, self, *(x, y, map.get_z(x, y)))
                entity.team = current_team
                entities.append(entity)

                if current_team is not None:
                    current_team.cps.append(entity)
                
                index += 1

            self.update_capturables()
            self.update_spawns()

            return entities
    
        def on_cp_capture(self, territory):
            capture_team = territory.team

            index = capture_team.other.cps.index(territory)
            
            if territory in capture_team.other.cps:
                capture_team.other.cps.remove(territory)

            if index is 0: #removed from front
                capture_team.cps.append(territory) #add to back
            else: #removed from back
                capture_team.cps.insert(0,territory) #add to front

            #return if game is already over
            if len(capture_team.other.cps) is 0:
                return
            
            self.update_capturables()
            self.update_spawns()

        def get_points(self):
            step = 2*math.pi/cp_count #angle between adjacent cps
            angle = start_angle + step/2

            #step through each angle and return
            for i in range(cp_count):
                x,y = get_point(circle_center,circle_radius,angle)
                yield (int(x),int(y))
                angle += step
            
            
        def update_capturables(self):
            for team in (self.blue_team, self.green_team):
                #start by disabling all cps
                for cp in team.cps:
                    cp.disable()
                
                #enable both end points
                team.cps[0].enable()
                team.cps[-1].enable()


        def update_spawns(self):
            for team in (self.blue_team, self.green_team):
                team.spawns = []
                #if not enough, all cps are spawn points
                if len(team.cps) < 3:
                    team.spawns = team.cps
                    continue
                
                #add both spawn points, one from the end
                team.spawns.append(team.cps[1])
                team.spawns.append(team.cps[-2])

    return CowProtocol, CowConnection
Obviously, I borrowed pretty heavily from the existing ToW script. So yeah, check it out and let me know if there're any bugs.
danhezee
Former Admin / Co-founder
Former Admin / Co-founder
Posts: 1710
Joined: Wed Oct 03, 2012 12:09 am


ohh ok ill have to check it out later
mr.f
Deuced Up
Posts: 37
Joined: Thu Jan 03, 2013 5:16 am


Screenie from classicgen
Attachments
cow.jpg
cow.jpg (150.48 KiB) Viewed 11597 times
danhezee
Former Admin / Co-founder
Former Admin / Co-founder
Posts: 1710
Joined: Wed Oct 03, 2012 12:09 am


Challenge 3:

Create a script that has one control point that cannot be captured by the blue and one control that cannot be captured by the green team

I also updated the first post to include this challenge and past challenge winners.
BR_
Coder
Coder
Posts: 41
Joined: Wed Nov 14, 2012 3:52 pm


Code: Select all
from commands import add, admin
from pyspades.constants import *
from pyspades.server import Territory

MAX_CP = 16

cp = []
free = [False] * MAX_CP

@admin
def setcp(self):
	global free
	i = free.index(False)
	free[i] = True
	cp[i].cap = True
	cp[i].set(self.world_object.position.x, self.world_object.position.y, self.world_object.position.z)
	self.protocol.update_entities()
add(setcp)

@admin
def setnccp(self):
	global free
	i = free.index(False)
	free[i] = True
	cp[i].cap = False
	cp[i].set(self.world_object.position.x, self.world_object.position.y, self.world_object.position.z)
	self.protocol.update_entities()
add(setnccp)

@admin
def resetcp(self):
	global free
	free = [False] * MAX_CP
	for entity in cp:
		entity.cap = False
		entity.set(0, 0, 0)
	self.protocol.update_entities()
add(resetcp)

def apply_script(protocol, connection, config):
	class CPProtocol(protocol):
		def get_cp_entities(self):
			global cp
			for i in range(MAX_CP):
				entity = NoCapTerritory(i, self, *(0, 0, 63))
				if i % 2 == 0:
					entity.team = self.blue_team
				else:
					entity.team = self.green_team
				cp.append(entity)
			return cp
	return CPProtocol, connection
	
class NoCapTerritory(Territory):
	cap = False

	def add_player(self, player):
		if self.cap:
			Territory.add_player(self, player)
EDIT: don't need block_action
Last edited by BR_ on Thu Feb 07, 2013 6:44 pm, edited 1 time in total.
Ultrablockstar
Deuced Up
Posts: 29
Joined: Tue Jan 01, 2013 3:57 pm


I've been waiting for someone to change TC and TOW for the longest, I can imagine the possibilties (also would it be possibly to make a tc version of tdm Green_Happy1 )
35 posts Page 1 of 3 First unread post
Return to “Work In Progress”

Who is online

Users browsing this forum: No registered users and 14 guests