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); }
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); }
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; }
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)); }
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)); }
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; }
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; } }