Ejemplo n.º 1
0
int depot_give_item (edict_t *self, edict_t *other, int item_index)
{
	int max, add, *p_inv, *d_inv;

	// max value that player can hold
	if (item_index == body_armor_index)
		max = MAX_ARMOR(other); 
	else
		max = MaxAmmoType(other, item_index);

	p_inv = &other->client->pers.inventory[item_index]; // player current inventory count
	d_inv = &self->packitems[item_index]; // depot current inventory count
	add = max - *p_inv; // amount player needs

	// the player can't carry any more ammo
	if (add < 0)
		return 0;

	// can't add more than the depot has
	if (add > *d_inv) 
		add = *d_inv;

	*p_inv += add; // add to player inventory
	*d_inv -= add; // reduce depot inventory

	//gi.dprintf("player: %d/%d depot: %d add: %d\n", *p_inv, max, *d_inv, add);

	return add;
}
Ejemplo n.º 2
0
//***********************************************************************
//	Save player v 1.0
//***********************************************************************
void WritePlayer_v1(FILE * fWrite, char *playername, edict_t *player)
{
	int i;
	int numAbilities = CountAbilities(player);
	int numWeapons = CountWeapons(player);
	int numRunes = CountRunes(player);

	//save header
	WriteString(fWrite, "Vortex Player File v1.0");
	//player's title
	WriteString(fWrite, player->myskills.title);
	//player's in-game name
	WriteString(fWrite, playername);
	//password
	WriteString(fWrite, player->myskills.password);
	//email address
	WriteString(fWrite, player->myskills.email);
	//owner
	WriteString(fWrite, player->myskills.owner);
	//creation date
	WriteString(fWrite, player->myskills.member_since);
	//last played date
	WriteString(fWrite, player->myskills.last_played);
	//playing time total
	WriteInteger(fWrite, player->myskills.total_playtime);
	//playing time today
	WriteInteger(fWrite, player->myskills.playingtime);

	//begin talents
	WriteInteger(fWrite, player->myskills.talents.count);
	for (i = 0; i < player->myskills.talents.count; ++i)
	{
		WriteInteger(fWrite, player->myskills.talents.talent[i].id);
		WriteInteger(fWrite, player->myskills.talents.talent[i].upgradeLevel);
		WriteInteger(fWrite, player->myskills.talents.talent[i].maxLevel);
	}
	//end talents

	//begin abilities
	WriteInteger(fWrite, numAbilities);
	for (i = 0; i < numAbilities; ++i)
	{
		int index = FindAbilityIndex(i+1, player);
		if (index != -1)
		{
			WriteInteger(fWrite, index);
			WriteInteger(fWrite, player->myskills.abilities[index].level);
			WriteInteger(fWrite, player->myskills.abilities[index].max_level);
			WriteInteger(fWrite, player->myskills.abilities[index].hard_max);
			WriteInteger(fWrite, player->myskills.abilities[index].modifier);
			WriteInteger(fWrite, (int)player->myskills.abilities[index].disable);
			WriteInteger(fWrite, (int)player->myskills.abilities[index].general_skill);
		}
	}
	//end abilities

	//begin weapons
    WriteInteger(fWrite, numWeapons);
	for (i = 0; i < numWeapons; ++i)
	{
		int index = FindWeaponIndex(i+1, player);
		if (index != -1)
		{
			int j;
			WriteInteger(fWrite, index);
			WriteInteger(fWrite, player->myskills.weapons[index].disable);

			for (j = 0; j < MAX_WEAPONMODS; ++j)
			{
				WriteInteger(fWrite, player->myskills.weapons[index].mods[j].level);
				WriteInteger(fWrite, player->myskills.weapons[index].mods[j].soft_max);
				WriteInteger(fWrite, player->myskills.weapons[index].mods[j].hard_max);
			}
		}
	}
	//end weapons

	//begin runes
    WriteInteger(fWrite, numRunes);
	for (i = 0; i < numRunes; ++i)
	{
		int index = FindRuneIndex(i+1, player);
		if (index != -1)
		{
			int j;
			WriteInteger(fWrite, index);
			WriteInteger(fWrite, player->myskills.items[index].itemtype);
			WriteInteger(fWrite, player->myskills.items[index].itemLevel);
			WriteInteger(fWrite, player->myskills.items[index].quantity);
			WriteInteger(fWrite, player->myskills.items[index].untradeable);
			WriteString(fWrite, player->myskills.items[index].id);
			WriteString(fWrite, player->myskills.items[index].name);
			WriteInteger(fWrite, player->myskills.items[index].numMods);
			WriteInteger(fWrite, player->myskills.items[index].setCode);
			WriteInteger(fWrite, player->myskills.items[index].classNum);

			for (j = 0; j < MAX_VRXITEMMODS; ++j)
			{
				WriteInteger(fWrite, player->myskills.items[index].modifiers[j].type);
				WriteInteger(fWrite, player->myskills.items[index].modifiers[j].index);
				WriteInteger(fWrite, player->myskills.items[index].modifiers[j].value);
				WriteInteger(fWrite, player->myskills.items[index].modifiers[j].set);
			}
		}
	}
	//end runes

	//*****************************
	//standard stats
	//*****************************

	//Exp
	WriteLong(fWrite, player->myskills.experience);
	//next_level
	WriteLong(fWrite, player->myskills.next_level);
	//Level
	WriteInteger(fWrite, player->myskills.level);
	//Class number
	WriteInteger(fWrite, player->myskills.class_num);
	//skill points
	WriteInteger(fWrite, player->myskills.speciality_points);
	//credits
	WriteInteger(fWrite, player->myskills.credits);
	//weapon points
	WriteInteger(fWrite, player->myskills.weapon_points);
	//respawn weapon
	WriteInteger(fWrite, player->myskills.respawn_weapon);
	//talent points
	WriteInteger(fWrite, player->myskills.talents.talentPoints);

	//*****************************
	//in-game stats
	//*****************************
	//respawns
	WriteInteger(fWrite, player->myskills.respawns);
	//health
	WriteInteger(fWrite, player->myskills.current_health);
	//max health
	WriteInteger(fWrite, MAX_HEALTH(player));
	//armour
	WriteInteger(fWrite, player->client->pers.inventory[body_armor_index]);
	//max armour
	WriteInteger(fWrite, MAX_ARMOR(player));
	//nerfme			(cursing a player maybe?)
	WriteInteger(fWrite, player->myskills.nerfme);

	//*****************************
	//flags
	//*****************************
	//admin flag
	WriteInteger(fWrite, player->myskills.administrator);
	//boss flag
	WriteInteger(fWrite, player->myskills.boss);

	//*****************************
	//stats
	//*****************************
	//shots fired
	WriteInteger(fWrite, player->myskills.shots);
	//shots hit
	WriteInteger(fWrite, player->myskills.shots_hit);
	//frags
	WriteInteger(fWrite, player->myskills.frags);
	//deaths
	WriteInteger(fWrite, player->myskills.fragged);
	//number of sprees
	WriteInteger(fWrite, player->myskills.num_sprees);
	//max spree
	WriteInteger(fWrite, player->myskills.max_streak);
	//number of wars
	WriteInteger(fWrite, player->myskills.spree_wars);
	//number of sprees broken
	WriteInteger(fWrite, player->myskills.break_sprees);
	//number of wars broken
	WriteInteger(fWrite, player->myskills.break_spree_wars);
	//suicides
	WriteInteger(fWrite, player->myskills.suicides);
	//teleports			(link this to "use tball self" maybe?)
	WriteInteger(fWrite, player->myskills.teleports);
	//number of 2fers
	WriteInteger(fWrite, player->myskills.num_2fers);

	//CTF statistics
	WriteInteger(fWrite, player->myskills.flag_pickups);
	WriteInteger(fWrite, player->myskills.flag_captures);
	WriteInteger(fWrite, player->myskills.flag_returns);
	WriteInteger(fWrite, player->myskills.flag_kills);
	WriteInteger(fWrite, player->myskills.offense_kills);
	WriteInteger(fWrite, player->myskills.defense_kills);
	WriteInteger(fWrite, player->myskills.assists);
	//End CTF

	//Don't let the player have > max cubes
	if (player->client->pers.inventory[power_cube_index] > player->client->pers.max_powercubes)
		player->client->pers.inventory[power_cube_index] = player->client->pers.max_powercubes;

	//standard iD inventory
	fwrite(player->client->pers.inventory, sizeof(int), MAX_ITEMS, fWrite);
}
Ejemplo n.º 3
0
//***********************************************************************
//	Load player v 1.0
//***********************************************************************
qboolean ReadPlayer_v1(FILE * fRead, edict_t *player)
{
	int numAbilities, numWeapons, numRunes;
	int i;

	//player's title
    ReadString(player->myskills.title, fRead);	
	//player's in-game name
	ReadString(player->myskills.player_name, fRead);
	//password
	ReadString(player->myskills.password, fRead);
	//email address
	ReadString(player->myskills.email, fRead);
	//owner
	ReadString(player->myskills.owner, fRead);
	//creation date
	ReadString(player->myskills.member_since, fRead);
	//last played date
	ReadString(player->myskills.last_played, fRead);
	//playing time total
	player->myskills.total_playtime =  ReadInteger(fRead);
	//playing time today
	player->myskills.playingtime =  ReadInteger(fRead);

    //begin talents
	player->myskills.talents.count = ReadInteger(fRead);
	for (i = 0; i < player->myskills.talents.count; ++i)
	{
		//don't crash.
        if (i > MAX_TALENTS)
			return false;

		player->myskills.talents.talent[i].id = ReadInteger(fRead);
		player->myskills.talents.talent[i].upgradeLevel = ReadInteger(fRead);
		player->myskills.talents.talent[i].maxLevel = ReadInteger(fRead);
	}
	//end talents

	//begin abilities
	numAbilities = ReadInteger(fRead);
	for (i = 0; i < numAbilities; ++i)
	{
		int index;
		index = ReadInteger(fRead);

		if ((index >= 0) && (index < MAX_ABILITIES))
		{
			player->myskills.abilities[index].level			= ReadInteger(fRead);
			player->myskills.abilities[index].max_level		= ReadInteger(fRead);
			player->myskills.abilities[index].hard_max		= ReadInteger(fRead);
			player->myskills.abilities[index].modifier		= ReadInteger(fRead);
			player->myskills.abilities[index].disable		= (qboolean)ReadInteger(fRead);
			player->myskills.abilities[index].general_skill = (qboolean)ReadInteger(fRead);
		}
		else
		{
			gi.dprintf("Error loading player: %s. Ability index not loaded correctly!\n", player->client->pers.netname);
			WriteToLogfile(player, "ERROR during loading: Ability index not loaded correctly!");
			return false;
		}
	}
	//end abilities

	//begin weapons
    numWeapons = ReadInteger(fRead);
	for (i = 0; i < numWeapons; ++i)
	{
		int index;
		index = ReadInteger(fRead);

		if ((index >= 0 ) && (index < MAX_WEAPONS))
		{
			int j;
			player->myskills.weapons[index].disable = ReadInteger(fRead);

			for (j = 0; j < MAX_WEAPONMODS; ++j)
			{
				player->myskills.weapons[index].mods[j].level = ReadInteger(fRead);
				player->myskills.weapons[index].mods[j].soft_max = ReadInteger(fRead);
				player->myskills.weapons[index].mods[j].hard_max = ReadInteger(fRead);
			}
		}
		else
		{
			gi.dprintf("Error loading player: %s. Weapon index not loaded correctly!\n", player->myskills.player_name);
			WriteToLogfile(player, "ERROR during loading: Weapon index not loaded correctly!");
			return false;
		}
	}
	//end weapons

	//begin runes
	numRunes = ReadInteger(fRead);
	for (i = 0; i < numRunes; ++i)
	{
		int index;
		index = ReadInteger(fRead);
		if ((index >= 0) && (index < MAX_VRXITEMS))
		{
			int j;
			player->myskills.items[index].itemtype = ReadInteger(fRead);
			player->myskills.items[index].itemLevel = ReadInteger(fRead);
			player->myskills.items[index].quantity = ReadInteger(fRead);
			player->myskills.items[index].untradeable = ReadInteger(fRead);
			ReadString(player->myskills.items[index].id, fRead);
			ReadString(player->myskills.items[index].name, fRead);
			player->myskills.items[index].numMods = ReadInteger(fRead);
			player->myskills.items[index].setCode = ReadInteger(fRead);
			player->myskills.items[index].classNum = ReadInteger(fRead);

			for (j = 0; j < MAX_VRXITEMMODS; ++j)
			{
				player->myskills.items[index].modifiers[j].type = ReadInteger(fRead);
				player->myskills.items[index].modifiers[j].index = ReadInteger(fRead);
				player->myskills.items[index].modifiers[j].value = ReadInteger(fRead);
				player->myskills.items[index].modifiers[j].set = ReadInteger(fRead);
			}
		}
	}
	//end runes


	//*****************************
	//standard stats
	//*****************************

	//Exp
	player->myskills.experience =  ReadLong(fRead);
	//next_level
	player->myskills.next_level =  ReadLong(fRead);
	//Level
	player->myskills.level =  ReadInteger(fRead);
	//Class number
	player->myskills.class_num =  ReadInteger(fRead);
	//skill points
	player->myskills.speciality_points =  ReadInteger(fRead);
	//credits
	player->myskills.credits =  ReadInteger(fRead);
	//weapon points
	player->myskills.weapon_points =  ReadInteger(fRead);
	//respawn weapon
	player->myskills.respawn_weapon =  ReadInteger(fRead);
	//talent points
	player->myskills.talents.talentPoints =  ReadInteger(fRead);

	//*****************************
	//in-game stats
	//*****************************
	//respawns
	player->myskills.respawns =  ReadInteger(fRead);
	//health
	player->myskills.current_health =  ReadInteger(fRead);
	//max health
	player->myskills.max_health =  ReadInteger(fRead);
	//armour
	player->myskills.current_armor =  ReadInteger(fRead);
	//max armour
	player->myskills.max_armor =  ReadInteger(fRead);
	//nerfme			(cursing a player maybe?)
	player->myskills.nerfme =  ReadInteger(fRead);

	//*****************************
	//flags
	//*****************************
	//admin flag
	player->myskills.administrator =  ReadInteger(fRead);
	//boss flag
	player->myskills.boss =  ReadInteger(fRead);

	//*****************************
	//stats
	//*****************************
	//shots fired
	player->myskills.shots =  ReadInteger(fRead);
	//shots hit
	player->myskills.shots_hit =  ReadInteger(fRead);
	//frags
	player->myskills.frags =  ReadInteger(fRead);
	//deaths
	player->myskills.fragged =  ReadInteger(fRead);
	//number of sprees
	player->myskills.num_sprees =  ReadInteger(fRead);
	//max spree
	player->myskills.max_streak =  ReadInteger(fRead);
	//number of wars
	player->myskills.spree_wars =  ReadInteger(fRead);
	//number of sprees broken
	player->myskills.break_sprees =  ReadInteger(fRead);
	//number of wars broken
	player->myskills.break_spree_wars =  ReadInteger(fRead);
	//suicides
	player->myskills.suicides =  ReadInteger(fRead);
	//teleports			(link this to "use tballself" maybe?)
	player->myskills.teleports =  ReadInteger(fRead);
	//number of 2fers
	player->myskills.num_2fers =  ReadInteger(fRead);

	//CTF statistics
	player->myskills.flag_pickups =  ReadInteger(fRead);
	player->myskills.flag_captures =  ReadInteger(fRead);
	player->myskills.flag_returns =  ReadInteger(fRead);
	player->myskills.flag_kills =  ReadInteger(fRead);
	player->myskills.offense_kills =  ReadInteger(fRead);
	player->myskills.defense_kills =  ReadInteger(fRead);
	player->myskills.assists =  ReadInteger(fRead);
	//End CTF

	//standard iD inventory
	fread(player->myskills.inventory, sizeof(int), MAX_ITEMS, fRead);

	//Apply runes
	V_ResetAllStats(player);
	for (i = 0; i < 3; ++i)
		V_ApplyRune(player, &player->myskills.items[i]);

	//Apply health
	if (player->myskills.current_health > MAX_HEALTH(player))
		player->myskills.current_health = MAX_HEALTH(player);

	//Apply armor
	if (player->myskills.current_armor > MAX_ARMOR(player))
		player->myskills.current_armor = MAX_ARMOR(player);
	player->myskills.inventory[body_armor_index] = player->myskills.current_armor;

	//done
	return true;
}
Ejemplo n.º 4
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);

}
Ejemplo n.º 5
0
float ArmorLevel (edict_t *ent) {
	return ((float)ent->client->pers.inventory[body_armor_index]/MAX_ARMOR(ent));
}
Ejemplo n.º 6
0
qboolean NeedArmor (edict_t *player) {
	return (player->client->pers.inventory[body_armor_index] < MAX_ARMOR(player));
}
Ejemplo n.º 7
0
qboolean VSFU_LoadPlayer(edict_t *player)
{
	sqlite3_stmt* statement, *statement_mods;
	char* format;
	int numAbilities, numWeapons, numRunes;
	int i, r, id;

	V_VSFU_StartConn();

	id = VSFU_GetID(player->client->pers.netname);

	if (id == -1)
		return false;
	
	LQUERY(va("SELECT * FROM userdata WHERE char_idx=%d", id));

    strcpy(player->myskills.title, sqlite3_column_text(statement, 1));
	strcpy(player->myskills.player_name, sqlite3_column_text(statement, 2));
	strcpy(player->myskills.password, sqlite3_column_text(statement, 3));
	strcpy(player->myskills.email, sqlite3_column_text(statement, 4));
	strcpy(player->myskills.owner, sqlite3_column_text(statement, 5));
	strcpy(player->myskills.member_since, sqlite3_column_text(statement, 6));
	strcpy(player->myskills.last_played, sqlite3_column_text(statement, 7));
	player->myskills.total_playtime =  sqlite3_column_int(statement, 8);

	player->myskills.playingtime =  sqlite3_column_int(statement, 9);

	sqlite3_finalize(statement);

	format = va("SELECT COUNT(*) FROM talents WHERE char_idx=%d", id);
	
	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

    //begin talents
	player->myskills.talents.count = sqlite3_column_int(statement, 0);

	sqlite3_finalize(statement);

	format = va("SELECT * FROM talents WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	for (i = 0; i < player->myskills.talents.count; ++i)
	{
		//don't crash.
        if (i > MAX_TALENTS)
			return false;

		player->myskills.talents.talent[i].id = sqlite3_column_int(statement, 1);
		player->myskills.talents.talent[i].upgradeLevel = sqlite3_column_int(statement, 2);
		player->myskills.talents.talent[i].maxLevel = sqlite3_column_int(statement, 3);


		if ( (r = sqlite3_step(statement)) == SQLITE_DONE)
			break;
	}
	//end talents
	
	sqlite3_finalize(statement);

	format = va("SELECT COUNT(*) FROM abilities WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	//begin abilities
	numAbilities = sqlite3_column_int(statement, 0);

	sqlite3_finalize(statement);

	format = va("SELECT * FROM abilities WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	for (i = 0; i < numAbilities; ++i)
	{
		int index;
		index = sqlite3_column_int(statement, 1);

		if ((index >= 0) && (index < MAX_ABILITIES))
		{
			player->myskills.abilities[index].level			= sqlite3_column_int(statement, 2);
			player->myskills.abilities[index].max_level		= sqlite3_column_int(statement, 3);
			player->myskills.abilities[index].hard_max		= sqlite3_column_int(statement, 4);
			player->myskills.abilities[index].modifier		= sqlite3_column_int(statement, 5);
			player->myskills.abilities[index].disable		= sqlite3_column_int(statement, 6);
			player->myskills.abilities[index].general_skill = (qboolean)sqlite3_column_int(statement, 7);

			if ( (r = sqlite3_step(statement)) == SQLITE_DONE)
				break;
		}
		else
		{
			gi.dprintf("Error loading player: %s. Ability index not loaded correctly!\n", player->client->pers.netname);
            vrx_write_to_logfile(player, "ERROR during loading: Ability index not loaded correctly!");
			return false;
		}
	}
	//end abilities

	sqlite3_finalize(statement);

	format = va("SELECT COUNT(*) FROM weapon_meta WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	//begin weapons
	numWeapons = sqlite3_column_int(statement, 0);
	
	sqlite3_finalize(statement);

	format = va("SELECT * FROM weapon_meta WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	for (i = 0; i < numWeapons; ++i)
	{
		int index;
		index = sqlite3_column_int(statement, 1);

		if ((index >= 0 ) && (index < MAX_WEAPONS))
		{
			int j;
			player->myskills.weapons[index].disable = sqlite3_column_int(statement, 2);

			format = strdup(va("SELECT * FROM weapon_mods WHERE weapon_index=%d AND char_idx=%d", index, id));

			r = sqlite3_prepare_v2(db, format, strlen(format), &statement_mods, NULL);
			r = sqlite3_step(statement_mods);

			for (j = 0; j < MAX_WEAPONMODS; ++j)
			{
				
				player->myskills.weapons[index].mods[j].level = sqlite3_column_int(statement_mods, 3);
				player->myskills.weapons[index].mods[j].soft_max = sqlite3_column_int(statement_mods, 4);
				player->myskills.weapons[index].mods[j].hard_max = sqlite3_column_int(statement_mods, 5);
				
				if ((r = sqlite3_step(statement_mods)) == SQLITE_DONE)
					break;
			}

			free (format);
			sqlite3_finalize(statement_mods);
		}
		else
		{
			gi.dprintf("Error loading player: %s. Weapon index not loaded correctly!\n", player->myskills.player_name);
            vrx_write_to_logfile(player, "ERROR during loading: Weapon index not loaded correctly!");
			return false;
		}

		if ((r = sqlite3_step(statement)) == SQLITE_DONE)
			break;

	}

	sqlite3_finalize(statement);
	//end weapons

	//begin runes

	format = va("SELECT COUNT(*) FROM runes_meta WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	numRunes = sqlite3_column_int(statement, 0);

	sqlite3_finalize(statement);

	format = va("SELECT * FROM runes_meta WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	for (i = 0; i < numRunes; ++i)
	{
		int index;
		index = sqlite3_column_int(statement, 1);
		if ((index >= 0) && (index < MAX_VRXITEMS))
		{
			int j;
			player->myskills.items[index].itemtype = sqlite3_column_int(statement, 2);
			player->myskills.items[index].itemLevel = sqlite3_column_int(statement, 3);
			player->myskills.items[index].quantity = sqlite3_column_int(statement, 4);
			player->myskills.items[index].untradeable = sqlite3_column_int(statement, 5);
			strcpy(player->myskills.items[index].id, sqlite3_column_text(statement, 6));
			strcpy(player->myskills.items[index].name, sqlite3_column_text(statement, 7));
			player->myskills.items[index].numMods = sqlite3_column_int(statement, 8);
			player->myskills.items[index].setCode = sqlite3_column_int(statement, 9);
			player->myskills.items[index].classNum = sqlite3_column_int(statement, 10);

			format = strdup(va("SELECT * FROM runes_mods WHERE rune_index=%d AND char_idx=%d", index, id));

			r = sqlite3_prepare_v2(db, format, strlen(format), &statement_mods, NULL);
			r = sqlite3_step(statement_mods);

			for (j = 0; j < MAX_VRXITEMMODS; ++j)
			{
				if (Lua_GetIntVariable("useMysqlTablesOnSQLite", 0))
				{
					player->myskills.items[index].modifiers[j].type = sqlite3_column_int(statement_mods, 3);
					player->myskills.items[index].modifiers[j].index = sqlite3_column_int(statement_mods, 4);
					player->myskills.items[index].modifiers[j].value = sqlite3_column_int(statement_mods, 5);
					player->myskills.items[index].modifiers[j].set = sqlite3_column_int(statement_mods, 6);
				}else
				{
					player->myskills.items[index].modifiers[j].type = sqlite3_column_int(statement_mods, 2);
					player->myskills.items[index].modifiers[j].index = sqlite3_column_int(statement_mods, 3);
					player->myskills.items[index].modifiers[j].value = sqlite3_column_int(statement_mods, 4);
					player->myskills.items[index].modifiers[j].set = sqlite3_column_int(statement_mods, 5);
				}

				if ((r = sqlite3_step(statement_mods)) == SQLITE_DONE)
					break;
			}

			free (format);
			sqlite3_finalize(statement_mods);
		}

		if ((r = sqlite3_step(statement)) == SQLITE_DONE)
			break;
	}

	sqlite3_finalize(statement);
	//end runes


	//*****************************
	//standard stats
	//*****************************

	format = va("SELECT * FROM point_data WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	//Exp
	player->myskills.experience =  sqlite3_column_int(statement, 1);
	//next_level
	player->myskills.next_level =  sqlite3_column_int(statement, 2);
	//Level
	player->myskills.level =  sqlite3_column_int(statement, 3);
	//Class number
	player->myskills.class_num = sqlite3_column_int(statement, 4);
	//skill points
	player->myskills.speciality_points = sqlite3_column_int(statement, 5);
	//credits
	player->myskills.credits = sqlite3_column_int(statement, 6);
	//weapon points
	player->myskills.weapon_points = sqlite3_column_int(statement, 7);
	//respawn weapon
	player->myskills.respawn_weapon = sqlite3_column_int(statement, 8);
	//talent points
	player->myskills.talents.talentPoints = sqlite3_column_int(statement, 9);

	sqlite3_finalize(statement);

	format = va("SELECT * FROM character_data WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);


	//*****************************
	//in-game stats
	//*****************************
	//respawns
	player->myskills.weapon_respawns = sqlite3_column_int(statement, 1);
	//health
	player->myskills.current_health = sqlite3_column_int(statement, 2);
	//max health
	player->myskills.max_health = sqlite3_column_int(statement, 3);
	//armour
	player->myskills.current_armor = sqlite3_column_int(statement, 4);
	//max armour
	player->myskills.max_armor = sqlite3_column_int(statement, 5);
	//nerfme			(cursing a player maybe?)
	player->myskills.nerfme = sqlite3_column_int(statement, 6);

	//*****************************
	//flags
	//*****************************
	//admin flag
	player->myskills.administrator =  sqlite3_column_int(statement, 7);
	//boss flag
	player->myskills.boss = sqlite3_column_int(statement, 8);

	//*****************************
	//stats
	//*****************************

	sqlite3_finalize(statement);

	format = va("SELECT * FROM game_stats WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	//shots fired
	player->myskills.shots = sqlite3_column_int(statement, 1);
	//shots hit
	player->myskills.shots_hit = sqlite3_column_int(statement, 2);
	//frags
	player->myskills.frags = sqlite3_column_int(statement, 3);
	//deaths
	player->myskills.fragged = sqlite3_column_int(statement, 4);
	//number of sprees
	player->myskills.num_sprees = sqlite3_column_int(statement, 5);
	//max spree
	player->myskills.max_streak = sqlite3_column_int(statement, 6);
	//number of wars
	player->myskills.spree_wars =  sqlite3_column_int(statement, 7);
	//number of sprees broken
	player->myskills.break_sprees =  sqlite3_column_int(statement, 8);
	//number of wars broken
	player->myskills.break_spree_wars = sqlite3_column_int(statement, 9);
	//suicides
	player->myskills.suicides = sqlite3_column_int(statement, 10);
	//teleports			(link this to "use tballself" maybe?)
	player->myskills.teleports =  sqlite3_column_int(statement, 11);
	//number of 2fers
	player->myskills.num_2fers = sqlite3_column_int(statement, 12);

	sqlite3_finalize(statement);

	format = va("SELECT * FROM ctf_stats WHERE char_idx=%d", id);

	r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL);
	r = sqlite3_step(statement);

	//CTF statistics
	player->myskills.flag_pickups =  sqlite3_column_int(statement, 1);
	player->myskills.flag_captures =  sqlite3_column_int(statement, 2);
	player->myskills.flag_returns =  sqlite3_column_int(statement, 3);
	player->myskills.flag_kills =  sqlite3_column_int(statement, 4);
	player->myskills.offense_kills =  sqlite3_column_int(statement, 5);
	player->myskills.defense_kills =  sqlite3_column_int(statement, 6);
	player->myskills.assists =  sqlite3_column_int(statement, 7);
	//End CTF

	sqlite3_finalize(statement);

	//Apply runes
	V_ResetAllStats(player);
    for (i = 0; i < 4; ++i)
		V_ApplyRune(player, &player->myskills.items[i]);

	//Apply health
	if (player->myskills.current_health > MAX_HEALTH(player))
		player->myskills.current_health = MAX_HEALTH(player);

	//Apply armor
	if (player->myskills.current_armor > MAX_ARMOR(player))
		player->myskills.current_armor = MAX_ARMOR(player);
	player->myskills.inventory[body_armor_index] = player->myskills.current_armor;

	V_VSFU_Cleanup();
	return true;
}
Ejemplo n.º 8
0
//************************************************
//************************************************
void VSFU_SavePlayer(edict_t *player)
{
	sqlite3_stmt *statement;
	int r, i, id;
	int numAbilities = CountAbilities(player);
	int numWeapons = CountWeapons(player);
	int numRunes = CountRunes(player);
	char *format;

	V_VSFU_StartConn();

	id = VSFU_GetID(player->client->pers.netname);

	BeginTransaction(db);

	if (id == -1)
	{

		// Create initial database.
		id = VSFU_NewID();
		
		gi.dprintf("SQLite (single mode): creating initial data for player id %d..", id);
		
		if (!Lua_GetIntVariable("useMysqlTablesOnSQLite", 0))
		{
			/* sorry about this :( -az*/
				QUERY(va (CA, id));
				QUERY(va (CB, id));
				QUERY(va (CC, id));
				QUERY(va (CD, id));
				QUERY(va (CE, id));
		}else
		{
			QUERY(va (CA, id));
			QUERY(va (CB, id));
			QUERY(va (CC, id));
			QUERY(va (CD, id));
			QUERY(va("INSERT INTO userdata VALUES (%d,\"\",\"\",\"\",\"\",\"\",\"\",\"\",0,0,0)", id));
		}
		gi.dprintf("inserted bases.\n", r);
	}

	{ // real saving
		sqlite3_stmt *statement;

		// reset tables (remove records for reinsertion)
		for (i = 0; i < TOTAL_RESETTABLES; i++)
		{
			QUERY( va(VSFU_RESETTABLES[i], id) );
		}

		QUERY(strdup(va(VSFU_UPDATEUDATA, 
		 player->myskills.title,
		 player->client->pers.netname,
		 player->myskills.password,
		 player->myskills.email,
		 player->myskills.owner,
 		 player->myskills.member_since,
		 player->myskills.last_played,
		 player->myskills.total_playtime,
 		 player->myskills.playingtime, id)));

		 free (format);

		// talents
		for (i = 0; i < player->myskills.talents.count; ++i)
		{
			QUERY( strdup(va(VSFU_INSERTTALENT, id, player->myskills.talents.talent[i].id,
				player->myskills.talents.talent[i].upgradeLevel,
				player->myskills.talents.talent[i].maxLevel)) );
			free (format);
		}

		// abilities
	
		for (i = 0; i < numAbilities; ++i)
		{
			int index = FindAbilityIndex(i+1, player);
			if (index != -1)
			{
				format = strdup(va(VSFU_INSERTABILITY, id, index, 
					player->myskills.abilities[index].level,
					player->myskills.abilities[index].max_level,
					player->myskills.abilities[index].hard_max,
					player->myskills.abilities[index].modifier,
					(int)player->myskills.abilities[index].disable,
					(int)player->myskills.abilities[index].general_skill));
				
				r = sqlite3_prepare_v2(db, format, strlen(format), &statement, NULL); // insert ability
				r = sqlite3_step(statement);
				sqlite3_finalize(statement);
				free (format); // this will be slow...
			}
		}
		// gi.dprintf("saved abilities");
		
		//*****************************
		//in-game stats
		//*****************************

		QUERY(strdup(va(VSFU_UPDATECDATA, 
		 player->myskills.weapon_respawns,
		 player->myskills.current_health,
		 MAX_HEALTH(player),
		 player->client->pers.inventory[body_armor_index],
  		 MAX_ARMOR(player),
 		 player->myskills.nerfme,
		 player->myskills.administrator, // flags
		 player->myskills.boss, id)));

		free (format);

		//*****************************
		//stats
		//*****************************

		QUERY( strdup(va(VSFU_UPDATESTATS, 
		 player->myskills.shots,
		 player->myskills.shots_hit,
		 player->myskills.frags,
		 player->myskills.fragged,
  		 player->myskills.num_sprees,
 		 player->myskills.max_streak,
		 player->myskills.spree_wars,
		 player->myskills.break_sprees,
		 player->myskills.break_spree_wars,
		 player->myskills.suicides,
		 player->myskills.teleports,
		 player->myskills.num_2fers, id)) );

		free (format);
		
		//*****************************
		//standard stats
		//*****************************
		
		QUERY( strdup(va(VSFU_UPDATEPDATA, 
		 player->myskills.experience,
		 player->myskills.next_level,
         player->myskills.level,
		 player->myskills.class_num,
		 player->myskills.speciality_points,
 		 player->myskills.credits,
		 player->myskills.weapon_points,
		 player->myskills.respawn_weapon,
		 player->myskills.talents.talentPoints, id)) );
		
		free (format);

		//begin weapons
		for (i = 0; i < numWeapons; ++i)
		{
			int index = FindWeaponIndex(i+1, player);
			if (index != -1)
			{
				int j;
				QUERY( strdup(va(VSFU_INSERTWMETA, id, 
				 index,
				 player->myskills.weapons[index].disable)));			
				
				free (format);

				for (j = 0; j < MAX_WEAPONMODS; ++j)
				{
					QUERY( strdup(va(VSFU_INSERTWMOD, id, 
						index,
						j,
					    player->myskills.weapons[index].mods[j].level,
					    player->myskills.weapons[index].mods[j].soft_max,
					    player->myskills.weapons[index].mods[j].hard_max)) );
					free (format);
				}
			}
		}
		//end weapons

		//begin runes
		for (i = 0; i < numRunes; ++i)
		{
			int index = FindRuneIndex(i+1, player);
			if (index != -1)
			{
				int j;

				QUERY( strdup(va(VSFU_INSERTRMETA, id, 
				 index,
				 player->myskills.items[index].itemtype,
				 player->myskills.items[index].itemLevel,
				 player->myskills.items[index].quantity,
				 player->myskills.items[index].untradeable,
				 player->myskills.items[index].id,
				 player->myskills.items[index].name,
				 player->myskills.items[index].numMods,
				 player->myskills.items[index].setCode,
				 player->myskills.items[index].classNum)));

				free (format);

				for (j = 0; j < MAX_VRXITEMMODS; ++j)
				{
					char* query;
					// cant remove columns with sqlite.
					// ugly hack to work around that
					if (Lua_GetIntVariable("useMysqlTablesOnSQLite", 0))
						query = VSFU_INSERTRMODEX;
					else
						query = VSFU_INSERTRMOD;

					QUERY( strdup(va(query, 
					 id, 
						index,
					    player->myskills.items[index].modifiers[j].type,
					    player->myskills.items[index].modifiers[j].index,
					    player->myskills.items[index].modifiers[j].value,
					    player->myskills.items[index].modifiers[j].set)) );
					
					free (format);
				}
			}
		}
		//end runes

		QUERY( strdup(va(VSFU_UPDATECTFSTATS, 
			player->myskills.flag_pickups,
			player->myskills.flag_captures,
			player->myskills.flag_returns,
			player->myskills.flag_kills,
			player->myskills.offense_kills,
			player->myskills.defense_kills,
			player->myskills.assists, id)) );

		free (format);

	} // end saving

	CommitTransaction(db);

	if (player->client->pers.inventory[power_cube_index] > player->client->pers.max_powercubes)
		player->client->pers.inventory[power_cube_index] = player->client->pers.max_powercubes;

	V_VSFU_Cleanup();
}
Ejemplo n.º 9
0
void NatureTotem_think(edict_t *self, edict_t *caster)
{
	edict_t *target = NULL;
	qboolean isSomeoneHealed = false;
	float cdmult = 1.0;

	//Find players in radius and attack them.
	while ((target = findradius(target, self->s.origin, TOTEM_MAX_RANGE)) != NULL)
	{
		if (G_ValidAlliedTarget(self, target, true))
		{
			int maxHP;// = MAX_HEALTH(target);
			int maxArmor;// = MAX_ARMOR(target);
			int maxcubes;// = target->client->pers.max_powercubes;
			int *armor;// = &target->client->pers.inventory[body_armor_index];
			int *cubes;// = &target->client->pers.inventory[ITEM_INDEX(Fdi_POWERCUBE)];
			int	regen_frames;//4.2 regen for non-clients
			
			if (!target->client)
			{
				regen_frames = 1000 / self->monsterinfo.level; // full-regeneration in 15 seconds at level 10
				M_Regenerate(target, regen_frames, 50, 1.0, true, true, false, &target->monsterinfo.regen_delay2);
				continue;
			}
			
			maxHP = MAX_HEALTH(target);
			maxArmor = MAX_ARMOR(target);
			maxcubes = target->client->pers.max_powercubes;
			armor = &target->client->pers.inventory[body_armor_index];
			cubes = &target->client->pers.inventory[ITEM_INDEX(Fdi_POWERCUBE)];

			//Heal their health.
			if(target->health < maxHP)
			{
				target->health += NATURETOTEM_HEALTH_BASE + self->monsterinfo.level * NATURETOTEM_HEALTH_MULT;
				if(target->health > maxHP)
					target->health = maxHP;
				isSomeoneHealed = true;
			}
			//Heal their armor.
			if(*armor < maxArmor)
			{
				*armor += NATURETOTEM_ARMOR_BASE + self->monsterinfo.level * NATURETOTEM_ARMOR_MULT;
				if(*armor > maxArmor)
					*armor = maxArmor;
				isSomeoneHealed = true;
			}

			//Talent: Peace.
			if(*cubes < maxcubes)
			{
				//Give them 5 cubes per talent point.
				*cubes += getTalentLevel(caster, TALENT_PEACE) * 10;
				if(*cubes > maxcubes)
					*cubes = maxcubes;
				isSomeoneHealed = true;
			}

			// We remove curses. -az
			CurseRemove(target, 0);
		}
	}

	//Play a sound or something.
	if(isSomeoneHealed)
	{
		gi.sound(self, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0);
	}

	cdmult = level.time + NATURETOTEM_REFIRE_BASE + NATURETOTEM_REFIRE_MULT * self->monsterinfo.level;

	if (cdmult <= level.time)
		cdmult = level.time + 0.1;

	//Next think.
	self->delay = cdmult;
}
Ejemplo n.º 10
0
void Healing_think(edict_t *self)
{
	//Find my slot
	que_t *slot = NULL;	
	int heal_amount = HEALING_HEAL_BASE + HEALING_HEAL_BONUS * self->owner->myskills.abilities[HEALING].current_level;
	float cooldown = 1.0;

	slot = que_findtype(self->enemy->curses, NULL, HEALING);

	// Blessing self-terminates if the enemy dies or the duration expires
	if (!slot || !que_valident(slot))
	{
		que_removeent(self->enemy->curses, self, true);
		return;
	}

	//Stick with the target
	VectorCopy(self->enemy->s.origin, self->s.origin);
	gi.linkentity(self);

	//Next think time
	self->nextthink = level.time + cooldown;

	//Heal the target's armor
	if (!self->enemy->client)
	{
		//Check to make sure it's a monster
		if (!self->enemy->mtype)
			return;
		
		heal_amount = self->enemy->max_health * (0.01 * self->owner->myskills.abilities[HEALING].current_level); // 1% healed per level
		
		if (heal_amount > 100)
			heal_amount = 100;

		//Heal the momster's health
		self->enemy->health += heal_amount;
		if (self->enemy->health > self->enemy->max_health)
			self->enemy->health = self->enemy->max_health;

		if (self->enemy->monsterinfo.power_armor_type)
		{
			heal_amount = self->enemy->monsterinfo.power_armor_power * (0.01 * self->owner->myskills.abilities[HEALING].current_level); // 1% healed per level
			
			if (heal_amount > 100)
				heal_amount = 100;

			//Heal the monster's armor
			self->enemy->monsterinfo.power_armor_power += heal_amount;
			if (self->enemy->monsterinfo.power_armor_power > self->enemy->monsterinfo.max_armor)
				self->enemy->monsterinfo.power_armor_power = self->enemy->monsterinfo.max_armor;
		}
	}
	else
	{
		if (self->enemy->health < MAX_HEALTH(self->enemy))
		{
			//Heal health
			self->enemy->health += heal_amount;
			if (self->enemy->health > MAX_HEALTH(self->enemy))
				self->enemy->health = MAX_HEALTH(self->enemy);
		}

		if (self->enemy->client->pers.inventory[body_armor_index] < MAX_ARMOR(self->enemy))
		{
			//Heal armor
			heal_amount *= 0.5; // don't heal as much armor
			if (heal_amount < 1)
				heal_amount = 1;
			self->enemy->client->pers.inventory[body_armor_index] += heal_amount;
			if (self->enemy->client->pers.inventory[body_armor_index] > MAX_ARMOR(self->enemy))
				self->enemy->client->pers.inventory[body_armor_index] = MAX_ARMOR(self->enemy);
		}
	}
}