-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrespec.py
137 lines (112 loc) · 4.36 KB
/
respec.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import os
import logging
import requests
from config import settings
from bs4 import BeautifulSoup
from typing import List
from collections import namedtuple
Perk = namedtuple(
"Perk",
["name", "attribute_requirement", "rank", "level_requirement", "description", "id"],
)
logging.basicConfig(
level=logging.DEBUG, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger("Fallout4Respec")
def retrieving_perks_data() -> List[Perk]:
logger.info("Crawling Fallout 4 Perks Page.")
html_data = requests.get(settings.internal.fallout_wiki_perks_url).content
parsed_page = BeautifulSoup(html_data, "html.parser")
tables = parsed_page.find_all(
"table", class_="va-table va-table-full va-table-shaded sortable"
)
perks: List[Perk] = list()
for table in tables:
raw_data = []
th = table.find_all("th")
if len(th) > 2 and th[0].next == "Name\n" and th[1].next == "Attribute Rank\n":
rows = table.find_all("tr")
for row in rows:
cols = row.find_all("td")
cols = [ele.text.strip() for ele in cols]
if cols != []:
raw_data.append([ele for ele in cols if ele])
current_header = ""
current_attribute_requirement = ""
for rd in raw_data:
if len(rd) == 0:
continue
else:
if len(rd[-1]) == 8:
perk_id = [rd[-1]]
else:
perk_id = [rd[-1][0:8], rd[-1][8:16]]
if not rd[0].isdigit():
current_header = rd[0]
current_attribute_requirement = rd[1]
perks.append(
Perk(
name=current_header,
attribute_requirement=current_attribute_requirement,
rank=rd[2],
level_requirement=1,
description=rd[-2],
id=perk_id,
)
)
else:
perks.append(
Perk(
name=current_header,
attribute_requirement=current_attribute_requirement,
rank=rd[0],
level_requirement=rd[1],
description=rd[-2],
id=perk_id,
)
)
return perks
def retrieving_char_data() -> dict:
points_to_add = (
settings.character.current_level - 1
) + settings.internal.initial_perk_points
special_points = {"FreePoints": points_to_add}
for special in settings.internal.special_names:
if special in settings.character.boobleheads:
special_points[special] = 2
else:
special_points[special] = 1
return special_points
def generate_script(perks: List[Perk], char_points: dict) -> None:
perks.sort(key=lambda x: x.rank, reverse=True)
commands = []
for pk in perks:
for pkid in pk.id:
commands.append(f"{settings.internal.remove_perk_cmd} {pkid};\n")
for special, value in char_points.items():
if special == "FreePoints":
commands.append(f"{settings.internal.add_perk_points_cmd} {value};\n")
else:
commands.append(
f"{settings.internal.set_special_value_cmd} {special.lower()} {value};\n"
)
filepath = os.path.join(
settings.internal.game_data_path, settings.internal.script_name
)
try:
with open(filepath, "w") as f:
f.writelines(commands)
logger.info(
f"Script '{settings.internal.script_name}' generated on '{settings.internal.game_data_path}'"
)
logger.info(
f"Just open console command and tip 'bat {settings.internal.script_name.split('.')[0]}'."
)
except Exception as e:
logger.error(f"Failed to save script: {str(e)}")
def main():
perks = retrieving_perks_data()
char_points = retrieving_char_data()
generate_script(perks, char_points)
if __name__ == "__main__":
main()