Exemplo n.º 1
0
//=================================================================================================
void Quest_Orcs2::SetProgress(int prog2)
{
	bool apply = true;

	switch(prog2)
	{
	case Progress::TalkedOrc:
		// zapisz gorusha
		{
			orc = DialogContext::current->talker;
			orc->RevealName(true);
		}
		break;
	case Progress::NotJoined:
		break;
	case Progress::Joined:
		// dodaj questa
		{
			OnStart(game->txQuest[214]);
			msgs.push_back(Format(game->txQuest[170], W.GetDate()));
			msgs.push_back(game->txQuest[197]);
			// ustaw stan
			if(orcs_state == Quest_Orcs2::State::Accepted)
				orcs_state = Quest_Orcs2::State::OrcJoined;
			else
			{
				orcs_state = Quest_Orcs2::State::CompletedJoined;
				days = Random(30, 60);
				QM.quest_orcs->GetTargetLocation().active_quest = nullptr;
				QM.quest_orcs->target_loc = -1;
			}
			// do³¹cz do dru¿yny
			DialogContext::current->talker->dont_attack = false;
			Team.AddTeamMember(DialogContext::current->talker, true);
			if(Team.free_recruits > 0)
				--Team.free_recruits;
		}
		break;
	case Progress::TalkedAboutCamp:
		// powiedzia³ o obozie
		{
			target_loc = W.CreateCamp(W.GetWorldPos(), SG_ORCS, 256.f, false);
			Location& target = GetTargetLocation();
			target.state = LS_HIDDEN;
			target.st = 11;
			target.active_quest = this;
			near_loc = W.GetNearestSettlement(target.pos);
			OnUpdate(game->txQuest[198]);
			orcs_state = Quest_Orcs2::State::ToldAboutCamp;
		}
		break;
	case Progress::TalkedWhereIsCamp:
		// powiedzia³ gdzie obóz
		{
			if(prog == Progress::TalkedWhereIsCamp)
				break;
			Location& target = GetTargetLocation();
			Location& nearl = *W.GetLocation(near_loc);
			target.SetKnown();
			done = false;
			location_event_handler = this;
			OnUpdate(Format(game->txQuest[199], GetLocationDirName(nearl.pos, target.pos), nearl.name.c_str()));
		}
		break;
	case Progress::ClearedCamp:
		// oczyszczono obóz orków
		{
			orc->StartAutoTalk();
			W.AddNews(game->txQuest[200]);
			Team.AddExp(14000);
		}
		break;
	case Progress::TalkedAfterClearingCamp:
		// pogada³ po oczyszczeniu
		{
			orcs_state = Quest_Orcs2::State::CampCleared;
			days = Random(25, 50);
			GetTargetLocation().active_quest = nullptr;
			target_loc = -1;
			OnUpdate(game->txQuest[201]);
		}
		break;
	case Progress::SelectWarrior:
		// zostañ wojownikiem
		apply = false;
		ChangeClass(OrcClass::Warrior);
		break;
	case Progress::SelectHunter:
		// zostañ ³owc¹
		apply = false;
		ChangeClass(OrcClass::Hunter);
		break;
	case Progress::SelectShaman:
		// zostañ szamanem
		apply = false;
		ChangeClass(OrcClass::Shaman);
		break;
	case Progress::SelectRandom:
		// losowo
		{
			OrcClass clas;
			if(DialogContext::current->pc->unit->GetClass() == Class::WARRIOR)
			{
				if(Rand() % 2 == 0)
					clas = OrcClass::Hunter;
				else
					clas = OrcClass::Shaman;
			}
			else if(DialogContext::current->pc->unit->GetClass() == Class::HUNTER)
			{
				if(Rand() % 2 == 0)
					clas = OrcClass::Warrior;
				else
					clas = OrcClass::Shaman;
			}
			else
			{
				int co = Rand() % 3;
				if(co == 0)
					clas = OrcClass::Warrior;
				else if(co == 1)
					clas = OrcClass::Hunter;
				else
					clas = OrcClass::Shaman;
			}

			apply = false;
			ChangeClass(clas);
		}
		break;
	case Progress::TalkedAboutBase:
		// pogada³ o bazie
		{
			done = false;
			Location& target = *W.CreateLocation(L_DUNGEON, W.GetWorldPos(), 256.f, THRONE_FORT, SG_ORCS, false);
			target.st = 15;
			target.active_quest = this;
			target.state = LS_HIDDEN;
			target_loc = target.index;
			OnUpdate(game->txQuest[202]);
			orcs_state = State::ToldAboutBase;
		}
		break;
	case Progress::TalkedWhereIsBase:
		// powiedzia³ gdzie baza
		{
			Location& target = GetTargetLocation();
			target.SetKnown();
			unit_to_spawn = UnitData::Get("q_orkowie_boss");
			spawn_unit_room = RoomTarget::Throne;
			callback = WarpToThroneOrcBoss;
			at_level = target.GetLastLevel();
			location_event_handler = nullptr;
			unit_event_handler = this;
			near_loc = W.GetNearestSettlement(target.pos);
			Location& nearl = *W.GetLocation(near_loc);
			OnUpdate(Format(game->txQuest[203], GetLocationDirName(nearl.pos, target.pos), nearl.name.c_str(), target.name.c_str()));
			done = false;
			orcs_state = State::GenerateOrcs;
		}
		break;
	case Progress::KilledBoss:
		// zabito bossa
		{
			orc->StartAutoTalk();
			OnUpdate(game->txQuest[204]);
			W.AddNews(game->txQuest[205]);
			Team.AddLearningPoint();
		}
		break;
	case Progress::Finished:
		// pogadano z gorushem
		{
			state = Quest::Completed;
			Team.AddReward(Random(9000, 11000), 25000);
			OnUpdate(game->txQuest[206]);
			QM.EndUniqueQuest();
			// gorush
			Team.RemoveTeamMember(orc);
			Usable* tron = L.local_ctx.FindUsable("throne");
			assert(tron);
			if(tron)
			{
				orc->ai->idle_action = AIController::Idle_WalkUse;
				orc->ai->idle_data.usable = tron;
				orc->ai->timer = 9999.f;
			}
			orc = nullptr;
			// orki
			UnitData* ud[12] = {
				UnitData::Get("orc"), UnitData::Get("q_orkowie_orc"),
				UnitData::Get("orc_fighter"), UnitData::Get("q_orkowie_orc_fighter"),
				UnitData::Get("orc_warius"), UnitData::Get("q_orkowie_orc_warius"),
				UnitData::Get("orc_hunter"), UnitData::Get("q_orkowie_orc_hunter"),
				UnitData::Get("orc_shaman"), UnitData::Get("q_orkowie_orc_shaman"),
				UnitData::Get("orc_chief"), UnitData::Get("q_orkowie_orc_chief")
			};
			UnitData* ud_slaby = UnitData::Get("q_orkowie_slaby");

			for(vector<Unit*>::iterator it = L.local_ctx.units->begin(), end = L.local_ctx.units->end(); it != end; ++it)
			{
				Unit& u = **it;
				if(u.IsAlive())
				{
					if(u.data == ud_slaby)
					{
						// usuñ dont_attack, od tak :3
						u.dont_attack = false;
						u.ai->change_ai_mode = true;
					}
					else
					{
						for(int i = 0; i < 6; ++i)
						{
							if(u.data == ud[i * 2])
							{
								u.data = ud[i * 2 + 1];
								u.ai->target = nullptr;
								u.ai->alert_target = nullptr;
								u.ai->state = AIController::Idle;
								u.ai->change_ai_mode = true;
								if(Net::IsOnline())
								{
									NetChange& c = Add1(Net::changes);
									c.type = NetChange::CHANGE_UNIT_BASE;
									c.unit = &u;
								}
								break;
							}
						}
					}
				}
			}
			// zak³ada ¿e gadamy na ostatnim levelu, mam nadzieje ¿e gracz z tamt¹d nie spierdoli przed pogadaniem :3
			MultiInsideLocation* multi = (MultiInsideLocation*)W.GetCurrentLocation();
			for(vector<InsideLocationLevel>::iterator it = multi->levels.begin(), end = multi->levels.end() - 1; it != end; ++it)
			{
				for(vector<Unit*>::iterator it2 = it->units.begin(), end2 = it->units.end(); it2 != end2; ++it2)
				{
					Unit& u = **it2;
					if(u.IsAlive())
					{
						for(int i = 0; i < 5; ++i)
						{
							if(u.data == ud[i * 2])
							{
								u.data = ud[i * 2 + 1];
								break;
							}
						}
					}
				}
			}
			// usuñ zw³oki po opuszczeniu lokacji
			orcs_state = State::ClearDungeon;
		}
		break;
	}

	if(apply)
		prog = prog2;
}
Exemplo n.º 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);

}