Advertisement
CUgopEntity

game_sv_cs.cpp

Jan 23rd, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.91 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "game_sv_cs.h"
  3. #include "HUDManager.h"
  4. #include "stdafx.h"
  5.  
  6. cs_money::cs_money() {
  7.     string256 fn;
  8.     if (Engine.FS.Exist(fn,Path.GameData,"game_cs.ltx")) {
  9.         CInifile* ini = CInifile::Create(fn);
  10.         startup = ini->ReadINT("cs_money","startup");
  11.         win = ini->ReadINT("cs_money","win");
  12.         lose = ini->ReadINT("cs_money","lose");
  13.         draw = ini->ReadINT("cs_money","draw");
  14.         kill = ini->ReadINT("cs_money","kill");
  15.         mission = ini->ReadINT("cs_money","mission");
  16.         CInifile::Destroy   (ini);
  17.     }
  18. }
  19.  
  20. void    game_sv_CS::Create          (LPCSTR options)
  21. {
  22.     __super::Create                 (options);
  23.  
  24.     R_ASSERT2                       (rpoints[0].size(), "No respawn point for team 0");
  25.     R_ASSERT2                       (rpoints[1].size(), "No respawn point for team 1");
  26.     R_ASSERT2                       (rpoints[2].size(), "No respawn point for artifacts");
  27.  
  28.     teams.resize                    (2); // @@@ WT
  29.     timelimit   = get_option_i      (options,"timelimit",0)*60000;  // in (ms)
  30.     switch_Phase                    (GAME_PHASE_PENDING);
  31.     m_delayedRoundEnd = false;
  32. }
  33.  
  34. void game_sv_CS::SavePlayerWeapon(u32 it, CFS_Memory &store) {
  35.     xrServer *l_pServer = Level().Server;
  36.     game_PlayerState *l_pPS = get_it(it);
  37.     u32 l_chunk = 0;
  38.     NET_Packet l_packet;
  39.     CFS_Memory &l_mem = store;
  40.     xrSE_Actor *l_pActor = dynamic_cast<xrSE_Actor*>(l_pServer->ID_to_entity(get_id_2_eid(get_it_2_id(it))));
  41.     if(!l_pActor) return;
  42.     vector<u16>* l_pCilds = get_children(get_it_2_id(it));
  43.     for(u32 cit = 0; cit < l_pCilds->size(); cit++) {
  44.         xrSE_Weapon *l_pWeapon = dynamic_cast<xrSE_Weapon*>(l_pServer->ID_to_entity((*l_pCilds)[cit]));
  45.         if(!l_pWeapon) continue;
  46.         //l_pWeapon->flags
  47.         u16 id_save = l_pWeapon->ID;            // save wpn entity ID
  48.         l_pWeapon->ID = 0xffff;                 // set 0xffff to get _new gen ID
  49.         l_pWeapon->Spawn_Write(l_packet, true);
  50.         l_pWeapon->ID = id_save;                // restore wpn entity ID
  51.         l_pWeapon->state = 4;
  52.         l_mem.open_chunk((l_pActor->weapon==l_pWeapon->get_slot())?(l_pCilds->size()-(l_pPS->flags&GAME_PLAYER_FLAG_CS_HAS_ARTEFACT?2:1)):l_chunk++); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  53.     }
  54. }
  55.  
  56. void game_sv_CS::SaveDefaultWeapon(CFS_Memory &store) {     //@@@ WT: Это надо переделать, чтоб читать ltx только один раз.
  57.     string256 fn;
  58.     if (Engine.FS.Exist(fn,Path.GameData,"game_cs.ltx")) {
  59.         CInifile* ini = CInifile::Create(fn);
  60.         LPCSTR prim = ini->ReadSTRING("cs_start_Arms","primary");
  61.         u32 prim_ammo = ini->ReadINT("cs_start_Arms","primary_ammo");
  62.         LPCSTR pistol = ini->ReadSTRING("cs_start_Arms","pistol");
  63.         u32 pistol_ammo = ini->ReadINT("cs_start_Arms","pistol_ammo");
  64.         xrSE_Weapon *W_prim = 0, *W_pistol = 0;
  65.         if(prim) {
  66.             W_prim = dynamic_cast<xrSE_Weapon*>(spawn_begin(prim));
  67.             if(W_prim) {
  68.                 strcpy(W_prim->s_name_replace,prim);
  69.                 W_prim->s_flags.set(M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL);
  70.                 W_prim->ID_Parent = 0;
  71.                 W_prim->ID = 0xffff;
  72.                 W_prim->a_elapsed = W_prim->get_ammo_magsize();
  73.                 W_prim->a_current = u16(prim_ammo) * W_prim->a_elapsed;
  74.                 W_prim->state = 4;
  75.             }
  76.         }
  77.         if(pistol) {
  78.             W_pistol = dynamic_cast<xrSE_Weapon*>(spawn_begin(pistol));
  79.             if(W_pistol) {
  80.                 strcpy(W_pistol->s_name_replace,pistol);
  81.                 W_pistol->s_flags.set(M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL);
  82.                 W_pistol->ID_Parent = 0;
  83.                 W_pistol->ID = 0xffff;
  84.                 W_pistol->a_elapsed = W_pistol->get_ammo_magsize();
  85.                 W_pistol->a_current = u16(pistol_ammo) * W_pistol->a_elapsed;
  86.                 W_pistol->state = 4;
  87.             }
  88.         }
  89.         CInifile::Destroy   (ini);
  90.         u32 l_chunk = 0;
  91.         NET_Packet l_packet;
  92.         CFS_Memory &l_mem = store;
  93.         if(W_prim) {
  94.             W_prim->Spawn_Write(l_packet, true);
  95.             l_mem.open_chunk(l_chunk++); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  96.         }
  97.         if(W_pistol) {
  98.             W_pistol->Spawn_Write(l_packet, true);
  99.             l_mem.open_chunk(l_chunk); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  100.         }
  101.         if(W_prim) F_entity_Destroy(W_prim);
  102.         if(W_pistol) F_entity_Destroy(W_pistol);
  103.     }
  104. }
  105.  
  106. void game_sv_CS::SpawnArtifacts() {
  107.     vector<RPoint>&     rp  = rpoints[2];
  108.     srand               ( (unsigned)time( NULL ) );
  109.     random_shuffle      ( rp.begin( ), rp.end( ) );
  110.     for(s32 i = 0; i < 3; i++) {
  111.         xrServerEntity*     E   =   spawn_begin ("m_target_cs");                                // create SE
  112.         xrSE_Target_CS* A       =   (xrSE_Target_CS*) E;                   
  113.         A->s_flags.set          (M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL);                // flags
  114.         RPoint&             r   = rp[i];
  115.         A->o_Position.set   (r.P);
  116.         A->o_Angle.set      (r.A);
  117.         spawn_end           (A,0);
  118.     }
  119. }
  120.  
  121. void game_sv_CS::SpawnPlayer(u32 it, CFS_Memory &weapon) {
  122.     game_PlayerState *l_pPS = get_it(it);
  123.  
  124.     LPCSTR  options = get_name_it(it);
  125.     xrServerEntity *E;
  126.     if(l_pPS->flags&GAME_PLAYER_FLAG_CS_SPECTATOR) {
  127.         l_pPS->flags |= GAME_PLAYER_FLAG_VERY_VERY_DEAD;
  128.         E = spawn_begin("spectator");
  129.     } else {
  130.         E = spawn_begin(l_pPS->team?"actor_cs_2":"actor_cs_1");
  131.         xrSE_Actor *A = (xrSE_Actor*)E;                
  132.         A->s_team = u8(l_pPS->team);
  133.     }
  134.     strcpy(E->s_name_replace,get_option_s(options,"name","Player"));
  135.     E->s_flags.set(M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL|M_SPAWN_OBJECT_ASPLAYER);
  136.     vector<RPoint> &rp = rpoints[l_pPS->team];
  137.     RPoint &r = rp[it%rp.size()];
  138.     E->o_Position.set(r.P);
  139.     E->o_Angle.set(r.A);
  140.     spawn_end(E,get_it_2_id(it));
  141.  
  142.     if(!(l_pPS->flags&GAME_PLAYER_FLAG_CS_SPECTATOR)) {
  143.         NET_Packet l_packet;
  144.         CFS_Memory &l_mem = weapon;
  145.         u32 l_chunk = 0;
  146.         u16 skip_header;
  147.         CStream l_stream(l_mem.pointer(), l_mem.size()), *l_pS;
  148.         while(NULL != (l_pS = l_stream.OpenChunk(l_chunk++))) {
  149.             l_packet.B.count = l_pS->Length();
  150.             l_pS->Read(l_packet.B.data, l_packet.B.count);
  151.             l_packet.r_begin(skip_header);
  152.             Level().Server->Process_spawn(l_packet,get_it_2_id(it),true);
  153.         }
  154.     }
  155. }
  156.  
  157. void game_sv_CS::OnRoundStart() {
  158.     m_delayedRoundEnd = false;
  159.     u32 l_cnt = get_count();
  160.  
  161.     // Сохраняем оружие для следующего раунда
  162.     // Для живых - то что у них есть, для мертвых - дефолтное.
  163.     vector<CFS_Memory> l_memAr; l_memAr.resize(l_cnt);
  164.     for(u32 i = 0; i < l_cnt; i++) {
  165.         game_PlayerState *l_pPS = get_it(i);
  166.         if(l_pPS->flags&GAME_PLAYER_FLAG_CS_SPECTATOR) continue;        // Наблюдателей это не касается
  167.         if((round==-1)||(l_pPS->flags&GAME_PLAYER_FLAG_VERY_VERY_DEAD)) SaveDefaultWeapon(l_memAr[i]);
  168.         else SavePlayerWeapon(i, l_memAr[i]);
  169.     }
  170.  
  171.     __super::OnRoundStart();
  172.  
  173.     // Обновляем состаяние всех игроков и команд
  174.     if(round == 0) {
  175.         teams[0].score = teams[1].score = 0;
  176.         for(u32 i = 0; i < l_cnt; i++) {
  177.             game_PlayerState *l_pPS = get_it(i);
  178.             if(l_pPS->flags&GAME_PLAYER_FLAG_CS_SPECTATOR) continue;        // Наблюдателей это не касается
  179.             l_pPS->money_total = money.startup;
  180.             l_pPS->money_for_round = 0;
  181.             l_pPS->flags = 0;
  182.             l_pPS->deaths = 0;
  183.             l_pPS->kills = 0;
  184.         }
  185.     } else {
  186.         for(u32 i = 0; i < l_cnt; i++) {
  187.             game_PlayerState *l_pPS = get_it(i);
  188.             if(l_pPS->flags&GAME_PLAYER_FLAG_CS_SPECTATOR) continue;        // Наблюдателей это не касается
  189.             l_pPS->money_total = l_pPS->money_total + l_pPS->money_for_round;
  190.             l_pPS->money_for_round = 0;
  191.             l_pPS->flags = 0;
  192.         }
  193.     }
  194.     teams[0].num_targets = teams[1].num_targets = 0;
  195.     SpawnArtifacts();
  196.     srand((unsigned)time(NULL));
  197.     vector<RPoint> &rp1 = rpoints[0];
  198.     random_shuffle(rp1.begin(), rp1.end());
  199.     vector<RPoint> &rp2 = rpoints[0];
  200.     random_shuffle(rp2.begin(), rp2.end());
  201.     for(u32 i = 0; i < l_cnt; i++) SpawnPlayer(i, l_memAr[i]);
  202. }
  203.  
  204.  
  205. //void  game_sv_CS_OnRoundStart ()
  206. //{
  207. //  m_delayedRoundEnd = false;
  208. //  NET_Packet l_packet;
  209. //  vector<CFS_Memory> l_memAr;
  210. //  if(round!=-1) {                         // Если раунд не первый сохраняем игроков и их оружие
  211. //      xrServer *l_pServer = Level().Server;
  212. //      u32 cnt = get_count();
  213. //      l_memAr.resize(cnt);
  214. //      for(u32 it = 0; it < cnt; it++) {
  215. //          if(get_it(it)->flags&GAME_PLAYER_FLAG_VERY_VERY_DEAD) continue;
  216. //          u32 l_chunk = 0;
  217. //          CFS_Memory &l_mem = l_memAr[it];
  218. //          vector<u16>* l_pCilds = get_children(get_it_2_id(it));
  219. //          for(u32 cit = 0; cit < l_pCilds->size(); cit++) {
  220. //              xrSE_Weapon *l_pWeapon = dynamic_cast<xrSE_Weapon*>(l_pServer->ID_to_entity((*l_pCilds)[cit]));
  221. //              if(!l_pWeapon) continue;
  222. //              u16 id_save = l_pWeapon->ID;            // save wpn entity ID
  223. //              l_pWeapon->ID = 0xffff;                 // set 0xffff to get _new gen ID
  224. //              l_pWeapon->Spawn_Write(l_packet, true);
  225. //              l_pWeapon->ID = id_save;                // restore wpn entity ID
  226. //              l_mem.open_chunk(l_chunk++); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  227. //          }
  228. //      }
  229. //  }
  230. //  {
  231. //      string256 fn;
  232. //      if (Engine.FS.Exist(fn,Path.GameData,"game_cs.ltx")) {
  233. //          CInifile* ini = CInifile::Create(fn);
  234. //          LPCSTR prim = ini->ReadSTRING("cs_start_Arms","primary");
  235. //          u32 prim_ammo = ini->ReadINT("cs_start_Arms","primary_ammo");
  236. //          LPCSTR pistol = ini->ReadSTRING("cs_start_Arms","pistol");
  237. //          u32 pistol_ammo = ini->ReadINT("cs_start_Arms","pistol_ammo");
  238. //          xrSE_Weapon *W_prim = 0, *W_pistol = 0;
  239. //          if(prim) {
  240. //              W_prim = dynamic_cast<xrSE_Weapon*>(spawn_begin(prim));
  241. //              if(W_prim) {
  242. //                  strcpy(W_prim->s_name_replace,prim);
  243. //                  W_prim->s_flags = M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL;
  244. //                  W_prim->ID_Parent = 0;
  245. //                  W_prim->ID = 0xffff;
  246. //                  W_prim->a_elapsed = W_prim->get_ammo_magsize();
  247. //                  W_prim->a_current = u16(prim_ammo) * W_prim->a_elapsed;
  248. //              }
  249. //          }
  250. //          if(pistol) {
  251. //              W_pistol = dynamic_cast<xrSE_Weapon*>(spawn_begin(pistol));
  252. //              if(W_pistol) {
  253. //                  strcpy(W_pistol->s_name_replace,pistol);
  254. //                  W_pistol->s_flags = M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL;
  255. //                  W_pistol->ID_Parent = 0;
  256. //                  W_pistol->ID = 0xffff;
  257. //                  W_pistol->a_elapsed = W_pistol->get_ammo_magsize();
  258. //                  W_pistol->a_current = u16(pistol_ammo) * W_pistol->a_elapsed;
  259. //              }
  260. //          }
  261. //          CInifile::Destroy   (ini);
  262. //          u32 cnt = get_count();
  263. //          l_memAr.resize(cnt);
  264. //          for(u32 it = 0; it < cnt; it++) {
  265. //              if(!(get_it(it)->flags&GAME_PLAYER_FLAG_VERY_VERY_DEAD) && (round!=-1)) continue;
  266. //              u32 l_chunk = 0;
  267. //              CFS_Memory &l_mem = l_memAr[it];
  268. //              if(W_prim) {
  269. //                  W_prim->Spawn_Write(l_packet, true);
  270. //                  l_mem.open_chunk(l_chunk++); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  271. //              }
  272. //              if(W_pistol) {
  273. //                  W_pistol->Spawn_Write(l_packet, true);
  274. //                  l_mem.open_chunk(l_chunk); l_mem.write(l_packet.B.data, l_packet.B.count); l_mem.close_chunk();
  275. //              }
  276. //          }
  277. //          if(W_prim) F_entity_Destroy(W_prim);
  278. //          if(W_pistol) F_entity_Destroy(W_pistol);
  279. //      }
  280. //  }
  281. //
  282. //  __super::OnRoundStart   ();
  283. //
  284. //  if (0==round)  
  285. //  {
  286. //      // give $1000 to everybody
  287. //      u32     cnt = get_count();
  288. //      for     (u32 it=0; it<cnt; it++)   
  289. //      {
  290. //          game_PlayerState*   ps  =   get_it  (it);
  291. //          ps->money_total         =   1000;
  292. //          ps->money_for_round     =   0;
  293. //          ps->flags = 0;
  294. //          ps->deaths = 0;
  295. //          ps->kills = 0;
  296. //      }
  297. //  } else {
  298. //      // sum-up money for round with total
  299. //      u32     cnt = get_count();
  300. //      for     (u32 it=0; it<cnt; it++)   
  301. //      {
  302. //          game_PlayerState*   ps  =   get_it  (it);
  303. //          ps->money_total         =   ps->money_total + ps->money_for_round;
  304. //          ps->money_for_round     =   0;
  305. //          ps->flags = 0;
  306. //      }
  307. //  }
  308. //  teams[0].num_targets = teams[1].num_targets = 0;
  309. //
  310. //  // Spawn "artifacts"
  311. //  vector<RPoint>&     rp  = rpoints[2];
  312. //  srand               ( (unsigned)time( NULL ) );
  313. //  random_shuffle      ( rp.begin( ), rp.end( ) );
  314. //  for(s32 i = 0; i < 3; i++) {
  315. //      xrServerEntity*     E   =   spawn_begin ("m_target_cs");                                    // create SE
  316. //      xrSE_Target_CS* A       =   (xrSE_Target_CS*) E;                   
  317. //      A->s_flags              =   M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL;              // flags
  318. //      RPoint&             r   = rp[i];
  319. //      A->o_Position.set   (r.P);
  320. //      A->o_Angle.set      (r.A);
  321. //      spawn_end           (A,0);
  322. //  }
  323. //
  324. //  // Respawn all players and some info
  325. //  u32     cnt = get_count();
  326. //  for     (u32 it=0; it<cnt; it++)   
  327. //  {
  328. //      // init
  329. //      game_PlayerState*   ps  =   get_it  (it);
  330. //      //ps->kills             =   0;
  331. //      //ps->deaths                =   0;
  332. //
  333. //      // spawn
  334. //      LPCSTR  options         =   get_name_it (it);
  335. //      xrServerEntity*     E   =   spawn_begin (ps->team==2?"spectator":(ps->team?"actor_cs_2":"actor_cs_1"));                     // create SE
  336. //      xrSE_Actor* A           =   (xrSE_Actor*) E;                   
  337. //      strcpy                  (A->s_name_replace,get_option_s(options,"name","Player"));                  // name
  338. //      A->s_team               =   u8(ps->team);                                                           // team
  339. //      A->s_flags              =   M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL | M_SPAWN_OBJECT_ASPLAYER;// flags
  340. //      assign_RP               (A);
  341. //      spawn_end               (A,get_it_2_id(it));
  342. //
  343. //      if(l_memAr.size() > it) {
  344. //          CFS_Memory &l_mem = l_memAr[it];
  345. //          u32 l_chunk = 0;
  346. //          u16 skip_header;
  347. //          CStream l_stream(l_mem.pointer(), l_mem.size()), *l_pS;
  348. //          while(NULL != (l_pS = l_stream.OpenChunk(l_chunk++))) {
  349. //              l_packet.B.count = l_pS->Length();
  350. //              l_pS->Read(l_packet.B.data, l_packet.B.count);
  351. //              l_packet.r_begin(skip_header);
  352. //              Level().Server->Process_spawn(l_packet,get_it_2_id(it),true);
  353. //          }
  354. //      }
  355. //  }
  356. //}
  357.  
  358. void    game_sv_CS::OnRoundEnd      (LPCSTR reason)
  359. {
  360.     __super::OnRoundEnd(reason);
  361. //  u32 cnt = get_count(); for(u32 it=0; it<cnt; it++) get_it(it)->flags &= (GAME_PLAYER_FLAG_CS_SPECTATOR|GAME_PLAYER_FLAG_VERY_VERY_DEAD);
  362. }
  363.  
  364. void    game_sv_CS::OnDelayedRoundEnd       (LPCSTR reason)
  365. {
  366.     m_delayedRoundEnd = true;
  367.     m_roundEndDelay = Device.TimerAsync() + 10000;
  368. }
  369.  
  370. void    game_sv_CS::OnTeamScore     (u32 team)
  371. {
  372.     if(GAME_PHASE_INPROGRESS != phase) return;
  373.  
  374.     teams[team].score++;
  375.     // Increment/decrement money
  376.     u32     cnt = get_count();
  377.     for     (u32 it=0; it<cnt; it++)   
  378.     {
  379.         game_PlayerState*   ps  =   get_it  (it);
  380.         ps->money_for_round = ps->money_for_round + (s32(team)==ps->team)?(s16)money.win:(s16)money.lose;
  381.     }
  382.     phase = u16(team?GAME_PHASE_TEAM2_SCORES:GAME_PHASE_TEAM1_SCORES);
  383. }
  384.  
  385. void    game_sv_CS::OnTeamsInDraw   ()
  386. {
  387.     if(GAME_PHASE_INPROGRESS != phase) return;
  388.  
  389.     // Give $1000 to everybody
  390.     u32     cnt = get_count();
  391.     for     (u32 it=0; it<cnt; it++)   
  392.     {
  393.         game_PlayerState*   ps  =   get_it  (it);
  394.         ps->money_for_round = ps->money_for_round + (s16)money.draw;
  395.     }
  396.     phase = GAME_PHASE_TEAMS_IN_A_DRAW;
  397. }
  398.  
  399. void    game_sv_CS::OnPlayerKillPlayer  (u32 id_killer, u32 id_killed)
  400. {
  401.     game_PlayerState*   ps_killer   =   get_id  (id_killer);
  402.     game_PlayerState*   ps_killed   =   get_id  (id_killed);
  403.     ps_killed->flags                |=  GAME_PLAYER_FLAG_VERY_VERY_DEAD;
  404.     ps_killed->deaths               +=  1;
  405.     if (ps_killer->team == ps_killed->team)
  406.     {
  407.         // Teammate killed - no frag, chop money
  408. //      ps_killer->money_for_round  -=  500;
  409.         ps_killer->money_total  -=  money.kill; if(ps_killer->money_total < 0) ps_killer->money_total = 0;
  410.     } else {
  411.         // Opponent killed - frag + money
  412. //      ps_killer->money_for_round  +=  500;
  413.         ps_killer->money_total  +=  money.kill;
  414.         ps_killer->kills            +=  1;
  415.  
  416.     }
  417.     // Check if there is no opponents left
  418.     u32 alive                   =   get_alive_count (ps_killed->team);
  419.     if (0==alive) {
  420.         OnTeamScore(ps_killer->team);
  421.         if(get_alive_count(ps_killer->team)) OnDelayedRoundEnd("ENEMY_quelled");
  422.         else OnRoundEnd("ENEMY_quelled");/**/
  423.         signal_Syncronize();
  424.     }
  425.  
  426.     xrServer*   S                   =   Level().Server;
  427.  
  428.     // Drop everything
  429.     vector<u16>*    C               =   get_children(id_killed);
  430.     if (0==C)                       return;
  431.     while(C->size())
  432.     {
  433.         u16     eid                     = (*C)[0];
  434.  
  435.         xrServerEntity*     from        = S->ID_to_entity(get_id_2_eid(id_killed));
  436.         xrServerEntity*     what        = S->ID_to_entity(eid);
  437.         S->Perform_reject               (what,from);
  438.     }
  439.  
  440.     // spectator
  441.     xrSE_Spectator*     A           =   (xrSE_Spectator*)spawn_begin    ("spectator");                                                          // create SE
  442.     strcpy                          (A->s_name_replace,get_option_s(get_name_id(id_killed),"name","Player"));                   // name
  443.     A->s_flags.set                  (M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL | M_SPAWN_OBJECT_ASPLAYER);                  // flags
  444.     A->o_Position                   =   S->ID_to_entity(get_id_2_eid(id_killed))->o_Position;
  445.     spawn_end                       (A,id_killed);
  446. }
  447.  
  448. void    game_sv_CS::OnPlayerDisconnect  (u32 id_who)
  449. {
  450.     __super::OnPlayerDisconnect         (id_who);
  451.  
  452.     xrServer*   S                   =   Level().Server;
  453.  
  454.     // Drop everything
  455.     vector<u16>*    C               =   get_children(id_who);
  456.     if (0==C)                       return;
  457.     while(C->size())
  458.     {
  459.         u16     eid                     = (*C)[0];
  460.  
  461.         xrServerEntity*     from        = S->ID_to_entity(get_id_2_eid(id_who));
  462.         xrServerEntity*     what        = S->ID_to_entity(eid);
  463.         S->Perform_reject               (what,from);
  464.     }
  465. }
  466.  
  467. void    game_sv_CS::OnTimelimitExceed   ()
  468. {
  469.     // Если у команд поровну артефактов, то ничья.
  470.     R_ASSERT(teams.size() == 2);
  471.     if(teams[0].num_targets == teams[1].num_targets) OnTeamsInDraw();
  472.     else OnTeamScore((teams[0].num_targets > teams[1].num_targets) ? 0 : 1);
  473.     OnRoundEnd      ("TIME_limit");
  474. }
  475.  
  476. BOOL    game_sv_CS::OnTouch         (u16 eid_who, u16 eid_what)
  477. {
  478.     xrServer*           S       = Level().Server;
  479.     xrServerEntity*     e_who   = S->ID_to_entity(eid_who);     VERIFY(e_who    );
  480.     xrServerEntity*     e_what  = S->ID_to_entity(eid_what);    VERIFY(e_what   );
  481.  
  482.     xrSE_Actor*         A       = dynamic_cast<xrSE_Actor*> (e_who);
  483.     if (A)  {
  484.         // player_id = entity->owner->ID            --
  485.         // entity->owner->owner == entity           -- is this entity player
  486.  
  487.         game_PlayerState*   ps_who  =   get_id          (e_who->owner->ID);
  488.  
  489.         if(ps_who->flags&GAME_PLAYER_FLAG_VERY_VERY_DEAD) return false;
  490.  
  491.         // Actor touches something
  492.         xrSE_Weapon*    W           =   dynamic_cast<xrSE_Weapon*> (e_what);
  493.         if (W)
  494.         {
  495.             // Weapon
  496.             vector<u16>&    C           =   A->children;
  497.             u8 slot                     =   W->get_slot ();
  498.             for (u32 it=0; it<C.size(); it++)
  499.             {
  500.                 xrServerEntity*     Et  = S->ID_to_entity               (C[it]);
  501.                 if (0==Et)              continue;
  502.                 xrSE_Weapon*        T   = dynamic_cast<xrSE_Weapon*>    (Et);
  503.                 if (0==T)               continue;
  504.                 if (slot == T->get_slot()) 
  505.                 {
  506.                     // We've found same slot occupied - disallow ownership
  507.                     return FALSE;
  508.                 }
  509.             }
  510.  
  511.             // Weapon slot empty - ownership OK
  512.             return TRUE;
  513.         }
  514.  
  515.         xrSE_Target_CSBase *l_pCSBase   =   dynamic_cast<xrSE_Target_CSBase*>(e_what);
  516.         if(l_pCSBase) {
  517.             // База
  518.             if(ps_who->team == -1) ps_who->team = l_pCSBase->g_team(); // @@@ WT : Пока не сделан респавн
  519.             if(l_pCSBase->s_team == ps_who->team) {             // Если игрок пришел на свою базу
  520.                 ps_who->flags |= GAME_PLAYER_FLAG_CS_ON_BASE;
  521.             } else ps_who->flags |= GAME_PLAYER_FLAG_CS_ON_ENEMY_BASE;
  522.             return false;
  523.         }
  524.  
  525.         xrSE_Target_CS *l_pMBall =  dynamic_cast<xrSE_Target_CS*>(e_what);
  526.         if(l_pMBall) {
  527.             // Мяч
  528.             if(ps_who->flags&GAME_PLAYER_FLAG_CS_HAS_ARTEFACT)      return false;
  529.             ps_who->flags |= GAME_PLAYER_FLAG_CS_HAS_ARTEFACT;
  530.             return true;
  531.         }
  532.  
  533.         xrSE_Target_CSCask *l_pCSCask =  dynamic_cast<xrSE_Target_CSCask*>(e_what);
  534.         if(l_pCSCask) {
  535.             // Бочка
  536.             // Если игрок на своей базе и у него есть мяч
  537.             if((ps_who->flags&GAME_PLAYER_FLAG_CS_HAS_ARTEFACT) && (ps_who->flags&GAME_PLAYER_FLAG_CS_ON_BASE))     {
  538.                 l_pMBall = NULL;                                    // Отбираем у игрока мяч
  539.                 vector<u16>&    C           =   A->children;
  540.                 for (u32 it=0; it<C.size(); it++) {
  541.                     l_pMBall = dynamic_cast<xrSE_Target_CS*>(S->ID_to_entity(C[it]));
  542.                     if (l_pMBall) break;
  543.                 }
  544.                 R_ASSERT(l_pMBall);
  545.                 S->Perform_transfer(l_pMBall, A, l_pCSCask);        // Кладем мяч в бочку
  546.                 ps_who->flags &= ~GAME_PLAYER_FLAG_CS_HAS_ARTEFACT;
  547.                 teams[ps_who->team].num_targets++;
  548.                 if(teams[ps_who->team].num_targets == 3) {
  549.                     OnTeamScore(ps_who->team);
  550.                     u32 cnt = get_count();                      // Доп. бонус за выполнение задания
  551.                     for(u32 it=0; it<cnt; it++) {
  552.                         game_PlayerState* ps = get_it(it);
  553.                         if(ps->team == ps_who->team) ps->money_for_round = ps->money_for_round + (s16)money.mission;
  554.                     }                                           //
  555.                     OnDelayedRoundEnd("MISSION_complete");
  556.                 }
  557.                 signal_Syncronize();
  558.                 return false;
  559.             }
  560.             // Если игрок на чужой базе и у него нет мяча
  561.             if(!(ps_who->flags&GAME_PLAYER_FLAG_CS_HAS_ARTEFACT) && (ps_who->flags&GAME_PLAYER_FLAG_CS_ON_ENEMY_BASE))      {
  562.                 l_pMBall = NULL;                                    // Достаем мяч из бочки
  563.                 vector<u16>&    C           =   l_pCSCask->children;
  564.                 for (u32 it=0; it<C.size(); it++) {
  565.                     l_pMBall = dynamic_cast<xrSE_Target_CS*>(S->ID_to_entity(C[it]));
  566.                     if(l_pMBall) break;
  567.                 }
  568.                 if (l_pMBall){
  569.                     S->Perform_transfer(l_pMBall, l_pCSCask, A);        // Отдаем игроку
  570.                     ps_who->flags |= GAME_PLAYER_FLAG_CS_HAS_ARTEFACT;
  571.                     teams[(ps_who->team+1)%2].num_targets--;
  572.                     signal_Syncronize();
  573.                 }
  574.                 return false;
  575.             }
  576.         }
  577.     }
  578.  
  579.     // We don't know what the hell is it, so disallow ownership just for safety
  580.     return FALSE;
  581. }
  582.  
  583. BOOL    game_sv_CS::OnDetach        (u16 eid_who, u16 eid_what)
  584. {
  585.     xrServer*           S       = Level().Server;
  586.     xrServerEntity*     e_who   = S->ID_to_entity(eid_who);     VERIFY(e_who    );
  587.     xrServerEntity*     e_what  = S->ID_to_entity(eid_what);    VERIFY(e_what   );
  588.  
  589.     xrSE_Actor*         A       = dynamic_cast<xrSE_Actor*> (e_who);
  590.     if (A)  {
  591.         game_PlayerState*   ps_who  =   get_id          (e_who->owner->ID);
  592.  
  593.  
  594.         xrSE_Target_CS *l_pMBall =  dynamic_cast<xrSE_Target_CS*>(e_what);
  595.         if(l_pMBall) {
  596.             // Мяч
  597.             if(ps_who->flags&GAME_PLAYER_FLAG_CS_HAS_ARTEFACT)  {
  598.                 ps_who->flags &= ~GAME_PLAYER_FLAG_CS_HAS_ARTEFACT;
  599.                 return true;
  600.             }
  601.             return false;
  602.         }
  603.  
  604.         xrSE_Target_CSBase *l_pCSBase   =   dynamic_cast<xrSE_Target_CSBase*>(e_what);
  605.         if(l_pCSBase) {
  606.             if(l_pCSBase->s_team == ps_who->team) {             // Если игрок пришел на свою базу
  607.                 ps_who->flags &= ~GAME_PLAYER_FLAG_CS_ON_BASE;
  608.             } else ps_who->flags &= ~GAME_PLAYER_FLAG_CS_ON_ENEMY_BASE;
  609.             return false;
  610.         }
  611.  
  612.         xrSE_Target_CSCask *l_pCSCask =  dynamic_cast<xrSE_Target_CSCask*>(e_what);
  613.         if(l_pCSCask) return false;
  614.     }
  615.     return TRUE;
  616. }
  617.  
  618. void    game_sv_CS::Update          ()
  619. {
  620.     __super::Update ();
  621.     switch(phase)   {
  622.         case GAME_PHASE_TEAM1_SCORES :
  623.         case GAME_PHASE_TEAM2_SCORES :
  624.         case GAME_PHASE_TEAMS_IN_A_DRAW :
  625.         case GAME_PHASE_INPROGRESS : {
  626.             if (timelimit) if (s32(Device.TimerAsync()-u32(start_time))>timelimit) OnTimelimitExceed();
  627.             if(m_delayedRoundEnd && m_roundEndDelay < Device.TimerAsync()) OnRoundEnd("Finish");
  628.         } break;
  629.         case GAME_PHASE_PENDING : {
  630.             if ((Device.TimerAsync()-start_time)>u32(30*1000)) OnRoundStart();
  631.         } break;
  632.     }
  633. }
  634.  
  635. void    game_sv_CS::OnPlayerReady   (u32 id)
  636. {
  637.     if  (GAME_PHASE_PENDING != phase) return;
  638.  
  639.     game_PlayerState*   ps  =   get_id  (id);
  640.     if (ps)
  641.     {
  642.         if(ps->flags&GAME_PLAYER_FLAG_CS_SPECTATOR) return;
  643.         if (ps->flags & GAME_PLAYER_FLAG_READY)
  644.         {
  645.             ps->flags &= ~GAME_PLAYER_FLAG_READY;
  646.         } else {
  647.             ps->flags |= GAME_PLAYER_FLAG_READY;
  648.  
  649.             // Check if all players ready
  650.             u32     cnt     = get_count ();
  651.             u32     ready   = 0;
  652.             for     (u32 it=0; it<cnt; it++)   
  653.             {
  654.                 ps      =   get_it  (it);
  655.                 if((ps->flags&GAME_PLAYER_FLAG_READY) || (ps->flags&GAME_PLAYER_FLAG_CS_SPECTATOR)) ready++;
  656.             }
  657.  
  658.             if (ready == cnt)
  659.             {
  660.                 OnRoundStart    ();
  661.             }
  662.         }
  663.     }
  664. }
  665. void game_sv_CS::OnPlayerChangeTeam(u32 id_who, s16 team) {
  666.     if(team == 0 || team == 1) {
  667.         s16 l_old_team = get_id(id_who)->team;
  668.         get_id(id_who)->team = team;
  669.         get_id(id_who)->flags &= ~GAME_PLAYER_FLAG_CS_SPECTATOR;
  670.         if(get_alive_count(l_old_team) == 0) {
  671.             OnTeamScore((l_old_team+1)%2);
  672.             OnRoundEnd("????");
  673.         }
  674.     } else {
  675.         get_id(id_who)->flags |= GAME_PLAYER_FLAG_CS_SPECTATOR|GAME_PLAYER_FLAG_VERY_VERY_DEAD;
  676.         if(get_alive_count(0)+get_alive_count(1) == 0) OnRoundEnd("????");
  677.     }
  678. }
  679.  
  680. void game_sv_CS::OnPlayerConnect    (u32 id_who)
  681. {
  682.     __super::OnPlayerConnect    (id_who);
  683.  
  684.     LPCSTR  options         =   get_name_id (id_who);
  685.     game_PlayerState*   ps_who  =   get_id  (id_who);
  686.     ps_who->money_total     = money.startup;
  687.     ps_who->flags |= GAME_PLAYER_FLAG_VERY_VERY_DEAD;
  688.     ps_who->team            = u8(get_option_i(options,"team",AutoTeam()));
  689.     ps_who->kills               =   0;
  690.     ps_who->deaths              =   0;
  691.  
  692.     // Spawn "actor"
  693.     xrSE_Spectator*     A   =   (xrSE_Spectator*)spawn_begin    ("spectator");                                                          // create SE
  694.     strcpy                  (A->s_name_replace,get_option_s(options,"name","Player"));                  // name
  695.     A->s_flags.set          (M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL | M_SPAWN_OBJECT_ASPLAYER);  // flags
  696.     assign_RP               (A);
  697.     spawn_end               (A,id_who);
  698.  
  699.     // Даем игроку децл оружия для начала. Если игрок изначально будет коннектится как наблюдатель то все это не нужно.
  700. /*  string256 fn;
  701.     if (Engine.FS.Exist(fn,Path.GameData,"game_cs.ltx")) {
  702.         CInifile* ini = CInifile::Create(fn);
  703.         LPCSTR prim = ini->ReadSTRING("cs_start_Arms","primary");
  704.         u32 prim_ammo = ini->ReadINT("cs_start_Arms","primary_ammo");
  705.         LPCSTR pistol = ini->ReadSTRING("cs_start_Arms","pistol");
  706.         u32 pistol_ammo = ini->ReadINT("cs_start_Arms","pistol_ammo");
  707.         xrSE_Weapon *W_prim = 0, *W_pistol = 0;
  708.         if(prim) {
  709.             W_prim = dynamic_cast<xrSE_Weapon*>(spawn_begin(prim));
  710.             if(W_prim) {
  711.                 strcpy(W_prim->s_name_replace,prim);
  712.                 W_prim->s_flags = M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL;
  713.                 //W_prim->ID_Parent = A->owner->ID;
  714.                 W_prim->a_elapsed = W_prim->get_ammo_magsize();
  715.                 W_prim->a_current = u16(prim_ammo) * W_prim->a_elapsed;
  716.                 NET_Packet                      P;
  717.                 u16                             skip_header;
  718.                 W_prim->Spawn_Write                 (P,TRUE);
  719.                 P.r_begin                       (skip_header);
  720.                 Level().Server->Process_spawn   (P,id_who,true);
  721.                 F_entity_Destroy                (W_prim);
  722.             }
  723.         }
  724.         if(pistol) {
  725.             W_pistol = dynamic_cast<xrSE_Weapon*>(spawn_begin(pistol));
  726.             if(W_pistol) {
  727.                 strcpy(W_pistol->s_name_replace,pistol);
  728.                 W_pistol->s_flags = M_SPAWN_OBJECT_ACTIVE|M_SPAWN_OBJECT_LOCAL;
  729.                 W_pistol->a_elapsed = W_pistol->get_ammo_magsize();
  730.                 W_pistol->a_current = u16(pistol_ammo) * W_pistol->a_elapsed;
  731.                 NET_Packet                      P;
  732.                 u16                             skip_header;
  733.                 W_pistol->Spawn_Write                   (P,TRUE);
  734.                 P.r_begin                       (skip_header);
  735.                 Level().Server->Process_spawn   (P,id_who,true);
  736.                 F_entity_Destroy                (W_pistol);
  737.             }
  738.         }
  739.     }
  740.     */
  741. }
  742.  
  743. void game_sv_CS::OnPlayerBuy        (u32 id_who, u16 eid_who, LPCSTR what)
  744. {
  745.     __super::OnPlayerBuy    (id_who,eid_who,what);
  746.  
  747.     // cost
  748.     int cost                =   get_option_i    (what,"cost",0);
  749.     if (0==cost)            return;
  750.     int iAmmoMagCount       =   get_option_i    (what,"ammo",0);
  751.     if (iAmmoMagCount) 
  752.     {
  753.         // Buy ammo
  754.         int     slot            =   get_option_i(what,"primary") ? 1:2;
  755.  
  756.         // Search weapon slot
  757.         xrServer*       S       =   Level().Server;
  758.         vector<u16>*    C       =   get_children(id_who);
  759.         if (0==C)               return;
  760.         for (u32 it=0; it<C->size(); it++)
  761.         {
  762.             xrServerEntity*     Et  = S->ID_to_entity               ((*C)[it]);
  763.             if (0==Et)              continue;
  764.             xrSE_Weapon*        T   = dynamic_cast<xrSE_Weapon*>    (Et);
  765.             if (0==T)               continue;
  766.             if (slot == T->get_slot()) 
  767.             {
  768.                 // We've found this slot - buy something :) |  491 05 36 - Andy
  769.  
  770.                 // TO: VITYA: I didn't bother to check all conditions, money, etc. Sorry :)))
  771.                 xrSE_Weapon*        W   = T;
  772.                 u16     a_limit         = W->get_ammo_limit     ();
  773.                 u16     a_total         = W->get_ammo_total     ();
  774.                 u16     a_magsize       = W->get_ammo_magsize   ();
  775.                 while (iAmmoMagCount && (iAmmoMagCount*a_magsize+a_total)>(a_limit+a_magsize-1))    iAmmoMagCount--;
  776.                 if      (0==iAmmoMagCount)  return;
  777.                 int     a_cost          = iAmmoMagCount*cost;
  778.  
  779.                 // check if has money to pay
  780.                 game_PlayerState*   ps_who  =   get_id  (id_who);
  781.                 if(ps_who->money_total < cost)  return;
  782.                 ps_who->money_total     = ps_who->money_total - s16(a_cost);
  783.  
  784.                 // Event
  785.                 NET_Packet          P;
  786.                 u_EventGen          (P, GE_WPN_AMMO_ADD, W->ID);       
  787.                 P.w_u16             (u16(iAmmoMagCount*a_magsize+a_total)>u16(a_limit)?u16(a_limit-a_total):u16(iAmmoMagCount*a_magsize));  // Amount of ammo to add
  788.                 u_EventSend         (P);
  789.                 return;
  790.             }
  791.         }
  792.     }
  793.     else
  794.     {
  795.         // Buy weapon
  796.         // entity-name
  797.         string64                name;
  798.         strcpy                  (name,what);
  799.         if ( strchr(name,'/') ) *strchr(name,'/') = 0;
  800.  
  801.         // initialize spawn
  802.         xrServerEntity*     E   =   spawn_begin (name);                                                     // create SE
  803.         strcpy                  (E->s_name_replace,name);                                                   // name
  804.         E->s_flags.set          (M_SPAWN_OBJECT_ACTIVE  | M_SPAWN_OBJECT_LOCAL);                            // flags
  805.         E->ID_Parent            =   u16(eid_who);
  806.  
  807.         // check if has same-slot-weapon(s)
  808.         xrSE_Weapon*        W   =   dynamic_cast<xrSE_Weapon*>(E);
  809.         W->state = 4;
  810.         if (W)
  811.         {
  812.             xrServer*       S       =   Level().Server;
  813.             vector<u16>*    C       =   get_children(id_who);
  814.             if (0==C)              
  815.             {
  816.                 F_entity_Destroy    (E);
  817.                 return;
  818.             }
  819.             u8 slot                 =   W->get_slot ();
  820.             for (u32 it=0; it<C->size(); it++)
  821.             {
  822.                 xrServerEntity*     Et  = S->ID_to_entity               ((*C)[it]);
  823.                 if (0==Et)              continue;
  824.                 xrSE_Weapon*        T   = dynamic_cast<xrSE_Weapon*>    (Et);
  825.                 if (0==T)               continue;
  826.                 if (slot == T->get_slot()) 
  827.                 {
  828.                     // We've found same slot occupied - don't buy anything
  829.                     F_entity_Destroy    (E);
  830.                     return;
  831.  
  832.                     // Выбрасываем старое
  833.                     //S->Perform_reject             (T,S->ID_to_entity(eid_who));
  834.                 }
  835.             }
  836.             W->a_current = 0;
  837.             W->a_elapsed = W->get_ammo_magsize();
  838.         }
  839.  
  840.         // check if has money to pay
  841.         game_PlayerState*   ps_who  =   get_id  (id_who);
  842.         if(ps_who->money_total < cost)  { F_entity_Destroy(E); return; }
  843.         ps_who->money_total         = ps_who->money_total - s16(cost);
  844.  
  845.         // Spawn item
  846.         spawn_end               (E, id_who);
  847.     }
  848. }
  849.  
  850. u8 game_sv_CS::AutoTeam()
  851. {
  852.     u32 cnt = get_count(), l_teams[2] = {0,0};
  853.     for(u32 it=0; it<cnt; it++) {
  854.         game_PlayerState* ps = get_it(it);
  855.         if(ps->team>=0) l_teams[ps->team]++;
  856.     }
  857.     return (l_teams[0]>l_teams[1])?1:0;
  858. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement