1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: actsummontrap.cpp
5 Desc: behavior function for summoning trap
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12 #include "main.hpp"
13 #include "game.hpp"
14 #include "stat.hpp"
15 #include "entity.hpp"
16 #include "items.hpp"
17 #include "monster.hpp"
18 #include "net.hpp"
19 #include "collision.hpp"
20 #include "magic/magic.hpp"
21 #include "sound.hpp"
22 #include "player.hpp"
23 #include "mod_tools.hpp"
24
25 #define SUMMONTRAP_MONSTER my->skill[0]
26 #define SUMMONTRAP_COUNT my->skill[1]
27 #define SUMMONTRAP_INTERVAL my->skill[2]
28 #define SUMMONTRAP_SPAWNCYCLES my->skill[3]
29 #define SUMMONTRAP_POWERTODISABLE my->skill[4]
30 #define SUMMONTRAP_FAILURERATE my->skill[5]
31 #define SUMMONTRAP_FIRED my->skill[6]
32 #define SUMMONTRAP_INITIALIZED my->skill[7]
33 #define SUMMONTRAP_TICKS_TO_FIRE my->skill[8]
34
actSummonTrap(Entity * my)35 void actSummonTrap(Entity* my)
36 {
37 if ( my->skill[28] == 0 || (SUMMONTRAP_INITIALIZED && SUMMONTRAP_FIRED) )
38 {
39 return;
40 }
41
42 // received on signal
43 if ( (my->skill[28] == 2 && !SUMMONTRAP_POWERTODISABLE) || my->skill[28] == 1 && SUMMONTRAP_POWERTODISABLE )
44 {
45 if ( SUMMONTRAP_TICKS_TO_FIRE > 0 )
46 {
47 --SUMMONTRAP_TICKS_TO_FIRE;
48 }
49
50 // if the time interval between between spawns is reached, or if the mechanism is switched on for the first time.
51 if ( SUMMONTRAP_TICKS_TO_FIRE == 0 || !SUMMONTRAP_INITIALIZED )
52 {
53 SUMMONTRAP_TICKS_TO_FIRE = (TICKS_PER_SECOND * SUMMONTRAP_INTERVAL);
54
55 if ( !SUMMONTRAP_FIRED && SUMMONTRAP_SPAWNCYCLES > 0 )
56 {
57 bool useCustomMonsters = monsterCurveCustomManager.curveExistsForCurrentMapName(map.name);
58 bool fixedCustomMonster = true;
59 Monster customMonsterType = NOTHING;
60 bool pickedRandomMonsters = (SUMMONTRAP_MONSTER == -1);
61
62 if ( SUMMONTRAP_MONSTER > 0 && SUMMONTRAP_MONSTER < NUMMONSTERS )
63 {
64 // spawn the monster given to the trap.
65 }
66 else if ( SUMMONTRAP_MONSTER == 0 || SUMMONTRAP_MONSTER >= NUMMONSTERS )
67 {
68 // spawn the monster scaled to current level.
69 if ( useCustomMonsters )
70 {
71 fixedCustomMonster = false;
72 customMonsterType = static_cast<Monster>(monsterCurveCustomManager.rollMonsterFromCurve(map.name));
73 }
74 else
75 {
76 SUMMONTRAP_MONSTER = monsterCurve(currentlevel);
77 }
78 }
79 else
80 {
81 // pick a completely random monster (barring some exceptions).
82 SUMMONTRAP_MONSTER = rand() % NUMMONSTERS;
83 while ( SUMMONTRAP_MONSTER == LICH || SUMMONTRAP_MONSTER == SHOPKEEPER || SUMMONTRAP_MONSTER == DEVIL
84 || SUMMONTRAP_MONSTER == MIMIC || SUMMONTRAP_MONSTER == BUGBEAR || SUMMONTRAP_MONSTER == OCTOPUS
85 || SUMMONTRAP_MONSTER == MINOTAUR || SUMMONTRAP_MONSTER == LICH_FIRE || SUMMONTRAP_MONSTER == LICH_ICE
86 || SUMMONTRAP_MONSTER == NOTHING || SUMMONTRAP_MONSTER == SENTRYBOT || SUMMONTRAP_MONSTER == SPELLBOT
87 || SUMMONTRAP_MONSTER == GYROBOT || SUMMONTRAP_MONSTER == DUMMYBOT )
88 {
89 SUMMONTRAP_MONSTER = rand() % NUMMONSTERS;
90 }
91 }
92
93 int count = 0;
94 for ( count = 0; count < SUMMONTRAP_COUNT; count++ )
95 {
96 Entity* monster = nullptr;
97 int typeToSpawn = SUMMONTRAP_MONSTER;
98 if ( useCustomMonsters && customMonsterType != NOTHING )
99 {
100 typeToSpawn = customMonsterType;
101 }
102 monster = summonMonster(static_cast<Monster>(typeToSpawn), my->x, my->y);
103 if ( monster && monster->getStats() )
104 {
105 if ( useCustomMonsters )
106 {
107 std::string variantName = "default";
108 if ( fixedCustomMonster )
109 {
110 variantName = monsterCurveCustomManager.rollFixedMonsterVariant(map.name, typeToSpawn);
111 }
112 else
113 {
114 variantName = monsterCurveCustomManager.rollMonsterVariant(map.name, typeToSpawn);
115 }
116 if ( variantName.compare("default") != 0 )
117 {
118 Monster tmp = NOTHING;
119 monsterCurveCustomManager.createMonsterFromFile(monster, monster->getStats(), variantName, tmp);
120 }
121 }
122 else
123 {
124 monster->getStats()->MISC_FLAGS[STAT_FLAG_DISABLE_MINIBOSS] = 1; // disable champion normally.
125 }
126 }
127 }
128
129 playSoundEntity(my, 153, 128);
130
131 if ( !SUMMONTRAP_INITIALIZED )
132 {
133 if ( SUMMONTRAP_MONSTER < KOBOLD )
134 {
135 //messagePlayer(clientnum, language[2352], language[90 + SUMMONTRAP_MONSTER]);
136 }
137 else if ( SUMMONTRAP_MONSTER >= KOBOLD )
138 {
139 //messagePlayer(clientnum, language[2352], language[2000 + (SUMMONTRAP_MONSTER - 21)]);
140 }
141 SUMMONTRAP_INITIALIZED = 1; // trap is starting up for the first time.
142 }
143
144 if ( pickedRandomMonsters )
145 {
146 SUMMONTRAP_MONSTER = -1;
147 }
148
149 if ( (SUMMONTRAP_FAILURERATE != 0) && (rand() % 100 < SUMMONTRAP_FAILURERATE) )
150 {
151 // trap breaks!
152 SUMMONTRAP_FIRED = 1;
153 playSoundEntity(my, 76, 128);
154 return;
155 }
156
157 if ( SUMMONTRAP_SPAWNCYCLES > 0 )
158 {
159 --SUMMONTRAP_SPAWNCYCLES; // decrement the amount of spawn chances left.
160 if ( SUMMONTRAP_SPAWNCYCLES == 0 )
161 {
162 // trap is finished running
163 SUMMONTRAP_FIRED = 1;
164 playSoundEntity(my, 76, 128);
165 }
166 }
167 else
168 {
169 // trap keeps running.
170 }
171 }
172 }
173 }
174 else
175 {
176 SUMMONTRAP_TICKS_TO_FIRE = 0;
177 }
178 return;
179 }
180