MMO-k és az Ő addonjaik

Már az idejét sem tudom mikor kezdtem el foglalkozni az MMORPG kel, de azóta rengeteget tanultam róluk. Mondhatom szerencsémre.
Jelenlegi írásomban nem a játékokról, hanem a hozzájuk tartozó addonokról szeretnék pár szót szólni. Eléggé sok MMO val volt már dolgom az elmúlt években, ezek közül természetesen mi lehetne az, ami a legtöbb időmet elvette és a mai napig is szép emlékeket társítok hozzá? (nem, nem a Hello Kitty Online) Természetesen a World Of Warcraft. Eme nagyszerű játék volt az első az életembe, Ő volt, aki behúzott az MMO-k, a Raidek, a BG-k világába, és Ő volt az, aki megismertette velem az Addonok-at is.

Azt hiszem mondhatom azt, hogy a WoW volt az alapozó, hisz legyen szó bármilyen MMO ról, az addon rendszer szinte teljesen ugyan az, mint a WoW -é. Ugyan az a scriptnyelv, ugyan azok a függvények, ugyan az a felépítés, így nem lenne csoda, ha az addonok minden ilyen stílusú játékban gomba mód szaporodnának, de ellenben az elvárással, a mai napig a WoW az, aki hatalmas addon adatbázissal rendelkezik, míg a többiek több ezerrel szorulnak mögé!

Egy nagyon hasznos oldal a Curse.com, ami az általam ismert legjobb, legigényesebb, legjobban használható és legnagyobb addon adatbázis, a WoW -nak 5.001, a 2. helyezett Warhammer Online nak pedig 199 addonja van!

A mostani addon fabrikálást egy régi WoW os addonommal fogom bemutatni, amit annak idején még drága barátom Taszi unszolására csináltam a Burning Crusade idején (de régen is volt … :))
Azóta sok víz folyt le a Dunán, de remélem még ma is működik.

Az addon neve: CritKing (WoW link: http://www.curse.com/addons/wow/crtkng, Rift link: http://www.curse.com/addons/rift/riftcritking)

Az alap működése az, hogy számolja a kritikus ütéseket és az egymás utáni győzelmeket egy harcban és annak megfelelő üzenetet ír ki, vagy épp játszik le egy hangot. Jelenleg Runes Of Magic -hez készül a legfrissebb verziója.

Scriptnyelv

Az addonok nyelve a LUA. Erről a nyelvről volt már szó itt a blogomon ( #1 #2 ), én kifejezetten szeretem, hisz nagyon könnyen használható, jól átlátható, és ha az ember sikeresen beintegrálja a C/C++ kódjába (vagy használ valami egyszerű interfacet), akkor már az összeköttetés és oda vissza hívás is egyszerű és kényelmes.

Talán ez az oka annak, hogy a Blizzard is (és utánna mások is) ezt a nyelvet választották.

 

FrameXML

http://www.wowwiki.com/FrameXML

Na ez nem scriptnyelv, viszont annál nagyobb találmány. A modern MMO-k GUI interface ét nem úgy készítik, hogy egy grafikus megrajzolja az egészet, majd egy texturaként bekerül a játékba és láss csodát. Szerencsénkre! A megoldás a FrameXML, ami nem más, mint egy XML fájl, amiben leírják a GU-t és a hozzá tartozó vezérlő függvényeket, amik LUA ban vannak megvalósítva. Ezáltal az addon fejlesztők is szabadon módosíthatják, alakíthatják a GUI-t, sokszor teljesen átszabva a felületet! Illetve ezzel a módszerrel könnyűszerrel hozhatunk létre új GUI elemeket, növelve ezzel a játék értékét és használhatóságát.

TOC fájl

http://www.wowwiki.com/TOC_format

A TOC fájl egy speciális fájl, ami az addonnal kapcsolatos információkat tárolja. Sok MMO ebben a fájlban kisebb eltérésekkel rendelkezik, de mindegyik ugyan arra használja. Ez a fájl mondja meg a nevet, verziót, betöltendő fájlokat, stb. (Ez a Runes Of Magicre pont nem igaz, mert csak a betöltendő fájlokat tárolja, ott nincs Addon Manager interface)

Megkötések

Általánosságban nehéz bármit is mondani, hogy milyen megkötései vannak az addonoknak, de az biztos, hogy sok minden ki van kötve belőlük, biztonsági okokból. Például egyik sem tud fájlt létrehozni, törölni, módosítani, stb. Nem képesek hálózati kapcsolatot nyitni, vagy alkalmazásokat elindítani. A Blizzrdnál az addonok nem is láttak ki a telepítés könyvtárából (World of Warcraft telepítési könyvtára).

Ezek ugye a LUA moduljainak menedzselése, azaz nem töltik be az OS, IO modulokat, ezáltal a fejlesztők nem férnek hozzá ezekhez a kényes függvényekhez.

Minden más megkötés már nagyon játék függő, attól függően, hogy az adott kiadó milyen megszorításokat ír elő a farmerek és botok ellen, illetve nagyban korlátozza az addonokat, hogy ki mennyi energiát és erőforrást áldoz a belső függvények kivezetésére (a legszerényebb az Allods Online volt, főleg, hogy a dokumentáció is orosz volt :))

Lecsó

Na de vágjunk is akkor bele, mert azt ígértem, hogy itt addonban fogunk taposni! Na azért nem 🙂

CRITKINGPREFIX = "CK"
CRITKINGVERSION = "0.1.0"

CritKing = {} -- critking class :)

