1 #include "g_local.h"
2 #include "runes.h"
3 #define RF_SHELL_YELLOW 65536
4 void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
5 char *rune_namefornum[] = {NULL, RUNE_STRENGTH_NAME, RUNE_RESIST_NAME, RUNE_HASTE_NAME, RUNE_REGEN_NAME};
6 char *rune_iconfornum[] = {NULL, RUNE_STRENGTH_ICON, RUNE_RESIST_ICON, RUNE_HASTE_ICON, RUNE_REGEN_ICON};
7 //int rune_renderfx[] = {RF_SHELL_RED, RF_SHELL_RED | RF_SHELL_BLUE, RF_SHELL_RED | RF_SHELL_GREEN, RF_SHELL_GREEN};
8 int rune_renderfx[] = {0, RF_SHELL_GREEN, RF_SHELL_BLUE, RF_SHELL_YELLOW/*RF_SHELL_RED | RF_SHELL_GREEN*/, RF_SHELL_RED};
9
10 // true if a person has a specific rune
rune_has_rune(edict_t * ent,int type)11 qboolean rune_has_rune(edict_t *ent, int type){
12 if(!ent->client) return(false);
13 return (ent->client->pers.inventory[ITEM_INDEX(FindItem(rune_namefornum[type]))]);
14 }
15
16 // true if the person has a rune
rune_has_a_rune(edict_t * ent)17 int rune_has_a_rune(edict_t *ent){
18 int i;
19 if(!ent->client)
20 return (0); // only people can have runes
21 for(i = RUNE_FIRST; i <= RUNE_LAST; i++)
22 if(rune_has_rune(ent, i))
23 return (i);
24 return(0);
25 }
26
27 // a live client has touched a rune
rune_pickup(edict_t * self,edict_t * other)28 qboolean rune_pickup(edict_t *self, edict_t *other){
29 // can only carry one rune
30 if(rune_has_a_rune(other))
31 return (false);
32 // give them this rune
33 other->client->pers.inventory[ITEM_INDEX(self->item)] = 1;
34 return(true);
35 }
36
37 // moves the rune to a teleporter pad
rune_move(edict_t * self)38 void rune_move(edict_t *self){
39 rune_select_spawn_point(self->s.origin);
40 if(VectorCompare(self->s.origin, vec3_origin)){
41 G_FreeEdict(self);
42 return;
43 }
44 self->touch = Touch_Item;
45 self->nextthink = level.time + 120;
46 self->think = rune_move;
47 gi.linkentity(self);
48 }
49
50 // makes the rune touchable again after being droppped
rune_make_touchable(edict_t * ent)51 void rune_make_touchable(edict_t *ent){
52 ent->touch = Touch_Item;
53 ent->nextthink = level.time + 120;
54 ent->think = rune_move;
55 }
56
57 // call rune_drop from here?
rune_use(edict_t * ent,gitem_t * item)58 void rune_use(edict_t *ent, gitem_t *item){
59 // do nothing
60 }
61
rune_drop_dying(edict_t * ent,gitem_t * item)62 void rune_drop_dying(edict_t *ent, gitem_t *item){
63 edict_t *rune;
64 rune = Drop_Item(ent, item);
65 rune->think = rune_make_touchable;
66 rune->s.renderfx |= rune_renderfx[item - FindItem(rune_namefornum[RUNE_FIRST]) + RUNE_FIRST];//RF_SHELL_RED | RF_SHELL_GREEN;
67
68 ent->client->pers.inventory[ITEM_INDEX(item)] = 0;
69 ValidateSelectedItem(ent);
70 }
71
72 // drops a rune
rune_drop(edict_t * ent,gitem_t * item)73 void rune_drop(edict_t *ent, gitem_t *item){
74 edict_t *rune;
75 // rune = G_Spawn();
76 // VectorCopy(ent->s.origin, rune->s.origin);
77 // rune_spawn(rune, item->pickup_name);
78 rune = Drop_Item(ent, item);
79 rune->nextthink = level.time + 120;
80 rune->think = rune_move;
81 rune->s.renderfx |= rune_renderfx[item - FindItem(rune_namefornum[RUNE_FIRST]) + RUNE_FIRST];//RF_SHELL_RED | RF_SHELL_GREEN;
82 // rune->noblock = true;
83
84 ent->client->pers.inventory[ITEM_INDEX(item)] = 0;
85 ValidateSelectedItem(ent);
86 }
87
runes_drop_dying(edict_t * ent)88 void runes_drop_dying(edict_t *ent){
89 int i;
90 if((i = rune_has_a_rune(ent)))
91 rune_drop_dying(ent, FindItem(rune_namefornum[i]));
92 }
93
94 // drops any rune a person might have
runes_drop(edict_t * ent)95 void runes_drop(edict_t *ent){
96 int i;
97 if((i = rune_has_a_rune(ent)))
98 rune_drop(ent, FindItem(rune_namefornum[i]));
99 }
100
101 // finds a place to put a rune
102 // or vec3_origin if it can't find one
rune_select_spawn_point(vec3_t origin)103 void rune_select_spawn_point(vec3_t origin){
104 // ZOID
105 edict_t *rune_spawn_point = NULL;
106 int i = rand() & 15;
107
108 while(i--)
109 rune_spawn_point = G_Find(rune_spawn_point, FOFS(classname), "info_player_deathmatch");
110 if(!rune_spawn_point)
111 rune_spawn_point = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
112 if(!rune_spawn_point){
113 gi.dprintf("Couldn't find spawn point for rune\n");
114 VectorClear(origin);
115 } else {
116 VectorCopy(rune_spawn_point->s.origin, origin);
117 }
118 }
119
120 // spawns a rune
rune_spawn(edict_t * rune,gitem_t * item)121 void rune_spawn(edict_t *rune, gitem_t *item){
122 rune->item = item;
123 rune->classname = rune->item->classname;
124 SpawnItem(rune, rune->item);
125 rune->s.renderfx |= rune_renderfx[rune->item - FindItem(rune_namefornum[RUNE_FIRST]) + RUNE_FIRST];//RF_SHELL_RED | RF_SHELL_GREEN;
126 // rune->noblock = true;
127 }
128
129 // spawns all the runes
runes_spawn(edict_t * self)130 void runes_spawn(edict_t *self){
131 edict_t *rune;
132 int i, j;
133
134 for(i = 0; i < (int)runes->value; i++){ // runes number of each rune
135 for(j = RUNE_FIRST; j <= RUNE_LAST; j++){ // run thru all runes
136 rune = G_Spawn();
137 rune_select_spawn_point(rune->s.origin);
138 if(VectorCompare(rune->s.origin, vec3_origin)){
139 G_FreeEdict(rune);
140 } else {
141 rune_spawn(rune, FindItem(rune_namefornum[j]));
142 }
143 }
144 }
145 G_FreeEdict(self);
146 }
147
148 // so we can spawn the runes after the level starts
runes_spawn_start()149 void runes_spawn_start(){
150 edict_t *temp;
151 if(((int)dmflags->value & DF_CTF_NO_TECH) || !runes->value)
152 return;
153 temp = G_Spawn();
154 temp->think = runes_spawn;
155 temp->nextthink = level.time + 2 * FRAMETIME;
156 }
157
rune_set_effects(edict_t * ent)158 void rune_set_effects(edict_t *ent){
159 if(ent->client->rune_time > level.time){
160 ent->s.effects |= EF_COLOR_SHELL;
161 ent->s.renderfx |= RF_SHELL_RED | RF_SHELL_BLUE;
162 // ent->s.effects |= EF_PENT | EF_QUAD;
163 }
164 }
165
rune_apply_regen(edict_t * ent)166 void rune_apply_regen(edict_t *ent){
167 // ZOID
168 gclient_t *client = ent->client;
169
170 if(!client)
171 return;
172
173 if(client->regen_time <= level.time){
174 client->regen_time = level.time;
175 if(ent->health < 150){
176 ent->health += RUNE_REGEN_PER_SEC / 2;
177 if(ent->health > 150)
178 ent->health = 150;
179 if(ent->pain_debounce_time < level.time){
180 if(client->silencer_shots)
181 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 0.2, ATTN_NORM, 0);
182 else
183 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1.0, ATTN_NORM, 0);
184 ent->pain_debounce_time = level.time + 1;
185 }
186 client->regen_time += 0.5;
187 }
188
189 if(ArmorIndex(ent) && client->pers.inventory[ArmorIndex(ent)] < 150){
190 client->pers.inventory[ArmorIndex(ent)] += RUNE_REGEN_PER_SEC / 2;
191 if(client->pers.inventory[ArmorIndex(ent)] > 150)
192 client->pers.inventory[ArmorIndex(ent)] = 150;
193 if(ent->pain_debounce_time < level.time){
194 if(client->silencer_shots)
195 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 0.2, ATTN_NORM, 0);
196 else
197 gi.sound(ent, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1.0, ATTN_NORM, 0);
198 ent->pain_debounce_time = level.time + 1;
199 }
200 client->regen_time += 0.5;
201 }
202 }
203 }
204