The Moba gamemode
Wikipedia wrote:Multiplayer online battle arena (MOBA), also known as action real-time strategy (ARTS), is a sub-genre of the real-time strategy (RTS) genre, in which often two teams of players compete with each other in discrete games, with each player controlling a single character through an RTS-style interface. It differs from traditional RTS games in that there is no unit construction and players control just one character. In this sense, it is a fusion of action games and real-time strategy games. The genre emphasizes cooperative team-play; players select and control one "hero", a powerful unit with various abilities and advantages to form a team's overall strategy. The objective is to destroy the opponents' main structure with the assistance of periodically spawned computer-controlled units that march towards the enemy's main structure via paths referred to as "lanes".The quote above is from the Moba article on Wikipedia. For the full article click here. I thought of the idea of a moba mode in AoS a few months ago when I learned that dungeon defenders two would have the gamemode. Seeing as almost all free to play Moba's are rip offs of each other I thought it would be interesting to see how it played in Ace of Spades. The objective in this gamemode is to go and capture all of the enemy's control points for a lane. Once you have captured the control points in a lane its time to take on the enemy teams main control point. Watch out though as their spawn is close by!
In a Moba the player controls a hero, in Ace of Spades they control a deuce that has a variety of powers. These powers are teleportation,flight,healing,extra ammo,invisibility, critical hit, extra damage, and armor. Powers are chosen with the /power command and are based off of block colors. Every power also has another level. You get a new level every ten kills. The powers are based off of heroes or champions in other moba's such as League of Legends, Dota2, Smite, and a few others that are lesser known.
Moba powers scripts: gives the powers for the gamemode
Code: Select all
"""
MOBApowers by thepolm3
Powers! Idea by blockpower
Use this script with the "MOBA" as your gamemode for epic win
#jdrew
"""
from pyspades.server import weapon_reload,set_tool
from pyspades.constants import *
from twisted.internet.reactor import callLater
from commands import invisible,add,admin,get_player
from random import randint
GREY,RED,ORANGE,YELLOW,GREEN,TOURQUOISE,BLUE,PINK=range(8)
ARMOR,DAMAGE,TELEPORT,FLY,INVISIBLE,AMMO,HEAL,CRITICAL=range(8)
MAX_LEVEL=5
LEVEL_UP_THRESHOLD=10 #kills-deaths
COOLDOWN=20
@admin
def super(connection,*args):
if args:
player=get_player(connection.protocol,args[0])
else:
player=connection
player.level=100
player.pickingPower=False
player.on_refill()
connection.send_chat("Superfied!")
add(super)
def resend_tool(player):
set_tool.player_id = player.player_id
set_tool.value = player.tool
if player.weapon_object.shoot:
player.protocol.send_contained(set_tool)
else:
player.send_contained(set_tool)
def power_name(powerid):
if powerid==None: return "No power"
return ["Armor","Damage","Teleportation","Fly","Invisibility","Ammo","Healing","Critical hit"][powerid]
def get_colour_id(colour):
r,g,b=colour
if r==g==b: return GREY #armor row
if r>g and g==b: return RED #damage row
if b==r and r>g: return PINK #critical hit row
if r>g>b: return ORANGE #teleport row
if r==g and r>b: return YELLOW #fly row
if g>b and b==r: return GREEN #invisible row
if g==b and b>r: return TOURQUOISE #ammo row
if b>r and r==g: return BLUE #heal row
return 0
def multiplier(powerid,level):
if powerid==ARMOR: return (1.0/(level+1))+0.25
if powerid==DAMAGE: return 1.0/((1.0/(level+1))+0.25)
if powerid==TELEPORT: return (level-1)
if powerid==FLY: return 2*level+3
if powerid==INVISIBLE: return 1.5*level+3.5
if powerid==AMMO: return (float(level)/2)+1
if powerid==HEAL: return level
if powerid==CRITICAL: return float(level)/100
def percentage(number):
return str(int(number*100))+"%"
def power_description(powerid,level):
n=multiplier(powerid,level)
if powerid==ARMOR: return "You take %s damage from hits" %(percentage(n))
if powerid==DAMAGE: return "You deal %s damage with hits" %(percentage(n))
if powerid==TELEPORT and level==1: return "You can teleport with grenades"
if powerid==TELEPORT: return "You can teleport using grenades and %d bullets" %(n)
if powerid==FLY: return "You can fly for %d seconds using /f" %(n)
if powerid==INVISIBLE: return "You can stealth for %d seconds using /i" %(n)
if powerid==AMMO: return "You start off with %s more ammo" %(percentage(n-1))
if powerid==HEAL: return "You heal those around you for %d hp" %(n)
if powerid==CRITICAL: return "You have a %s chance to deal critical damage" %(percentage(n))
def apply_script(protocol,connection,config):
class PowConnection(connection):
PickingPower=True
power=POWdeaths=POWkills=teleports=on_cooldown=0
level=1
flop=True
def remind_power(self):
self.send_chat(power_description(self.power,self.level))
self.send_chat("You are a level %d %s" %(self.level, power_name(self.power)))
def level_up(self):
if self.POWkills-self.POWdeaths>LEVEL_UP_THRESHOLD:
if self.level<MAX_LEVEL:
self.POWkills=0
self.POWdeaths=0
self.level+=1
self.remind_power()
self.send_chat("Congratulations! You leveled up!")
self.refill()
def on_refill(self):
self.remind_power()
if self.power==TELEPORT and not self.PickingPower:
self.teleports=multiplier(TELEPORT,self.level)
print(self.teleports)
if self.power==AMMO and not self.PickingPower:
callLater(0.01,self.set_ammo,self.weapon_object.current_ammo,self.weapon_object.current_stock*multiplier(AMMO,self.level))
return connection.on_refill(self)
def on_spawn_location(self,pos):
if self.PickingPower:
self.send_chat("You are picking your power, use blocks to change power and /power to finish")
else:
self.on_refill()
connection.on_spawn_location(self,pos)
def on_hit(self,amount,victim,type,weapon):
print(amount)
if self.power==CRITICAL and not self.PickingPower:
if not self==victim:
rand=randint(0,100)
if rand<(multiplier(CRITICAL,self.level)*100):
amount=200
self.send_chat("Critical strike!")
if victim.power==ARMOR and not victim.PickingPower:
amount*=multiplier(ARMOR,victim.level)
if self.power==DAMAGE and not self.PickingPower:
if not self==victim:
amount*=multiplier(DAMAGE,self.level)
temp=connection.on_hit(self,amount,victim,type,weapon)
if temp:
amount=temp
print(amount)
return amount
def on_kill(self,killer,type,weapon):
if killer and killer!=self:
self.POWdeaths+=1
killer.POWkills+=1
killer.level_up()
self.send_chat("Your killer had the power; "+power_name(killer.power))
return connection.on_kill(self,killer,type,weapon)
def on_position_update(self):
if self.power==HEAL and not self.PickingPower:
x,y,z=self.get_location()
for player in self.protocol.players.values():
xa,ya,za = player.get_location()
if 5>xa-x>-5 and 5>ya-y>-5 and 5>za-z>-5 and self.team==player.team:
if player.hp!=100:
player.set_hp(player.hp+multiplier(HEAL,self.level),self,type=FALL_KILL)
return connection.on_position_update(self)
def on_block_destroy(self,x,y,z,type):
if self.power==TELEPORT and self.teleports>0 and self.tool==WEAPON_TOOL: #lost of ands XD
#from my script, worldedit
for zt in range(z,0,-1):
solid,colour=self.protocol.map.get_point(x,y,zt)
if solid:
z=zt-3
if zt!=0:
self.set_location((x,y,z))
else:
self.set_location((x,y,-1))
self.teleports-=1
self.send_chat("You have %d gun teleports remaining"%(self.teleports))
return connection.on_block_destroy(self,x,y,z,type)
def on_color_set(self,colour):
if self.PickingPower:
self.power=power=get_colour_id(colour)
self.send_chat("Type /power to choose this")
self.send_chat(power_name(power)+" : "+power_description(power,self.level))
return connection.on_color_set(self,colour)
def end_pow(self):
self.fly=False
if self.invisible:
invisible(self)
self.on_cooldown=True
self.send_chat("Your power has timed out")
callLater(COOLDOWN,self.reset_pow,"You can now use fly and invisible again")
def reset_pow(self,prompt):
self.send_chat(prompt)
self.on_cooldown=False
def on_command(self,command,parameters):
if command=="power":
if self.PickingPower:
self.remind_power()
self.fly=False
if self.invisible:
invisible(self)
callLater(COOLDOWN,self.reset_pow,"")
self.send_chat("Your power has been set")
self.PickingPower=False
else:
self.send_chat("You are now picking your power, use block colours to change power")
self.PickingPower=True
if self.power==FLY:
if command=="f" and not self.PickingPower:
if self.on_cooldown:
self.send_chat("You can't fly so soon after your last fly!")
else:
self.fly=True
callLater(multiplier(FLY,self.level),self.end_pow)
self.send_chat("Spam ctrl to fly!")
if self.power==INVISIBLE:
if command=="i" and not self.PickingPower:
if self.on_cooldown:
self.send_chat("You can't hide so soon after your last fly!")
else:
invisible(self)
callLater(multiplier(FLY,self.level),self.end_pow)
return connection.on_command(self,command,parameters)
def on_grenade_thrown(self, grenade):
if self.power==TELEPORT and not self.PickingPower:
callLater(grenade.fuse+0.5,self.on_grenade_splode,grenade)
return connection.on_grenade_thrown(self,grenade)
def on_grenade_splode(self, grenade):
x, y, z = (int(n) for n in grenade.position.get())
self.set_location((x,y,z))
def set_ammo(self, new_ammo, new_stock=None):
#from my ammo.py ^^
if new_ammo>255:
new_ammo=255
if new_stock>255:
new_stock=255
weapon=self.weapon_object
weapon.set_shoot(False)
weapon_reload.player_id = self.player_id
weapon_reload.clip_ammo = weapon.current_ammo
weapon.current_ammo = new_ammo
if new_stock:
weapon.current_stock = new_stock
weapon_reload.reserve_ammo = weapon.current_stock
self.send_contained(weapon_reload)
self.ammo=(new_ammo,new_stock)
class PowProtocol(protocol):
pass
return PowProtocol, PowConnection
Moba gamemode script: this script is the gamemode itself
Code: Select all
Maps:"""
MOBA by thepolm3
Idea by Jdrew
Use this script with the "mobapowers" script for best effects
"""
from twisted.internet.reactor import callLater
from random import randint
from pyspades.server import Territory
from pyspades.collision import vector_collision
PER_LANE=2
LANES=3
BLUE_BASE=20,492
GREEN_BASE=492,20
NOCP=max(0,min(16,PER_LANE*LANES*2+2))
LANEMIDDLES=[(20,20),(255,255),(492,492)]
class MOBACP(Territory):
lane=0
position=0
start_team=None
per_lane=PER_LANE
lanes=LANES
def reset(self):
self.team=self.start_team
self.update()
def add_player(self, player):
if self.position==0:
for i in range(LANES):
cp=self.protocol.find_cp(i,1,self.team)
if cp and cp.team!=self.team:
return Territory.add_player(self,player)
if player.team!=self.team:
player.kill()
return
elif player.team!= self.start_team and self.position<PER_LANE:
cp=self.protocol.find_cp(self.lane,self.position+1,self.start_team)
if cp:
if cp.team==self.start_team: #if the lane hasn't been captured yet
player.hit(10)
return
Territory.add_player(self,player)
def apply_script(protocol,connection,config):
class MOBAConnection(connection):
def on_spawn_location(self,pos):
x,y=[BLUE_BASE,GREEN_BASE][self.team==self.protocol.green_team]
x+=randint(-20,20)
y+=randint(-20,20)
connection.on_spawn_location(self,pos)
return (x,y,self.protocol.map.get_z(x,y)-3)
def get_cp_standing_in(self):
if self.world_object:
for cp in self.protocol.cps:
if vector_collision(self.world_object.position, cp):
return cp
def on_refill(self):
cp=self.get_cp_standing_in()
if cp:
if cp.team==self.team.other:
return False
return connection.on_refill(self)
class MOBAProtocol(protocol):
game_mode=1
cps=[]
def on_cp_capture(self,cp):
if cp.position==0:
for player in cp.players:
if player.team!=cp.start_team:
self.reset_game(player)
callLater(0.1,cp.reset)
return protocol.on_cp_capture(self,cp)
return protocol.on_cp_capture(self,cp)
def on_map_change(self,map):
global PER_LANE,LANES,BLUE_BASE,GREEN_BASE,NOCP,LANEMIDDLES
extensions=self.map_info.extensions
if extensions.has_key('per_lane'):
PER_LANE = extensions['per_lane']
if extensions.has_key('lanes'):
LANEMIDDLES = extensions['lanes']
LANES=len(LANEMIDDLES)
if extensions.has_key('blue_base'):
BLUE_BASE = extensions['blue_base']
if extensions.has_key('green_base'):
GREEN_BASE = extensions['green_base']
NOCP=max(0,min(16,PER_LANE*LANES*2+2))
return protocol.on_map_change(self,map)
def find_cp(self,lane=None,position=None,team=None):
max_count=[1,0][lane==None]+[1,0][position==None]+[1,0][team==None]
for cp in self.cps:
count=0
if lane!=None and cp.lane==lane:
count+=1
if position!=None and cp.position==position:
count+=1
if team!=None and cp.start_team==team:
count+=1
if count>=max_count:
return cp
def get_cp(self,index):
#magic function
if index>=NOCP/2:
team=self.green_team
index-=NOCP/2
else:
team=self.blue_team
if index+1==NOCP/2:
x,y=[BLUE_BASE,GREEN_BASE][team==self.green_team]
lane=0
position=0
else:
position=index % PER_LANE+1
lane=((index-(position-1))/PER_LANE)
if team==self.blue_team:
xa,ya=LANEMIDDLES[lane]
xb,yb=BLUE_BASE
xa,ya=xa-xb,ya-yb
xa,ya=xa/(PER_LANE+1),ya/(PER_LANE+1)
x,y=(xa*(position))+BLUE_BASE[0],(ya*(position))+BLUE_BASE[1]
else:
xa,ya=LANEMIDDLES[lane]
xb,yb=GREEN_BASE
xa,ya=xa-xb,ya-yb
xa,ya=xa/(PER_LANE+1),ya/(PER_LANE+1)
x,y=(xa*(position))+GREEN_BASE[0],(ya*(position))+GREEN_BASE[1]
return lane,position,team,x,y,self.map.get_z(x,y)
def get_cp_entities(self):
cps = []
for i in xrange(NOCP):
l,p,t,x,y,z = self.get_cp(i)
cp = MOBACP(i, self, x,y,z)
cp.team = t
cp.position = p
cp.lane = l
cp.start_team = t
cps.append(cp)
self.cps=cps
return cps
return MOBAProtocol,MOBAConnection
Lanes by Jdrew! lanes is your basic moba map but the two corners of the map are not there, you will have to build to the other corner. It is best to have no airstrikes and have "user blocks only" set to true when using the map. Enjoy! Here is the drop box link. *click here*
Credits:
Jdrew - Idea and tester
thepolm3 - Scripter
blockpower concept is by Danke