示例#1
0
//=================================================================================================
void TeamPanel::OnGiveGold(int id)
{
	if(id != BUTTON_OK || counter == 0)
		return;

	if(!Team.IsTeamMember(*target))
		SimpleDialog(Format(txCAlreadyLeft, target->GetName()));
	else if(counter > game.pc->unit->gold)
		SimpleDialog(txNotEnoughGold);
	else
	{
		game.pc->unit->gold -= counter;
		game.sound_mgr->PlaySound2d(game.sCoins);
		if(Net::IsLocal())
		{
			target->gold += counter;
			if(target->IsPlayer() && target->player != game.pc)
			{
				NetChangePlayer& c = Add1(target->player->player_info->changes);
				c.type = NetChangePlayer::GOLD_RECEIVED;
				c.id = game.pc->id;
				c.count = counter;
				target->player->player_info->UpdateGold();
			}
		}
		else
		{
			NetChange& c = Add1(Net::changes);
			c.type = NetChange::GIVE_GOLD;
			c.id = target->netid;
			c.count = counter;
		}
	}
}
示例#2
0
//=================================================================================================
void TeamPanel::OnPayCredit(int id)
{
	if(id != BUTTON_OK)
		return;

	if(game.pc->credit == 0)
		SimpleDialog(txNoCredit);
	else if(counter > game.pc->unit->gold)
		SimpleDialog(txNotEnoughGold);
	else
	{
		int count = min(counter, game.pc->credit);
		if(game.pc->credit == count)
			SimpleDialog(txPaidCredit);
		else
			SimpleDialog(Format(txPaidCreditPart, count, game.pc->credit - count));
		game.pc->unit->gold -= count;
		game.sound_mgr->PlaySound2d(game.sCoins);
		if(Net::IsLocal())
			game.pc->PayCredit(count);
		else
		{
			NetChange& c = Add1(Net::changes);
			c.type = NetChange::PAY_CREDIT;
			c.id = count;
		}
	}
}
示例#3
0
void CommandParser::ParseStringCommand(int cmd, const string& s, PlayerInfo& info)
{
	LocalString str;
	PrintMsgFunc prev_func = g_print_func;
	g_print_func = [&str](cstring s)
	{
		if(!str.empty())
			str += "\n";
		str += s;
	};

	switch((CMD)cmd)
	{
	case CMD_ARENA:
		ArenaCombat(s.c_str());
		break;
	}

	g_print_func = prev_func;

	if(!str.empty())
	{
		NetChangePlayer& c = Add1(info.changes);
		c.type = NetChangePlayer::GENERIC_CMD_RESPONSE;
		c.str = str.Pin();
	}
}
示例#4
0
//=================================================================================================
bool Game::RemoveQuestGroundItem(LevelAreaContext* lac, int quest_refid)
{
	assert(lac);

	lac->AddRef();
	LevelAreaContext::Entry* entry;
	int index;
	GroundItem* item = FindQuestGroundItem(lac, quest_refid, &entry, &index);
	if(item)
	{
		if(entry->active && Net::IsOnline())
		{
			NetChange& c = Add1(Net::changes);
			c.type = NetChange::REMOVE_ITEM;
			c.id = item->netid;
		}
		RemoveElementIndex(entry->area->items, index);
		lac->Free();
		return true;
	}
	else
	{
		lac->Free();
		return false;
	}
}
int main()
{
    printf("%d \n", Add1(15, 32));
    printf("%d \n", Add2(15, 32));
    printf("%d \n", Add3(15, 32));

    return 0;
}
示例#6
0
文件: main.cpp 项目: kippler/Samples
void test()
{
	Assign();
	Add1();
	Add2();
	GetBuffer();
	Compare();
	Mid();
}
示例#7
0
文件: Base.cpp 项目: edeksumo/carpg
Config::Result Config::Open(cstring filename)
{
	assert(filename);

	Tokenizer t(Tokenizer::F_JOIN_DOT);
	if(!t.FromFile(filename))
		return NO_FILE;

	LocalString item, value;

	try
	{
		while(true)
		{
			// nazwa zmiennej lub eof
			t.Next();
			if(t.IsEof())
				break;
			item = t.MustGetItem();
			t.Next();

			// =
			t.AssertSymbol('=');
			t.Next(true);

			// wartoϾ lub eol
			if(t.IsEol())
				value->clear();
			else
				value = t.GetToken();

			bool jest = false;
			for(vector<Entry>::iterator it = entries.begin(), end = entries.end(); it != end; ++it)
			{
				if(item == it->name)
				{
					jest = true;
					break;
				}
			}

			if(!jest)
			{
				Entry& e = Add1(entries);
				e.name = item;
				e.value = value;
			}
		}
	}
	catch(cstring err)
	{
		error = err;
		return PARSE_ERROR;
	}

	return OK;
}
示例#8
0
//=================================================================================================
void PlayerController::Rest(int days, bool resting, bool travel)
{
	// update effects that work for days, end other
	int best_nat;
	float prev_hp = unit->hp,
		prev_stamina = unit->stamina;
	unit->EndEffects(days, &best_nat);

	// regenerate hp
	if(unit->hp != unit->hpmax)
	{
		float heal = 0.5f * unit->Get(Attribute::END);
		if(resting)
			heal *= 2;
		if(best_nat)
		{
			if(best_nat != days)
				heal = heal*best_nat * 2 + heal*(days - best_nat);
			else
				heal *= 2 * days;
		}
		else
			heal *= days;

		heal = min(heal, unit->hpmax - unit->hp);
		unit->hp += heal;

		Train(Attribute::END, int(heal));
	}

	// send update
	Game& game = Game::Get();
	if(Net::IsOnline() && !travel)
	{
		if(unit->hp != prev_hp)
		{
			NetChange& c = Add1(Net::changes);
			c.type = NetChange::UPDATE_HP;
			c.unit = unit;
		}

		if(unit->stamina != prev_stamina && this != game.pc)
			game.GetPlayerInfo(this).update_flags |= PlayerInfo::UF_STAMINA;
	}

	// reset last damage
	last_dmg = 0;
	last_dmg_poison = 0;
	dmgc = 0;
	poison_dmgc = 0;

	// reset action
	action_cooldown = 0;
	action_recharge = 0;
	action_charges = GetAction().charges;
}
void CALLBACK Add1(
    __in HRESULT hr, 
    __in WS_CALLBACK_MODEL callbackModel, 
    __in void* state)
{
    ADD_STATE* addState = (ADD_STATE*)state;
    // Mark the operation as being async
    addState->async = TRUE;
    Add1(hr, callbackModel, addState);
}
int Add1(int a, int b)
{
    if(b == 0)
	return a;
    int sum = a^b; // sum without carry
    int carry = (a&b) << 1; // carry
    a = sum;
    b = carry;
    return Add1(a, b);
}
示例#11
0
//=============================================================================
bool TryMove(Unit& u, DIR new_dir, bool attack)
{
	u.new_pos = u.pos + dir_change[new_dir];
	if(u.new_pos.x >= 0 && u.new_pos.y >= 0 && u.new_pos.x < MAP_W && u.new_pos.y < MAP_H)
	{
		Tile& tile = mapa[u.new_pos.x+u.new_pos.y*MAP_W];
		if(tile.IsBlocking(u.is_player))
			return false;
		else if(tile.unit)
		{
			if(CheckRef(tile.unit) && attack && tile.unit->GetRef().alive)
			{
				// attack
				if(u.attack_timer <= 0.f)
				{
					Unit& target = tile.unit->GetRef();
					Hit& hit = Add1(hits);
					hit.pos = target.GetPos();
					hit.timer = 0.5f;
					hit._ref = tile.unit;
					u.waiting = 0.5f;
					u.attack_timer = 1.f/u.base->attack_speed;
					target.hp -= (u.base->attack - target.base->defense);
					if(target.hp <= 0)
					{
						target.alive = false;
						player->untaxed_gold += target.gold;
						player->AddExp(target.base->lvl);
					}
				}
				return true;
			}
			else
				return false;
		}
		else
		{
			if(new_dir == DIR_NE || new_dir == DIR_NW || new_dir == DIR_SE || new_dir == DIR_SW)
			{
				if(mapa[u.pos.x+dir_change[new_dir].x+u.pos.y*MAP_W].IsBlocking() &&
					mapa[u.pos.x+(u.pos.y+dir_change[new_dir].y)*MAP_W].IsBlocking())
					return false;
			}

			u.dir = new_dir;
			u.moving = true;
			u.move_progress = 0.f;
			mapa[u.new_pos.x+u.new_pos.y*MAP_W].unit = u._ref;
			return true;
		}
	}

	return false;
}
示例#12
0
//=================================================================================================
void TeamPanel::ChangeLeader()
{
	if(target->IsAI())
		SimpleDialog(txOnlyPcLeader);
	else if(target == game.pc->unit)
	{
		if(Team.IsLeader())
			SimpleDialog(txAlreadyLeader);
		else if(Net::IsServer())
		{
			NetChange& c = Add1(Net::changes);
			c.type = NetChange::CHANGE_LEADER;
			c.id = Team.my_id;

			Team.leader_id = Team.my_id;
			Team.leader = game.pc->unit;

			game.AddMultiMsg(txYouAreLeader);
		}
		else
			SimpleDialog(txCantChangeLeader);
	}
	else if(Team.IsLeader(target))
		SimpleDialog(Format(txPcAlreadyLeader, target->GetName()));
	else if(Team.IsLeader() || Net::IsServer())
	{
		NetChange& c = Add1(Net::changes);
		c.type = NetChange::CHANGE_LEADER;
		c.id = target->player->id;

		if(Net::IsServer())
		{
			Team.leader_id = c.id;
			Team.leader = target;

			game.AddMultiMsg(Format(txPcIsLeader, target->GetName()));
		}
	}
	else
		SimpleDialog(txCantChangeLeader);
}
示例#13
0
int main() {
	Add1(1,2);
	Add2(1,2);

	int(*f)(int,int);

	int n;
	cin >> n;
	if(n==0)	f = &Add1;
	else		f = &Add2;

	f(1,2);
}
示例#14
0
文件: Base.cpp 项目: edeksumo/carpg
void Config::Add(cstring name, cstring value)
{
	assert(name && value);

	for(vector<Entry>::iterator it = entries.begin(), end = entries.end(); it != end; ++it)
	{
		if(it->name == name)
		{
			it->value = value;
			return;
		}
	}

	Entry& e = Add1(entries);
	e.name = name;
	e.value = value;
}
示例#15
0
//=================================================================================================
void Quest_SpreadNews::Start()
{
	type = QuestType::Mayor;
	quest_id = Q_SPREAD_NEWS;
	start_loc = W.GetCurrentLocationIndex();
	Vec2 pos = GetStartLocation().pos;
	bool sorted = false;
	const vector<Location*>& locations = W.GetLocations();
	for(uint i = 0, count = locations.size(); i < count; ++i)
	{
		if(!locations[i] || locations[i]->type != L_CITY)
			break;
		if(i == start_loc)
			continue;
		Location& loc = *locations[i];
		float dist = Vec2::Distance(pos, loc.pos);
		bool ok = false;
		if(entries.size() < 5)
			ok = true;
		else
		{
			if(!sorted)
			{
				std::sort(entries.begin(), entries.end(), SortEntries);
				sorted = true;
			}
			if(entries.back().dist > dist)
			{
				ok = true;
				sorted = false;
				entries.pop_back();
			}
		}
		if(ok)
		{
			Entry& e = Add1(entries);
			e.location = i;
			e.given = false;
			e.dist = dist;
		}
	}
}
示例#16
0
void InsertItemBare(vector<ItemSlot>& items, const Item* item, uint count, uint team_count)
{
	assert(item && count && count >= team_count);

	if(item->IsStackable())
	{
		for(vector<ItemSlot>::iterator it = items.begin(), end = items.end(); it != end; ++it)
		{
			if(it->item == item)
			{
				it->count += count;
				it->team_count += team_count;
				return;
			}
		}
	}

	// nie stackuje siê lub nie ma takiego, dodaj
	ItemSlot& slot = Add1(items);
	slot.Set(item, count, team_count);
}
HRESULT CALLBACK AddThree(
    __in ADD_STATE* addState, 
    __in int a, 
    __in int b, 
    __in int c, 
    __out int* result, 
    __in_opt const WS_ASYNC_CONTEXT* asyncContext, 
    __in_opt WS_ERROR* error)
{
    HRESULT hr = S_OK;

    // Determine if the function should be executed synchronously or asynchronously
    if (asyncContext != NULL)
    {
        addState->asyncContext = *asyncContext;
    }
    else
    {
        addState->asyncContext.callback = NULL;
    }
    // Set up the state for the operation
    addState->error = error;
    addState->result = result;
    addState->c = c;
    addState->sum = 0;
    addState->async = FALSE;

    // Add the first two values and continue at Add1
    WS_ASYNC_CONTEXT add1;
    add1.callback = Add1;
    add1.callbackState = addState;
    hr = Add(a, b, &addState->sum, (addState->asyncContext.callback != NULL ? &add1 : NULL), error);
    if (hr == WS_S_ASYNC)
    {
        // Add1 will get called asynchronously
        return hr;
    }
    // Operation completed synchronously, so no callback will occur, so call directly
    return Add1(hr, WS_SHORT_CALLBACK, addState);
}
示例#18
0
//=================================================================================================
void Electro::AddLine(const Vec3& from, const Vec3& to)
{
	ElectroLine& line = Add1(lines);

	line.t = 0.f;
	line.pts.push_back(from);

	int steps = int(Vec3::Distance(from, to) * 10);

	Vec3 dir = to - from;
	const Vec3 step = dir / float(steps);
	Vec3 prev_off(0.f, 0.f, 0.f);

	for(int i = 1; i < steps; ++i)
	{
		Vec3 p = from + step*(float(i) + Random(-0.25f, 0.25f));
		Vec3 r = Vec3::Random(Vec3(-0.3f, -0.3f, -0.3f), Vec3(0.3f, 0.3f, 0.3f));
		prev_off = (r + prev_off) / 2;
		line.pts.push_back(p + prev_off);
	}

	line.pts.push_back(to);
}
示例#19
0
static void Convert(char *b_string, HugeNumber &w)
// Prweobrazovanie iz stroki v chislo
{
	word n,m;
	word i;
	char *b;
	HugeNumber tmp;

	// Ydalit razdeliteli
	n=strlen(b_string);
	b=new char[n+1];	// Videlit pamiat dlia stroki po chisly simvolov + 1 byte for 
							// priznaka konza stroki
	// !!! Predidyshij operator bil zapisan s oshibkoj i vigladel tak: b=new char[n];
	// Odnako v Borland vsio rabotalo i oshibka vsplila tolko v VC++
	strcpy(b,b_string);

	for (;;)
	{
		for (i=0; i<n; i++) if (b[i]=='`') break;
		if (i==n) break;
		for (   ; i<n; i++) b[i]=b[i+1];
		n--;
	};

	m=strlen(b);
	w.Resize(m+55);
	n=w.Razr();

	for (i=0; i<n; i++) w.digit[i]=0;
	for (i=0; i<m; i++)
	{
		Mult1(w,10,tmp);
		Add1(tmp,b[i]-'0');
		w=tmp;
	};
	delete b;
};
示例#20
0
bool CommandParser::ParseStream(BitStreamReader& f, PlayerInfo& info)
{
	LocalString str;
	PrintMsgFunc prev_func = g_print_func;
	g_print_func = [&str](cstring s)
	{
		if(!str.empty())
			str += "\n";
		str += s;
	};

	bool result = ParseStreamInner(f);

	g_print_func = prev_func;

	if(result && !str.empty())
	{
		NetChangePlayer& c = Add1(info.changes);
		c.type = NetChangePlayer::GENERIC_CMD_RESPONSE;
		c.str = str.Pin();
	}

	return result;
}
示例#21
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;
}
示例#22
0
//=============================================================================
void Update(float dt)
{
	// selecting unit
	INT2 tile((cursor_pos.x + cam_pos.x)/32, (cursor_pos.y + cam_pos.y)/32);
	if(tile.x >= 0 && tile.y >= 0 && tile.x < MAP_W && tile.y < MAP_W && MousePressedRelease(1))
	{
		Tile& t = mapa[tile.x+tile.y*MAP_W];
		selected = t.unit;
	}

	// sleep button
	if(player && player->alive && player->inside_building && cursor_pos.x >= 32 && cursor_pos.y >= 700 && cursor_pos.x < 32+16 && cursor_pos.y < 700+16 && MousePressedRelease(1))
	{
		if(player->gold >= 10 && !player->sleeping && player->hp != player->base->hp)
		{
			player->gold -= 10;
			player->sleeping = true;
			player->sleeping_progress = 0.f;
		}
	}

	// update player
	if(player && player->alive && player->waiting <= 0.f && !player->moving)
	{
		Unit& u = *player;

		if(player->sleeping)
		{
			player->sleeping_progress += dt;
			if(player->sleeping_progress >= 1.f)
			{
				player->hp += 5;
				player->sleeping_progress = 0.f;
				if(player->hp >= player->base->hp)
				{
					player->hp = player->base->hp;
					player->sleeping = false;
				}
			}
		}
		else if(u.inside_building)
		{
			// unit inside building, press SPACE to exit
			if(KeyPressedRelease(SDL_SCANCODE_SPACE) && !mapa[u.pos.x+u.pos.y*MAP_W].unit)
			{
				if(!TryMove(u, DIR_S, false))
				{
					if(rand()%2 == 0)
					{
						if(!TryMove(u, DIR_SW, false))
						{
							if(TryMove(u, DIR_SE, false))
								u.inside_building = false;
						}
						else
							u.inside_building = false;
					}
					else
					{
						if(!TryMove(u, DIR_SE, false))
						{
							if(TryMove(u, DIR_SW, false))
								u.inside_building = false;
						}
						else
							u.inside_building = false;
					}
				}
				else
					u.inside_building = false;
			}
		}
		else
		{
			struct Key1
			{
				SDL_Scancode k1;
				SDL_Scancode k2;
				DIR dir;
			};
			const Key1 keys1[] = {
				SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_4, DIR_W,
				SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_6, DIR_E,
				SDL_SCANCODE_UP, SDL_SCANCODE_KP_8, DIR_N,
				SDL_SCANCODE_DOWN, SDL_SCANCODE_KP_2, DIR_S
			};
			struct Key2
			{
				SDL_Scancode k1;
				SDL_Scancode k2;
				SDL_Scancode k3;
				DIR dir;
			};
			const Key2 keys2[] = {
				SDL_SCANCODE_KP_1, SDL_SCANCODE_LEFT, SDL_SCANCODE_DOWN, DIR_SW,
				SDL_SCANCODE_KP_3, SDL_SCANCODE_RIGHT, SDL_SCANCODE_DOWN, DIR_SE,
				SDL_SCANCODE_KP_7, SDL_SCANCODE_LEFT, SDL_SCANCODE_UP, DIR_NW,
				SDL_SCANCODE_KP_9, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, DIR_NE
			};

			for(int i=0; i<4; ++i)
			{
				if(KeyDown(keys2[i].k1) || (KeyDown(keys2[i].k2) && KeyDown(keys2[i].k3)))
				{
					if(TryMove(u, keys2[i].dir, true))
						break;
				}
			}
			if(!u.moving && u.waiting <= 0.f)
			{
				for(int i=0; i<4; ++i)
				{
					if(KeyDown(keys1[i].k1) || KeyDown(keys1[i].k2))
					{
						if(TryMove(u, keys1[i].dir, true))
							break;
					}
				}
			}
		}
	}

	// update ai
	for(vector<Unit*>::iterator it = units.begin(), end = units.end(); it != end; ++it)
	{
		Unit& u = **it;
		u.attack_timer -= dt;
		if(u.hp <= 0)
		{
			if(&u == player)
				player = NULL;
			if(u.moving)
				mapa[u.new_pos.x+u.new_pos.y*MAP_W].unit = NULL;
			mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL;
			delete &u;
			it = units.erase(it);
			end = units.end();
			if(it == end)
				break;
		}
		else if(u.waiting > 0.f)
			u.waiting -= dt;
		else if(u.moving)
		{
			u.move_progress += dt*u.base->move_speed;
			if(u.move_progress >= 1.f)
			{
				u.moving = false;
				mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL;
				u.pos = u.new_pos;
				Tile& tile = mapa[u.pos.x+u.pos.y*MAP_W];
				if(tile.building)
				{
					tile.unit = NULL;
					u.inside_building = true;
					if(player->untaxed_gold)
					{
						int tax = player->untaxed_gold*TAX/100;
						player->untaxed_gold -= tax;
						player->gold += player->untaxed_gold;
						player->untaxed_gold = 0;
					}
				}
			}
		}
		else if(&u != player && player && player->alive && !player->inside_building)
		{
			INT2 enemy_pt;
			int dist = GetClosestPoint(u.pos, *player, enemy_pt);
			if(dist <= 50)
			{
				if(dist <= 15)
				{
					// in attack range
					if(u.attack_timer <= 0.f)
					{
						Hit& hit = Add1(hits);
						hit.pos = player->GetPos();
						hit.timer = 0.5f;
						hit._ref = player->_ref;
						u.waiting = 0.5f;
						u.attack_timer = 1.f/u.base->attack_speed;
						player->hp -= u.base->attack - player->base->defense;
						if(player->hp <= 0)
						{
							player->alive = false;
							u.gold += (player->gold + player->untaxed_gold);
							player->gold = 0;
							player->untaxed_gold = 0;
						}
					}
				}
				else
				{
					DIR dir = GetDir(u.pos, enemy_pt);
					if(!TryMove(u, dir, false))
					{
						struct SubDir
						{
							DIR a, b;
						};
						const SubDir sub_dir[8] = {
							DIR_SE, DIR_SW, //DIR_S,
							DIR_W, DIR_S, //DIR_SW,
							DIR_NW, DIR_SW, //DIR_W,
							DIR_N, DIR_W, //DIR_NW,
							DIR_NE, DIR_NW, //DIR_N,
							DIR_N, DIR_E, //DIR_NE,
							DIR_SE, DIR_NE, //DIR_E,
							DIR_S, DIR_E //DIR_SE,
						};
						if(rand()%2 == 0)
						{
							if(!TryMove(u, sub_dir[dir].a, false))
								TryMove(u, sub_dir[dir].b, false);
						}
						else
						{
							if(!TryMove(u, sub_dir[dir].b, false))
								TryMove(u, sub_dir[dir].a, false);
						}
					}
				}
			}
		}
	}

	// update hit animations
	for(vector<Hit>::iterator it = hits.begin(), end = hits.end(); it != end;)
	{
		Hit& hit = *it;
		hit.timer -= dt;
		if(hit.timer <= 0.f)
		{
			if(it+1 == end)
			{
				hits.pop_back();
				break;
			}
			else
			{
				std::iter_swap(it, end-1);
				hits.pop_back();
				end = hits.end();
			}
		}
		else
		{
			if(CheckRef(hit._ref))
				hit.pos = hit._ref->GetRef().GetPos();
			++it;
		}
	}

	// set camera
	if(player)
	{
		cam_pos = player->GetPos() - SCREEN_SIZE/2;
		if(cam_pos.x < 0)
			cam_pos.x = 0;
		if(cam_pos.y < 0)
			cam_pos.y = 0;
		if(cam_pos.x + SCREEN_SIZE.x > MAP_W*32)
			cam_pos.x = MAP_W*32-SCREEN_SIZE.x;
		if(cam_pos.y + SCREEN_SIZE.y > MAP_H*32)
			cam_pos.y = MAP_H*32-SCREEN_SIZE.y;
	}
}
示例#23
0
文件: City.cpp 项目: edeksumo/carpg
//=================================================================================================
void City::Load(HANDLE file, bool local)
{
	OutsideLocation::Load(file, local);

	ReadFile(file, &citzens, sizeof(citzens), &tmp, NULL);
	ReadFile(file, &citzens_world, sizeof(citzens_world), &tmp, NULL);

	if(last_visit != -1)
	{
		int side;
		BOX2D spawn_area;
		BOX2D exit_area;
		float spawn_dir;

		if(LOAD_VERSION < V_0_3)
		{
			ReadFile(file, &side, sizeof(side), &tmp, NULL);
			ReadFile(file, &spawn_area, sizeof(spawn_area), &tmp, NULL);
			ReadFile(file, &exit_area, sizeof(exit_area), &tmp, NULL);
			ReadFile(file, &spawn_dir, sizeof(spawn_dir), &tmp, NULL);
		}
		else
		{
			File f(file);
			f.ReadVector1(entry_points);
			f >> have_exit;
			gates = f.Read<byte>();
		}

		uint ile;
		ReadFile(file, &ile, sizeof(ile), &tmp, NULL);
		buildings.resize(ile);
		ReadFile(file, &buildings[0], sizeof(CityBuilding)*ile, &tmp, NULL);
		ReadFile(file, &inside_offset, sizeof(inside_offset), &tmp, NULL);
		ReadFile(file, &ile, sizeof(ile), &tmp, NULL);
		inside_buildings.resize(ile);
		int index = 0;
		for(vector<InsideBuilding*>::iterator it = inside_buildings.begin(), end = inside_buildings.end(); it != end; ++it, ++index)
		{
			*it = new InsideBuilding;
			(*it)->Load(file, local);
			(*it)->ctx.building_id = index;
			(*it)->ctx.mine = INT2((*it)->level_shift.x*256, (*it)->level_shift.y*256);
			(*it)->ctx.maxe = (*it)->ctx.mine + INT2(256,256);
		}

		ReadFile(file, &quest_burmistrz, sizeof(quest_burmistrz), &tmp, NULL);
		ReadFile(file, &quest_burmistrz_czas, sizeof(quest_burmistrz_czas), &tmp, NULL);
		ReadFile(file, &quest_dowodca, sizeof(quest_dowodca), &tmp, NULL);
		ReadFile(file, &quest_dowodca_czas, sizeof(quest_dowodca_czas), &tmp, NULL);
		ReadFile(file, &arena_czas, sizeof(arena_czas), &tmp, NULL);
		ReadFile(file, &arena_pos, sizeof(arena_pos), &tmp, NULL);

		if(LOAD_VERSION < V_0_3)
		{
			const float aa = 11.1f;
			const float bb = 12.6f;
			const float es = 1.3f;
			const uint _s = 16 * 8;
			const int w = size;
			const int w1 = w+1;
			const int mur1 = int(0.15f*w);
			const int mur2 = int(0.85f*w);
			TERRAIN_TILE road_type;

			// setup entrance
			switch(side)
			{
			case 0: // from top
				{
					VEC2 p(float(_s)+1.f, 0.8f*_s*2);
					exit_area = BOX2D(p.x-es, p.y+aa, p.x+es, p.y+bb);
					gates = GATE_NORTH;
					road_type = tiles[w/2+int(0.85f*w-2)*w].t;
				}
				break;
			case 1: // from left
				{
					VEC2 p(0.2f*_s*2, float(_s)+1.f);
					exit_area = BOX2D(p.x-bb, p.y-es, p.x-aa, p.y+es);
					gates = GATE_WEST;
					road_type = tiles[int(0.15f*w)+2+(w/2)*w].t;
				}
				break;
			case 2: // from bottom
				{
					VEC2 p(float(_s)+1.f, 0.2f*_s*2);
					exit_area = BOX2D(p.x-es, p.y-bb, p.x+es, p.y-aa);
					gates = GATE_SOUTH;
					road_type = tiles[w/2+int(0.15f*w+2)*w].t;
				}
				break;
			case 3: // from right
				{
					VEC2 p(0.8f*_s*2, float(_s)+1.f);
					exit_area = BOX2D(p.x+aa, p.y-es, p.x+bb, p.y+es);
					gates = GATE_EAST;
					road_type = tiles[int(0.85f*w)-2+(w/2)*w].t;
				}
				break;
			}

			// update terrain tiles
			// tiles under walls
			for(int i=mur1; i<=mur2; ++i)
			{
				// north
				tiles[i+mur1*w].Set(TT_SAND, TM_BUILDING);
				if(tiles[i+(mur1+1)*w].t == TT_GRASS)
					tiles[i+(mur1+1)*w].Set(TT_SAND, TT_GRASS, 128, TM_BUILDING);
				// south
				tiles[i+mur2*w].Set(TT_SAND, TM_BUILDING);
				if(tiles[i+(mur2-1)*w].t == TT_GRASS)
					tiles[i+(mur2-1)*w].Set(TT_SAND, TT_GRASS, 128, TM_BUILDING);
				// west
				tiles[mur1+i*w].Set(TT_SAND, TM_BUILDING);
				if(tiles[mur1+1+i*w].t == TT_GRASS)
					tiles[mur1+1+i*w].Set(TT_SAND, TT_GRASS, 128, TM_BUILDING);
				// east
				tiles[mur2+i*w].Set(TT_SAND, TM_BUILDING);
				if(tiles[mur2-1+i*w].t == TT_GRASS)
					tiles[mur2-1+i*w].Set(TT_SAND, TT_GRASS, 128, TM_BUILDING);
			}

			// tiles under gates
			if(gates == GATE_SOUTH)
			{
				tiles[w/2-1+int(0.15f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2  +int(0.15f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2+1+int(0.15f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2-1+(int(0.15f*w)+1)*w].Set(road_type, TM_ROAD);
				tiles[w/2  +(int(0.15f*w)+1)*w].Set(road_type, TM_ROAD);
				tiles[w/2+1+(int(0.15f*w)+1)*w].Set(road_type, TM_ROAD);
			}
			if(gates == GATE_WEST)
			{
				tiles[int(0.15f*w)+(w/2-1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.15f*w)+(w/2  )*w].Set(road_type, TM_ROAD);
				tiles[int(0.15f*w)+(w/2+1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.15f*w)+1+(w/2-1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.15f*w)+1+(w/2  )*w].Set(road_type, TM_ROAD);
				tiles[int(0.15f*w)+1+(w/2+1)*w].Set(road_type, TM_ROAD);
			}
			if(gates == GATE_NORTH)
			{
				tiles[w/2-1+int(0.85f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2  +int(0.85f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2+1+int(0.85f*w)*w].Set(road_type, TM_ROAD);
				tiles[w/2-1+(int(0.85f*w)-1)*w].Set(road_type, TM_ROAD);
				tiles[w/2  +(int(0.85f*w)-1)*w].Set(road_type, TM_ROAD);
				tiles[w/2+1+(int(0.85f*w)-1)*w].Set(road_type, TM_ROAD);
			}
			if(gates == GATE_EAST)
			{
				tiles[int(0.85f*w)+(w/2-1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.85f*w)+(w/2  )*w].Set(road_type, TM_ROAD);
				tiles[int(0.85f*w)+(w/2+1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.85f*w)-1+(w/2-1)*w].Set(road_type, TM_ROAD);
				tiles[int(0.85f*w)-1+(w/2  )*w].Set(road_type, TM_ROAD);
				tiles[int(0.85f*w)-1+(w/2+1)*w].Set(road_type, TM_ROAD);
			}

			// delete old walls
			Obj* to_remove = FindObject("to_remove");
			vector<Object>::iterator it = objects.begin();
			while(it != objects.end())
			{
				if(it->base == to_remove)
					it = objects.erase(it);
				else
					++it;
			}

			// add new buildings
			Obj* oMur = FindObject("wall");
			Obj* oWieza = FindObject("tower");

			const int mid = int(0.5f*_s);

			// walls
			for(int i=mur1; i<mur2; i += 3)
			{
				// top
				if(side != 2 || i < mid-1 || i > mid)
				{
					Object& o = Add1(objects);
					o.pos = VEC3(float(i)*2+1.f, 1.f, int(0.15f*_s)*2+1.f);
					o.rot = VEC3(0,PI,0);
					o.scale = 1.f;
					o.base = oMur;
					o.mesh = oMur->ani;
				}

				// bottom
				if(side != 0 || i < mid-1 || i > mid)
				{
					Object& o = Add1(objects);
					o.pos = VEC3(float(i)*2+1.f, 1.f, int(0.85f*_s)*2+1.f);
					o.rot = VEC3(0,0,0);
					o.scale = 1.f;
					o.base = oMur;
					o.mesh = oMur->ani;
				}

				// left
				if(side != 1 || i < mid-1 || i > mid)
				{
					Object& o = Add1(objects);
					o.pos = VEC3(int(0.15f*_s)*2+1.f, 1.f, float(i)*2+1.f);
					o.rot = VEC3(0,PI*3/2,0);
					o.scale = 1.f;
					o.base = oMur;
					o.mesh = oMur->ani;
				}

				// right
				if(side != 3 || i < mid-1 || i > mid)
				{
					Object& o = Add1(objects);
					o.pos = VEC3(int(0.85f*_s)*2+1.f, 1.f, float(i)*2+1.f);
					o.rot = VEC3(0,PI/2,0);
					o.scale = 1.f;
					o.base = oMur;
					o.mesh = oMur->ani;
				}
			}

			// towers
			{
				// right top
				Object& o = Add1(objects);
				o.pos = VEC3(int(0.85f*_s)*2+1.f,1.f,int(0.85f*_s)*2+1.f);
				o.rot = VEC3(0,0,0);		
				o.scale = 1.f;
				o.base = oWieza;
				o.mesh = oWieza->ani;
			}
			{
				// right bottom
				Object& o = Add1(objects);
				o.pos = VEC3(int(0.85f*_s)*2+1.f,1.f,int(0.15f*_s)*2+1.f);
				o.rot = VEC3(0,PI/2,0);
				o.scale = 1.f;
				o.base = oWieza;
				o.mesh = oWieza->ani;
			}
			{
				// left bottom
				Object& o = Add1(objects);
				o.pos = VEC3(int(0.15f*_s)*2+1.f,1.f,int(0.15f*_s)*2+1.f);
				o.rot = VEC3(0,PI,0);
				o.scale = 1.f;
				o.base = oWieza;
				o.mesh = oWieza->ani;
			}
			{
				// left top
				Object& o = Add1(objects);
				o.pos = VEC3(int(0.15f*_s)*2+1.f,1.f,int(0.85f*_s)*2+1.f);
				o.rot = VEC3(0,PI*3/2,0);
				o.scale = 1.f;
				o.base = oWieza;
				o.mesh = oWieza->ani;
			}

			// gate
			Object& o = Add1(objects);
			o.rot.x = o.rot.z = 0.f;
			o.scale = 1.f;
			o.base = FindObject("gate");
			o.mesh = o.base->ani;
			switch(side)
			{
			case 0:
				o.rot.y = 0;
				o.pos = VEC3(0.5f*_s*2+1.f,1.f,0.85f*_s*2);
				break;
			case 1:
				o.rot.y = PI*3/2;
				o.pos = VEC3(0.15f*_s*2,1.f,0.5f*_s*2+1.f);
				break;
			case 2:
				o.rot.y = PI;
				o.pos = VEC3(0.5f*_s*2+1.f,1.f,0.15f*_s*2);
				break;
			case 3:
				o.rot.y = PI/2;
				o.pos = VEC3(0.85f*_s*2,1.f,0.5f*_s*2+1.f);
				break;
			}

			// grate
			Object& o2 = Add1(objects);
			o2.pos = o.pos;
			o2.rot = o.rot;
			o2.scale = 1.f;
			o2.base = FindObject("grate");
			o2.mesh = o2.base->ani;

			// exit
			EntryPoint& entry = Add1(entry_points);
			entry.spawn_area = spawn_area;
			entry.spawn_rot = spawn_dir;
			entry.exit_area = exit_area;
			entry.exit_y = 1.1f;
		}
	}
示例#24
0
文件: Main.cpp 项目: lcs2/carpg
//=================================================================================================
bool RunInstallScripts()
{
	Info("Reading install scripts.");
	WIN32_FIND_DATA data;
	HANDLE find = FindFirstFile(Format("%s/install/*.txt", g_system_dir.c_str()), &data);
	if(find == INVALID_HANDLE_VALUE)
		return true;

	vector<InstallScript> scripts;

	Tokenizer t;
	t.AddKeyword("install", 0);
	t.AddKeyword("version", 1);
	t.AddKeyword("remove", 2);

	do
	{
		int major, minor, patch;

		// read file to find version info
		try
		{
			if(t.FromFile(Format("%s/install/%s", g_system_dir.c_str(), data.cFileName)))
			{
				t.Next();
				if(t.MustGetKeywordId() == 2)
				{
					// old install script
					if(sscanf_s(data.cFileName, "%d.%d.%d.txt", &major, &minor, &patch) != 3)
					{
						if(sscanf_s(data.cFileName, "%d.%d.txt", &major, &minor) == 2)
							patch = 0;
						else
						{
							// unknown version
							major = 0;
							minor = 0;
							patch = 0;
						}
					}
				}
				else
				{
					t.AssertKeyword(0);
					t.Next();
					if(t.MustGetInt() != 1)
						t.Throw(Format("Unknown install script version '%d'.", t.MustGetInt()));
					t.Next();
					t.AssertKeyword(1);
					t.Next();
					major = t.MustGetInt();
					t.Next();
					minor = t.MustGetInt();
					t.Next();
					patch = t.MustGetInt();
				}

				InstallScript& s = Add1(scripts);
				s.filename = data.cFileName;
				s.version = (((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF));
			}
		}
		catch(const Tokenizer::Exception& e)
		{
			Warn("Unknown install script '%s': %s", data.cFileName, e.ToString());
		}
	} while(FindNextFile(find, &data));

	FindClose(find);

	if(scripts.empty())
		return true;

	std::sort(scripts.begin(), scripts.end());

	GetModuleFileName(nullptr, BUF, 256);
	char buf[512], buf2[512];
	char* filename;
	GetFullPathName(BUF, 512, buf, &filename);
	*filename = 0;
	DWORD len = strlen(buf);

	LocalString s, s2;

	for(vector<InstallScript>::iterator it = scripts.begin(), end = scripts.end(); it != end; ++it)
	{
		cstring path = Format("%s/install/%s", g_system_dir.c_str(), it->filename.c_str());

		try
		{
			if(!t.FromFile(path))
			{
				Error("Failed to load install script '%s'.", it->filename.c_str());
				continue;
			}
			Info("Using install script %s.", it->filename.c_str());

			t.Next();
			t.AssertKeyword();
			if(t.MustGetKeywordId() == 0)
			{
				// skip install 1, version X Y Z W
				t.Next();
				t.AssertInt();
				t.Next();
				t.AssertKeyword(1);
				t.Next();
				t.AssertInt();
				t.Next();
				t.AssertInt();
				t.Next();
				t.AssertInt();
				t.Next();
				t.AssertInt();
				t.Next();
			}

			while(true)
			{
				if(t.IsEof())
					break;
				t.AssertKeyword(2);

				t.Next();
				s2 = t.MustGetString();

				if(GetFullPathName(s2->c_str(), 512, buf2, nullptr) == 0 || strncmp(buf, buf2, len) != 0)
				{
					Error("Invalid file path '%s'.", s2->c_str());
					return false;
				}

				DeleteFile(buf2);
				t.Next();
			}

			DeleteFile(path);
		}
		catch(cstring err)
		{
			Error("Failed to parse install script '%s': %s", path, err);
		}
	}

	return true;
}
示例#25
0
int main() {
	int n1 = Add1(1,2);
	int n2 = Add2(1,2);
}
示例#26
0
//=================================================================================================
void PickServerPanel::Update(float dt)
{
	// update gui
	for(int i=0; i<2; ++i)
	{
		bts[i].mouse_focus = focus;
		bts[i].Update(dt);
	}

	grid.focus = focus;
	grid.Update(dt);

	if(!focus)
		return;

	if(Key.Focus() && Key.PressedRelease(VK_ESCAPE))
	{
		Event((GuiEvent)(GuiEvent_Custom+BUTTON_CANCEL));
		return;
	}

	// ping servers
	ping_timer -= dt;
	if(ping_timer < 0.f)
	{
		ping_timer = 1.f;
		game->peer->Ping("255.255.255.255", (word)game->mp_port, true);
	}

	// listen for packets
	RakNet::Packet* packet;
	for(packet=game->peer->Receive(); packet; game->peer->DeallocatePacket(packet), packet=game->peer->Receive())
	{
		switch(packet->data[0])
		{
		case ID_UNCONNECTED_PONG:
			{
				BitStream s(packet->data+5, packet->length-5, false);
				char sign[2];
				if(!ReadStruct(s, sign))
				{
					WARN(Format("Unknown response from %s: %s.", packet->systemAddress.ToString(), PacketToString(packet)));
					break;
				}

				if(sign[0] != 'C' || sign[1] != 'A')
				{
					WARN(Format("Unknown response from %s, it's not CaRpg server: %s.", packet->systemAddress.ToString(), PacketToString(packet)));
					break;
				}

				uint wersja, build;
				byte gracze, gracze_max, flagi;
				string nazwa;

				if(	!s.Read(wersja) ||
					!s.Read(gracze) ||
					!s.Read(gracze_max) ||
					!s.Read(flagi) ||
					!ReadString1(s, nazwa))
				{
					WARN(Format("Broken response from %s: %s.", packet->systemAddress.ToString(), PacketToString(packet)));
					break;
				}

				if(!s.Read(build))
					build = 0;

				bool valid_version = (wersja == WERSJA && build == g_build);

				// szukaj serwera w bazie
				bool jest = false;
				int index = 0;
				for(vector<ServerData>::iterator it = servers.begin(), end = servers.end(); it != end; ++it, ++index)
				{
					if(it->adr == packet->systemAddress)
					{
						jest = true;
						// aktualizuj
						it->name = nazwa;
						it->players = gracze;
						it->max_players = gracze_max;
						it->flags = flagi;
						it->timer = 0.f;
						it->valid_version = valid_version;

						if(game->pick_autojoin && it->players != it->max_players && it->valid_version)
						{
							bts[0].state = Button::NONE;
							game->pick_autojoin = false;
							grid.selected = index;
							Event(GuiEvent(GuiEvent_Custom+BUTTON_OK));
						}

						break;
					}
				}

				if(!jest)
				{
					// nie ma, dodaj
					ServerData& sd = Add1(servers);
					sd.name = nazwa;
					sd.players = gracze;
					sd.max_players = gracze_max;
					sd.adr = packet->systemAddress;
					sd.flags = flagi;
					sd.timer = 0.f;
					sd.valid_version = valid_version;
					grid.AddItem();

					if(game->pick_autojoin && sd.players != sd.max_players && sd.valid_version)
					{
						bts[0].state = Button::NONE;
						game->pick_autojoin = false;
						grid.selected = servers.size()-1;
						Event(GuiEvent(GuiEvent_Custom+BUTTON_OK));
					}
				}
			}
			break;
		default:
			LOG(Format(txUnknownPacket, packet->data[0], packet->systemAddress.ToString(), PacketToString(packet)));
			break;
		}
	}

	// update servers
	int index = 0;
	for(vector<ServerData>::iterator it = servers.begin(), end = servers.end(); it != end;)
	{
		it->timer += dt;
		if(it->timer >= 2.f)
		{
			grid.RemoveItem(index);
			it = servers.erase(it);
			end = servers.end();
		}
		else
		{
			++it;
			++index;
		}
	}

	if(grid.selected == -1 || !servers[grid.selected].valid_version)
		bts[0].state = Button::DISABLED;
	else if(bts[0].state == Button::DISABLED)
		bts[0].state = Button::NONE;
}
示例#27
0
//=================================================================================================
// Get area levels for selected location and level (in multilevel dungeon not generated levels are ignored for -1)
// Level have special meaning here
// >= 0 (dungeon_level, building index)
// -1 whole location
// -2 outside part of city/village
LevelAreaContext* Game::ForLevel(int loc, int level)
{
	LevelAreaContext* lac = LevelAreaContextPool.Get();
	lac->refs = 1;
	lac->entries.clear();

	bool active = (current_location == loc);
	Location* l = locations[loc];
	assert(l->state >= LS_ENTERED);

	switch(l->type)
	{
	case L_CITY:
		{
			City* city = (City*)l;
			if(level == -1)
			{
				lac->entries.resize(city->inside_buildings.size() + 1);
				LevelAreaContext::Entry& e = lac->entries[0];
				e.active = active;
				e.area = city;
				e.level = -2;
				e.loc = loc;
				for(int i = 0, len = (int)city->inside_buildings.size(); i < len; ++i)
				{
					LevelAreaContext::Entry& e2 = lac->entries[i + 1];
					e2.active = active;
					e2.area = city->inside_buildings[i];
					e2.level = i;
					e2.loc = loc;
				}
			}
			else if(level == -2)
			{
				LevelAreaContext::Entry& e = Add1(lac->entries);
				e.active = active;
				e.area = city;
				e.level = -2;
				e.loc = loc;
			}
			else
			{
				assert(level >= 0 && level < (int)city->inside_buildings.size());
				LevelAreaContext::Entry& e = Add1(lac->entries);
				e.active = active;
				e.area = city->inside_buildings[level];
				e.level = level;
				e.loc = loc;
			}
		}
		break;
	case L_CAVE:
	case L_DUNGEON:
	case L_CRYPT:
		{
			InsideLocation* inside = (InsideLocation*)l;
			if(inside->IsMultilevel())
			{
				MultiInsideLocation* multi = (MultiInsideLocation*)inside;
				if(level == -1)
				{
					lac->entries.resize(multi->generated);
					for(int i = 0; i < multi->generated; ++i)
					{
						LevelAreaContext::Entry& e = lac->entries[i];
						e.active = (active && dungeon_level == i);
						e.area = &multi->levels[i];
						e.level = i;
						e.loc = loc;
					}
				}
				else
				{
					assert(level >= 0 && level < multi->generated);
					LevelAreaContext::Entry& e = Add1(lac->entries);
					e.active = (active && dungeon_level == level);
					e.area = &multi->levels[level];
					e.level = level;
					e.loc = loc;
				}
			}
			else
			{
				assert(level == -1 || level == 0);
				SingleInsideLocation* single = (SingleInsideLocation*)inside;
				LevelAreaContext::Entry& e = Add1(lac->entries);
				e.active = active;
				e.area = single;
				e.level = 0;
				e.loc = loc;
			}
		}
		break;
	case L_FOREST:
	case L_MOONWELL:
	case L_ENCOUNTER:
	case L_ACADEMY:
	case L_CAMP:
		{
			assert(level == -1);
			OutsideLocation* outside = (OutsideLocation*)l;
			LevelAreaContext::Entry& e = Add1(lac->entries);
			e.active = active;
			e.area = outside;
			e.level = -1;
			e.loc = loc;
		}
		break;
	default:
		assert(0);
		break;
	}

	return lac;
}