Paralysis effect not functioning properly

I'm making a battle system in C which incorporates things like attacking, defending and casting spells. It's a console app, so nothing too fancy. One of the problems I've run into is that when I paralyze the enemy, they stay paralyzed. The paralysis doesn't wear off after 1 - 3 turns as it's supposed to. I've provided all of the functions that incorporate paralysis and which I think are relevant. The full program is over one thousand lines overall, and it's not yet finished, but I'll put it up if more context is needed.

Would anyone be willing to help with this?
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
int main()
{
    // Seeds a random number based on time()
    srand(time(NULL));

    // Player properties
    Player player =
    {
        "Name", // name
        300, // max_health
        300, // health
        500, // max_mana
        500, // mana
        12, // attack
        6, // defense
        11, // max_agility
        11, // agility

        // Spells
        {"Fireball", "Lightning Bolt", "Ice Blast"},

        // Status
        {
            false, // faster
            false, // burned
            false, // paralyzed
            false, // freezing
            0, // max_turns_paralyzed
            0 // turns_paralyzed
        }
    };

    // Enemy properties
    Player enemy =
    {
        "Enemy", // name
        350, // max_health
        350, // health
        0, // max_mana
        0, // mana
        10, // attack
        8, // defense
        10, // max_agility
        10, // agility

        // Spells
        {},

        // Status
        {
            false, // faster
            false, // burned
            false, // paralyzed
            false, // freezing
            0, // max_turns_paralyzed
            0 // turns_paralyzed
        }
    };

    // Pointers
    Player *p_ptr = &player;
    Player *e_ptr = &enemy;

    // Name the player
    // name_player(p_ptr);

    do
    {
        battle(p_ptr, e_ptr);
    }while(1);

    return 0;
}// end main() 


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
void attack_first(Player *p_ptr, Player *e_ptr)
{
    int random = 0;
    bool crit = false;

    random = 1 + rand() % 5;

    if(p_ptr->status.paralyzed == true && e_ptr->status.paralyzed == false)
    {
        receive_paralyze_effect(p_ptr);

        if(random == 1)
        {
            printf("The enemy is defending!\n");
        }
        else
        {
            crit = receive_crit(p_ptr, e_ptr);

            if(crit == false)
            {
                receive_attack_damage(p_ptr, e_ptr);

                is_player_alive(p_ptr, e_ptr);
            }
        }

        p_ptr->status.turns_paralyzed++;
    }
    else if(p_ptr->status.paralyzed == false && e_ptr->status.paralyzed == true)
    {
        crit = apply_crit(p_ptr, e_ptr);

        if(crit == false)
        {
            apply_attack_damage(p_ptr, e_ptr);

            is_enemy_alive(p_ptr, e_ptr);
        }

        apply_paralyze_effect(e_ptr);

        e_ptr->status.turns_paralyzed++;
    }
    else if(p_ptr->status.paralyzed == true && e_ptr->status.paralyzed == true)
    {
        receive_paralyze_effect(p_ptr);

        apply_paralyze_effect(e_ptr);

        p_ptr->status.turns_paralyzed++;

        e_ptr->status.turns_paralyzed++;
    }
    else
    {
        if(random == 1)
        {
            apply_reduced_damage(p_ptr, e_ptr);

            is_enemy_alive(p_ptr, e_ptr);
        }
        else
        {
            crit = apply_crit(p_ptr, e_ptr);

            if(crit == false)
            {
                apply_attack_damage(p_ptr, e_ptr);

                is_enemy_alive(p_ptr, e_ptr);
            }

            crit = receive_crit(p_ptr, e_ptr);

            if(crit == false)
            {
                receive_attack_damage(p_ptr, e_ptr);

                is_player_alive(p_ptr, e_ptr);
            }
        }
    }
}// end attack_first() 


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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
void magic_first(Player *p_ptr, Player *e_ptr, int *turn)
{
    int choose_magic = 0;
    int random = 0;
    bool crit = false;

    random = 1 + rand() % 5;

    scanf("%d", &choose_magic);

    switch(choose_magic)
    {
        // Fireball
        case 1:
        {
            if(p_ptr->mana < 8)
            {
                printf("Insufficient mana!\n");
            }
            else
            {
                if(random == 1)
                {
                    apply_reduced_fireball(p_ptr, e_ptr);
                }
                else
                {
                    apply_fireball(p_ptr, e_ptr);

                    crit = receive_crit(p_ptr, e_ptr);

                    if(crit == false)
                    {
                        receive_attack_damage(p_ptr, e_ptr);
                    }
                }

                check_status(p_ptr, e_ptr);

                *turn = *turn + 1;
            }

            break;
        }// end case 1

        // Lightningbolt
        case 2:
        {
            if(p_ptr->status.paralyzed == true && e_ptr->status.paralyzed == false)
            {
                receive_paralyze_effect(p_ptr);

                crit = receive_crit(p_ptr, e_ptr);

                if(crit == false)
                {
                    receive_attack_damage(p_ptr, e_ptr);
                }

                check_status(p_ptr, e_ptr);

                *turn = *turn + 1;
            }
            else if(p_ptr->status.paralyzed == false && e_ptr->status.paralyzed == true)
            {
                if(p_ptr->mana < 12)
                {
                    printf("Insufficient mana!\n");
                }
                else
                {
                    apply_lightningbolt(p_ptr, e_ptr);

                    apply_paralyze_effect(e_ptr);

                    check_status(p_ptr, e_ptr);

                    *turn = *turn + 1;
                }
            }
            else if(p_ptr->status.paralyzed == true && e_ptr->status.paralyzed == true)
            {
                receive_paralyze_effect(p_ptr);

                apply_paralyze_effect(e_ptr);

                *turn = *turn + 1;
            }
            else
            {
                if(p_ptr->mana < 12)
                {
                    printf("Insufficient mana!\n");
                }
                else
                {
                    if(random == 1)
                    {
                        apply_reduced_lightningbolt(p_ptr, e_ptr);
                    }
                    else
                    {
                        apply_lightningbolt(p_ptr, e_ptr);

                        crit = receive_crit(p_ptr, e_ptr);

                        if(crit == false)
                        {
                            receive_attack_damage(p_ptr, e_ptr);
                        }

                        /*if(e_ptr->status.paralyzed == true)
                        {
                            apply_paralyze_effect(e_ptr);
                        }*/
                    }

                    check_status(p_ptr, e_ptr);

                    *turn = *turn + 1;
                }
            }

            break;
        }// end case 2

        // Iceblast
        case 3:
        {
            if(p_ptr->mana < 10)
            {
                printf("Insufficient mana!\n");
            }
            else
            {
                if(random == 1)
                {
                    apply_reduced_iceblast(p_ptr, e_ptr);
                }
                else
                {
                    apply_iceblast(p_ptr, e_ptr);

                    crit = receive_crit(p_ptr, e_ptr);

                    if(crit == false)
                    {
                        receive_attack_damage(p_ptr, e_ptr);
                    }
                }

                check_status(p_ptr, e_ptr);

                *turn = *turn + 1;
            }

            break;
        }// end case 3

        case 4:
        {
            display_battle_menu(p_ptr, e_ptr);

            break;
        }// end case 4
    }// end switch()
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void apply_lightningbolt(Player *p_ptr, Player *e_ptr)
{
    printf("You cast Lightningbolt!\nThe enemy takes 12 damage!\n");

    e_ptr->health = e_ptr->health - 12;

    p_ptr->mana = p_ptr->mana - 12;

    is_enemy_alive(p_ptr, e_ptr);

    if(e_ptr->status.paralyzed == false)
    {
        apply_paralyze_chance(e_ptr);
    }
    else
    {
        e_ptr->status.turns_paralyzed++;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void apply_reduced_lightningbolt(Player *p_ptr, Player *e_ptr)
{
    printf("The enemy is defending!\n");

    printf("You cast Lightningbolt!\nThe enemy takes 6 damage!\n");

    e_ptr->health = e_ptr->health - 6;

    p_ptr->mana = p_ptr->mana - 12;

    is_enemy_alive(p_ptr, e_ptr);

    if(e_ptr->status.paralyzed == false)
    {
        apply_paralyze_chance(e_ptr);
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void apply_paralyze_chance(Player *e_ptr)
{
    int random = 0;
    int turns = 0;

    if(e_ptr->status.paralyzed == false)
    {
        random = 1 + rand() % 4;

        if(random == 1)
        {
            printf("The enemy has been paralyzed!\n");

            e_ptr->status.paralyzed = true;

            turns = 1 + rand() % 3;

            e_ptr->status.max_turns_paralyzed = turns;

            //printf("You are to be paralyzed for %d turns\n", e_ptr->status.max_turns_paralyzed);
        }
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void apply_paralyze_effect(Player *e_ptr)
{
    printf("apply_paralyze_effect %d\n", e_ptr->status.turns_paralyzed);

    printf("The enemy is paralyzed! It cannot move!\n");

    e_ptr->status.turns_paralyzed = e_ptr->status.turns_paralyzed + 1;

    if(e_ptr->status.turns_paralyzed == e_ptr->status.max_turns_paralyzed)
    {
        printf("The enemy is no longer paralyzed!\n");

        e_ptr->status.paralyzed == false;

        e_ptr->status.turns_paralyzed = 0;

        e_ptr->status.max_turns_paralyzed = 0;
    }
}
Where is the code for receive_paralyze_effect?
Didn't look through all of it,
but this looks like a mistake ;)
 
e_ptr->status.paralyzed == false;

in your last block of code.
@fg109
In the bug I ran into, the player isn't paralyzed. But it's essentially just a reverse of apply_paralyze_effect, on the player instead of the enemy.

@Ganado
*facepalm*... Thank you, that fixed that particular problem.

I'm getting another error now, which is that immediately after I paralyze the enemy, it still attacks me. I'll look into it and get back to you if I can't figure it out.
Have you noticed that you increment turns_paralyzed in both attack_first and apply_paralyze_effect?
Yeah I just noticed that. I'm currently testing it with that removed. Thanks for pointing it out though.
Okay, thanks guys, paralysis against the enemy seems to be working fine now. It's very frustrating when you are repeatedly looking through your code for some error in your logic that's stopping the program from working properly, when all that was wrong was a damn syntax error the compiler failed to pick up.

As a side question, what is the point of function prototyping aside from code layout? Does it make the program run faster?

Also, is it okay to post large (1000+ lines) programs here or is there a limit?
Anyone know?
function prototyping is required because declarations need to be seen before they are used.

in this example the compiler has no idea what b() is when its trying to compile a().

1
2
3
4
5
6
7
8
9

void a()
{
    b();
}

void b()
{
}

Okay, thanks. Don't you think things get quite cluttered though when you have a couple dozen or more prototypes at the top of your code? Could you move those into a header file or do you need them in the same file as your functions? In fact, would it be better to move all your functions to a header file, especially if your program becomes quite big(1000+ lines)?

Can we post any size program here, or is there a limit?
its debatable whether to put them in a header or not. tradition says it goes in a header if you want to reference it from more than one file, otherwise keep it contained.

you can make it work to your advantage though, it you have lots of forward declarations you can organise them into groups with a nice comment saying what that group does, it helps the reader because they dont have to search your code to see what functions are available.

1
2
3
4
5
6
7
// conversion functions
int f1(float);
float f2(int);

// search functions
bool hasFlag();
int findAge();


we have some massive classes at work, and we have to organise our member functions in the same way otherwise we would never find anything without doing a search.


I dont think there is a limit to how much code you can post, but there is definately a limit to how much i am prepared to read :) I didnt read your original code problem, but did read your later questions.
Last edited on
Ha, I understand. It's a lot to ask of people to read through that much code.

Thanks for the tip with commenting the prototypes, I think I'll start doing that from now on.

One of the big reasons to use classes is to improve code structure and things like legibility, expandability and maintainability, right? I've been working with C for the past few months, and one of the things I've noticed is how quickly code can get messy if you're not careful. It feels like things lack structure and direction and I don't know if that's an issue with procedural programming or just my inexperience with large code complexity.

I'm thinking of going back to C++ and the next thing to learn would be classes. Would classes help with this issue and keep things in order and easy to manage?
keeping it clean and legible is down to you unfortunately, classes will help because you will have somewhere to organise code, but having lots of small shelves wont stop some people putting stuff on them willy nilly.

organisation is in the mind, i've worked on very large C programs and they are just as readable and maintainable as any other language. I guess the trick is in knowing how to organise.

if you want to stay in C for a while try to be modular, i found it the best way to organise my code. Indeed, before OO came along modules was the way to go and many languages were invented to help with that like modula2 and ada.

try to keep a public and private interface, ie; dont put everything in headers, just the stuff other modules will need access to.
By modular do you mean breaking tasks up into separate functions? If so I already do. It's keeping track of the functions themselves that then starts to become a bit tricky, which is I think where classes come in, as the different classes will hold relevant functions, rather than the functions being indiscriminately spread throughout the code. This will help with organisation, I hope. I've never used classes before, but I think that's one way in which they can help.
Topic archived. No new replies allowed.