CritKing.__index = CritKing

CritKingDisplay = "on" -- saved variable, per character
CritKingResetOnNormalHit = "on" -- reset crit statistic when hit normal

CritKing.VariablesLoaded = false

CritKing.PlayerName = ""  -- the player's character name

CritKing.MaxDamage = 0        -- The maximum damage
CritKing.MaxCritNum = 0       -- The maximum crit number
CritKing.Damage = 0           -- The actual damage
CritKing.CritNum = 0          -- The actual critical number
CritKing.KillNum = 0          -- The actual killing blow number
CritKing.MaxKillNum = 0       -- The maximum killing blow number

CritKing.CritMessages =
{
    "Head shot!"        -- 1
  , "Oh, Yeah!"         -- 2
  , "Unstoppable!"      -- 3
  , "Killing Spree!"    -- 4
  , "Dominating!"       -- 5
  , "Ultra Kill!"       -- 6
  , "Wicked Sick!"      -- 7
  , "God Like!"         -- 8
  , "God Like!"         -- 9
  , "Holy Shit!"        -- 10
  , "Holy Shit!"        -- 11
  , "Holy Shit!"        -- 12
  , "Holy Shit!"        -- 13
  , "Holy Shit!"        -- 14
  , "Monster Kill!"     -- 15
  , "Monster Kill!"     -- 16
  , "Monster Kill!"     -- 17
  , "Monster Kill!"     -- 18
  , "Monster Kill!"     -- 19
  , "Ludicrous Kill!"   -- 20
  , "Ludicrous Kill!"   -- 21
  , "Ownage!"           -- 22
}

CritKing.CritSounds = 
{
    "Interface\\Addons\\CritKing\\sounds\\head_shot.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ohyeah.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\unstoppable.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\killer.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\dominating.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ultrakill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\wickedsick.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\godlike.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\godlike.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\holyshit.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\holyshit.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\holyshit.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\holyshit.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ludicrouskill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ludicrouskill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ownage.ogg"
}

CritKing.KillingMessages =
{
    "First Blood!"          -- 1
  , "Double Kill!"          -- 2
  , "Tripple Kill!"         -- 3
  , "Multi Kill!"           -- 4
  , "Ultra Kill!"           -- 5
  , "Mega Kill!"            -- 6
  , "Monster Kill!"         -- 7
  , "Ludicrous Kill!"       -- 8
  , "Wicked Sick!"          -- 9
  , "Holy Shit!"            -- 10
  , "God Like!"             -- 11
  , "Ownage!"               -- 12
  , "Ownage!"               -- 13
  , "Ownage!"               -- 14
  , "Ownage!"               -- 14
  , "Ownage!"               -- 15
  , "I am INVICIBLE!"       -- 16
  , "I am INVICIBLE!"       -- 17
  , "I am INVICIBLE!"       -- 18
  , "I am INVICIBLE!"       -- 19
  , "YES! I'm a GOD!"       -- 20
}

