Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions cc2me/savedata/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os
import random
from abc import ABC
from enum import Enum
from typing import cast, List, Optional, Union
from typing import cast, List, Optional, Union, Dict
from xml.etree import ElementTree
from xml.etree.ElementTree import Element

MAX_INTEGER = 4294967295

Expand Down Expand Up @@ -421,10 +424,14 @@ def __init__(self, count: int, *vtype: VehicleType):
AmmunitionCapacity(a_type, 1,
VehicleType.Manta, VehicleType.Petrel, VehicleType.Razorbill, VehicleType.Albatross))

ATTACHMENT_CAPACITY.append(
ATTACHMENT_CAPACITY.extend([
AmmunitionCapacity(VehicleAttachmentDefinitionIndex.Gun20mm,
500, VehicleType.Mule
),
AmmunitionCapacity(VehicleAttachmentDefinitionIndex.Gun40mm,
500, VehicleType.Mule
)
]
)
ATTACHMENT_CAPACITY.append(
AmmunitionCapacity(VehicleAttachmentDefinitionIndex.Refuel,
Expand All @@ -441,6 +448,11 @@ def __init__(self, count: int, *vtype: VehicleType):
400, VehicleType.Mule
)
)
ATTACHMENT_CAPACITY.append(
AmmunitionCapacity(VehicleAttachmentDefinitionIndex.Rearm40mm,
300, VehicleType.Mule
)
)
ATTACHMENT_CAPACITY.extend(
[
AmmunitionCapacity(VehicleAttachmentDefinitionIndex.BattleDroids,
Expand Down Expand Up @@ -508,3 +520,33 @@ def get_default_state(v_type: VehicleType) -> List[Capacity]:
if v_type in item.vtypes:
values.append(item)
return values


def get_cc2_appdata() -> str:
cc2dir = os.path.expandvars(r'%APPDATA%\\Carrier Command 2')
return cc2dir


def get_persistent_file_path() -> str:
persistent = os.path.join(get_cc2_appdata(), "persistent_data.xml")
return persistent


def read_save_slots(slots_file: Optional[str] = None) -> List[Dict[str, str]]:
if slots_file is None:
slots_file = get_persistent_file_path()
slots = []
with open(slots_file, "r") as xmlfile:
xml = xmlfile.read()
etree = ElementTree.fromstring(xml)
for item in etree:
if isinstance(item, Element):
filename = item.attrib.get("save_name")
text = item.attrib.get("display_name")
if filename:
slots.append({
"filename": filename,
"display": text
})
return slots

38 changes: 36 additions & 2 deletions cc2me/savedata/loader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, List
from typing import Optional, List, Tuple
from xml.etree.ElementTree import Element
import os
import re
Expand All @@ -8,9 +8,9 @@
from .types.abstract import CC2Save
from .types.teams import Team
from .types.tiles import Tile
from .types.spawndata import VehicleSpawnData, VehicleSpawn
from .types.vehicles.vehicle import Vehicle
from .types.vehicles.vehicle_state import VehicleStateContainer
from ..paths import SCHEMA
from .logging import logger
from .constants import POS_Y_SEABOTTOM, BIOME_SANDY_PINES, VehicleType, get_default_state

Expand Down Expand Up @@ -125,6 +125,20 @@ def tile(self, tile_id: int) -> Tile:

raise KeyError(tile_id)

def spawn(self, spawn_id: int) -> Optional[VehicleSpawn]:
for tile in self.tiles:
for spawn in tile.spawn_data.vehicles.items():
if spawn.data.respawn_id == spawn_id:
return spawn
return None

def get_spawn_tile(self, spawn_id: int) -> Tuple[Optional[Tile], Optional[VehicleSpawn]]:
for tile in self.tiles:
for spawn in tile.spawn_data.vehicles.items():
if spawn.data.respawn_id == spawn_id:
return tile, spawn
return None, None

def find_vehicles_by_definition(self, definition_id: int):
return [
x for x in self.vehicles if x.definition_index == definition_id
Expand Down Expand Up @@ -181,6 +195,17 @@ def remove_vehicle(self, vehicle: Vehicle):
vsparent = self.vehicle_states_parent

if vehicle:
if vehicle.definition_index == VehicleType.Jetty.value:
return # dont' delete a jetty, it causes problems if the carrier isnt launched
if vehicle.definition_index == VehicleType.Carrier.value:
# if this is the last carrier a team has, mark the team as destroyed.
team_carriers = [x for x in self.vehicles
if x.team_id == vehicle.team_id and x.definition_index == vehicle.definition_index]
if len(team_carriers) == 1:
# destroy the team
team = self.team(vehicle.team_id)
team.is_destroyed = True

vid = str(vehicle.id)
state = vehicle.state
if state:
Expand All @@ -190,6 +215,15 @@ def remove_vehicle(self, vehicle: Vehicle):
ve = [x for x in vparent if x.attrib.get("id") == vid]
if ve:
vparent.remove(ve[0])
# if there was a spawn, remove that too
spawn = self.spawn(vehicle.id)
if spawn:
self.remove_spawn(vehicle.id)

def remove_spawn(self, spawn_id: int):
tile, spawn = self.get_spawn_tile(spawn_id)
if spawn and tile:
tile.spawn_data.vehicles.remove(spawn_id)

@property
def _teams(self) -> List[Element]:
Expand Down
18 changes: 14 additions & 4 deletions cc2me/savedata/types/spawndata.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import cast, Iterable, Optional, List, Any
from typing import cast, Iterable, Optional, List, Any, Union
from xml.etree.ElementTree import Element

from .utils import ElementProxy, IsSetMixin, e_property, IntAttribute, FloatAttribute, WorldPosition, \
Expand Down Expand Up @@ -70,6 +70,11 @@ def move(self, x: float, y: float, z: float) -> None:
self.data.world_position.y = y
self.data.world_position.z = z

def translate(self, dx: float, dy: float, dz: float) -> None:
self.move(self.data.world_position.x + dx,
self.data.world_position.y + dy,
self.data.world_position.z + dz)

@property
def loc(self) -> Location:
pos = self.data.world_position
Expand Down Expand Up @@ -99,11 +104,16 @@ def items(self) -> Iterable[VehicleSpawn]:
ret.append(VehicleSpawn(element, self.cc2obj))
return ret

def remove(self, child: VehicleSpawn):
def remove(self, child: Union[VehicleSpawn, int]):
remove_ident = -1
if isinstance(child, VehicleSpawn):
remove_ident = child.data.respawn_id
elif isinstance(child, int):
remove_ident = child
children = self.items()
for item in children:
item: VehicleSpawn
if item.data.respawn_id == child.data.respawn_id:
if item.data.respawn_id == remove_ident:
self.element.remove(item.element)

def append(self, item: VehicleSpawn):
Expand All @@ -115,7 +125,7 @@ class SpawnData(ElementProxy, IsSetMixin):
team_id = e_property(IntAttribute("team_id", default_value=0))

def defaults(self):
self.is_set = False
self.is_set = True

@property
def vehicles(self) -> VehicleSpawnContainer:
Expand Down
5 changes: 5 additions & 0 deletions cc2me/savedata/types/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ def set_position(self, *,
def move(self, x: float, y: float, z: float) -> None:
self.set_position(x=x, y=y, z=z)

def translate(self, dx: float, dy: float, dz: float) -> None:
self.set_position(x=self.loc.x + dx,
y=self.loc.y + dy,
z=self.loc.z + dz)

@property
def loc(self) -> Location:
return Location(self.world_position.x, self.world_position.y, self.world_position.z)
4 changes: 4 additions & 0 deletions cc2me/savedata/types/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ class MovableLocationMixin(LocationMixin, ABC):
def move(self, x: float, y: float, z: float) -> None:
pass

@abstractmethod
def translate(self, dx: float, dy: float, dz: float) -> None:
pass


class WorldPosition(Point3D):
tag = "world_position"
Expand Down
5 changes: 5 additions & 0 deletions cc2me/savedata/types/vehicles/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ def set_location(self,
def move(self, x: float, y: float, z: float) -> None:
self.set_location(x, y, z)

def translate(self, dx: float, dy: float, dz: float) -> None:
self.set_location(self.loc.x + dx,
self.loc.y + dy,
self.loc.z + dz)

@property
def loc(self) -> Location:
return Location(self.transform.tx, self.transform.ty, self.transform.tz)
Expand Down
Binary file added cc2me/ui/icons/dupe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cc2me/ui/icons/dupe.xcf
Binary file not shown.
18 changes: 4 additions & 14 deletions cc2me/ui/saveslotchooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from xml.etree.ElementTree import Element
from tkinter import simpledialog

from cc2me.savedata.constants import read_save_slots


class SlotChooser(simpledialog.Dialog):

Expand All @@ -22,22 +24,10 @@ def body(self, master) -> None:
command=callback)
btn.pack(fill=tkinter.X)

def __init__(self, app, persistent_file: str, choice: dict, title="Load a save slot", ):
def __init__(self, app, persistent_file: str, choice: dict, title="Load a save slot"):
self.persistent_file = persistent_file
self.slots = []
self.slots = read_save_slots(persistent_file)
self.choice = choice
with open(self.persistent_file, "r") as xmlfile:
xml = xmlfile.read()
self.etree = ElementTree.fromstring(xml)
for item in self.etree:
if isinstance(item, Element):
filename = item.attrib.get("save_name")
text = item.attrib.get("display_name")
if filename:
self.slots.append({
"filename": filename,
"display": text
})

super(SlotChooser, self).__init__(parent=app, title=title)

Expand Down
13 changes: 8 additions & 5 deletions cc2me/ui/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Optional, List

from .properties import Properties
from ..savedata.constants import get_island_name, VehicleType, VehicleAttachmentDefinitionIndex
from ..savedata.constants import VehicleType, VehicleAttachmentDefinitionIndex, get_persistent_file_path, get_cc2_appdata
from ..savedata.types.objects import Island, Unit, get_unit, Spawn
from ..savedata.types.tiles import Tile
from ..savedata.loader import CC2XMLSave, load_save_file
Expand All @@ -25,8 +25,8 @@
class App(tkinter.Tk):
WIDTH = 900
HEIGHT = 750
cc2dir = os.path.expandvars(r'%APPDATA%\\Carrier Command 2')
persistent = os.path.join(cc2dir, "persistent_data.xml")
cc2dir = get_cc2_appdata()
persistent = get_persistent_file_path()

def __init__(self, *args, **kwargs):
tkinter.Tk.__init__(self, *args, **kwargs)
Expand Down Expand Up @@ -239,7 +239,6 @@ def duplicate_selected(self):
if new_units:
self.select_markers(new_units)


def add_new_seal(self):
self.add_new_unit(VehicleType.Seal)

Expand Down Expand Up @@ -272,7 +271,11 @@ def remove_item(self):
self.cc2me.remove_tile(tile)
if isinstance(marker, UnitMarker):
vehicle = marker.unit.vehicle()
self.cc2me.remove_vehicle(vehicle)
if vehicle is not None:
self.cc2me.remove_vehicle(vehicle)
if isinstance(marker.unit, Spawn):
self.cc2me.remove_spawn(marker.object.object.data.respawn_id)

marker.delete()
self.select_none()

Expand Down
Empty file added cc2me/web/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions cc2me/web/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .tool import run

run()
Loading