Exemple #1
0
void adminSpawnRune(edict_t *self, int type, int index)
{
	gitem_t *item;
	edict_t *rune;

	item = FindItem("Rune");		// get the item properties
	rune = Drop_Item(self, item);	// create the entity that holds those properties
	V_ItemClear(&rune->vrxitem);	// initialize the rune
	rune->vrxitem.quantity = 1;
	
	switch(type)
	{
	case ITEM_WEAPON:		spawnNorm(rune, index, ITEM_WEAPON); return;
	case ITEM_ABILITY:		spawnNorm(rune, index, ITEM_ABILITY); return;
	case ITEM_COMBO:		spawnCombo(rune, index); return;
	case ITEM_CLASSRUNE:	spawnClassRune(rune, index); return;
	//Try to spawn a unique (or a random one if it fails to find one at the index)
	case ITEM_UNIQUE:		if (!spawnUnique(rune, index)) spawnNorm(rune, index, 0); return;
	}

	//Randomize id
	strcpy(rune->vrxitem.id, GetRandomString(16));

	//Free the ent (if no rune was spawned)
	G_FreeEdict(rune);
}
Exemple #2
0
void Cmd_Armory_f(edict_t *ent, int selection)
{
	int			cur_credits=ent->myskills.credits;
	gitem_t		*item = 0;
	int			price = 0;
	int			qty = 0;
	item_t		*slot;
	int			type = ITEM_NONE;
	//int			talentLevel;

	if (ent->deadflag == DEAD_DEAD)
		return;

	//What is the price/qty of the item?
	if ((selection < 11) && (selection > 0))
		price = ARMORY_PRICE_WEAPON;
	else if (selection < 17)
		price = ARMORY_PRICE_AMMO;
	
    switch(selection)
	{
		//weapons
		case 1:		item = FindItem("Shotgun");			break;	//sg
		case 2:		item = FindItem("Super Shotgun");	break;	//ssg
		case 3:		item = FindItem("Machinegun");		break;	//mg
		case 4:		item = FindItem("Chaingun");		break;	//cg
		case 5:		item = FindItem("Grenade Launcher");break;	//gl
		case 6:		item = FindItem("Rocket Launcher");	break;	//rl
		case 7:		item = FindItem("Hyperblaster");	break;	//hb
		case 8:		item = FindItem("Railgun");			break;	//rg
		case 9:		item = FindItem("bfg10k");			break;	//bfg
		case 10:	item = FindItem("20mm Cannon");		break;	//20mm

		//ammo
		case 11:
			item = FindItem("Bullets");
			qty = ent->client->pers.max_bullets;
			break;
		case 12:
			item = FindItem("Shells");
			qty = ent->client->pers.max_shells;
			break;
		case 13:
			item = FindItem("Cells");
			qty = ent->client->pers.max_cells;
			break;
		case 14:
			item = FindItem("Grenades");
			qty = ent->client->pers.max_grenades;
			break;
		case 15:
			item = FindItem("Rockets");
			qty = ent->client->pers.max_rockets;
			break;
		case 16:
			item = FindItem("Slugs");
			qty = ent->client->pers.max_slugs;
			break;

		//others
		case 17:	//tballs
			price	= ARMORY_PRICE_TBALLS;
			item	= FindItem("tballs");
			qty		= ent->client->pers.max_tballs;
			break;
		case 18:	//4.5 replaced respawns with health
			price	= ARMORY_PRICE_HEALTH;
			qty		= ent->max_health - ent->health;
			break;
		case 19:	//power cubes
			qty		= MAX_POWERCUBES(ent) - ent->client->pers.inventory[ITEM_INDEX(Fdi_POWERCUBE)];
			//Base the price on how many cubes the player needs.
			price	=  qty * ARMORY_PRICE_POWERCUBE;
			break;
		case 20:	//armor
			price	= ARMORY_PRICE_ARMOR;
			item	= FindItem("Body Armor");
			qty		= MAX_ARMOR(ent);
			break;
		case 21:	//health potions
			type	= ITEM_POTION;
			price	= ARMORY_PRICE_POTIONS;
			qty		= ARMORY_QTY_POTIONS;
			slot	= V_FindFreeItemSlot(ent);
			break;
		case 22:	//antidotes
			type	= ITEM_ANTIDOTE;
			price	= ARMORY_PRICE_ANTIDOTES;
			qty		= ARMORY_QTY_ANTIDOTES;
			slot	= V_FindFreeItemSlot(ent);
			break;
		case 23:	//grav boots
			type	= ITEM_GRAVBOOTS;
			price	= ARMORY_PRICE_GRAVITYBOOTS;
			qty		= ARMORY_QTY_GRAVITYBOOTS;
			slot	= V_FindFreeItemSlot(ent);
			break;
		case 24:	//fire resistant clothing
			type	= ITEM_FIRE_RESIST;
			price	= ARMORY_PRICE_FIRE_RESIST;
			qty		= ARMORY_QTY_FIRE_RESIST;
			slot	= V_FindFreeItemSlot(ent);
			break;
		case 25:	//auto-tball
			type	= ITEM_AUTO_TBALL;
			price	= ARMORY_PRICE_AUTO_TBALL;
			qty		= ARMORY_QTY_AUTO_TBALL;
			slot	= V_FindFreeItemSlot(ent);
			break;
		//Runes
		case 26:	//ability rune
			PurchaseRandomRune(ent, ITEM_ABILITY); return;
		case 27:	//weapon rune
			PurchaseRandomRune(ent, ITEM_WEAPON); return;
		case 28:	//reset char data
			price = ARMORY_PRICE_RESET*ent->myskills.level;
			if (price > 50000)
				price = 50000;
			break;
		default:
			gi.dprintf("ERROR: Invalid armory item!\n");
			return;
	}

	//Talent: Bartering
	//talentLevel = getTalentLevel(ent, TALENT_BARTERING);
	//if(talentLevel > 0)		price *= 1.0 - 0.05 * talentLevel;

	if (cur_credits > MAX_CREDITS+10000)
	{
		// as of version 3.13, we can only handle up to 65,535 (unsigned int) credits
		// if we have much more than this, then the player's credits probably got corrupted
		gi.dprintf("WARNING: Cmd_Armory_f corrected invalid player credits\n");
		gi.cprintf(ent, PRINT_HIGH, "Your credits were fixed.\n");
		ent->myskills.credits = 0;
		return;
	}

	if (cur_credits < price)
	{
		gi.cprintf(ent, PRINT_HIGH, "You need at least %d credits to buy this item.\n", price);
		return;
	}

	//If a weapon was purchased
	if ((selection < 11) && (selection > 0))
	{
		ent->client->pers.inventory[ITEM_INDEX(item)] = 1;
		gi.cprintf(ent, PRINT_HIGH, "You bought a %s.\n", item->pickup_name);
	}
	//If ammo was purchased (or T-Balls)
	else if (selection < 18)
	{
		ent->client->pers.inventory[ITEM_INDEX(item)] = qty;
		gi.cprintf(ent, PRINT_HIGH, "You bought %d %s.\n", qty, item->pickup_name);
	}
	//Something else was selected
	else
	{
		switch(selection)
		{
		case 18:	//4.5 health
			{
				if (ent->health >= ent->max_health)
				{
					gi.cprintf(ent, PRINT_HIGH, "You don't need health.\n");
					return;
				}
				ent->health = ent->max_health;
				gi.cprintf(ent, PRINT_HIGH, "You bought %d health.\n", qty);
			}
			break;
		case 19:	//Power Cubes
			{
				if (qty < 1)
				{
					gi.cprintf(ent, PRINT_HIGH, "You don't need power cubes.\n");
					return;
				}
				ent->client->pers.inventory[ITEM_INDEX(Fdi_POWERCUBE)] += qty;
				gi.cprintf(ent, PRINT_HIGH, "You bought %d power cubes.\n", qty);
			}
			break;
		case 20:	//armor
			{
				if (ent->client->pers.inventory[ITEM_INDEX(item)] < MAX_ARMOR(ent))
				{
					ent->client->pers.inventory[ITEM_INDEX(item)] += 100;
					if (ent->client->pers.inventory[ITEM_INDEX(item)] > MAX_ARMOR(ent))
						ent->client->pers.inventory[ITEM_INDEX(item)] = MAX_ARMOR(ent);
					gi.cprintf(ent, PRINT_HIGH, "You bought some armor.\n");
				}
				else
				{
					gi.cprintf(ent, PRINT_HIGH, "You are maxed out on armor already.\n");
					return;
				}
			}
			break;

		// handle all the new items in the same way
		case 21:	//Health Potions
		case 22:	//Antidote Potions (Holy Water)
		case 23:	//Anti-Grav boots
		case 24:	//Fire resist clothing
		case 25:	//Auto-tball
			{
				if (slot == NULL)
				{
					gi.cprintf(ent, PRINT_HIGH, "Not enough inventory space.\n");
					return;
				}

				//4.0 Players can't buy too many stackable items
				if(V_ItemCount(ent, type) >= ARMORY_MAX_CONSUMABLES)
				{
					gi.cprintf(ent, PRINT_HIGH, va("You can't buy more than %d of these items.\n", ARMORY_MAX_CONSUMABLES));
					return;
				}

				//Give them the item
				V_ItemClear(slot);
				slot->itemLevel = 0;
				slot->itemtype = type;
				slot->quantity = qty;

				//Tell the user what they bought
                switch(selection)
				{
				case 21:	gi.cprintf(ent, PRINT_HIGH, "You bought %d health potions.\n", qty);		break;
				case 22:	gi.cprintf(ent, PRINT_HIGH, "You bought %d vials of holy water.\n", qty);	break;
				case 23:	gi.cprintf(ent, PRINT_HIGH, "You bought a pair of anti-gravity boots.\n");	break;
				case 24:	gi.cprintf(ent, PRINT_HIGH, "You bought some fire resistant clothing.\n");	break;
				case 25:	gi.cprintf(ent, PRINT_HIGH, "You bought an Auto-Tball.\n");	break;
				}
			}
			break;
		case 28:	//Reset char data
			ChangeClass(ent->client->pers.netname, ent->myskills.class_num, 2);
			break;
		}
	}

	//spend the credits
	ent->myskills.credits -= price;
	gi.cprintf(ent, PRINT_HIGH, "You now have %d credits left. \n", ent->myskills.credits);
	gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/gold.wav"), 1, ATTN_NORM, 0);

}
Exemple #3
0
void fire_think (edict_t *self)
{
	edict_t *ed=NULL;
	qboolean quench = false;
	int i;
	int damage;

	// fire self-terminates if
	if (!G_EntIsAlive(self->enemy)
		|| !G_EntIsAlive(self->owner)//owner dies
		|| (level.time > self->delay))	// enemy dies								//duration expires
		//|| que_findtype(self->enemy->curses, NULL, HEALING) != NULL)	//3.0 when player is blessed with healing
	{
		que_removeent(self->enemy->curses, self, true);
		return;
	}

	//3.0 quench the flames if the player is in possesion of a flame stopping item
	if (!(self->enemy->waterlevel || self->waterlevel))
	{
		for (i = 3; i < MAX_VRXITEMS; ++i)
		{
			if (self->enemy->myskills.items[i].itemtype & ITEM_FIRE_RESIST)
			{
				quench = true;
				break;
			}
		}
	}

	if (self->enemy->waterlevel || self->waterlevel || quench)
	{
		//if item and not water stopped the fire
		if (quench)
		{
			//Consume an item charge
			if (!(self->enemy->myskills.items[i].itemtype & ITEM_UNIQUE))
				self->enemy->myskills.items[i].quantity -= 1;
			if(self->enemy->myskills.items[i].quantity == 0)
			{
				int count = 0;
				gi.cprintf(self->enemy, PRINT_HIGH, "Your burn resistant clothing has been destroyed!\n");
				//erase the item
				V_ItemClear(&self->enemy->myskills.items[i]);
				//Tell the user if they have any left
				for (i = 3; i < MAX_VRXITEMS; ++i)
					if (self->enemy->myskills.items[i].itemtype & ITEM_FIRE_RESIST)
						count++;
				if (count) gi.cprintf(self->enemy, PRINT_HIGH, "You have %d left.\n", count);
			}
		}
		//water did it, so play a hissing dound
		else gi.sound (self->enemy, CHAN_WEAPON, gi.soundindex ("world/airhiss1.wav"), 1, ATTN_NORM, 0);

		que_removeent(self->enemy->curses, self, true);
		return;
	}

	damage = self->dmg;	

	VectorCopy(self->enemy->s.origin,self->s.origin);
	if (self->PlasmaDelay < level.time)
	{
		T_Damage (self->enemy, self, self->owner, vec3_origin, self->enemy->s.origin, 
			vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_BURN);
		self->PlasmaDelay = level.time + 1;
	}
	self->nextthink = level.time + FRAMETIME;
}
Exemple #4
0
void PurchaseRandomRune(edict_t *ent, int runetype)
{
	int	cost;
	edict_t *rune;
	item_t *slot;
	char buf[64];

	cost = RUNE_COST_BASE + RUNE_COST_ADDON * ent->myskills.level;
	if (ent->myskills.credits < cost)
	{
		safe_cprintf(ent, PRINT_HIGH, "You need %d credits to purchase a rune.\n", cost);
		return;
	}

	slot = V_FindFreeItemSlot(ent);
	if (!slot)
	{
		safe_cprintf(ent, PRINT_HIGH, "Not enough inventory space!\n");
		return;
	}

	// rune pick-up delay
	if (ent->client->rune_delay > level.time)
		return;

	rune = G_Spawn();				// create a rune
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	ent->myskills.credits -= cost;
	
	if (runetype)
	{
		spawnNorm(rune, ent->myskills.level, runetype);
	}
	else if (random() > 0.5)
	{
		spawnNorm(rune, ent->myskills.level, ITEM_WEAPON);
	}
	else
	{
		spawnNorm(rune, ent->myskills.level, ITEM_ABILITY);
	}
    
	if (Pickup_Rune(rune, ent) == false)
	{
		G_FreeEdict(rune);
		//gi.dprintf("WARNING: PurchaseRandomRune() was unable to spawn a rune\n");
		return;
	}
	G_FreeEdict(rune);

	//Find out what the player bought
	strcpy(buf, GetRuneValString(slot));
	switch(slot->itemtype)
	{
	case ITEM_WEAPON:	strcat(buf, va(" weapon rune (%d mods)", slot->numMods));	break;
	case ITEM_ABILITY:	strcat(buf, va(" ability rune (%d mods)", slot->numMods));	break;
	case ITEM_COMBO:	strcat(buf, va(" combo rune (%d mods)", slot->numMods));	break;
	}

	//send the message to the player
	safe_cprintf(ent, PRINT_HIGH, "You bought a %s.\n", buf);
	safe_cprintf(ent, PRINT_HIGH, "You now have %d credits left. \n", ent->myskills.credits);
	gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/gold.wav"), 1, ATTN_NORM, 0);

	//Save the player
	if (savemethod->value == 1)
		SaveCharacter(ent);
	else if (savemethod->value == 0)
	{
		char path[MAX_QPATH];
		memset(path, 0, MAX_QPATH);
		VRXGetPath(path, ent);
		VSF_SaveRunes(ent, path);
	}else if (savemethod->value == 3)
	{
		VSFU_SaveRunes(ent);
	}

	//write to the log
	gi.dprintf("INFO: %s purchased a level %d rune (%s).\n", 
		ent->client->pers.netname, slot->itemLevel, slot->id);
	WriteToLogfile(ent, va("Purchased a level %d rune (%s) for %d credits. Player has %d credits left.\n",
		slot->itemLevel, slot->id, cost, ent->myskills.credits));
}
Exemple #5
0
void SpawnRune (edict_t *self, edict_t *attacker, qboolean debug)
{
	int		iRandom;
	int		targ_level = 0;
	float	temp = 0;
	gitem_t *item;
	edict_t *rune;

	attacker = G_GetClient(attacker);

	if (!attacker)
		return;

	if(!self->client)
	{
		// is this a world monster?
		if (self->mtype && (self->svflags & SVF_MONSTER) && self->activator && !self->activator->client)
		{
			if (IsABoss(self) || (self->mtype == M_COMMANDER))
			//boss has a 100% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 100.0;
			else if (self->monsterinfo.bonus_flags & BF_UNIQUE_LIGHTNING 
				|| self->monsterinfo.bonus_flags & BF_UNIQUE_FIRE)
			// unique monsters have a 50% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 75.0;
			else if (self->monsterinfo.bonus_flags & BF_CHAMPION)
			// champion monsters have a 15% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 15.0; // from 2%
			else
			// monsters have a 5% chance to spawn a rune NOP MONSTERS DON'T DROP RUNES
				//temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 5.0; // from 0.2%
				temp = 1; // 1% to drop runes.
			//gi.dprintf("%.3f\n", temp*RUNE_SPAWN_BASE);

			if (RUNE_SPAWN_BASE * temp < random())
				return;

			//set target level
			targ_level = (self->monsterinfo.level + attacker->myskills.level) / 2;
			// don't allow runes higher than attacker's level
			if (targ_level > attacker->myskills.level)
				targ_level = attacker->myskills.level;
		}
		else
			return;
	}
	else if (attacker != self)
	{
		//boss has a greater chance of dropping a rune
		if (attacker->myskills.boss > 0)
            temp = (float)attacker->myskills.boss * 5;
		else
			temp = (float) (self->myskills.level + 1) * 5.0 / (attacker->myskills.level + 1);
		
		// miniboss has greater chance of dropping a rune
		if (IsNewbieBasher(self))
			temp *= 2;
		
		//boss has a greater chance of dropping a rune
		temp *= 1.0 + ((float)self->myskills.boss / 2.0);
		
		if (RUNE_SPAWN_BASE * temp < random())
			return;
		
		//set target level
		targ_level = (self->myskills.level + attacker->myskills.level) / 2;
	}
	else if (debug == false)
		return;

	item = FindItem("Rune");		// get the item properties
	rune = Drop_Item(self, item);	// create the entity that holds those properties
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	//set target level to 20 if we are debugging
	if (debug == true)
		targ_level = 20;
	
	rune->vrxitem.quantity = 1;

	//Spawn a random rune
    iRandom = GetRandom(0, 1000);

	if (iRandom < CHANCE_UNIQUE)
	{
		//spawn a unique
#ifdef ENABLE_UNIQUES
		if (!spawnUnique(rune, 0))
#endif
			spawnNorm(rune, targ_level, 0);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS)
	{
		//spawn a class-specific rune
		spawnClassRune(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO)
	{
		//spawn a combo rune
		spawnCombo(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO + CHANCE_NORM)
	{
		//spawn a normal rune
		spawnNorm(rune, targ_level, 0);
	}
	else
	{
		G_FreeEdict(rune);
		return;
	}

	//Randomize id
	strcpy(rune->vrxitem.id, GetRandomString(16));
}
Exemple #6
0
edict_t *V_SpawnRune (edict_t *self, edict_t *attacker, float base_drop_chance, float levelmod)
{
	int		iRandom;
	int		targ_level;
	float	temp = 0;
	gitem_t *item;
	edict_t *rune;

	attacker = G_GetClient(attacker);

	if (!attacker || !attacker->client)
		return NULL;

	if(!self->client && self->activator && self->svflags & SVF_MONSTER)
	{
		temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1);
		
		if (base_drop_chance * temp < random())
			return NULL;

		//set target level
		targ_level = (self->monsterinfo.level + attacker->myskills.level) / 2;

		// don't allow runes higher than attacker's level
		if (targ_level > attacker->myskills.level)
			targ_level = attacker->myskills.level;
	}
	else if (attacker != self && attacker != world)
	{
		//boss has a greater chance of dropping a rune
		if (attacker->myskills.boss > 0)
            temp = (float)attacker->myskills.boss / 5.0;
		else
			temp = (float) (self->myskills.level + 1) / (attacker->myskills.level + 1);
		
		// miniboss has greater chance of dropping a rune
		if (IsNewbieBasher(self))
			temp *= 2;
		
		//boss has a greater chance of dropping a rune
		temp *= 1.0 + ((float)self->myskills.boss / 2.0);
		
		if (base_drop_chance * temp < random())
			return NULL;
		
		//set target level
		targ_level = (self->myskills.level + attacker->myskills.level) / 2;
	}
	else
		return NULL;

	item = FindItem("Rune");		// get the item properties
	rune = Drop_Item(self, item);	// create the entity that holds those properties
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	if (levelmod)
		targ_level *= levelmod;
	
	rune->vrxitem.quantity = 1;

	//Spawn a random rune
    iRandom = GetRandom(0, 1000);

	if (iRandom < CHANCE_UNIQUE)
	{
		//spawn a unique 
		// vrx chile 1.4 no uniques until someone makes them
		if (!spawnUnique(rune, 0))
			spawnNorm(rune, targ_level, 0);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS)
	{
		//spawn a class-specific rune
		spawnClassRune(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO)
	{
		//spawn a combo rune
		spawnCombo(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO + CHANCE_NORM)
	{
		//spawn a normal rune
		spawnNorm(rune, targ_level, 0);
	}
	else
	{
		G_FreeEdict(rune);
		return NULL;
	}

	//Randomize id
	strcpy(rune->vrxitem.id, GetRandomString(16));

	return rune;
}
Exemple #7
0
void cmd_Drink(edict_t *ent, int itemtype, int index)
{
	int i;
	item_t *slot = NULL;
	qboolean found = false;

	//Don't drink too many potions too quickly
	if (ent->client->ability_delay > level.time)
		return;

	if (ctf->value && ctf_enable_balanced_fc->value && HasFlag(ent))
		return;

	if (index)
	{
		slot = &ent->myskills.items[index-1];
		found = true;
	}
	else
	{
		//Find item in inventory
		for (i = 3; i < MAX_VRXITEMS; ++i)
		{
			if (ent->myskills.items[i].itemtype == itemtype)
			{
				slot = &ent->myskills.items[i];
				found = true;
				break;
			}
		}
	}

	if (!found)
	{
		safe_cprintf(ent, PRINT_HIGH, "You have none in stock.\n");
		return;
	}

	//use it
	switch(itemtype)
	{
	case ITEM_POTION:
		{
			int max_hp = MAX_HEALTH(ent);

			if (ent->health < max_hp)
			{
				//Use the potion
				ent->health += max_hp/* / 3*/; // make them useful once again vrx chile 1.4
				if (ent->health > max_hp)
					ent->health = max_hp;

				//You can only drink 1/sec
				ent->client->ability_delay = level.time + 3.3;
				
				//Play sound
				gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/potiondrink.wav"), 1, ATTN_NORM, 0);
				
				//Consume a potion
				slot->quantity--;
				safe_cprintf(ent, PRINT_HIGH, "You drank a potion. Potions left: %d\n", slot->quantity);
				if (slot->quantity < 1)
					V_ItemClear(slot);
			}
			else safe_cprintf(ent, PRINT_HIGH, "You don't need to drink this yet, you have lots of health.\n");
			return;

		}
		break;
	case ITEM_ANTIDOTE:
		{
			if (que_typeexists(ent->curses, 0))
			{
				int i;
				//Use the potion
				for (i = 0; i < QUE_MAXSIZE; ++i)
				{
					que_t *curse = &ent->curses[i];
					if ((curse->ent && curse->ent->inuse) && (curse->ent->atype != HEALING && curse->ent->atype != BLESS))
					{
						//destroy the curse
						if (curse->ent->enemy && (curse->ent->enemy == ent))
							G_FreeEdict(curse->ent);
						// remove entry from the queue
						curse->time = 0;
						curse->ent = NULL;
					}
				}

				//Give them a short period of curse immunity
				ent->holywaterProtection = level.time + 5.0; //5 seconds immunity

				//You can only drink 1/sec
				ent->client->ability_delay = level.time + 1.0;
				
				//Play sound
				gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/rare.wav"), 1, ATTN_NORM, 0);
				
				//Consume a potion
				slot->quantity--;
				safe_cprintf(ent, PRINT_HIGH, "You used some holywater. Vials left: %d\n", slot->quantity);
				if (slot->quantity < 1)
					V_ItemClear(slot);
				
			}
			else safe_cprintf(ent, PRINT_HIGH, "You are not cursed, so you don't need to use this yet.\n");
			return;
		}
		break;
	}
}