Kampf um Resourcen. Programmieren von Gewusel

aus dem Wiki des Entropia e.V., CCC Karlsruhe
Infon.jpg

Sourcecode

Ich habe auf http://infon.dividuum.de eine vorerst minimale Seite zum Spiel eingerichtet. Dort gibt es den Sourcecode.

Wenn ihr das Spiel irgendwo laufen lasst, waere es super, wenn ihr Bilder davon an mich (Email Adresse siehe obige Seite) schickt/bei flickr postet.

Feature Requests

  • Möglichkeit für *alle* spieler, sich die Punkte anzeigen zu lassen (evtl. per Kommando "p" an der Konsole?)
    • Erm, "p" ist ja schon part game. Wie waers mit "s" (wie stats)? --codec
      • Ich baue das bei der naechsten Iteration ein --dividuum
  • mehr farben
    • done. sind jetzt 16 unterschiedliche --dividuum
  • laengere kaempfe?
    • done. nur noch halbe hitpoints bei kaempfen --dividuum
  • fuettern schneller als essen --kcarccmkcaj
  • mehr essen?
  • mehr bass!
  • blackjack und nutten!
  • kein selbstmord
    • doch. wird aber haerter bestraft.
  • server sourcen irgendwo schon zu haben ?
    • jetzt schon

Beispiel-Scripte

Blueloop V00

 --------------------------------------------------------------------------
 -- Blueloop V00 
 --
 -- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
 --------------------------------------------------------------------------

	function Creature:onSpawned()
		print("Creature " .. self.id .. " spawned")
	end
	
	function Creature:onAttacked(attacker)
		print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
	end
	
	function Creature:onKilled(killer)
		if killer == self.id then
			print("Creature " .. self.id .. " suicided")
		elseif killer then 
			print("Creature " .. self.id .. " killed by Creature " .. killer)
		else
			print("Creature " .. self.id .. " died")
		end
	end
	
	function Wait()
		while (get_state(self.id) ~= CREATURE_IDLE) do
			self:wait_for_next_round()	
		end;
	end
	
	function Creature:main()
		if self.dx == nil then self.dx = 256 end
		if self.dy == nil then self.dy = 0 end
		if victim  == nil then victim  = -1 end
		
		---------------------------------------------- Wenn ein globaler Angriff aktiv ist:
		if (victim ~= -1) and (get_type(self.id) == 1) then
			if exists(victim) then
			
				local x,y = get_pos(victim)                    -- Wo ist der angegriffene?
				self:moveto(x,y)                               -- hinlaufen
				self:attack(victim)                            -- angreifen!
			else
				victim = -1                                    -- Tot -> Angriff beenden
				print"Angriff beendet!"
			end
		end
		
	
		---------------------------------------------- Warten bis Creatur IDLE
		if get_state(self.id) ~= CREATURE_IDLE  then
			self:wait_for_next_round()
			return
		end
		
		---------------------------------------------- Wo ist der nächste Feind?
		local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)	
		
		---------------------------------------------- Wenn er nah genug ist und wir gesund sind -> angreifen
		
		if (feind_id ~= nil) and (victim == -1) then
			if (feind_dist < 8000) and (self:health() > 50) and (victim == -1) then
				print("Starte Angriff auf " .. feind_id )
				victim = feind_id
			end
		end
	
		---------------------------------------------- Fressen!
		
		if get_tile_food(self.id) > 0 then  
			set_state(self.id, CREATURE_EAT)
		else
			local x, y = self:pos()
			if not self:moveto(x+self.dx,y+self.dy) then
				self.dx = math.random(512)-256
				self.dy = math.random(512)-256
			end
		end
		
		
		if self:health() < 90 then 
			set_state(self.id, CREATURE_HEAL)
		end;
			
		if get_food(self.id) > 8000 then
			if get_type(self.id) == 0 then
				set_convert(self.id, 1)
				set_state(self.id,CREATURE_CONVERT)
			else
				set_state(self.id,CREATURE_SPAWN)
			end
		end
		
		if get_state(self.id) == CREATURE_IDLE then
			self:moveto(get_koth_pos())
		end
		
		self:wait_for_next_round()
	end
	
 ---------------------------------------------------------------------------------

Blueloop V01


--------------------------------------------------------------------------
-- Default Logik 
--
-- Fuer jedes gespawnte Vieh wird eine eigene Creature Klasse instanziiert
--------------------------------------------------------------------------

function Creature:onSpawned()
    print("Creature " .. self.id .. " spawned")
end

function Creature:onAttacked(attacker)
    print("Help! Creature " .. self.id .. " is attacked by Creature " .. attacker)
	
										-- Ich bin noch zu klein zum kämpfen
	if (get_type(self.id) == 0) or (self:health() > 20) then
		local x,y = self:pos()
		                                 -- weglaufen
		self:set_path(x-16000+math.random(8000),y-1600+math.random(8000)) 
		self:begin_walk_path()
	else								 -- Smack my Bit up!
		self:set_target(attacker)
		self:begin_attacking()		
	end