CritKing.Killingsounds =
{
    "Interface\\Addons\\CritKing\\sounds\\firstblood.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\doublekill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\tripplekill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\multikill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ultrakill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\megakill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\monsterkill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ludicrouskill.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\wickedsick.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\holyshit.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\godlike.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ownage.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ownage.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ownage.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\ownage.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\invicible.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\invicible.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\invicible.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\invicible.ogg"
  , "Interface\\Addons\\CritKing\\sounds\\god.ogg"
}

CritKing.MaxCrit = 23
CritKing.MaxKill = 21

-- Simple message function, to the default chat frame
function CritKing.SendMsg( msg )
    DEFAULT_CHAT_FRAME:AddMessage( CRITKINGPREFIX .. ": " .. msg, 1.0, 0.0, 0.0 )
end

-- Command handler
function CritKing.OnCommand( args )

    if ( ( args ~= nil      )
     and ( string.len( args ) > 0 ) )
    then
        if ( string.lower( args ) == "help" )
        then
            CritKing.SendMsg( "/ck display on  - enable error frame messages" )
            CritKing.SendMsg( "/ck display off - disable error frame messages" )
            CritKing.SendMsg( "/ck normal on - reset critical statistic when hit normal and end of fight" )
            CritKing.SendMsg( "/ck normal off - reset critical statistic just when end of fight" )
            CritKing.SendMsg( "/ck help - display this text" )
            CritKing.SendMsg( "/ck - display max damage, critical number, killing blow statistic" )
            return
        end

        if ( string.lower( args ) == "display on" )
        then
            CritKingDisplay = "on"
            CritKing.SendMsg( "set display on" )
            return
        end

        if ( string.lower( args ) == "display off" )
        then
            CritKingDisplay = "off"
            CritKing.SendMsg( "set display off" )
            return
        end

        if ( string.lower( args ) == "normal on" )
        then
            CritKingResetOnNormalHit = "on"
            CritKing.SendMsg( "reset critical statistic when hit normal" )
            return
        end

        if ( string.lower( args ) == "normal off" )
        then
            CritKingResetOnNormalHit = "off"
            CritKing.SendMsg( "no reset critical statistic when hit normal" )
            return
        end
    end     
    -- no parameters given, show the infos
    CritKing.SendMsg( " - Max damage: " .. CritKing.MaxDamage )
    CritKing.SendMsg( " - Max crit num: " .. CritKing.MaxCritNum )
    CritKing.SendMsg( " - Max kill num: " .. CritKing.MaxKillNum )
end

-- Fired when the player hit critical
function CritKing.OnCrit()
    local msg = CritKing.CritMessages[ CritKing.CritNum ]
    local sound = CritKing.CritSounds[ CritKing.CritNum ]
    
    if ( CritKingDisplay == "on" )
    then
        UIErrorsFrame:AddMessage( msg .. " (x" .. CritKing.CritNum .. ") Damage: " .. CritKing.Damage )
    end

    PlaySoundFile( sound )
end

-- Fired when the player kill an enemy
function CritKing.OnKill()
    local msg = CritKing.KillingMessages[ CritKing.KillNum ]
    local sound = CritKing.Killingsounds[ CritKing.KillNum ]
   
    if ( CritKingDisplay == "on" )
    then
        UIErrorsFrame:AddMessage( msg .. " (x" .. CritKing.KillNum .. ")" )
    end
    
    PlaySoundFile( sound )
end

-- Init function
function CritKing.OnLoad(self)
    self:RegisterEvent( "COMBAT_LOG_EVENT_UNFILTERED")
    self:RegisterEvent( "PLAYER_REGEN_DISABLED" )
    self:RegisterEvent( "PLAYER_REGEN_ENABLED" )
    self:RegisterEvent( "CHAT_MSG_COMBAT_HOSTILE_DEATH" )
    self:RegisterEvent( "VARIABLES_LOADED" )

    SlashCmdList[ "CRK_CMD" ] = CritKing.OnCommand
    SLASH_CRK_CMD1 = "/ck"
end

