async def remove_initiative_effect(sid: str, data: ServerRemoveInitiativeEffectActor): pr: PlayerRoom = game_state.get(sid) if not has_ownership(Shape.get_or_none(uuid=data["shape"]), pr): logger.warning( f"{pr.player.name} attempted to remove an initiative effect") return location_data = Initiative.get(location=pr.active_location) with db.atomic(): json_data = json.loads(location_data.data) for initiative in json_data: if initiative["shape"] == data["shape"]: initiative["effects"].pop(data["index"]) location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Effect.Remove", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_initiative_option(sid: str, data: ServerInitiativeOption): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data["shape"]) if not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to change initiative of an asset it does not own" ) return location_data = Initiative.get_or_none(location=pr.active_location) if location_data is None: logger.error( "Initiative updated for location without initiative tracking") return json_data = json.loads(location_data.data) with db.atomic(): for i, initiative_data in enumerate(json_data): if initiative_data["shape"] == data["shape"]: json_data[i][data["option"]] = data["value"] break location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Option.Set", data, skip_sid=sid, room=pr.active_location.get_path(), namespace=GAME_NS, )
async def set_initiative_value(sid: str, data: ServerSetInitiativeValue): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to remove initiative of an asset it does not own" ) return with db.atomic(): location_data = Initiative.get(location=pr.active_location) json_data = json.loads(location_data.data) for initiative in json_data: if initiative["shape"] == data["shape"]: initiative["initiative"] = data["value"] break json_data = sort_initiative(json_data, location_data.sort) location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Set", location_data.as_dict(), room=pr.active_location.get_path(), namespace=GAME_NS, )
async def update_initiative_round(sid: str, data: int): pr: PlayerRoom = game_state.get(sid) location_data = Initiative.get(location=pr.active_location) if pr.role != Role.DM: json_data = json.loads(location_data.data) if not has_ownership( Shape.get_or_none(uuid=json_data[location_data.turn]["shape"]), pr): logger.warning( f"{pr.player.name} attempted to advance the initiative tracker" ) return with db.atomic(): location_data.round = data location_data.save() await sio.emit( "Initiative.Round.Update", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def remove_initiative(sid: str, data: str): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to remove initiative of an asset it does not own" ) return with db.atomic(): location_data = Initiative.get(location=pr.active_location) json_data = json.loads(location_data.data) location_data.data = json.dumps([ initiative for initiative in json_data if initiative["shape"] != data ]) location_data.save() await sio.emit( "Initiative.Remove", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_shape_options(sid: str, data: OptionUpdateList): pr: PlayerRoom = game_state.get(sid) shapes: List[Tuple[Shape, OptionUpdate]] = [] for sh in data["options"]: shape = Shape.get_or_none(Shape.uuid == sh["uuid"]) if shape is not None and not has_ownership(shape, pr, movement=True): logger.warning( f"User {pr.player.name} attempted to change options for a shape it does not own." ) return shapes.append((shape, sh)) if not data["temporary"]: with db.atomic(): for db_shape, data_shape in shapes: db_shape.options = data_shape["option"] db_shape.save() await sio.emit( "Shapes.Options.Update", data["options"], room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_shape_positions(sid: str, data: PositionUpdateList): pr: PlayerRoom = game_state.get(sid) shapes: List[Tuple[Shape, PositionUpdate]] = [] for sh in data["shapes"]: shape = Shape.get_or_none(Shape.uuid == sh["uuid"]) if shape is not None and not has_ownership(shape, pr, movement=True): logger.warning( f"User {pr.player.name} attempted to move a shape it does not own." ) return shapes.append((shape, sh)) if not data["temporary"]: with db.atomic(): for db_shape, data_shape in shapes: points = data_shape["position"]["points"] db_shape.x = points[0][0] db_shape.y = points[0][1] db_shape.angle = data_shape["position"]["angle"] db_shape.save() if len(points) > 1: # Subshape type_instance = db_shape.subtype type_instance.set_location(points[1:]) await sio.emit( "Shapes.Position.Update", data["shapes"], room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def remove_initiative_effect(sid: str, data: ServerInitiativeEffectActor): pr: PlayerRoom = game_state.get(sid) if not has_ownership(Shape.get_or_none(uuid=data["actor"]), pr): logger.warning( f"{pr.player.name} attempted to remove an initiative effect") return with db.atomic(): effect = InitiativeEffect.get(uuid=data["effect"]["uuid"]) effect.delete_instance() await sio.emit( "Initiative.Effect.Remove", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_initiative_turn(sid: str, turn: int): pr: PlayerRoom = game_state.get(sid) location_data: Initiative = Initiative.get(location=pr.active_location) json_data = json.loads(location_data.data) if pr.role != Role.DM and not has_ownership( Shape.get_or_none(uuid=json_data[location_data.turn]["shape"]), pr): logger.warning( f"{pr.player.name} attempted to advance the initiative tracker") return with db.atomic(): nextTurn = turn > location_data.turn location_data.turn = turn for i, effect in enumerate(json_data[turn]["effects"][-1:]): try: turns = int(effect["turns"]) if turns <= 0 and nextTurn: json_data[turn]["effects"].pop(i) elif turns > 0 and nextTurn: effect["turns"] = str(turns - 1) else: effect["turns"] = str(turns + 1) except ValueError: # For non-number inputs do not update the effect pass location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Turn.Update", turn, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_initiative_effect(sid: int, data: Dict[str, Any]): pr: PlayerRoom = game_state.get(sid) if not has_ownership(Shape.get_or_none(uuid=data["actor"]), pr): logger.warning( f"{pr.player.name} attempted to update an initiative effect") return with db.atomic(): effect = InitiativeEffect.get(uuid=data["effect"]["uuid"]) update_model_from_dict( effect, reduce_data_to_model(InitiativeEffect, data["effect"])) effect.save() await sio.emit( "Initiative.Effect.Update", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def new_initiative_effect(sid: int, data: Dict[str, Any]): pr: PlayerRoom = game_state.get(sid) if not has_ownership(Shape.get_or_none(uuid=data["actor"]), pr): logger.warning( f"{pr.player.name} attempted to create a new initiative effect") return InitiativeEffect.create( initiative=data["actor"], uuid=data["effect"]["uuid"], name=data["effect"]["name"], turns=data["effect"]["turns"], ) await sio.emit( "Initiative.Effect.New", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def add_initiative(sid: str, data: ServerInitiativeData): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to add initiative to an asset it does not own" ) return with db.atomic(): location_data, _ = Initiative.get_or_create( location=pr.active_location, defaults={ "round": 0, "turn": 0, "data": "[]" }) json_data = json.loads(location_data.data) for initiative in json_data: if initiative["shape"] == data["shape"]: initiative.update(**data) break else: json_data.append(data) location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Set", location_data.as_dict(), room=pr.active_location.get_path(), namespace=GAME_NS, )
async def remove_initiative(sid: int, data: Dict[str, Any]): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to remove initiative of an asset it does not own" ) return initiative = Initiative.get_or_none(uuid=data) location_data = InitiativeLocationData.get_or_none( location=pr.active_location) if initiative: with db.atomic(): Initiative.update( index=Initiative.index - 1).where((Initiative.location_data == location_data) & (Initiative.index >= initiative.index)) initiative.delete_instance(True) await send_client_initiatives(pr)
async def update_initiative(sid: int, data: Dict[str, Any]): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data["uuid"]) if not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to change initiative of an asset it does not own" ) return location_data = InitiativeLocationData.get_or_none( location=pr.active_location) if location_data is None: location_data = InitiativeLocationData.create( location=pr.active_location, turn=data["uuid"], round=1) initiatives = Initiative.select().where( Initiative.location_data == location_data) initiative = Initiative.get_or_none(uuid=data["uuid"]) # Create new initiative if initiative is None: with db.atomic(): # Update indices try: index = (initiatives.where( Initiative.initiative >= data["initiative"]).order_by( -Initiative.index)[0].index + 1) except IndexError: index = 0 else: Initiative.update( index=Initiative.index + 1).where((Initiative.location_data == location_data) & (Initiative.index >= index)) # Create model instance initiative = dict_to_model(Initiative, reduce_data_to_model(Initiative, data)) initiative.location_data = location_data initiative.index = index initiative.save(force_insert=True) # Update initiative else: with db.atomic(): if data["initiative"] != initiative.initiative: # Update indices old_index = initiative.index try: new_index = (initiatives.where( Initiative.initiative >= data["initiative"]).order_by( -Initiative.index)[0].index) except IndexError: new_index = 0 else: if new_index < old_index: new_index += 1 if old_index != new_index: # SIGN=1 IF old_index > new_index WHICH MEANS the initiative is increased # SIGN=-1 IF old_index < new_index WHICH MEANS the initiative is decreased sign = (old_index - new_index) // abs(old_index - new_index) indices = [0, old_index, new_index] update = Initiative.update( index=Initiative.index + sign).where((Initiative.location_data == location_data) & (Initiative.index <= indices[sign]) & (Initiative.index >= indices[-sign])) update.execute() data["index"] = new_index # Update model instance update_model_from_dict(initiative, reduce_data_to_model(Initiative, data)) initiative.save() data["index"] = initiative.index await send_client_initiatives(pr)
async def update_initiative(sid, data): sid_data = state.sid_map[sid] user = sid_data["user"] room = sid_data["room"] location = sid_data["location"] shape = Shape.get_or_none(uuid=data["uuid"]) owner = ShapeOwner.get_or_none(shape=shape, user=user) is not None if room.creator != user and not owner: logger.warning( f"{user.name} attempted to change initiative of an asset it does not own" ) return used_to_be_visible = False location_data = InitiativeLocationData.get_or_none(location=location) if location_data is None: location_data = InitiativeLocationData.create(location=location, turn=data["uuid"], round=1) initiatives = Initiative.select().where( Initiative.location_data == location_data) initiative = Initiative.get_or_none(uuid=data["uuid"]) # Create new initiative if initiative is None: with db.atomic(): # Update indices try: index = (initiatives.where( Initiative.initiative >= data["initiative"]).order_by( -Initiative.index)[0].index + 1) except IndexError: index = 0 else: Initiative.update( index=Initiative.index + 1).where((Initiative.location_data == location_data) & (Initiative.index >= index)) # Create model instance initiative = dict_to_model(Initiative, reduce_data_to_model(Initiative, data)) initiative.location_data = location_data initiative.index = index initiative.save(force_insert=True) # Remove initiative elif "initiative" not in data: with db.atomic(): Initiative.update( index=Initiative.index - 1).where((Initiative.location_data == location_data) & (Initiative.index >= initiative.index)) initiative.delete_instance(True) # Update initiative else: used_to_be_visible = initiative.visible with db.atomic(): if data["initiative"] != initiative.initiative: # Update indices old_index = initiative.index try: new_index = (initiatives.where( Initiative.initiative >= data["initiative"]).order_by( -Initiative.index)[0].index) except IndexError: new_index = 0 else: if new_index < old_index: new_index += 1 if old_index != new_index: # SIGN=1 IF old_index > new_index WHICH MEANS the initiative is increased # SIGN=-1 IF old_index < new_index WHICH MEANS the initiative is decreased sign = (old_index - new_index) // abs(old_index - new_index) indices = [0, old_index, new_index] update = Initiative.update( index=Initiative.index + sign).where((Initiative.location_data == location_data) & (Initiative.index <= indices[sign]) & (Initiative.index >= indices[-sign])) update.execute() data["index"] = new_index # Update model instance update_model_from_dict(initiative, reduce_data_to_model(Initiative, data)) initiative.save() data["index"] = initiative.index await send_client_initiatives(room, location)