//================================================================================================= 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; } } }
//================================================================================================= 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; } } }
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(); } }
//================================================================================================= 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; }
void test() { Assign(); Add1(); Add2(); GetBuffer(); Compare(); Mid(); }
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; }
//================================================================================================= 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); }
//============================================================================= 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; }
//================================================================================================= 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); }
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); }
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; }
//================================================================================================= 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; } } }
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); }
//================================================================================================= 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); }
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; };
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; }
//================================================================================================= 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; }
//============================================================================= 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; } }
//================================================================================================= 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; } }
//================================================================================================= 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; }
int main() { int n1 = Add1(1,2); int n2 = Add2(1,2); }
//================================================================================================= 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; }
//================================================================================================= // 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; }