Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #225

Merged
merged 12 commits into from
Dec 19, 2024
Merged

Dev #225

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
16 changes: 16 additions & 0 deletions energetica/database/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,22 @@ def notify(self, title: str, message: str) -> None:
except WebPushException as ex:
engine.warn(f"Failed to send notification: {repr(ex)}")

def send_worker_info(self) -> None:
"""Send the number of available construction and lab workers to the player's clients."""
self.emit(
"worker_info",
{
"construction_workers": {
"available": self.available_construction_workers(),
"total": self.construction_workers,
},
"lab_workers": {
"available": self.available_lab_workers(),
"total": self.lab_workers,
},
},
)

def calculate_net_emissions(self) -> float:
"""Calculate the net emissions of the player."""
cumulative_emissions = self.data.cumul_emissions.get_all()
Expand Down
41 changes: 21 additions & 20 deletions energetica/production_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,22 @@ class all capacity offers in ascending order of price
Sell all capacities that are below market price at market price.
"""

def add_to_market_data(quantity, export=True):
"""Adds the exported or imported quantity to the market data so that it can be shown in the charts."""
import_export = "player_imports"
generation_consumption = "consumption"
if export:
import_export = "player_exports"
generation_consumption = "generation"
if row.player_id in market[import_export]:
market[import_export][row.player_id] += quantity
else:
market[import_export][row.player_id] = quantity
if row.facility in market[generation_consumption]:
market[generation_consumption][row.facility] += quantity
else:
market[generation_consumption][row.facility] = quantity

def sell(row, market_price, quantity=None):
"""Sell and produce offered power capacity."""
player = db.session.get(Player, row.player_id)
Expand All @@ -446,15 +462,7 @@ def sell(row, market_price, quantity=None):
demand["exports"] += quantity
player.money += quantity * market_price / 3600 * engine.in_game_seconds_per_tick / 1_000_000
revenue["exports"] += quantity * market_price / 3600 * engine.in_game_seconds_per_tick / 1_000_000

if row.player_id in market["player_exports"]:
market["player_exports"][row.player_id] += quantity
else:
market["player_exports"][row.player_id] = quantity
if row.facility in market["generation"]:
market["generation"][row.facility] += quantity
else:
market["generation"][row.facility] = quantity
add_to_market_data(quantity, export=True)

def buy(row, market_price, quantity=None):
"""Buy demanded power capacity."""
Expand All @@ -466,15 +474,7 @@ def buy(row, market_price, quantity=None):
generation["imports"] += quantity
player.money -= quantity * market_price / 3600 * engine.in_game_seconds_per_tick / 1_000_000
revenue["imports"] -= quantity * market_price / 3600 * engine.in_game_seconds_per_tick / 1_000_000

if row.player_id in market["player_imports"]:
market["player_imports"][row.player_id] += quantity
else:
market["player_imports"][row.player_id] = quantity
if row.facility in market["consumption"]:
market["consumption"][row.facility] += quantity
else:
market["consumption"][row.facility] = quantity
add_to_market_data(quantity, export=False)

market["player_exports"] = {}
market["player_imports"] = {}
Expand Down Expand Up @@ -508,6 +508,7 @@ def buy(row, market_price, quantity=None):
player.money -= dump_cap * 5 / 3600 * engine.in_game_seconds_per_tick / 1_000_000
revenue = new_values[row.player_id]["revenues"]
revenue["dumping"] -= dump_cap * 5 / 3600 * engine.in_game_seconds_per_tick / 1_000_000
add_to_market_data(dump_cap, export=False)
continue
break
sell(row, market_price)
Expand Down Expand Up @@ -589,7 +590,7 @@ def solar_generation(engine, player, generation, in_game_seconds_passed):
Each instance of facility generates a different amount of power depending on the position of the facility.
The clear sky index is calculated using a 3D perlin noise that moves over time, simulating the movement of clouds.
The csi is then multiplied by the clear sky value to get the actual irradiance at the location.
The effective power of the solar facility is then calculated as irradiance / 1000 * max_power.
The effective power of the solar facility is then calculated as irradiance / 950 * max_power.
"""
for facility_type in ["CSP_solar", "PV_solar"]:
if player.data.capacities[facility_type] is not None:
Expand All @@ -603,7 +604,7 @@ def solar_generation(engine, player, generation, in_game_seconds_passed):
max_power = (
engine.const_config["assets"][facility_type]["base_power_generation"] * facility.multiplier_1
)
facility.usage = irradiance / 1000
facility.usage = irradiance / 950.0
generation[facility_type] += facility.usage * max_power


Expand Down
51 changes: 27 additions & 24 deletions energetica/static/chat_logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ refresh_chats();

/* Load all players and sort them by username */
load_players().then((players_) => {
const player_id = sessionStorage.getItem("player_id");
const playerArray = Object.entries(players_)
.filter(([id, user]) => id != player_id)
.map(([id, user]) => ({ id, username: user.username }));
playerArray.sort((a, b) => a.username.localeCompare(b.username));
sortedNames = playerArray;
load_player_id().then((player_id) => {
const playerArray = Object.entries(players_)
.filter(([id, user]) => id != player_id)
.map(([id, user]) => ({ id, username: user.username }));
playerArray.sort((a, b) => a.username.localeCompare(b.username));
sortedNames = playerArray;
});
});

function refresh_chats() {
Expand Down Expand Up @@ -289,29 +290,31 @@ function openChat(chatID) {
.then((response) => response.json())
.then((data) => {
load_players().then((players) => {
let messages = data.messages;
let chat_title = document.getElementById("chat_title_div");
chat_title.innerHTML = `<b>${chats[chatID].name}</b>`;
document.getElementById("message_input_field").classList.remove("hidden");
for (let i = 0; i < messages.length; i++) {
let alignment = "left";
let username = "";
if (messages[i].player_id == sessionStorage.getItem("player_id")) {
alignment = "right";
} else if (chats[chatID].group_chat) {
username = players[messages[i].player_id].username + "&emsp;";
}
html += `<div class="message ${alignment}">
load_player_id().then((player_id) => {
let messages = data.messages;
let chat_title = document.getElementById("chat_title_div");
chat_title.innerHTML = `<b>${chats[chatID].name}</b>`;
document.getElementById("message_input_field").classList.remove("hidden");
for (let i = 0; i < messages.length; i++) {
let alignment = "left";
let username = "";
if (messages[i].player_id == player_id) {
alignment = "right";
} else if (chats[chatID].group_chat) {
username = players[messages[i].player_id].username + "&emsp;";
}
html += `<div class="message ${alignment}">
<div class="message_infos">
<span>${username}</span>
<span class="txt_pine">${formatDateString(messages[i].time)}</span></div>
<div class="message_text bone ${alignment}">${messages[i].text}</div>
</div>`;
}
let message_container = document.getElementById("message_container");
message_container.innerHTML = html;
message_container.scrollTop = message_container.scrollHeight;
document.getElementById("new_message").focus();
}
let message_container = document.getElementById("message_container");
message_container.innerHTML = html;
message_container.scrollTop = message_container.scrollHeight;
document.getElementById("new_message").focus();
});
});
})
.catch((error) => {
Expand Down
13 changes: 10 additions & 3 deletions energetica/static/energetica.css
Original file line number Diff line number Diff line change
Expand Up @@ -1730,11 +1730,18 @@ table.tan_green tr:nth-child(even) {
}

.graph-container img {
max-width: 600px;
width: 600px;
max-width: 100%;
}

img.small.graph-container {
width: 300px;
max-width: 100%;
}

.graph-container img.small {
max-width: 450px;
.graph-container img.large {
width: 1100px;
max-width: 100%;
}

.info_icon {
Expand Down
18 changes: 18 additions & 0 deletions energetica/static/frontend_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,24 @@ function retrieve_player_data() {
});
}

function load_player_id() {
if (typeof (Storage) !== "undefined") {
const player_id = sessionStorage.getItem("player_id");
if (player_id) {
return Promise.resolve(player_id);
}
}
return fetch("/api/get_player_id")
.then((response) => response.json())
.then((player_id) => {
sessionStorage.setItem("player_id", player_id);
return player_id;
})
.catch((error) => {
console.error(`caught error ${error}`);
});
}

function load_const_config() {
if (typeof (Storage) !== "undefined") {
const const_config = sessionStorage.getItem("const_config");
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 27 additions & 25 deletions energetica/static/map_visualisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,32 +63,34 @@ function preload() {
fetch("/api/get_map") // retrieves map data from the database using api.py
.then((response) => response.json())
.then((raw_data) => {
data = raw_data;
current_player_id = sessionStorage.getItem("player_id");
load_players().then((_players_ids) => {
players_ids = _players_ids;
console.log(players_ids, current_player_id);
load_player_id().then((_current_player_id) => {
current_player_id = _current_player_id;
data = raw_data;
load_players().then((_players_ids) => {
players_ids = _players_ids;
console.log(players_ids, current_player_id);
});
for (let i = 0; i < data.length; i++) {
let resources = [
data[i].solar,
data[i].wind,
data[i].hydro,
data[i].coal,
data[i].gas,
data[i].uranium,
data[i].climate_risk,
];
map.push(
new Hex(
data[i].id,
data[i].q,
data[i].r,
resources,
data[i].player_id
)
);
}
});
for (let i = 0; i < data.length; i++) {
let resources = [
data[i].solar,
data[i].wind,
data[i].hydro,
data[i].coal,
data[i].gas,
data[i].uranium,
data[i].climate_risk,
];
map.push(
new Hex(
data[i].id,
data[i].q,
data[i].r,
resources,
data[i].player_id
)
);
}
})
.catch((error) => {
console.error("Error:", error);
Expand Down
2 changes: 2 additions & 0 deletions energetica/static/network/market_graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ function setup() {

imports: [color(255, 89, 94), "Imports"],
exports: [color(138, 201, 38), "Exports"],

dumping: [color(208, 0, 0), "Dumping"],
};

canvas_width = 0.7 * windowWidth;
Expand Down
11 changes: 6 additions & 5 deletions energetica/static/network/network_logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ let invitations = [];


load_players().then((players_) => {
const player_id = sessionStorage.getItem("player_id");
const usernames = Object.entries(players_)
.filter(([id, user]) => id != player_id)
.map(([id, user]) => user.username);
sortedNames = usernames.sort();
load_player_id().then((player_id) => {
const usernames = Object.entries(players_)
.filter(([id, user]) => id != player_id)
.map(([id, user]) => user.username);
sortedNames = usernames.sort();
});
});

let input = document.getElementById("invite_player");
Expand Down
33 changes: 17 additions & 16 deletions energetica/static/scoreboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,28 +55,29 @@ function sortTable(columnName) {
html += `<th id="co2_emissions" onclick="sortTable('co2_emissions')">Emissions</th>`;
}
html += `</tr>`;
let current_player_id = sessionStorage.getItem("player_id");
for (const [id, player] of sortedData) {
if (id == current_player_id) {
href = "/profile";
} else {
href = `/profile?player_id=${id}`;
}
html += `<tr>
load_player_id().then((current_player_id) => {
for (const [id, player] of sortedData) {
if (id == current_player_id) {
href = "/profile";
} else {
href = `/profile?player_id=${id}`;
}
html += `<tr>
<td><a href="${href}">${player['username']}</a></td>
<td>${player['network_name']}</td>
<td>${format_money(player['average_hourly_revenues'])}/h</td>
<td>${format_power(player['max_power_consumption'])}</td>
<td>${player['total_technology_levels']}</td>
<td>${player['xp']}</td>`;
if (include_co2_emissions) {
html += `<td>${format_mass(player['co2_emissions'])}</td>`;
if (include_co2_emissions) {
html += `<td>${format_mass(player['co2_emissions'])}</td>`;
}
html += `</tr > `;
}
html += `</tr > `;
}
table.innerHTML = html;
table.innerHTML = html;

// Update the sorting indicator
column = document.getElementById(columnName);
column.innerHTML += triangle;
// Update the sorting indicator
column = document.getElementById(columnName);
column.innerHTML += triangle;
});
};
Loading
Loading