-- Reset critical statistric
function CritKing.ResetCrit()
	CritKing.CritNum = 0
end

-- Reset killing blow statistic
function CritKing.ResetKill()
	CritKing.KillNum = 0
end

-- Reset all statistic
function CritKing.ResetStat()
    CritKing.ResetCrit()
    CritKing.ResetKill()
end

-- Event handler
function CritKing.OnEvent( self, event, ... )
    if ( event == "VARIABLES_LOADED" ) -- loading saved variables, and player name
    then
        CritKing.VariablesLoaded = true
        CritKing.PlayerName = UnitName( "player" )
	CritKing.SendMsg( "variables loaded! " .. CRITKINGVERSION )
        return
    end

    if ( CritKing.VariablesLoaded == false ) -- no event handling, while saved variables not loaded ...
    then
    	return
    end
	
    if ( event == "COMBAT_LOG_EVENT_UNFILTERED" ) -- new event from combatlog
    then
	local timestamp, eType, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags  = ...;
        if ( sourceName == nil )
        then
            sourceName = ""
        end

	if ( sourceName ~= CritKing.PlayerName ) -- if the sender not equal with the player, just return
        then
            return
        end
        
	local fromNum = 9;
	if ( eType == "SPELL_DAMAGE" )
	then
		fromNum = 12;
	end
		
	local amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = select(fromNum, ...)
        if ( critical == nil )
        then
            critical = false
        end
       
	if ( eType == "PARTY_KILL" )
        then
            CritKing.KillNum = CritKing.KillNum + 1
		    if ( CritKing.MaxKillNum < CritKing.KillNum )
            then
                CritKing.MaxKillNum = CritKing.KillNum
            end

            if ( CritKing.KillNum < CritKing.MaxKill )
            then
                CritKing.OnKill()
            end
    
            return
        end
    
        if( critical )
        then
            CritKing.CritNum = CritKing.CritNum + 1
            CritKing.Damage = amount

            if ( amount > CritKing.MaxDamage )
            then
                CritKing.MaxDamage = amount
            end
            
            if ( CritKing.CritNum > CritKing.MaxCritNum )
            then
                CritKing.MaxCritNum = CritKing.CritNum
            end
            
            if ( CritKing.CritNum < CritKing.MaxCrit )
            then
                CritKing.OnCrit()
            end
            else
            if ( CritKingResetOnNormalHit == "on" )
            then
                CritKing.ResetCrit()
            end
        end

        return
    end
    
    if ( ( event == "PLAYER_REGEN_ENABLED" )   -- player enter, or leave from combat
      or ( event == "PLAYER_REGEN_DISABLED" ) )
    then
	    CritKing.ResetStat()
    	return
    end
end

Mondhatnám, hogy ennyi dióhéjban 🙂
De azért nézzük meg közelebbről, ha már ilyen szépen sikerült ide tennem ezt a pár oldalnyi borzalmat.

A kód eleje nem más, csak adat feltöltés, ahol megadom a hangokat és szövegeket, ez eléggé egyszerű. Habár kitérnék arra a kicsit csúnyaságra, hogy kézzel adom meg a tömb elemeinek számát

CritKing.MaxCrit = 23
CritKing.MaxKill = 21

Az oka egyszerű, a table.getn nem akart működni 🙂

Az első függvény, ami fel fog hívódni az OnLoad( self )
Rift ben a CritKing:RegisterEvent( Event.Addon.Load.End, OnLoad ) ot kellett felhívni, ahol az OnLoad az addon nevét kapta meg, míg Runes Of Magic -ben a FrameXML ben kellett megadni, hogy mi az OnLoad függvény, ahol a self helyett this -t kapott.

Apró eltérések, de érdemes feljegyezni Őket, ha valaki portolható addont akar készíteni.

Az OnLoad ezután regisztrálja az eventeket es a Slash commandot (mindjárt kitérek a Slash commandokra). Ez WoWban és ROM ban szinte teljesen ugyan az, míg a Rift ben a
CritKing:RegisterSlash( “crtk”, EvntSlash ) felhívásával értük el ugyan azt. Ez is csak apró különbség.

