bug fixes , cleanup

This commit is contained in:
Ayush Saini 2023-02-19 13:24:59 +05:30
parent 1dfd8366e5
commit 180603d6ca
23 changed files with 1217 additions and 666 deletions

Binary file not shown.

View file

@ -1,14 +1,19 @@
from .Handlers import handlemsg, handlemsg_all,send from .Handlers import handlemsg, handlemsg_all, send
from playersData import pdata from playersData import pdata
# from tools.whitelist import add_to_white_list, add_commit_to_logs # from tools.whitelist import add_to_white_list, add_commit_to_logs
from serverData import serverdata from serverData import serverdata
import ba, _ba, time, setting import ba
import _ba
import time
import setting
import ba.internal import ba.internal
import _thread import _thread
import random
from tools import playlist from tools import playlist
Commands = ['showid','hideid','lm', 'gp', 'party', 'quit', 'kickvote','maxplayers','playlist','ban','kick', 'remove', 'end', 'quit', 'mute', 'unmute', 'slowmo', 'nv', 'dv', 'pause', 'cameramode', 'createrole', 'addrole', 'removerole', 'addcommand', 'addcmd', 'removecommand','getroles', 'removecmd', 'changetag','customtag','customeffect','add', 'spectators', 'lobbytime'] Commands = ['createteam', 'showid', 'hideid', 'lm', 'gp', 'party', 'quit', 'kickvote', 'maxplayers', 'playlist', 'ban', 'kick', 'remove', 'end', 'quit', 'mute', 'unmute', 'slowmo', 'nv', 'dv', 'pause',
CommandAliases = ['max','rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm', 'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera','effect'] 'cameramode', 'createrole', 'addrole', 'removerole', 'addcommand', 'addcmd', 'removecommand', 'getroles', 'removecmd', 'changetag', 'customtag', 'customeffect', 'add', 'spectators', 'lobbytime']
CommandAliases = ['max', 'rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm',
'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera', 'effect']
def ExcelCommand(command, arguments, clientid, accountid): def ExcelCommand(command, arguments, clientid, accountid):
@ -24,9 +29,11 @@ def ExcelCommand(command, arguments, clientid, accountid):
Returns: Returns:
None None
""" """
if command in ['maxplayers','max']: if command in ['maxplayers', 'max']:
changepartysize(arguments) changepartysize(arguments)
elif command =='playlist': if command in ['createteam']:
create_team(arguments)
elif command == 'playlist':
changeplaylist(arguments) changeplaylist(arguments)
elif command == 'kick': elif command == 'kick':
kick(arguments) kick(arguments)
@ -85,8 +92,8 @@ def ExcelCommand(command, arguments, clientid, accountid):
elif command == 'removerole': elif command == 'removerole':
remove_role_from_player(arguments) remove_role_from_player(arguments)
elif command=='getroles': elif command == 'getroles':
get_roles_of_player(arguments,clientid) get_roles_of_player(arguments, clientid)
elif command in ['addcommand', 'addcmd']: elif command in ['addcommand', 'addcmd']:
add_command_to_role(arguments) add_command_to_role(arguments)
@ -97,10 +104,10 @@ def ExcelCommand(command, arguments, clientid, accountid):
elif command == 'changetag': elif command == 'changetag':
change_role_tag(arguments) change_role_tag(arguments)
elif command=='customtag': elif command == 'customtag':
set_custom_tag(arguments) set_custom_tag(arguments)
elif command in ['customeffect','effect']: elif command in ['customeffect', 'effect']:
set_custom_effect(arguments) set_custom_effect(arguments)
# elif command in ['add', 'whitelist']: # elif command in ['add', 'whitelist']:
@ -113,26 +120,40 @@ def ExcelCommand(command, arguments, clientid, accountid):
change_lobby_check_time(arguments) change_lobby_check_time(arguments)
def create_team(arguments):
if len(arguments) == 0:
ba.internal.chatmessage("enter team name")
else:
from ba._team import SessionTeam
_ba.get_foreground_host_session().sessionteams.append(SessionTeam(team_id=2, name=str(arguments[0]), color=(random.uniform(0, 1.2), random.uniform(
0, 1.2), random.uniform(0, 1.2))))
from ba._lobby import Lobby
_ba.get_foreground_host_session().lobby = Lobby()
def hide_player_spec(): def hide_player_spec():
_ba.hide_player_device_id(True) _ba.hide_player_device_id(True)
def show_player_spec(): def show_player_spec():
_ba.hide_player_device_id(False) _ba.hide_player_device_id(False)
def changepartysize(arguments): def changepartysize(arguments):
if len(arguments)==0: if len(arguments) == 0:
ba.internal.chatmessage("enter number") ba.internal.chatmessage("enter number")
else: else:
ba.internal.set_public_party_max_size(int(arguments[0])) ba.internal.set_public_party_max_size(int(arguments[0]))
def changeplaylist(arguments): def changeplaylist(arguments):
if len(arguments)==0: if len(arguments) == 0:
ba.internal.chatmessage("enter list code or name") ba.internal.chatmessage("enter list code or name")
else: else:
if arguments[0]=='coop': if arguments[0] == 'coop':
serverdata.coopmode=True serverdata.coopmode = True
else: else:
serverdata.coopmode=False serverdata.coopmode = False
playlist.setPlaylist(arguments[0]) playlist.setPlaylist(arguments[0])
return return
@ -140,6 +161,8 @@ def changeplaylist(arguments):
def kick(arguments): def kick(arguments):
ba.internal.disconnect_client(int(arguments[0])) ba.internal.disconnect_client(int(arguments[0]))
return return
def kikvote(arguments, clientid): def kikvote(arguments, clientid):
if arguments == [] or arguments == [''] or len(arguments) < 2: if arguments == [] or arguments == [''] or len(arguments) < 2:
return return
@ -149,12 +172,14 @@ def kikvote(arguments, clientid):
_ba.set_enable_default_kick_voting(True) _ba.set_enable_default_kick_voting(True)
else: else:
try: try:
cl_id=int(arguments[1]) cl_id = int(arguments[1])
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id: if ros["client_id"] == cl_id:
if ros["account_id"] in serverdata.clients: if ros["account_id"] in serverdata.clients:
serverdata.clients[ros["account_id"]]["canStartKickVote"]=True serverdata.clients[ros["account_id"]
send("Upon server restart, Kick-vote will be enabled for this person", clientid) ]["canStartKickVote"] = True
send(
"Upon server restart, Kick-vote will be enabled for this person", clientid)
return return
except: except:
return return
@ -164,36 +189,40 @@ def kikvote(arguments, clientid):
_ba.set_enable_default_kick_voting(False) _ba.set_enable_default_kick_voting(False)
else: else:
try: try:
cl_id=int(arguments[1]) cl_id = int(arguments[1])
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id: if ros["client_id"] == cl_id:
_ba.disable_kickvote(ros["account_id"]) _ba.disable_kickvote(ros["account_id"])
send("Kick-vote disabled for this person", clientid) send("Kick-vote disabled for this person", clientid)
if ros["account_id"] in serverdata.clients: if ros["account_id"] in serverdata.clients:
serverdata.clients[ros["account_id"]]["canStartKickVote"]=False serverdata.clients[ros["account_id"]
]["canStartKickVote"] = False
return return
except: except:
return return
else: else:
return return
def last_msgs(clientid): def last_msgs(clientid):
for i in ba.internal.get_chat_messages(): for i in ba.internal.get_chat_messages():
send(i,clientid) send(i, clientid)
def get_profiles(arguments,clientid):
def get_profiles(arguments, clientid):
try: try:
playerID = int(arguments[0]) playerID = int(arguments[0])
num = 1 num = 1
for i in ba.internal.get_foreground_host_session().sessionplayers[playerID].inputdevice.get_player_profiles(): for i in ba.internal.get_foreground_host_session().sessionplayers[playerID].inputdevice.get_player_profiles():
try: try:
send(f"{num})- {i}",clientid) send(f"{num})- {i}", clientid)
num += 1 num += 1
except: except:
pass pass
except: except:
pass pass
def party_toggle(arguments): def party_toggle(arguments):
if arguments == ['public']: if arguments == ['public']:
ba.internal.set_public_party_enabled(True) ba.internal.set_public_party_enabled(True)
@ -213,67 +242,62 @@ def end(arguments):
except: except:
pass pass
def ban(arguments): def ban(arguments):
try: try:
cl_id=int(arguments[0]) cl_id = int(arguments[0])
ac_id="" ac_id = ""
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id: if ros["client_id"] == cl_id:
pdata.ban_player(ros['account_id']) pdata.ban_player(ros['account_id'])
ac_id=ros['account_id'] ac_id = ros['account_id']
if ac_id in serverdata.clients: if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isBan"]=True serverdata.clients[ac_id]["isBan"] = True
kick(arguments) kick(arguments)
except: except:
pass pass
def quit(arguments): def quit(arguments):
if arguments == [] or arguments == ['']: if arguments == [] or arguments == ['']:
ba.quit() ba.quit()
def mute(arguments): def mute(arguments):
if len(arguments)==0: if len(arguments) == 0:
serverdata.muted=True serverdata.muted = True
try: try:
cl_id=int(arguments[0]) cl_id = int(arguments[0])
ac_id="" ac_id = ""
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id: if ros["client_id"] == cl_id:
_thread.start_new_thread(pdata.mute,(ros['account_id'],)) _thread.start_new_thread(pdata.mute, (ros['account_id'],))
ac_id = ros['account_id']
ac_id=ros['account_id']
if ac_id in serverdata.clients: if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isMuted"]=True serverdata.clients[ac_id]["isMuted"] = True
except: except:
pass pass
return return
def un_mute(arguments): def un_mute(arguments):
if len(arguments)==0: if len(arguments) == 0:
serverdata.muted=False serverdata.muted = False
try: try:
cl_id=int(arguments[0]) cl_id = int(arguments[0])
ac_id="" ac_id = ""
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id: if ros["client_id"] == cl_id:
pdata.unmute(ros['account_id']) pdata.unmute(ros['account_id'])
ac_id=ros['account_id'] ac_id = ros['account_id']
if ac_id in serverdata.clients: if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isMuted"]=False serverdata.clients[ac_id]["isMuted"] = False
return return
except: except:
pass pass
def remove(arguments): def remove(arguments):
if arguments == [] or arguments == ['']: if arguments == [] or arguments == ['']:
@ -288,13 +312,12 @@ def remove(arguments):
try: try:
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[0]): if i.inputdevice.client_id == int(arguments[0]):
i.remove_from_game() i.remove_from_game()
except: except:
return return
def slow_motion(): def slow_motion():
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
@ -306,7 +329,6 @@ def slow_motion():
activity.globalsnode.slow_motion = False activity.globalsnode.slow_motion = False
def nv(arguments): def nv(arguments):
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
@ -316,7 +338,7 @@ def nv(arguments):
if activity.globalsnode.tint != (0.5, 0.7, 1.0): if activity.globalsnode.tint != (0.5, 0.7, 1.0):
activity.globalsnode.tint = (0.5, 0.7, 1.0) activity.globalsnode.tint = (0.5, 0.7, 1.0)
else: else:
#will fix this soon # will fix this soon
pass pass
elif arguments[0] == 'off': elif arguments[0] == 'off':
@ -326,27 +348,25 @@ def nv(arguments):
pass pass
def dv(arguments): def dv(arguments):
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
if arguments == [] or arguments == ['']: if arguments == [] or arguments == ['']:
if activity.globalsnode.tint != (1,1,1): if activity.globalsnode.tint != (1, 1, 1):
activity.globalsnode.tint = (1,1,1) activity.globalsnode.tint = (1, 1, 1)
else: else:
#will fix this soon # will fix this soon
pass pass
elif arguments[0] == 'off': elif arguments[0] == 'off':
if activity.globalsnode.tint != (1,1,1): if activity.globalsnode.tint != (1, 1, 1):
return return
else: else:
pass pass
def pause(): def pause():
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
@ -362,12 +382,11 @@ def rotate_camera():
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
if activity.globalsnode.camera_mode != 'rotate': if activity.globalsnode.camera_mode != 'rotate':
activity.globalsnode.camera_mode = 'rotate' activity.globalsnode.camera_mode = 'rotate'
else: else:
activity.globalsnode.camera_mode == 'normal' activity.globalsnode.camera_mode == 'normal'
def create_role(arguments): def create_role(arguments):
@ -382,83 +401,90 @@ def add_role_to_player(arguments):
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]): if i.inputdevice.client_id == int(arguments[1]):
roles=pdata.add_player_role(arguments[0],i.get_v1_account_id()) roles = pdata.add_player_role(
arguments[0], i.get_v1_account_id())
except: except:
return return
def remove_role_from_player(arguments): def remove_role_from_player(arguments):
try: try:
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]): if i.inputdevice.client_id == int(arguments[1]):
roles=pdata.remove_player_role(arguments[0],i.get_v1_account_id()) roles = pdata.remove_player_role(
arguments[0], i.get_v1_account_id())
except: except:
return return
def get_roles_of_player(arguments,clientid):
def get_roles_of_player(arguments, clientid):
try: try:
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
roles=[] roles = []
reply="" reply = ""
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[0]): if i.inputdevice.client_id == int(arguments[0]):
roles=pdata.get_player_roles(i.get_v1_account_id()) roles = pdata.get_player_roles(i.get_v1_account_id())
print(roles) print(roles)
for role in roles: for role in roles:
reply=reply+role+"," reply = reply+role+","
send(reply,clientid) send(reply, clientid)
except: except:
return return
def change_role_tag(arguments): def change_role_tag(arguments):
try: try:
pdata.change_role_tag(arguments[0], arguments[1]) pdata.change_role_tag(arguments[0], arguments[1])
except: except:
return return
def set_custom_tag(arguments): def set_custom_tag(arguments):
try: try:
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]): if i.inputdevice.client_id == int(arguments[1]):
roles=pdata.set_tag(arguments[0],i.get_v1_account_id()) roles = pdata.set_tag(arguments[0], i.get_v1_account_id())
except: except:
return return
def set_custom_effect(arguments): def set_custom_effect(arguments):
try: try:
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers: for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]): if i.inputdevice.client_id == int(arguments[1]):
roles=pdata.set_effect(arguments[0],i.get_v1_account_id()) roles = pdata.set_effect(arguments[0], i.get_v1_account_id())
except: except:
return return
all_commands = ["changetag", "createrole", "addrole", "removerole", "addcommand", "addcmd", "removecommand", "removecmd", "kick", "remove", "rm", "end", "next", "quit", "restart", "mute", "mutechat", "unmute", "unmutechat", "sm", "slow", "slowmo", "nv", "night", "dv", "day", "pause", "pausegame", "cameraMode",
all_commands = ["changetag","createrole", "addrole", "removerole", "addcommand", "addcmd","removecommand","removecmd","kick","remove","rm","end","next","quit","restart","mute","mutechat","unmute","unmutechat","sm","slow","slowmo","nv","night","dv","day","pause","pausegame","cameraMode","camera_mode","rotate_camera","kill","die","heal","heath","curse","cur","sleep","sp","superpunch","gloves","punch","shield","protect","freeze","ice","unfreeze","thaw","gm","godmode","fly","inv","invisible","hl","headless","creepy","creep","celebrate","celeb","spaz"] "camera_mode", "rotate_camera", "kill", "die", "heal", "heath", "curse", "cur", "sleep", "sp", "superpunch", "gloves", "punch", "shield", "protect", "freeze", "ice", "unfreeze", "thaw", "gm", "godmode", "fly", "inv", "invisible", "hl", "headless", "creepy", "creep", "celebrate", "celeb", "spaz"]
def add_command_to_role(arguments): def add_command_to_role(arguments):
try: try:
if arguments[1] in all_commands: if len(arguments) == 2:
pdata.add_command_role(arguments[0], arguments[1]) pdata.add_command_role(arguments[0], arguments[1])
else:
ba.internal.chatmessage("invalid command arguments")
except: except:
return return
def remove_command_to_role(arguments): def remove_command_to_role(arguments):
try: try:
if arguments[1] in all_commands: if len(arguments) == 2:
pdata.remove_command_role(arguments[0], arguments[1]) pdata.remove_command_role(arguments[0], arguments[1])
except: except:
return return
# def whitelst_it(accountid : str, arguments): # def whitelst_it(accountid : str, arguments):
# settings = setting.get_settings_data() # settings = setting.get_settings_data()
@ -489,8 +515,6 @@ def remove_command_to_role(arguments):
# add_commit_to_logs(accountid+" added "+i['account_id']) # add_commit_to_logs(accountid+" added "+i['account_id'])
def spectators(arguments): def spectators(arguments):
if arguments[0] in ['on', 'off']: if arguments[0] in ['on', 'off']:
@ -507,8 +531,6 @@ def spectators(arguments):
ba.internal.chatmessage("spectators off") ba.internal.chatmessage("spectators off")
def change_lobby_check_time(arguments): def change_lobby_check_time(arguments):
try: try:
argument = int(arguments[0]) argument = int(arguments[0])

