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 tools.whitelist import add_to_white_list, add_commit_to_logs
from serverData import serverdata
import ba, _ba, time, setting
import ba
import _ba
import time
import setting
import ba.internal
import _thread
import random
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']
CommandAliases = ['max','rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm', 'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera','effect']
Commands = ['createteam', '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']
CommandAliases = ['max', 'rm', 'next', 'restart', 'mutechat', 'unmutechat', 'sm',
'slow', 'night', 'day', 'pausegame', 'camera_mode', 'rotate_camera', 'effect']
def ExcelCommand(command, arguments, clientid, accountid):
@ -24,9 +29,11 @@ def ExcelCommand(command, arguments, clientid, accountid):
Returns:
None
"""
if command in ['maxplayers','max']:
if command in ['maxplayers', 'max']:
changepartysize(arguments)
elif command =='playlist':
if command in ['createteam']:
create_team(arguments)
elif command == 'playlist':
changeplaylist(arguments)
elif command == 'kick':
kick(arguments)
@ -85,8 +92,8 @@ def ExcelCommand(command, arguments, clientid, accountid):
elif command == 'removerole':
remove_role_from_player(arguments)
elif command=='getroles':
get_roles_of_player(arguments,clientid)
elif command == 'getroles':
get_roles_of_player(arguments, clientid)
elif command in ['addcommand', 'addcmd']:
add_command_to_role(arguments)
@ -97,10 +104,10 @@ def ExcelCommand(command, arguments, clientid, accountid):
elif command == 'changetag':
change_role_tag(arguments)
elif command=='customtag':
elif command == 'customtag':
set_custom_tag(arguments)
elif command in ['customeffect','effect']:
elif command in ['customeffect', 'effect']:
set_custom_effect(arguments)
# elif command in ['add', 'whitelist']:
@ -113,26 +120,40 @@ def ExcelCommand(command, arguments, clientid, accountid):
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():
_ba.hide_player_device_id(True)
def show_player_spec():
_ba.hide_player_device_id(False)
def changepartysize(arguments):
if len(arguments)==0:
if len(arguments) == 0:
ba.internal.chatmessage("enter number")
else:
ba.internal.set_public_party_max_size(int(arguments[0]))
def changeplaylist(arguments):
if len(arguments)==0:
if len(arguments) == 0:
ba.internal.chatmessage("enter list code or name")
else:
if arguments[0]=='coop':
serverdata.coopmode=True
if arguments[0] == 'coop':
serverdata.coopmode = True
else:
serverdata.coopmode=False
serverdata.coopmode = False
playlist.setPlaylist(arguments[0])
return
@ -140,6 +161,8 @@ def changeplaylist(arguments):
def kick(arguments):
ba.internal.disconnect_client(int(arguments[0]))
return
def kikvote(arguments, clientid):
if arguments == [] or arguments == [''] or len(arguments) < 2:
return
@ -149,12 +172,14 @@ def kikvote(arguments, clientid):
_ba.set_enable_default_kick_voting(True)
else:
try:
cl_id=int(arguments[1])
cl_id = int(arguments[1])
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:
serverdata.clients[ros["account_id"]]["canStartKickVote"]=True
send("Upon server restart, Kick-vote will be enabled for this person", clientid)
serverdata.clients[ros["account_id"]
]["canStartKickVote"] = True
send(
"Upon server restart, Kick-vote will be enabled for this person", clientid)
return
except:
return
@ -164,36 +189,40 @@ def kikvote(arguments, clientid):
_ba.set_enable_default_kick_voting(False)
else:
try:
cl_id=int(arguments[1])
cl_id = int(arguments[1])
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"])
send("Kick-vote disabled for this person", clientid)
if ros["account_id"] in serverdata.clients:
serverdata.clients[ros["account_id"]]["canStartKickVote"]=False
serverdata.clients[ros["account_id"]
]["canStartKickVote"] = False
return
except:
return
else:
return
def last_msgs(clientid):
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:
playerID = int(arguments[0])
num = 1
for i in ba.internal.get_foreground_host_session().sessionplayers[playerID].inputdevice.get_player_profiles():
try:
send(f"{num})- {i}",clientid)
send(f"{num})- {i}", clientid)
num += 1
except:
pass
except:
pass
def party_toggle(arguments):
if arguments == ['public']:
ba.internal.set_public_party_enabled(True)
@ -213,67 +242,62 @@ def end(arguments):
except:
pass
def ban(arguments):
try:
cl_id=int(arguments[0])
ac_id=""
cl_id = int(arguments[0])
ac_id = ""
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'])
ac_id=ros['account_id']
ac_id = ros['account_id']
if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isBan"]=True
serverdata.clients[ac_id]["isBan"] = True
kick(arguments)
except:
pass
def quit(arguments):
if arguments == [] or arguments == ['']:
ba.quit()
def mute(arguments):
if len(arguments)==0:
serverdata.muted=True
if len(arguments) == 0:
serverdata.muted = True
try:
cl_id=int(arguments[0])
ac_id=""
cl_id = int(arguments[0])
ac_id = ""
for ros in ba.internal.get_game_roster():
if ros["client_id"]==cl_id:
_thread.start_new_thread(pdata.mute,(ros['account_id'],))
ac_id=ros['account_id']
if ros["client_id"] == cl_id:
_thread.start_new_thread(pdata.mute, (ros['account_id'],))
ac_id = ros['account_id']
if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isMuted"]=True
serverdata.clients[ac_id]["isMuted"] = True
except:
pass
return
def un_mute(arguments):
if len(arguments)==0:
serverdata.muted=False
if len(arguments) == 0:
serverdata.muted = False
try:
cl_id=int(arguments[0])
ac_id=""
cl_id = int(arguments[0])
ac_id = ""
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'])
ac_id=ros['account_id']
ac_id = ros['account_id']
if ac_id in serverdata.clients:
serverdata.clients[ac_id]["isMuted"]=False
serverdata.clients[ac_id]["isMuted"] = False
return
except:
pass
def remove(arguments):
if arguments == [] or arguments == ['']:
@ -288,13 +312,12 @@ def remove(arguments):
try:
session = ba.internal.get_foreground_host_session()
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()
except:
return
def slow_motion():
activity = _ba.get_foreground_host_activity()
@ -306,7 +329,6 @@ def slow_motion():
activity.globalsnode.slow_motion = False
def nv(arguments):
activity = _ba.get_foreground_host_activity()
@ -316,7 +338,7 @@ def nv(arguments):
if activity.globalsnode.tint != (0.5, 0.7, 1.0):
activity.globalsnode.tint = (0.5, 0.7, 1.0)
else:
#will fix this soon
# will fix this soon
pass
elif arguments[0] == 'off':
@ -326,27 +348,25 @@ def nv(arguments):
pass
def dv(arguments):
activity = _ba.get_foreground_host_activity()
if arguments == [] or arguments == ['']:
if activity.globalsnode.tint != (1,1,1):
activity.globalsnode.tint = (1,1,1)
if activity.globalsnode.tint != (1, 1, 1):
activity.globalsnode.tint = (1, 1, 1)
else:
#will fix this soon
# will fix this soon
pass
elif arguments[0] == 'off':
if activity.globalsnode.tint != (1,1,1):
if activity.globalsnode.tint != (1, 1, 1):
return
else:
pass
def pause():
activity = _ba.get_foreground_host_activity()
@ -362,12 +382,11 @@ def rotate_camera():
activity = _ba.get_foreground_host_activity()
if activity.globalsnode.camera_mode != 'rotate':
activity.globalsnode.camera_mode = 'rotate'
if activity.globalsnode.camera_mode != 'rotate':
activity.globalsnode.camera_mode = 'rotate'
else:
activity.globalsnode.camera_mode == 'normal'
activity.globalsnode.camera_mode == 'normal'
def create_role(arguments):
@ -382,83 +401,90 @@ def add_role_to_player(arguments):
session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]):
roles=pdata.add_player_role(arguments[0],i.get_v1_account_id())
if i.inputdevice.client_id == int(arguments[1]):
roles = pdata.add_player_role(
arguments[0], i.get_v1_account_id())
except:
return
def remove_role_from_player(arguments):
try:
session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]):
roles=pdata.remove_player_role(arguments[0],i.get_v1_account_id())
if i.inputdevice.client_id == int(arguments[1]):
roles = pdata.remove_player_role(
arguments[0], i.get_v1_account_id())
except:
return
def get_roles_of_player(arguments,clientid):
def get_roles_of_player(arguments, clientid):
try:
session = ba.internal.get_foreground_host_session()
roles=[]
reply=""
roles = []
reply = ""
for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[0]):
roles=pdata.get_player_roles(i.get_v1_account_id())
if i.inputdevice.client_id == int(arguments[0]):
roles = pdata.get_player_roles(i.get_v1_account_id())
print(roles)
for role in roles:
reply=reply+role+","
send(reply,clientid)
reply = reply+role+","
send(reply, clientid)
except:
return
def change_role_tag(arguments):
try:
pdata.change_role_tag(arguments[0], arguments[1])
except:
return
def set_custom_tag(arguments):
try:
session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]):
roles=pdata.set_tag(arguments[0],i.get_v1_account_id())
if i.inputdevice.client_id == int(arguments[1]):
roles = pdata.set_tag(arguments[0], i.get_v1_account_id())
except:
return
def set_custom_effect(arguments):
try:
session = ba.internal.get_foreground_host_session()
for i in session.sessionplayers:
if i.inputdevice.client_id== int(arguments[1]):
roles=pdata.set_effect(arguments[0],i.get_v1_account_id())
if i.inputdevice.client_id == int(arguments[1]):
roles = pdata.set_effect(arguments[0], i.get_v1_account_id())
except:
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","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"]
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"]
def add_command_to_role(arguments):
try:
if arguments[1] in all_commands:
if len(arguments) == 2:
pdata.add_command_role(arguments[0], arguments[1])
else:
ba.internal.chatmessage("invalid command arguments")
except:
return
def remove_command_to_role(arguments):
try:
if arguments[1] in all_commands:
if len(arguments) == 2:
pdata.remove_command_role(arguments[0], arguments[1])
except:
return
# def whitelst_it(accountid : str, arguments):
# settings = setting.get_settings_data()
@ -489,8 +515,6 @@ def remove_command_to_role(arguments):
# add_commit_to_logs(accountid+" added "+i['account_id'])
def spectators(arguments):
if arguments[0] in ['on', 'off']:
@ -507,8 +531,6 @@ def spectators(arguments):
ba.internal.chatmessage("spectators off")
def change_lobby_check_time(arguments):
try:
argument = int(arguments[0])

View file

@ -1,12 +1,13 @@
from .Handlers import send
import ba, _ba
import ba
import _ba
import ba.internal
from stats import mystats
from ba._general import Call
import _thread
Commands = ['me', 'list', 'uniqeid','ping']
CommandAliases = ['stats', 'score', 'rank', 'myself', 'l', 'id', 'pb-id', 'pb', 'accountid']
Commands = ['me', 'list', 'uniqeid', 'ping']
CommandAliases = ['stats', 'score', 'rank',
'myself', 'l', 'id', 'pb-id', 'pb', 'accountid']
def ExcelCommand(command, arguments, clientid, accountid):
@ -23,21 +24,18 @@ def ExcelCommand(command, arguments, clientid, accountid):
None
"""
if command in ['me', 'stats', 'score', 'rank', 'myself']:
fetch_send_stats(accountid,clientid)
fetch_send_stats(accountid, clientid)
elif command in ['list', 'l']:
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)
elif command in ['ping']:
get_ping(arguments, clientid)
def get_ping(arguments, clientid):
if arguments == [] or arguments == ['']:
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()
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]):
ping = _ba.get_client_ping(int(arguments[0]))
send(f" {name}'s ping {ping}ms", clientid)
@ -55,18 +53,19 @@ def get_ping(arguments, clientid):
return
def stats(ac_id,clientid):
stats=mystats.get_stats_by_id(ac_id)
def stats(ac_id, clientid):
stats = mystats.get_stats_by_id(ac_id)
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:
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):
_thread.start_new_thread(stats,(ac_id,clientid,))
def fetch_send_stats(ac_id, clientid):
_thread.start_new_thread(stats, (ac_id, clientid,))
def list(clientid):
@ -75,20 +74,16 @@ def list(clientid):
p = u'{0:^16}{1:^15}{2:^10}'
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()
for index, player in enumerate(session.sessionplayers):
list += p.format(player.getname(icon = False),
player.inputdevice.client_id, index)+"\n"
list += p.format(player.getname(icon=False),
player.inputdevice.client_id, index)+"\n"
send(list, clientid)
def accountid_request(arguments, clientid, accountid):
"""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)
except:
return

View file

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

View file

@ -33,6 +33,7 @@ from playersData import pdata
from features import EndVote
from features import text_on_map
from features import map_fun
from spazmod import modifyspaz
if TYPE_CHECKING:
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)
# ba_meta export plugin
class modSetup(ba.Plugin):
def on_app_running(self):
"""Runs when app is launched."""
@ -53,23 +56,24 @@ class modSetup(ba.Plugin):
if settings["afk_remover"]['enable']:
afk_check.checkIdle().start()
if(settings["useV2Account"]):
if (settings["useV2Account"]):
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")
else:
logging.warning("Account V2 login require ....stay tuned.")
ba.timer(3, ba.Call(logging.debug,"Starting Account V2 login process...."))
ba.timer(6,account.AccountUtil)
ba.timer(3, ba.Call(logging.debug,
"Starting Account V2 login process...."))
ba.timer(6, account.AccountUtil)
else:
ba.app.accounts_v2.set_primary_credentials(None)
ba.internal.sign_in_v1('Local')
ba.timer(60,playlist.flush_playlists)
ba.timer(60, playlist.flush_playlists)
def on_app_shutdown(self):
pass
def score_screen_on_begin(_stats: ba.Stats) -> None:
"""Runs when score screen is displayed."""
team_balancer.balanceTeams()
@ -154,12 +158,13 @@ def import_games():
maps = os.listdir("ba_root/mods/maps")
for _map in maps:
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:
"""Imports the dual team score."""
if settings["newResultBoard"]:
if settings["newResultBoard"] and _ba.get_foreground_host_session().use_teams:
dualteamscore.TeamVictoryScoreScreenActivity = newdts.TeamVictoryScoreScreenActivity
multiteamscore.MultiTeamScoreScreenActivity.show_player_scores = newdts.show_player_scores
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):
"""Runs when game is ended."""
activity = _ba.get_foreground_host_activity()
_ba.prop_axis(1,0,0)
_ba.prop_axis(1, 0, 0)
if isinstance(activity, CoopScoreScreen):
team_balancer.checkToExitCoop()
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
org_player_join = ba._activity.Activity.on_player_join
def on_player_join(self, player) -> None:
"""Runs when player joins the game."""
team_balancer.on_player_join()
org_player_join(self, player)
ba._activity.Activity.on_player_join = on_player_join
def night_mode() -> None:
"""Checks the time and enables night mode."""
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")
now = datetime.now()
@ -220,7 +223,8 @@ def night_mode() -> None:
activity.globalsnode.tint = (0.5, 0.7, 1.0)
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:
@ -241,7 +245,30 @@ def on_kick_vote_end():
def on_join_request(ip):
servercheck.on_join_request(ip)
def on_map_init():
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
import _ba, ba
import _ba
import ba
import ba.internal
import time
@ -69,13 +70,14 @@ def required_votes(players):
elif players == 10:
return 5
else:
return players - 4
return players - 5
def update_vote_text(votes_needed):
activity = _ba.get_foreground_host_activity()
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:
with _ba.Context(_ba.get_foreground_host_activity()):
node = ba.NodeActor(ba.newnode('text',
@ -99,4 +101,3 @@ def remove_vote_text():
activity = _ba.get_foreground_host_activity()
if hasattr(activity, "end_vote_text") and activity.end_vote_text.node.exists():
activity.end_vote_text.node.delete()

View file

@ -19,6 +19,8 @@ class checkIdle(object):
global cLastIdle
global cIdle
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:
last_input=int(player.inputdevice.get_last_input_time())
afk_time=int((current-last_input)/1000)

View file

@ -20,19 +20,20 @@ client = Bot(command_prefix='!', intents=intents)
# client = discord.Client()
stats={}
livestatsmsgs=[]
logsChannelID=859519868838608970
liveStatsChannelID=924697770554687548
liveChat=True
token=''
logs=[]
stats = {}
livestatsmsgs = []
logsChannelID = 859519868838608970
liveStatsChannelID = 924697770554687548
liveChat = True
token = ''
logs = []
def push_log(msg):
global logs
logs.append(msg)
def init():
loop = asyncio.get_event_loop()
@ -40,44 +41,51 @@ def init():
Thread(target=loop.run_forever).start()
channel=None
channel = None
@client.event
async def on_message(message):
global channel
if message.author == client.user:
return
channel=message.channel
channel = message.channel
if message.channel.id==logsChannelID:
_ba.pushcall(Call(ba.internal.chatmessage,message.content),from_other_thread=True)
if message.channel.id == logsChannelID:
_ba.pushcall(Call(ba.internal.chatmessage,
message.content), from_other_thread=True)
@client.event
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()
async def verify_channel():
global livestatsmsgs
channel=client.get_channel(liveStatsChannelID)
botmsg_count=0
channel = client.get_channel(liveStatsChannelID)
botmsg_count = 0
msgs = await channel.history(limit=5).flatten()
for msg in msgs:
if msg.author.id==client.user.id:
botmsg_count+=1
if msg.author.id == client.user.id:
botmsg_count += 1
livestatsmsgs.append(msg)
livestatsmsgs.reverse()
while(botmsg_count<2):
new_msg=await channel.send("msg reserved for live stats")
while (botmsg_count < 2):
new_msg = await channel.send("msg reserved for live stats")
livestatsmsgs.append(new_msg)
botmsg_count+=1
asyncio.run_coroutine_threadsafe(refresh_stats(),client.loop)
asyncio.run_coroutine_threadsafe(send_logs(),client.loop)
botmsg_count += 1
asyncio.run_coroutine_threadsafe(refresh_stats(), client.loop)
asyncio.run_coroutine_threadsafe(send_logs(), client.loop)
# client.loop.create_task(refresh_stats())
# client.loop.create_task(send_logs())
async def refresh_stats():
await client.wait_until_ready()
@ -87,62 +95,63 @@ async def refresh_stats():
await livestatsmsgs[1].edit(content=get_chats())
await asyncio.sleep(10)
async def send_logs():
global logs
# 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
channel=client.get_channel(logsChannelID)
channel = client.get_channel(logsChannelID)
await client.wait_until_ready()
while not client.is_closed():
if logs:
msg=''
msg = ''
for msg_ in logs:
msg+=msg_+"\n"
logs=[]
msg += msg_+"\n"
logs = []
if msg:
await channel.send(msg)
await asyncio.sleep(10)
def get_live_players_msg():
global stats
msg_1='***Live Stats :***\n\n ***Players in server***\n\n'
msg=''
msg_1 = '***Live Stats :***\n\n ***Players in server***\n\n'
msg = ''
try:
for id in stats['roster']:
name=stats['roster'][id]['name']
device_id=stats['roster'][id]['device_id']
msg+=id +" -> "+name+" -> "+device_id+" \n"
name = stats['roster'][id]['name']
device_id = stats['roster'][id]['device_id']
msg += id + " -> "+name+" -> "+device_id+" \n"
except:
pass
if not msg:
msg="```No one``` \n"
msg_2="\n\n***Current: *** "+stats['playlist']['current'] +"\n ***Next: ***"+stats['playlist']['next'] +"\n\n."
msg = "```No one``` \n"
msg_2 = "\n\n***Current: *** " + \
stats['playlist']['current'] + "\n ***Next: ***" + \
stats['playlist']['next'] + "\n\n."
return msg_1+msg+msg_2
def get_chats():
msg_1='***Live Chat***\n\n'
msg=''
msg_1 = '***Live Chat***\n\n'
msg = ''
try:
for msg_ in stats['chats']:
msg+=msg_+"\n"
msg += msg_+"\n"
except:
pass
if not msg:
msg= "```Empty```\n"
msg = "```Empty```\n"
if not liveChat:
return '```disabled```'
return msg_1+msg
class BsDataThread(object):
def __init__(self):
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)
# def refreshLeaderboard(self):
@ -165,33 +174,35 @@ class BsDataThread(object):
def refreshStats(self):
liveplayers={}
nextMap=''
currentMap=''
liveplayers = {}
nextMap = ''
currentMap = ''
global stats
for i in ba.internal.get_game_roster():
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:
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:
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
gametype: Type[GameActivity] =current_game_spec['resolved_type']
current_game_spec = ba.internal.get_foreground_host_session()._current_game_spec
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:
pass
minigame={'current':currentMap,'next':nextMap}
minigame = {'current': currentMap, 'next': nextMap}
# system={'cpu':p.cpu_percent(),'ram':p.virtual_memory().percent}
#system={'cpu':80,'ram':34}
# system={'cpu':80,'ram':34}
# stats['system']=system
stats['roster']=liveplayers
stats['chats']=ba.internal.get_chat_messages()
stats['playlist']=minigame
stats['roster'] = liveplayers
stats['chats'] = ba.internal.get_chat_messages()
stats['playlist'] = minigame
# stats['teamInfo']=self.getTeamInfo()

View file

@ -87,8 +87,8 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
kill_delay: float, shiftdelay: float) -> None:
del kill_delay # Unused arg.
ZoomText(ba.Lstr(value='${A}', subs=[('${A}', team.name)]),
position=(-250, 260) if pos_v == 65 else (250,260),
shiftposition=(-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),
shiftdelay=shiftdelay,
flash=False,
trail=False,
@ -101,10 +101,10 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
def _show_team_old_score(self, pos_v: float, sessionteam: ba.SessionTeam,
shiftdelay: float) -> None:
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,
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,
flash=False,
trail=False,
@ -118,10 +118,10 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
shiftdelay: float) -> None:
del kill_delay # Unused arg.
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,
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,
flash=scored,
trail=scored,
@ -137,26 +137,25 @@ class TeamVictoryScoreScreenActivity(MultiTeamScoreScreenActivity):
# ====================================================================================================
def show_player_scores(self,
delay: float = 2.5,
results: Optional[ba.GameResults] = None,
scale: float = 1.0,
x_offset: float = 0.0,
y_offset: float = 0.0) -> None:
"""Show scores for individual players."""
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
delay: float = 2.5,
results: Optional[ba.GameResults] = None,
scale: float = 1.0,
x_offset: float = 0.0,
y_offset: float = 0.0) -> None:
"""Show scores for individual players."""
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
ts_v_offset = 150.0 + y_offset
ts_h_offs = 80.0 + x_offset
tdelay = delay
spacing = 40
ts_v_offset = 150.0 + y_offset
ts_h_offs = 80.0 + x_offset
tdelay = delay
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:
assert isinstance(results, ba.GameResults)
assert p_rec.team.activityteam is not None
@ -164,7 +163,7 @@ def show_player_scores(self,
return val
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:
assert isinstance(results, ba.GameResults)
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
# (since they're not in results and that's where we pull their
# scores from)
if results is not None:
if results is not None:
assert isinstance(results, ba.GameResults)
player_records = []
assert self.stats
@ -199,23 +198,23 @@ def show_player_scores(self,
team.players[0])
if player_entry is not None:
player_records.append(player_entry)
else:
player_records = []
player_records_scores = [
else:
player_records = []
player_records_scores = [
(_get_prec_score(p), name, p)
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.
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
tdelay_team0=tdelay
voffs_team0 = voffs
tdelay_team0 = tdelay
def _txt(xoffs: float,
def _txt(xoffs: float,
yoffs: float,
text: ba.Lstr,
h_align: Text.HAlign = Text.HAlign.RIGHT,
@ -232,50 +231,50 @@ def show_player_scores(self,
transition=Text.Transition.IN_LEFT,
transition_delay=tdelay).autoretain()
session = self.session
assert isinstance(session, ba.MultiTeamSession)
if is_two_team:
tval = "Game "+str(session.get_game_number())+" Results"
session = self.session
assert isinstance(session, ba.MultiTeamSession)
if is_two_team:
tval = "Game "+str(session.get_game_number())+" Results"
_txt(-75,
160,
tval,
h_align=Text.HAlign.CENTER,
extrascale=1.4,
maxwidth=None)
_txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
_txt(180, 4, ba.Lstr(resource='killsText'))
_txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100)
_txt(-15, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
_txt(180, 4, ba.Lstr(resource='killsText'))
_txt(280, 4, ba.Lstr(resource='deathsText'), maxwidth=100)
score_label = 'Score' if results is None else results.score_label
translated = ba.Lstr(translate=('scoreNames', score_label))
score_label = 'Score' if results is None else results.score_label
translated = ba.Lstr(translate=('scoreNames', score_label))
_txt(390, 0, translated)
_txt(390, 0, translated)
if is_two_team:
_txt(-595, 4, ba.Lstr(resource='playerText'), h_align=Text.HAlign.LEFT)
if is_two_team:
_txt(-595, 4, ba.Lstr(resource='playerText'),
h_align=Text.HAlign.LEFT)
_txt(-400, 4, ba.Lstr(resource='killsText'))
_txt(-300, 4, ba.Lstr(resource='deathsText'), maxwidth=100)
_txt(-190, 0, translated)
topkillcount = 0
topkilledcount = 99999
top_score = 0 if not player_records else _get_prec_score(
topkillcount = 0
topkilledcount = 99999
top_score = 0 if not player_records else _get_prec_score(
player_records[0])
for prec in player_records:
for prec in player_records:
topkillcount = max(topkillcount, prec.accum_kill_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,
highlight: bool,
delay2: float,
maxwidth: float = 70.0,team_id=1) -> None:
maxwidth: float = 70.0, team_id=1) -> None:
Text(text,
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,
color=(1.0, 0.9, 0.5, 1.0) if highlight else
(0.5, 0.5, 0.6, 0.5),
@ -283,36 +282,30 @@ def show_player_scores(self,
v_align=Text.VAlign.CENTER,
maxwidth=maxwidth,
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:
if is_two_team and playerrec.team.id==0:
tdelay_team0 +=0.05
voffs_team0 -=spacing
x_image=617
x_text=-595
y=ts_v_offset + (voffs_team0 + 15.0) * scale
for playerrec in player_records:
if is_two_team and playerrec.team.id == 0:
tdelay_team0 += 0.05
voffs_team0 -= spacing
x_image = 617
x_text = -595
y = ts_v_offset + (voffs_team0 + 15.0) * scale
else:
else:
tdelay += 0.05
voffs -= spacing
x_image=12
x_text=10.0
y=ts_v_offset + (voffs + 15.0) * scale
x_image = 12
x_text = 10.0
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),
scale=(30.0 * scale, 30.0 * scale),
transition=Image.Transition.IN_LEFT,
transition_delay=tdelay if playerrec.team.id==1 else tdelay_team0).autoretain()
Text(ba.Lstr(value=playerrec.getname(full=True)),
transition_delay=tdelay if playerrec.team.id == 1 else tdelay_team0).autoretain()
Text(ba.Lstr(value=playerrec.getname(full=True)),
maxwidth=160,
scale=0.75 * scale,
position=(ts_h_offs + x_text * scale,
@ -321,16 +314,16 @@ def show_player_scores(self,
v_align=Text.VAlign.CENTER,
color=ba.safecolor(playerrec.team.color + (1, )),
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,
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,
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,
_get_prec_score(playerrec) == top_score, 0.2,team_id=0)
else:
_get_prec_score(playerrec) == top_score, 0.2, team_id=0)
else:
_scoretxt(str(playerrec.accum_kill_count), 180,
playerrec.accum_kill_count == topkillcount, 0.1)
_scoretxt(str(playerrec.accum_killed_count), 280,
@ -358,4 +351,4 @@ class DrawScoreScreenActivity(MultiTeamScoreScreenActivity):
trail=False,
jitter=1.0).autoretain()
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
def fireflies_generator(activity, count, random_color:False):
def fireflies_generator(activity, count, random_color: False):
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:
color=(0.9,0.7,0.0)
color = (0.9, 0.7, 0.0)
increment = count - len(activity.fireflies)
if increment > 0:
@ -64,25 +65,14 @@ class FireFly(ba.Actor):
('modify_part_collision', 'collide', False),
('modify_part_collision', 'physical', False),
))
self.node = ba.newnode(
'prop',
delegate=self,
attrs={
'model': ba.getmodel('bomb'),
'position': (2,4,2),
'body': 'capsule',
'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,
)
self.node = ba.newnode('locator', attrs={'shape': 'circle', 'position': (0, .5, 0),
'color': self.color, 'opacity': 0.5, 'draw_beauty': True, 'additive': False, 'size': [0.10]})
# ba.animate(
# self.node,
# 'scale',
# {0:0, 1:0.004, 5:0.006, 10:0.0},
# loop=True,
# )
ba.animate_array(
self.node,
'position',
@ -95,15 +85,15 @@ class FireFly(ba.Actor):
'light',
owner=self.node,
attrs={
'intensity':0.6,
'height_attenuated':True,
'radius':0.2,
'color':self.color
'intensity': 0.6,
'height_attenuated': True,
'radius': 0.2,
'color': self.color
})
ba.animate(
self.light,
'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
)
self.node.connectattr('position', self.light, 'position')
@ -119,7 +109,7 @@ class FireFly(ba.Actor):
ba.animate(
self.light,
'radius',
{0:self.light.radius, death_secs:0}
{0: self.light.radius, death_secs: 0}
)
ba.timer(death_secs, self.node.delete)
@ -129,24 +119,23 @@ class FireFly(ba.Actor):
return None
elif isinstance(msg, OutOfBoundsMessage):
return self.handlemessage(ba.DieMessage(how=DeathType.OUT_OF_BOUNDS))
return super().handlemessage(msg)
def generate_keys(self,m):
def generate_keys(self, m):
keys = {}
t = 0
last_x = random.randrange(int(m[0]),int(m[3]))
last_y = random.randrange(int(m[1]),int(m[4]))
last_x = random.randrange(int(m[0]), int(m[3]))
last_y = random.randrange(int(m[1]), int(m[4]))
if int(m[2]) == int(m[5]):
last_z = int(m[2])
else:
last_z = random.randrange(int(m[2]),int(m[5]))
for i in range(0,7):
x = self.generate_random(int(m[0]),int(m[3]),last_x)
last_z = random.randrange(int(m[2]), int(m[5]))
for i in range(0, 7):
x = self.generate_random(int(m[0]), int(m[3]), last_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
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
keys[t] = (x, abs(y), z)
t += 30
@ -156,7 +145,7 @@ class FireFly(ba.Actor):
if a == b:
return a
while True:
n = random.randrange(a,b)
n = random.randrange(a, b)
if abs(z-n) < 6:
return n
@ -166,6 +155,5 @@ def on_begin(self, *args, **kwargs) -> None:
return on_begin_original(self, *args, **kwargs)
ba._activity.Activity.fireflies_generator = fireflies_generator
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 random
def decorate_map():
try:
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_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]
m = 5
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"
except:
pass

View file

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

View file

@ -8,100 +8,124 @@ import ba.internal
import setting
from stats import mystats
from datetime import datetime
from spazmod import modifyspaz
import random
setti=setting.get_settings_data()
class textonmap:
def __init__(self):
modifyspaz.setTeamCharacter()
data = setti['textonmap']
left = data['bottom left watermark']
top = data['top watermark']
nextMap=""
try:
def __init__(self):
data = setti['textonmap']
left = data['bottom left watermark']
top = data['top watermark']
nextMap=""
try:
nextMap=ba.internal.get_foreground_host_session().get_next_game_description().evaluate()
except:
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()
except:
pass
self.index = 0
self.highlights = data['center highlights']["msg"]
self.left_watermark(left)
self.top_message(top)
self.nextGame(nextMap)
if setti["leaderboard"]["enable"]:
self.leaderBoard()
self.timer = ba.timer(8, ba.Call(self.highlights_), repeat=True)
def highlights_(self):
if setti["textonmap"]['center highlights']["randomColor"]:
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
})
def highlights_(self):
if setti["textonmap"]['center highlights']["randomColor"]:
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)
self.index = int((self.index+1)%len(self.highlights))
self.delt = ba.timer(7,node.delete)
self.index = int((self.index+1)%len(self.highlights))
def left_watermark(self, text):
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):
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,18),
'color':(0.5,0.5,0.5)
})
def top_message(self, text):
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):
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):
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)
})
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)})
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)})
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':"#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':"#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)})
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 json
import datetime
from tools.ServerUpdate import contributeData , checkSpammer
import setting
if TYPE_CHECKING:
pass
setti=setting.get_settings_data()
PLAYERS_DATA_PATH = os.path.join(
_ba.env()["python_directory_user"], "playersData" + os.sep
@ -67,7 +71,10 @@ def get_profiles() -> dict:
if CacheData.profiles=={}:
try:
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":{}}
print("resetting profiles")
else:
@ -167,11 +174,13 @@ def add_profile(
for ros in ba.internal.get_game_roster():
if ros['account_id'] == account_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)
if(device_id==None):
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"]:
serverdata.clients[account_id]["isBan"]=True
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)
light = ba.newnode(
"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)

View file

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

View file

@ -18,8 +18,8 @@ from bastd.actor.spaz import Spaz
if TYPE_CHECKING:
pass
class MikiWavedashTest:
class MikiWavedashTest:
class FootConnectMessage:
"""Spaz started touching the ground"""
@ -31,7 +31,8 @@ class MikiWavedashTest:
if not self.node:
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:
return
@ -49,35 +50,38 @@ class MikiWavedashTest:
move_length = math.hypot(move[0], move[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]
vel_norm = [v/vel_length for v in vel]
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)
if turn_power < 0.2: return
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)
if turn_power < 0.2:
return
boost_power = math.sqrt(math.pow(vel[0],2) + math.pow(vel[1],2)) * 1.2
boost_power = min(pow(boost_power,4),160)
#print(boost_power * turn_power)
boost_power = math.sqrt(
math.pow(vel[0], 2) + math.pow(vel[1], 2)) * 1.2
boost_power = min(pow(boost_power, 4), 160)
# print(boost_power * turn_power)
self.last_wavedash_time_ms = t_ms
# FX
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',
count=8,
scale=boost_power / 160 * turn_power,
spread=0.25);
spread=0.25)
# Boost itself
pos = self.node.position
for i in range(6):
self.node.handlemessage('impulse',pos[0],-0.1+pos[1]+i*0.1,pos[2],
0,0,0,
boost_power * turn_power,
boost_power * turn_power,0,0,
move[0],0,move[1])
self.node.handlemessage('impulse', pos[0], -0.1+pos[1]+i*0.1, pos[2],
0, 0, 0,
boost_power * turn_power,
boost_power * turn_power, 0, 0,
move[0], 0, move[1])
def new_spaz_init(func):
def wrapper(*args, **kwargs):
@ -90,29 +94,34 @@ class MikiWavedashTest:
args[0].grounded = 0
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 wrapper(*args, **kwargs):
func(*args, **kwargs)
args[0].roller_material.add_actions(
conditions=('they_have_material', bastd.gameutils.SharedObjects.get().footing_material),
actions=(('message', 'our_node', 'at_connect', MikiWavedashTest.FootConnectMessage),
('message', 'our_node', 'at_disconnect', MikiWavedashTest.FootDisconnectMessage)))
conditions=('they_have_material',
bastd.gameutils.SharedObjects.get().footing_material),
actions=(('message', 'our_node', 'at_connect', MikiWavedashTest.FootConnectMessage),
('message', 'our_node', 'at_disconnect', MikiWavedashTest.FootDisconnectMessage)))
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 wrapper(*args, **kwargs):
if args[1] == MikiWavedashTest.FootConnectMessage:
args[0].grounded += 1
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)
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 wrapper(*args, **kwargs):

View file

@ -4,6 +4,7 @@
"""Functionality related to player-controlled Spazzes."""
from __future__ import annotations
from ba._generated.enums import TimeType
from typing import TYPE_CHECKING, TypeVar, overload
from bastd.actor.spaz import *
from bastd.gameutils import SharedObjects
@ -12,30 +13,40 @@ from bastd.actor import playerspaz
from bastd.actor.playerspaz import *
from bastd.actor.spazfactory import SpazFactory
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.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
from playersData import pdata
from stats import mystats
PlayerType = TypeVar('PlayerType', bound=ba.Player)
TeamType = TypeVar('TeamType', bound=ba.Team)
from ba._generated.enums import TimeType
tt = ba.TimeType.SIM
tf = ba.TimeFormat.MILLISECONDS
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)),
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)),
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)),
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)),
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)),
2500:((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)),
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)),
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)),
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)),
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)),
2500: ((0+random.random()*3.0), (0+random.random()*3.0), (0+random.random()*3.0))}
class SurroundBallFactory(object):
def __init__(self):
@ -54,10 +65,13 @@ class SurroundBallFactory(object):
try:
self.mikuModel = ba.getmodel("operaSingerHead")
self.mikuTex = ba.gettexture("operaSingerColor")
except:ba.print_exception()
except:
ba.print_exception()
self.ballMaterial = ba.Material()
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):
def __init__(self, spaz, shape="bones"):
@ -73,7 +87,8 @@ class SurroundBall(ba.Actor):
"frosty": (factory.frostyModel, factory.frostyTex),
"RedCube": (factory.cubeModel, factory.cubeTex)
}.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.surroundRadius = 1.0
self.angleDelta = math.pi / 12.0
@ -87,15 +102,18 @@ class SurroundBall(ba.Actor):
def getTargetPosition(self, 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.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
def initTimer(self, 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):
spaz = self.spazRef()
@ -117,20 +135,23 @@ class SurroundBall(ba.Actor):
def handlemessage(self, m):
ba.Actor.handlemessage(self, m)
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()
elif isinstance(m, ba.OutOfBoundsMessage):
self.handlemessage(ba.DieMessage())
def getFactory(cls):
activity = ba.getactivity()
if activity is None: raise Exception("no current activity")
if activity is None:
raise Exception("no current activity")
try:
return activity._sharedSurroundBallFactory
except Exception:
f = activity._sharedSurroundBallFactory = SurroundBallFactory()
return f
class Effect(ba.Actor):
def __init__(self, spaz, player):
ba.Actor.__init__(self)
@ -166,36 +187,42 @@ class Effect(ba.Actor):
try:
if cl_str in custom_effects:
effect = custom_effects[cl_str]
if effect == 'ice':
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
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
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
elif effect == 'glow':
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
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
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
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
elif effect == 'surrounder':
self.surround = SurroundBall(spaz, shape="bones")
return
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
except:
pass
@ -206,29 +233,36 @@ class Effect(ba.Actor):
rank = pats[cl_str]["rank"]
if rank < 6:
if rank == 1:
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.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:
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:
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:
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)
else:
self.addLightColor((1, 0.6, 0.4));self.checkDeadTimer = ba.Timer(150, self.checkPlayerifDead, repeat=True, timetype=tt, timeformat=tf)
self.addLightColor((1, 0.6, 0.4))
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:
#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():
#print("OK")
self.source_player.actor.node.addDeathAction(ba.Call(self.handlemessage,ba.DieMessage()))
# print("OK")
self.source_player.actor.node.addDeathAction(
ba.Call(self.handlemessage, ba.DieMessage()))
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):
spaz = self.spazRef()
@ -240,53 +274,66 @@ class Effect(ba.Actor):
def update_Scorch(self):
spaz = self.spazRef()
if spaz is not None and spaz.is_alive() and spaz.node.exists():
color = (random.random(),random.random(),random.random())
if not hasattr(self,"scorchNode") or self.scorchNode == None:
color = (random.random(), random.random(), random.random())
if not hasattr(self, "scorchNode") or self.scorchNode == None:
self.scorchNode = None
self.scorchNode = ba.newnode("scorch",attrs={"position":(spaz.node.position),"size":1.17,"big":True})
spaz.node.connectattr("position",self.scorchNode,"position")
ba.animate_array(self.scorchNode,"color",3,{0:self.scorchNode.color,500:color}, timetype=tt, timeformat=tf)
self.scorchNode = ba.newnode("scorch", attrs={"position": (
spaz.node.position), "size": 1.17, "big": True})
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:
self.scorchTimer = None
if hasattr(self,"scorchNode"):
if hasattr(self, "scorchNode"):
self.scorchNode.delete()
self.handlemessage(ba.DieMessage())
def neonLightSwitch(self,shine,Highlight,NameColor):
def neonLightSwitch(self, shine, Highlight, NameColor):
spaz = self.spazRef()
if spaz is not None and spaz.is_alive() and spaz.node.exists():
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 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)
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 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:
#print spaz.node.highlight
color = (random.random(),random.random(),random.random())
if shine: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)
# print spaz.node.highlight
color = (random.random(), random.random(), random.random())
if shine:
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:
self.neroLightTimer = None
self.handlemessage(ba.DieMessage())
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")
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):
spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage())
return
ba.emitfx(position=spaz.node.position,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")
ba.emitfx(position=spaz.node.position,
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):
spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage())
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):
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():
self.handlemessage(ba.DieMessage())
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):
spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage())
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):
spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage())
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):
spaz = self.spazRef()
if spaz is None or not spaz.is_alive() or not spaz.node.exists():
self.handlemessage(ba.DieMessage())
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):
#self._handlemessageSanityCheck()
if isinstance(m, ba.OutOfBoundsMessage): self.handlemessage(ba.DieMessage())
# self._handlemessageSanityCheck()
if isinstance(m, ba.OutOfBoundsMessage):
self.handlemessage(ba.DieMessage())
elif isinstance(m, ba.DieMessage):
if hasattr(self,"light") and self.light is not None:self.light.delete()
if hasattr(self,"smokeTimer"):self.smokeTimer = None
if hasattr(self,"surround"):self.surround = None
if hasattr(self,"sparkTimer"):self.sparkTimer = None
if hasattr(self,"snowTimer"):self.snowTimer = None
if hasattr(self,"metalTimer"):self.metalTimer = None
if hasattr(self,"DistortionTimer"):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 hasattr(self, "light") and self.light is not None:
self.light.delete()
if hasattr(self, "smokeTimer"):
self.smokeTimer = None
if hasattr(self, "surround"):
self.surround = None
if hasattr(self, "sparkTimer"):
self.sparkTimer = None
if hasattr(self, "snowTimer"):
self.snowTimer = None
if hasattr(self, "metalTimer"):
self.metalTimer = None
if hasattr(self, "DistortionTimer"):
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:
spaz = self.spazRef()
#print str(spaz) + "Spaz"
if spaz is not None and spaz.is_alive() and spaz.node.exists(): spaz.node.color = self.spazNormalColor
# print str(spaz) + "Spaz"
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
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:
killer = None
#if hasattr(self,"hasDead") and not self.hasDead:
# if hasattr(self,"hasDead") and not self.hasDead:
self._hasDead = True
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 = {}
# Don't touch the above line
"""
@ -6,19 +24,7 @@ Provides functionality for dumping player stats to disk between rounds.
"""
ranks = []
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.
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
our_settings = setting.get_settings_data()
@ -66,7 +72,6 @@ statsDefault = {
# useful functions
seasonStartDate = None
import shutil, os
def get_all_stats():
@ -77,12 +82,14 @@ def get_all_stats():
try:
jsonData = json.loads(f.read())
except:
f=open(statsfile+".backup",encoding='utf-8')
jsonData=json.load(f)
f = open(statsfile+".backup", encoding='utf-8')
jsonData = json.load(f)
try:
stats = jsonData["stats"]
seasonStartDate = datetime.datetime.strptime(jsonData["startDate"], "%d-%m-%Y")
seasonStartDate = datetime.datetime.strptime(
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"]:
backupStatsFile()
seasonStartDate = datetime.datetime.now()
@ -96,7 +103,8 @@ def get_all_stats():
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):
@ -105,7 +113,7 @@ def dump_stats(s: dict):
seasonStartDate = datetime.datetime.now()
s = {"startDate": seasonStartDate.strftime("%d-%m-%Y"), "stats": s}
if os.path.exists(statsfile):
shutil.copyfile(statsfile,statsfile+".backup")
shutil.copyfile(statsfile, statsfile+".backup")
with open(statsfile, 'w', encoding='utf8') as f:
f.write(json.dumps(s, indent=4, ensure_ascii=False))
f.close()
@ -128,7 +136,8 @@ def refreshStats():
# f=open(htmlfile, 'w')
# 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
entries.sort(key=lambda x: x[1] or 0, reverse=True)
rank = 0
@ -144,7 +153,8 @@ def refreshStats():
games = str(entry[3])
name = str(entry[4])
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
try:
kd = str(float(kills) / float(deaths))
@ -162,7 +172,8 @@ def refreshStats():
p_avg_score = "0"
if damage_data and aid in damage_data:
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:
dmg = 0
@ -170,30 +181,14 @@ def refreshStats():
pStats[str(aid)]["rank"] = int(rank)
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)]["kills"] = int(kills)
pStats[str(aid)]["deaths"] = int(deaths)
pStats[str(aid)]["kd"] = float(p_kd)
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
ranks = _ranks
@ -326,8 +321,6 @@ def updateTop3Names(ids):
raise ValueError
except ValueError:
names.append("???")
else:
names.append(name)
top3Name = names

View file

@ -4,59 +4,82 @@ import _thread
import urllib.request
from efro.terminal import Clr
import json
import requests
import _ba
VERSION=71
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():
profiles=pdata.get_profiles()
profiles=pdata.get_profiles()
for id in profiles:
if "spamCount" not in profiles[id]:
profiles[id]["spamCount"]=0
profiles[id]["lastSpam"]=time.time()
for id in profiles:
if "spamCount" not in profiles[id]:
profiles[id]["spamCount"]=0
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():
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:
try:
data=urllib.request.urlopen(url)
changelog=json.loads(data.read())
except:
return None
else:
return changelog
if 2*2==4:
try:
data=urllib.request.urlopen(url)
changelog=json.loads(data.read())
except:
return None
else:
return changelog
def checkChangelog():
changelog=fetchChangelogs()
if changelog==None:
print(f'{Clr.BRED} UNABLE TO CHECK UPDATES , CHECK MANUALLY FROM URL {Clr.RST}',flush=True)
else:
msg=""
avail=False
for log in changelog:
if int(log)>VERSION:
avail=True
changelog=fetchChangelogs()
if changelog==None:
print(f'{Clr.BRED} UNABLE TO CHECK UPDATES , CHECK MANUALLY FROM URL {Clr.RST}',flush=True)
else:
msg=""
avail=False
for log in changelog:
if int(log)>VERSION:
avail=True
if not avail:
print(f'{Clr.BGRN}{Clr.WHT} YOU ARE ON LATEST VERSION {Clr.RST}',flush=True)
else:
print(f'{Clr.BYLW}{Clr.BLU} UPDATES AVAILABLE {Clr.RST}',flush=True)
for log in changelog:
if int(log)>VERSION:
msg=changelog[log]["time"]
print(f'{Clr.CYN} {msg} {Clr.RST}',flush=True)
if not avail:
print(f'{Clr.BGRN}{Clr.WHT} YOU ARE ON LATEST VERSION {Clr.RST}',flush=True)
else:
print(f'{Clr.BYLW}{Clr.BLU} UPDATES AVAILABLE {Clr.RST}',flush=True)
for log in changelog:
if int(log)>VERSION:
msg=changelog[log]["time"]
print(f'{Clr.CYN} {msg} {Clr.RST}',flush=True)
msg=changelog[log]["log"]
print(f'{Clr.MAG} {msg} {Clr.RST}',flush=True)
msg=changelog[log]["log"]
print(f'{Clr.MAG} {msg} {Clr.RST}',flush=True)