From 341655ea250b6eb673055081a165b8cd910e7c15 Mon Sep 17 00:00:00 2001 From: komiko44240BB Date: Sat, 26 Oct 2024 15:44:03 +0200 Subject: [PATCH] Commenting --- Perk_data/data/weapons_perks.xlsx | Bin 20168 -> 20186 bytes Perk_data/event_Rarity_Item.csv | 8 - Perk_data/event_epic_all_cannons.csv | 8 - Perk_data/event_epic_all_fire.csv | 2 - Perk_data/event_epic_all_missiles.csv | 6 - Perk_data/event_epic_all_mortars.csv | 6 - Perk_data/event_epic_all_repair_items.csv | 2 - Perk_data/event_epic_all_shields.csv | 4 - Perk_data/event_epic_all_torpedoes.csv | 4 - Perk_data/event_epic_ballpark_mortar.csv | 2 - Perk_data/event_epic_big_bandage.csv | 2 - Perk_data/event_epic_big_berta.csv | 4 - Perk_data/event_epic_big_torpedo.csv | 4 - Perk_data/event_epic_blast_cannon.csv | 2 - Perk_data/event_epic_carronade.csv | 6 - Perk_data/event_epic_duct_tape.csv | 2 - Perk_data/event_epic_explosive_cannon.csv | 2 - Perk_data/event_epic_fire_bomb.csv | 4 - Perk_data/event_epic_flare_gun.csv | 6 - Perk_data/event_epic_freeze_items.csv | 2 - Perk_data/event_epic_frost_blaster.csv | 2 - Perk_data/event_epic_gatling_gun.csv | 6 - Perk_data/event_epic_grenades.csv | 8 - Perk_data/event_epic_long_range_mortar.csv | 2 - Perk_data/event_epic_mines.csv | 6 - Perk_data/event_epic_missiles.csv | 2 - Perk_data/event_epic_napalm.csv | 4 - Perk_data/event_epic_none.csv | 2 - Perk_data/event_epic_railguns.csv | 6 - Perk_data/event_epic_repair_bolt.csv | 4 - Perk_data/event_epic_repair_box.csv | 4 - Perk_data/event_epic_repair_plasma.csv | 2 - Perk_data/event_epic_repair_pulse.csv | 2 - Perk_data/event_epic_sniper_cannon.csv | 4 - Perk_data/event_epic_standard_cannon.csv | 2 - Perk_data/event_epic_standard_mortar.csv | 2 - Perk_data/event_epic_standard_torpedo.csv | 2 - Perk_data/event_epic_swift_torpedo.csv | 4 - Perk_data/event_epic_tesla_bolt.csv | 2 - Perk_data/event_epic_tesla_shield.csv | 2 - Perk_data/event_epic_triple_torpedo.csv | 6 - Perk_data/event_epic_turbo.csv | 4 - Perk_data/event_legendary_all_cannons.csv | 8 - Perk_data/event_legendary_all_fire.csv | 2 - Perk_data/event_legendary_all_missiles.csv | 6 - Perk_data/event_legendary_all_mortars.csv | 6 - .../event_legendary_all_repair_items.csv | 2 - Perk_data/event_legendary_all_shields.csv | 4 - Perk_data/event_legendary_all_torpedoes.csv | 4 - Perk_data/event_legendary_ballpark_mortar.csv | 2 - Perk_data/event_legendary_big_bandage.csv | 2 - Perk_data/event_legendary_big_berta.csv | 4 - Perk_data/event_legendary_big_torpedo.csv | 4 - Perk_data/event_legendary_blast_cannon.csv | 2 - Perk_data/event_legendary_carronade.csv | 6 - Perk_data/event_legendary_duct_tape.csv | 2 - .../event_legendary_explosive_cannon.csv | 2 - Perk_data/event_legendary_fire_bomb.csv | 4 - Perk_data/event_legendary_flare_gun.csv | 6 - Perk_data/event_legendary_freeze_items.csv | 2 - Perk_data/event_legendary_frost_blaster.csv | 2 - Perk_data/event_legendary_gatling_gun.csv | 6 - Perk_data/event_legendary_grenades.csv | 8 - .../event_legendary_long_range_mortar.csv | 2 - Perk_data/event_legendary_mines.csv | 6 - Perk_data/event_legendary_missiles.csv | 2 - Perk_data/event_legendary_napalm.csv | 4 - Perk_data/event_legendary_none.csv | 2 - Perk_data/event_legendary_railguns.csv | 6 - Perk_data/event_legendary_repair_bolt.csv | 4 - Perk_data/event_legendary_repair_box.csv | 4 - Perk_data/event_legendary_repair_plasma.csv | 2 - Perk_data/event_legendary_repair_pulse.csv | 2 - Perk_data/event_legendary_sniper_cannon.csv | 4 - Perk_data/event_legendary_standard_cannon.csv | 2 - Perk_data/event_legendary_standard_mortar.csv | 2 - .../event_legendary_standard_torpedo.csv | 2 - Perk_data/event_legendary_swift_torpedo.csv | 4 - Perk_data/event_legendary_tesla_bolt.csv | 2 - Perk_data/event_legendary_tesla_shield.csv | 2 - Perk_data/event_legendary_triple_torpedo.csv | 6 - Perk_data/event_legendary_turbo.csv | 4 - Perk_data/event_rare_all_cannons.csv | 8 - Perk_data/event_rare_all_fire.csv | 4 - Perk_data/event_rare_all_missiles.csv | 6 - Perk_data/event_rare_all_mortars.csv | 6 - Perk_data/event_rare_all_repair_items.csv | 2 - Perk_data/event_rare_all_shields.csv | 4 - Perk_data/event_rare_all_torpedoes.csv | 4 - Perk_data/event_rare_ballpark_mortar.csv | 2 - Perk_data/event_rare_big_bandage.csv | 2 - Perk_data/event_rare_big_berta.csv | 4 - Perk_data/event_rare_big_torpedo.csv | 4 - Perk_data/event_rare_blast_cannon.csv | 2 - Perk_data/event_rare_carronade.csv | 6 - Perk_data/event_rare_duct_tape.csv | 2 - Perk_data/event_rare_explosive_cannon.csv | 2 - Perk_data/event_rare_fire_bomb.csv | 4 - Perk_data/event_rare_flare_gun.csv | 6 - Perk_data/event_rare_freeze_items.csv | 2 - Perk_data/event_rare_frost_blaster.csv | 2 - Perk_data/event_rare_gatling_gun.csv | 6 - Perk_data/event_rare_grenades.csv | 8 - Perk_data/event_rare_long_range_mortar.csv | 2 - Perk_data/event_rare_mines.csv | 6 - Perk_data/event_rare_missiles.csv | 2 - Perk_data/event_rare_napalm.csv | 4 - Perk_data/event_rare_none.csv | 2 - Perk_data/event_rare_railguns.csv | 6 - Perk_data/event_rare_repair_bolt.csv | 4 - Perk_data/event_rare_repair_box.csv | 4 - Perk_data/event_rare_repair_plasma.csv | 2 - Perk_data/event_rare_repair_pulse.csv | 2 - Perk_data/event_rare_sniper_cannon.csv | 4 - Perk_data/event_rare_standard_cannon.csv | 2 - Perk_data/event_rare_standard_mortar.csv | 2 - Perk_data/event_rare_standard_torpedo.csv | 2 - Perk_data/event_rare_swift_torpedo.csv | 4 - Perk_data/event_rare_tesla_bolt.csv | 2 - Perk_data/event_rare_tesla_shield.csv | 2 - Perk_data/event_rare_triple_torpedo.csv | 6 - Perk_data/event_rare_turbo.csv | 4 - Perk_data/event_uncommon_all_cannons.csv | 8 - Perk_data/event_uncommon_all_fire.csv | 2 - Perk_data/event_uncommon_all_missiles.csv | 6 - Perk_data/event_uncommon_all_mortars.csv | 6 - Perk_data/event_uncommon_all_repair_items.csv | 2 - Perk_data/event_uncommon_all_shields.csv | 4 - Perk_data/event_uncommon_all_torpedoes.csv | 4 - Perk_data/event_uncommon_ballpark_mortar.csv | 2 - Perk_data/event_uncommon_big_bandage.csv | 2 - Perk_data/event_uncommon_big_berta.csv | 4 - Perk_data/event_uncommon_big_torpedo.csv | 4 - Perk_data/event_uncommon_blast_cannon.csv | 2 - Perk_data/event_uncommon_carronade.csv | 6 - Perk_data/event_uncommon_duct_tape.csv | 2 - Perk_data/event_uncommon_explosive_cannon.csv | 2 - Perk_data/event_uncommon_fire_bomb.csv | 4 - Perk_data/event_uncommon_flare_gun.csv | 6 - Perk_data/event_uncommon_freeze_items.csv | 2 - Perk_data/event_uncommon_frost_blaster.csv | 2 - Perk_data/event_uncommon_gatling_gun.csv | 6 - Perk_data/event_uncommon_grenades.csv | 8 - .../event_uncommon_long_range_mortar.csv | 2 - Perk_data/event_uncommon_mines.csv | 6 - Perk_data/event_uncommon_missiles.csv | 2 - Perk_data/event_uncommon_napalm.csv | 4 - Perk_data/event_uncommon_none.csv | 2 - Perk_data/event_uncommon_railguns.csv | 6 - Perk_data/event_uncommon_repair_bolt.csv | 4 - Perk_data/event_uncommon_repair_box.csv | 4 - Perk_data/event_uncommon_repair_plasma.csv | 2 - Perk_data/event_uncommon_repair_pulse.csv | 2 - Perk_data/event_uncommon_sniper_cannon.csv | 4 - Perk_data/event_uncommon_standard_cannon.csv | 2 - Perk_data/event_uncommon_standard_mortar.csv | 2 - Perk_data/event_uncommon_standard_torpedo.csv | 2 - Perk_data/event_uncommon_swift_torpedo.csv | 4 - Perk_data/event_uncommon_tesla_bolt.csv | 2 - Perk_data/event_uncommon_tesla_shield.csv | 2 - Perk_data/event_uncommon_triple_torpedo.csv | 6 - Perk_data/event_uncommon_turbo.csv | 4 - Perk_data/event_uncommon_uncommon.csv | 2 - main.c | 26 -- menu.c | 5 +- objects.c | 92 +++++-- perks.c | 230 ++++++++++++------ readtraining.c | 8 +- readtraining.h | 4 +- 169 files changed, 238 insertions(+), 723 deletions(-) delete mode 100644 Perk_data/event_Rarity_Item.csv delete mode 100644 Perk_data/event_epic_all_cannons.csv delete mode 100644 Perk_data/event_epic_all_fire.csv delete mode 100644 Perk_data/event_epic_all_missiles.csv delete mode 100644 Perk_data/event_epic_all_mortars.csv delete mode 100644 Perk_data/event_epic_all_repair_items.csv delete mode 100644 Perk_data/event_epic_all_shields.csv delete mode 100644 Perk_data/event_epic_all_torpedoes.csv delete mode 100644 Perk_data/event_epic_ballpark_mortar.csv delete mode 100644 Perk_data/event_epic_big_bandage.csv delete mode 100644 Perk_data/event_epic_big_berta.csv delete mode 100644 Perk_data/event_epic_big_torpedo.csv delete mode 100644 Perk_data/event_epic_blast_cannon.csv delete mode 100644 Perk_data/event_epic_carronade.csv delete mode 100644 Perk_data/event_epic_duct_tape.csv delete mode 100644 Perk_data/event_epic_explosive_cannon.csv delete mode 100644 Perk_data/event_epic_fire_bomb.csv delete mode 100644 Perk_data/event_epic_flare_gun.csv delete mode 100644 Perk_data/event_epic_freeze_items.csv delete mode 100644 Perk_data/event_epic_frost_blaster.csv delete mode 100644 Perk_data/event_epic_gatling_gun.csv delete mode 100644 Perk_data/event_epic_grenades.csv delete mode 100644 Perk_data/event_epic_long_range_mortar.csv delete mode 100644 Perk_data/event_epic_mines.csv delete mode 100644 Perk_data/event_epic_missiles.csv delete mode 100644 Perk_data/event_epic_napalm.csv delete mode 100644 Perk_data/event_epic_none.csv delete mode 100644 Perk_data/event_epic_railguns.csv delete mode 100644 Perk_data/event_epic_repair_bolt.csv delete mode 100644 Perk_data/event_epic_repair_box.csv delete mode 100644 Perk_data/event_epic_repair_plasma.csv delete mode 100644 Perk_data/event_epic_repair_pulse.csv delete mode 100644 Perk_data/event_epic_sniper_cannon.csv delete mode 100644 Perk_data/event_epic_standard_cannon.csv delete mode 100644 Perk_data/event_epic_standard_mortar.csv delete mode 100644 Perk_data/event_epic_standard_torpedo.csv delete mode 100644 Perk_data/event_epic_swift_torpedo.csv delete mode 100644 Perk_data/event_epic_tesla_bolt.csv delete mode 100644 Perk_data/event_epic_tesla_shield.csv delete mode 100644 Perk_data/event_epic_triple_torpedo.csv delete mode 100644 Perk_data/event_epic_turbo.csv delete mode 100644 Perk_data/event_legendary_all_cannons.csv delete mode 100644 Perk_data/event_legendary_all_fire.csv delete mode 100644 Perk_data/event_legendary_all_missiles.csv delete mode 100644 Perk_data/event_legendary_all_mortars.csv delete mode 100644 Perk_data/event_legendary_all_repair_items.csv delete mode 100644 Perk_data/event_legendary_all_shields.csv delete mode 100644 Perk_data/event_legendary_all_torpedoes.csv delete mode 100644 Perk_data/event_legendary_ballpark_mortar.csv delete mode 100644 Perk_data/event_legendary_big_bandage.csv delete mode 100644 Perk_data/event_legendary_big_berta.csv delete mode 100644 Perk_data/event_legendary_big_torpedo.csv delete mode 100644 Perk_data/event_legendary_blast_cannon.csv delete mode 100644 Perk_data/event_legendary_carronade.csv delete mode 100644 Perk_data/event_legendary_duct_tape.csv delete mode 100644 Perk_data/event_legendary_explosive_cannon.csv delete mode 100644 Perk_data/event_legendary_fire_bomb.csv delete mode 100644 Perk_data/event_legendary_flare_gun.csv delete mode 100644 Perk_data/event_legendary_freeze_items.csv delete mode 100644 Perk_data/event_legendary_frost_blaster.csv delete mode 100644 Perk_data/event_legendary_gatling_gun.csv delete mode 100644 Perk_data/event_legendary_grenades.csv delete mode 100644 Perk_data/event_legendary_long_range_mortar.csv delete mode 100644 Perk_data/event_legendary_mines.csv delete mode 100644 Perk_data/event_legendary_missiles.csv delete mode 100644 Perk_data/event_legendary_napalm.csv delete mode 100644 Perk_data/event_legendary_none.csv delete mode 100644 Perk_data/event_legendary_railguns.csv delete mode 100644 Perk_data/event_legendary_repair_bolt.csv delete mode 100644 Perk_data/event_legendary_repair_box.csv delete mode 100644 Perk_data/event_legendary_repair_plasma.csv delete mode 100644 Perk_data/event_legendary_repair_pulse.csv delete mode 100644 Perk_data/event_legendary_sniper_cannon.csv delete mode 100644 Perk_data/event_legendary_standard_cannon.csv delete mode 100644 Perk_data/event_legendary_standard_mortar.csv delete mode 100644 Perk_data/event_legendary_standard_torpedo.csv delete mode 100644 Perk_data/event_legendary_swift_torpedo.csv delete mode 100644 Perk_data/event_legendary_tesla_bolt.csv delete mode 100644 Perk_data/event_legendary_tesla_shield.csv delete mode 100644 Perk_data/event_legendary_triple_torpedo.csv delete mode 100644 Perk_data/event_legendary_turbo.csv delete mode 100644 Perk_data/event_rare_all_cannons.csv delete mode 100644 Perk_data/event_rare_all_fire.csv delete mode 100644 Perk_data/event_rare_all_missiles.csv delete mode 100644 Perk_data/event_rare_all_mortars.csv delete mode 100644 Perk_data/event_rare_all_repair_items.csv delete mode 100644 Perk_data/event_rare_all_shields.csv delete mode 100644 Perk_data/event_rare_all_torpedoes.csv delete mode 100644 Perk_data/event_rare_ballpark_mortar.csv delete mode 100644 Perk_data/event_rare_big_bandage.csv delete mode 100644 Perk_data/event_rare_big_berta.csv delete mode 100644 Perk_data/event_rare_big_torpedo.csv delete mode 100644 Perk_data/event_rare_blast_cannon.csv delete mode 100644 Perk_data/event_rare_carronade.csv delete mode 100644 Perk_data/event_rare_duct_tape.csv delete mode 100644 Perk_data/event_rare_explosive_cannon.csv delete mode 100644 Perk_data/event_rare_fire_bomb.csv delete mode 100644 Perk_data/event_rare_flare_gun.csv delete mode 100644 Perk_data/event_rare_freeze_items.csv delete mode 100644 Perk_data/event_rare_frost_blaster.csv delete mode 100644 Perk_data/event_rare_gatling_gun.csv delete mode 100644 Perk_data/event_rare_grenades.csv delete mode 100644 Perk_data/event_rare_long_range_mortar.csv delete mode 100644 Perk_data/event_rare_mines.csv delete mode 100644 Perk_data/event_rare_missiles.csv delete mode 100644 Perk_data/event_rare_napalm.csv delete mode 100644 Perk_data/event_rare_none.csv delete mode 100644 Perk_data/event_rare_railguns.csv delete mode 100644 Perk_data/event_rare_repair_bolt.csv delete mode 100644 Perk_data/event_rare_repair_box.csv delete mode 100644 Perk_data/event_rare_repair_plasma.csv delete mode 100644 Perk_data/event_rare_repair_pulse.csv delete mode 100644 Perk_data/event_rare_sniper_cannon.csv delete mode 100644 Perk_data/event_rare_standard_cannon.csv delete mode 100644 Perk_data/event_rare_standard_mortar.csv delete mode 100644 Perk_data/event_rare_standard_torpedo.csv delete mode 100644 Perk_data/event_rare_swift_torpedo.csv delete mode 100644 Perk_data/event_rare_tesla_bolt.csv delete mode 100644 Perk_data/event_rare_tesla_shield.csv delete mode 100644 Perk_data/event_rare_triple_torpedo.csv delete mode 100644 Perk_data/event_rare_turbo.csv delete mode 100644 Perk_data/event_uncommon_all_cannons.csv delete mode 100644 Perk_data/event_uncommon_all_fire.csv delete mode 100644 Perk_data/event_uncommon_all_missiles.csv delete mode 100644 Perk_data/event_uncommon_all_mortars.csv delete mode 100644 Perk_data/event_uncommon_all_repair_items.csv delete mode 100644 Perk_data/event_uncommon_all_shields.csv delete mode 100644 Perk_data/event_uncommon_all_torpedoes.csv delete mode 100644 Perk_data/event_uncommon_ballpark_mortar.csv delete mode 100644 Perk_data/event_uncommon_big_bandage.csv delete mode 100644 Perk_data/event_uncommon_big_berta.csv delete mode 100644 Perk_data/event_uncommon_big_torpedo.csv delete mode 100644 Perk_data/event_uncommon_blast_cannon.csv delete mode 100644 Perk_data/event_uncommon_carronade.csv delete mode 100644 Perk_data/event_uncommon_duct_tape.csv delete mode 100644 Perk_data/event_uncommon_explosive_cannon.csv delete mode 100644 Perk_data/event_uncommon_fire_bomb.csv delete mode 100644 Perk_data/event_uncommon_flare_gun.csv delete mode 100644 Perk_data/event_uncommon_freeze_items.csv delete mode 100644 Perk_data/event_uncommon_frost_blaster.csv delete mode 100644 Perk_data/event_uncommon_gatling_gun.csv delete mode 100644 Perk_data/event_uncommon_grenades.csv delete mode 100644 Perk_data/event_uncommon_long_range_mortar.csv delete mode 100644 Perk_data/event_uncommon_mines.csv delete mode 100644 Perk_data/event_uncommon_missiles.csv delete mode 100644 Perk_data/event_uncommon_napalm.csv delete mode 100644 Perk_data/event_uncommon_none.csv delete mode 100644 Perk_data/event_uncommon_railguns.csv delete mode 100644 Perk_data/event_uncommon_repair_bolt.csv delete mode 100644 Perk_data/event_uncommon_repair_box.csv delete mode 100644 Perk_data/event_uncommon_repair_plasma.csv delete mode 100644 Perk_data/event_uncommon_repair_pulse.csv delete mode 100644 Perk_data/event_uncommon_sniper_cannon.csv delete mode 100644 Perk_data/event_uncommon_standard_cannon.csv delete mode 100644 Perk_data/event_uncommon_standard_mortar.csv delete mode 100644 Perk_data/event_uncommon_standard_torpedo.csv delete mode 100644 Perk_data/event_uncommon_swift_torpedo.csv delete mode 100644 Perk_data/event_uncommon_tesla_bolt.csv delete mode 100644 Perk_data/event_uncommon_tesla_shield.csv delete mode 100644 Perk_data/event_uncommon_triple_torpedo.csv delete mode 100644 Perk_data/event_uncommon_turbo.csv delete mode 100644 Perk_data/event_uncommon_uncommon.csv diff --git a/Perk_data/data/weapons_perks.xlsx b/Perk_data/data/weapons_perks.xlsx index 62087528a002becf729e7b13e1c3a8fe1906d7d7..158ed4627812cc1b607451be487abf20ac123df2 100644 GIT binary patch delta 11424 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