View file

@ -1,12 +1,13 @@
from .Handlers import send from .Handlers import send
import ba, _ba import ba
import _ba
import ba.internal import ba.internal
from stats import mystats from stats import mystats
from ba._general import Call from ba._general import Call
import _thread import _thread
Commands = ['me', 'list', 'uniqeid','ping'] Commands = ['me', 'list', 'uniqeid', 'ping']
CommandAliases = ['stats', 'score', 'rank', 'myself', 'l', 'id', 'pb-id', 'pb', 'accountid'] CommandAliases = ['stats', 'score', 'rank',
'myself', 'l', 'id', 'pb-id', 'pb', 'accountid']
def ExcelCommand(command, arguments, clientid, accountid): def ExcelCommand(command, arguments, clientid, accountid):
@ -23,21 +24,18 @@ def ExcelCommand(command, arguments, clientid, accountid):
None None
""" """
if command in ['me', 'stats', 'score', 'rank', 'myself']: if command in ['me', 'stats', 'score', 'rank', 'myself']:
fetch_send_stats(accountid,clientid) fetch_send_stats(accountid, clientid)
elif command in ['list', 'l']: elif command in ['list', 'l']:
list(clientid) list(clientid)
elif command in ['uniqeid', 'id', 'pb-id', 'pb' , 'accountid']: elif command in ['uniqeid', 'id', 'pb-id', 'pb', 'accountid']:
accountid_request(arguments, clientid, accountid) accountid_request(arguments, clientid, accountid)
elif command in ['ping']: elif command in ['ping']:
get_ping(arguments, clientid) get_ping(arguments, clientid)
def get_ping(arguments, clientid): def get_ping(arguments, clientid):
if arguments == [] or arguments == ['']: if arguments == [] or arguments == ['']:
send(f"Your ping {_ba.get_client_ping(clientid)}ms ", clientid) send(f"Your ping {_ba.get_client_ping(clientid)}ms ", clientid)
@ -47,7 +45,7 @@ def get_ping(arguments, clientid):
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for index, player in enumerate(session.sessionplayers): for index, player in enumerate(session.sessionplayers):
name = player.getname(full=True,icon = False), name = player.getname(full=True, icon=False),
if player.inputdevice.client_id == int(arguments[0]): if player.inputdevice.client_id == int(arguments[0]):
ping = _ba.get_client_ping(int(arguments[0])) ping = _ba.get_client_ping(int(arguments[0]))
send(f" {name}'s ping {ping}ms", clientid) send(f" {name}'s ping {ping}ms", clientid)
@ -55,18 +53,19 @@ def get_ping(arguments, clientid):
return return
def stats(ac_id,clientid): def stats(ac_id, clientid):
stats=mystats.get_stats_by_id(ac_id) stats = mystats.get_stats_by_id(ac_id)
if stats: if stats:
reply="Score:"+str(stats["scores"])+"\nGames:"+str(stats["games"])+"\nKills:"+str(stats["kills"])+"\nDeaths:"+str(stats["deaths"])+"\nAvg.:"+str(stats["avg_score"]) reply = "Score:"+str(stats["scores"])+"\nGames:"+str(stats["games"])+"\nKills:"+str(
stats["kills"])+"\nDeaths:"+str(stats["deaths"])+"\nAvg.:"+str(stats["avg_score"])
else: else:
reply="Not played any match yet." reply = "Not played any match yet."
_ba.pushcall(Call(send,reply,clientid),from_other_thread=True) _ba.pushcall(Call(send, reply, clientid), from_other_thread=True)
def fetch_send_stats(ac_id,clientid): def fetch_send_stats(ac_id, clientid):
_thread.start_new_thread(stats,(ac_id,clientid,)) _thread.start_new_thread(stats, (ac_id, clientid,))
def list(clientid): def list(clientid):
@ -75,20 +74,16 @@ def list(clientid):
p = u'{0:^16}{1:^15}{2:^10}' p = u'{0:^16}{1:^15}{2:^10}'
seprator = '\n______________________________\n' seprator = '\n______________________________\n'
list = p.format('Name', 'Client ID', 'Player ID')+seprator
list = p.format('Name', 'Client ID' , 'Player ID')+seprator
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
for index, player in enumerate(session.sessionplayers): for index, player in enumerate(session.sessionplayers):
list += p.format(player.getname(icon = False), list += p.format(player.getname(icon=False),
player.inputdevice.client_id, index)+"\n" player.inputdevice.client_id, index)+"\n"
send(list, clientid) send(list, clientid)
def accountid_request(arguments, clientid, accountid): def accountid_request(arguments, clientid, accountid):
"""Returns The Account Id Of Players""" """Returns The Account Id Of Players"""
@ -106,4 +101,3 @@ def accountid_request(arguments, clientid, accountid):
send(f" {name}'s account id is '{accountid}' ", clientid) send(f" {name}'s account id is '{accountid}' ", clientid)
except: except:
return return

View file

@ -18,7 +18,7 @@ def filter_chat_message(msg, client_id):
if msg.startswith("/"): if msg.startswith("/"):
Main.Command(msg, client_id) Main.Command(msg, client_id)
return None return None
logger.log("Host msg: |" + msg , "chat") logger.log("Host msg: | " + msg , "chat")
return msg return msg
acid = "" acid = ""
displaystring = "" displaystring = ""

View file

@ -33,6 +33,7 @@ from playersData import pdata
from features import EndVote from features import EndVote
from features import text_on_map from features import text_on_map
from features import map_fun from features import map_fun
from spazmod import modifyspaz
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Optional, Any from typing import Optional, Any
@ -44,6 +45,8 @@ def filter_chat_message(msg: str, client_id: int) -> str | None:
return handlechat.filter_chat_message(msg, client_id) return handlechat.filter_chat_message(msg, client_id)
# ba_meta export plugin # ba_meta export plugin
class modSetup(ba.Plugin): class modSetup(ba.Plugin):
def on_app_running(self): def on_app_running(self):
"""Runs when app is launched.""" """Runs when app is launched."""
@ -53,23 +56,24 @@ class modSetup(ba.Plugin):
if settings["afk_remover"]['enable']: if settings["afk_remover"]['enable']:
afk_check.checkIdle().start() afk_check.checkIdle().start()
if(settings["useV2Account"]): if (settings["useV2Account"]):
from tools import account from tools import account
if(ba.internal.get_v1_account_state()=='signed_in' and ba.internal.get_v1_account_type()=='V2'): if (ba.internal.get_v1_account_state() == 'signed_in' and ba.internal.get_v1_account_type() == 'V2'):
logging.debug("Account V2 is active") logging.debug("Account V2 is active")
else: else:
logging.warning("Account V2 login require ....stay tuned.") logging.warning("Account V2 login require ....stay tuned.")
ba.timer(3, ba.Call(logging.debug,"Starting Account V2 login process....")) ba.timer(3, ba.Call(logging.debug,
ba.timer(6,account.AccountUtil) "Starting Account V2 login process...."))
ba.timer(6, account.AccountUtil)
else: else:
ba.app.accounts_v2.set_primary_credentials(None) ba.app.accounts_v2.set_primary_credentials(None)
ba.internal.sign_in_v1('Local') ba.internal.sign_in_v1('Local')
ba.timer(60,playlist.flush_playlists) ba.timer(60, playlist.flush_playlists)
def on_app_shutdown(self): def on_app_shutdown(self):
pass pass
def score_screen_on_begin(_stats: ba.Stats) -> None: def score_screen_on_begin(_stats: ba.Stats) -> None:
"""Runs when score screen is displayed.""" """Runs when score screen is displayed."""
team_balancer.balanceTeams() team_balancer.balanceTeams()
@ -154,12 +158,13 @@ def import_games():
maps = os.listdir("ba_root/mods/maps") maps = os.listdir("ba_root/mods/maps")
for _map in maps: for _map in maps:
if _map.endswith(".py") or _map.endswith(".so"): if _map.endswith(".py") or _map.endswith(".so"):
importlib.import_module("maps." + _map.replace(".so", "").replace(".py", "")) importlib.import_module(
"maps." + _map.replace(".so", "").replace(".py", ""))
def import_dual_team_score() -> None: def import_dual_team_score() -> None:
"""Imports the dual team score.""" """Imports the dual team score."""
if settings["newResultBoard"]: if settings["newResultBoard"] and _ba.get_foreground_host_session().use_teams:
dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity
multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores
drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity drawscore.DrawScoreScreenActivity = newdts.DrawScoreScreenActivity
@ -186,7 +191,7 @@ org_end = ba._activity.Activity.end
def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False): def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False):
"""Runs when game is ended.""" """Runs when game is ended."""
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
_ba.prop_axis(1,0,0) _ba.prop_axis(1, 0, 0)
if isinstance(activity, CoopScoreScreen): if isinstance(activity, CoopScoreScreen):
team_balancer.checkToExitCoop() team_balancer.checkToExitCoop()
org_end(self, results, delay, force) org_end(self, results, delay, force)
@ -195,22 +200,20 @@ def new_end(self, results: Any = None, delay: float = 0.0, force: bool = False):
ba._activity.Activity.end = new_end ba._activity.Activity.end = new_end
org_player_join = ba._activity.Activity.on_player_join org_player_join = ba._activity.Activity.on_player_join
def on_player_join(self, player) -> None: def on_player_join(self, player) -> None:
"""Runs when player joins the game.""" """Runs when player joins the game."""
team_balancer.on_player_join() team_balancer.on_player_join()
org_player_join(self, player) org_player_join(self, player)
ba._activity.Activity.on_player_join = on_player_join ba._activity.Activity.on_player_join = on_player_join
def night_mode() -> None: def night_mode() -> None:
"""Checks the time and enables night mode.""" """Checks the time and enables night mode."""
if settings['autoNightMode']['enable']: if settings['autoNightMode']['enable']:
start = datetime.strptime(settings['autoNightMode']['startTime'], "%H:%M") start = datetime.strptime(
settings['autoNightMode']['startTime'], "%H:%M")
end = datetime.strptime(settings['autoNightMode']['endTime'], "%H:%M") end = datetime.strptime(settings['autoNightMode']['endTime'], "%H:%M")
now = datetime.now() now = datetime.now()
@ -220,7 +223,8 @@ def night_mode() -> None:
activity.globalsnode.tint = (0.5, 0.7, 1.0) activity.globalsnode.tint = (0.5, 0.7, 1.0)
if settings['autoNightMode']['fireflies']: if settings['autoNightMode']['fireflies']:
activity.fireflies_generator(20,settings['autoNightMode']["fireflies_random_color"]) activity.fireflies_generator(
20, settings['autoNightMode']["fireflies_random_color"])
def kick_vote_started(started_by: str, started_to: str) -> None: def kick_vote_started(started_by: str, started_to: str) -> None:
@ -241,7 +245,30 @@ def on_kick_vote_end():
def on_join_request(ip): def on_join_request(ip):
servercheck.on_join_request(ip) servercheck.on_join_request(ip)
def on_map_init(): def on_map_init():
text_on_map.textonmap() text_on_map.textonmap()
modifyspaz.setTeamCharacter()
from ba._servermode import ServerController
def shutdown(func) -> None:
"""Set the app to quit either now or at the next clean opportunity."""
def wrapper(*args, **kwargs):
# add screen text and tell players we are going to restart soon.
_ba.restart_scheduled = True
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
attrs={
'text':"Server going to restart after this series.",
'flatness':1.0,
'h_align':'right',
'v_attach':'bottom',
'h_attach':'right',
'scale':0.5,
'position':(-25,54),
'color':(1,0.5,0.7)
})
func(*args, **kwargs)
return wrapper
ServerController.shutdown = shutdown(ServerController.shutdown)

View file