end

function Creature:onKilled(killer)
    if killer == self.id then
        print("Creature " .. self.id .. " suicided")
    elseif killer then 
        print("Creature " .. self.id .. " killed by Creature " .. killer)
    else
        print("Creature " .. self.id .. " died")
    end
end

function Creature:Wait()
	while (get_state(self.id) ~= CREATURE_IDLE) do
		self:wait_for_next_round()	
	end;
end

function Creature:Fressen()
	if get_tile_food(self.id) > 0 then  
		set_state(self.id, CREATURE_EAT)
		self:Wait()
	else
		local x, y = self:pos()
		if not self:moveto(x+self.dx,y+self.dy) then

			self.dx = math.random(256)-128
			self.dy = math.random(256)-128
			
			
		end
	end
	
	if self:health() < 90 then
		set_state(self.id, CREATURE_HEAL)
		self:Wait()
	end
end

function Creature:Angreifen()
	-- Wo ist der nächste Feind?
	local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)	
	
	-- Wenn er nah genug ist und wir gesund sind -> angreifen
	
	if (feind_id ~= nil) and (feind_dist < 500) and (self:health() > 60) then
		print("Starte Angriff auf " .. feind_id .. " Abstand: " .. feind_dist)

		while (exists(feind_id)) do
			local x,y = get_pos(feind_id)                  -- Wo ist der angegriffene?
			self:moveto(x,y)                               -- hinlaufen
			self:attack(feind_id)                          -- angreifen!
			self:Wait()
		end
	end
	
end

function Creature:main()
	if self.dx == nil then self.dx = 256 end
	if self.dy == nil then self.dy = 0 end
	if victim  == nil then victim  = -1 end
	
	if get_type(self.id) == 0 then
		print("Creature " .. self.id .. " soll fressen")
		while get_food(self.id) < 8000 do
			self:Fressen()
		end
		print("Creature " .. self.id .. " soll sich verwandeln")
		set_convert(self.id, 1)
		set_state(self.id,CREATURE_CONVERT)
		self:Wait()
	else
		print("Creature " .. self.id .. " soll fressen")
		while get_food(self.id) < 8000 do
			self:Fressen()
			self:Angreifen()
		end
		print("Creature " .. self.id .. " vermehrt sich")
		set_state(self.id,CREATURE_SPAWN)
		self:Wait()
		--print("Creature " .. self.id .. " soll zu King of the Hill")
		
		--self:moveto(get_koth_pos())
		--self:Wait()
		--print("Creature " .. self.id .. " ist King of the Hill")
		--while self:health() > 30 do
		--	local feind_id, feind_x, feind_y, feind_playernum, feind_dist = nearest_enemy(self.id)			
		--	self:attack(feind_id) 
		--end
	end
end

Updater

require 'socket'
require 'timeout'

class GameConn
  def initialize
    @sock = TCPSocket.new('23.42.2.254', 1234)

    while buf = read_with_timeout
      if buf =~ /Press \<enter\>/
        @sock.puts
      elsif buf =~ /enter '\?' for help/
        @sock.puts 'j'
      elsif buf =~ /enter \<playernum\> or press enter for new player: /
        return
      end
    end
  end

  def join_already(num, password)
    @sock.puts(num)
    while buf = read_with_timeout
      if buf =~ /password for player \d+: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        return
      elsif buf =~/could not attach to player/
        raise buf
      end
    end
  end

  def join_new(password)
    @sock.puts
    while buf = read_with_timeout
      if buf =~ /password for new player: /
        @sock.puts(password)
      elsif buf =~ /joined\. /
        puts buf
        return
      end
    end
  end

  def name=(n)
    @sock.puts 'n'
    while buf = read_with_timeout
      if buf =~ /Player Name: /
        @sock.puts n
      elsif buf =~ /\> /
        return
      elsif buf =~ /cannot set name/
        raise buf
      end
    end
  end

  def read_with_timeout
    buf = ''
    while buf.size == 0
      begin
        Timeout::timeout(0.1) {
          buf += @sock.read(1) while true
        }
      rescue Timeout::Error
      end
    end
    buf
  end

  def debug_loop!
    while buf = read_with_timeout
      print buf
    end
  end

  def batch(source)
    @sock.puts 'b'
    while buf = read_with_timeout
      if buf =~ /enter your lua code/
        @sock.puts source + "\n."
      elsif buf =~ /\> /
        return
      end
    end
  end
end

g = GameConn.new
if true  # Bei Bedarf zu false ändern
  g.join_already(6, '123')
else
  g.join_new('123')
end
g.name = 'CoolBot'
g.batch(IO::readlines('coolbot.lua').to_s)
g.debug_loop!

Update Makefile

PASS=XXX
PLAYERNO=XXX
IP=23.42.2.254

all:
        (echo ; echo j; echo ${PLAYERNO}; echo ${PASS}; echo b; cat bot.lua; echo ; echo .; echo r; echo q) | netcat ${IP} 1234