6l>*8({kgK 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 -#include -#include -#include -#include "ships.h" -#include "readobjects.h" -#include "readtraining.h" -#include "objects.h" -#include "perks.h" #include "menu.h" // Formula to calculate stat and combo stat : ( base stat + flat train stat + flat perk stat ) * ( 1 + % perk stat + % train stat ) * ( 1 + % combo train stat + % combo perk stat ) int main() { - - /*int gear[5][2] = {{5,8},{3,4},{0,0},{0,0},{0,0}}; - struct Ship* s = initialiseShip("defender",1.2,0.9,0.5,1596,5); - setUpShip(s,gear); - char* object_name= "swift_torpedo"; - char* rarity = "legendary"; - struct Object* o = readObjectFile(1,object_name,rarity); - bool isAdded = addOject(s,o); - if(!isAdded){ - printf("Could not add objects, not enought slot points or slots\n"); - }else{ - printf("Object added sucesfuly\n"); - } - addPerks(o); - printf("\n"); - printLoadout(s); - printObject(o);*/ start(); return 0; } \ No newline at end of file diff --git a/menu.c b/menu.c index 5d7ab34..09e28ed 100644 --- a/menu.c +++ b/menu.c @@ -2,7 +2,6 @@ #include #include #include - #include "ships.h" #include "readobjects.h" #include "readtraining.h" @@ -11,7 +10,7 @@ #include "clear_input.h" #include "menu.h" - +#include "objects.h" #define FILENAME_SIZE 40 @@ -404,7 +403,7 @@ void addObjects(struct Ship* s) { i--; }else{ printf("Object has been added\n"); - struct Training* t = readTraining(o,object_name); + struct Training* t = readTraining(o->name); addPerks(o); applytrainingAndPerks(o,t); } diff --git a/objects.c b/objects.c index 91ef6d1..16b74da 100644 --- a/objects.c +++ b/objects.c @@ -3,15 +3,35 @@ #include #include "objects.h" - -struct Object* createObject(char* rarity, char* name, unsigned int level, float base_stat, float cool_down, float range, float projectile_speed, float critical_hit_chance, float critcal_hit_multiplier, float radius, float spread, unsigned int amount_of_projectiles, float duration, unsigned int slot_points, float combo_dmg_boost) { +/** + * Creates a new Object instance with specified parameters and allocates memory for it. + * Initializes the object fields with given values and default values where necessary. + * + * @param rarity A string indicating the object's rarity (e.g., "common", "rare"). + * @param name A string specifying the object's name. + * @param level The level of the object. + * @param base_stat The base stat value of the object. + * @param cool_down Cooldown time for the object in seconds. + * @param range Range value for the object. + * @param projectile_speed Speed of the object's projectile. + * @param critical_hit_chance The probability of a critical hit. + * @param critical_hit_multiplier Multiplier applied on critical hits. + * @param radius Radius of the object’s area of effect. + * @param spread Spread of the object’s attack. + * @param amount_of_projectiles Number of projectiles the object launches. + * @param duration Duration of the object's effect in seconds. + * @param slot_points Number of slot points the object requires. + * @param combo_dmg_boost Damage boost percentage when in combo. + * @return Pointer to the created Object struct, or NULL if memory allocation fails. + */ +struct Object* createObject(char* rarity, char* name, unsigned int level, float base_stat, float cool_down, float range, float projectile_speed, float critical_hit_chance, float critical_hit_multiplier, float radius, float spread, unsigned int amount_of_projectiles, float duration, unsigned int slot_points, float combo_dmg_boost) { struct Object* o = malloc(sizeof(struct Object)); if(o == NULL) { return NULL; } o->name = strdup(name); o->rarity = strdup(rarity); - o->type = -1; + o->type = -1; // Initial default type value o->level = level; o->training_level = 0; o->base_stat = base_stat; @@ -19,20 +39,26 @@ struct Object* createObject(char* rarity, char* name, unsigned int level, float o->range = range; o->projectile_speed = projectile_speed; o->critical_hit_chance = critical_hit_chance; - o->critical_hit_multiplier = critcal_hit_multiplier; + o->critical_hit_multiplier = critical_hit_multiplier; o->radius = radius; o->spread = spread; o->amount_of_projectiles = amount_of_projectiles; o->duration = duration; o->combo_dmg_boost = combo_dmg_boost; o->slot_points = slot_points; - for(int i = 0 ; i < 4; i++){ - o->perk_list[i] = NULL; + for(int i = 0; i < 4; i++){ + o->perk_list[i] = NULL; // Initialize perk slots as empty } - o->next = NULL; + o->next = NULL; // Initialize next pointer for linked structure return o; } +/** + * Retrieves the type of an Object instance. + * + * @param o Pointer to the Object whose type is to be retrieved. + * @return Integer representing the object's type, or -1 if the object is NULL. + */ int getObjectType(struct Object* o) { if(o == NULL){ return -1; @@ -40,10 +66,22 @@ int getObjectType(struct Object* o) { return o->type; } +/** + * Retrieves the slot points of an Object instance. + * + * @param o Pointer to the Object whose slot points are to be retrieved. + * @return Integer value representing the object's slot points. + */ int getObjectPoints(struct Object* o) { return o->slot_points; } +/** + * Prints the details of an Object instance, including attributes such as name, level, + * base stat, cooldown, and others, if they are non-zero. + * + * @param o Pointer to the Object to be printed. + */ void printObject(struct Object* o) { if (o == NULL){ return; @@ -84,34 +122,48 @@ void printObject(struct Object* o) { } } +/** + * Frees the memory allocated for an Object instance, including dynamic strings. + * + * @param o Pointer to the Object to be deleted. + */ void deleteObject(struct Object* o) { - if (o == NULL){ // handle null pointer + if (o == NULL){ return; } - // free the rarity string - free(o->rarity); - free(o->name); - // free the current object - free(o); + free(o->rarity); // Free dynamically allocated rarity string + free(o->name); // Free dynamically allocated name string + free(o); // Free the object itself } +/** + * Edits the type field of an Object instance. + * + * @param o Pointer to the Object whose type is to be modified. + * @param type New type value to assign, decremented by 1 for internal usage. + */ void editObjectType(struct Object* o, unsigned int type) { type--; o->type = type; - } - +/** + * Adds a Perk to an Object’s perk list if there is available space. + * If successfully added, prints a confirmation message. + * + * @param p Pointer to the Perk to be added. + * @param o Pointer to the Object to which the Perk will be added. + */ void addPerk(struct Perk* p, struct Object* o) { if(o == NULL || p == NULL){ return; } - for(int i = 0; i<4; i++){ - if(o->perk_list[i]== NULL){ + for(int i = 0; i < 4; i++){ + if(o->perk_list[i] == NULL){ o->perk_list[i] = p; - printf("Perk was added succesfully\n"); + printf("Perk was added successfully\n"); return; } } - printf("Perk could not be added, what did you try to bypass ?\n"); -} \ No newline at end of file + printf("Perk could not be added, maximum perks reached.\n"); +} diff --git a/perks.c b/perks.c index 8896ec4..70eaa97 100644 --- a/perks.c +++ b/perks.c @@ -6,7 +6,16 @@ #include "clear_input.h" #define MAX_LINE_SIZE 1024 -struct Perk* createPerk(char* first_boost_type,char* second_boost_type, float first_boost_value,float second_boost_value) { +/** + * Allocates memory for and initializes a new Perk structure with the specified boost types and values. + * + * @param first_boost_type A string representing the type of the first boost (e.g., "attack", "defense"). + * @param second_boost_type A string representing the type of the second boost. + * @param first_boost_value The numeric value of the first boost. + * @param second_boost_value The numeric value of the second boost. + * @return A pointer to the newly created Perk structure. + */ +struct Perk* createPerk(char* first_boost_type, char* second_boost_type, float first_boost_value, float second_boost_value) { struct Perk* p = malloc(sizeof(struct Perk)); p->first_boost_type = strdup(first_boost_type); p->second_boost_type = strdup(second_boost_type); @@ -16,6 +25,13 @@ struct Perk* createPerk(char* first_boost_type,char* second_boost_type, float fi return p; } +/** + * Determines the number of perks available to an Object based on its rarity and level. + * + * @param o A pointer to the Object structure for which the perks are being evaluated. + * @return The number of perks the Object is eligible for based on its rarity and level. + * Returns 0 for unrecognized item rarity, printing an error message. + */ int numberOfPerks(struct Object* o) { if(strcmp(o->rarity, "common") == 0){ if(o->level > 20){ @@ -53,18 +69,26 @@ int numberOfPerks(struct Object* o) { } return 3; } - printf("Error handeling your item, please report it to @komiko\n"); + printf("Error handling your item, please report it to @komiko\n"); return 0; } +/** + * Adds eligible perks to an Object based on its number of available perks. + * + * @param o A pointer to the Object structure to which perks are being added. + * If NULL, the function returns immediately. + */ void addPerks(struct Object* o) { if(o == NULL){ return; } - bool perk_choice = true; - bool is_event = true; - int number_of_perks = numberOfPerks(o); - for(int i = 0; iperk_list[i] = displayAndChooseAvailablePerks(perk_list, is_event, o); - perk_choice = true; - free(perk_list); + + char** perk_list = perkLists(o); // Retrieves the list of available perks for the Object. + o->perk_list[i] = displayAndChooseAvailablePerks(perk_list, is_event, o); // Prompts user to choose a perk. + perk_choice = true; // Reset choice for next iteration. + free(perk_list); // Free allocated memory for the perk list. } return; } + +/** + * Displays available perks based on specified rarity and allows the user to choose one. + * Allocates memory for file paths, handles user input for perk rarity, reads files + * to display available perks, and creates the selected Perk struct for the specified object. + * + * @param perk_list Array of perk names as strings to determine perk file paths + * @param is_event Boolean indicating if the perk is event-based or regular + * @param o Pointer to the Object struct for which the perk is selected + * @return Pointer to the created Perk struct, or NULL if an error occurs + */ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, struct Object* o) { if (perk_list == NULL) { printf("Error: perk_list is NULL\n"); @@ -107,6 +145,8 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str char* perk_rarity = NULL; bool perk_rarity_choice = true; + + // Prompt user to select perk rarity while (perk_rarity_choice) { printf("What do you want to do\n"); printf("------------------------\n"); @@ -144,8 +184,8 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str char* perks_full_path[3] = {NULL, NULL, NULL}; // Array to store file paths int num_files = 0; + // Allocate and build file paths based on event status and selected rarity if (is_event) { - // Allocate memory for event perk file paths perks_full_path[0] = malloc(19 + strlen(perk_rarity) + 1 + strlen(perk_list[0]) + 4 + 1); perks_full_path[1] = malloc(19 + strlen(perk_rarity) + 1 + strlen(perk_list[1]) + 4 + 1); if (perks_full_path[0] == NULL || perks_full_path[1] == NULL) { @@ -158,9 +198,7 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str sprintf(perks_full_path[0], "../Perk_data/event_%s_%s.csv", perk_rarity, perk_list[0]); sprintf(perks_full_path[1], "../Perk_data/event_%s_%s.csv", perk_rarity, perk_list[1]); num_files = 2; - } - else { - // Allocate memory for normal perk file paths + } else { perks_full_path[0] = malloc(20 + strlen(perk_rarity) + 1 + strlen(perk_list[0]) + 4 + 1); perks_full_path[1] = malloc(20 + strlen(perk_rarity) + 1 + strlen(perk_list[1]) + 4 + 1); perks_full_path[2] = malloc(20 + strlen(perk_rarity) + 14 + 1); @@ -182,6 +220,7 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str int perk_iter = 0; int perk_choice[3] = {0}; // Array to store the number of perks in each file + // Display available perks from files printf("Available perks for your object\n"); printf("------------------------\n"); for (int i = 0; i < num_files; i++) { @@ -191,6 +230,7 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str continue; } + // Read perks line by line while (!feof(file)) { if (fgets(line, sizeof(line), file) == NULL) { printf("Error reading line from file \"%s\"\n", perks_full_path[i]); @@ -198,20 +238,20 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str file = NULL; break; } - char* copiedline = strdup(line); perk_iter++; printf("%d. %s", perk_iter, copiedline); free(copiedline); // Free the copied line } + // Calculate perks count per file if (i > 0) { - perk_choice[i] = perk_iter - perk_choice[i - 1]; // Calculate the number of perks in the current file + perk_choice[i] = perk_iter - perk_choice[i - 1]; } else { perk_choice[i] = perk_iter; } - if(file!= NULL){ - fclose(file); // Close the file after reading + if (file != NULL) { + fclose(file); // Close file after reading } printf("\n"); } @@ -221,6 +261,8 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str scanf("%d", &choice_perk); clearInputBuffer(); int file_number = -1; + + // Determine which file contains the selected perk based on user input if (choice_perk <= perk_choice[0]) { file_number = 0; choice_perk = choice_perk - 1; @@ -238,6 +280,7 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str return NULL; } + // Find and read the selected perk line in the chosen file perk_iter = 0; while (choice_perk > perk_iter) { if (fgets(line, sizeof(line), file) == NULL) { @@ -257,8 +300,7 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str char* copiedline = strdup(line); struct Perk* p = NULL; - printf("\n %s \n",line); - + // Parse perk values and types from the selected line char* token = strtok(copiedline, ","); float first_boost_value = atof(token); token = strtok(NULL, ","); @@ -268,85 +310,103 @@ struct Perk* displayAndChooseAvailablePerks(char** perk_list, bool is_event, str token = strtok(NULL, "\r"); char* second_boost_type = strdup(token); - free(copiedline); // Free the copied line - fclose(file); // Close the file after reading + free(copiedline); // Free copied line memory + fclose(file); // Close file after reading char* selected_perk = malloc((strlen(first_boost_type) + strlen(second_boost_type)) * sizeof(char)); + snprintf(selected_perk, strlen(first_boost_type) + strlen(second_boost_type), "%s,%s", first_boost_type, second_boost_type); - snprintf(selected_perk, strlen(first_boost_type) + strlen(second_boost_type), "%s,%s",first_boost_type,second_boost_type); - - if(perk_already_fited(is_event,o,selected_perk) == false){ - + // Check if selected perk is already applied; if not, create and update it + if (perk_already_fited(is_event, o, selected_perk) == false) { p = createPerk(first_boost_type, second_boost_type, first_boost_value, second_boost_value); - updateEvent(p, is_event); - - } else{ + } else { printf("You can't have multiple of the same event perks on an object"); - p = displayAndChooseAvailablePerks(perk_list,is_event,o); + p = displayAndChooseAvailablePerks(perk_list, is_event, o); } free(selected_perk); - // Free the memory allocated for perk_rarity and perks_full_path + // Free memory allocated for perk_rarity and perks_full_path free(perk_rarity); - for (int i = 0; i < num_files; i++) { free(perks_full_path[i]); } - + return p; } -void updateEvent(struct Perk* p,bool is_event) { +/** + * Updates the event status of a perk. + * + * @param p Pointer to a Perk struct, representing the perk to be updated. + * @param is_event Boolean indicating whether the perk is part of an event. + */ +void updateEvent(struct Perk* p, bool is_event) { p->is_event = is_event; } +/** + * Generates a list of perk files based on the object type and name. + * + * Allocates memory for an array of strings with two elements. + * If the object name matches certain predefined values, the function assigns + * the corresponding filenames and category. Otherwise, returns NULL if + * allocation fails or the object name is invalid. + * + * @param o Pointer to an Object struct, representing the object for which the perk list is generated. + * @return A dynamically allocated array of strings containing the object name and category, + * or NULL if allocation fails or the name is unrecognized. + */ char** perkLists(struct Object* o) { char** files_names = malloc(sizeof(char*) * 2); if (files_names == NULL) { return NULL; } - if(o->type == 0){ - if(strcmp(o->name, "standard_cannon") == 0 || strcmp(o->name, "blast_cannon") == 0 ||strcmp(o->name, "sniper_cannon") == 0 || strcmp(o->name, "explosive_cannon") == 0) { + if(o->type == 0) { + if(strcmp(o->name, "standard_cannon") == 0 || strcmp(o->name, "blast_cannon") == 0 || + strcmp(o->name, "sniper_cannon") == 0 || strcmp(o->name, "explosive_cannon") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_cannons"); - } else if(strcmp(o->name, "galting_gun") == 0 || strcmp(o->name, "carronade") == 0 ||strcmp(o->name, "grenade_launcher") == 0 || strcmp(o->name, "railgun") == 0 || strcmp(o->name, "mine") == 0) { + } else if(strcmp(o->name, "galting_gun") == 0 || strcmp(o->name, "carronade") == 0 || + strcmp(o->name, "grenade_launcher") == 0 || strcmp(o->name, "railgun") == 0 || strcmp(o->name, "mine") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("none"); - } else if(strcmp(o->name, "standard_mortar") == 0 || strcmp(o->name, "long_range_mortar") == 0 ||strcmp(o->name, "ballpark_mortar") == 0 || strcmp(o->name, "big_berta") == 0) { + } else if(strcmp(o->name, "standard_mortar") == 0 || strcmp(o->name, "long_range_mortar") == 0 || + strcmp(o->name, "ballpark_mortar") == 0 || strcmp(o->name, "big_berta") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_mortars"); - } else if(strcmp(o->name, "standard_torpedo") == 0 || strcmp(o->name, "big_torpedo") == 0 ||strcmp(o->name, "swift_torpedo") == 0 || strcmp(o->name, "triple_torpedo") == 0) { + } else if(strcmp(o->name, "standard_torpedo") == 0 || strcmp(o->name, "big_torpedo") == 0 || + strcmp(o->name, "swift_torpedo") == 0 || strcmp(o->name, "triple_torpedo") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_torpedoes"); } else if(strcmp(o->name, "missile_launcher") == 0 || strcmp(o->name, "multi_missile") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_missiles"); - } else if(strcmp(o->name, "flare_gun") == 0 || strcmp(o->name, "napalm_launcher") == 0 ||strcmp(o->name, "fire_bomb") == 0) { + } else if(strcmp(o->name, "flare_gun") == 0 || strcmp(o->name, "napalm_launcher") == 0 || + strcmp(o->name, "fire_bomb") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_fire"); } else { free(files_names); return NULL; } - } - else if(o->type == 1){ - if(strcmp(o->name, "standard_shield") == 0 || strcmp(o->name, "big_shield") == 0){ + } else if(o->type == 1) { + if(strcmp(o->name, "standard_shield") == 0 || strcmp(o->name, "big_shield") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_shields"); - } else if(strcmp(o->name, "turbo") == 0){ + } else if(strcmp(o->name, "turbo") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("none"); - } else if(strcmp(o->name, "bandage") == 0 || strcmp(o->name, "big_bandage") == 0){ + } else if(strcmp(o->name, "bandage") == 0 || strcmp(o->name, "big_bandage") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_healing"); } else { free(files_names); return NULL; } - } - else if(o->type == 2) { - if(strcmp(o->name, "overboost") == 0 || strcmp(o->name, "nitro") == 0 || strcmp(o->name, "tesla_bolt") == 0 || strcmp(o->name, "tesla_shield") == 0) { + } else if(o->type == 2) { + if(strcmp(o->name, "overboost") == 0 || strcmp(o->name, "nitro") == 0 || strcmp(o->name, "tesla_bolt") == 0 || + strcmp(o->name, "tesla_shield") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("none"); } else if(strcmp(o->name, "frost_blaster") == 0 || strcmp(o->name, "frost_launcher") == 0) { @@ -356,35 +416,46 @@ char** perkLists(struct Object* o) { free(files_names); return NULL; } - } - else if(o->type == 3) { - if(strcmp(o->name, "repair_box_launcher") == 0 || strcmp(o->name, "repair_pulse") == 0 || strcmp(o->name, "duct_tape") == 0 || strcmp(o->name, "repair_bolt") == 0 || strcmp(o->name, "repair_plasma") == 0) { + } else if(o->type == 3) { + if(strcmp(o->name, "repair_box_launcher") == 0 || strcmp(o->name, "repair_pulse") == 0 || + strcmp(o->name, "duct_tape") == 0 || strcmp(o->name, "repair_bolt") == 0 || strcmp(o->name, "repair_plasma") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("all_healing"); - } else { - free(files_names); - return NULL; - } - } - else if(o->type == 4) { - if(strcmp(o->name, "defence_wall") == 0 || strcmp(o->name, "defence_aura") == 0 || strcmp(o->name, "bloster_armor") == 0 || strcmp(o->name, "cleanse_pulse") == 0) { + } else { + free(files_names); + return NULL; + } + } else if(o->type == 4) { + if(strcmp(o->name, "defence_wall") == 0 || strcmp(o->name, "defence_aura") == 0 || + strcmp(o->name, "bloster_armor") == 0 || strcmp(o->name, "cleanse_pulse") == 0) { files_names[0] = strdup(o->name); files_names[1] = strdup("none"); - } else { - free(files_names); - return NULL; - } + } else { + free(files_names); + return NULL; + } } return files_names; } +/** + * Checks if a perk is already fitted to the object based on the event type. + * + * Iterates through the object's perk list, comparing each perk to the selected perk + * (case-insensitive). Returns true if a matching perk is found, otherwise false. + * + * @param is_event Boolean indicating if the object is event-based. + * @param o Pointer to an Object struct containing the perk list. + * @param selected_perk String representing the name of the perk to check. + * @return True if the selected perk is already fitted, false otherwise. + */ bool perk_already_fited(bool is_event, struct Object* o, char* selected_perk) { bool is_fited = false; - if(is_event){ - for(int i = 0; i<4;i++){ - if(o->perk_list[i] != NULL){ + if(is_event) { + for(int i = 0; i < 4; i++) { + if(o->perk_list[i] != NULL) { char* perk = perk_to_string(o->perk_list[i]); - if(strcasecmp(perk,selected_perk)==0){ + if(strcasecmp(perk, selected_perk) == 0) { is_fited = true; } free(perk); @@ -394,19 +465,36 @@ bool perk_already_fited(bool is_event, struct Object* o, char* selected_perk) { return is_fited; } +/** + * Converts the boost types of a perk into a comma-separated string format. + * + * Allocates memory for a string containing the first and second boost types, + * separated by a comma. Returns NULL if allocation fails. + * + * @param p Pointer to a Perk struct, representing the perk to convert. + * @return A dynamically allocated string of the perk's boost types in "type1,type2" format, or NULL if allocation fails. + */ char* perk_to_string(struct Perk* p) { char* perk = malloc((strlen(p->first_boost_type) + strlen(p->second_boost_type)) * sizeof(char)); if (perk == NULL) { return NULL; } - snprintf(perk, strlen(p->first_boost_type) + strlen(p->second_boost_type), "%s,%s",p->first_boost_type,p->second_boost_type); + snprintf(perk, strlen(p->first_boost_type) + strlen(p->second_boost_type), "%s,%s", p->first_boost_type, p->second_boost_type); return perk; } -void displayPerk(struct Perk p ) { +/** + * Displays the details of a given perk. + * + * Prints the event status, first and second boost values, and boost types + * of the perk to standard output. + * + * @param p Perk struct containing the details to be displayed. + */ +void displayPerk(struct Perk p) { printf("Is Event: %s\n", p.is_event ? "True" : "False"); printf("First Boost Value: %.2f\n", p.first_boost_value); printf("First Boost Type: %s\n", p.first_boost_type); printf("Second Boost Value: %.2f\n", p.second_boost_value); printf("Second Boost Type: %s\n", p.second_boost_type); -} \ No newline at end of file +} diff --git a/readtraining.c b/readtraining.c index c6fa842..7c868d8 100644 --- a/readtraining.c +++ b/readtraining.c @@ -3,7 +3,6 @@ #include #include #include -#include "objects.h" #include "readtraining.h" #include "clear_input.h" #define MAX_LINE_SIZE 1024 @@ -52,13 +51,12 @@ struct Training* createTraining(unsigned int training_lvl) { /** * Reads training data from a CSV file for a specified object and returns a Training struct. * - * @param o The object whose training data is being requested. * @param object_name The name of the object to locate its training data file. * @return A pointer to a Training struct, or NULL if an error occurs (e.g., object or file is not found). */ -struct Training* readTraining(struct Object* o, char* object_name) { - // Check if object or object name is null, return NULL in case of invalid input - if (o == NULL || object_name == NULL) { +struct Training* readTraining(char* object_name) { + // Check if object name is null, return NULL in case of invalid input + if (object_name == NULL) { return NULL; } // Allocate memory for the training file name string, including the base path, object name, and extension diff --git a/readtraining.h b/readtraining.h index 438ef61..a54a8e5 100644 --- a/readtraining.h +++ b/readtraining.h @@ -6,6 +6,6 @@ struct Training { char** type; float* value; }; - -struct Training* readTraining(struct Object* o,char* object_name); +struct Training* createTraining(unsigned int training_lvl); +struct Training* readTraining(char* object_name); #endif