@ -1,6 +1,7 @@
# EndVote by -mr.smoothy # EndVote by -mr.smoothy
import _ba, ba import _ba
import ba
import ba.internal import ba.internal
import time import time
@ -69,13 +70,14 @@ def required_votes(players):
elif players == 10: elif players == 10:
return 5 return 5
else: else:
return players - 4 return players - 5
def update_vote_text(votes_needed): def update_vote_text(votes_needed):
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
try: try:
activity.end_vote_text.node.text = "{} more votes to end this map\ntype 'end' to vote".format(votes_needed) activity.end_vote_text.node.text = "{} more votes to end this map\ntype 'end' to vote".format(
votes_needed)
except: except:
with _ba.Context(_ba.get_foreground_host_activity()): with _ba.Context(_ba.get_foreground_host_activity()):
node = ba.NodeActor(ba.newnode('text', node = ba.NodeActor(ba.newnode('text',
@ -99,4 +101,3 @@ def remove_vote_text():
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
if hasattr(activity, "end_vote_text") and activity.end_vote_text.node.exists(): if hasattr(activity, "end_vote_text") and activity.end_vote_text.node.exists():
activity.end_vote_text.node.delete() activity.end_vote_text.node.delete()

View file

@ -19,6 +19,8 @@ class checkIdle(object):
global cLastIdle global cLastIdle
global cIdle global cIdle
current=ba.time(ba.TimeType.REAL,timeformat=ba.TimeFormat.MILLISECONDS) current=ba.time(ba.TimeType.REAL,timeformat=ba.TimeFormat.MILLISECONDS)
if not ba.internal.get_foreground_host_session():
return
for player in ba.internal.get_foreground_host_session().sessionplayers: for player in ba.internal.get_foreground_host_session().sessionplayers:
last_input=int(player.inputdevice.get_last_input_time()) last_input=int(player.inputdevice.get_last_input_time())
afk_time=int((current-last_input)/1000) afk_time=int((current-last_input)/1000)

View file

@ -20,19 +20,20 @@ client = Bot(command_prefix='!', intents=intents)
# client = discord.Client() # client = discord.Client()
stats={} stats = {}
livestatsmsgs=[] livestatsmsgs = []
logsChannelID=859519868838608970 logsChannelID = 859519868838608970
liveStatsChannelID=924697770554687548 liveStatsChannelID = 924697770554687548
liveChat=True liveChat = True
token='' token = ''
logs=[] logs = []
def push_log(msg): def push_log(msg):
global logs global logs
logs.append(msg) logs.append(msg)
def init(): def init():
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
@ -40,44 +41,51 @@ def init():
Thread(target=loop.run_forever).start() Thread(target=loop.run_forever).start()
channel=None
channel = None
@client.event @client.event
async def on_message(message): async def on_message(message):
global channel global channel
if message.author == client.user: if message.author == client.user:
return return
channel=message.channel channel = message.channel
if message.channel.id==logsChannelID: if message.channel.id == logsChannelID:
_ba.pushcall(Call(ba.internal.chatmessage,message.content),from_other_thread=True) _ba.pushcall(Call(ba.internal.chatmessage,
message.content), from_other_thread=True)
@client.event @client.event
async def on_ready(): async def on_ready():
print("Discord bot logged in as: %s, %s" % (client.user.name, client.user.id)) print("Discord bot logged in as: %s, %s" %
(client.user.name, client.user.id))
await verify_channel() await verify_channel()
async def verify_channel(): async def verify_channel():
global livestatsmsgs global livestatsmsgs
channel=client.get_channel(liveStatsChannelID) channel = client.get_channel(liveStatsChannelID)
botmsg_count=0 botmsg_count = 0
msgs = await channel.history(limit=5).flatten() msgs = await channel.history(limit=5).flatten()
for msg in msgs: for msg in msgs:
if msg.author.id==client.user.id: if msg.author.id == client.user.id:
botmsg_count+=1 botmsg_count += 1
livestatsmsgs.append(msg) livestatsmsgs.append(msg)
livestatsmsgs.reverse() livestatsmsgs.reverse()
while(botmsg_count<2): while (botmsg_count < 2):
new_msg=await channel.send("msg reserved for live stats") new_msg = await channel.send("msg reserved for live stats")
livestatsmsgs.append(new_msg) livestatsmsgs.append(new_msg)
botmsg_count+=1 botmsg_count += 1
asyncio.run_coroutine_threadsafe(refresh_stats(),client.loop) asyncio.run_coroutine_threadsafe(refresh_stats(), client.loop)
asyncio.run_coroutine_threadsafe(send_logs(),client.loop) asyncio.run_coroutine_threadsafe(send_logs(), client.loop)
# client.loop.create_task(refresh_stats()) # client.loop.create_task(refresh_stats())
# client.loop.create_task(send_logs()) # client.loop.create_task(send_logs())
async def refresh_stats(): async def refresh_stats():
await client.wait_until_ready() await client.wait_until_ready()
@ -87,62 +95,63 @@ async def refresh_stats():
await livestatsmsgs[1].edit(content=get_chats()) await livestatsmsgs[1].edit(content=get_chats())
await asyncio.sleep(10) await asyncio.sleep(10)
async def send_logs(): async def send_logs():
global logs global logs
# safely dispatch logs to dc channel , without being rate limited and getting ban from discord # safely dispatch logs to dc channel , without being rate limited and getting ban from discord
# still we sending 2 msg and updating 2 msg within 5 seconds , umm still risky ...nvm not my problem # still we sending 2 msg and updating 2 msg within 5 seconds , umm still risky ...nvm not my problem
channel=client.get_channel(logsChannelID) channel = client.get_channel(logsChannelID)
await client.wait_until_ready() await client.wait_until_ready()
while not client.is_closed(): while not client.is_closed():
if logs: if logs:
msg='' msg = ''
for msg_ in logs: for msg_ in logs:
msg+=msg_+"\n" msg += msg_+"\n"
logs=[] logs = []
if msg: if msg:
await channel.send(msg) await channel.send(msg)
await asyncio.sleep(10) await asyncio.sleep(10)
def get_live_players_msg(): def get_live_players_msg():
global stats global stats
msg_1='***Live Stats :***\n\n ***Players in server***\n\n' msg_1 = '***Live Stats :***\n\n ***Players in server***\n\n'
msg='' msg = ''
try: try:
for id in stats['roster']: for id in stats['roster']:
name=stats['roster'][id]['name'] name = stats['roster'][id]['name']
device_id=stats['roster'][id]['device_id'] device_id = stats['roster'][id]['device_id']
msg+=id +" -> "+name+" -> "+device_id+" \n" msg += id + " -> "+name+" -> "+device_id+" \n"
except: except:
pass pass
if not msg: if not msg:
msg="```No one``` \n" msg = "```No one``` \n"
msg_2="\n\n***Current: *** "+stats['playlist']['current'] +"\n ***Next: ***"+stats['playlist']['next'] +"\n\n." msg_2 = "\n\n***Current: *** " + \
stats['playlist']['current'] + "\n ***Next: ***" + \
stats['playlist']['next'] + "\n\n."
return msg_1+msg+msg_2 return msg_1+msg+msg_2
def get_chats(): def get_chats():
msg_1='***Live Chat***\n\n' msg_1 = '***Live Chat***\n\n'
msg='' msg = ''
try: try:
for msg_ in stats['chats']: for msg_ in stats['chats']:
msg+=msg_+"\n" msg += msg_+"\n"
except: except:
pass pass
if not msg: if not msg:
msg= "```Empty```\n" msg = "```Empty```\n"
if not liveChat: if not liveChat:
return '```disabled```' return '```disabled```'
return msg_1+msg return msg_1+msg
class BsDataThread(object): class BsDataThread(object):
def __init__(self): def __init__(self):
self.refreshStats() self.refreshStats()
self.Timer = ba.Timer( 8,ba.Call(self.refreshStats),repeat = True) self.Timer = ba.Timer(8, ba.Call(self.refreshStats), repeat=True)
# self.Timerr = ba.Timer( 10,ba.Call(self.refreshLeaderboard),timetype = ba.TimeType.REAL,repeat = True) # self.Timerr = ba.Timer( 10,ba.Call(self.refreshLeaderboard),timetype = ba.TimeType.REAL,repeat = True)
# def refreshLeaderboard(self): # def refreshLeaderboard(self):
@ -165,33 +174,35 @@ class BsDataThread(object):
def refreshStats(self): def refreshStats(self):
liveplayers={} liveplayers = {}
nextMap='' nextMap = ''
currentMap='' currentMap = ''
global stats global stats
for i in ba.internal.get_game_roster(): for i in ba.internal.get_game_roster():
try: try:
liveplayers[i['account_id']]={'name':i['players'][0]['name_full'],'client_id':i['client_id'],'device_id':i['display_string']} liveplayers[i['account_id']] = {
'name': i['players'][0]['name_full'], 'client_id': i['client_id'], 'device_id': i['display_string']}
except: except:
liveplayers[i['account_id']]={'name':"<in-lobby>",'clientid':i['client_id'],'device_id':i['display_string']} liveplayers[i['account_id']] = {
'name': "<in-lobby>", 'clientid': i['client_id'], 'device_id': i['display_string']}
try: try:
nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate() nextMap = ba.internal.get_foreground_host_session(
).get_next_game_description().evaluate()
current_game_spec=ba.internal.get_foreground_host_session()._current_game_spec current_game_spec = ba.internal.get_foreground_host_session()._current_game_spec
gametype: Type[GameActivity] =current_game_spec['resolved_type'] gametype: Type[GameActivity] = current_game_spec['resolved_type']
currentMap=gametype.get_settings_display_string(current_game_spec).evaluate() currentMap = gametype.get_settings_display_string(
current_game_spec).evaluate()
except: except:
pass pass
minigame={'current':currentMap,'next':nextMap} minigame = {'current': currentMap, 'next': nextMap}
# system={'cpu':p.cpu_percent(),'ram':p.virtual_memory().percent} # system={'cpu':p.cpu_percent(),'ram':p.virtual_memory().percent}
#system={'cpu':80,'ram':34} # system={'cpu':80,'ram':34}
# stats['system']=system # stats['system']=system
stats['roster']=liveplayers stats['roster'] = liveplayers
stats['chats']=ba.internal.get_chat_messages() stats['chats'] = ba.internal.get_chat_messages()
stats['playlist']=minigame stats['playlist'] = minigame
# stats['teamInfo']=self.getTeamInfo() # stats['teamInfo']=self.getTeamInfo()

View file

@ -87,8 +87,8 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
kill_delay: float, shiftdelay: float) -> None: kill_delay: float, shiftdelay: float) -> None:
del kill_delay # Unused arg. del kill_delay # Unused arg.
ZoomText(ba.Lstr(value='${A}', subs=[('${A}', team.name)]), ZoomText(ba.Lstr(value='${A}', subs=[('${A}', team.name)]),
position=(-250, 260) if pos_v == 65 else (250,260), position=(-250, 260) if pos_v == 65 else (250, 260),
shiftposition=(-250, 260) if pos_v == 65 else (250,260), shiftposition=(-250, 260) if pos_v == 65 else (250, 260),
shiftdelay=shiftdelay, shiftdelay=shiftdelay,
flash=False, flash=False,
trail=False, trail=False,
@ -101,10 +101,10 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
def _show_team_old_score(self, pos_v: float, sessionteam: ba.SessionTeam, def _show_team_old_score(self, pos_v: float, sessionteam: ba.SessionTeam,
shiftdelay: float) -> None: shiftdelay: float) -> None:
ZoomText(str(sessionteam.customdata['score'] - 1), ZoomText(str(sessionteam.customdata['score'] - 1),
position=(-250, 190) if pos_v == 65 else (250,190), position=(-250, 190) if pos_v == 65 else (250, 190),
maxwidth=100, maxwidth=100,
color=(0.6, 0.6, 0.7), color=(0.6, 0.6, 0.7),
shiftposition=(-250, 190) if pos_v == 65 else (250,190), shiftposition=(-250, 190) if pos_v == 65 else (250, 190),
shiftdelay=shiftdelay, shiftdelay=shiftdelay,
flash=False, flash=False,
trail=False, trail=False,
@ -118,10 +118,10 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
shiftdelay: float) -> None: shiftdelay: float) -> None:
del kill_delay # Unused arg. del kill_delay # Unused arg.
ZoomText(str(sessionteam.customdata['score']), ZoomText(str(sessionteam.customdata['score']),
position=(-250, 190) if pos_v == 65 else (250,190), position=(-250, 190) if pos_v == 65 else (250, 190),
maxwidth=100, maxwidth=100,
color=(1.0, 0.9, 0.5) if scored else (0.6, 0.6, 0.7), color=(1.0, 0.9, 0.5) if scored else (0.6, 0.6, 0.7),
shiftposition=(-250, 190) if pos_v == 65 else (250,190), shiftposition=(-250, 190) if pos_v == 65 else (250, 190),
shiftdelay=shiftdelay, shiftdelay=shiftdelay,
flash=scored, flash=scored,
trail=scored, trail=scored,
@ -137,26 +137,25 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
# ==================================================================================================== # ====================================================================================================
def show_player_scores(self, def show_player_scores(self,
delay: float = 2.5, delay: float = 2.5,
results: Optional[ba.GameResults] = None, results: Optional[ba.GameResults] = None,
scale: float = 1.0, scale: float = 1.0,
x_offset: float = 0.0, x_offset: float = 0.0,
y_offset: float = 0.0) -> None: y_offset: float = 0.0) -> None:
"""Show scores for individual players.""" """Show scores for individual players."""
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
ts_v_offset = 150.0 + y_offset ts_v_offset = 150.0 + y_offset
ts_h_offs = 80.0 + x_offset ts_h_offs = 80.0 + x_offset
tdelay = delay tdelay = delay
spacing = 40 spacing = 40
is_free_for_all = isinstance(self.session, ba.FreeForAllSession)
is_free_for_all = isinstance(self.session, ba.FreeForAllSession) is_two_team = True if len(self.session.sessionteams) == 2 else False
is_two_team = True if len(self.session.sessionteams) == 2 else False def _get_prec_score(p_rec: ba.PlayerRecord) -> Optional[int]:
def _get_prec_score(p_rec: ba.PlayerRecord) -> Optional[int]:
if is_free_for_all and results is not None: if is_free_for_all and results is not None:
assert isinstance(results, ba.GameResults) assert isinstance(results, ba.GameResults)
assert p_rec.team.activityteam is not None assert p_rec.team.activityteam is not None
@ -164,7 +163,7 @@ def show_player_scores(self,
return val return val
return p_rec.accumscore return p_rec.accumscore
def _get_prec_score_str(p_rec: ba.PlayerRecord) -> Union[str, ba.Lstr]: def _get_prec_score_str(p_rec: ba.PlayerRecord) -> Union[str, ba.Lstr]:
if is_free_for_all and results is not None: if is_free_for_all and results is not None:
assert isinstance(results, ba.GameResults) assert isinstance(results, ba.GameResults)
assert p_rec.team.activityteam is not None assert p_rec.team.activityteam is not None
@ -177,7 +176,7 @@ def show_player_scores(self,
# the game.. if we're using results we have to filter those out # the game.. if we're using results we have to filter those out
# (since they're not in results and that's where we pull their # (since they're not in results and that's where we pull their
# scores from) # scores from)
if results is not None: if results is not None:
assert isinstance(results, ba.GameResults) assert isinstance(results, ba.GameResults)
player_records = [] player_records = []
assert self.stats assert self.stats
@ -199,23 +198,23 @@ def show_player_scores(self,
team.players[0]) team.players[0])
if player_entry is not None: if player_entry is not None:
player_records.append(player_entry) player_records.append(player_entry)
else: else:
player_records = [] player_records = []
player_records_scores = [ player_records_scores = [
(_get_prec_score(p), name, p) (_get_prec_score(p), name, p)
for name, p in list(self.stats.get_records().items()) for name, p in list(self.stats.get_records().items())
] ]
player_records_scores.sort(reverse=True) player_records_scores.sort(reverse=True)
# Just want living player entries. # Just want living player entries.
player_records = [p[2] for p in player_records_scores if p[2]] player_records = [p[2] for p in player_records_scores if p[2]]
voffs = -140.0 + spacing * 5 * 0.5 voffs = -140.0 + spacing * 5 * 0.5
voffs_team0=voffs voffs_team0 = voffs
tdelay_team0=tdelay tdelay_team0 = tdelay
def _txt(xoffs: float, def _txt(xoffs: float,
yoffs: float, yoffs: float,
text: ba.Lstr, text: ba.Lstr,
h_align: Text.HAlign = Text.HAlign.RIGHT, h_align: Text.HAlign = Text.HAlign.RIGHT,
@ -232,50 +231,50 @@ def show_player_scores(self,
transition=Text.Transition.IN_LEFT, transition=Text.Transition.IN_LEFT,
transition_delay=tdelay).autoretain() transition_delay=tdelay).autoretain()
session = self.session session = self.session
assert isinstance(session, ba.MultiTeamSession) assert isinstance(session, ba.MultiTeamSession)
if is_two_team: if is_two_team:
tval = "Game "+str(session.get_game_number())+" Results" tval = "Game "+str(session.get_game_number())+" Results"
_txt(-75, _txt(-75,
160, 160,
tval, tval,
h_align=Text.HAlign.CENTER, h_align=Text.HAlign.CENTER,
extrascale=1.4, extrascale=1.4,
maxwidth=None) maxwidth=None)
_txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT) _txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
_txt(180, 4, ba.Lstr(resource='killsText')) _txt(180, 4, ba.Lstr(resource='killsText'))
_txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100) _txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100)
score_label = 'Score' if results is None else results.score_label score_label = 'Score' if results is None else results.score_label
translated = ba.Lstr(translate=('scoreNames', score_label)) translated = ba.Lstr(translate=('scoreNames', score_label))
_txt(390, 0, translated) _txt(390, 0, translated)
if is_two_team: if is_two_team:
_txt(-595, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT) _txt(-595, 4, ba.Lstr(resource='playerText'),
h_align=Text.HAlign.LEFT)
_txt(-400, 4, ba.Lstr(resource='killsText')) _txt(-400, 4, ba.Lstr(resource='killsText'))
_txt(-300, 4, ba.Lstr(resource='deathsText'), maxwidth=100) _txt(-300, 4, ba.Lstr(resource='deathsText'), maxwidth=100)
_txt(-190, 0, translated) _txt(-190, 0, translated)
topkillcount = 0
topkillcount = 0 topkilledcount = 99999
topkilledcount = 99999 top_score = 0 if not player_records else _get_prec_score(
top_score = 0 if not player_records else _get_prec_score(
player_records[0]) player_records[0])
for prec in player_records: for prec in player_records:
topkillcount = max(topkillcount, prec.accum_kill_count) topkillcount = max(topkillcount, prec.accum_kill_count)
topkilledcount = min(topkilledcount, prec.accum_killed_count) topkilledcount = min(topkilledcount, prec.accum_killed_count)
def _scoretxt(text: Union[str, ba.Lstr], def _scoretxt(text: Union[str, ba.Lstr],
x_offs: float, x_offs: float,
highlight: bool, highlight: bool,
delay2: float, delay2: float,
maxwidth: float = 70.0,team_id=1) -> None: maxwidth: float = 70.0, team_id=1) -> None:
Text(text, Text(text,
position=(ts_h_offs + x_offs * scale, position=(ts_h_offs + x_offs * scale,
ts_v_offset + (voffs + 15) * scale) if team_id==1 else (ts_h_offs+x_offs*scale,ts_v_offset+(voffs_team0+15)*scale), ts_v_offset + (voffs + 15) * scale) if team_id == 1 else (ts_h_offs+x_offs*scale, ts_v_offset+(voffs_team0+15)*scale),
scale=scale, scale=scale,
color=(1.0, 0.9, 0.5, 1.0) if highlight else color=(1.0, 0.9, 0.5, 1.0) if highlight else
(0.5, 0.5, 0.6, 0.5), (0.5, 0.5, 0.6, 0.5),
@ -283,36 +282,30 @@ def show_player_scores(self,
v_align=Text.VAlign.CENTER, v_align=Text.VAlign.CENTER,
maxwidth=maxwidth, maxwidth=maxwidth,
transition=Text.Transition.IN_LEFT, transition=Text.Transition.IN_LEFT,
transition_delay=(tdelay + delay2) if team_id==1 else (tdelay_team0+delay2) ).autoretain() transition_delay=(tdelay + delay2) if team_id == 1 else (tdelay_team0+delay2)).autoretain()
for playerrec in player_records: for playerrec in player_records:
if is_two_team and playerrec.team.id==0: if is_two_team and playerrec.team.id == 0:
tdelay_team0 +=0.05 tdelay_team0 += 0.05
voffs_team0 -=spacing voffs_team0 -= spacing
x_image=617 x_image = 617
x_text=-595 x_text = -595
y=ts_v_offset + (voffs_team0 + 15.0) * scale y = ts_v_offset + (voffs_team0 + 15.0) * scale
else:
else:
tdelay += 0.05 tdelay += 0.05
voffs -= spacing voffs -= spacing
x_image=12 x_image = 12
x_text=10.0 x_text = 10.0
y=ts_v_offset + (voffs + 15.0) * scale y = ts_v_offset + (voffs + 15.0) * scale
Image(playerrec.get_icon(),
position=(ts_h_offs - x_image * scale,
Image(playerrec.get_icon(),
position=(ts_h_offs - x_image* scale,
y), y),
scale=(30.0 * scale, 30.0 * scale), scale=(30.0 * scale, 30.0 * scale),
transition=Image.Transition.IN_LEFT, transition=Image.Transition.IN_LEFT,
transition_delay=tdelay if playerrec.team.id==1 else tdelay_team0).autoretain() transition_delay=tdelay if playerrec.team.id == 1 else tdelay_team0).autoretain()
Text(ba.Lstr(value=playerrec.getname(full=True)), Text(ba.Lstr(value=playerrec.getname(full=True)),
maxwidth=160, maxwidth=160,
scale=0.75 * scale, scale=0.75 * scale,
position=(ts_h_offs + x_text * scale, position=(ts_h_offs + x_text * scale,
@ -321,16 +314,16 @@ def show_player_scores(self,
v_align=Text.VAlign.CENTER, v_align=Text.VAlign.CENTER,
color=ba.safecolor(playerrec.team.color + (1, )), color=ba.safecolor(playerrec.team.color + (1, )),
transition=Text.Transition.IN_LEFT, transition=Text.Transition.IN_LEFT,
transition_delay=tdelay if playerrec.team.id==1 else tdelay_team0).autoretain() transition_delay=tdelay if playerrec.team.id == 1 else tdelay_team0).autoretain()
if is_two_team and playerrec.team.id==0: if is_two_team and playerrec.team.id == 0:
_scoretxt(str(playerrec.accum_kill_count), -400, _scoretxt(str(playerrec.accum_kill_count), -400,
playerrec.accum_kill_count == topkillcount, 0.1,team_id=0) playerrec.accum_kill_count == topkillcount, 0.1, team_id=0)
_scoretxt(str(playerrec.accum_killed_count), -300, _scoretxt(str(playerrec.accum_killed_count), -300,
playerrec.accum_killed_count == topkilledcount, 0.1,team_id=0) playerrec.accum_killed_count == topkilledcount, 0.1, team_id=0)
_scoretxt(_get_prec_score_str(playerrec), -190, _scoretxt(_get_prec_score_str(playerrec), -190,
_get_prec_score(playerrec) == top_score, 0.2,team_id=0) _get_prec_score(playerrec) == top_score, 0.2, team_id=0)
else: else:
_scoretxt(str(playerrec.accum_kill_count), 180, _scoretxt(str(playerrec.accum_kill_count), 180,
playerrec.accum_kill_count == topkillcount, 0.1) playerrec.accum_kill_count == topkillcount, 0.1)
_scoretxt(str(playerrec.accum_killed_count), 280, _scoretxt(str(playerrec.accum_killed_count), 280,
@ -358,4 +351,4 @@ class DrawScoreScreenActivity(MultiTeamScoreScreenActivity):
trail=False, trail=False,
jitter=1.0).autoretain() jitter=1.0).autoretain()
ba.timer(0.35, ba.Call(ba.playsound, self._score_display_sound)) ba.timer(0.35, ba.Call(ba.playsound, self._score_display_sound))
self.show_player_scores(results=self.settings_raw.get('results', None)) self.show_player_scores(results=self.settings_raw.get('results', None))

View file

@ -8,11 +8,12 @@ from ba._messages import DieMessage, DeathType, OutOfBoundsMessage, UNHANDLED
on_begin_original = ba._activity.Activity.on_begin on_begin_original = ba._activity.Activity.on_begin
def fireflies_generator(activity, count, random_color:False): def fireflies_generator(activity, count, random_color: False):
if random_color: if random_color:
color=(random.uniform(0,1.2),random.uniform(0,1.2),random.uniform(0,1.2)) color = (random.uniform(0, 1.2), random.uniform(
0, 1.2), random.uniform(0, 1.2))
else: else:
color=(0.9,0.7,0.0) color = (0.9, 0.7, 0.0)
increment = count - len(activity.fireflies) increment = count - len(activity.fireflies)
if increment > 0: if increment > 0:
@ -64,25 +65,14 @@ class FireFly(ba.Actor):
('modify_part_collision', 'collide', False), ('modify_part_collision', 'collide', False),
('modify_part_collision', 'physical', False), ('modify_part_collision', 'physical', False),
)) ))
self.node = ba.newnode( self.node = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, 0),
'prop', 'color': self.color, 'opacity': 0.5, 'draw_beauty': True, 'additive': False, 'size': [0.10]})
delegate=self, # ba.animate(
attrs={ # self.node,
'model': ba.getmodel('bomb'), # 'scale',
'position': (2,4,2), # {0:0, 1:0.004, 5:0.006, 10:0.0},
'body': 'capsule', # loop=True,
'shadow_size': 0.0, # )
'color_texture': random.choice([ba.gettexture(tex) for tex in ("egg1", "egg2", "egg3")]),
'reflection': 'soft',
'reflection_scale': [1.5],
'materials': (shared.object_material, self.mat)
})
ba.animate(
self.node,
'model_scale',
{0:0, 1:0.23, 5:0.15, 10:0.0},
loop=True,
)
ba.animate_array( ba.animate_array(
self.node, self.node,
'position', 'position',
@ -95,15 +85,15 @@ class FireFly(ba.Actor):
'light', 'light',
owner=self.node, owner=self.node,
attrs={ attrs={
'intensity':0.6, 'intensity': 0.6,
'height_attenuated':True, 'height_attenuated': True,
'radius':0.2, 'radius': 0.2,
'color':self.color 'color': self.color
}) })
ba.animate( ba.animate(
self.light, self.light,
'radius', 'radius',
{0:0.0, 20:0.4 ,70:0.1 ,100:0.3 ,150:0}, {0: 0.0, 20: 0.4, 70: 0.1, 100: 0.3, 150: 0},
loop=True loop=True
) )
self.node.connectattr('position', self.light, 'position') self.node.connectattr('position', self.light, 'position')
@ -119,7 +109,7 @@ class FireFly(ba.Actor):
ba.animate( ba.animate(
self.light, self.light,
'radius', 'radius',
{0:self.light.radius, death_secs:0} {0: self.light.radius, death_secs: 0}
) )
ba.timer(death_secs, self.node.delete) ba.timer(death_secs, self.node.delete)
@ -129,24 +119,23 @@ class FireFly(ba.Actor):
return None return None
elif isinstance(msg, OutOfBoundsMessage): elif isinstance(msg, OutOfBoundsMessage):
return self.handlemessage(ba.DieMessage(how=DeathType.OUT_OF_BOUNDS)) return self.handlemessage(ba.DieMessage(how=DeathType.OUT_OF_BOUNDS))
return super().handlemessage(msg) return super().handlemessage(msg)
def generate_keys(self,m): def generate_keys(self, m):
keys = {} keys = {}
t = 0 t = 0
last_x = random.randrange(int(m[0]),int(m[3])) last_x = random.randrange(int(m[0]), int(m[3]))
last_y = random.randrange(int(m[1]),int(m[4])) last_y = random.randrange(int(m[1]), int(m[4]))
if int(m[2]) == int(m[5]): if int(m[2]) == int(m[5]):
last_z = int(m[2]) last_z = int(m[2])
else: else:
last_z = random.randrange(int(m[2]),int(m[5])) last_z = random.randrange(int(m[2]), int(m[5]))
for i in range(0,7): for i in range(0, 7):
x = self.generate_random(int(m[0]),int(m[3]),last_x) x = self.generate_random(int(m[0]), int(m[3]), last_x)
last_x = x last_x = x
y = self.generate_random(int(m[1]),int(m[4]),last_y) y = self.generate_random(int(m[1]), int(m[4]), last_y)
last_y = y last_y = y
z = self.generate_random(int(m[2]),int(m[5]),last_z) z = self.generate_random(int(m[2]), int(m[5]), last_z)
last_z = z last_z = z
keys[t] = (x, abs(y), z) keys[t] = (x, abs(y), z)
t += 30 t += 30
@ -156,7 +145,7 @@ class FireFly(ba.Actor):
if a == b: if a == b:
return a return a
while True: while True:
n = random.randrange(a,b) n = random.randrange(a, b)
if abs(z-n) < 6: if abs(z-n) < 6:
return n return n
@ -166,6 +155,5 @@ def on_begin(self, *args, **kwargs) -> None:
return on_begin_original(self, *args, **kwargs) return on_begin_original(self, *args, **kwargs)
ba._activity.Activity.fireflies_generator = fireflies_generator ba._activity.Activity.fireflies_generator = fireflies_generator
ba._activity.Activity.on_begin = on_begin ba._activity.Activity.on_begin = on_begin

145
dist/ba_root/mods/features/hearts.py vendored Normal file
View file

@ -0,0 +1,145 @@
import random
from typing import TYPE_CHECKING
import ba
import _ba
from typing import Any, Sequence
class PopupText(ba.Actor):
"""Text that pops up above a position to denote something special.
category: Gameplay Classes
"""
def __init__(
self,
text: str | ba.Lstr,
position: Sequence[float] = (0.0, 0.0, 0.0),
color: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
random_offset: float = 0.5,
offset: Sequence[float] = (0.0, 0.0, 0.0),
scale: float = 1.0,
):
"""Instantiate with given values.
random_offset is the amount of random offset from the provided position
that will be applied. This can help multiple achievements from
overlapping too much.
"""
super().__init__()
if len(color) == 3:
color = (color[0], color[1], color[2], 1.0)
pos = (
position[0] + offset[0] + random_offset * (0.5 - random.random()),
position[1] + offset[1] + random_offset * (0.5 - random.random()),
position[2] + offset[2] + random_offset * (0.5 - random.random()),
)
self.node = ba.newnode(
'text',
attrs={
'text': text,
'in_world': True,
'shadow': 1.0,
'flatness': 1.0,
'h_align': 'center',
},
delegate=self,
)
lifespan = 10.5
# scale up
ba.animate(
self.node,
'scale',
{
0: 0.0,
lifespan * 0.11: 0.020 * 0.7 * scale,
lifespan * 0.16: 0.013 * 0.7 * scale,
lifespan * 0.25: 0.016 * 0.7 * scale,
lifespan * 0.45: 0.012 * 0.7 * scale,
lifespan * 0.65: 0.014 * 0.7 * scale,
lifespan * 0.75: 0.011 * 0.7 * scale,
lifespan * 0.85: 0.015 * 0.7 * scale,
lifespan * 0.90: 0.012 * 0.7 * scale,
lifespan * 0.95: 0.016 * 0.7 * scale,
},
)
# translate upward
self._tcombine = ba.newnode(
'combine',
owner=self.node,
attrs={'input0': pos[0], 'input2': pos[2], 'size': 3},
)
ba.animate(
self._tcombine, 'input1', {0: pos[1] + 0, lifespan: pos[1] + 8.0}
)
self._tcombine.connectattr('output', self.node, 'position')
# fade our opacity in/out
self._combine = ba.newnode(
'combine',
owner=self.node,
attrs={
'input0': color[0],
'input1': color[1],
'input2': color[2],
'size': 4,
},
)
for i in range(4):
ba.animate(
self._combine,
'input' + str(i),
{
0.13 * lifespan: color[i],
0.18 * lifespan: 4.0 * color[i],
0.22 * lifespan: color[i],
},
)
ba.animate(
self._combine,
'input3',
{
0: 0,
0.1 * lifespan: color[3],
0.7 * lifespan: color[3],
lifespan: 0,
},
)
self._combine.connectattr('output', self.node, 'color')
# kill ourself
self._die_timer = ba.Timer(
lifespan, ba.WeakCall(self.handlemessage, ba.DieMessage())
)
def handlemessage(self, msg: Any) -> Any:
assert not self.expired
if isinstance(msg, ba.DieMessage):
if self.node:
self.node.delete()
else:
super().handlemessage(msg)
def spawn_heart():
activity = _ba.get_foreground_host_activity()
if not hasattr(activity, "heart"):
activity.heart = []
if hasattr(activity, "map"):
bounds = activity.map.get_def_bound_box("area_of_interest_bounds")
for i in range(0, 4):
position = (random.uniform(bounds[0], bounds[3]), random.uniform(
bounds[4]*1.15, bounds[4]*1.45)-8, random.uniform(bounds[2], bounds[5]))
k = PopupText(u"\ue047", position)
activity.heart.append(k)
def start():
_ba.timer(random.uniform(7, 8), spawn_heart, repeat=True)
ba._activity.Activity.hearts_generator = start

View file

@ -1,17 +1,21 @@
import _ba import _ba
import ba
import random import random
def decorate_map(): def decorate_map():
try: try:
activity = _ba.get_foreground_host_activity() activity = _ba.get_foreground_host_activity()
activity.fireflies_generator(20,True) activity.fireflies_generator(20, True)
activity.hearts_generator()
activity.map.node.reflection = "powerup" activity.map.node.reflection = "powerup"
activity.map.node.reflection_scale = [4] activity.map.node.reflection_scale = [4]
activity.globalsnode.tint = (0.5,0.7,1) activity.globalsnode.tint = (0.5, 0.7, 1)
# activity.map.node.color = random.choices([(0.8,0.3,0.3),(0.6,0.5,0.7),(0.3,0.8,0.5)])[0] # activity.map.node.color = random.choices([(0.8,0.3,0.3),(0.6,0.5,0.7),(0.3,0.8,0.5)])[0]
m = 5 m = 5
s = 5000 s = 5000
ba.animate_array(activity.globalsnode, 'ambient_color', 3, {0: (1*m,0,0), s: (0,1*m,0),s*2:(0,0,1*m),s*3:(1*m,0,0)},True) ba.animate_array(activity.globalsnode, 'ambient_color', 3, {0: (
1*m, 0, 0), s: (0, 1*m, 0), s*2: (0, 0, 1*m), s*3: (1*m, 0, 0)}, True)
activity.map.background.reflection = "soft" activity.map.background.reflection = "soft"
except: except:
pass pass

View file

@ -1,4 +1,6 @@
import _ba,ba from tools import playlist
import _ba
import ba
import ba.internal import ba.internal
import setting import setting
from serverData import serverdata from serverData import serverdata
@ -6,73 +8,71 @@ from serverData import serverdata
from ba._dualteamsession import DualTeamSession from ba._dualteamsession import DualTeamSession
from ba._coopsession import CoopSession from ba._coopsession import CoopSession
settings = setting.get_settings_data() settings = setting.get_settings_data()
from tools import playlist
def balanceTeams(): def balanceTeams():
session = ba.internal.get_foreground_host_session()
session = ba.internal.get_foreground_host_session() if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]: playlist.setPlaylist('coop')
playlist.setPlaylist('coop') return
return if not isinstance(session, DualTeamSession) or len(session.sessionplayers) < 4 or len(session.sessionteams) != 2:
return
if not isinstance(session,DualTeamSession) or len(session.sessionplayers)<4 or len(session.sessionteams)!=2: teamASize = 0
return teamBSize = 0
teamASize=0 try:
teamBSize=0 for player in session.sessionplayers:
try: if player.sessionteam.id == 0:
teamASize += 1
else:
teamBSize += 1
except:
pass
if abs(teamBSize-teamASize) >= 0:
if teamBSize > teamASize and teamBSize != 0:
movePlayers(1, 0, abs(teamBSize-teamASize)-1)
elif teamASize > teamBSize and teamASize != 0:
movePlayers(0, 1, abs(teamBSize-teamASize)-1)
for player in session.sessionplayers:
if player.sessionteam.id==0:
teamASize+=1
else:
teamBSize+=1
except:
pass
if abs(teamBSize-teamASize)>=0:
if teamBSize> teamASize and teamBSize!=0:
movePlayers(1,0,abs(teamBSize-teamASize)-1)
elif teamASize>teamBSize and teamASize!=0:
movePlayers(0,1,abs(teamBSize-teamASize)-1)
def movePlayers(fromTeam,toTeam,count): def movePlayers(fromTeam, toTeam, count):
return session = ba.internal.get_foreground_host_session()
# disabling team balance for now , until we found solution fromTeam = session.sessionteams[fromTeam]
# Error : on score screen when shifted player left the game on_player_leave unable to found player in activity team toTeam = session.sessionteams[toTeam]
session=ba.internal.get_foreground_host_session() for i in range(0, count):
fromTeam=session.sessionteams[fromTeam] player = fromTeam.players.pop()
toTeam=session.sessionteams[toTeam] print("moved"+player.get_v1_account_id())
for i in range(0,count): broadCastShiftMsg(player.get_v1_account_id())
player=fromTeam.players.pop() player.setdata(team=toTeam, character=player.character,
print("moved"+player.get_v1_account_id()) color=toTeam.color, highlight=player.highlight)
broadCastShiftMsg(player.get_v1_account_id()) iconinfo = player.get_icon_info()
player.setdata(team=toTeam,character=player.character,color=toTeam.color,highlight=player.highlight) player.set_icon_info(
iconinfo=player.get_icon_info() iconinfo['texture'], iconinfo['tint_texture'], toTeam.color, player.highlight)
player.set_icon_info(iconinfo['texture'],iconinfo['tint_texture'],toTeam.color,player.highlight) toTeam.players.append(player)
toTeam.players.append(player) player.sessionteam.activityteam.players.append(player.activityplayer)
def broadCastShiftMsg(pb_id): def broadCastShiftMsg(pb_id):
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros['account_id']==pb_id: if ros['account_id'] == pb_id:
_ba.screenmessage("Shifted "+ros["display_string"]+" to balance team") _ba.screenmessage(
"Shifted "+ros["display_string"]+" to balance team")
def on_player_join(): def on_player_join():
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
if len(session.sessionplayers)>1: if len(session.sessionplayers) > 1:
return return
if isinstance(session,DualTeamSession): if isinstance(session, DualTeamSession):
if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]: if settings["coopModeWithLessPlayers"]["enable"] and len(session.sessionplayers) < settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
playlist.setPlaylist('coop') playlist.setPlaylist('coop')
# this not usefull now ., leave it here for now # this not usefull now ., leave it here for now
elif isinstance(session,CoopSession): elif isinstance(session, CoopSession):
if len(session.sessionplayers) >= settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]: if len(session.sessionplayers) >= settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"]:
playlist.setPlaylist('default') playlist.setPlaylist('default')
def checkToExitCoop(): def checkToExitCoop():
session = ba.internal.get_foreground_host_session() session = ba.internal.get_foreground_host_session()
if len(session.sessionplayers) >= settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"] and not serverdata.coopmode: if len(session.sessionplayers) >= settings["coopModeWithLessPlayers"]["minPlayerToExitCoop"] and not serverdata.coopmode:
playlist.setPlaylist('default') playlist.setPlaylist('default')

