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