home *** CD-ROM | disk | FTP | other *** search
- --------------------------------------------------------------------------------
- -- Really Unoptimized Rope
- -- Tobchen Carnage Contest Weapon
- -- Script by Tobchen, August 2010, www.tobchen.de
- --------------------------------------------------------------------------------
-
- --[[
- CHANGES BY DC August/September 2010:
- - attack key for shooting and releasing
- - forceframe command activated
- - playercollision activated
- - impact fx disabled
- - item amount is decreased on use (first shot)
- - rope disappears when terrain changes (e.g. mine explosion)
- ]]
-
- -- Setup Tables
- if cc == nil then cc = {} end
- cc.rope = {}
-
-
- -- Some things
- cc.rope.stack = {} -- The stack contains every rope-terrain-collision-point
- cc.rope.stack_top = 0
- cc.rope.len = 0
- cc.rope.left = 0
- cc.rope.rot = 0
- cc.rope.max_len = 400 -- I really think it's not wise to increase that one
- cc.rope.dir = 0
- cc.rope.speed = 0
-
- -- Load & Prepare Ressources
- cc.rope.gfx_icon = loadgfx("weapons/ropeicon.png")
- setmidhandle(cc.rope.gfx_icon)
- cc.rope.gfx_arms = loadgfx("weapons/ropearms.png")
- setmidhandle(cc.rope.gfx_arms)
-
- --------------------------------------------------------------------------------
- -- Weapon: Unfinished Ninja Rope
- --------------------------------------------------------------------------------
-
- cc.rope.id=addweapon("cc.rope", "Rope (experimental! bugs!)", cc.rope.gfx_icon,1,0) -- Add Weapon (1 use, first in round 0)
-
- -- Draw
- function cc.rope.draw()
- -- Draw crosshair
- if weapon_mode == 0 then
- -- FOR KEYBOARD-AIMING:
- hudcrosshair(0, 0)
- hudinfo("Press [fire] to shoot the rope, press [fire] again to release!")
- -- Draw the rope
- elseif weapon_mode == 1 then
- setblend(blend_alpha)
- setalpha(1)
- setcolor(200, 200, 200)
- drawline(getplayerx(0), getplayery(0), cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 2)
- if cc.rope.stack_top > 1 then
- for i=1, cc.rope.stack_top-1, 1 do
- drawline(cc.rope.stack[i].x, cc.rope.stack[i].y, cc.rope.stack[i+1].x, cc.rope.stack[i+1].y, 2)
- end
- end
- setrotation(0)
- setscale(1, 1)
- setcolor(255, 255, 255)
- -- No player animation, but new arms
- playerforceframe(0, 2)
- drawimage(cc.rope.gfx_arms, getplayerx(0), getplayery(0)+3)
- end
- end
-
- -- Attack
- function cc.rope.attack(attack)
- -- // CHANGE BY DC: Disable rope with space (requires a timer)
- if weapon_timer>0 then weapon_timer=weapon_timer-1 end
- -- CHANGE BY DC //
-
- -- FOR MOUSE-AIMING:
- --hudpositioning(pos_invisible)
-
- -- FOR MOUSE-AIMING:
- --if (weapon_position == 1) then
- -- FOR KEYBOARD-AIMING:
-
- -- // CHANGE BY DC: Disable rope with space (requires a timer)
- --if (weapon_mode == 0 and attack == 1) then
- if (weapon_mode == 0 and attack == 1 and weapon_timer<=0) then
- -- CHANGE BY DC //
-
- -- Is it a hit?
- -- FOR MOUSE-AIMING:
- --go_x = math.sin(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
- --go_y = -math.cos(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
- -- FOR KEYBOARD-AIMING:
- go_x = math.sin(math.rad(getplayerrotation(0)))
- go_y = -math.cos(math.rad(getplayerrotation(0)))
- okay = 1
- for i=7, cc.rope.max_len, 5 do
- tmp_x = getplayerx(0)+(go_x*i)
- tmp_y = getplayery(0)+(go_y*i)
- if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
- for j=(i-2), i+2, 1 do
- tmp_x = getplayerx(0)+(go_x*j)
- tmp_y = getplayery(0)+(go_y*j)
- if collision(col1x1, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
- -- No more player control
- playercontrol(0)
- weapon_mode = 1
- -- // CHANGE BY DC: Decrease amount (use weapon)
- if weapon_shots==0 then useweapon(1) end
- -- CHANGE BY DC //
- weapon_shots = weapon_shots + 1
- -- Go
- cc.rope.stack_top = 0
- cc.rope.stack = {}
- cc.rope.stack_push(tmp_x, tmp_y, 0, 0)
- cc.rope.len = j
- cc.rope.left = j
- -- FOR MOUSE-AIMING:
- --cc.rope.rot = cc.rope.normangle(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))+90)
- -- FOR KEYBOARD-AIMING:
- cc.rope.rot = cc.rope.normangle(-getplayerdirection(0)*(180-math.abs(getplayerrotation(0))))
-
- tmp_angle = cc.rope.normangle(math.deg(math.atan2(getplayerxspeed(0), getplayeryspeed(0)))-180)-180
- tmp_rot = 180-cc.rope.rot
- cc.rope.speed = math.min(cc.rope.rot-tmp_angle, 180-cc.rope.rot-tmp_angle)/90.0
- cc.rope.speed = cc.rope.speed*(math.sqrt((getplayerxspeed(0)^2)+(getplayeryspeed(0)^2)))/1.5
-
- -- Visual and audioel (yeah, that word might exist) appeal
- playsound(sfx_splatter5)
- -- Impact FX disabled by DC
- -- terrainalphaimage(gfx_blood25, cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 1.0, 200, 200, 200)
-
- -- // CHANGE BY DC: Disable rope with space (requires a timer)
- weapon_timer=15
- -- CHANGE BY DC //
-
- okay = 0
- break
- end
- end
- if okay == 0 then break end
- end
- end
-
- -- FOR MOUSE-AIMING:
- --weapon_position = 0
- end
-
- -- Rope is out
- if weapon_mode == 1 then
- cc.rope.rot = cc.rope.normangle(cc.rope.rot)
-
- -- Longer
- if keydown(key_down) == 1 then
- cc.rope.change_length(3)
- -- Shorter
- elseif keydown(key_up) == 1 then
- cc.rope.change_length(-3)
- end
-
- -- Turn left
- if keydown(key_left) == 1 then
- cc.rope.speed = cc.rope.speed + math.abs(math.cos(180-cc.rope.rot)*0.15) -- +0.08
- end
-
- -- Turn right
- if keydown(key_right) == 1 then
- cc.rope.speed = cc.rope.speed - math.abs(math.cos(180-cc.rope.rot)*0.15) -- 0.08
- end
-
- cc.rope.speed = cc.rope.speed+(0.15*cc.rope.sign(180-cc.rope.rot))
- if math.abs(cc.rope.speed) > 5 then cc.rope.speed = 5*cc.rope.sign(cc.rope.speed) end
- cc.rope.speed = cc.rope.speed*0.985
- --if math.abs(cc.rope.speed) < 0.1 then cc.rope.speed = 0 end
-
- tmp_sp = cc.rope.speed
- if cc.rope.left > 150 then tmp_sp = tmp_sp*(150/cc.rope.left) end
- tmp = cc.rope.precision_turn(tmp_sp)
- if tmp == 1 then
- cc.rope.speed = -cc.rope.speed
- end
-
- playerposition(0, cc.rope.posplx(cc.rope.rot, cc.rope.left), cc.rope.posply(cc.rope.rot, cc.rope.left))
- playerpush(0, 0, 0, 1)
-
- -- No more rope
- -- // CHANGE BY DC: Disable rope with space (requires a timer)
- -- if keydown(key_jump) == 1 then
- if keydown(key_attack)==1 and weapon_timer<=0 then
- weapon_timer=10
- -- CHANGE BY DC //
- playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
- playercontrol(1)
- --useweapon(1)
- weapon_mode = 0
- end
-
- -- Disable Rope (Terrain Modification)
- if terrainmodification()==1 then
- weapon_timer=10
- playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
- playercontrol(1)
- weapon_mode = 0
- end
-
- -- Time out
- if getframesleft() < 5 then
- weapon_mode = 3
- playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
- endturn()
- end
- end
- end
-
- -- Turning: positive degree for left, negative for right
- function cc.rope.precision_turn(degree)
- tmp_rot = degree/3.0
- tmp_col = 0
- for i=0, 2, 1 do
- col = cc.rope.turn(tmp_rot)
- if col == 1 then break end
- end
- return col
- end
-
- function cc.rope.turn(degree)
- if degree == 0.0 then return 0 end
- --if (cc.rope.rot > 315 and degree > 0.0) then return 1 end
- --if (cc.rope.rot < 45 and degree < 0.0) then return 1 end
-
- old_top = cc.rope.stack_top
- old_left = cc.rope.left
- -- New vertices
- repeat
- okay = cc.rope.col(degree)
- if okay == 1 then break end
- if cc.rope.left < 1 then break end
- until 1 == 2
- if okay == 1 then
- -- Player may not collide
- if collision(colplayer, cc.rope.posplx(cc.rope.rot+degree, cc.rope.left), cc.rope.posply(cc.rope.rot+degree, cc.rope.left), 1, 1, 1, 0) == 0 then
- cc.rope.rot = cc.rope.rot + degree
-
- -- maybe delete some points
- if cc.rope.stack_top > 1 then
- repeat
- if degree > 0.0 then
- if (cc.rope.stack[cc.rope.stack_top].rot > cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot <= cc.rope.rot) then
- cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
- cc.rope.stack_top = cc.rope.stack_top - 1
- else
- break
- end
- else
- if (cc.rope.stack[cc.rope.stack_top].rot < cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot >= cc.rope.rot) then
- cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
- cc.rope.stack_top = cc.rope.stack_top - 1
- else
- break
- end
- end
- until cc.rope.stack_top == 1
- end
- else
- cc.rope.stack_top = old_top
- cc.rope.left = old_left
- return 1
- end
- end
-
- return 0
- end
-
- -- Change rope length, please just integers
- function cc.rope.change_length(len)
- if len == 0.0 then return end
- if (len > 0.0 and cc.rope.len >= cc.rope.max_len) then return end
- if (len < 0.0 and cc.rope.left <= 1) then return end
-
- for i=1, math.abs(len), 1 do
- if collision(colplayer, cc.rope.posplx(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), cc.rope.posply(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), 1, 1, 1, 0) == 0 then
- cc.rope.len = cc.rope.len + (1*cc.rope.sign(len))
- cc.rope.left = cc.rope.left + (1*cc.rope.sign(len))
- else
- break
- end
- end
- end
-
- -- Collision check
- function cc.rope.col(dir)
- go_x = math.sin(math.rad(cc.rope.rot+dir))
- go_y = -math.cos(math.rad(cc.rope.rot+dir))
- go_x_old = math.sin(math.rad(cc.rope.rot))
- go_y_old = -math.cos(math.rad(cc.rope.rot))
- okay = 1
-
- if cc.rope.left >= 2 then
- tmp = cc.rope.left
-
- for i=3, tmp, 5 do
- tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*i)
- tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*i)
-
- if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
- for j=(i-2), i+2, 1 do
- if j > cc.rope.left then break end
-
- tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*j)
- tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*j)
-
- if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
- tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x_old*j)
- tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y_old*j)
- cc.rope.stack_push(tmp_x, tmp_y, j, cc.rope.normangle(cc.rope.rot))
- cc.rope.left = cc.rope.left - j
- okay = 0
- break
- end
- end
- end
-
- if okay == 0 then break end
- end
- end
-
- return okay
- end
-
-
-
- -- Some simple stack functions (stack, using an array)
- function cc.rope.stack_push(fx, fy, fu, fr)
- cc.rope.stack_top = cc.rope.stack_top + 1
- cc.rope.stack[cc.rope.stack_top] = {}
- cc.rope.stack[cc.rope.stack_top].x = fx
- cc.rope.stack[cc.rope.stack_top].y = fy
- cc.rope.stack[cc.rope.stack_top].used = fu
- cc.rope.stack[cc.rope.stack_top].rot = fr
- end
-
- -- Get relative
- function cc.rope.getanglex(rot, len)
- return math.sin(math.rad(rot))*len
- end
-
- function cc.rope.getangley(rot, len)
- return -math.cos(math.rad(rot))*len
- end
-
- -- Position player
- function cc.rope.posplx(rot, len)
- return cc.rope.stack[cc.rope.stack_top].x+cc.rope.getanglex(rot , len)
- end
-
- function cc.rope.posply(rot, len)
- return cc.rope.stack[cc.rope.stack_top].y+cc.rope.getangley(rot, len)
- end
-
- -- Norm the angle
- function cc.rope.normangle(rot)
- if rot < 0 then
- rot = rot + 360
- cc.rope.normangle(rot)
- elseif rot > 360 then
- rot = rot - 360
- cc.rope.normangle(rot)
- end
- return rot
- end
-
- -- Sign
- function cc.rope.sign(number)
- if number < 0.0 then return -1 end
- return 1
- end