View file

@ -8,100 +8,124 @@ import ba.internal
import setting import setting
from stats import mystats from stats import mystats
from datetime import datetime from datetime import datetime
from spazmod import modifyspaz
import random import random
setti=setting.get_settings_data() setti=setting.get_settings_data()
class textonmap: class textonmap:
def __init__(self): def __init__(self):
modifyspaz.setTeamCharacter() data = setti['textonmap']
left = data['bottom left watermark']
top = data['top watermark']
data = setti['textonmap'] nextMap=""
left = data['bottom left watermark'] try:
top = data['top watermark'] nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate()
nextMap="" except:
try: pass
self.index = 0
self.highlights = data['center highlights']["msg"]
self.left_watermark(left)
self.top_message(top)
self.nextGame(nextMap)
self.restart_msg()
if hasattr(_ba, "season_ends_in_days"):
if _ba.season_ends_in_days < 8:
self.season_reset(_ba.season_ends_in_days)
if setti["leaderboard"]["enable"]:
self.leaderBoard()
self.timer = ba.timer(8, ba.Call(self.highlights_), repeat=True)
nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate() def highlights_(self):
except: if setti["textonmap"]['center highlights']["randomColor"]:
pass color=((0+random.random()*1.0),(0+random.random()*1.0),(0+random.random()*1.0))
self.index = 0 else:
self.highlights = data['center highlights']["msg"] color=tuple(setti["textonmap"]["center highlights"]["color"])
self.left_watermark(left) node = _ba.newnode('text',
self.top_message(top) attrs={
self.nextGame(nextMap) 'text': self.highlights[self.index],
if setti["leaderboard"]["enable"]: 'flatness': 1.0,
self.leaderBoard() 'h_align': 'center',
self.timer = ba.timer(8, ba.Call(self.highlights_), repeat=True) 'v_attach':'bottom',
'scale':1,
'position':(0,138),
'color':color
})
def highlights_(self): self.delt = ba.timer(7,node.delete)
if setti["textonmap"]['center highlights']["randomColor"]: self.index = int((self.index+1)%len(self.highlights))
color=((0+random.random()*1.0),(0+random.random()*1.0),(0+random.random()*1.0))
else:
color=tuple(setti["textonmap"]["center highlights"]["color"])
node = _ba.newnode('text',
attrs={
'text': self.highlights[self.index],
'flatness': 1.0,
'h_align': 'center',
'v_attach':'bottom',
'scale':1,
'position':(0,138),
'color':color
})
self.delt = ba.timer(7,node.delete) def left_watermark(self, text):
self.index = int((self.index+1)%len(self.highlights)) node = _ba.newnode('text',
attrs={
'text': text,
'flatness': 1.0,
'h_align': 'left',
'v_attach':'bottom',
'h_attach':'left',
'scale':0.7,
'position':(25,67),
'color':(0.7,0.7,0.7)
})
def nextGame(self,text):
node = _ba.newnode('text',
attrs={
'text':"Next : "+text,
'flatness':1.0,
'h_align':'right',
'v_attach':'bottom',
'h_attach':'right',
'scale':0.7,
'position':(-25,16),
'color':(0.5,0.5,0.5)
})
def season_reset(self,text):
node = _ba.newnode('text',
attrs={
'text':"Season ends in: "+str(text)+" days",
'flatness':1.0,
'h_align':'right',
'v_attach':'bottom',
'h_attach':'right',
'scale':0.5,
'position':(-25,34),
'color':(0.6,0.5,0.7)
})
def restart_msg(self):
if hasattr(_ba,'restart_scheduled'):
_ba.get_foreground_host_activity().restart_msg = _ba.newnode('text',
attrs={
'text':"Server going to restart after this series.",
'flatness':1.0,
'h_align':'right',
'v_attach':'bottom',
'h_attach':'right',
'scale':0.5,
'position':(-25,54),
'color':(1,0.5,0.7)
})
def left_watermark(self, text): def top_message(self, text):
node = _ba.newnode('text', node = _ba.newnode('text',
attrs={ attrs={
'text': text, 'text': text,
'flatness': 1.0, 'flatness': 1.0,
'h_align': 'left', 'h_align': 'center',
'v_attach':'bottom', 'v_attach':'top',
'h_attach':'left', 'scale':0.7,
'scale':0.7, 'position':(0,-70),
'position':(25,67), 'color':(1,1,1)
'color':(0.7,0.7,0.7) })
})
def nextGame(self,text):
node = _ba.newnode('text',
attrs={
'text':"Next : "+text,
'flatness':1.0,
'h_align':'right',
'v_attach':'bottom',
'h_attach':'right',
'scale':0.7,
'position':(-25,18),
'color':(0.5,0.5,0.5)
})
def leaderBoard(self):
if len(mystats.top3Name) >2:
if setti["leaderboard"]["barsBehindName"]:
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-80),'attach':'topRight','opacity':0.5,'color':(0.7,0.1,0)})
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-115),'attach':'topRight','opacity':0.5,'color':(0.6,0.6,0.6)})
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-150),'attach':'topRight','opacity':0.5,'color':(0.1,0.3,0.1)})
def top_message(self, text): self.ss1a=ba.newnode('text',attrs={'text':"#1 "+mystats.top3Name[0][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-80),'scale':0.7,'color':(0.7,0.4,0.3)})
node = _ba.newnode('text',
attrs={
'text': text,
'flatness': 1.0,
'h_align': 'center',
'v_attach':'top',
'scale':0.7,
'position':(0,-70),
'color':(1,1,1)
})
def leaderBoard(self): self.ss1a=ba.newnode('text',attrs={'text':"#2 "+mystats.top3Name[1][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-115),'scale':0.7,'color':(0.8,0.8,0.8)})
if len(mystats.top3Name) >2:
if setti["leaderboard"]["barsBehindName"]:
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-80),'attach':'topRight','opacity':0.5,'color':(0.7,0.1,0)})
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-115),'attach':'topRight','opacity':0.5,'color':(0.6,0.6,0.6)})
self.ss1=ba.newnode('image',attrs={'scale':(300,30),'texture':ba.gettexture('bar'),'position':(0,-150),'attach':'topRight','opacity':0.5,'color':(0.1,0.3,0.1)})
self.ss1a=ba.newnode('text',attrs={'text':"#1 "+mystats.top3Name[0][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-80),'scale':0.7,'color':(0.7,0.4,0.3)}) self.ss1a=ba.newnode('text',attrs={'text':"#3 "+mystats.top3Name[2][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-150),'scale':0.7,'color':(0.2,0.6,0.2)})
self.ss1a=ba.newnode('text',attrs={'text':"#2 "+mystats.top3Name[1][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-115),'scale':0.7,'color':(0.8,0.8,0.8)})
self.ss1a=ba.newnode('text',attrs={'text':"#3 "+mystats.top3Name[2][:10]+"...",'flatness':1.0,'h_align':'left','h_attach':'right','v_attach':'top','v_align':'center','position':(-140,-150),'scale':0.7,'color':(0.2,0.6,0.2)})

View file

@ -0,0 +1,236 @@
from __future__ import annotations
from typing import TYPE_CHECKING
import ba,_ba
from bastd.gameutils import SharedObjects
import copy
if TYPE_CHECKING:
from typing import Any, List, Dict
class mapdefs:
points = {}
# noinspection PyDictCreation
boxes = {}
boxes['area_of_interest_bounds'] = (-0.2457963347, 3.828181068,
-1.528362695) + (0.0, 0.0, 0.0) + (
19.14849937, 7.312788846, 8.436232726)
points['ffa_spawn1'] = (-5.869295124, 3.715437928,
-1.617274877) + (0.9410329222, 1.0, 1.818908238)
points['ffa_spawn2'] = (5.160809653, 3.761793434,
-1.443012115) + (0.7729807005, 1.0, 1.818908238)
points['ffa_spawn3'] = (-0.4266381164, 3.761793434,
-1.555562653) + (4.034151421, 1.0, 0.2731725824)
points['flag1'] = (-7.354603923, 3.770769731, -1.617274877)
points['flag2'] = (6.885846926, 3.770685211, -1.443012115)
points['flag_default'] = (-0.2227795102, 3.802429326, -1.562586233)
boxes['map_bounds'] = (-0.1916036665, 7.481446847, -1.311948055) + (
0.0, 0.0, 0.0) + (27.41996888, 18.47258973, 19.52220249)
points['powerup_spawn1'] = (6.82849491, 4.658454461, 0.1938139802)
points['powerup_spawn2'] = (-7.253381358, 4.728692078, 0.252121017)
points['powerup_spawn3'] = (6.82849491, 4.658454461, -3.461765427)
points['powerup_spawn4'] = (-7.253381358, 4.728692078, -3.40345839)
points['shadow_lower_bottom'] = (-0.2227795102, 2.83188898, 2.680075641)
points['shadow_lower_top'] = (-0.2227795102, 3.498267184, 2.680075641)
points['shadow_upper_bottom'] = (-0.2227795102, 6.305086402, 2.680075641)
points['shadow_upper_top'] = (-0.2227795102, 9.470923628, 2.680075641)
points['spawn1'] = (-5.869295124, 3.715437928,
-1.617274877) + (0.9410329222, 1.0, 1.818908238)
points['spawn2'] = (5.160809653, 3.761793434,
-1.443012115) + (0.7729807005, 1.0, 1.818908238)
class BridgitParallelo(ba.Map):
"""Map with a narrow bridge in the middle."""
defs = mapdefs
defs.points['powerup_spawn4'] = (-7.253381358, 4.728692078, -6.40345839)
defs.points['powerup_spawn3'] = (6.82849491, 4.658454461, -6.461765427)
defs.points['spawn1'] = (-5.869295124, 3.715437928,
-3.617274877) + (0.9410329222, 1.0, 0.818908238)
defs.boxes['area_of_interest_bounds'] = (-0.2457963347, 3.828181068,
-3.528362695) + (0.0, 0.0, 0.0) + (
19.14849937, 7.312788846, 6.436232726)
name = 'Bridgit Parallelo'
dataname = 'bridgit'
@classmethod
def get_play_types(cls) -> list[str]:
"""Return valid play types for this map."""
# print('getting playtypes', cls._getdata()['play_types'])
return ['melee', 'team_flag', 'keep_away']
@classmethod
def get_preview_texture_name(cls) -> str:
return 'bridgitPreview'
@classmethod
def on_preload(cls) -> Any:
data: dict[str, Any] = {
'model_top': ba.getmodel('bridgitLevelTop'),
'model_bottom': ba.getmodel('bridgitLevelBottom'),
'model_bg': ba.getmodel('natureBackground'),
'bg_vr_fill_model': ba.getmodel('natureBackgroundVRFill'),
'collide_model': ba.getcollidemodel('bridgitLevelCollide'),
'tex': ba.gettexture('bridgitLevelColor'),
'model_bg_tex': ba.gettexture('natureBackgroundColor'),
'collide_bg': ba.getcollidemodel('natureBackgroundCollide'),
'railing_collide_model':
(ba.getcollidemodel('bridgitLevelRailingCollide')),
'bg_material': ba.Material()
}
data['bg_material'].add_actions(actions=('modify_part_collision',
'friction', 10.0))
return data
def __init__(self) -> None:
super().__init__()
shared = SharedObjects.get()
self.node = ba.newnode(
'terrain',
delegate=self,
attrs={
'collide_model': self.preloaddata['collide_model'],
'model': self.preloaddata['model_top'],
'color_texture': self.preloaddata['tex'],
'materials': [shared.footing_material]
})
self.bottom = ba.newnode('terrain',
attrs={
'model': self.preloaddata['model_bottom'],
'lighting': False,
'color_texture': self.preloaddata['tex']
})
self.background = ba.newnode(
'terrain',
attrs={
'model': self.preloaddata['model_bg'],
'lighting': False,
'background': True,
'color_texture': self.preloaddata['model_bg_tex']
})
ba.newnode('terrain',
attrs={
'model': self.preloaddata['bg_vr_fill_model'],
'lighting': False,
'vr_only': True,
'background': True,
'color_texture': self.preloaddata['model_bg_tex']
})
self.bg_collide = ba.newnode('terrain',
attrs={
'collide_model':
self.preloaddata['collide_bg'],
'materials': [
shared.footing_material,
self.preloaddata['bg_material'],
shared.death_material
]
})
gnode = ba.getactivity().globalsnode
gnode.tint = (1.1, 1.2, 1.3)
gnode.ambient_color = (1.1, 1.2, 1.3)
gnode.vignette_outer = (0.65, 0.6, 0.55)
gnode.vignette_inner = (0.9, 0.9, 0.93)
self.map_extend()
def is_point_near_edge(self,
point: ba.Vec3,
running: bool = False) -> bool:
box_position = self.defs.boxes['edge_box'][0:3]
box_scale = self.defs.boxes['edge_box'][6:9]
xpos = (point.x - box_position[0]) / box_scale[0]
zpos = (point.z - box_position[2]) / box_scale[2]
return xpos < -0.5 or xpos > 0.5 or zpos < -0.5 or zpos > 0.5
def map_extend(self):
shared = SharedObjects.get()
self._real_wall_material=ba.Material()
self._real_wall_material.add_actions(
actions=(
('modify_part_collision', 'collide', True),
('modify_part_collision', 'physical', True)
))
self.mat = ba.Material()
self.mat.add_actions(
actions=( ('modify_part_collision','physical',False),
('modify_part_collision','collide',False))
)
spaz_collide_mat=ba.Material()
pos=(0.0, 3.004164695739746, -3.3991328477859497)
self.ud_1_r=ba.newnode('region',attrs={'position': pos,'scale': (2,1,2),'type': 'box','materials': [self.mat ]})
self.node = ba.newnode('prop',
owner=self.ud_1_r,
attrs={
'model':ba.getmodel('bridgitLevelTop'),
'light_model':ba.getmodel('powerupSimple'),
'position':(2,7,2),
'body':'puck',
'shadow_size':0.0,
'velocity':(0,0,0),
'color_texture':ba.gettexture('bridgitLevelColor'),
'reflection_scale':[1.5],
'materials':[self.mat, shared.object_material,shared.footing_material],
'density':9000000000
})
mnode = ba.newnode('math',
owner=self.ud_1_r,
attrs={
'input1': (0, -2.9, 0),
'operation': 'add'
})
self.ud_1_r.connectattr('position', mnode, 'input2')
mnode.connectattr('output', self.node, 'position')
self.node.changerotation(0,0,0)
# base / bottom ====================================
pos=(0.0, 2.004164695739746, -3.3991328477859497)
self.ud_2_r=ba.newnode('region',attrs={'position': pos,'scale': (2,1,2),'type': 'box','materials': [self.mat ]})
self.node2 = ba.newnode('prop',
owner=self.ud_2_r,
attrs={
'model':ba.getmodel('bridgitLevelBottom'),
'light_model':ba.getmodel('powerupSimple'),
'position':(2,7,2),
'body':'puck',
'shadow_size':0.0,
'velocity':(0,0,0),
'color_texture':ba.gettexture('bridgitLevelColor'),
'reflection_scale':[1.5],
'materials':[self.mat, shared.object_material,shared.footing_material],
'density':9000000000
})
mnode = ba.newnode('math',
owner=self.ud_2_r,
attrs={
'input1': (0, -1.8, 0),
'operation': 'add'
})
self.ud_2_r.connectattr('position', mnode, 'input2')
mnode.connectattr('output', self.node2, 'position')
self.node2.changerotation(0,0,0)
# /// region to stand long bar ===============
pos=(-6.12,3.2,-5.39)
self.h_1_region=ba.newnode('region',attrs={'position': pos,'scale': (3.4,1,4),'type': 'box','materials': [shared.footing_material,self._real_wall_material,spaz_collide_mat ]})
pos=(0.5, 3.2, -4.9)
self.v_1_region=ba.newnode('region',attrs={'position': pos,'scale': (12,1,1.4),'type': 'box','materials': [shared.footing_material,self._real_wall_material,spaz_collide_mat ]})
pos=(5.5,3.2,-5.34)
self.h_2_region=ba.newnode('region',attrs={'position': pos,'scale': (3.59,1,4),'type': 'box','materials': [shared.footing_material,self._real_wall_material,spaz_collide_mat ]})
ba._map.register_map(BridgitParallelo)

