1 /************************************************************************
2 * *
3 * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
4 * *
5 * Copyright (C) 2012 Ryan Cocks <ryan@ryancocks.net> *
6 * *
7 * This program is free software; you can redistribute it and / or *
8 * modify it under the terms of the GNU General Public License as *
9 * published by the Free Software Foundation; either version 2 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15 * General Public License for more details. *
16 * *
17 * You can view the GNU General Public License, online, at the GNU *
18 * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
19 * The full text of the license is also included in the file COPYING. *
20 * *
21 ************************************************************************/
22
23 #include "ipastim.h"
24 #include <assert.h>
25
26 #ifdef _DEBUG
27 #include <stdio.h>
28
29 const char * IPAStim::IPANames[3] = {
30 "Adrenaline",
31 "Perception",
32 "Intelligence"
33 };
34 #endif
35
IPAStim(IPAType ipa_type,int amount,int dependency)36 IPAStim::IPAStim(IPAType ipa_type, int amount, int dependency)
37 :ipa_type_(ipa_type), effect_(50), effect_timer_(1000), dependency_timer_(4500)
38 {
39 assert(ipa_type_ <= 3);
40 setLevels(amount, dependency);
41 }
42
getMagnitude() const43 int IPAStim::getMagnitude() const
44 {
45 return dependency_ < amount_ ? amount_ - dependency_: dependency_ - amount_;
46 }
47
48
getMultiplier() const49 float IPAStim::getMultiplier() const
50 {
51 // With an agent with no mods and his adrenaline dependency in the
52 // center: his speed will be halved or doubled with the adrenaline
53 // bar at the respective extreme.
54
55 // An agent with no adrenaline, no mods and no weaponry walks at
56 // the same speed as a civilian.
57
58 // This function has been implemented to assume that FULL adrenaline
59 // would give a 2x increase in speed and the worst case would leave
60 // you walking at a half speed. With neutral adrenaline it has no
61 // effect and therefore returns 1.
62
63 // Thus, the algortithm used here goes from 0.5 to 1 for 'negative'
64 // adrenaline and 1 to 2 on the positive side.
65 int magnitude = getMagnitude();
66
67 if(direction() == IPA_boost) {
68 // return value is 1 to 2 for values
69 // of 'magnitude' from 0 to 100
70 // If you fiddle with this equation beware of
71 // values for effective which are close to 0
72 float mult = part_of_two(magnitude);
73 assert(mult >= 1 && mult <= 2);
74 //printf("%s boost: m:%d->%fx\n", getName(), magnitude_, mult);
75 return mult;
76 } else {
77 // < 0
78 // range: 0.5 up towards 1
79 float mult = 1.0/part_of_two(magnitude);
80 assert(mult >= 0.5 && mult <= 1.0);
81 //printf("%s reduce: m:%d->%fx\n", getName(), magnitude_, mult);
82 return mult;
83 }
84 }
85
setLevels(int amount,int dependency,int effect)86 void IPAStim::setLevels(int amount, int dependency, int effect)
87 {
88 amount_ = amount;
89 dependency_ = dependency;
90
91 effect_ = dependency;
92
93 //printf("%s: A: %d, D: %d, E: %d\n", getName(), amount, dependency, effect_);
94 }
95
processTicks(int elapsed)96 void IPAStim::processTicks(int elapsed)
97 {
98 // From observation of the original Syndicate:
99 // * Effect moves about once a second.
100 // * Dependency bar moves once for every 5 or 6 moves of Effect
101 // * Effect is independent of amount! If you flick amount to the
102 // other side effect will stay where it was.
103 // * there appear to be 50 'positions' on the bar so it looks
104 // like the levels move in notches, 1% at a time.
105
106 if(effect_timer_.update(elapsed))
107 {
108 if(effect_ > amount_)
109 {
110 --effect_;
111 }
112 else if(effect_ < amount_)
113 {
114 ++effect_;
115 }
116 else // equal
117 {
118 // So once effect has 'caught up' to amount then they
119 // both start moving towards the value of dependency
120 // together
121 if(amount_ > dependency_)
122 {
123 effect_ = --amount_;
124 }
125 else if(amount_ < dependency_)
126 {
127 effect_ = ++amount_;
128 }
129 }
130 assert(effect_ >= 0 && effect_ <= 100);
131 }
132
133 // The dependency indicator always creaps towards amount
134 if(dependency_timer_.update(elapsed))
135 {
136 if (dependency_ > amount_) {
137 --dependency_;
138 } else if (dependency_ < amount_) {
139 ++dependency_;
140 } else {
141 // equal
142 if (amount_ < 50) {
143 ++amount_;
144 ++dependency_;
145 } else if (amount_ > 50) {
146 --amount_;
147 --dependency_;
148 }
149 }
150 assert(dependency_ >= 0 && dependency_ <= 100);
151
152 }
153 }
154