/** * Sett ned helsen til spilleren etter skade utført av en annen spiller * @param int $miste_helse hvor mye helse som skal settes ned * @param player $up spilleren som forårsaker dette * @param int $attack_type hva slags angrep det var (0=drapsforsøk, 1=utpressing) * @param float $skadeprosent skadeprosenten ved et angrep * @param int $bullets antall kuler benyttet i angrep */ public function health_decrease($miste_helse, player $up, $attack_type, $skadeprosent = null, $params = array()) { // lås spillerene $up->lock(); $this->lock(); // allerede død? if (!$this->active) { $up->lock_commit(); $this->lock_commit(); return false; } $miste_helse = (int) $miste_helse; $attack_type = (int) $attack_type; // dør spilleren? if ($this->data['up_health'] <= $miste_helse) { // gi rankpoeng $rankpoeng = $up->health_calc_rankpoints($this, true, $skadeprosent); if ($rankpoeng > 0) { $rankpoeng = $this->calc_rankpoints_get($rankpoeng); $up->increase_rank($rankpoeng, false, true); } // oppdater ff-stats $this->attacked_ff_update("killed"); // drep offeret $ret = $this->dies(true, $up); if (!$ret) { $up->lock_commit(); $this->lock_commit(); return false; } // gi angriper pengene offeret hadde på hånden $cash = 0; if ($this->data['up_cash'] > 0) { \Kofradia\DB::get()->exec("UPDATE users_players SET up_cash = up_cash - {$this->data['up_cash']} WHERE up_id = {$this->id}"); \Kofradia\DB::get()->exec("UPDATE users_players SET up_cash = up_cash + {$this->data['up_cash']} WHERE up_id = {$up->id}"); $cash = $this->data['up_cash']; $this->data['up_cash'] = 0; $up->data['up_cash'] += $cash; } // øk telleren over antall drap \Kofradia\DB::get()->exec("UPDATE users_players SET up_attack_killed_num = up_attack_killed_num + 1 WHERE up_id = {$up->id}"); // øk telleren over antall drap i familien spilleren er medlem i $up->attack_ff_update("killed"); $ret = array_merge($ret, array("drept" => true, "rankpoeng" => $rankpoeng, "penger" => $cash)); } else { $ret = array(); // hent alle FF angriperen er medlem av eller nylig var medlem av $ff_ids = $this->get_ff_id_list(); // sett ny energi og helse for offeret $set = ""; $energi_mistet = $this->data['up_energy']; if ($skadeprosent !== null) { $r = 1 - 0.4 * $skadeprosent; $set = "up_energy = up_energy * {$r}, "; $this->data['up_energy'] = round($this->data['up_energy'] * $r); } $energi_mistet = $energi_mistet - $this->data['up_energy']; // lagre energi, helse og angriper-FF $time = time(); \Kofradia\DB::get()->exec("\n\t\t\t\tUPDATE users_players\n\t\t\t\tSET {$set}up_health = up_health - {$miste_helse},\n\t\t\t\t\tup_attacked_time = {$time}, up_attacked_up_id = {$up->id},\n\t\t\t\t\tup_attacked_ff_id_list = " . \Kofradia\DB::quote(implode(",", $ff_ids)) . ",\n\t\t\t\t\tup_health_ff_time = IF(up_health_ff_time IS NULL, up_health_ff_time, IF(up_health / up_health_max >= " . self::FF_HEALTH_LOW . ", IF(up_health_ff_time = 0, {$time}, up_health_ff_time), 0))\n\t\t\t\tWHERE up_id = {$this->id}"); $this->data['up_health'] -= $miste_helse; $this->data['up_attacked_time'] = $time; $this->data['up_attacked_up_id'] = $up->id; $ret['drept'] = false; $ret['rankpoeng'] = 0; $ret['rankpoeng_lost'] = 0; // sett ny beskyttelse på offeret $prot_mistet = ""; $ret['protection_replaced'] = false; if ($this->protection->data) { $prot_skadeprosent = $skadeprosent === null ? 0.02 : $skadeprosent; // bruk 2 % som skadeprosent hvis det ikke er angitt (utpressing) $prot_mistet = $this->protection->weakened($prot_skadeprosent); if ($prot_mistet === false) { $ret['protection_replaced'] = true; $prot_mistet = ""; } else { $prot_mistet = round($prot_mistet, 5); } } // rettet drapsforsøk? $rankpoeng = 0; if ($attack_type == self::ATTACK_TYPE_KILL) { // flytte til tilfeldig bydel $moved = false; if ($this->data['up_health'] / $this->data['up_health_max'] < self::HEALTH_MOVE_AUTO) { // finn en tilfeldig bydel $result = \Kofradia\DB::get()->query("SELECT id, name FROM bydeler WHERE active = 1 AND id != {$this->data['up_b_id']} ORDER BY RAND()"); $moved_from = array("id" => $this->data['up_b_id'], "name" => $this->bydel['name']); $moved = $result->fetch(); $this->data['up_b_id'] = $moved['id']; unset($this->bydel); \Kofradia\DB::get()->exec("UPDATE users_players SET up_b_id = {$moved['id']} WHERE up_id = {$this->id}"); } // mister penger $ret['penger'] = round($this->data['up_cash'] * $miste_helse / $this->data['up_health_max']); $extra = ""; if ($ret['penger'] > 0) { $up->data['up_cash'] = bcadd($up->data['up_cash'], $ret['penger']); $extra = ", up_cash = up_cash + {$ret['penger']}"; $this->data['up_cash'] = bcsub($this->data['up_cash'], $ret['penger']); \Kofradia\DB::get()->exec("UPDATE users_players SET up_cash = up_cash - {$ret['penger']} WHERE up_id = {$this->id}"); } // behandle etterlyst $ret['hitlist'] = etterlyst::player_hurt($this, $up, $miste_helse / $this->data['up_health_max']); // øk telleren over antall mislykkede drapsforsøk for angriper \Kofradia\DB::get()->exec("UPDATE users_players SET up_attack_damaged_num = up_attack_damaged_num + 1{$extra} WHERE up_id = {$up->id}"); // øk telleren over antall mislykkede drapsforsøk i familien spilleren er medlem i $up->attack_ff_update("damaged"); // oppdater ff-stats $this->attacked_ff_update("damaged"); // juster rankpoeng $rankpoeng_lost = $up->health_calc_rankpoints($this, false, $skadeprosent); if ($rankpoeng_lost > 0) { $rankpoeng = $this->calc_rankpoints_get($rankpoeng_lost); $up->increase_rank($rankpoeng, false, true, null, "attack"); $this->increase_rank(-$rankpoeng_lost, false, true, -$rankpoeng, "attack"); } // informer spilleren på e-post $email = new email(); $email->text = 'Hei, Din spiller ' . $this->data['up_name'] . ' har blitt angrepet av en annen spiller og du har blitt skadet. Spilleren har nå ' . game::format_num($this->get_health_percent(), 2) . ' % helse' . ($this->protection->data ? ', ' : ' og ') . game::format_num($this->get_energy_percent(), 2) . ' % energi' . ($this->protection->data ? ' og ' . game::format_num($this->get_protection_percent(), 2) . ' % beskyttelse' : '') . '. Pass på så du ikke risikerer at spilleren blør ihjel! -- www.kofradia.no'; $email->send($this->user->data['u_email'], "Din spiller {$this->data['up_name']} har blitt angrepet"); // hendelse for spilleren $note_data = array(round($miste_helse / $this->data['up_health_max'], 5), round($energi_mistet / $this->data['up_energy_max'], 5), $prot_mistet, $rankpoeng, round($this->data['up_health'] / $this->data['up_health_max'], 5), round($this->data['up_energy'] / $this->data['up_energy_max'], 5), $this->protection->data ? round($this->data['up_protection_state'], 5) : "", $this->data['up_points'], $moved ? urlencode($moved_from['name']) : "", $moved ? urlencode($moved['name']) : "", $ret['penger']); $this->add_log("attacked", implode(":", $note_data), 0); $ret['rankpoeng'] = $rankpoeng; $ret['rankpoeng_lost'] = $rankpoeng_lost; $ret['health_lost_p'] = $note_data[0]; $ret['energy_lost_p'] = $note_data[1]; $ret['protection_lost_p'] = $note_data[2]; $ret['health_lost'] = $miste_helse; $ret['energy_lost'] = $energi_mistet; $ret['health_new_p'] = $note_data[4]; $ret['energy_new_p'] = $note_data[5]; $ret['protection_new_p'] = $note_data[6]; } // så lite helse at spilleren mister medlemskap i familie/firma if ($this->data['up_health'] / $this->data['up_health_max'] < self::FF_HEALTH_LOW) { $ret = array_merge($ret, $this->release_relations_low_health(null, $up, true)); } } // behandle vitner // hvis det er en utpressing er det kun vitner hvis spilleren dør $vitner_id = array(); $vitner = array(); $vitner_log = array(); $r = rand(1, 100); if ($r >= 20 && ($ret['drept'] || $attack_type != self::ATTACK_TYPE_UTPRESSING)) { // antall vitner $antall = 1; if ($ret['drept']) { if ($r >= 40) { $antall++; } if ($r >= 60) { $antall++; } if ($r >= 80) { $antall++; } } else { if ($r >= 60) { $antall++; } } // hent ut tilfeldige vitner $timelimit = time() - 86400; // vitnet må ha vært pålogget siste 24 timene // hent ut tilfeldige vitner $result = \Kofradia\DB::get()->query("\n\t\t\t\tSELECT up_id\n\t\t\t\tFROM users_players\n\t\t\t\tWHERE up_access_level != 0 AND up_access_level < " . ess::$g['access_noplay'] . " AND up_b_id = {$up->data['up_b_id']} AND up_id NOT IN ({$up->id}, {$this->id}) AND up_last_online >= {$timelimit} AND up_brom_expire < " . time() . " AND up_fengsel_time < " . time() . "\n\t\t\t\tORDER BY RAND()\n\t\t\t\tLIMIT {$antall}"); while ($row = $result->fetch()) { $up_vitne = player::get($row['up_id']); $row = array("up" => $up_vitne, "visible" => rand(1, 100) >= 70); // send hendelse til vitne // drept:attack_type:ble_sett:offer_up_id (num = angriper) $up_vitne->add_log("vitne", ($ret['drept'] ? 1 : 0) . ":{$attack_type}:" . ($row['visible'] ? 1 : 0) . ":" . $this->id, $up->id); $vitner_id[] = $up_vitne->id; $vitner[] = $row; $vitner_log[] = array($up_vitne->id, $row['visible']); } } // hent medlemmer av familie til offeret og sjekk om de skal være vitner if ($ret['drept'] || $attack_type != self::ATTACK_TYPE_UTPRESSING) { // sett opp liste $ids = array(); $list = $this->get_ff_list(); foreach ($list as $row) { if ($row['ff_is_crew'] != 0 || $row['ff_type'] != ff::TYPE_FAMILIE) { continue; } $ids[] = $row['ff_id']; } if (count($ids) > 0) { $limit = 21600; // pålogget innen 6 timer $expire = time() - $limit; $result = \Kofradia\DB::get()->query("\n\t\t\t\t\tSELECT DISTINCT up_id, up_last_online\n\t\t\t\t\tFROM ff_members\n\t\t\t\t\t\tJOIN users_players ON ffm_up_id = up_id AND up_b_id = {$up->data['up_b_id']} AND up_last_online > {$expire}\n\t\t\t\t\tWHERE ffm_ff_id IN (" . implode(",", $ids) . ") AND ffm_status = " . ff_member::STATUS_MEMBER . " AND ffm_up_id NOT IN ({$this->id}, {$up->id})"); while ($row = $result->fetch()) { // er allerede vitne if (in_array($row['up_id'], $vitner_id)) { continue; } // beregn sannsynlighet $prob = min($limit, $row['up_last_online'] - $expire) / $limit * 0.8; // 80 % maks sannsynlighet hvis pålogget akkurat nå // sjekk sannsynlighet if (round($prob * 1000) < rand(1, 1000)) { continue; } $up_vitne = player::get($row['up_id']); $row = array("up" => $up_vitne, "visible" => rand(1, 100) >= 70); // send hendelse til vitne // drept:attack_type:ble_sett:offer_up_id (num = angriper) $up_vitne->add_log("vitne", ($ret['drept'] ? 1 : 0) . ":{$attack_type}:" . ($row['visible'] ? 1 : 0) . ":" . $this->id, $up->id); $vitner[] = $row; $vitner_log[] = array($up_vitne->id, $row['visible']); } } } $ret['vitner'] = $vitner; if ($params && is_array($params)) { $ret = array_merge($ret, $params); } // lagre logg $ret['bullets'] = isset($ret['bullets']) ? (int) $ret['bullets'] : 0; $this->attack_log($ret, $attack_type, $vitner_log, $up); // trigger for offer if (!$ret['drept'] && $attack_type == self::ATTACK_TYPE_KILL) { $this->trigger("attacked", array("attack" => $ret, "up" => $up)); } $up->lock_commit(); $this->lock_commit(); return $ret; }
/** * Kjøpe ut en spiller */ protected function show_free_player() { $up_id = (int) getval("free"); // hent informasjon om spilleren $expire = etterlyst::get_freeze_expire(); $result = \Kofradia\DB::get()->query("\n\t\t\tSELECT SUM(hl_amount_valid) AS sum_hl_amount_valid, SUM(IF(hl_time < {$expire}, hl_amount_valid, 0)) AS sum_can_remove\n\t\t\tFROM hitlist\n\t\t\tWHERE hl_up_id = {$up_id}\n\t\t\tGROUP BY hl_up_id"); $hl = $result->fetch(); if (!$hl) { ess::$b->page->add_message('Spilleren <user id="' . $hl['hl_up_id'] . '" /> har ingen dusør på seg.', "error"); redirect::handle("etterlyst"); } // kan ikke kjøpe ut noe? if ($hl['sum_can_remove'] == 0) { ess::$b->page->add_message('Du må vente lenger for å kunne kjøpe ut dusøren til <user id="' . $up_id . '" />.', "error"); redirect::handle("etterlyst"); } $least = min(max(etterlyst::MIN_AMOUNT_BUYOUT, etterlyst::MIN_AMOUNT_BUYOUT_RATIO * $hl['sum_can_remove']), $hl['sum_can_remove']); // kjøpe ut? if (isset($_POST['amount'])) { $amount = game::intval($_POST['amount']); // under minstebeløpet? if ($amount < $least) { ess::$b->page->add_message("Beløpet kan ikke være mindre enn " . game::format_cash($least) . ".", "error"); } else { // beregn kostnad $m = $up_id == $this->up->id ? 3 : 2; $result = \Kofradia\DB::get()->query("SELECT {$amount} * {$m}, {$amount} > {$hl['sum_can_remove']}, {$amount} * {$m} > " . $this->up->data['up_cash']); $row = $result->fetch(\PDO::FETCH_NUM); $price = $row[0]; // for høyt beløp? if ($row[1]) { ess::$b->page->add_message("Beløpet var for høyt.", "error"); } elseif ($row[2]) { ess::$b->page->add_message("Du har ikke nok penger på hånda. Du må ha " . game::format_cash($price) . " på hånda for å kunne betale ut " . game::format_cash($amount) . ".", "error"); } else { \Kofradia\DB::get()->beginTransaction(); // forsøk å trekk fra pengene $a = \Kofradia\DB::get()->exec("UPDATE users_players SET up_cash = up_cash - {$price} WHERE up_id = " . $this->up->id . " AND up_cash >= {$price}"); if ($a == 0) { ess::$b->page->add_message("Du har ikke nok penger på hånda. Du må ha " . game::format_cash($price) . " på hånda for å kunne betale ut " . game::format_cash($amount) . ".", "error"); \Kofradia\DB::get()->commit(); } else { // forsøk å trekk fra pengene fra hitlist \Kofradia\DB::get()->exec("SET @t := {$amount}"); \Kofradia\DB::get()->exec("\n\t\t\t\t\t\t\tUPDATE hitlist h, (\n\t\t\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\t\t\thl_id,\n\t\t\t\t\t\t\t\t\tGREATEST(0, LEAST(@t, hl_amount_valid)) AS to_remove,\n\t\t\t\t\t\t\t\t\t@t := GREATEST(0, @t - hl_amount_valid)\n\t\t\t\t\t\t\t\tFROM hitlist\n\t\t\t\t\t\t\t\tWHERE hl_up_id = {$up_id} AND @t > 0 AND hl_time < {$expire}\n\t\t\t\t\t\t\t\tORDER BY hl_time DESC\n\t\t\t\t\t\t\t) r\n\t\t\t\t\t\t\tSET h.hl_amount_valid = h.hl_amount_valid - to_remove\n\t\t\t\t\t\t\tWHERE h.hl_id = r.hl_id"); \Kofradia\DB::get()->exec("DELETE FROM hitlist WHERE hl_amount_valid = 0"); // har vi noe til overs? $result = \Kofradia\DB::get()->query("SELECT @t"); $a = $result->fetchColumn(0); if ($a > 0) { \Kofradia\DB::get()->rollback(); ess::$b->page->add_message("Beløpet var for høyt.", "error"); } else { \Kofradia\DB::get()->commit(); putlog("LOG", "ETTERLYST: " . $this->up->data['up_name'] . " kjøpte ut dusør for UP_ID={$up_id} på " . game::format_cash($amount) . '. Betalte ' . game::format_cash($price) . '.'); if ($up_id == $this->up->id) { ess::$b->page->add_message("Du kjøpte ut en dusør på " . game::format_cash($amount) . ' for deg selv. Du måtte betale ' . game::format_cash($price) . ' for dette.'); } else { ess::$b->page->add_message("Du kjøpte ut en dusør på " . game::format_cash($amount) . ' for <user id="' . $up_id . '" />. Du måtte betale ' . game::format_cash($price) . ' for dette.'); } redirect::handle("etterlyst"); } } } } } ess::$b->page->add_js_domready('$("select_amount").focus();'); echo ' <div class="bg1_c xxsmall"> <h1 class="bg1">Etterlyst - kjøp ut spiller<span class="left2"></span><span class="right2"></span></h1> <div class="bg1"><boxes /> <dl class="dd_right"> <dt>Spiller</dt> <dd><user id="' . $up_id . '" /></dd> <dt>Total dusør</dt> <dd>' . game::format_cash($hl['sum_hl_amount_valid']) . '</dd> <dt>Dusør som kan kjøpes ut</dt> <dd>' . game::format_cash($hl['sum_can_remove']) . '</dd> </dl> <form action="" method="post"> <input type="hidden" name="up_id" value="' . $up_id . '" /> <dl class="dd_right"> <dt>Dusør å kjøpe ut</dt> <dd><input type="text" name="amount" id="select_amount" value="' . htmlspecialchars(postval("amount", game::format_cash($hl['sum_can_remove']))) . '" class="styled w100" /></dd> </dl> <p class="c">' . show_sbutton("Kjøp ut") . '</p> <p class="c"><a href="etterlyst">Avbryt</a> - <a href="etterlyst?add">Velg en annen spiller</a></p> <p>' . ($up_id == $this->up->id ? 'Du må betale 3 ganger beløpet du velger å kjøpe ut for når du kjøper ut deg selv.' : 'Du må betale det dobbelte av beløpet du velger å kjøpe ut en annen spiller for.') . '</p> </form> </div> </div>'; }