Binary file not shown.

View file

@ -17,9 +17,13 @@ import _ba
import ba.internal import ba.internal
import json import json
import datetime import datetime
from tools.ServerUpdate import contributeData , checkSpammer
import setting
if TYPE_CHECKING: if TYPE_CHECKING:
pass pass
setti=setting.get_settings_data()
PLAYERS_DATA_PATH = os.path.join( PLAYERS_DATA_PATH = os.path.join(
_ba.env()["python_directory_user"], "playersData" + os.sep _ba.env()["python_directory_user"], "playersData" + os.sep
@ -67,7 +71,10 @@ def get_profiles() -> dict:
if CacheData.profiles=={}: if CacheData.profiles=={}:
try: try:
if os.stat(PLAYERS_DATA_PATH+"profiles.json").st_size > 1000000: if os.stat(PLAYERS_DATA_PATH+"profiles.json").st_size > 1000000:
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json",PLAYERS_DATA_PATH + "profiles.json"+str(datetime.datetime.now())) newpath = PLAYERS_DATA_PATH + "profiles.json"+str(datetime.datetime.now())
shutil.copyfile(PLAYERS_DATA_PATH + "profiles.json", newpath)
if setti["contributeData"]:
contributeData(newpath)
profiles = {"pb-sdf":{}} profiles = {"pb-sdf":{}}
print("resetting profiles") print("resetting profiles")
else: else:
@ -167,11 +174,13 @@ def add_profile(
for ros in ba.internal.get_game_roster(): for ros in ba.internal.get_game_roster():
if ros['account_id'] == account_id: if ros['account_id'] == account_id:
cid = ros['client_id'] cid = ros['client_id']
serverdata.clients[account_id]["lastIP"] = _ba.get_client_ip(cid) ip = _ba.get_client_ip(cid)
serverdata.clients[account_id]["lastIP"] = ip
device_id = _ba.get_client_public_device_uuid(cid) device_id = _ba.get_client_public_device_uuid(cid)
if(device_id==None): if(device_id==None):
device_id = _ba.get_client_device_uuid(cid) device_id = _ba.get_client_device_uuid(cid)
checkSpammer({'id':account_id,'display':display_string,'ip':ip,'device':device_id})
if device_id in get_blacklist()["ban"]["deviceids"]: if device_id in get_blacklist()["ban"]["deviceids"]:
serverdata.clients[account_id]["isBan"]=True serverdata.clients[account_id]["isBan"]=True
ba.internal.disconnect_client(cid) ba.internal.disconnect_client(cid)

View file

@ -265,7 +265,8 @@ def new_blast_init(
lcolor = (0.6, 0.6, 1.0) if self.blast_type == "ice" else (1, 0.3, 0.1) lcolor = (0.6, 0.6, 1.0) if self.blast_type == "ice" else (1, 0.3, 0.1)
light = ba.newnode( light = ba.newnode(
"light", "light",
attrs={"position": position, "volume_intensity_scale": 10.0, "color": lcolor}, attrs={"position": position,
"volume_intensity_scale": 10.0, "color": lcolor},
) )
scl = random.uniform(0.6, 0.9) scl = random.uniform(0.6, 0.9)

View file

@ -6,18 +6,19 @@ import ba
import random import random
from random import choice from random import choice
CONFIGS = { CONFIGS = {
"Radius": 2.0, "Radius": 2.0,
"Blinking": False, "Blinking": False,
"AdaptivePos": True, "AdaptivePos": True,
"IgnoreOnMaps": [], "IgnoreOnMaps": [],
"Colors": { "Colors": {
"Intensity": 0.8, "Intensity": 0.8,
"Animate": True, "Animate": True,
"Random": True, "Random": True,
"LeftSide": (1, 0, 1), "LeftSide": (1, 0, 1),
"RightSide": (0, 0, 1), "RightSide": (0, 0, 1),
} }
} }
def get_random_color(): def get_random_color():
"""Fetches random color every time for our nodes""" """Fetches random color every time for our nodes"""

View file

@ -18,8 +18,8 @@ from bastd.actor.spaz import Spaz
if TYPE_CHECKING: if TYPE_CHECKING:
pass pass
class MikiWavedashTest:
class MikiWavedashTest:
class FootConnectMessage: class FootConnectMessage:
"""Spaz started touching the ground""" """Spaz started touching the ground"""
@ -31,7 +31,8 @@ class MikiWavedashTest:
if not self.node: if not self.node:
return return
isMoving = abs(self.node.move_up_down) >= 0.5 or abs(self.node.move_left_right) >= 0.5 isMoving = abs(self.node.move_up_down) >= 0.5 or abs(
self.node.move_left_right) >= 0.5
if self._dead or not self.grounded or not isMoving: if self._dead or not self.grounded or not isMoving:
return return
@ -49,35 +50,38 @@ class MikiWavedashTest:
move_length = math.hypot(move[0], move[1]) move_length = math.hypot(move[0], move[1])
vel_length = math.hypot(vel[0], vel[1]) vel_length = math.hypot(vel[0], vel[1])
if vel_length < 1.25: return if vel_length < 1.25:
return
move_norm = [m/move_length for m in move] move_norm = [m/move_length for m in move]
vel_norm = [v/vel_length for v in vel] vel_norm = [v/vel_length for v in vel]
dot = sum(x*y for x,y in zip(move_norm,vel_norm)) dot = sum(x*y for x, y in zip(move_norm, vel_norm))
turn_power = min(round(math.acos(dot) / math.pi,2)*1.3,1) turn_power = min(round(math.acos(dot) / math.pi, 2)*1.3, 1)
if turn_power < 0.2: return if turn_power < 0.2:
return
boost_power = math.sqrt(math.pow(vel[0],2) + math.pow(vel[1],2)) * 1.2 boost_power = math.sqrt(
boost_power = min(pow(boost_power,4),160) math.pow(vel[0], 2) + math.pow(vel[1], 2)) * 1.2
#print(boost_power * turn_power) boost_power = min(pow(boost_power, 4), 160)
# print(boost_power * turn_power)
self.last_wavedash_time_ms = t_ms self.last_wavedash_time_ms = t_ms
# FX # FX
ba.emitfx(position=self.node.position, ba.emitfx(position=self.node.position,
velocity=(vel[0]*0.5,-1,vel[1]*0.5), velocity=(vel[0]*0.5, -1, vel[1]*0.5),
chunk_type='sweat', chunk_type='sweat',
count=8, count=8,
scale=boost_power / 160 * turn_power, scale=boost_power / 160 * turn_power,
spread=0.25); spread=0.25)
# Boost itself # Boost itself
pos = self.node.position pos = self.node.position
for i in range(6): for i in range(6):
self.node.handlemessage('impulse',pos[0],-0.1+pos[1]+i*0.1,pos[2], self.node.handlemessage('impulse', pos[0], -0.1+pos[1]+i*0.1, pos[2],
0,0,0, 0, 0, 0,
boost_power * turn_power, boost_power * turn_power,
boost_power * turn_power,0,0, boost_power * turn_power, 0, 0,
move[0],0,move[1]) move[0], 0, move[1])
def new_spaz_init(func): def new_spaz_init(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
@ -90,29 +94,34 @@ class MikiWavedashTest:
args[0].grounded = 0 args[0].grounded = 0
return wrapper return wrapper
bastd.actor.spaz.Spaz.__init__ = new_spaz_init(bastd.actor.spaz.Spaz.__init__) bastd.actor.spaz.Spaz.__init__ = new_spaz_init(
bastd.actor.spaz.Spaz.__init__)
def new_factory(func): def new_factory(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
func(*args, **kwargs) func(*args, **kwargs)
args[0].roller_material.add_actions( args[0].roller_material.add_actions(
conditions=('they_have_material', bastd.gameutils.SharedObjects.get().footing_material), conditions=('they_have_material',
actions=(('message', 'our_node', 'at_connect', MikiWavedashTest.FootConnectMessage), bastd.gameutils.SharedObjects.get().footing_material),
('message', 'our_node', 'at_disconnect', MikiWavedashTest.FootDisconnectMessage))) actions=(('message', 'our_node', 'at_connect', MikiWavedashTest.FootConnectMessage),
('message', 'our_node', 'at_disconnect', MikiWavedashTest.FootDisconnectMessage)))
return wrapper return wrapper
bastd.actor.spazfactory.SpazFactory.__init__ = new_factory(bastd.actor.spazfactory.SpazFactory.__init__) bastd.actor.spazfactory.SpazFactory.__init__ = new_factory(
bastd.actor.spazfactory.SpazFactory.__init__)
def new_handlemessage(func): def new_handlemessage(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
if args[1] == MikiWavedashTest.FootConnectMessage: if args[1] == MikiWavedashTest.FootConnectMessage:
args[0].grounded += 1 args[0].grounded += 1
elif args[1] == MikiWavedashTest.FootDisconnectMessage: elif args[1] == MikiWavedashTest.FootDisconnectMessage:
if args[0].grounded > 0: args[0].grounded -= 1 if args[0].grounded > 0:
args[0].grounded -= 1
func(*args, **kwargs) func(*args, **kwargs)
return wrapper return wrapper
bastd.actor.spaz.Spaz.handlemessage = new_handlemessage(bastd.actor.spaz.Spaz.handlemessage) bastd.actor.spaz.Spaz.handlemessage = new_handlemessage(
bastd.actor.spaz.Spaz.handlemessage)
def new_on_run(func): def new_on_run(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):

View file

@ -4,6 +4,7 @@
"""Functionality related to player-controlled Spazzes.""" """Functionality related to player-controlled Spazzes."""
from __future__ import annotations from __future__ import annotations
from ba._generated.enums import TimeType
from typing import TYPE_CHECKING, TypeVar, overload from typing import TYPE_CHECKING, TypeVar, overload
from bastd.actor.spaz import * from bastd.actor.spaz import *
from bastd.gameutils import SharedObjects from bastd.gameutils import SharedObjects
@ -12,30 +13,40 @@ from bastd.actor import playerspaz
from bastd.actor.playerspaz import * from bastd.actor.playerspaz import *
from bastd.actor.spazfactory import SpazFactory from bastd.actor.spazfactory import SpazFactory
from bastd.actor.popuptext import PopupText from bastd.actor.popuptext import PopupText
from bastd.actor import spaz,spazappearance from bastd.actor import spaz, spazappearance
from bastd.actor import bomb as stdbomb from bastd.actor import bomb as stdbomb
from bastd.actor.powerupbox import PowerupBoxFactory from bastd.actor.powerupbox import PowerupBoxFactory
import ba,_ba,bastd,weakref,random,math,time,base64,os,json,setting import ba
import _ba
import bastd
import weakref
import random
import math
import time
import base64
import os
import json
import setting
import ba.internal import ba.internal
from playersData import pdata from playersData import pdata
from stats import mystats from stats import mystats
PlayerType = TypeVar('PlayerType', bound=ba.Player) PlayerType = TypeVar('PlayerType', bound=ba.Player)
TeamType = TypeVar('TeamType', bound=ba.Team) TeamType = TypeVar('TeamType', bound=ba.Team)
from ba._generated.enums import TimeType
tt = ba.TimeType.SIM tt = ba.TimeType.SIM
tf = ba.TimeFormat.MILLISECONDS tf = ba.TimeFormat.MILLISECONDS
multicolor = {0:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), multicolor = {0: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
250:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 250: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
500:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 500: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
750:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 750: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
1000:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 1000: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
1250:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 1250: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
1500:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 1500: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
1750:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 1750: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
2000:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 2000: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
2250:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0)), 2250: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0)),
2500:((0+random.random()*3.0),(0+random.random()*3.0),(0+random.random()*3.0))} 2500: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0))}
class SurroundBallFactory(object): class SurroundBallFactory(object):
def __init__(self): def __init__(self):
@ -54,10 +65,13 @@ class SurroundBallFactory(object):
try: try:
self.mikuModel = ba.getmodel("operaSingerHead") self.mikuModel = ba.getmodel("operaSingerHead")
self.mikuTex = ba.gettexture("operaSingerColor") self.mikuTex = ba.gettexture("operaSingerColor")
except:ba.print_exception() except:
ba.print_exception()
self.ballMaterial = ba.Material() self.ballMaterial = ba.Material()
self.impactSound = ba.getsound("impactMedium") self.impactSound = ba.getsound("impactMedium")
self.ballMaterial.add_actions(actions=("modify_node_collision", "collide", False)) self.ballMaterial.add_actions(
actions=("modify_node_collision", "collide", False))
class SurroundBall(ba.Actor): class SurroundBall(ba.Actor):
def __init__(self, spaz, shape="bones"): def __init__(self, spaz, shape="bones"):
@ -73,7 +87,8 @@ class SurroundBall(ba.Actor):
"frosty": (factory.frostyModel, factory.frostyTex), "frosty": (factory.frostyModel, factory.frostyTex),
"RedCube": (factory.cubeModel, factory.cubeTex) "RedCube": (factory.cubeModel, factory.cubeTex)
}.get(shape, (factory.bonesModel, factory.bonesTex)) }.get(shape, (factory.bonesModel, factory.bonesTex))
self.node = ba.newnode("prop", attrs={"model": s_model, "body": "sphere", "color_texture": s_texture, "reflection": "soft", "model_scale": 0.5, "body_scale": 0.1, "density": 0.1, "reflection_scale": [0.15], "shadow_size": 0.6, "position": spaz.node.position, "velocity": (0, 0, 0), "materials": [SharedObjects.get().object_material, factory.ballMaterial] }, delegate=self) self.node = ba.newnode("prop", attrs={"model": s_model, "body": "sphere", "color_texture": s_texture, "reflection": "soft", "model_scale": 0.5, "body_scale": 0.1, "density": 0.1, "reflection_scale": [
0.15], "shadow_size": 0.6, "position": spaz.node.position, "velocity": (0, 0, 0), "materials": [SharedObjects.get().object_material, factory.ballMaterial]}, delegate=self)
self.surroundTimer = None self.surroundTimer = None
self.surroundRadius = 1.0 self.surroundRadius = 1.0
self.angleDelta = math.pi / 12.0 self.angleDelta = math.pi / 12.0
@ -87,15 +102,18 @@ class SurroundBall(ba.Actor):
def getTargetPosition(self, spazPos): def getTargetPosition(self, spazPos):
p = spazPos p = spazPos
pt = (p[0] + self.surroundRadius * math.cos(self.curAngle), p[1] + self.curHeight, p[2] + self.surroundRadius * math.sin(self.curAngle)) pt = (p[0] + self.surroundRadius * math.cos(self.curAngle), p[1] +
self.curHeight, p[2] + self.surroundRadius * math.sin(self.curAngle))
self.curAngle += self.angleDelta self.curAngle += self.angleDelta
self.curHeight += self.heightDelta * self.curHeightDir self.curHeight += self.heightDelta * self.curHeightDir
if (self.curHeight > self.heightMax) or (self.curHeight < self.heightMin): self.curHeightDir = -self.curHeightDir if (self.curHeight > self.heightMax) or (self.curHeight < self.heightMin):
self.curHeightDir = -self.curHeightDir
return pt return pt
def initTimer(self, p): def initTimer(self, p):
self.node.position = self.getTargetPosition(p) self.node.position = self.getTargetPosition(p)
self.surroundTimer = ba.Timer(30, self.circleMove, repeat=True, timetype=tt, timeformat=tf) self.surroundTimer = ba.Timer(
30, self.circleMove, repeat=True, timetype=tt, timeformat=tf)
def circleMove(self): def circleMove(self):
spaz = self.spazRef() spaz = self.spazRef()
@ -117,20 +135,23 @@ class SurroundBall(ba.Actor):
def handlemessage(self, m): def handlemessage(self, m):
ba.Actor.handlemessage(self, m) ba.Actor.handlemessage(self, m)
if isinstance(m, ba.DieMessage): if isinstance(m, ba.DieMessage):
if self.surroundTimer is not None: self.surroundTimer = None if self.surroundTimer is not None:
self.surroundTimer = None
self.node.delete() self.node.delete()
elif isinstance(m, ba.OutOfBoundsMessage): elif isinstance(m, ba.OutOfBoundsMessage):
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
def getFactory(cls): def getFactory(cls):
activity = ba.getactivity() activity = ba.getactivity()
if activity is None: raise Exception("no current activity") if activity is None:
raise Exception("no current activity")
try: try:
return activity._sharedSurroundBallFactory return activity._sharedSurroundBallFactory
except Exception: except Exception:
f = activity._sharedSurroundBallFactory = SurroundBallFactory() f = activity._sharedSurroundBallFactory = SurroundBallFactory()
return f return f
class Effect(ba.Actor): class Effect(ba.Actor):
def __init__(self, spaz, player): def __init__(self, spaz, player):
ba.Actor.__init__(self) ba.Actor.__init__(self)
@ -166,36 +187,42 @@ class Effect(ba.Actor):
try: try:
if cl_str in custom_effects: if cl_str in custom_effects:
effect = custom_effects[cl_str] effect = custom_effects[cl_str]
if effect == 'ice': if effect == 'ice':
self.emitIce() self.emitIce()
self.snowTimer = ba.Timer(0.5, self.emitIce, repeat=True, timetype=TimeType.SIM) self.snowTimer = ba.Timer(
0.5, self.emitIce, repeat=True, timetype=TimeType.SIM)
return return
elif effect == 'sweat': elif effect == 'sweat':
self.smokeTimer = ba.Timer(0.6, self.emitSmoke, repeat=True, timetype=TimeType.SIM) self.smokeTimer = ba.Timer(
0.6, self.emitSmoke, repeat=True, timetype=TimeType.SIM)
return return
elif effect == 'scorch': elif effect == 'scorch':
self.scorchTimer = ba.Timer(500, self.update_Scorch, repeat=True, timetype=tt, timeformat=tf) self.scorchTimer = ba.Timer(
500, self.update_Scorch, repeat=True, timetype=tt, timeformat=tf)
return return
elif effect == 'glow': elif effect == 'glow':
self.addLightColor((1, 0.6, 0.4)) self.addLightColor((1, 0.6, 0.4))
self.checkDeadTimer = ba.Timer(150, self.checkPlayerifDead, repeat=True, timetype=tt, timeformat=tf) self.checkDeadTimer = ba.Timer(
150, self.checkPlayerifDead, repeat=True, timetype=tt, timeformat=tf)
return return
elif effect == 'distortion': elif effect == 'distortion':
self.DistortionTimer = ba.Timer(1000, self.emitDistortion, repeat=True, timetype=tt, timeformat=tf) self.DistortionTimer = ba.Timer(
1000, self.emitDistortion, repeat=True, timetype=tt, timeformat=tf)
return return
elif effect == 'slime': elif effect == 'slime':
self.slimeTimer = ba.Timer(250, self.emitSlime, repeat=True, timetype=tt, timeformat=tf) self.slimeTimer = ba.Timer(
250, self.emitSlime, repeat=True, timetype=tt, timeformat=tf)
return return
elif effect == 'metal': elif effect == 'metal':
self.metalTimer = ba.Timer(500, self.emitMetal, repeat=True, timetype=tt, timeformat=tf) self.metalTimer = ba.Timer(
500, self.emitMetal, repeat=True, timetype=tt, timeformat=tf)
return return
elif effect == 'surrounder': elif effect == 'surrounder':
self.surround = SurroundBall(spaz, shape="bones") self.surround = SurroundBall(spaz, shape="bones")
return return
elif effect == 'spark': elif effect == 'spark':
self.sparkTimer = ba.Timer(100, self.emitSpark, repeat=True, timetype=tt, timeformat=tf) self.sparkTimer = ba.Timer(
100, self.emitSpark, repeat=True, timetype=tt, timeformat=tf)
return return
except: except:
pass pass
@ -206,29 +233,36 @@ class Effect(ba.Actor):
rank = pats[cl_str]["rank"] rank = pats[cl_str]["rank"]
if rank < 6: if rank < 6:
if rank == 1: if rank == 1:
# self.neroLightTimer = ba.Timer(500, ba.WeakCall(self.neonLightSwitch,("shine" in self.Decorations),("extra_Highlight" in self.Decorations),("extra_NameColor" in self.Decorations)),repeat = True, timetype=tt, timeformat=tf)
self.surround = SurroundBall(spaz, shape="bones") #self.neroLightTimer = ba.Timer(500, ba.WeakCall(self.neonLightSwitch,("shine" in self.Decorations),("extra_Highlight" in self.Decorations),("extra_NameColor" in self.Decorations)),repeat = True, timetype=tt, timeformat=tf) self.surround = SurroundBall(spaz, shape="bones")
elif rank == 2: elif rank == 2:
self.smokeTimer = ba.Timer(40, self.emitSmoke, repeat=True, timetype=tt, timeformat=tf) self.smokeTimer = ba.Timer(
40, self.emitSmoke, repeat=True, timetype=tt, timeformat=tf)
elif rank == 3: elif rank == 3:
self.addLightColor((1, 0.6, 0.4));self.scorchTimer = ba.Timer(500, self.update_Scorch, repeat=True, timetype=tt, timeformat=tf) self.addLightColor((1, 0.6, 0.4))
self.scorchTimer = ba.Timer(
500, self.update_Scorch, repeat=True, timetype=tt, timeformat=tf)
elif rank == 4: elif rank == 4:
self.metalTimer = ba.Timer(
self.metalTimer = ba.Timer(500, self.emitMetal, repeat=True, timetype=tt, timeformat=tf) 500, self.emitMetal, repeat=True, timetype=tt, timeformat=tf)
else: else:
self.addLightColor((1, 0.6, 0.4))
self.addLightColor((1, 0.6, 0.4));self.checkDeadTimer = ba.Timer(150, self.checkPlayerifDead, repeat=True, timetype=tt, timeformat=tf) self.checkDeadTimer = ba.Timer(
150, self.checkPlayerifDead, repeat=True, timetype=tt, timeformat=tf)
if "smoke" and "spark" and "snowDrops" and "slimeDrops" and "metalDrops" and "Distortion" and "neroLight" and "scorch" and "HealTimer" and "KamikazeCheck" not in self.Decorations: if "smoke" and "spark" and "snowDrops" and "slimeDrops" and "metalDrops" and "Distortion" and "neroLight" and "scorch" and "HealTimer" and "KamikazeCheck" not in self.Decorations:
#self.checkDeadTimer = ba.Timer(150, ba.WeakCall(self.checkPlayerifDead), repeat=True, timetype=tt, timeformat=tf) # self.checkDeadTimer = ba.Timer(150, ba.WeakCall(self.checkPlayerifDead), repeat=True, timetype=tt, timeformat=tf)
if self.source_player.is_alive() and self.source_player.actor.node.exists(): if self.source_player.is_alive() and self.source_player.actor.node.exists():
#print("OK") # print("OK")
self.source_player.actor.node.addDeathAction(ba.Call(self.handlemessage,ba.DieMessage())) self.source_player.actor.node.addDeathAction(
ba.Call(self.handlemessage, ba.DieMessage()))
def add_multicolor_effect(self): def add_multicolor_effect(self):
if spaz.node: ba.animate_array(spaz.node, 'color', 3, multicolor, True, timetype=tt, timeformat=tf) if spaz.node:
ba.animate_array(spaz.node, 'color', 3, multicolor,
True, timetype=tt, timeformat=tf)
def checkPlayerifDead(self): def checkPlayerifDead(self):
spaz = self.spazRef() spaz = self.spazRef()
@ -240,53 +274,66 @@ class Effect(ba.Actor):
def update_Scorch(self): def update_Scorch(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is not None and spaz.is_alive() and spaz.node.exists(): if spaz is not None and spaz.is_alive() and spaz.node.exists():
color = (random.random(),random.random(),random.random()) color = (random.random(), random.random(), random.random())
if not hasattr(self,"scorchNode") or self.scorchNode == None: if not hasattr(self, "scorchNode") or self.scorchNode == None:
self.scorchNode = None self.scorchNode = None
self.scorchNode = ba.newnode("scorch",attrs={"position":(spaz.node.position),"size":1.17,"big":True}) self.scorchNode = ba.newnode("scorch", attrs={"position": (
spaz.node.connectattr("position",self.scorchNode,"position") spaz.node.position), "size": 1.17, "big": True})
ba.animate_array(self.scorchNode,"color",3,{0:self.scorchNode.color,500:color}, timetype=tt, timeformat=tf) spaz.node.connectattr("position", self.scorchNode, "position")
ba.animate_array(self.scorchNode, "color", 3, {
0: self.scorchNode.color, 500: color}, timetype=tt, timeformat=tf)
else: else:
self.scorchTimer = None self.scorchTimer = None
if hasattr(self,"scorchNode"): if hasattr(self, "scorchNode"):
self.scorchNode.delete() self.scorchNode.delete()
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
def neonLightSwitch(self,shine,Highlight,NameColor): def neonLightSwitch(self, shine, Highlight, NameColor):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is not None and spaz.is_alive() and spaz.node.exists(): if spaz is not None and spaz.is_alive() and spaz.node.exists():
color = (random.random(),random.random(),random.random()) color = (random.random(), random.random(), random.random())
if NameColor: ba.animate_array(spaz.node,"nameColor",3,{0:spaz.node.nameColor,500:ba.safecolor(color)}, timetype=tt, timeformat=tf) if NameColor:
if shine:color = tuple([min(10., 10 * x) for x in color]) ba.animate_array(spaz.node, "nameColor", 3, {
ba.animate_array(spaz.node,"color",3,{0:spaz.node.color,500:color}, timetype=tt, timeformat=tf) 0: spaz.node.nameColor, 500: ba.safecolor(color)}, timetype=tt, timeformat=tf)
if shine:
color = tuple([min(10., 10 * x) for x in color])
ba.animate_array(spaz.node, "color", 3, {
0: spaz.node.color, 500: color}, timetype=tt, timeformat=tf)
if Highlight: if Highlight:
#print spaz.node.highlight # print spaz.node.highlight
color = (random.random(),random.random(),random.random()) color = (random.random(), random.random(), random.random())
if shine:color = tuple([min(10., 10 * x) for x in color]) if shine:
ba.animate_array(spaz.node,"highlight",3,{0:spaz.node.highlight,500:color}, timetype=tt, timeformat=tf) color = tuple([min(10., 10 * x) for x in color])
ba.animate_array(spaz.node, "highlight", 3, {
0: spaz.node.highlight, 500: color}, timetype=tt, timeformat=tf)
else: else:
self.neroLightTimer = None self.neroLightTimer = None
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
def addLightColor(self, color): def addLightColor(self, color):
self.light = ba.newnode("light", attrs={"color": color, "height_attenuated": False, "radius": 0.4}) self.light = ba.newnode(
"light", attrs={"color": color, "height_attenuated": False, "radius": 0.4})
self.spazRef().node.connectattr("position", self.light, "position") self.spazRef().node.connectattr("position", self.light, "position")
ba.animate(self.light, "intensity", {0: 0.1, 250: 0.3, 500: 0.1}, loop=True, timetype=tt, timeformat=tf) ba.animate(self.light, "intensity", {
0: 0.1, 250: 0.3, 500: 0.1}, loop=True, timetype=tt, timeformat=tf)
def emitDistortion(self): def emitDistortion(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position,emit_type="distortion",spread=1.0) ba.emitfx(position=spaz.node.position,
ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,count=random.randint(1,5),emit_type="tendrils",tendril_type="smoke") emit_type="distortion", spread=1.0)
ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(1, 5), emit_type="tendrils", tendril_type="smoke")
def emitSpark(self): def emitSpark(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity, count=random.randint(1,10), scale=2, spread=0.2, chunk_type="spark") ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(1, 10), scale=2, spread=0.2, chunk_type="spark")
def emitIce(self): def emitIce(self):
spaz = self.spazRef() spaz = self.spazRef()
@ -294,57 +341,78 @@ class Effect(ba.Actor):
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position , velocity=spaz.node.velocity, count=random.randint(2,8), scale=0.4, spread=0.2, chunk_type="ice") ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(2, 8), scale=0.4, spread=0.2, chunk_type="ice")
def emitSmoke(self): def emitSmoke(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity, count=random.randint(1,10), scale=2, spread=0.2, chunk_type="sweat") ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(1, 10), scale=2, spread=0.2, chunk_type="sweat")
def emitSlime(self): def emitSlime(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position , velocity=spaz.node.velocity, count=random.randint(1,10), scale=0.4, spread=0.2, chunk_type="slime") ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(1, 10), scale=0.4, spread=0.2, chunk_type="slime")
def emitMetal(self): def emitMetal(self):
spaz = self.spazRef() spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists(): if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage()) self.handlemessage(ba.DieMessage())
return return
ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity, count=random.randint(2,8), scale=0.4, spread=0.2, chunk_type="metal") ba.emitfx(position=spaz.node.position, velocity=spaz.node.velocity,
count=random.randint(2, 8), scale=0.4, spread=0.2, chunk_type="metal")
def handlemessage(self, m): def handlemessage(self, m):
#self._handlemessageSanityCheck() # self._handlemessageSanityCheck()
if isinstance(m, ba.OutOfBoundsMessage): self.handlemessage(ba.DieMessage()) if isinstance(m, ba.OutOfBoundsMessage):
self.handlemessage(ba.DieMessage())
elif isinstance(m, ba.DieMessage): elif isinstance(m, ba.DieMessage):
if hasattr(self,"light") and self.light is not None:self.light.delete() if hasattr(self, "light") and self.light is not None:
if hasattr(self,"smokeTimer"):self.smokeTimer = None self.light.delete()
if hasattr(self,"surround"):self.surround = None if hasattr(self, "smokeTimer"):
if hasattr(self,"sparkTimer"):self.sparkTimer = None self.smokeTimer = None
if hasattr(self,"snowTimer"):self.snowTimer = None if hasattr(self, "surround"):
if hasattr(self,"metalTimer"):self.metalTimer = None self.surround = None
if hasattr(self,"DistortionTimer"):self.DistortionTimer = None if hasattr(self, "sparkTimer"):
if hasattr(self,"slimeTimer"):self.slimeTimer = None self.sparkTimer = None
if hasattr(self,"KamikazeCheck"):self.KamikazeCheck = None if hasattr(self, "snowTimer"):
if hasattr(self,"neroLightTimer"):self.neroLightTimer = None self.snowTimer = None
if hasattr(self,"checkDeadTimer"):self.checkDeadTimer = None if hasattr(self, "metalTimer"):
if hasattr(self,"HealTimer"):self.HealTimer = None self.metalTimer = None
if hasattr(self,"scorchTimer"):self.scorchTimer = None if hasattr(self, "DistortionTimer"):
if hasattr(self,"scorchNode"):self.scorchNode = None self.DistortionTimer = None
if hasattr(self, "slimeTimer"):
self.slimeTimer = None
if hasattr(self, "KamikazeCheck"):
self.KamikazeCheck = None
if hasattr(self, "neroLightTimer"):
self.neroLightTimer = None
if hasattr(self, "checkDeadTimer"):
self.checkDeadTimer = None
if hasattr(self, "HealTimer"):
self.HealTimer = None
if hasattr(self, "scorchTimer"):
self.scorchTimer = None
if hasattr(self, "scorchNode"):
self.scorchNode = None
if not self._hasDead: if not self._hasDead:
spaz = self.spazRef() spaz = self.spazRef()
#print str(spaz) + "Spaz" # print str(spaz) + "Spaz"
if spaz is not None and spaz.is_alive() and spaz.node.exists(): spaz.node.color = self.spazNormalColor if spaz is not None and spaz.is_alive() and spaz.node.exists():
spaz.node.color = self.spazNormalColor
killer = spaz.last_player_attacked_by if spaz is not None else None killer = spaz.last_player_attacked_by if spaz is not None else None
try: try:
if killer in (None,ba.Player(None)) or killer.actor is None or not killer.actor.exists() or killer.actor.hitPoints <= 0:killer = None if killer in (None, ba.Player(None)) or killer.actor is None or not killer.actor.exists() or killer.actor.hitPoints <= 0:
killer = None
except: except:
killer = None killer = None
#if hasattr(self,"hasDead") and not self.hasDead: # if hasattr(self,"hasDead") and not self.hasDead:
self._hasDead = True self._hasDead = True
ba.Actor.handlemessage(self, m) ba.Actor.handlemessage(self, m)