Alapvetően a Rift annyiban tér el a WoW és ROM tól, hogy nála egy table ban vannak az események, és ehhez adjuk hozzá a mi függvényünket is, míg a másik kettőben az eventeket stringes nevükkel regisztráljuk be.

WoW events: http://www.wowwiki.com/Events_%28API%29
ROM events: http://www.theromwiki.com/List_of_Events
Rift events:   http://wiki.riftui.com/Event

A további részek már egyszerűek, csak kezelni kell a beérkező eseményeket. Természetesen a Rift, ROM és WoW teljesen más sorrendben, teljesen másképp közli a számunkra fontos dolgokat, erre is lehet írni egy kellemes interfacet és már el is van fedve.

Egyszer ha igény / energia lesz rá kitérünk erre is 🙂

Slash Command

Ígértem, hogy írok erről is, hogy micsoda. A Slash command, ahogy a neve is mutatja a / es parancsok felsorolása, amit az addonunk kezel. Ez mindenhol megegyezett, hogy így kezelik a chatben a parancsokat, a regisztrációjuk, ahogy már említettem más és más. A lényeg viszont szintén ugyan az, 1 függvény, ami kap 1 bemenő paramétert, ami a string, a parancsunk után. Ezt kell értelmezni és lehet különféle műveleteket végezni.

Addon dokumentációk:

WoW: http://www.wowwiki.com/World_of_Warcraft_API
ROM:

Addon Tutorial: http://www.theromwiki.com/Addon_Tutorial
Eventek: http://www.theromwiki.com/List_of_Events
Függvények: http://www.theromwiki.com/List_of_Functions

Rift: http://wiki.riftui.com/Main_Page

Addon gyűjtemény: http://www.curse.com

Most ennyi lett volna, de ugye megint csak lehet zavarni a kommentekkel, annak, akit érdekel a téma 🙂

WP Pluginok

Na aki erre téved és eléggé figyelmes megfigyelhet pár újdonságot a weblapon.
Kicsit nézelődtem és telepítettem pár érdekes plugint a WordPress hez. Meglepődtem, hogy ezek a pluginok milyen jól meg vannak csinálva, de még jobban meglepődtem azon, hogy ezekből a pluginokból van ingyenes és fizetős verzió is! Persze nem mindegyik fizetős, de van.

Az új pluginok:

  • Rating-Widget – ha megnézitek a bejegyzések, hozzászólások alján megjelent 5db csillag, amivel lehet szavazni, hogy mennyire tetszik neked az adott iromány. Nagyon profi felülete van, ahol lehet állítgatni. Ez is az egyik ingyenes / fizetős plugin
  • SFC – Comment – végre nem kell belépned, hogy commentet írj a blogomra, habár eddig is csak Blekinek okozott gondot :). Mostantól elég a Facebook accountodal belépned. Ugyan ez a plugin adja a Like buttont, és minden egyébb Facebook os dolgot, teljesen ingyenes
  • SFC – Register – regisztráció a Facebook accountdal! Csak egy kattintás.
  • WPtouch – na ez egy komoly plugin! Ha bizonyos okos telefonos böngészővel érkezel Blogra, akkor nem az itt látható theme-t fogod látni, hanem a telefonodra optimalizált változatot, ami nem mellesleg nagyon igényesen néz ki, és ami kicsit még meg is lepett, hogy működött! (Phone, iPod touch, Android, Palm Pre, Samsung touch and BlackBerry Storm/Torch)

Mindegyik plugin nagyon jó, és meglepő módon mindegyik működik is. Annak idején nagyon nem értettem egyet azzal, hogy ilyen open source eszközt használjak, mindenképpen csak saját magam által írt dolgok lehettek jók, de azt mindenképpen el kell ismerni, hogy ha meg is tudnám írni ezeket a dolgokat (amiben kicsit kételkedem) akkor sem végeznék ebben az életben.

Az élet apró? örömei

Huha, egy ilyen komoly cím után mi lehet az ami történt? Hát sok minden.

Hol is kezdjem, talán annál a pontnál, amire a legbüszkébb vagyok. Nemrégiben a Curse.com om (ami a World of Warcraft nevű szerepjáték addon gyűjtő oldala) jelezték, hogy az általam írt addont nagyon várják, hogy frissítsem, mert szeretik. Ez az addon a Crit King, amit még Taszi kérésére csináltam, annak idején TBC ben. Jaj régi szép idők.