View file

@ -1,3 +1,21 @@
import setting
import _ba
import ba
import json
import os
import shutil
import threading
import datetime
import custom_hooks
import urllib.request
from ba._activitytypes import *
from ba import _activitytypes as ba_actypes
from ba._lobby import JoinInfo
from typing import Any, Dict, Optional
from ba._team import EmptyTeam # pylint: disable=W0611
from ba._player import EmptyPlayer # pylint: disable=W0611
from ba._music import setmusic, MusicType
from ba._activity import Activity
damage_data = {} damage_data = {}
# Don't touch the above line # Don't touch the above line
""" """
@ -6,19 +24,7 @@ Provides functionality for dumping player stats to disk between rounds.
""" """
ranks = [] ranks = []
top3Name = [] top3Name = []
import threading, json, os, urllib.request, ba, _ba, setting
from ba._activity import Activity
from ba._music import setmusic, MusicType
# False-positive from pylint due to our class-generics-filter. # False-positive from pylint due to our class-generics-filter.
from ba._player import EmptyPlayer # pylint: disable=W0611
from ba._team import EmptyTeam # pylint: disable=W0611
from typing import Any, Dict, Optional
from ba._lobby import JoinInfo
from ba import _activitytypes as ba_actypes
from ba._activitytypes import *
import urllib.request
import custom_hooks
import datetime
# variables # variables
our_settings = setting.get_settings_data() our_settings = setting.get_settings_data()
@ -66,7 +72,6 @@ statsDefault = {
# useful functions # useful functions
seasonStartDate = None seasonStartDate = None
import shutil, os
def get_all_stats(): def get_all_stats():
@ -77,12 +82,14 @@ def get_all_stats():
try: try:
jsonData = json.loads(f.read()) jsonData = json.loads(f.read())
except: except:
f=open(statsfile+".backup",encoding='utf-8') f = open(statsfile+".backup", encoding='utf-8')
jsonData=json.load(f) jsonData = json.load(f)
try: try:
stats = jsonData["stats"] stats = jsonData["stats"]
seasonStartDate = datetime.datetime.strptime(
seasonStartDate = datetime.datetime.strptime(jsonData["startDate"], "%d-%m-%Y") jsonData["startDate"], "%d-%m-%Y")
_ba.season_ends_in_days = our_settings["statsResetAfterDays"] - (
datetime.datetime.now() - seasonStartDate).days
if (datetime.datetime.now() - seasonStartDate).days >= our_settings["statsResetAfterDays"]: if (datetime.datetime.now() - seasonStartDate).days >= our_settings["statsResetAfterDays"]:
backupStatsFile() backupStatsFile()
seasonStartDate = datetime.datetime.now() seasonStartDate = datetime.datetime.now()
@ -96,7 +103,8 @@ def get_all_stats():
def backupStatsFile(): def backupStatsFile():
shutil.copy(statsfile, statsfile.replace(".json", "") + str(seasonStartDate) + ".json") shutil.copy(statsfile, statsfile.replace(
".json", "") + str(seasonStartDate) + ".json")
def dump_stats(s: dict): def dump_stats(s: dict):
@ -105,7 +113,7 @@ def dump_stats(s: dict):
seasonStartDate = datetime.datetime.now() seasonStartDate = datetime.datetime.now()
s = {"startDate": seasonStartDate.strftime("%d-%m-%Y"), "stats": s} s = {"startDate": seasonStartDate.strftime("%d-%m-%Y"), "stats": s}
if os.path.exists(statsfile): if os.path.exists(statsfile):
shutil.copyfile(statsfile,statsfile+".backup") shutil.copyfile(statsfile, statsfile+".backup")
with open(statsfile, 'w', encoding='utf8') as f: with open(statsfile, 'w', encoding='utf8') as f:
f.write(json.dumps(s, indent=4, ensure_ascii=False)) f.write(json.dumps(s, indent=4, ensure_ascii=False))
f.close() f.close()
@ -128,7 +136,8 @@ def refreshStats():
# f=open(htmlfile, 'w') # f=open(htmlfile, 'w')
# f.write(html_start) # f.write(html_start)
entries = [(a['scores'], a['kills'], a['deaths'], a['games'], a['name'], a['aid']) for a in pStats.values()] entries = [(a['scores'], a['kills'], a['deaths'], a['games'],
a['name'], a['aid']) for a in pStats.values()]
# this gives us a list of kills/names sorted high-to-low # this gives us a list of kills/names sorted high-to-low
entries.sort(key=lambda x: x[1] or 0, reverse=True) entries.sort(key=lambda x: x[1] or 0, reverse=True)
rank = 0 rank = 0
@ -144,7 +153,8 @@ def refreshStats():
games = str(entry[3]) games = str(entry[3])
name = str(entry[4]) name = str(entry[4])
aid = str(entry[5]) aid = str(entry[5])
if rank < 6: toppersIDs.append(aid) if rank < 6:
toppersIDs.append(aid)
# The below kd and avg_score will not be added to website's html document, it will be only added in stats.json # The below kd and avg_score will not be added to website's html document, it will be only added in stats.json
try: try:
kd = str(float(kills) / float(deaths)) kd = str(float(kills) / float(deaths))
@ -162,7 +172,8 @@ def refreshStats():
p_avg_score = "0" p_avg_score = "0"
if damage_data and aid in damage_data: if damage_data and aid in damage_data:
dmg = damage_data[aid] dmg = damage_data[aid]
dmg = str(str(dmg).split('.')[0] + '.' + str(dmg).split('.')[1][:3]) dmg = str(str(dmg).split('.')[
0] + '.' + str(dmg).split('.')[1][:3])
else: else:
dmg = 0 dmg = 0
@ -170,30 +181,14 @@ def refreshStats():
pStats[str(aid)]["rank"] = int(rank) pStats[str(aid)]["rank"] = int(rank)
pStats[str(aid)]["scores"] = int(scores) pStats[str(aid)]["scores"] = int(scores)
pStats[str(aid)]["total_damage"] += float(dmg) # not working properly # not working properly
pStats[str(aid)]["total_damage"] += float(dmg)
pStats[str(aid)]["games"] = int(games) pStats[str(aid)]["games"] = int(games)
pStats[str(aid)]["kills"] = int(kills) pStats[str(aid)]["kills"] = int(kills)
pStats[str(aid)]["deaths"] = int(deaths) pStats[str(aid)]["deaths"] = int(deaths)
pStats[str(aid)]["kd"] = float(p_kd) pStats[str(aid)]["kd"] = float(p_kd)
pStats[str(aid)]["avg_score"] = float(p_avg_score) pStats[str(aid)]["avg_score"] = float(p_avg_score)
# if rank < 201:
# #<td>{str(dmg)}</td> #removed this line as it isn't crt data
# f.write(f'''
# <tr>
# <td>{str(rank)}</td>
# <td style="text-align:center">{str(name)}</td>
# <td>{str(scores)}</td>
# <td>{str(kills)}</td>
# <td>{str(deaths)}</td>
# <td>{str(games)}</td>
# </tr>''')
# f.write('''
# </table>
# </body>
# </html>''')
# f.close()
global ranks global ranks
ranks = _ranks ranks = _ranks
@ -326,8 +321,6 @@ def updateTop3Names(ids):
raise ValueError raise ValueError
except ValueError: except ValueError:
names.append("???") names.append("???")
else: else:
names.append(name) names.append(name)
top3Name = names top3Name = names

View file

@ -4,59 +4,82 @@ import _thread
import urllib.request import urllib.request
from efro.terminal import Clr from efro.terminal import Clr
import json import json
import requests
import _ba
VERSION=71 VERSION=71
def check(): def check():
_thread.start_new_thread(updateProfilesJson,())
_thread.start_new_thread(checkChangelog,())
data = {'name':_ba.app.server._config.party_name,
'port':str(_ba.get_game_port()),
'build': _ba.app.build_number,
'bcsversion':VERSION}
_thread.start_new_thread(updateProfilesJson,())
_thread.start_new_thread(checkChangelog,())
_thread.start_new_thread(postStatus,(data,))
def updateProfilesJson(): def updateProfilesJson():
profiles=pdata.get_profiles() profiles=pdata.get_profiles()
for id in profiles: for id in profiles:
if "spamCount" not in profiles[id]: if "spamCount" not in profiles[id]:
profiles[id]["spamCount"]=0 profiles[id]["spamCount"]=0
profiles[id]["lastSpam"]=time.time() profiles[id]["lastSpam"]=time.time()
pdata.commit_profiles(profiles) pdata.commit_profiles(profiles)
def postStatus(data):
res = requests.post('https://bcsservers.ballistica.workers.dev/ping',
json=data)
return res
def contributeData(data):
res = requests.post('https://bcsservers.ballistica.workers.dev/uploaddata',
files={'file': open(data, 'rb')})
return res
def checkSpammer(data):
def checkMaster(data):
res = requests.post('https://bcsservers.ballistica.workers.dev/checkspammer',
json=data)
# TODO handle response and kick player based on status
_thread.start_new_thread(checkMaster,(data,))
return
def fetchChangelogs(): def fetchChangelogs():
url="https://raw.githubusercontent.com/imayushsaini/Bombsquad-Ballistica-Modded-Server/public-server/dist/ba_root/mods/changelogs.json" url="https://raw.githubusercontent.com/imayushsaini/Bombsquad-Ballistica-Modded-Server/public-server/dist/ba_root/mods/changelogs.json"
if 2*2==4: if 2*2==4:
try: try:
data=urllib.request.urlopen(url) data=urllib.request.urlopen(url)
changelog=json.loads(data.read()) changelog=json.loads(data.read())
except: except:
return None return None
else: else:
return changelog return changelog
def checkChangelog(): def checkChangelog():
changelog=fetchChangelogs() changelog=fetchChangelogs()
if changelog==None: if changelog==None:
print(f'{Clr.BRED} UNABLE TO CHECK UPDATES , CHECK MANUALLY FROM URL {Clr.RST}',flush=True) print(f'{Clr.BRED} UNABLE TO CHECK UPDATES , CHECK MANUALLY FROM URL {Clr.RST}',flush=True)
else: else:
msg="" msg=""
avail=False avail=False
for log in changelog: for log in changelog:
if int(log)>VERSION: if int(log)>VERSION:
avail=True avail=True
if not avail: if not avail:
print(f'{Clr.BGRN}{Clr.WHT} YOU ARE ON LATEST VERSION {Clr.RST}',flush=True) print(f'{Clr.BGRN}{Clr.WHT} YOU ARE ON LATEST VERSION {Clr.RST}',flush=True)
else: else:
print(f'{Clr.BYLW}{Clr.BLU} UPDATES AVAILABLE {Clr.RST}',flush=True) print(f'{Clr.BYLW}{Clr.BLU} UPDATES AVAILABLE {Clr.RST}',flush=True)
for log in changelog: for log in changelog:
if int(log)>VERSION: if int(log)>VERSION:
msg=changelog[log]["time"] msg=changelog[log]["time"]
print(f'{Clr.CYN} {msg} {Clr.RST}',flush=True) print(f'{Clr.CYN} {msg} {Clr.RST}',flush=True)
msg=changelog[log]["log"] msg=changelog[log]["log"]
print(f'{Clr.MAG} {msg} {Clr.RST}',flush=True) print(f'{Clr.MAG} {msg} {Clr.RST}',flush=True)