Ezzel kapcsolatos, hatalmas hír! Berni beadta a derekát is kipróbálja a WoW ot! Igen igen! már lvl3 asok vagyunk, Burning Blade szerver alli oldal. Ha tetszik neki remélem majd rá tudom venni, hogy horda oldalon játszunk, indít egy szépességes Blood Elfet és végre tudunk majd együtt játszani, szórakozni. Még nagyon az alapokat tanulja szegény, miközben én meg ott pörgök forgok körülötte, de emlékszem, hogy hát komoly küzdelem volt nekem is az első 3D –s játék, na meg a WoW is. Szóval bizakodom, reménykedem, ha minden jól megy Halálszárnyat közös erővel fogjuk elpusztítani! 🙂

Aztán … hát ez annyira nem jó hír, de végre beszéltünk egy tanácsadóval lakás ügyben, el is szomorított, de azért mondott jó dolgokat is. Először is a házhoz minimum 25% önerő kell, ami úgy 5 millió forint, mert egy normális méretű lakás úgy 20 millió körül mozog. Viszont majd csinálunk ilyen takarékossági valamit, ahová havonta fizethetünk be pénzt és 10-15 év múlva ki is vehetjük. Én még azt sem értem, hogy 10-15 év múlva hogy fog többet érni az, amit most beteszünk … (10 évvel ezelőtt valaki betett 5000 ft ot, azzal most … a … :)) nahh de hát biztos jó lesz, nálam okosabb emberek szerint, úgyhogy spórolunk. Habár meg kell legyen az új lakás 2011 nyár elejéig, mert innen menni kell, még 1 évet nem húzunk le.

Noh mi van még. Jaj filmek, filmek, filmek …
Megnéztük a Jonah Hex –et. Hát így egynek elmegy, de nem volt az igazi. Nem volt vicces mint a Vadiúj Vadnyugat, viszont hasonló mennyiségű butasággal volt megtömve. Szóval az ember elnézte, de a végét úgyis tudja. A filmben Megan Fox volt az egyetlen látni való, de hát Őt meg nézze aki nagyon unatkozik.

A másik film, amivel volt szerencsénk megismerkedni a Végrehajtók. A sztori szerint a nem messzi jövőben a 3. világháború után van egy cég, aki mű szerveket árul, hitelre akár. Aki nem tud fizetni ahhoz elmennek ilyen végrehajtó emberek és kivágják belőlük a szerveket. De semmiféle bírósági végzés, ott akár a metró közepén egy hatalmas Bowie késsel. Hát ez is egy látványos film, persze csak ha belegondolunk milyen borzalmas üzlet lenne, hogy sok sok pénzért szerveket állítasz elő, majd odaadod olyanoknak akiknek nincs pénze (hitelre), majd jó sok pénzért tartasz embereket, akik drága technikával elmennek a nem fizető nincstelenekhez visszavenni a használt szerveket … és persze mindeközben senki nem állít meg, hogy hé barátom, észnél vagy? … gyerekeket, nőket, öregeket simán kaszabolnak a filmben, mindenféle lelkiismeret furdalás nélkül. Biztos volt valami mondani valója is a filmnek (mert a főhős egyszer csak megjavul …) de a mészárlás közepette nem nagyon vettem észre. Egyszerű véres akció, egyszer meg lehet nézni, de erősen a felejtős kategória volt számomra.

A 3. film amit megnéztünk, Jackie Chan és Jet Li “filmje” A Tiltott Királyság. Hát sokat nem vártam a filmtől, csak hogy legyen kicsit vicces, tele jó verekedéssel, meg ne legyen űber brutál gagyi … nos, nem kellett csalódnom. Egyszerű, verekedős, szép kínai lányos(?) akció, jót lehet rajta szórakozni, nem ömlik a vér, nincs tele borzalmas szerelmi jelenetekkel és nem vitték túlzásba a számítógépes grafikát sem, szóval ajánlom aki egy nagyon könnyed kis kikapcsolódásra vágyik.

Huh jó sok lett, legközelebb majd rövidebbre fogom 🙂